Skip to content

Runner::printProgress(): minor refactor #960

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 28 additions & 35 deletions src/Runner.php
Original file line number Diff line number Diff line change
Expand Up @@ -856,9 +856,14 @@ public function printProgress(File $file, $numFiles, $numProcessed)
return;
}

$showColors = $this->config->colors;
$colorOpen = '';
$progressDot = '.';
$colorClose = '';

// Show progress information.
if ($file->ignored === true) {
echo 'S';
$progressDot = 'S';
} else {
$errors = $file->getErrorCount();
$warnings = $file->getWarningCount();
Expand All @@ -870,27 +875,19 @@ public function printProgress(File $file, $numFiles, $numProcessed)
// Files with unfixable errors or warnings are E (red).
// Files with no errors or warnings are . (black).
if ($fixable > 0) {
if ($this->config->colors === true) {
echo "\033[31m";
}
$progressDot = 'E';

echo 'E';

if ($this->config->colors === true) {
echo "\033[0m";
if ($showColors === true) {
$colorOpen = "\033[31m";
$colorClose = "\033[0m";
}
} else if ($fixed > 0) {
if ($this->config->colors === true) {
echo "\033[32m";
}
$progressDot = 'F';

echo 'F';

if ($this->config->colors === true) {
echo "\033[0m";
if ($showColors === true) {
$colorOpen = "\033[32m";
$colorClose = "\033[0m";
}
} else {
echo '.';
}//end if
} else {
// Files with errors are E (red).
Expand All @@ -899,39 +896,35 @@ public function printProgress(File $file, $numFiles, $numProcessed)
// Files with fixable warnings are W (green).
// Files with no errors or warnings are . (black).
if ($errors > 0) {
if ($this->config->colors === true) {
$progressDot = 'E';

if ($showColors === true) {
if ($fixable > 0) {
echo "\033[32m";
$colorOpen = "\033[32m";
} else {
echo "\033[31m";
$colorOpen = "\033[31m";
}
}

echo 'E';

if ($this->config->colors === true) {
echo "\033[0m";
$colorClose = "\033[0m";
}
} else if ($warnings > 0) {
if ($this->config->colors === true) {
$progressDot = 'W';

if ($showColors === true) {
if ($fixable > 0) {
echo "\033[32m";
$colorOpen = "\033[32m";
} else {
echo "\033[33m";
$colorOpen = "\033[33m";
}
}

echo 'W';

if ($this->config->colors === true) {
echo "\033[0m";
$colorClose = "\033[0m";
}
} else {
echo '.';
}//end if
}//end if
}//end if

echo $colorOpen.$progressDot.$colorClose;

$numPerLine = 60;
if ($numProcessed !== $numFiles && ($numProcessed % $numPerLine) !== 0) {
return;
Expand Down
222 changes: 222 additions & 0 deletions tests/Core/Runner/PrintProgressDotsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
<?php
/**
* Tests progress reporting in the Runner class.
*
* @copyright 2025 PHPCSStandards and contributors
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/

namespace PHP_CodeSniffer\Tests\Core\Runner;

use PHP_CodeSniffer\Files\DummyFile;
use PHP_CodeSniffer\Ruleset;
use PHP_CodeSniffer\Runner;
use PHP_CodeSniffer\Tests\ConfigDouble;
use PHPUnit\Framework\TestCase;

/**
* Tests progress reporting.
*
* @covers \PHP_CodeSniffer\Runner::printProgress
*/
final class PrintProgressDotsTest extends TestCase
{


/**
* Verify the correct progress indicator is used for a file in CS mode.
*
* @param bool $colors Whether to enable colors or not.
* @param string $code Code snippet to process.
* @param string $sniffs Comma-separated list of sniff(s) to run against the code snippet.
* @param string $expected Expected output of the progress printer.
*
* @dataProvider dataProgressDotCs
*
* @return void
*/
public function testProgressDotCs($colors, $code, $sniffs, $expected)
{
if (PHP_CODESNIFFER_CBF === true) {
$this->markTestSkipped('This test needs CS mode to run');
}

$this->checkProgressDot($colors, $code, $sniffs, $expected);

}//end testProgressDotCs()


/**
* Data provider.
*
* @return array<string, array<string, bool|string>>
*/
public static function dataProgressDotCs()
{
return [
'No colors: Dot: no errors, no warnings' => [
'colors' => false,
'code' => '<?php'."\n".'$var = false;'."\n",
'sniff' => 'Generic.PHP.LowerCaseConstant',
'expected' => '.',
],
'No colors: E: has error' => [
'colors' => false,
'code' => '<?php'."\n".'if ($a && $b || $c) {}'."\n",
'sniff' => 'Generic.CodeAnalysis.RequireExplicitBooleanOperatorPrecedence',
'expected' => 'E',
],
'No colors: W: has warning' => [
'colors' => false,
'code' => '<?php'."\n".'// TODO: something'."\n",
'sniff' => 'Generic.Commenting.Todo',
'expected' => 'W',
],

'Colors: Dot: no errors, no warnings' => [
'colors' => true,
'code' => '<?php'."\n".'$var = false;'."\n",
'sniff' => 'Generic.PHP.LowerCaseConstant',
'expected' => '.',
],
'Colors: E: has error (red)' => [
'colors' => true,
'code' => '<?php'."\n".'if ($a && $b || $c) {}'."\n",
'sniff' => 'Generic.CodeAnalysis.RequireExplicitBooleanOperatorPrecedence',
'expected' => "\033[31m".'E'."\033[0m",
],
'Colors: E: has fixable error (green)' => [
'colors' => true,
'code' => '<?php'."\n".'$a = array();'."\n",
'sniff' => 'Generic.Arrays.DisallowLongArraySyntax',
'expected' => "\033[32m".'E'."\033[0m",
],
'Colors: W: has warning (yellow)' => [
'colors' => true,
'code' => '<?php'."\n".'// TODO: something'."\n",
'sniff' => 'Generic.Commenting.Todo',
'expected' => "\033[33m".'W'."\033[0m",
],
'Colors: W: has fixable warning (green)' => [
'colors' => true,
'code' => '<?php'."\n".'echo \'hello\';;'."\n",
'sniff' => 'Generic.CodeAnalysis.EmptyPHPStatement',
'expected' => "\033[32m".'W'."\033[0m",
],
];

}//end dataProgressDotCs()


/**
* Verify the correct progress indicator is used for a file in CBF mode.
*
* @param bool $colors Whether to enable colors or not.
* @param string $code Code snippet to process.
* @param string $sniffs Comma-separated list of sniff(s) to run against the code snippet.
* @param string $expected Expected output of the progress printer.
*
* @dataProvider dataProgressDotCbf
*
* @group CBF
*
* @return void
*/
public function testProgressDotCbf($colors, $code, $sniffs, $expected)
{
if (PHP_CODESNIFFER_CBF === false) {
$this->markTestSkipped('This test needs CBF mode to run');
}

$this->checkProgressDot($colors, $code, $sniffs, $expected, true);

}//end testProgressDotCbf()


/**
* Data provider.
*
* @return array<string, array<string, bool|string>>
*/
public static function dataProgressDotCbf()
{
return [
'No colors: Dot: no errors, no warnings' => [
'colors' => false,
'code' => '<?php'."\n".'$var = false;'."\n",
'sniff' => 'Generic.PHP.LowerCaseConstant',
'expected' => '.',
],
'No colors: F: fixes made' => [
'colors' => false,
'code' => '<?php'."\n".'$a = array();'."\n",
'sniff' => 'Generic.Arrays.DisallowLongArraySyntax',
'expected' => 'F',
],
'No colors: E: has fixer conflict' => [
'colors' => false,
'code' => '<?php'."\n".'$a = array();'."\n",
'sniff' => 'Generic.Arrays.DisallowLongArraySyntax,Generic.Arrays.DisallowShortArraySyntax',
'expected' => 'E',
],

'Colors: Dot: no errors, no warnings (no color)' => [
'colors' => true,
'code' => '<?php'."\n".'$var = false;'."\n",
'sniff' => 'Generic.PHP.LowerCaseConstant',
'expected' => '.',
],
'Colors: F: fixes made (green)' => [
'colors' => true,
'code' => '<?php'."\n".'$a = array();'."\n",
'sniff' => 'Generic.Arrays.DisallowLongArraySyntax',
'expected' => "\033[32m".'F'."\033[0m",
],
'Colors: E: has fixer conflict (red)' => [
'colors' => true,
'code' => '<?php'."\n".'$a = array();'."\n",
'sniff' => 'Generic.Arrays.DisallowLongArraySyntax,Generic.Arrays.DisallowShortArraySyntax',
'expected' => "\033[31m".'E'."\033[0m",
],
];

}//end dataProgressDotCbf()


/**
* Verify the correct progress indicator is used for a file in CBF mode.
*
* @param bool $colors Whether to enable colors or not.
* @param string $code Code snippet to process.
* @param string $sniffs Comma-separated list of sniff(s) to run against the code snippet.
* @param string $expected Expected output of the progress printer.
* @param bool $enableFixer Whether to fix the code or not.
*
* @return void
*/
private function checkProgressDot($colors, $code, $sniffs, $expected, $enableFixer=false)
{
$this->expectOutputString($expected);

$config = new ConfigDouble(['-p']);
$config->colors = $colors;
$config->standards = ['Generic'];
$config->sniffs = explode(',', $sniffs);
$ruleset = new Ruleset($config);

$runner = new Runner();
$runner->config = $config;

$file = new DummyFile($code, $ruleset, $config);
$file->process();

if ($enableFixer === true) {
$file->fixer->fixFile();
}

$runner->printProgress($file, 2, 1);

}//end checkProgressDot()


}//end class
Loading