Skip to content

Commit 295eed1

Browse files
committed
Use now() and rename to UnhandledException
1 parent 8d78a6f commit 295eed1

3 files changed

Lines changed: 50 additions & 47 deletions

File tree

src/AsyncTestCase.php

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,13 @@
1111
use Revolt\EventLoop\Driver\TracingDriver;
1212
use function Amp\async;
1313
use function Amp\Future\all;
14+
use function Amp\now;
1415

1516
abstract class AsyncTestCase extends PHPUnitTestCase
1617
{
1718
private const RUNTIME_PRECISION = 2;
1819

19-
private DeferredFuture $deferred;
20+
private DeferredFuture $deferredFuture;
2021

2122
private string $timeoutId;
2223

@@ -48,15 +49,14 @@ protected function cleanup(): void
4849
protected function setUp(): void
4950
{
5051
$this->setUpInvoked = true;
51-
52-
$this->deferred = new DeferredFuture();
52+
$this->deferredFuture = new DeferredFuture();
5353

5454
EventLoop::setErrorHandler(function (\Throwable $exception): void {
55-
if ($this->deferred->isComplete()) {
55+
if ($this->deferredFuture->isComplete()) {
5656
return;
5757
}
5858

59-
$this->deferred->error(new LoopCaughtException($exception));
59+
$this->deferredFuture->error(new UnhandledException($exception));
6060
});
6161
}
6262

@@ -73,11 +73,12 @@ final protected function runAsyncTest(mixed ...$args): mixed
7373

7474
parent::setName($this->realTestName);
7575

76-
$start = \microtime(true);
76+
$start = now();
7777

7878
try {
7979
try {
80-
[$returnValue] = all([
80+
[, $returnValue] = all([
81+
$this->deferredFuture->getFuture(),
8182
async(function () use ($args): mixed {
8283
try {
8384
$result = ([$this, $this->realTestName])(...$args);
@@ -93,12 +94,11 @@ final protected function runAsyncTest(mixed ...$args): mixed
9394

9495
return $result;
9596
} finally {
96-
if (!$this->deferred->isComplete()) {
97-
$this->deferred->complete();
97+
if (!$this->deferredFuture->isComplete()) {
98+
$this->deferredFuture->complete();
9899
}
99100
}
100101
}),
101-
$this->deferred->getFuture()
102102
]);
103103
} finally {
104104
$this->cleanup();
@@ -111,7 +111,7 @@ final protected function runAsyncTest(mixed ...$args): mixed
111111
\gc_collect_cycles(); // Throw from as many destructors as possible.
112112
}
113113

114-
$end = \microtime(true);
114+
$end = now();
115115

116116
if ($this->minimumRuntime > 0) {
117117
$actualRuntime = \round($end - $start, self::RUNTIME_PRECISION);
@@ -133,27 +133,27 @@ final protected function runTest(): mixed
133133
}
134134

135135
/**
136-
* Fails the test if the loop does not run for at least the given amount of time.
136+
* Fails the test if it does not run for at least the given amount of time.
137137
*
138-
* @param float $runtime Required run time in seconds.
138+
* @param float $seconds Required runtime in seconds.
139139
*/
140-
final protected function setMinimumRuntime(float $runtime): void
140+
final protected function setMinimumRuntime(float $seconds): void
141141
{
142-
if ($runtime < 0.001) {
143-
throw new \Error('Minimum runtime must be at least 0.001s');
142+
if ($seconds <= 0) {
143+
throw new \Error('Minimum runtime must be greater than 0, got ' . $seconds);
144144
}
145145

146-
$this->minimumRuntime = \round($runtime, self::RUNTIME_PRECISION);
146+
$this->minimumRuntime = \round($seconds, self::RUNTIME_PRECISION);
147147
}
148148

149149
/**
150-
* Fails the test (and stops the loop) after the given timeout.
150+
* Fails the test (and stops the event loop) after the given timeout.
151151
*
152-
* @param float $timeout Timeout in seconds.
152+
* @param float $seconds Timeout in seconds.
153153
*/
154-
final protected function setTimeout(float $timeout): void
154+
final protected function setTimeout(float $seconds): void
155155
{
156-
$this->timeoutId = EventLoop::delay($timeout, function () use ($timeout): void {
156+
$this->timeoutId = EventLoop::delay($seconds, function () use ($seconds): void {
157157
EventLoop::setErrorHandler(null);
158158

159159
$additionalInfo = '';
@@ -167,22 +167,26 @@ final protected function setTimeout(float $timeout): void
167167
$additionalInfo .= "\r\n\r\nSet REVOLT_DEBUG_TRACE_WATCHERS=true as environment variable to trace watchers keeping the loop running.";
168168
}
169169

170-
if ($this->deferred->isComplete()) {
170+
if ($this->deferredFuture->isComplete()) {
171171
return;
172172
}
173173

174174
try {
175-
$this->fail(\sprintf('Expected test to complete before %0.3fs time limit%s', $timeout, $additionalInfo));
175+
$this->fail(\sprintf(
176+
'Expected test to complete before %0.3fs time limit%s',
177+
$seconds,
178+
$additionalInfo
179+
));
176180
} catch (AssertionFailedError $e) {
177-
$this->deferred->error($e);
181+
$this->deferredFuture->error($e);
178182
}
179183
});
180184

181185
EventLoop::unreference($this->timeoutId);
182186
}
183187

184188
/**
185-
* @param int $invocationCount Number of times the callback must be invoked or the test will fail.
189+
* @param int $invocationCount Number of times the callback must be invoked or the test will fail.
186190
* @param callable|null $returnCallback Callable providing a return value for the callback.
187191
*
188192
* @return \Closure&MockObject Mock object having only an __invoke method.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
namespace Amp\PHPUnit;
44

5-
final class LoopCaughtException extends \Exception
5+
final class UnhandledException extends \Exception
66
{
7-
public function __construct(\Throwable $previous = null)
7+
public function __construct(\Throwable $previous)
88
{
99
parent::__construct(\sprintf(
1010
"%s thrown to event loop error handler: %s",

test/AsyncTestCaseTest.php

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
use Amp\DeferredFuture;
66
use Amp\Future;
77
use Amp\PHPUnit\AsyncTestCase;
8-
use Amp\PHPUnit\LoopCaughtException;
98
use Amp\PHPUnit\TestException;
9+
use Amp\PHPUnit\UnhandledException;
1010
use PHPUnit\Framework\AssertionFailedError;
1111
use Revolt\EventLoop;
1212
use function Amp\async;
@@ -25,14 +25,14 @@ public function cleanup(): void
2525
}
2626
}
2727

28-
public function testThatMethodRunsInLoopContext(): Future
28+
public function testThatMethodRunsInEventLoopContext(): Future
2929
{
3030
$returnDeferred = new DeferredFuture; // make sure our test runs to completion
3131
$testDeferred = new DeferredFuture; // used by our defer callback to ensure we're running on the Loop
3232

3333
EventLoop::queue(function () use ($testDeferred, $returnDeferred): void {
3434
$data = $testDeferred->getFuture()->await();
35-
self::assertEquals('foobar', $data, 'Expected the data to be what was resolved in EventLoop::defer');
35+
self::assertSame('foobar', $data);
3636
$returnDeferred->complete();
3737
});
3838

@@ -43,19 +43,20 @@ public function testThatMethodRunsInLoopContext(): Future
4343
return $returnDeferred->getFuture();
4444
}
4545

46-
public function testThatWeHandleNullReturn(): void
46+
public function testHandleNullReturn(): void
4747
{
4848
$testDeferred = new DeferredFuture;
4949
$testData = new \stdClass;
50-
$testData->val = null;
50+
$testData->val = 0;
51+
5152
EventLoop::defer(function () use ($testData, $testDeferred) {
52-
$testData->val = true;
53-
$testDeferred->complete(null);
53+
$testData->val++;
54+
$testDeferred->complete();
5455
});
5556

5657
$testDeferred->getFuture()->await();
5758

58-
self::assertTrue($testData->val, 'Expected our test to run on loop to completion');
59+
self::assertSame(1, $testData->val);
5960
}
6061

6162
public function testReturningFuture(): Future
@@ -65,18 +66,20 @@ public function testReturningFuture(): Future
6566
EventLoop::delay(0.1, fn () => $deferred->complete('value'));
6667

6768
$returnValue = $deferred->getFuture();
68-
self::assertInstanceOf(Future::class, $returnValue); // An assertion is required for the test to pass
69+
$this->expectNotToPerformAssertions();
70+
6971
return $returnValue; // Return value used by testReturnValueFromDependentTest
7072
}
7173

7274
public function testExpectingAnExceptionThrown(): Future
7375
{
7476
$throwException = function (): void {
7577
delay(0.1);
76-
throw new \Exception('threw the error');
78+
79+
throw new TestException('threw the error');
7780
};
7881

79-
$this->expectException(\Exception::class);
82+
$this->expectException(TestException::class);
8083
$this->expectExceptionMessage('threw the error');
8184

8285
return async($throwException);
@@ -91,19 +94,15 @@ public function testExpectingAnErrorThrown(): Future
9194
});
9295
}
9396

94-
public function argumentSupportProvider(): array
97+
public function provideArguments(): array
9598
{
9699
return [
97100
['foo', 42, true],
98101
];
99102
}
100103

101104
/**
102-
* @param string $foo
103-
* @param int $bar
104-
* @param bool $baz
105-
*
106-
* @dataProvider argumentSupportProvider
105+
* @dataProvider provideArguments
107106
*/
108107
public function testArgumentSupport(string $foo, int $bar, bool $baz): void
109108
{
@@ -126,6 +125,7 @@ public function testSetTimeout(): void
126125
{
127126
$this->setTimeout(0.1);
128127
$this->expectNotToPerformAssertions();
128+
129129
delay(0.05);
130130
}
131131

@@ -158,8 +158,7 @@ public function testSetMinimumRunTime(): void
158158
$this->setMinimumRuntime(0.1);
159159

160160
$this->expectException(AssertionFailedError::class);
161-
$pattern = "/Expected test to take at least 0.100s but instead took 0.(\d+)s/";
162-
$this->expectExceptionMessageMatches($pattern);
161+
$this->expectExceptionMessageMatches("/Expected test to take at least 0.100s but instead took 0.\d{3}s/");
163162

164163
delay(0.05);
165164
}
@@ -179,7 +178,7 @@ public function testThrowToEventLoop(): void
179178

180179
EventLoop::queue(static fn () => throw new TestException('message'));
181180

182-
$this->expectException(LoopCaughtException::class);
181+
$this->expectException(UnhandledException::class);
183182
$pattern = "/(.+) thrown to event loop error handler: (.*)/";
184183
$this->expectExceptionMessageMatches($pattern);
185184

0 commit comments

Comments
 (0)