Skip to content

Commit

Permalink
Ruleset::registerSniffs(): add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jrfnl committed Dec 12, 2024
1 parent 855f261 commit d7ecf7e
Showing 1 changed file with 293 additions and 0 deletions.
293 changes: 293 additions & 0 deletions tests/Core/Ruleset/RegisterSniffsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,293 @@
<?php
/**
* Test the Ruleset::registerSniffs() method.
*
* @author Juliette Reinders Folmer <[email protected]>
* @copyright 2024 PHPCSStandards and contributors
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/

namespace PHP_CodeSniffer\Tests\Core\Ruleset;

use PHP_CodeSniffer\Ruleset;
use PHP_CodeSniffer\Tests\ConfigDouble;
use PHPUnit\Framework\TestCase;

/**
* Test the Ruleset::registerSniffs() method.
*
* @covers \PHP_CodeSniffer\Ruleset::registerSniffs
*/
final class RegisterSniffsTest extends TestCase
{

/**
* The Ruleset object.
*
* @var \PHP_CodeSniffer\Ruleset
*/
private static $ruleset;

/**
* Original value of the $sniffs property on the Ruleset.
*
* @var array<string, \PHP_CodeSniffer\Sniffs\Sniff>
*/
private static $originalSniffs = [];

/**
* List of Standards dir relative sniff files loaded for the PSR1 standard.
*
* @var array<string>
*/
private static $psr1SniffFiles = [
'Generic/Sniffs/Files/ByteOrderMarkSniff.php',
'Generic/Sniffs/NamingConventions/UpperCaseConstantNameSniff.php',
'Generic/Sniffs/PHP/DisallowAlternativePHPTagsSniff.php',
'Generic/Sniffs/PHP/DisallowShortOpenTagSniff.php',
'PSR1/Sniffs/Classes/ClassDeclarationSniff.php',
'PSR1/Sniffs/Files/SideEffectsSniff.php',
'PSR1/Sniffs/Methods/CamelCapsMethodNameSniff.php',
'Squiz/Sniffs/Classes/ValidClassNameSniff.php',
];

/**
* Absolute paths to the sniff files loaded for the PSR1 standard.
*
* @var array<string>
*/
private static $psr1SniffAbsolutePaths = [];


/**
* Initialize the config and ruleset objects which will be used for some of these tests.
*
* @beforeClass
*
* @return void
*/
public static function initializeConfigAndRuleset()
{
// Set up the ruleset.
$config = new ConfigDouble(['--standard=PSR1']);
self::$ruleset = new Ruleset($config);

// Remember the original value of the Ruleset::$sniff property as the tests adjust it.
self::$originalSniffs = self::$ruleset->sniffs;

// Sort the value to make the tests stable as different OSes will read directories
// in a different order and the order is not relevant for these tests. Just the values.
ksort(self::$originalSniffs);

// Update the sniff file list.
$standardsDir = dirname(dirname(dirname(__DIR__))).DIRECTORY_SEPARATOR;
$standardsDir .= 'src'.DIRECTORY_SEPARATOR.'Standards'.DIRECTORY_SEPARATOR;

self::$psr1SniffAbsolutePaths = self::relativeToAbsoluteSniffFiles($standardsDir, self::$psr1SniffFiles);

}//end initializeConfigAndRuleset()


/**
* Convert relative paths to absolute paths and ensure the paths use the correct OS-specific directory separator.
*
* @param string $baseDir Directory to which these paths are relative to. Including trailing slash.
* @param array<string> $relativePaths Relative paths.
*
* @return array<string>
*/
public static function relativeToAbsoluteSniffFiles($baseDir, $relativePaths)
{
$fileList = [];
foreach ($relativePaths as $sniffName) {
$sniffFile = str_replace('/', DIRECTORY_SEPARATOR, $sniffName);
$sniffFile = $baseDir.$sniffFile;
$fileList[] = $sniffFile;
}

return $fileList;

}//end relativeToAbsoluteSniffFiles()


/**
* Clear out the Ruleset::$sniffs property.
*
* @before
*
* @return void
*/
protected function clearOutSniffs()
{
// Clear out the Ruleset::$sniffs property.
self::$ruleset->sniffs = [];

}//end clearOutSniffs()


/**
* Test that registering sniffs works as expected (simple base test case).
*
* @return void
*/
public function testRegisteredSniffsShouldBeTheSame()
{
self::$ruleset->registerSniffs(self::$psr1SniffAbsolutePaths, [], []);

// Make sure the same sniff list was recreated (but without the objects having been created yet).
$this->assertSame(array_keys(self::$originalSniffs), array_keys(self::$ruleset->sniffs));
$this->assertSame(array_keys(self::$originalSniffs), array_values(self::$ruleset->sniffs));

}//end 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,
];

$expected = [
'PHP_CodeSniffer\\Standards\\PSR1\\Sniffs\\Classes\\ClassDeclarationSniff',
'PHP_CodeSniffer\\Standards\\PSR1\\Sniffs\\Files\\SideEffectsSniff',
'PHP_CodeSniffer\\Standards\\PSR1\\Sniffs\\Methods\\CamelCapsMethodNameSniff',
];

self::$ruleset->registerSniffs(self::$psr1SniffAbsolutePaths, $restrictions, []);

