Skip to content

Commit afbfcc0

Browse files
committed
fix 6102
1 parent e31113a commit afbfcc0

File tree

9 files changed

+242
-16
lines changed

9 files changed

+242
-16
lines changed

src/Event/Dispatcher/CollectingDispatcher.php

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
*/
1010
namespace PHPUnit\Event;
1111

12+
use PHPUnit\Runner\DeprecationCollector\Facade as DeprecationCollector;
13+
use PHPUnit\Runner\DeprecationCollector\TestTriggeredDeprecationSubscriber;
14+
1215
/**
1316
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
1417
*
@@ -17,15 +20,25 @@
1720
final class CollectingDispatcher implements Dispatcher
1821
{
1922
private EventCollection $events;
23+
private DirectDispatcher $isolatedDirectDispatcher;
2024

21-
public function __construct()
25+
public function __construct(DirectDispatcher $directDispatcher)
2226
{
23-
$this->events = new EventCollection;
27+
$this->isolatedDirectDispatcher = $directDispatcher;
28+
$this->events = new EventCollection;
29+
30+
$this->isolatedDirectDispatcher->registerSubscriber(new TestTriggeredDeprecationSubscriber(DeprecationCollector::collector()));
2431
}
2532

2633
public function dispatch(Event $event): void
2734
{
2835
$this->events->add($event);
36+
37+
try {
38+
$this->isolatedDirectDispatcher->dispatch($event);
39+
} catch (UnknownEventTypeException) {
40+
// Do nothing.
41+
}
2942
}
3043

3144
public function flush(): EventCollection

src/Event/Facade.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use PHPUnit\Event\Telemetry\HRTime;
1717
use PHPUnit\Event\Telemetry\Php81GarbageCollectorStatusProvider;
1818
use PHPUnit\Event\Telemetry\Php83GarbageCollectorStatusProvider;
19+
use PHPUnit\Runner\DeprecationCollector\Facade as DeprecationCollector;
1920

2021
/**
2122
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
@@ -92,7 +93,11 @@ public function registerTracer(Tracer\Tracer $tracer): void
9293
*/
9394
public function initForIsolation(HRTime $offset): CollectingDispatcher
9495
{
95-
$dispatcher = new CollectingDispatcher;
96+
DeprecationCollector::initForIsolation();
97+
98+
$dispatcher = new CollectingDispatcher(
99+
new DirectDispatcher($this->typeMap()),
100+
);
96101

97102
$this->emitter = new DispatchingEmitter(
98103
$dispatcher,

src/Runner/DeprecationCollector/Facade.php

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
*/
2323
final class Facade
2424
{
25-
private static ?Collector $collector = null;
25+
private static null|Collector|InIsolationCollector $collector = null;
26+
private static bool $inIsolation = false;
2627

2728
/**
2829
* @throws EventFacadeIsSealedException
@@ -33,6 +34,12 @@ public static function init(): void
3334
self::collector();
3435
}
3536

37+
public static function initForIsolation(): void
38+
{
39+
self::$inIsolation = true;
40+
self::collector();
41+
}
42+
3643
/**
3744
* @throws EventFacadeIsSealedException
3845
* @throws UnknownSubscriberTypeException
@@ -59,15 +66,23 @@ public static function filteredDeprecations(): array
5966
* @throws EventFacadeIsSealedException
6067
* @throws UnknownSubscriberTypeException
6168
*/
62-
private static function collector(): Collector
69+
public static function collector(): Collector|InIsolationCollector
6370
{
6471
if (self::$collector === null) {
65-
self::$collector = new Collector(
66-
EventFacade::instance(),
67-
new IssueFilter(
68-
ConfigurationRegistry::get()->source(),
69-
),
70-
);
72+
if (self::$inIsolation) {
73+
self::$collector = new InIsolationCollector(
74+
new IssueFilter(
75+
ConfigurationRegistry::get()->source(),
76+
),
77+
);
78+
} else {
79+
self::$collector = new Collector(
80+
EventFacade::instance(),
81+
new IssueFilter(
82+
ConfigurationRegistry::get()->source(),
83+
),
84+
);
85+
}
7186
}
7287

7388
return self::$collector;
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php declare(strict_types=1);
2+
/*
3+
* This file is part of PHPUnit.
4+
*
5+
* (c) Sebastian Bergmann <[email protected]>
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
namespace PHPUnit\Runner\DeprecationCollector;
11+
12+
use PHPUnit\Event\Test\DeprecationTriggered;
13+
use PHPUnit\TestRunner\IssueFilter;
14+
15+
/**
16+
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
17+
*
18+
* @internal This class is not covered by the backward compatibility promise for PHPUnit
19+
*/
20+
final class InIsolationCollector
21+
{
22+
private readonly IssueFilter $issueFilter;
23+
24+
/**
25+
* @var list<non-empty-string>
26+
*/
27+
private array $deprecations = [];
28+
29+
/**
30+
* @var list<non-empty-string>
31+
*/
32+
private array $filteredDeprecations = [];
33+
34+
public function __construct(IssueFilter $issueFilter)
35+
{
36+
$this->issueFilter = $issueFilter;
37+
}
38+
39+
/**
40+
* @return list<non-empty-string>
41+
*/
42+
public function deprecations(): array
43+
{
44+
return $this->deprecations;
45+
}
46+
47+
/**
48+
* @return list<non-empty-string>
49+
*/
50+
public function filteredDeprecations(): array
51+
{
52+
return $this->filteredDeprecations;
53+
}
54+
55+
public function testTriggeredDeprecation(DeprecationTriggered $event): void
56+
{
57+
$this->deprecations[] = $event->message();
58+
59+
if (!$this->issueFilter->shouldBeProcessed($event)) {
60+
return;
61+
}
62+
63+
$this->filteredDeprecations[] = $event->message();
64+
}
65+
}

src/Runner/DeprecationCollector/Subscriber/Subscriber.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@
1616
*/
1717
abstract class Subscriber
1818
{
19-
private readonly Collector $collector;
19+
private readonly Collector|InIsolationCollector $collector;
2020

21-
public function __construct(Collector $collector)
21+
public function __construct(Collector|InIsolationCollector $collector)
2222
{
2323
$this->collector = $collector;
2424
}
2525

26-
protected function collector(): Collector
26+
protected function collector(): Collector|InIsolationCollector
2727
{
2828
return $this->collector;
2929
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php declare(strict_types=1);
2+
/*
3+
* This file is part of PHPUnit.
4+
*
5+
* (c) Sebastian Bergmann <[email protected]>
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
namespace PHPUnit\TestFixture\Event;
11+
12+
use const E_USER_DEPRECATED;
13+
use function trigger_error;
14+
use PHPUnit\Framework\Attributes\IgnoreDeprecations;
15+
use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
16+
use PHPUnit\Framework\TestCase;
17+
18+
#[RunTestsInSeparateProcesses]
19+
final class TestForDeprecatedFeatureInIsolationTest extends TestCase
20+
{
21+
#[IgnoreDeprecations]
22+
public function testExpectationOnExactDeprecationMessageWorksWhenExpectedDeprecationIsTriggered(): void
23+
{
24+
$this->expectUserDeprecationMessage('message');
25+
26+
@trigger_error('message', E_USER_DEPRECATED);
27+
}
28+
29+
#[IgnoreDeprecations]
30+
public function testExpectationsOnExactDeprecationMessagesWorkWhenExpectedDeprecationsAreTriggered(): void
31+
{
32+
$this->expectUserDeprecationMessage('message');
33+
$this->expectUserDeprecationMessage('another message');
34+
35+
@trigger_error('message', E_USER_DEPRECATED);
36+
@trigger_error('another message', E_USER_DEPRECATED);
37+
}
38+
39+
#[IgnoreDeprecations]
40+
public function testExpectationOnExactDeprecationMessageWorksWhenExpectedDeprecationIsNotTriggered(): void
41+
{
42+
$this->expectUserDeprecationMessage('message');
43+
}
44+
45+
#[IgnoreDeprecations]
46+
public function testExpectationOnExactDeprecationMessageWorksWhenUnexpectedDeprecationIsTriggered(): void
47+
{
48+
$this->expectUserDeprecationMessage('message');
49+
50+
@trigger_error('another message', E_USER_DEPRECATED);
51+
}
52+
53+
#[IgnoreDeprecations]
54+
public function testExpectationOnDeprecationMessageMatchingRegularExpressionWorksWhenExpectedDeprecationIsTriggered(): void
55+
{
56+
$this->expectUserDeprecationMessageMatches('/message/');
57+
58+
@trigger_error('...message...', E_USER_DEPRECATED);
59+
}
60+
61+
#[IgnoreDeprecations]
62+
public function testExpectationsOnDeprecationMessagesMatchingRegularExpressionsWorkWhenExpectedDeprecationsAreTriggered(): void
63+
{
64+
$this->expectUserDeprecationMessageMatches('/foo/');
65+
$this->expectUserDeprecationMessageMatches('/bar/');
66+
67+
@trigger_error('...foo...', E_USER_DEPRECATED);
68+
@trigger_error('...bar...', E_USER_DEPRECATED);
69+
}
70+
71+
#[IgnoreDeprecations]
72+
public function testExpectationOnDeprecationMessageMatchingRegularExpressionWorksWhenExpectedDeprecationIsNotTriggered(): void
73+
{
74+
$this->expectUserDeprecationMessageMatches('/message/');
75+
}
76+
77+
#[IgnoreDeprecations]
78+
public function testExpectationOnDeprecationMessageMatchingRegularExpressionWorksWhenUnepectedDeprecationIsTriggered(): void
79+
{
80+
$this->expectUserDeprecationMessageMatches('/message/');
81+
82+
@trigger_error('something else', E_USER_DEPRECATED);
83+
}
84+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
--TEST--
2+
https://github.com/sebastianbergmann/phpunit/issues/6102
3+
--XFAIL--
4+
https://github.com/sebastianbergmann/phpunit/issues/6102
5+
--FILE--
6+
<?php declare(strict_types=1);
7+
$_SERVER['argv'][] = '--do-not-cache-result';
8+
$_SERVER['argv'][] = '--no-configuration';
9+
$_SERVER['argv'][] = __DIR__ . '/../../end-to-end/generic/_files/TestForDeprecatedFeatureInIsolationTest.php';
10+
11+
require __DIR__ . '/../../bootstrap.php';
12+
13+
(new PHPUnit\TextUI\Application)->run($_SERVER['argv']);
14+
--EXPECTF--
15+
PHPUnit %s by Sebastian Bergmann and contributors.
16+
17+
Runtime: %s
18+
19+
..FF..FF 8 / 8 (100%)
20+
21+
Time: %s, Memory: %s
22+
23+
There were 4 failures:
24+
25+
1) PHPUnit\TestFixture\Event\TestForDeprecatedFeatureInIsolationTest::testExpectationOnExactDeprecationMessageWorksWhenExpectedDeprecationIsNotTriggered
26+
Expected deprecation with message "message" was not triggered
27+
28+
2) PHPUnit\TestFixture\Event\TestForDeprecatedFeatureInIsolationTest::testExpectationOnExactDeprecationMessageWorksWhenUnexpectedDeprecationIsTriggered
29+
Expected deprecation with message "message" was not triggered
30+
31+
3) PHPUnit\TestFixture\Event\TestForDeprecatedFeatureInIsolationTest::testExpectationOnDeprecationMessageMatchingRegularExpressionWorksWhenExpectedDeprecationIsNotTriggered
32+
Expected deprecation with message matching regular expression "/message/" was not triggered
33+
34+
4) PHPUnit\TestFixture\Event\TestForDeprecatedFeatureInIsolationTest::testExpectationOnDeprecationMessageMatchingRegularExpressionWorksWhenUnepectedDeprecationIsTriggered
35+
Expected deprecation with message matching regular expression "/message/" was not triggered
36+
37+
FAILURES!
38+
Tests: 8, Assertions: 10, Failures: 4.

tests/unit/Event/Dispatcher/CollectingDispatcherTest.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,20 @@ final class CollectingDispatcherTest extends TestCase
1919
{
2020
public function testHasNoCollectedEventsWhenFlushedImmediatelyAfterCreation(): void
2121
{
22-
$dispatcher = new CollectingDispatcher;
22+
$typeMap = new TypeMap;
23+
$typeMap->addMapping(Test\DeprecationTriggeredSubscriber::class, Test\DeprecationTriggered::class);
24+
25+
$dispatcher = new CollectingDispatcher(new DirectDispatcher($typeMap));
2326

2427
$this->assertEmpty($dispatcher->flush());
2528
}
2629

2730
public function testCollectsDispatchedEventsUntilFlushed(): void
2831
{
29-
$dispatcher = new CollectingDispatcher;
32+
$typeMap = new TypeMap;
33+
$typeMap->addMapping(Test\DeprecationTriggeredSubscriber::class, Test\DeprecationTriggered::class);
34+
35+
$dispatcher = new CollectingDispatcher(new DirectDispatcher($typeMap));
3036
$event = $this->createStub(Event::class);
3137

3238
$dispatcher->dispatch($event);

0 commit comments

Comments
 (0)