Skip to content

Commit f696392

Browse files
authored
Merge pull request #144 from clue-labs/fragile
Improve test suite to be less fragile
2 parents 914304f + e4619fa commit f696392

File tree

3 files changed

+69
-31
lines changed

3 files changed

+69
-31
lines changed

tests/AbstractLoopTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,8 @@ public function testRemoveInvalid()
262262
// remove a valid stream from the event loop that was never added in the first place
263263
$this->loop->removeReadStream($stream);
264264
$this->loop->removeWriteStream($stream);
265+
266+
$this->assertTrue(true);
265267
}
266268

267269
/** @test */

tests/Timer/AbstractTimerTest.php

Lines changed: 65 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,69 +8,103 @@ abstract class AbstractTimerTest extends TestCase
88
{
99
abstract public function createLoop();
1010

11-
public function testAddTimer()
11+
public function testAddTimerReturnsNonPeriodicTimerInstance()
1212
{
13-
// usleep is intentionally high
13+
$loop = $this->createLoop();
14+
15+
$timer = $loop->addTimer(0.001, $this->expectCallableNever());
16+
17+
$this->assertInstanceOf('React\EventLoop\TimerInterface', $timer);
18+
$this->assertFalse($timer->isPeriodic());
19+
}
1420

21+
public function testAddTimerWillBeInvokedOnceAndBlocksLoopWhenRunning()
22+
{
1523
$loop = $this->createLoop();
1624

1725
$loop->addTimer(0.001, $this->expectCallableOnce());
18-
usleep(1000);
19-
$this->tickLoop($loop);
26+
27+
$start = microtime(true);
28+
$loop->run();
29+
$end = microtime(true);
30+
31+
// make no strict assumptions about actual time interval.
32+
// must be at least 0.001s (1ms) and should not take longer than 0.1s
33+
$this->assertGreaterThanOrEqual(0.001, $end - $start);
34+
$this->assertLessThan(0.1, $end - $start);
2035
}
2136

22-
public function testAddPeriodicTimer()
37+
public function testAddPeriodicTimerReturnsPeriodicTimerInstance()
2338
{
2439
$loop = $this->createLoop();
2540

26-
$loop->addPeriodicTimer(0.001, $this->expectCallableExactly(3));
27-
usleep(1000);
28-
$this->tickLoop($loop);
29-
usleep(1000);
30-
$this->tickLoop($loop);
31-
usleep(1000);
32-
$this->tickLoop($loop);
41+
$periodic = $loop->addPeriodicTimer(0.1, $this->expectCallableNever());
42+
43+
$this->assertInstanceOf('React\EventLoop\TimerInterface', $periodic);
44+
$this->assertTrue($periodic->isPeriodic());
3345
}
3446

35-
public function testAddPeriodicTimerWithCancel()
47+
public function testAddPeriodicTimerWillBeInvokedUntilItIsCancelled()
3648
{
3749
$loop = $this->createLoop();
3850

39-
$timer = $loop->addPeriodicTimer(0.001, $this->expectCallableExactly(2));
40-
41-
usleep(1000);
42-
$this->tickLoop($loop);
43-
usleep(1000);
44-
$this->tickLoop($loop);
51+
$periodic = $loop->addPeriodicTimer(0.1, $this->expectCallableExactly(3));
4552

46-
$loop->cancelTimer($timer);
53+
// make no strict assumptions about actual time interval.
54+
// leave some room to ensure this ticks exactly 3 times.
55+
$loop->addTimer(0.399, function () use ($loop, $periodic) {
56+
$loop->cancelTimer($periodic);
57+
});
4758

48-
usleep(1000);
49-
$this->tickLoop($loop);
59+
$loop->run();
5060
}
5161

52-
public function testAddPeriodicTimerCancelsItself()
62+
public function testAddPeriodicTimerWillBeInvokedWithMaximumAccuracyUntilItIsCancelled()
5363
{
64+
$loop = $this->createLoop();
65+
5466
$i = 0;
67+
$periodic = $loop->addPeriodicTimer(0.001, function () use (&$i) {
68+
++$i;
69+
});
70+
71+
$loop->addTimer(0.02, function () use ($loop, $periodic) {
72+
$loop->cancelTimer($periodic);
73+
});
74+
75+
$loop->run();
5576

77+
// make no strict assumptions about number of invocations.
78+
// we know it must be no more than 20 times and should at least be
79+
// invoked twice for really slow loops
80+
$this->assertLessThanOrEqual(20, $i);
81+
$this->assertGreaterThan(2, $i);
82+
}
83+
84+
public function testAddPeriodicTimerCancelsItself()
85+
{
5686
$loop = $this->createLoop();
5787

88+
$i = 0;
5889
$loop->addPeriodicTimer(0.001, function ($timer) use (&$i, $loop) {
5990
$i++;
6091

61-
if ($i == 2) {
92+
if ($i === 5) {
6293
$loop->cancelTimer($timer);
6394
}
6495
});
6596

66-
usleep(1000);
67-
$this->tickLoop($loop);
68-
usleep(1000);
69-
$this->tickLoop($loop);
70-
usleep(1000);
71-
$this->tickLoop($loop);
97+
$start = microtime(true);
98+
$loop->run();
99+
$end = microtime(true);
100+
101+
$this->assertEquals(5, $i);
72102

73-
$this->assertSame(2, $i);
103+
// make no strict assumptions about time interval.
104+
// 5 invocations must take at least 0.005s (5ms) and should not take
105+
// longer than 0.1s for slower loops.
106+
$this->assertGreaterThanOrEqual(0.005, $end - $start);
107+
$this->assertLessThan(0.1, $end - $start);
74108
}
75109

76110
public function testMinimumIntervalOneMicrosecond()

tests/Timer/TimersTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,7 @@ public function testBlockedTimer()
2525
}));
2626

2727
$timers->tick();
28+
29+
$this->assertTrue(true);
2830
}
2931
}

0 commit comments

Comments
 (0)