Skip to content

Commit ef80a8d

Browse files
Closes #5605
1 parent a958ff3 commit ef80a8d

File tree

10 files changed

+379
-0
lines changed

10 files changed

+379
-0
lines changed

ChangeLog-11.0.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ All notable changes of the PHPUnit 11.0 release series are documented in this fi
77
### Added
88

99
* [#5600](https://github.com/sebastianbergmann/phpunit/pull/5600): Assertions for comparing arrays while ignoring a specified list of keys
10+
* [#5605](https://github.com/sebastianbergmann/phpunit/pull/5605): `expectUserDeprecationMessage()` and `expectUserDeprecationMessageMatches()` for expecting `E_USER_DEPRECATED` issues
1011

1112
### Changed
1213

src/Framework/TestCase.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
use function ob_start;
4848
use function parse_url;
4949
use function pathinfo;
50+
use function preg_match;
5051
use function preg_replace;
5152
use function setlocale;
5253
use function sprintf;
@@ -84,6 +85,7 @@
8485
use PHPUnit\Metadata\Api\HookMethods;
8586
use PHPUnit\Metadata\Api\Requirements;
8687
use PHPUnit\Metadata\Parser\Registry as MetadataRegistry;
88+
use PHPUnit\Runner\DeprecationCollector\Facade as DeprecationCollector;
8789
use PHPUnit\TestRunner\TestResult\PassedTests;
8890
use PHPUnit\TextUI\Configuration\Registry as ConfigurationRegistry;
8991
use PHPUnit\Util\Test as TestUtil;
@@ -188,6 +190,16 @@ abstract class TestCase extends Assert implements Reorderable, SelfDescribing, T
188190
*/
189191
private array $failureTypes = [];
190192

193+
/**
194+
* @psalm-var list<non-empty-string>
195+
*/
196+
private array $expectedUserDeprecationMessage = [];
197+
198+
/**
199+
* @psalm-var list<non-empty-string>
200+
*/
201+
private array $expectedUserDeprecationMessageRegularExpression = [];
202+
191203
/**
192204
* @psalm-param non-empty-string $name
193205
*
@@ -446,6 +458,7 @@ final public function runBare(): void
446458
$this->wasPrepared = true;
447459
$this->testResult = $this->runTest();
448460

461+
$this->verifyDeprecationExpectations();
449462
$this->verifyMockObjects();
450463
$this->invokePostConditionHookMethods($hookMethods, $emitter);
451464

@@ -1080,6 +1093,22 @@ final protected function expectNotToPerformAssertions(): void
10801093
$this->doesNotPerformAssertions = true;
10811094
}
10821095

1096+
/**
1097+
* @psalm-param non-empty-string $expectedUserDeprecationMessage
1098+
*/
1099+
final protected function expectUserDeprecationMessage(string $expectedUserDeprecationMessage): void
1100+
{
1101+
$this->expectedUserDeprecationMessage[] = $expectedUserDeprecationMessage;
1102+
}
1103+
1104+
/**
1105+
* @psalm-param non-empty-string $expectedUserDeprecationMessageRegularExpression
1106+
*/
1107+
final protected function expectUserDeprecationMessageMatches(string $expectedUserDeprecationMessageRegularExpression): void
1108+
{
1109+
$this->expectedUserDeprecationMessageRegularExpression[] = $expectedUserDeprecationMessageRegularExpression;
1110+
}
1111+
10831112
/**
10841113
* Returns a builder object to create mock objects using a fluent interface.
10851114
*
@@ -1535,6 +1564,48 @@ protected function onNotSuccessfulTest(Throwable $t): never
15351564
throw $t;
15361565
}
15371566

1567+
/**
1568+
* @throws ExpectationFailedException
1569+
*/
1570+
private function verifyDeprecationExpectations(): void
1571+
{
1572+
foreach ($this->expectedUserDeprecationMessage as $deprecationExpectation) {
1573+
$this->numberOfAssertionsPerformed++;
1574+
1575+
if (!in_array($deprecationExpectation, DeprecationCollector::deprecations(), true)) {
1576+
throw new ExpectationFailedException(
1577+
sprintf(
1578+
'Expected deprecation with message "%s" was not triggered',
1579+
$deprecationExpectation,
1580+
),
1581+
);
1582+
}
1583+
}
1584+
1585+
foreach ($this->expectedUserDeprecationMessageRegularExpression as $deprecationExpectation) {
1586+
$this->numberOfAssertionsPerformed++;
1587+
1588+
$expectedDeprecationTriggered = false;
1589+
1590+
foreach (DeprecationCollector::deprecations() as $deprecation) {
1591+
if (@preg_match($deprecationExpectation, $deprecation) > 0) {
1592+
$expectedDeprecationTriggered = true;
1593+
1594+
break;
1595+
}
1596+
}
1597+
1598+
if (!$expectedDeprecationTriggered) {
1599+
throw new ExpectationFailedException(
1600+
sprintf(
1601+
'Expected deprecation with message matching regular expression "%s" was not triggered',
1602+
$deprecationExpectation,
1603+
),
1604+
);
1605+
}
1606+
}
1607+
}
1608+
15381609
/**
15391610
* @throws Throwable
15401611
*/
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
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\EventFacadeIsSealedException;
13+
use PHPUnit\Event\Facade;
14+
use PHPUnit\Event\Test\DeprecationTriggered;
15+
use PHPUnit\Event\UnknownSubscriberTypeException;
16+
17+
/**
18+
* @internal This class is not covered by the backward compatibility promise for PHPUnit
19+
*/
20+
final class Collector
21+
{
22+
/**
23+
* @psalm-var list<non-empty-string>
24+
*/
25+
private array $deprecations = [];
26+
27+
/**
28+
* @throws EventFacadeIsSealedException
29+
* @throws UnknownSubscriberTypeException
30+
*/
31+
public function __construct(Facade $facade)
32+
{
33+
$facade->registerSubscribers(
34+
new TestPreparedSubscriber($this),
35+
new TestTriggeredDeprecationSubscriber($this),
36+
);
37+
}
38+
39+
/**
40+
* @psalm-return list<non-empty-string>
41+
*/
42+
public function deprecations(): array
43+
{
44+
return $this->deprecations;
45+
}
46+
47+
public function testPrepared(): void
48+
{
49+
$this->deprecations = [];
50+
}
51+
52+
public function testTriggeredDeprecation(DeprecationTriggered $event): void
53+
{
54+
$this->deprecations[] = $event->message();
55+
}
56+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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\EventFacadeIsSealedException;
13+
use PHPUnit\Event\Facade as EventFacade;
14+
use PHPUnit\Event\UnknownSubscriberTypeException;
15+
16+
/**
17+
* @internal This class is not covered by the backward compatibility promise for PHPUnit
18+
*/
19+
final class Facade
20+
{
21+
private static ?Collector $collector = null;
22+
23+
/**
24+
* @throws EventFacadeIsSealedException
25+
* @throws UnknownSubscriberTypeException
26+
*/
27+
public static function init(): void
28+
{
29+
self::collector();
30+
}
31+
32+
/**
33+
* @psalm-return list<non-empty-string>
34+
*
35+
* @throws EventFacadeIsSealedException
36+
* @throws UnknownSubscriberTypeException
37+
*/
38+
public static function deprecations(): array
39+
{
40+
return self::collector()->deprecations();
41+
}
42+
43+
/**
44+
* @throws EventFacadeIsSealedException
45+
* @throws UnknownSubscriberTypeException
46+
*/
47+
private static function collector(): Collector
48+
{
49+
if (self::$collector === null) {
50+
self::$collector = new Collector(EventFacade::instance());
51+
}
52+
53+
return self::$collector;
54+
}
55+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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+
/**
13+
* @internal This class is not covered by the backward compatibility promise for PHPUnit
14+
*/
15+
abstract class Subscriber
16+
{
17+
private readonly Collector $collector;
18+
19+
public function __construct(Collector $collector)
20+
{
21+
$this->collector = $collector;
22+
}
23+
24+
protected function collector(): Collector
25+
{
26+
return $this->collector;
27+
}
28+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
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\Prepared;
13+
use PHPUnit\Event\Test\PreparedSubscriber;
14+
15+
/**
16+
* @internal This class is not covered by the backward compatibility promise for PHPUnit
17+
*/
18+
final class TestPreparedSubscriber extends Subscriber implements PreparedSubscriber
19+
{
20+
public function notify(Prepared $event): void
21+
{
22+
$this->collector()->testPrepared();
23+
}
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
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\Event\Test\DeprecationTriggeredSubscriber;
14+
15+
/**
16+
* @internal This class is not covered by the backward compatibility promise for PHPUnit
17+
*/
18+
final class TestTriggeredDeprecationSubscriber extends Subscriber implements DeprecationTriggeredSubscriber
19+
{
20+
public function notify(DeprecationTriggered $event): void
21+
{
22+
$this->collector()->testTriggeredDeprecation($event);
23+
}
24+
}

src/TextUI/Application.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
use PHPUnit\Runner\Baseline\Reader;
3333
use PHPUnit\Runner\Baseline\Writer;
3434
use PHPUnit\Runner\CodeCoverage;
35+
use PHPUnit\Runner\DeprecationCollector\Facade as DeprecationCollector;
3536
use PHPUnit\Runner\ErrorHandler;
3637
use PHPUnit\Runner\Extension\ExtensionBootstrapper;
3738
use PHPUnit\Runner\Extension\Facade as ExtensionFacade;
@@ -154,6 +155,7 @@ public function run(array $argv): int
154155
$testDoxResultCollector = $this->testDoxResultCollector($configuration);
155156

156157
TestResultFacade::init();
158+
DeprecationCollector::init();
157159

158160
$resultCache = $this->initializeTestResultCache($configuration);
159161

0 commit comments

Comments
 (0)