Skip to content

Commit 8169944

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 b35dba4 commit 8169944

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
@@ -107,6 +107,57 @@ public static function reset()
107107
}//end reset()
108108

109109

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

tests/Core/File/GetMethodParametersTest.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ function messyDeclaration(
118118
?\MyNS /* comment */
119119
\ SubCat // phpcs:ignore Standard.Cat.Sniff -- for reasons.
120120
\ MyClass $a,
121-
$b /* test */ = /* test */ 'default' /* test*/,
121+
$b /* comment */ = /* comment */ 'default' /* comment*/,
122122
// phpcs:ignore Stnd.Cat.Sniff -- For reasons.
123123
? /*comment*/
124124
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
@@ -1268,8 +1268,8 @@ public function testMessyDeclaration()
12681268
$expected[1] = [
12691269
'token' => 29,
12701270
'name' => '$b',
1271-
'content' => "\$b /* test */ = /* test */ 'default' /* test*/",
1272-
'default' => "'default' /* test*/",
1271+
'content' => "\$b /* comment */ = /* comment */ 'default' /* comment*/",
1272+
'default' => "'default' /* comment*/",
12731273
'default_token' => 37,
12741274
'default_equal_token' => 33,
12751275
'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)