Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 19e3d1f

Browse files
committed
[PhpUnitBridge] Add the ability to expect a deprecation inside a test
1 parent b350c80 commit 19e3d1f

File tree

4 files changed

+141
-25
lines changed

4 files changed

+141
-25
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ install:
195195
# To run a PR with a patched phpunit-bridge, first submit the patch for the
196196
# phpunit-bridge as a separate PR against the next feature-branch then
197197
# uncomment and update the following line with that PR number
198-
#SYMFONY_PHPUNIT_BRIDGE_PR=32886
198+
SYMFONY_PHPUNIT_BRIDGE_PR=35192
199199
200200
if [[ $SYMFONY_PHPUNIT_BRIDGE_PR ]]; then
201201
git fetch --depth=2 origin refs/pull/$SYMFONY_PHPUNIT_BRIDGE_PR/head

src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@
1313

1414
use Doctrine\Common\Annotations\AnnotationRegistry;
1515
use PHPUnit\Framework\AssertionFailedError;
16+
use PHPUnit\Framework\RiskyTestError;
1617
use PHPUnit\Framework\TestCase;
1718
use PHPUnit\Framework\TestSuite;
1819
use PHPUnit\Runner\BaseTestRunner;
1920
use PHPUnit\Util\Blacklist;
2021
use PHPUnit\Util\Test;
2122
use Symfony\Bridge\PhpUnit\ClockMock;
2223
use Symfony\Bridge\PhpUnit\DnsMock;
24+
use Symfony\Bridge\PhpUnit\SymfonyExpectDeprecationTrait;
2325
use Symfony\Component\Debug\DebugClassLoader as LegacyDebugClassLoader;
2426
use Symfony\Component\ErrorHandler\DebugClassLoader;
2527

