13
13
14
14
use Doctrine \Common \Annotations \AnnotationRegistry ;
15
15
use PHPUnit \Framework \AssertionFailedError ;
16
+ use PHPUnit \Framework \RiskyTestError ;
16
17
use PHPUnit \Framework \TestCase ;
17
18
use PHPUnit \Framework \TestSuite ;
18
19
use PHPUnit \Runner \BaseTestRunner ;
19
20
use PHPUnit \Util \Blacklist ;
20
21
use PHPUnit \Util \Test ;
21
22
use Symfony \Bridge \PhpUnit \ClockMock ;
22
23
use Symfony \Bridge \PhpUnit \DnsMock ;
24
+ use Symfony \Bridge \PhpUnit \SymfonyExpectDeprecationTrait ;
23
25
use Symfony \Component \Debug \DebugClassLoader as LegacyDebugClassLoader ;
24
26
use Symfony \Component \ErrorHandler \DebugClassLoader ;
25
27
32
34
*/
33
35
class SymfonyTestsListenerTrait
34
36
{
37
+ public static $ expectedDeprecations = array ();
38
+ public static $ previousErrorHandler ;
39
+ private static $ gatheredDeprecations = array ();
35
40
private static $ globallyEnabled = false ;
36
41
private $ state = -1 ;
37
42
private $ skippedFile = false ;
38
43
private $ wasSkipped = array ();
39
44
private $ isSkipped = array ();
40
- private $ expectedDeprecations = array ();
41
- private $ gatheredDeprecations = array ();
42
- private $ previousErrorHandler ;
43
45
private $ reportUselessTests ;
44
- private $ error ;
45
46
private $ runsInSeparateProcess = false ;
47
+ private $ checkNumAssertions = false ;
46
48
47
49
/**
48
50
* @param array $mockedNamespaces List of namespaces, indexed by mocked features (time-sensitive or dns-sensitive)
@@ -221,15 +223,17 @@ public function startTest($test)
221
223
if (isset ($ annotations ['class ' ]['expectedDeprecation ' ])) {
222
224
$ test ->getTestResultObject ()->addError ($ test , new AssertionFailedError ('`@expectedDeprecation` annotations are not allowed at the class level. ' ), 0 );
223
225
}
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 ' ));
227
230
}
228
231
229
- $ test ->getTestResultObject ()->beStrictAboutTestsThatDoNotTestAnything (false );
232
+ if ($ this ->checkNumAssertions ) {
233
+ $ this ->checkNumAssertions = $ test ->getTestResultObject ()->isStrictAboutTestsThatDoNotTestAnything () && !$ test ->doesNotPerformAssertions ();
234
+ }
230
235
231
- $ this ->expectedDeprecations = $ annotations ['method ' ]['expectedDeprecation ' ];
232
- $ this ->previousErrorHandler = set_error_handler (array ($ this , 'handleError ' ));
236
+ $ test ->getTestResultObject ()->beStrictAboutTestsThatDoNotTestAnything (false );
233
237
}
234
238
}
235
239
}
@@ -243,16 +247,19 @@ public function endTest($test, $time)
243
247
$ className = \get_class ($ test );
244
248
$ groups = Test::getGroups ($ className , $ test ->getName (false ));
245
249
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
+
246
258
if (null !== $ this ->reportUselessTests ) {
247
259
$ test ->getTestResultObject ()->beStrictAboutTestsThatDoNotTestAnything ($ this ->reportUselessTests );
248
260
$ this ->reportUselessTests = null ;
249
261
}
250
262
251
- if ($ errored = null !== $ this ->error ) {
252
- $ test ->getTestResultObject ()->addError ($ test , $ this ->error , 0 );
253
- $ this ->error = null ;
254
- }
255
-
256
263
if ($ this ->runsInSeparateProcess ) {
257
264
$ deprecations = file_get_contents ($ this ->runsInSeparateProcess );
258
265
unlink ($ this ->runsInSeparateProcess );
@@ -269,24 +276,26 @@ public function endTest($test, $time)
269
276
$ this ->runsInSeparateProcess = false ;
270
277
}
271
278
272
- if ($ this -> expectedDeprecations ) {
279
+ if (self :: $ expectedDeprecations ) {
273
280
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 ));
275
282
}
276
283
277
284
restore_error_handler ();
278
285
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 )) {
280
289
try {
281
290
$ 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" );
283
292
} catch (AssertionFailedError $ e ) {
284
293
$ test ->getTestResultObject ()->addFailure ($ test , $ e , $ time );
285
294
}
286
295
}
287
296
288
- $ this -> expectedDeprecations = $ this -> gatheredDeprecations = array ();
289
- $ this -> previousErrorHandler = null ;
297
+ self :: $ expectedDeprecations = self :: $ gatheredDeprecations = array ();
298
+ self :: $ previousErrorHandler = null ;
290
299
}
291
300
if (!$ this ->runsInSeparateProcess && -2 < $ this ->state && ($ test instanceof \PHPUnit \Framework \TestCase || $ test instanceof TestCase)) {
292
301
if (\in_array ('time-sensitive ' , $ groups , true )) {
@@ -298,10 +307,10 @@ public function endTest($test, $time)
298
307
}
299
308
}
300
309
301
- public function handleError ($ type , $ msg , $ file , $ line , $ context = array ())
310
+ public static function handleError ($ type , $ msg , $ file , $ line , $ context = array ())
302
311
{
303
312
if (E_USER_DEPRECATED !== $ type && E_DEPRECATED !== $ type ) {
304
- $ h = $ this -> previousErrorHandler ;
313
+ $ h = self :: $ previousErrorHandler ;
305
314
306
315
return $ h ? $ h ($ type , $ msg , $ file , $ line , $ context ) : false ;
307
316
}
@@ -314,7 +323,7 @@ public function handleError($type, $msg, $file, $line, $context = array())
314
323
if (error_reporting ()) {
315
324
$ msg = 'Unsilenced deprecation: ' .$ msg ;
316
325
}
317
- $ this -> gatheredDeprecations [] = $ msg ;
326
+ self :: $ gatheredDeprecations [] = $ msg ;
318
327
319
328
return null ;
320
329
}
0 commit comments