Skip to content

Commit

Permalink
UtilityMethodTestCase::getTargetToken(): throw a custom exception whe…
Browse files Browse the repository at this point in the history
…n target token not found

PR 248 introduced the option to throw an exception when the target token couldn't be found (instead of failing the test).
In that initial implementation, the exception thrown would be the PHP native `RuntimeException`.

This commit changes the principle:
* The new parameter `$failTest` has been removed.
* A new, PHPCSUtils native `PHPCSUtils\Exceptions\TestTargetNotFound` exception is introduced, which extends the PHP native `OutOfBoundsException`.
* If the target token is not found, the test will now always throw a `TestTargetNotFound` exception.

As the change from PR 248 has not been in a release yet, the removal of the parameter is non-breaking.

All the same, this is a functional change as an uncaught exception will result in a test being marked as "errored", while previously, the test would be marked as "failed" when the target token could not be found.

The reason for making this change anyway are as follows:
1. The test run will still be marked as unsuccessful, so in that sense, there is no change.
2. Marking the test as "errored" is semantically more correct as a basic condition for the test to be able to run (having a token to examine) has not been fulfilled.
3. If a test would need to look for different token (contents) depending on PHP/PHPCS versions, they can choose to `catch` the exception and do a second token search. This means that the benefits of the change from 248 are still in place.

Includes perfunctory tests for the new `TestTargetNotFound` exception.
Includes updating the related test in the `GetTargetTokenTest` class to expect the new exception.
  • Loading branch information
jrfnl committed Oct 17, 2022
1 parent 189222e commit a58b175
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 43 deletions.
50 changes: 50 additions & 0 deletions PHPCSUtils/Exceptions/TestTargetNotFound.php
@@ -0,0 +1,50 @@
<?php
/**
* PHPCSUtils, utility functions and classes for PHP_CodeSniffer sniff developers.
*
* @package PHPCSUtils
* @copyright 2019-2020 PHPCSUtils Contributors
* @license https://opensource.org/licenses/LGPL-3.0 LGPL3
* @link https://github.com/PHPCSStandards/PHPCSUtils
*/

namespace PHPCSUtils\Exceptions;

use OutOfBoundsException;

/**
* Exception thrown when a test target token can not be found in a test case file.
*
* @since 1.0.0-alpha4
*/
final class TestTargetNotFound extends OutOfBoundsException
{

/**
* Create a new "test target token not found" exception with a standardized text.
*
* @since 1.0.0-alpha4
*
* @param string $marker The delimiter comment.
* @param string $content The (optional) target token content.
* @param string $file The file in which the target token was not found.
*
* @return \PHPCSUtils\Exceptions\TestMarkerNotFound
*/
public static function create($marker, $content, $file)
{
$contentPhrase = '';
if ($content !== null) {
$contentPhrase = ' with token content: ' . $content;
}

return new self(
\sprintf(
'Failed to find test target token for comment string: %s%s in test case file: %s',
$marker,
$contentPhrase,
$file
)
);
}
}
21 changes: 4 additions & 17 deletions PHPCSUtils/TestUtils/UtilityMethodTestCase.php
Expand Up @@ -12,9 +12,9 @@

use PHP_CodeSniffer\Exceptions\TokenizerException;
use PHPCSUtils\BackCompat\Helper;
use PHPCSUtils\Exceptions\TestTargetNotFound;
use PHPUnit\Framework\TestCase;
use ReflectionClass;
use RuntimeException as PHPRuntimeException;

