Skip to content

Commit

Permalink
Tests\Core\AbstractMethodUnitTest: add new getTargetToken() method
Browse files Browse the repository at this point in the history
This adds a new `getTargetToken()` method which can retrieve the target token for testing with higher precision than the (duplicate) code which was so far used in the individual test methods.

The improvements this method offers are:
* Avoid test leaking/contamination.
    If/when the token to start the test from was retrieved by doing a `findNext()` from the delimiter comment, a typo could cause a token from the *next* test to be used for the testing instead of the target token.
    If the expected results would be the same for both tests, this would go completely unnoticed.
    This is now no longer possible.
    The only requirement is that the delimiter comments start with `/* test...`.
* No more token counting when setting up the unit tests, just pass the target token type constant to this method and it will get you the correct token.
    This also allows for not having to jump through hoops when deciding where to place the delimiter comment for the test.
* If the token a test looks for is a `T_STRING` or text based token, the optional `$tokenContent` allows for selecting the correct token, even when there are several of the same type in the test case line.
  • Loading branch information
jrfnl committed Aug 27, 2019
1 parent 511a538 commit abad7a0
Showing 1 changed file with 60 additions and 0 deletions.
60 changes: 60 additions & 0 deletions tests/Core/AbstractMethodUnitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,64 @@ public static function tearDownAfterClass()
}//end tearDownAfterClass()


/**
* Get the token pointer for a target token based on a specific comment found on the line before.
*
* Note: the test delimiter comment MUST start with "/* test" to allow this function to
* distinguish between comments used *in* a test and test delimiters.
*
* @param string $commentString The delimiter comment to look for.
* @param int|string|array $tokenType The type of token(s) to look for.
* @param string $tokenContent Optional. The token content for the target token.
*
* @return int
*/
public function getTargetToken($commentString, $tokenType, $tokenContent=null)
{
$start = (self::$phpcsFile->numTokens - 1);
$comment = self::$phpcsFile->findPrevious(
T_COMMENT,
$start,
null,
false,
$commentString
);

$tokens = self::$phpcsFile->getTokens();
$end = ($start + 1);

// Limit the token finding to between this and the next delimiter comment.
for ($i = ($comment + 1); $i < $end; $i++) {
if ($tokens[$i]['code'] !== T_COMMENT) {
continue;
}

if (stripos($tokens[$i]['content'], '/* test') === 0) {
$end = $i;
break;
}
}

$target = self::$phpcsFile->findNext(
$tokenType,
($comment + 1),
$end,
false,
$tokenContent
);

if ($target === false) {
$msg = 'Failed to find test target token for comment string: '.$commentString;
if ($tokenContent !== null) {
$msg .= ' With token content: '.$tokenContent;
}

$this->assertFalse(true, $msg);
}

return $target;

}//end getTargetToken()


}//end class

0 comments on commit abad7a0

Please sign in to comment.