Skip to content

Commit

Permalink
Common::getSniffCode(): be more lenient about sniffs not following na…
Browse files Browse the repository at this point in the history
…ming conventions

Sniff classes _should_ always follow the directory layout and naming conventions for sniffs as per the [Tutorial](https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki/Coding-Standard-Tutorial).

However, before the change made in 524, when given a sniff class name for a sniff not following the naming conventions, the `Common::getSniffCode()` method would return a "sniff code" anyway. And even though the sniff code would be unconventional and not really valid, it would still _work_.

Since 524 this is no longer the case.

Given the above, the change from 524 breaks custom rulesets which use `<rule>` includes for individual sniff files not complying with the naming conventions. Breaking changes can only be made in majors, so this commit reverts the problematic part of the change from 524.

Includes additional tests safeguarding the (broken) behaviour which needs to be maintained until the next major.

Fixes 675
  • Loading branch information
jrfnl committed Nov 12, 2024
1 parent 204c963 commit c5fe229
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 16 deletions.
20 changes: 11 additions & 9 deletions src/Util/Common.php
Original file line number Diff line number Diff line change
Expand Up @@ -542,13 +542,7 @@ public static function getSniffCode($sniffClass)

$parts = explode('\\', $sniffClass);
$partsCount = count($parts);
if ($partsCount < 4) {
throw new InvalidArgumentException(
'The $sniffClass parameter was not passed a fully qualified sniff(test) class name. Received: '.$sniffClass
);
}

$sniff = $parts[($partsCount - 1)];
$sniff = $parts[($partsCount - 1)];

if (substr($sniff, -5) === 'Sniff') {
// Sniff class name.
Expand All @@ -562,8 +556,16 @@ public static function getSniffCode($sniffClass)
);
}

$standard = $parts[($partsCount - 4)];
$category = $parts[($partsCount - 2)];
$standard = '';
if (isset($parts[($partsCount - 4)]) === true) {
$standard = $parts[($partsCount - 4)];
}

$category = '';
if (isset($parts[($partsCount - 2)]) === true) {
$category = $parts[($partsCount - 2)];
}

return $standard.'.'.$category.'.'.$sniff;

}//end getSniffCode()
Expand Down
41 changes: 34 additions & 7 deletions tests/Core/Util/Common/GetSniffCodeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ public static function dataGetSniffCodeThrowsExceptionOnInputWhichIsNotASniffTes
'Unqualified class name' => ['ClassName'],
'Fully qualified class name, not enough parts' => ['Fully\\Qualified\\ClassName'],
'Fully qualified class name, doesn\'t end on Sniff or UnitTest' => ['Fully\\Sniffs\\Qualified\\ClassName'],
'Fully qualified class name, ends on Sniff, but isn\'t' => ['Fully\\Sniffs\\AbstractSomethingSniff'],
];

}//end dataGetSniffCodeThrowsExceptionOnInputWhichIsNotASniffTestClass()
Expand Down Expand Up @@ -141,30 +140,58 @@ public function testGetSniffCode($fqnClass, $expected)
public static function dataGetSniffCode()
{
return [
'PHPCS native sniff' => [
'PHPCS native sniff' => [
'fqnClass' => 'PHP_CodeSniffer\\Standards\\Generic\\Sniffs\\Arrays\\ArrayIndentSniff',
'expected' => 'Generic.Arrays.ArrayIndent',
],
'Class is a PHPCS native test class' => [
'Class is a PHPCS native test class' => [
'fqnClass' => 'PHP_CodeSniffer\\Standards\\Generic\\Tests\\Arrays\\ArrayIndentUnitTest',
'expected' => 'Generic.Arrays.ArrayIndent',
],
'Sniff in external standard without namespace prefix' => [
'Sniff in external standard without namespace prefix' => [
'fqnClass' => 'MyStandard\\Sniffs\\PHP\\MyNameSniff',
'expected' => 'MyStandard.PHP.MyName',
],
'Test in external standard without namespace prefix' => [
'Test in external standard without namespace prefix' => [
'fqnClass' => 'MyStandard\\Tests\\PHP\\MyNameSniff',
'expected' => 'MyStandard.PHP.MyName',
],
'Sniff in external standard with namespace prefix' => [
'Sniff in external standard with namespace prefix' => [
'fqnClass' => 'Vendor\\Package\\MyStandard\\Sniffs\\Category\\AnalyzeMeSniff',
'expected' => 'MyStandard.Category.AnalyzeMe',
],
'Test in external standard with namespace prefix' => [
'Test in external standard with namespace prefix' => [
'fqnClass' => 'Vendor\\Package\\MyStandard\\Tests\\Category\\AnalyzeMeUnitTest',
'expected' => 'MyStandard.Category.AnalyzeMe',
],

/*
* These are not valid sniff codes and is an undesirable result, but can't be helped
* as changing this would be a BC-break.
* Supporting these to allow for <rule> tags directly including sniff files.
* See: https://github.com/PHPCSStandards/PHP_CodeSniffer/issues/675
*/

'Fully qualified class name, ends on Sniff, but isn\'t' => [
'fqnClass' => 'Fully\\Sniffs\\AbstractSomethingSniff',
'expected' => '.Sniffs.AbstractSomething',
],
'Sniff provided via file include and doesn\'t comply with naming conventions [1]' => [
'fqnClass' => 'CheckMeSniff',
'expected' => '..CheckMe',
],
'Sniff provided via file include and doesn\'t comply with naming conventions [2]' => [
'fqnClass' => 'CompanyName\\CheckMeSniff',
'expected' => '.CompanyName.CheckMe',
],
'Sniff provided via file include and doesn\'t comply with naming conventions [3]' => [
'fqnClass' => 'CompanyName\\Sniffs\\CheckMeSniff',
'expected' => '.Sniffs.CheckMe',
],
'Sniff provided via file include and doesn\'t comply with naming conventions [4]' => [
'fqnClass' => 'CompanyName\\CustomSniffs\\Whatever\\CheckMeSniff',
'expected' => 'CompanyName.Whatever.CheckMe',
],
];

}//end dataGetSniffCode()
Expand Down

0 comments on commit c5fe229

Please sign in to comment.