Skip to content

Commit a246223

Browse files
committed
Core tests: safeguard against duplicate test markers
This commit adds a new test to both the `AbstractMethodUnitTest` and the `AbstractTokenizerTestCase` classes to automatically verify that the case file in use by the child test class only contains unique test markers. The actual logic for the test is in a custom, `static`, assertion `assertTestMarkersAreUnique()` to allow for calling the assertion directly if an additional test case file is tokenized for the test; and to prevent duplicating the logic in both test case classes. Includes fixing a few test markers which this new test identified as duplicates straight off. Fixes 773
1 parent 05a2534 commit a246223

File tree

6 files changed

+85
-13
lines changed

6 files changed

+85
-13
lines changed

tests/Core/AbstractMethodUnitTest.php

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,57 @@ public static function tearDownAfterClass(): void
104104
}//end tearDownAfterClass()
105105

106106

107+
/**
108+
* Test QA: verify that a test case file does not contain any duplicate test markers.
109+
*
110+
* When a test case file contains a lot of test cases, it is easy to overlook that a test marker name
111+
* is already in use.
112+
* A test wouldn't necessarily fail on this, but would not be testing what is intended to be tested as
113+
* it would be verifying token properties for the wrong token.
114+
*
115+
* This test safeguards against this.
116+
*
117+
* @coversNothing
118+
*
119+
* @return void
120+
*/
121+
public function testTestMarkersAreUnique()
122+
{
123+
$this->assertTestMarkersAreUnique(self::$phpcsFile);
124+
125+
}//end testTestMarkersAreUnique()
126+
127+
128+
/**
129+
* Assertion to verify that a test case file does not contain any duplicate test markers.
130+
*
131+
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file to validate.
132+
*
133+
* @return void
134+
*/
135+
public static function assertTestMarkersAreUnique(File $phpcsFile)
136+
{
137+
$tokens = $phpcsFile->getTokens();
138+
139+
// Collect all marker comments in the file.
140+
$seenComments = [];
141+
for ($i = 0; $i < $phpcsFile->numTokens; $i++) {
142+
if ($tokens[$i]['code'] !== T_COMMENT) {
143+
continue;
144+
}
145+
146+
if (stripos($tokens[$i]['content'], '/* test') !== 0) {
147+
continue;
148+
}
149+
150+
$seenComments[] = $tokens[$i]['content'];
151+
}
152+
153+
self::assertSame(array_unique($seenComments), $seenComments, 'Duplicate test markers found.');
154+
155+
}//end assertTestMarkersAreUnique()
156+
157+
107158
/**
108159
* Get the token pointer for a target token based on a specific comment found on the line before.
109160
*

tests/Core/File/GetMethodParametersTest.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ function messyDeclaration(
112112
?\MyNS /* comment */
113113
\ SubCat // phpcs:ignore Standard.Cat.Sniff -- for reasons.
114114
\ MyClass $a,
115-
$b /* test */ = /* test */ 'default' /* test*/,
115+
$b /* comment */ = /* comment */ 'default' /* comment*/,
116116
// phpcs:ignore Stnd.Cat.Sniff -- For reasons.
117117
? /*comment*/
118118
bool // phpcs:disable Stnd.Cat.Sniff -- For reasons.

tests/Core/File/GetMethodParametersTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,8 +1180,8 @@ public function testMessyDeclaration()
11801180
$expected[1] = [
11811181
'token' => 28,
11821182
'name' => '$b',
1183-
'content' => "\$b /* test */ = /* test */ 'default' /* test*/",
1184-
'default' => "'default' /* test*/",
1183+
'content' => "\$b /* comment */ = /* comment */ 'default' /* comment*/",
1184+
'default' => "'default' /* comment*/",
11851185
'default_token' => 36,
11861186
'default_equal_token' => 32,
11871187
'has_attributes' => false,

tests/Core/Tokenizers/AbstractTokenizerTestCase.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,27 @@ protected function initializeFile()
8686
}//end initializeFile()
8787

8888