$this->assertSame($expected, array_keys(self::$ruleset->sniffs));

}//end testRegisteredSniffsWithRestrictions()


/**
* Test that sniffs excluded via the CLI are not registered.
*
* @return void
*/
public function testRegisteredSniffsWithExclusions()
{
// Set up the ruleset.
$args = [
'--standard=PSR1',
'--exclude=PSR1.Classes.ClassDeclaration,PSR1.Files.SideEffects,PSR1.Methods.CamelCapsMethodName',
];
$config = new ConfigDouble($args);
$ruleset = new Ruleset($config);

$expected = [
'PHP_CodeSniffer\\Standards\\Generic\\Sniffs\\Files\\ByteOrderMarkSniff',
'PHP_CodeSniffer\\Standards\\Generic\\Sniffs\\NamingConventions\\UpperCaseConstantNameSniff',
'PHP_CodeSniffer\\Standards\\Generic\\Sniffs\\PHP\\DisallowAlternativePHPTagsSniff',
'PHP_CodeSniffer\\Standards\\Generic\\Sniffs\\PHP\\DisallowShortOpenTagSniff',
'PHP_CodeSniffer\\Standards\\Squiz\\Sniffs\\Classes\\ValidClassNameSniff',
];

$actual = array_keys($ruleset->sniffs);
sort($actual);

$this->assertSame($expected, $actual);

}//end testRegisteredSniffsWithExclusions()


/**
* Test combining requesting specific sniffs and excluding a subset of those.
*
* @return void
*/
public function testRegisteredSniffsBothRestrictionsAndExclusions()
{
$restrictions = [
'generic\\sniffs\\namingconventions\\uppercaseconstantnamesniff' => true,
'generic\\sniffs\\php\\disallowalternativephptagssniff' => true,
'generic\\sniffs\\php\\disallowshortopentagsniff' => true,
'psr1\\sniffs\\classes\\classdeclarationsniff' => true,
'squiz\\sniffs\\classes\\validclassnamesniff' => true,
];

$exclusions = [
'squiz\\sniffs\\classes\\validclassnamesniff' => true,
'generic\\sniffs\\php\\disallowalternativephptagssniff' => true,
'generic\\sniffs\\namingconventions\\uppercaseconstantnamesniff' => true,
];

$expected = [
'PHP_CodeSniffer\\Standards\\Generic\\Sniffs\\PHP\\DisallowShortOpenTagSniff',
'PHP_CodeSniffer\\Standards\\PSR1\\Sniffs\\Classes\\ClassDeclarationSniff',
];

self::$ruleset->registerSniffs(self::$psr1SniffAbsolutePaths, $restrictions, $exclusions);

$this->assertEquals($expected, array_keys(self::$ruleset->sniffs));

}//end testRegisteredSniffsBothRestrictionsAndExclusions()


/**
* Verify that abstract sniffs are filtered out and not registered.
*
* @return void
*/
public function testRegisterSniffsFiltersOutAbstractClasses()
{
$extraPathsBaseDir = __DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR;
$extraPaths = [
'DirectoryExpansion/.hiddenAbove/src/MyStandard/Sniffs/AbstractSniff.php',
'DirectoryExpansion/.hiddenAbove/src/MyStandard/Sniffs/CategoryB/AnotherAbstractSniff.php',
];
$extraPaths = self::relativeToAbsoluteSniffFiles($extraPathsBaseDir, $extraPaths);

$fileList = self::$psr1SniffAbsolutePaths;
foreach ($extraPaths as $path) {
$fileList[] = $path;
}

self::$ruleset->registerSniffs($fileList, [], []);

// Make sure the same sniff list was recreated (but without the objects having been created yet).
$this->assertSame(array_keys(self::$originalSniffs), array_keys(self::$ruleset->sniffs));
$this->assertSame(array_keys(self::$originalSniffs), array_values(self::$ruleset->sniffs));

}//end testRegisterSniffsFiltersOutAbstractClasses()


/**
* Test that sniff files not in a "/Sniffs/" directory are filtered out and not registered.
*
* @return void
*/
public function testRegisteredSniffsFiltersOutFilePathsWithoutSniffsDir()
{
$extraPathsBaseDir = __DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR;
$extraPaths = [
'DirectoryExpansion/.hiddenAbove/src/MyStandard/Utils/NotInSniffsDirSniff.php',
'DirectoryExpansion/.hiddenAbove/src/MyStandard/Utils/SubDir/NotInSniffsDirSniff.php',
];
$extraPaths = self::relativeToAbsoluteSniffFiles($extraPathsBaseDir, $extraPaths);

$fileList = self::$psr1SniffAbsolutePaths;
foreach ($extraPaths as $path) {
$fileList[] = $path;
}

self::$ruleset->registerSniffs($fileList, [], []);

// Make sure the same sniff list was recreated (but without the objects having been created yet).
$this->assertSame(array_keys(self::$originalSniffs), array_keys(self::$ruleset->sniffs));
$this->assertSame(array_keys(self::$originalSniffs), array_values(self::$ruleset->sniffs));

}//end testRegisteredSniffsFiltersOutFilePathsWithoutSniffsDir()


}//end class

0 comments on commit d7ecf7e

Please sign in to comment.