@@ -37,6 +37,15 @@ abstract class AsyncTestCase extends PHPUnitTestCase
3737 /** @var \Generator|null */
3838 private $ generator ;
3939
40+ /** @var int|null */
41+ private $ timeout ;
42+
43+ final protected function runTest ()
44+ {
45+ parent ::setName ('runAsyncTest ' );
46+ return parent ::runTest ();
47+ }
48+
4049 /** @internal */
4150 final public function runAsyncTest (...$ args )
4251 {
@@ -61,6 +70,28 @@ final public function runAsyncTest(...$args)
6170 $ invoked = true ;
6271 $ exception = $ error ;
6372 $ returnValue = $ value ;
73+
74+ if ($ this ->timeout === null ) {
75+ Loop::unreference (Loop::defer (function () use ($ exception ) {
76+ Loop::stop ();
77+
78+ if ($ exception ) {
79+ $ this ->fail (\sprintf (
80+ 'An exception was thrown from the test method or promise returned from test method failed, '
81+ . ' but the event loop continued to run; set a timeout with %s::setTimeout() to allow the loop to continue '
82+ . ' to run for a given period of time; Exception thrown: %s ' ,
83+ self ::class,
84+ $ exception
85+ ));
86+ }
87+
88+ $ this ->fail (\sprintf (
89+ 'The event loop continued to run after the test method completed or the promise returned resolved; '
90+ . ' set a timeout with %s::setTimeout() to allow the loop to continue to run for a given period of time ' ,
91+ self ::class
92+ ));
93+ }));
94+ }
6495 });
6596 });
6697
@@ -124,12 +155,6 @@ private function runAsyncTestCycle(array $args): \Generator
124155 return $ returnValue ;
125156 }
126157
127- final protected function runTest ()
128- {
129- parent ::setName ('runAsyncTest ' );
130- return parent ::runTest ();
131- }
132-
133158 /**
134159 * Called before each test. Similar to {@see TestCase::setUp()}, except the method may return a promise or
135160 * coroutine (@see \Amp\call()} that will be awaited before executing the test.
@@ -169,6 +194,8 @@ final protected function setMinimumRuntime(int $runtime)
169194 */
170195 final protected function setTimeout (int $ timeout )
171196 {
197+ $ this ->timeout = $ timeout ;
198+
172199 $ this ->timeoutId = Loop::delay ($ timeout , function () use ($ timeout ) {
173200 Loop::stop ();
174201 Loop::setErrorHandler (null );
0 commit comments