Skip to content

Commit d78846e

Browse files
authored
Merge pull request #845 from PHPCSStandards/feature/squiz-classfilename-various-improvements
Squiz/ClassFileName: various improvements
2 parents 68e9871 + cf5d4c1 commit d78846e

8 files changed

+152
-53
lines changed

src/Standards/Squiz/Sniffs/Classes/ClassFileNameSniff.php

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
use PHP_CodeSniffer\Files\File;
1313
use PHP_CodeSniffer\Sniffs\Sniff;
14+
use PHP_CodeSniffer\Util\Tokens;
1415

1516
class ClassFileNameSniff implements Sniff
1617
{
@@ -23,12 +24,10 @@ class ClassFileNameSniff implements Sniff
2324
*/
2425
public function register()
2526
{
26-
return [
27-
T_CLASS,
28-
T_INTERFACE,
29-
T_TRAIT,
30-
T_ENUM,
31-
];
27+
$targets = Tokens::$ooScopeTokens;
28+
unset($targets[T_ANON_CLASS]);
29+
30+
return $targets;
3231

3332
}//end register()
3433

@@ -44,22 +43,27 @@ public function register()
4443
*/
4544
public function process(File $phpcsFile, $stackPtr)
4645
{
47-
$fullPath = basename($phpcsFile->getFilename());
48-
$fileName = substr($fullPath, 0, strrpos($fullPath, '.'));
49-
if ($fileName === '') {
50-
// No filename probably means STDIN, so we can't do this check.
51-
return;
46+
$fullPath = $phpcsFile->getFilename();
47+
if ($fullPath === 'STDIN') {
48+
return $phpcsFile->numTokens;
5249
}
5350

54-
$tokens = $phpcsFile->getTokens();
55-
$decName = $phpcsFile->findNext(T_STRING, $stackPtr);
51+
$fileName = basename($fullPath);
52+
$fileNoExt = substr($fileName, 0, strrpos($fileName, '.'));
53+
$extension = substr($fileName, (strrpos($fileName, '.') + 1));
54+
55+
$tokens = $phpcsFile->getTokens();
56+
$ooName = $phpcsFile->getDeclarationName($stackPtr);
57+
if ($ooName === null) {
58+
// Probably parse error/live coding.
59+
return;
60+
}
5661

57-
if ($tokens[$decName]['content'] !== $fileName) {
58-
$error = '%s name doesn\'t match filename; expected "%s %s"';
62+
if ($ooName !== $fileNoExt) {
63+
$error = 'Filename doesn\'t match %s name; expected file name "%s"';
5964
$data = [
60-
ucfirst($tokens[$stackPtr]['content']),
6165
$tokens[$stackPtr]['content'],
62-
$fileName,
66+
$ooName.'.'.$extension,
6367
];
6468
$phpcsFile->addError($error, $stackPtr, 'NoMatch', $data);
6569
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
// Test to demonstrate that file names should follow class names, not the other way around.
4+
// Making the class name comply with the file name would result in a parse error for this file,
5+
// as the file name doesn't comply with the naming conventions for PHP symbol names.
6+
7+
class ClassFileNameSpacesInFilenameUnitTest {}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
// Test to demonstrate that file names should follow class names, not the other way around.
4+
// Making the class name comply with the file name would result in a parse error for this file,
5+
// as the file name doesn't comply with the naming conventions for PHP symbol names.
6+
7+
class ClassFileNameDashesInFilenameUnitTest
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?php
2+
3+
// Intentional parse error. This should be the only test in this file.
4+
// Live coding/missing curlies should not block the sniff from functioning.
5+
6+
class Class_FileName_Live_Coding_Fail_UnitTest
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?php
2+
3+
// Intentional parse error. This should be the only test in this file.
4+
// Live coding/missing curlies should not block the sniff from functioning.
5+
6+
class ClassFileNameLiveCodingPassUnitTest
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?php
2+
3+
// Intentional parse error. This should be the only test in this file.
4+
// Class missing class name should be ignored.
5+
6+
class

src/Standards/Squiz/Tests/Classes/ClassFileNameUnitTest.inc

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class CLASSFILENAMEUNITTEST {}
1515
interface classFileNameUnitTest {}
1616
interface classfilenameunittest {}
1717
interface CLASSFILENAMEUNITTEST {}
18-
trait classFileNameUnitTest {}
18+
trait /*comment*/ classFileNameUnitTest {}
1919
trait classfilenameunittest {}
2020
trait CLASSFILENAMEUNITTEST {}
2121
enum classFileNameUnitTest {}
@@ -39,7 +39,6 @@ trait ExtraClassFileNameUnitTest {}
3939
enum CompletelyWrongClassName {}
4040
enum ClassFileNameUnitTestExtra {}
4141
enum ClassFileNameUnitTestInc {}
42-
enum ExtraClassFileNameUnitTest {}
43-
44-
45-
?>
42+
enum
43+
// Comment
44+
ExtraClassFileNameUnitTest {}

src/Standards/Squiz/Tests/Classes/ClassFileNameUnitTest.php

Lines changed: 95 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
namespace PHP_CodeSniffer\Standards\Squiz\Tests\Classes;
1111

12+
use DirectoryIterator;
1213
use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;
1314

1415
/**
@@ -20,46 +21,109 @@ final class ClassFileNameUnitTest extends AbstractSniffUnitTest
2021
{
2122

2223

24+
/**
25+
* Get a list of all test files to check.
26+
*
27+
* These will have the same base as the sniff name but different extensions.
28+
* We ignore the .php file as it is the class.
29+
*
30+
* @param string $testFileBase The base path that the unit tests files will have.
31+
*
32+
* @return string[]
33+
*/
34+
protected function getTestFiles($testFileBase)
35+
{
36+
$testFiles = [];
37+
38+
$dir = substr($testFileBase, 0, strrpos($testFileBase, DIRECTORY_SEPARATOR));
39+
$di = new DirectoryIterator($dir);
40+
41+
// Strip off the path and the "UnitTest." suffix from the $testFileBase to allow
42+
// for some less conventionally named test case files.
43+
$fileBase = str_replace($dir, '', $testFileBase);
44+
$fileBase = substr($fileBase, 1, -9);
45+
46+
foreach ($di as $file) {
47+
$fileName = $file->getBasename('UnitTest.inc');
48+
$extension = $file->getExtension();
49+
if (substr($fileName, 0, strlen($fileBase)) === $fileBase
50+
&& $extension === 'inc'
51+
) {
52+
$testFiles[] = $file->getPathname();
53+
}
54+
}
55+
56+
// Put them in order.
57+
sort($testFiles, SORT_NATURAL);
58+
59+
return $testFiles;
60+
61+
}//end getTestFiles()
62+
63+
2364
/**
2465
* Returns the lines where errors should occur.
2566
*
2667
* The key of the array should represent the line number and the value
2768
* should represent the number of errors that should occur on that line.
2869
*
70+
* @param string $testFile The name of the file being tested.
71+
*
2972
* @return array<int, int>
3073
*/
31-
public function getErrorList()
74+
public function getErrorList($testFile='')
3275
{
33-
return [
34-
12 => 1,
35-
13 => 1,
36-
14 => 1,
37-
15 => 1,
38-
16 => 1,
39-
17 => 1,
40-
18 => 1,
41-
19 => 1,
42-
20 => 1,
43-
21 => 1,
44-
22 => 1,
45-
23 => 1,
46-
27 => 1,
47-
28 => 1,
48-
29 => 1,
49-
30 => 1,
50-
31 => 1,
51-
32 => 1,
52-
33 => 1,
53-
34 => 1,
54-
35 => 1,
55-
36 => 1,
56-
37 => 1,
57-
38 => 1,
58-
39 => 1,
59-
40 => 1,
60-
41 => 1,
61-
42 => 1,
62-
];
76+
switch ($testFile) {
77+
case 'ClassFileNameUnitTest.inc':
78+
return [
79+
12 => 1,
80+
13 => 1,
81+
14 => 1,
82+
15 => 1,
83+
16 => 1,
84+
17 => 1,
85+
18 => 1,
86+
19 => 1,
87+
20 => 1,
88+
21 => 1,
89+
22 => 1,
90+
23 => 1,
91+
27 => 1,
92+
28 => 1,
93+
29 => 1,
94+
30 => 1,
95+
31 => 1,
96+
32 => 1,
97+
33 => 1,
98+
34 => 1,
99+
35 => 1,
100+
36 => 1,
101+
37 => 1,
102+
38 => 1,
103+
39 => 1,
104+
40 => 1,
105+
41 => 1,
106+
42 => 1,
107+
];
108+
109+
case 'ClassFileNameLiveCodingFailUnitTest.inc':
110+
return [
111+
6 => 1,
112+
];
113+
114+
case 'ClassFileName Spaces In FilenameUnitTest.inc':
115+
return [
116+
7 => 1,
117+
];
118+
119+
case 'ClassFileName-Dashes-In-FilenameUnitTest.inc':
120+
return [
121+
7 => 1,
122+
];
123+
124+
default:
125+
return [];
126+
}//end switch
63127

64128
}//end getErrorList()
65129

0 commit comments

Comments
 (0)