Skip to content

Commit 0ccbb5e

Browse files
committed
feat: add extension for phpunit >= 10
1 parent e57a97f commit 0ccbb5e

5 files changed

+147
-51
lines changed

Diff for: src/Extension/TestFinishedSubscriber.php

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace VCR\PHPUnit\TestListener;
6+
7+
use PHPUnit\Event\Test\Finished;
8+
use PHPUnit\Event\Test\FinishedSubscriber;
9+
10+
final class TestFinishedSubscriber implements FinishedSubscriber
11+
{
12+
public function notify(Finished $event): void
13+
{
14+
VCRTestHandler::onEnd();
15+
}
16+
}

Diff for: src/Extension/TestPreparationStartedSubscriber.php

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace VCR\PHPUnit\TestListener;
6+
7+
use PHPUnit\Event\Code\TestMethod;
8+
use PHPUnit\Event\Test\PreparationStarted;
9+
use PHPUnit\Event\Test\PreparationStartedSubscriber;
10+
11+
final class TestPreparationStartedSubscriber implements PreparationStartedSubscriber
12+
{
13+
public function notify(PreparationStarted $event): void
14+
{
15+
$testMethod = $event->test();
16+
if (!$testMethod instanceof TestMethod) {
17+
return;
18+
}
19+
20+
VCRTestHandler::onStart($testMethod->className(), $testMethod->name());
21+
}
22+
}

Diff for: src/Extension/VCRExtension.php

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace VCR\PHPUnit\TestListener;
6+
7+
use PHPUnit\Runner\Extension\Extension;
8+
use PHPUnit\Runner\Extension\Facade;
9+
use PHPUnit\Runner\Extension\ParameterCollection;
10+
use PHPUnit\TextUI\Configuration\Configuration;
11+
12+
/**
13+
* An Extension that integrates with PHP-VCR.
14+
*
15+
* Here is an example XML configuration for activating this listener in PHPUnit >= 10.
16+
*
17+
* <code>
18+
* <extensions>
19+
* <bootstrap class="VCR\PHPUnit\TestListener\VcrExtension" />
20+
* </extensions>
21+
* </code>
22+
*/
23+
final class VCRExtension implements Extension
24+
{
25+
public function bootstrap(Configuration $configuration, Facade $facade, ParameterCollection $parameters): void
26+
{
27+
$facade->registerSubscribers(
28+
new TestPreparationStartedSubscriber(),
29+
new TestFinishedSubscriber()
30+
);
31+
}
32+
}

Diff for: src/VCRTestHandler.php

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace VCR\PHPUnit\TestListener;
5+
6+
use PHPUnit\Framework\AssertionFailedError;
7+
use PHPUnit\Framework\Test;
8+
use PHPUnit\Framework\TestCase;
9+
use PHPUnit\Framework\TestListener;
10+
use PHPUnit\Framework\TestSuite;
11+
use PHPUnit\Framework\Warning;
12+
use VCR\VCR;
13+
14+
final class VCRTestHandler
15+
{
16+
private function __construct() {}
17+
18+
public static function onStart(string $class, string $method): void
19+
{
20+
if (!method_exists($class, $method)) {
21+
return;
22+
}
23+
24+
$reflection = new \ReflectionMethod($class, $method);
25+
$docBlock = $reflection->getDocComment();
26+
27+
// Use regex to parse the doc_block for a specific annotation
28+
$parsed = self::parseDocBlock($docBlock, '@vcr');
29+
$cassetteName = array_pop($parsed);
30+
31+
if (empty($cassetteName)) {
32+
return;
33+
}
34+
35+
// If the cassette name ends in .json, then use the JSON storage format
36+
if (substr($cassetteName, -5) === '.json') {
37+
VCR::configure()->setStorage('json');
38+
}
39+
40+
VCR::turnOn();
41+
VCR::insertCassette($cassetteName);
42+
}
43+
44+
public static function onEnd(): void
45+
{
46+
VCR::turnOff();
47+
}
48+
49+
private static function parseDocBlock($docBlock, $tag): array
50+
{
51+
$matches = [];
52+
53+
if (empty($docBlock)) {
54+
return $matches;
55+
}
56+
57+
$regex = "/{$tag} (.*)(\\r\\n|\\r|\\n)/U";
58+
preg_match_all($regex, $docBlock, $matches);
59+
60+
if (empty($matches[1])) {
61+
return array();
62+
}
63+
64+
// Removed extra index
65+
$matches = $matches[1];
66+
67+
// Trim the results, array item by array item
68+
foreach ($matches as $ix => $match) {
69+
$matches[$ix] = trim($match);
70+
}
71+
72+
return $matches;
73+
}
74+
}

Diff for: src/VCRTestListener.php

+3-51
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
/**
1515
* A TestListener that integrates with PHP-VCR.
1616
*
17-
* Here is an example XML configuration for activating this listener:
17+
* Here is an example XML configuration for activating this listener in PHPUnit < 10.
1818
*
1919
* <code>
2020
* <listeners>
@@ -32,61 +32,13 @@ public function startTest(Test $test): void
3232
{
3333
$class = \get_class($test);
3434
\assert($test instanceof TestCase);
35-
$method = $test->getName(false);
3635

37-
if (!method_exists($class, $method)) {
38-
return;
39-
}
40-
41-
$reflection = new \ReflectionMethod($class, $method);
42-
$docBlock = $reflection->getDocComment();
43-
44-
// Use regex to parse the doc_block for a specific annotation
45-
$parsed = self::parseDocBlock($docBlock, '@vcr');
46-
$cassetteName = array_pop($parsed);
47-
48-
if (empty($cassetteName)) {
49-
return;
50-
}
51-
52-
// If the cassette name ends in .json, then use the JSON storage format
53-
if (substr($cassetteName, -5) === '.json') {
54-
VCR::configure()->setStorage('json');
55-
}
56-
57-
VCR::turnOn();
58-
VCR::insertCassette($cassetteName);
59-
}
60-
61-
private static function parseDocBlock($docBlock, $tag): array
62-
{
63-
$matches = [];
64-
65-
if (empty($docBlock)) {
66-
return $matches;
67-
}
68-
69-
$regex = "/{$tag} (.*)(\\r\\n|\\r|\\n)/U";
70-
preg_match_all($regex, $docBlock, $matches);
71-
72-
if (empty($matches[1])) {
73-
return array();
74-
}
75-
76-
// Removed extra index
77-
$matches = $matches[1];
78-
79-
// Trim the results, array item by array item
80-
foreach ($matches as $ix => $match) {
81-
$matches[$ix] = trim($match);
82-
}
83-
84-
return $matches;
36+
VCRTestHandler::onStart($class, $test->getName(false));
8537
}
8638

8739
public function endTest(Test $test, float $time): void
8840
{
89-
VCR::turnOff();
41+
VCRTestHandler::onEnd();
9042
}
9143

9244
public function addError(Test $test, \Throwable $t, float $time): void

0 commit comments

Comments
 (0)