From 4e0457af6915da63d97caf7159396a476d1c68ab Mon Sep 17 00:00:00 2001 From: cg-x <53591541+cg-x@users.noreply.github.com> Date: Fri, 14 Jul 2023 16:10:29 +1000 Subject: [PATCH] Phpunit10 update (#2) * Updated to support PHPUnit 10 * Fixed XML validation errors --- README.md | 12 ++- composer.json | 4 +- phpunit.xml.dist | 23 +++--- src/Subscribers/BeforeTestEnds.php | 20 +++++ src/Subscribers/OnTestPrepared.php | 89 ++++++++++++++++++++ src/VCRTestListener.php | 126 ++++++----------------------- tests/VCRTestListenerTest.php | 5 +- 7 files changed, 163 insertions(+), 116 deletions(-) create mode 100644 src/Subscribers/BeforeTestEnds.php create mode 100644 src/Subscribers/OnTestPrepared.php diff --git a/README.md b/README.md index 4e68906..0fcbe5c 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,13 @@ composer require --dev php-vcr/phpunit-testlistener-vcr 2) Add listener to your `phpunit.xml`: +``` xml + + + +``` + +Prior to PHPUnit 10 ``` xml @@ -47,8 +54,11 @@ composer require --dev php-vcr/phpunit-testlistener-vcr ## Dependencies PHPUnit-Testlistener-VCR depends on: - * PHP 7.1+ + * PHP 8.1+ + * PHP 7.1+ (use <4.0) * PHP 7.0+ (use <3.0) + * PHPUnit 10+ + * PHPUnit <10 (use <4.0) * [php-vcr/php-vcr](https://github.com/php-vcr/php-vcr) ## Run tests diff --git a/composer.json b/composer.json index 5b213bd..cf44d52 100644 --- a/composer.json +++ b/composer.json @@ -20,9 +20,9 @@ }, "require": { "covergenius/php-vcr": "^1.7", - "php": "^7.4||^8.0" + "php": "^8.1" }, "require-dev": { - "phpunit/phpunit": "^8.0||^9.5.13" + "phpunit/phpunit": "^10.1" } } diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 29e3929..99cd6cf 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,16 +1,21 @@ - - - - src - - + ./tests - - - + + + diff --git a/src/Subscribers/BeforeTestEnds.php b/src/Subscribers/BeforeTestEnds.php new file mode 100644 index 0000000..45c3b46 --- /dev/null +++ b/src/Subscribers/BeforeTestEnds.php @@ -0,0 +1,20 @@ +getCassette($event->test()); + + if (empty($cassette)) { + return; + } + + // Use the JSON storage format if applicable + if (str_ends_with('.json', $cassette)) { + VCR::configure()->setStorage('json'); + } + + VCR::turnOn(); + VCR::insertCassette($cassette); + } + + /** + * @param Test $test + * @param string $tag + * @return string|null + * @throws \ReflectionException + */ + public function getCassette(Test $test, string $tag = '@vcr'): ?string + { + $reflection = new \ReflectionClass($test); + $class = $reflection->getProperty('className')->getValue($test); + $method = $test->name(); + + $reflection = new \ReflectionMethod($class, $method); + $docblock = $reflection->getDocComment(); + + if (!empty($docblock)) { + $parsed = self::parseDocBlock($docblock, $tag); + return array_pop($parsed); + } + + return null; + } + + /** + * @param string $docBlock + * @param string $tag + * @return array + */ + private static function parseDocBlock(string $docBlock, string $tag): array + { + $matches = []; + + if (empty($docBlock)) { + return $matches; + } + + $regex = "/{$tag} (.*)(\\r\\n|\\r|\\n)/U"; + preg_match_all($regex, $docBlock, $matches); + + if (empty($matches[1])) { + return array(); + } + + // Removed extra index + $matches = $matches[1]; + + // Trim the results, array item by array item + foreach ($matches as $ix => $match) { + $matches[$ix] = trim($match); + } + + return $matches; + } +} diff --git a/src/VCRTestListener.php b/src/VCRTestListener.php index 0c8cae2..374f971 100644 --- a/src/VCRTestListener.php +++ b/src/VCRTestListener.php @@ -3,22 +3,21 @@ namespace VCR\PHPUnit\TestListener; -use PHPUnit\Framework\AssertionFailedError; -use PHPUnit\Framework\Test; -use PHPUnit\Framework\TestCase; -use PHPUnit\Framework\TestListener; -use PHPUnit\Framework\TestSuite; -use PHPUnit\Framework\Warning; -use VCR\VCR; +use PHPUnit\Runner\Extension\Extension; +use PHPUnit\Runner\Extension\Facade; +use PHPUnit\Runner\Extension\ParameterCollection; +use PHPUnit\TextUI\Configuration\Configuration; +use VCR\PHPUnit\TestListener\Subscribers\BeforeTestEnds; +use VCR\PHPUnit\TestListener\Subscribers\OnTestPrepared; /** - * A TestListener that integrates with PHP-VCR. + * An extension that integrates with PHP-VCR. * - * Here is an example XML configuration for activating this listener: + * Here is an example XML configuration for activating this extension: * * - * - * + * + * * * * @@ -26,98 +25,19 @@ * @author Davide Borsatto * @author Renato Mefi */ -final class VCRTestListener implements TestListener +final class VCRTestListener implements Extension { - public function startTest(Test $test): void - { - $class = \get_class($test); - \assert($test instanceof TestCase); - $method = $test->getName(false); - - if (!method_exists($class, $method)) { - return; - } - - $reflection = new \ReflectionMethod($class, $method); - $docBlock = $reflection->getDocComment(); - - // Use regex to parse the doc_block for a specific annotation - $parsed = self::parseDocBlock($docBlock, '@vcr'); - $cassetteName = array_pop($parsed); - - if (empty($cassetteName)) { - return; - } - - // If the cassette name ends in .json, then use the JSON storage format - if (substr($cassetteName, -5) === '.json') { - VCR::configure()->setStorage('json'); - } - - VCR::turnOn(); - VCR::insertCassette($cassetteName); - } - - private static function parseDocBlock($docBlock, $tag): array - { - $matches = []; - - if (empty($docBlock)) { - return $matches; - } - - $regex = "/{$tag} (.*)(\\r\\n|\\r|\\n)/U"; - preg_match_all($regex, $docBlock, $matches); - - if (empty($matches[1])) { - return array(); - } - - // Removed extra index - $matches = $matches[1]; - - // Trim the results, array item by array item - foreach ($matches as $ix => $match) { - $matches[$ix] = trim($match); - } - - return $matches; - } - - public function endTest(Test $test, float $time): void - { - VCR::turnOff(); - } - - public function addError(Test $test, \Throwable $t, float $time): void - { - } - - public function addWarning(Test $test, Warning $e, float $time): void - { - } - - public function addFailure(Test $test, AssertionFailedError $e, float $time): void - { - } - - public function addIncompleteTest(Test $test, \Throwable $e, float $time): void - { - } - - public function addSkippedTest(Test $test, \Throwable $e, float $time): void - { - } - - public function addRiskyTest(Test $test, \Throwable $e, float $time): void - { - } - - public function startTestSuite(TestSuite $suite): void - { - } - - public function endTestSuite(TestSuite $suite): void - { + /** + * @param Configuration $configuration + * @param Facade $facade + * @param ParameterCollection $parameters + * @return void + */ + public function bootstrap(Configuration $configuration, Facade $facade, ParameterCollection $parameters): void + { + $facade->registerSubscribers( + new OnTestPrepared(), + new BeforeTestEnds(), + ); } } diff --git a/tests/VCRTestListenerTest.php b/tests/VCRTestListenerTest.php index 652d9bc..09c55bf 100644 --- a/tests/VCRTestListenerTest.php +++ b/tests/VCRTestListenerTest.php @@ -48,7 +48,10 @@ public function testNoVcrAnnotationRunsSuccessfulAndDoesNotProduceWarnings() $this->assertTrue(true, 'just adding an assertion here'); } - public function dummyDataProvider(): array + /** + * @return \int[][] + */ + public static function dummyDataProvider(): array { return [ [1],