Skip to content

Commit af9c2b7

Browse files
committed
Trait magic to support PHPUnit 6, 7, and 8
1 parent 4b98dff commit af9c2b7

File tree

6 files changed

+112
-39
lines changed

6 files changed

+112
-39
lines changed

composer.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,18 @@
77
{
88
"name": "Niklas Keller",
99
"email": "[email protected]"
10+
},
11+
{
12+
"name": "Aaron Piotrowski",
13+
"email": "[email protected]"
1014
}
1115
],
1216
"support": {
1317
"issues": "https://github.com/amphp/phpunit-util/issues",
1418
"irc": "irc://irc.freenode.org/amphp"
1519
},
1620
"require": {
17-
"phpunit/phpunit": "^6"
21+
"phpunit/phpunit": "^6 | ^7 | ^8"
1822
},
1923
"require-dev": {
2024
"amphp/amp": "^2",

phpunit.xml.dist

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,4 @@
2525
<directory suffix=".php">src</directory>
2626
</whitelist>
2727
</filter>
28-
<listeners>
29-
<listener class="Amp\PHPUnit\LoopReset"/>
30-
</listeners>
3128
</phpunit>

src/AsyncTestCase.php

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,36 +13,17 @@
1313
*/
1414
abstract class AsyncTestCase extends PHPUnitTestCase
1515
{
16+
use Internal\AsyncTestSetNameTrait,
17+
Internal\AsyncTestSetUpTrait;
18+
1619
const RUNTIME_PRECISION = 2;
1720

1821
/** @var string|null Timeout watcher ID. */
1922
private $timeoutId;
2023

21-
/** @var string Temporary storage for actual test name. */
22-
private $realTestName;
23-
2424
/** @var int Minimum runtime in milliseconds. */
2525
private $minimumRuntime = 0;
2626

27-
/** @var bool */
28-
private $setUpInvoked = false;
29-
30-
protected function setUp()
31-
{
32-
$this->setUpInvoked = true;
33-
Loop::set((new Loop\DriverFactory)->create());
34-
\gc_collect_cycles(); // extensions using an event loop may otherwise leak the file descriptors to the loop
35-
}
36-
37-
/**
38-
* @codeCoverageIgnore Invoked before code coverage data is being collected.
39-
*/
40-
final public function setName($name)
41-
{
42-
parent::setName($name);
43-
$this->realTestName = $name;
44-
}
45-
4627
final protected function runTest()
4728
{
4829
parent::setName('runAsyncTest');
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
namespace Amp\PHPUnit\Internal;
4+
5+
use PHPUnit\Framework\TestCase;
6+
7+
if ((new \ReflectionMethod(TestCase::class, 'setName'))->hasReturnType()) {
8+
// PHPUnit 7+
9+
trait AsyncTestSetNameTrait
10+
{
11+
/** @var string Temporary storage for actual test name. */
12+
private $realTestName;
13+
14+
/**
15+
* @codeCoverageIgnore Invoked before code coverage data is being collected.
16+
*/
17+
final public function setName(string $name): void
18+
{
19+
parent::setName($name);
20+
$this->realTestName = $name;
21+
}
22+
}
23+
} else {
24+
// PHPUnit 6
25+
trait AsyncTestSetNameTrait
26+
{
27+
/** @var string Temporary storage for actual test name. */
28+
private $realTestName;
29+
30+
/**
31+
* @codeCoverageIgnore Invoked before code coverage data is being collected.
32+
*/
33+
final public function setName($name)
34+
{
35+
parent::setName($name);
36+
$this->realTestName = $name;
37+
}
38+
}
39+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace Amp\PHPUnit\Internal;
4+
5+
use Amp\Loop;
6+
use PHPUnit\Framework\TestCase;
7+
8+
if ((new \ReflectionMethod(TestCase::class, 'setUp'))->hasReturnType()) {
9+
// PHPUnit 8+
10+
trait AsyncTestSetUpTrait
11+
{
12+
/** @var bool */
13+
private $setUpInvoked = false;
14+
15+
protected function setUp(): void
16+
{
17+
$this->setUpInvoked = true;
18+
Loop::set((new Loop\DriverFactory)->create());
19+
\gc_collect_cycles(); // extensions using an event loop may otherwise leak the file descriptors to the loop
20+
}
21+
}
22+
} else {
23+
// PHPUnit 6 or 7
24+
trait AsyncTestSetUpTrait
25+
{
26+
/** @var bool */
27+
private $setUpInvoked = false;
28+
29+
protected function setUp()
30+
{
31+
$this->setUpInvoked = true;
32+
Loop::set((new Loop\DriverFactory)->create());
33+
\gc_collect_cycles(); // extensions using an event loop may otherwise leak the file descriptors to the loop
34+
}
35+
}
36+
}

test/InvalidAsyncTestCaseTest.php

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,38 @@
55
use Amp\PHPUnit\AsyncTestCase;
66
use PHPUnit\Framework\AssertionFailedError;
77

8-
class InvalidAsyncTestCaseTest extends AsyncTestCase
9-
{
10-
protected function setUp()
8+
if ((new \ReflectionMethod(AsyncTestCase::class, 'setUp'))->hasReturnType()) {
9+
// PHPUnit 8+
10+
class InvalidAsyncTestCaseTest extends AsyncTestCase
1111
{
12-
// No call to parent::setUp()
12+
protected function setUp(): void
13+
{
14+
// No call to parent::setUp()
1315

14-
$this->expectException(AssertionFailedError::class);
15-
$this->expectExceptionMessage('without calling the parent method');
16-
}
16+
$this->expectException(AssertionFailedError::class);
17+
$this->expectExceptionMessage('without calling the parent method');
18+
}
1719

18-
/**
19-
* @expectedException \Error
20-
* @expectedExceptionMessage without calling the parent method
21-
*/
22-
public function testMethod()
20+
public function testMethod()
21+
{
22+
// Test will fail because setUp() did not call the parent method
23+
}
24+
}
25+
} else {
26+
// PHPUnit 6 or 7
27+
class InvalidAsyncTestCaseTest extends AsyncTestCase
2328
{
24-
// Test will fail because setUp() did not call the parent method
29+
protected function setUp()
30+
{
31+
// No call to parent::setUp()
32+
33+
$this->expectException(AssertionFailedError::class);
34+
$this->expectExceptionMessage('without calling the parent method');
35+
}
36+
37+
public function testMethod()
38+
{
39+
// Test will fail because setUp() did not call the parent method
40+
}
2541
}
2642
}

0 commit comments

Comments
 (0)