/**
* Base class for use when testing utility methods for PHP_CodeSniffer.
Expand Down Expand Up @@ -333,16 +333,12 @@ public static function usesPhp8NameTokens()
* This string should include the comment opener and closer.
* @param int|string|array $tokenType The type of token(s) to look for.
* @param string $tokenContent Optional. The token content for the target token.
* @param bool $failTest Optional. Whether the test should be marked as failed when
* the target token cannot be found. Defaults to `true`.
* When set to `false`, a catchable PHP native `RuntimeException`
* will be thrown instead.
*
* @return int
*
* @throws \RuntimeException When the target token cannot be found and `$failTest` has been set to `false`.
* @throws \PHPCSUtils\Exceptions\TestTargetNotFound When the target token cannot be found.
*/
public function getTargetToken($commentString, $tokenType, $tokenContent = null, $failTest = true)
public function getTargetToken($commentString, $tokenType, $tokenContent = null)
{
$start = (self::$phpcsFile->numTokens - 1);
$comment = self::$phpcsFile->findPrevious(
Expand Down Expand Up @@ -382,16 +378,7 @@ public function getTargetToken($commentString, $tokenType, $tokenContent = null,
);

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

if ($failTest === false) {
throw new PHPRuntimeException($msg);
}

$this->fail($msg);
throw TestTargetNotFound::create($commentString, $tokenContent, self::$phpcsFile->getFilename());
}

return $target;
Expand Down
56 changes: 56 additions & 0 deletions Tests/Exceptions/TestTargetNotFound/TestTargetNotFoundTest.php
@@ -0,0 +1,56 @@
<?php
/**
* PHPCSUtils, utility functions and classes for PHP_CodeSniffer sniff developers.
*
* @package PHPCSUtils
* @copyright 2019-2020 PHPCSUtils Contributors
* @license https://opensource.org/licenses/LGPL-3.0 LGPL3
* @link https://github.com/PHPCSStandards/PHPCSUtils
*/

namespace PHPCSUtils\Tests\Exceptions\TestTargetNotFound;

use PHPCSUtils\Exceptions\TestTargetNotFound;
use Yoast\PHPUnitPolyfills\TestCases\TestCase;

/**
* Test class.
*
* @covers \PHPCSUtils\Exceptions\TestTargetNotFound
*
* @since 1.0.0
*/
final class TestTargetNotFoundTest extends TestCase
{

/**
* Test that the text of the exception is as expected.
*
* @return void
*/
public function testCreateWithoutContent()
{
$this->expectException('PHPCSUtils\Exceptions\TestTargetNotFound');
$this->expectExceptionMessage(
'Failed to find test target token for comment string: /* testDummy */ in test case file: filename.inc'
);

throw TestTargetNotFound::create('/* testDummy */', null, 'filename.inc');
}

/**
* Test that the text of the exception is as expected.
*
* @return void
*/
public function testCreateWithContent()
{
$this->expectException('PHPCSUtils\Exceptions\TestTargetNotFound');
$this->expectExceptionMessage(
'Failed to find test target token for comment string: /* testDummy */'
. ' with token content: foo in test case file: filename.inc'
);

throw TestTargetNotFound::create('/* testDummy */', 'foo', 'filename.inc');
}
}
29 changes: 3 additions & 26 deletions Tests/TestUtils/UtilityMethodTestCase/GetTargetTokenTest.php
Expand Up @@ -144,39 +144,16 @@ public function testGetTargetTokenCommentNotFound()
$this->getTargetToken('/* testCommentDoesNotExist */', [\T_VARIABLE], '$a');
}

/**
* Test the behaviour of the getTargetToken() method when the target is not found.
*
* @return void
*/
public function testGetTargetTokenNotFound()
{
$msg = 'Failed to find test target token for comment string: ';
$exception = 'PHPUnit\Framework\AssertionFailedError';
if (\class_exists('PHPUnit_Framework_AssertionFailedError')) {
// PHPUnit < 6.
$exception = 'PHPUnit_Framework_AssertionFailedError';
}

$this->expectException($exception);
$this->expectExceptionMessage($msg);

$this->getTargetToken('/* testNotFindingTarget */', [\T_VARIABLE], '$a');
}

/**
* Test the behaviour of the getTargetToken() method when the target is not found.
*
* @return void
*/
public function testGetTargetTokenNotFoundException()
{
$msg = 'Failed to find test target token for comment string: ';
$exception = '\RuntimeException';
$this->expectException('PHPCSUtils\Exceptions\TestTargetNotFound');
$this->expectExceptionMessage('Failed to find test target token for comment string: ');

$this->expectException($exception);
$this->expectExceptionMessage($msg);

$this->getTargetToken('/* testNotFindingTarget */', [\T_VARIABLE], '$a', false);
$this->getTargetToken('/* testNotFindingTarget */', [\T_VARIABLE], '$a');
}
}

0 comments on commit a58b175

Please sign in to comment.