@@ -32,17 +34,17 @@
3234
*/
3335
class SymfonyTestsListenerTrait
3436
{
37+
public static $expectedDeprecations = array();
38+
public static $previousErrorHandler;
39+
private static $gatheredDeprecations = array();
3540
private static $globallyEnabled = false;
3641
private $state = -1;
3742
private $skippedFile = false;
3843
private $wasSkipped = array();
3944
private $isSkipped = array();
40-
private $expectedDeprecations = array();
41-
private $gatheredDeprecations = array();
42-
private $previousErrorHandler;
4345
private $reportUselessTests;
44-
private $error;
4546
private $runsInSeparateProcess = false;
47+
private $checkNumAssertions = false;
4648

4749
/**
4850
* @param array $mockedNamespaces List of namespaces, indexed by mocked features (time-sensitive or dns-sensitive)
@@ -221,15 +223,17 @@ public function startTest($test)
221223
if (isset($annotations['class']['expectedDeprecation'])) {
222224
$test->getTestResultObject()->addError($test, new AssertionFailedError('`@expectedDeprecation` annotations are not allowed at the class level.'), 0);
223225
}
224-
if (isset($annotations['method']['expectedDeprecation'])) {
225-
if (!\in_array('legacy', $groups, true)) {
226-
$this->error = new AssertionFailedError('Only tests with the `@group legacy` annotation can have `@expectedDeprecation`.');
226+
if (($hasExpectedDeprecationAnnotation = isset($annotations['method']['expectedDeprecation'])) || $this->checkNumAssertions = \in_array(SymfonyExpectDeprecationTrait::class, (new \ReflectionClass($test))->getTraitNames(), true)) {
227+
if ($hasExpectedDeprecationAnnotation) {
228+
self::$expectedDeprecations = $annotations['method']['expectedDeprecation'];
229+
self::$previousErrorHandler = set_error_handler(array($this, 'handleError'));
227230
}
228231

229-
$test->getTestResultObject()->beStrictAboutTestsThatDoNotTestAnything(false);
232+
if ($this->checkNumAssertions) {
233+
$this->checkNumAssertions = $test->getTestResultObject()->isStrictAboutTestsThatDoNotTestAnything() && !$test->doesNotPerformAssertions();
234+
}
230235

231-
$this->expectedDeprecations = $annotations['method']['expectedDeprecation'];
232-
$this->previousErrorHandler = set_error_handler(array($this, 'handleError'));
236+
$test->getTestResultObject()->beStrictAboutTestsThatDoNotTestAnything(false);
233237
}
234238
}
235239
}
@@ -243,16 +247,19 @@ public function endTest($test, $time)
243247
$className = \get_class($test);
244248
$groups = Test::getGroups($className, $test->getName(false));
245249

250+
if ($this->checkNumAssertions && !self::$expectedDeprecations) {
251+
if (0 === $test->getNumAssertions()) {
252+
$test->getTestResultObject()->addFailure($test, new RiskyTestError('This test did not perform any assertions'), $time);
253+
}
254+
255+
$this->checkNumAssertions = false;
256+
}
257+
246258
if (null !== $this->reportUselessTests) {
247259
$test->getTestResultObject()->beStrictAboutTestsThatDoNotTestAnything($this->reportUselessTests);
248260
$this->reportUselessTests = null;
249261
}
250262

251-
if ($errored = null !== $this->error) {
252-
$test->getTestResultObject()->addError($test, $this->error, 0);
253-
$this->error = null;
254-
}
255-
256263
if ($this->runsInSeparateProcess) {
257264
$deprecations = file_get_contents($this->runsInSeparateProcess);
258265
unlink($this->runsInSeparateProcess);
@@ -269,24 +276,26 @@ public function endTest($test, $time)
269276
$this->runsInSeparateProcess = false;
270277
}
271278

272-
if ($this->expectedDeprecations) {
279+
if (self::$expectedDeprecations) {
273280
if (!\in_array($test->getStatus(), array(BaseTestRunner::STATUS_SKIPPED, BaseTestRunner::STATUS_INCOMPLETE), true)) {
274-
$test->addToAssertionCount(\count($this->expectedDeprecations));
281+
$test->addToAssertionCount(\count(self::$expectedDeprecations));
275282
}
276283

277284
restore_error_handler();
278285

279-
if (!$errored && !\in_array($test->getStatus(), array(BaseTestRunner::STATUS_SKIPPED, BaseTestRunner::STATUS_INCOMPLETE, BaseTestRunner::STATUS_FAILURE, BaseTestRunner::STATUS_ERROR), true)) {
286+
if (!\in_array('legacy', $groups, true)) {
287+
$test->getTestResultObject()->addError($test, new AssertionFailedError('Only tests with the `@group legacy` annotation can expect a deprecation.'), 0);
288+
} elseif (!\in_array($test->getStatus(), array(BaseTestRunner::STATUS_SKIPPED, BaseTestRunner::STATUS_INCOMPLETE, BaseTestRunner::STATUS_FAILURE, BaseTestRunner::STATUS_ERROR), true)) {
280289
try {
281290
$prefix = "@expectedDeprecation:\n";
282-
$test->assertStringMatchesFormat($prefix.'%A '.implode("\n%A ", $this->expectedDeprecations)."\n%A", $prefix.' '.implode("\n ", $this->gatheredDeprecations)."\n");
291+
$test->assertStringMatchesFormat($prefix.'%A '.implode("\n%A ", self::$expectedDeprecations)."\n%A", $prefix.' '.implode("\n ", self::$gatheredDeprecations)."\n");
283292
} catch (AssertionFailedError $e) {
284293
$test->getTestResultObject()->addFailure($test, $e, $time);
285294
}
286295
}
287296

288-
$this->expectedDeprecations = $this->gatheredDeprecations = array();
289-
$this->previousErrorHandler = null;
297+
self::$expectedDeprecations = self::$gatheredDeprecations = array();
298+
self::$previousErrorHandler = null;
290299
}
291300
if (!$this->runsInSeparateProcess && -2 < $this->state && ($test instanceof \PHPUnit\Framework\TestCase || $test instanceof TestCase)) {
292301
if (\in_array('time-sensitive', $groups, true)) {
@@ -298,10 +307,10 @@ public function endTest($test, $time)
298307
}
299308
}
300309

301-
public function handleError($type, $msg, $file, $line, $context = array())
310+
public static function handleError($type, $msg, $file, $line, $context = array())
302311
{
303312
if (E_USER_DEPRECATED !== $type && E_DEPRECATED !== $type) {
304-
$h = $this->previousErrorHandler;
313+
$h = self::$previousErrorHandler;
305314

306315
return $h ? $h($type, $msg, $file, $line, $context) : false;
307316
}
@@ -314,7 +323,7 @@ public function handleError($type, $msg, $file, $line, $context = array())
314323
if (error_reporting()) {
315324
$msg = 'Unsilenced deprecation: '.$msg;
316325
}
317-
$this->gatheredDeprecations[] = $msg;
326+
self::$gatheredDeprecations[] = $msg;
318327

319328
return null;
320329
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\PhpUnit;
13+
14+
use Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait;
15+
16+
trait SymfonyExpectDeprecationTrait
17+
{
18+
/**
19+
* @param string $message
20+
*
21+
* @return void
22+
*/
23+
private function expectDeprecation($message)
24+
{
25+
if (!SymfonyTestsListenerTrait::$previousErrorHandler) {
26+
SymfonyTestsListenerTrait::$previousErrorHandler = set_error_handler(array(SymfonyTestsListenerTrait::class, 'handleError'));
27+
}
28+
29+
SymfonyTestsListenerTrait::$expectedDeprecations[] = $message;
30+
}
31+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\PhpUnit\Tests;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Bridge\PhpUnit\SymfonyExpectDeprecationTrait;
16+
17+
final class SymfonyExpectDeprecationTraitTest extends TestCase
18+
{
19+
use SymfonyExpectDeprecationTrait;
20+
21+
/**
22+
* Do not remove this test in the next major version.
23+
*
24+
* @group legacy
25+
*/
26+
public function testOne()
27+
{
28+
$this->expectDeprecation('foo');
29+
@trigger_error('foo', E_USER_DEPRECATED);
30+
}
31+
32+
/**
33+
* Do not remove this test in the next major version.
34+
*
35+
* @group legacy
36+
*/
37+
public function testMany()
38+
{
39+
$this->expectDeprecation('foo');
40+
$this->expectDeprecation('bar');
41+
@trigger_error('foo', E_USER_DEPRECATED);
42+
@trigger_error('bar', E_USER_DEPRECATED);
43+
}
44+
45+
/**
46+
* Do not remove this test in the next major version.
47+
*
48+
* @group legacy
49+
*
50+
* @expectedDeprecation foo
51+
*/
52+
public function testOneWithAnnotation()
53+
{
54+
$this->expectDeprecation('bar');
55+
@trigger_error('foo', E_USER_DEPRECATED);
56+
@trigger_error('bar', E_USER_DEPRECATED);
57+
}
58+
59+
/**
60+
* Do not remove this test in the next major version.
61+
*
62+
* @group legacy
63+
*
64+
* @expectedDeprecation foo
65+
* @expectedDeprecation bar
66+
*/
67+
public function testManyWithAnnotation()
68+
{
69+
$this->expectDeprecation('ccc');
70+
$this->expectDeprecation('fcy');
71+
@trigger_error('foo', E_USER_DEPRECATED);
72+
@trigger_error('bar', E_USER_DEPRECATED);
73+
@trigger_error('ccc', E_USER_DEPRECATED);
74+
@trigger_error('fcy', E_USER_DEPRECATED);
75+
}
76+
}

0 commit comments

Comments
 (0)