diff --git a/.gitignore b/.gitignore index 3b1c9e6084..b4acb5a7f8 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ composer.lock phpstan.neon /node_modules/ +/tests/Standards/sniffStnd.xml diff --git a/src/Ruleset.php b/src/Ruleset.php index ef3b77461d..746659b47c 100644 --- a/src/Ruleset.php +++ b/src/Ruleset.php @@ -201,22 +201,6 @@ public function __construct(Config $config) Autoload::addSearchPath(dirname($standard), $namespace); } - if (defined('PHP_CODESNIFFER_IN_TESTS') === true && empty($restrictions) === false) { - // In unit tests, only register the sniffs that the test wants and not the entire standard. - foreach ($restrictions as $restriction) { - $sniffs = array_merge($sniffs, $this->expandRulesetReference($restriction, dirname($standard))); - } - - if (empty($sniffs) === true) { - // Sniff reference could not be expanded, which probably means this - // is an installed standard. Let the unit test system take care of - // setting the correct sniff for testing. - return; - } - - break; - } - if (PHP_CODESNIFFER_VERBOSITY === 1) { echo "Registering sniffs in the $standardName standard... "; if (count($config->standards) > 1 || PHP_CODESNIFFER_VERBOSITY > 2) { diff --git a/tests/Core/Generators/GeneratorTest.php b/tests/Core/Generators/GeneratorTest.php index fb237b3a39..8d2c646481 100644 --- a/tests/Core/Generators/GeneratorTest.php +++ b/tests/Core/Generators/GeneratorTest.php @@ -194,16 +194,6 @@ public function testGetTitleFallbackToFilename() $config = new ConfigDouble(["--standard=$standard", "--sniffs=$sniffs"]); $ruleset = new Ruleset($config); - // In tests, the `--sniffs` setting doesn't work out of the box. - $sniffParts = explode('.', $sniffs); - $sniffFile = __DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.$sniffParts[0].DIRECTORY_SEPARATOR; - $sniffFile .= 'Sniffs'.DIRECTORY_SEPARATOR.$sniffParts[1].DIRECTORY_SEPARATOR.$sniffParts[2].'Sniff.php'; - - $sniffParts = array_map('strtolower', $sniffParts); - $sniffName = $sniffParts[0].'\sniffs\\'.$sniffParts[1].'\\'.$sniffParts[2].'sniff'; - $restrictions = [$sniffName => true]; - $ruleset->registerSniffs([$sniffFile], $restrictions, []); - // Make the test OS independent. $this->expectOutputString('Documentation Title PCRE Fallback'.PHP_EOL); diff --git a/tests/Core/Generators/HTMLTest.php b/tests/Core/Generators/HTMLTest.php index a8ac84a8ab..004b2cac7a 100644 --- a/tests/Core/Generators/HTMLTest.php +++ b/tests/Core/Generators/HTMLTest.php @@ -94,16 +94,6 @@ public function testDocSpecifics($sniffs, $pathToExpected) $config = new ConfigDouble(["--standard=$standard", "--sniffs=$sniffs"]); $ruleset = new Ruleset($config); - // In tests, the `--sniffs` setting doesn't work out of the box. - $sniffParts = explode('.', $sniffs); - $sniffFile = __DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.$sniffParts[0].DIRECTORY_SEPARATOR; - $sniffFile .= 'Sniffs'.DIRECTORY_SEPARATOR.$sniffParts[1].DIRECTORY_SEPARATOR.$sniffParts[2].'Sniff.php'; - - $sniffParts = array_map('strtolower', $sniffParts); - $sniffName = $sniffParts[0].'\sniffs\\'.$sniffParts[1].'\\'.$sniffParts[2].'sniff'; - $restrictions = [$sniffName => true]; - $ruleset->registerSniffs([$sniffFile], $restrictions, []); - $expected = file_get_contents($pathToExpected); $this->assertNotFalse($expected, 'Output expectation file could not be found'); diff --git a/tests/Core/Generators/MarkdownTest.php b/tests/Core/Generators/MarkdownTest.php index 6bc2c4fba2..193183bb02 100644 --- a/tests/Core/Generators/MarkdownTest.php +++ b/tests/Core/Generators/MarkdownTest.php @@ -94,16 +94,6 @@ public function testDocSpecifics($sniffs, $pathToExpected) $config = new ConfigDouble(["--standard=$standard", "--sniffs=$sniffs"]); $ruleset = new Ruleset($config); - // In tests, the `--sniffs` setting doesn't work out of the box. - $sniffParts = explode('.', $sniffs); - $sniffFile = __DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.$sniffParts[0].DIRECTORY_SEPARATOR; - $sniffFile .= 'Sniffs'.DIRECTORY_SEPARATOR.$sniffParts[1].DIRECTORY_SEPARATOR.$sniffParts[2].'Sniff.php'; - - $sniffParts = array_map('strtolower', $sniffParts); - $sniffName = $sniffParts[0].'\sniffs\\'.$sniffParts[1].'\\'.$sniffParts[2].'sniff'; - $restrictions = [$sniffName => true]; - $ruleset->registerSniffs([$sniffFile], $restrictions, []); - $expected = file_get_contents($pathToExpected); $this->assertNotFalse($expected, 'Output expectation file could not be found'); diff --git a/tests/Core/Generators/TextTest.php b/tests/Core/Generators/TextTest.php index 90bb7bf89c..d283deda73 100644 --- a/tests/Core/Generators/TextTest.php +++ b/tests/Core/Generators/TextTest.php @@ -94,16 +94,6 @@ public function testDocSpecifics($sniffs, $pathToExpected) $config = new ConfigDouble(["--standard=$standard", "--sniffs=$sniffs"]); $ruleset = new Ruleset($config); - // In tests, the `--sniffs` setting doesn't work out of the box. - $sniffParts = explode('.', $sniffs); - $sniffFile = __DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.$sniffParts[0].DIRECTORY_SEPARATOR; - $sniffFile .= 'Sniffs'.DIRECTORY_SEPARATOR.$sniffParts[1].DIRECTORY_SEPARATOR.$sniffParts[2].'Sniff.php'; - - $sniffParts = array_map('strtolower', $sniffParts); - $sniffName = $sniffParts[0].'\sniffs\\'.$sniffParts[1].'\\'.$sniffParts[2].'sniff'; - $restrictions = [$sniffName => true]; - $ruleset->registerSniffs([$sniffFile], $restrictions, []); - $expected = file_get_contents($pathToExpected); $this->assertNotFalse($expected, 'Output expectation file could not be found'); diff --git a/tests/Core/Ruleset/RegisterSniffsTest.php b/tests/Core/Ruleset/RegisterSniffsTest.php index 37fe2b500d..d9510e18b2 100644 --- a/tests/Core/Ruleset/RegisterSniffsTest.php +++ b/tests/Core/Ruleset/RegisterSniffsTest.php @@ -140,18 +140,17 @@ public function testRegisteredSniffsShouldBeTheSame() /** * Test that if only specific sniffs are requested, only those are registered. * - * {@internal Can't test this via the CLI arguments due to some code in the Ruleset class - * related to sniff tests.} - * * @return void */ public function testRegisteredSniffsWithRestrictions() { - $restrictions = [ - 'psr1\\sniffs\\classes\\classdeclarationsniff' => true, - 'psr1\\sniffs\\files\\sideeffectssniff' => true, - 'psr1\\sniffs\\methods\\camelcapsmethodnamesniff' => true, + // Set up the ruleset. + $args = [ + '--standard=PSR1', + '--sniffs=PSR1.Classes.ClassDeclaration,PSR1.Files.SideEffects,PSR1.Methods.CamelCapsMethodName', ]; + $config = new ConfigDouble($args); + $ruleset = new Ruleset($config); $expected = [ 'PHP_CodeSniffer\\Standards\\PSR1\\Sniffs\\Classes\\ClassDeclarationSniff', @@ -159,9 +158,10 @@ public function testRegisteredSniffsWithRestrictions() 'PHP_CodeSniffer\\Standards\\PSR1\\Sniffs\\Methods\\CamelCapsMethodNameSniff', ]; - self::$ruleset->registerSniffs(self::$psr1SniffAbsolutePaths, $restrictions, []); + $actual = array_keys($ruleset->sniffs); + sort($actual); - $this->assertSame($expected, array_keys(self::$ruleset->sniffs)); + $this->assertSame($expected, $actual); }//end testRegisteredSniffsWithRestrictions() diff --git a/tests/Core/Ruleset/ShowSniffDeprecationsTest.php b/tests/Core/Ruleset/ShowSniffDeprecationsTest.php index db793fdeb0..1e72052840 100644 --- a/tests/Core/Ruleset/ShowSniffDeprecationsTest.php +++ b/tests/Core/Ruleset/ShowSniffDeprecationsTest.php @@ -169,35 +169,13 @@ public static function dataDeprecatedSniffsListDoesNotShowNeedsCsMode() public function testDeprecatedSniffsListDoesNotShowWhenSelectedSniffsAreNotDeprecated() { $standard = __DIR__.'/ShowSniffDeprecationsTest.xml'; - $config = new ConfigDouble(['.', "--standard=$standard"]); - $ruleset = new Ruleset($config); - - /* - * Apply sniff restrictions. - * For tests we need to manually trigger this if the standard is "installed", like with the fixtures these tests use. - */ - - $restrictions = []; - $sniffs = [ - 'TestStandard.SetProperty.AllowedAsDeclared', - 'TestStandard.SetProperty.AllowedViaStdClass', + $cliArgs = [ + '.', + "--standard=$standard", + '--sniffs=TestStandard.SetProperty.AllowedAsDeclared,TestStandard.SetProperty.AllowedViaStdClass', ]; - foreach ($sniffs as $sniffCode) { - $parts = explode('.', strtolower($sniffCode)); - $sniffName = $parts[0].'\\sniffs\\'.$parts[1].'\\'.$parts[2].'sniff'; - $restrictions[strtolower($sniffName)] = true; - } - - $sniffFiles = []; - $allSniffs = $ruleset->sniffCodes; - foreach ($allSniffs as $sniffName) { - $sniffFile = str_replace('\\', DIRECTORY_SEPARATOR, $sniffName); - $sniffFile = __DIR__.DIRECTORY_SEPARATOR.$sniffFile.'.php'; - $sniffFiles[] = $sniffFile; - } - - $ruleset->registerSniffs($sniffFiles, $restrictions, []); - $ruleset->populateTokenListeners(); + $config = new ConfigDouble($cliArgs); + $ruleset = new Ruleset($config); $this->expectOutputString(''); @@ -215,38 +193,20 @@ public function testDeprecatedSniffsListDoesNotShowWhenSelectedSniffsAreNotDepre public function testDeprecatedSniffsListDoesNotShowWhenAllDeprecatedSniffsAreExcluded() { $standard = __DIR__.'/ShowSniffDeprecationsTest.xml'; - $config = new ConfigDouble(['.', "--standard=$standard"]); - $ruleset = new Ruleset($config); - - /* - * Apply sniff restrictions. - * For tests we need to manually trigger this if the standard is "installed", like with the fixtures these tests use. - */ - - $exclusions = []; - $exclude = [ + $exclude = [ 'TestStandard.Deprecated.WithLongReplacement', 'TestStandard.Deprecated.WithoutReplacement', 'TestStandard.Deprecated.WithReplacement', 'TestStandard.Deprecated.WithReplacementContainingLinuxNewlines', 'TestStandard.Deprecated.WithReplacementContainingNewlines', ]; - foreach ($exclude as $sniffCode) { - $parts = explode('.', strtolower($sniffCode)); - $sniffName = $parts[0].'\\sniffs\\'.$parts[1].'\\'.$parts[2].'sniff'; - $exclusions[strtolower($sniffName)] = true; - } - - $sniffFiles = []; - $allSniffs = $ruleset->sniffCodes; - foreach ($allSniffs as $sniffName) { - $sniffFile = str_replace('\\', DIRECTORY_SEPARATOR, $sniffName); - $sniffFile = __DIR__.DIRECTORY_SEPARATOR.$sniffFile.'.php'; - $sniffFiles[] = $sniffFile; - } - - $ruleset->registerSniffs($sniffFiles, [], $exclusions); - $ruleset->populateTokenListeners(); + $cliArgs = [ + '.', + "--standard=$standard", + '--exclude='.implode(',', $exclude), + ]; + $config = new ConfigDouble($cliArgs); + $ruleset = new Ruleset($config); $this->expectOutputString(''); diff --git a/tests/Standards/AbstractSniffUnitTest.php b/tests/Standards/AbstractSniffUnitTest.php index 8b8f8a5dfb..333b77c05c 100644 --- a/tests/Standards/AbstractSniffUnitTest.php +++ b/tests/Standards/AbstractSniffUnitTest.php @@ -26,18 +26,43 @@ abstract class AbstractSniffUnitTest extends TestCase { /** - * Cache for the Config object. + * Ruleset template with placeholders. * - * @var \PHP_CodeSniffer\Tests\ConfigDouble + * @var string */ - private static $config; + private const RULESET_TEMPLATE = <<<'TEMPLATE' + + + Temporary ruleset used by the AbstractSniffUnitTest class. + + + + +TEMPLATE; + + /** + * Placeholders used in the ruleset template which need to be replaced. + * + * @var array + */ + private const SEARCH_FOR = [ + '[STANDARDNAME]', + '[SNIFFFILEREF]', + ]; + + /** + * Location where the temporary ruleset file will be saved. + * + * @var string + */ + private const RULESET_FILENAME = __DIR__.'/sniffStnd.xml'; /** - * Cache for Ruleset objects. + * Cache for the Config object. * - * @var array + * @var \PHP_CodeSniffer\Tests\ConfigDouble */ - private static $rulesets = []; + private static $config; /** * Extensions to disregard when gathering the test files. @@ -52,6 +77,18 @@ abstract class AbstractSniffUnitTest extends TestCase ]; + /** + * Clean up temporary ruleset file. + * + * @return void + */ + public static function tearDownAfterClass(): void + { + @unlink(self::RULESET_FILENAME); + + }//end tearDownAfterClass() + + /** * Get a list of all test files to check. * @@ -103,7 +140,8 @@ protected function shouldSkipTest() * Tests the extending classes Sniff class. * * @return void - * @throws \PHPUnit\Framework\Exception + * + * @throws \PHP_CodeSniffer\Exceptions\RuntimeException */ final public function testSniff() { @@ -122,6 +160,23 @@ final public function testSniff() // Get a list of all test files to check. $testFiles = $this->getTestFiles($testFileBase); + $sniffFile = preg_replace('`[/\\\\]Tests[/\\\\]`', DIRECTORY_SEPARATOR.'Sniffs'.DIRECTORY_SEPARATOR, $testFileBase); + $sniffFile = str_replace('UnitTest.', 'Sniff.php', $sniffFile); + + if (file_exists($sniffFile) === false) { + $this->fail(sprintf('ERROR: Sniff file %s for test %s does not appear to exist', $sniffFile, static::class)); + } + + $replacements = [ + $standardName, + $sniffFile, + ]; + $rulesetContents = str_replace(self::SEARCH_FOR, $replacements, self::RULESET_TEMPLATE); + + if (file_put_contents(self::RULESET_FILENAME, $rulesetContents) === false) { + throw new RuntimeException('Failed to write custom ruleset file'); + } + if (isset(self::$config) === true) { $config = self::$config; } else { @@ -130,31 +185,11 @@ final public function testSniff() self::$config = $config; } - $config->standards = [$standardName]; + $config->standards = [self::RULESET_FILENAME]; $config->sniffs = [$sniffCode]; $config->ignored = []; - if (isset(self::$rulesets[$standardName]) === false) { - $ruleset = new Ruleset($config); - self::$rulesets[$standardName] = $ruleset; - } - - $ruleset = self::$rulesets[$standardName]; - - $sniffFile = preg_replace('`[/\\\\]Tests[/\\\\]`', DIRECTORY_SEPARATOR.'Sniffs'.DIRECTORY_SEPARATOR, $testFileBase); - $sniffFile = str_replace('UnitTest.', 'Sniff.php', $sniffFile); - - if (file_exists($sniffFile) === false) { - $this->fail(sprintf('ERROR: Sniff file %s for test %s does not appear to exist', $sniffFile, static::class)); - } - - $sniffClassName = substr(get_class($this), 0, -8).'Sniff'; - $sniffClassName = str_replace('\Tests\\', '\Sniffs\\', $sniffClassName); - $sniffClassName = Common::cleanSniffClass($sniffClassName); - - $restrictions = [strtolower($sniffClassName) => true]; - $ruleset->registerSniffs([$sniffFile], $restrictions, []); - $ruleset->populateTokenListeners(); + $ruleset = new Ruleset($config); $failureMessages = []; foreach ($testFiles as $testFile) {