89+
/**
90+
* Test QA: verify that a test case file does not contain any duplicate test markers.
91+
*
92+
* When a test case file contains a lot of test cases, it is easy to overlook that a test marker name
93+
* is already in use.
94+
* A test wouldn't necessarily fail on this, but would not be testing what is intended to be tested as
95+
* it would be verifying token properties for the wrong token.
96+
*
97+
* This test safeguards against this.
98+
*
99+
* @coversNothing
100+
*
101+
* @return void
102+
*/
103+
public function testTestMarkersAreUnique()
104+
{
105+
AbstractMethodUnitTest::assertTestMarkersAreUnique($this->phpcsFile);
106+
107+
}//end testTestMarkersAreUnique()
108+
109+
89110
/**
90111
* Get the token pointer for a target token based on a specific comment found on the line before.
91112
*

tests/Core/Tokenizers/PHP/OtherContextSensitiveKeywordsTest.inc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,11 @@ class DNFTypes extends Something {
212212
const /* testSelfIsKeywordAsConstDNFType */ (self&B)|int NAME_SELF = SOME_CONST;
213213
const bool|(A&/* testParentIsKeywordAsConstDNFType */ parent) NAME_PARENT = SOME_CONST;
214214

215-
readonly public (A&B)/* testFalseIsKeywordAsConstDNFType */ |false $false;
216-
protected /* testTrueIsKeywordAsConstDNFType */ true|(A&B) $true = SOME_CONST;
217-
static private (A&B)|/* testNullIsKeywordAsConstDNFType */ null|(C&D) $null = SOME_CONST;
218-
var string|/* testSelfIsKeywordAsConstDNFType */ (self&Stringable) $self = SOME_CONST;
219-
protected (A/* testParentIsKeywordAsConstDNFType */ &parent)|float $parent = SOME_CONST;
215+
readonly public (A&B)/* testFalseIsKeywordAsPropertyDNFType */ |false $false;
216+
protected /* testTrueIsKeywordAsPropertyDNFType */ true|(A&B) $true = SOME_CONST;
217+
static private (A&B)|/* testNullIsKeywordAsPropertyDNFType */ null|(C&D) $null = SOME_CONST;
218+
var string|/* testSelfIsKeywordAsPropertyDNFType */ (self&Stringable) $self = SOME_CONST;
219+
protected (A/* testParentIsKeywordAsPropertyDNFType */ &parent)|float $parent = SOME_CONST;
220220

221221
public function DNFWithFalse(
222222
/* testFalseIsKeywordAsParamDNFType */

tests/Core/Tokenizers/PHP/OtherContextSensitiveKeywordsTest.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -652,23 +652,23 @@ public static function dataKeywords()
652652
],
653653

654654
'false: DNF type in property declaration' => [
655-
'testMarker' => '/* testFalseIsKeywordAsConstDNFType */',
655+
'testMarker' => '/* testFalseIsKeywordAsPropertyDNFType */',
656656
'expectedTokenType' => 'T_FALSE',
657657
],
658658
'true: DNF type in property declaration' => [
659-
'testMarker' => '/* testTrueIsKeywordAsConstDNFType */',
659+
'testMarker' => '/* testTrueIsKeywordAsPropertyDNFType */',
660660
'expectedTokenType' => 'T_TRUE',
661661
],
662662
'null: DNF type in property declaration' => [
663-
'testMarker' => '/* testNullIsKeywordAsConstDNFType */',
663+
'testMarker' => '/* testNullIsKeywordAsPropertyDNFType */',
664664
'expectedTokenType' => 'T_NULL',
665665
],
666666
'self: DNF type in property declaration' => [
667-
'testMarker' => '/* testSelfIsKeywordAsConstDNFType */',
667+
'testMarker' => '/* testSelfIsKeywordAsPropertyDNFType */',
668668
'expectedTokenType' => 'T_SELF',
669669
],
670670
'parent: DNF type in property declaration' => [
671-
'testMarker' => '/* testParentIsKeywordAsConstDNFType */',
671+
'testMarker' => '/* testParentIsKeywordAsPropertyDNFType */',
672672
'expectedTokenType' => 'T_PARENT',
673673
],
674674

0 commit comments

Comments
 (0)