From ef17834a5512b5f236d5a82d618e03474e0e591d Mon Sep 17 00:00:00 2001 From: Cees-Jan Kiewiet Date: Fri, 29 Mar 2024 20:33:24 +0100 Subject: [PATCH] Delegatge running tests in fibers to wyrihaximus/react-phpunit-run-tests-in-fiber --- composer-require-checker.json | 18 --------- composer.json | 1 + composer.lock | 55 ++++++++++++++++++++++++- etc/qa/phpstan.neon | 3 -- infection.json.dist | 18 ++++----- phpunit.xml.dist | 13 ------ src/AsyncTestCase.php | 75 ++--------------------------------- src/TimeOut.php | 8 +++- tests/AsyncTestCaseTest.php | 10 ++--- 9 files changed, 78 insertions(+), 123 deletions(-) delete mode 100644 composer-require-checker.json delete mode 100644 phpunit.xml.dist diff --git a/composer-require-checker.json b/composer-require-checker.json deleted file mode 100644 index fe22d36..0000000 --- a/composer-require-checker.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "symbol-whitelist" : [ - "null", "true", "false", - "static", "self", "parent", - "array", "string", "int", "float", "bool", "iterable", "callable", "void", "object", - "Clue\\React\\Block\\await", "Clue\\React\\Block\\awaitAny", "Clue\\React\\Block\\awaitAll" - ], - "php-core-extensions" : [ - "Core", - "date", - "pcre", - "Phar", - "Reflection", - "SPL", - "standard" - ], - "scan-files" : [] -} diff --git a/composer.json b/composer.json index 00fa1a9..a257441 100644 --- a/composer.json +++ b/composer.json @@ -15,6 +15,7 @@ "react/event-loop": "^1.5.0", "react/promise": "^3.1", "wyrihaximus/phpstan-react": "^1", + "wyrihaximus/react-phpunit-run-tests-in-fiber": "^1.0", "wyrihaximus/test-utilities": "^5.5.4 || ^6" }, "require-dev": { diff --git a/composer.lock b/composer.lock index b9b295b..702a934 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "732ddf86f273cdcaa97e8297b6ea241f", + "content-hash": "d4242dabf829f2f415c2698fe925336e", "packages": [ { "name": "amphp/amp", @@ -10005,6 +10005,59 @@ ], "time": "2023-07-22T03:17:18+00:00" }, + { + "name": "wyrihaximus/react-phpunit-run-tests-in-fiber", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/WyriHaximus/reactphp-phpunit-run-tests-in-fiber.git", + "reference": "bfa65c9b12fbe2735fc76a8f85535ea1117571fb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/WyriHaximus/reactphp-phpunit-run-tests-in-fiber/zipball/bfa65c9b12fbe2735fc76a8f85535ea1117571fb", + "reference": "bfa65c9b12fbe2735fc76a8f85535ea1117571fb", + "shasum": "" + }, + "require": { + "php": "^8.1", + "react/async": "^4.2.0", + "react/event-loop": "^1.5.0", + "react/promise": "^2.10 || ^3.0" + }, + "require-dev": { + "react/promise-timer": "^1.10.0", + "wyrihaximus/test-utilities": "^5.2.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "WyriHaximus\\React\\PHPUnit\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Cees-Jan Kiewiet", + "email": "ceesjank@gmail.com" + } + ], + "description": "Trait to run all tests in a fiber", + "support": { + "issues": "https://github.com/WyriHaximus/reactphp-phpunit-run-tests-in-fiber/issues", + "source": "https://github.com/WyriHaximus/reactphp-phpunit-run-tests-in-fiber/tree/1.0.1" + }, + "funding": [ + { + "url": "https://github.com/WyriHaximus", + "type": "github" + } + ], + "time": "2024-02-16T19:13:50+00:00" + }, { "name": "wyrihaximus/test-utilities", "version": "5.6.0", diff --git a/etc/qa/phpstan.neon b/etc/qa/phpstan.neon index a7254a1..2e9e6df 100644 --- a/etc/qa/phpstan.neon +++ b/etc/qa/phpstan.neon @@ -2,10 +2,7 @@ parameters: excludePaths: - tests/bootstrap.php ignoreErrors: - - '#Parameter \#1 \$name of method PHPUnit\\Framework\\TestCase::setName\(\) expects string, string\|null given.#' - - '#Trying to invoke array\{\$this\(WyriHaximus\\AsyncTestUtilities\\AsyncTestCase\), string\|null\} but it might not be a callable.#' - '#Method WyriHaximus\\AsyncTestUtilities\\CallableStub::__invoke\(\) is not final, but since the containing class is abstract, it should be.#' - - '#Parameter \#1 \$name of method ReflectionClass\<\$this\(WyriHaximus\\AsyncTestUtilities\\AsyncTestCase\)\>::getMethod\(\) expects string, string\|null given.#' - '#Call to deprecated method expectCallableExactly\(\)#' - '#Call to deprecated method expectCallableOnce\(\)#' ergebnis: diff --git a/infection.json.dist b/infection.json.dist index dd10b76..2648707 100644 --- a/infection.json.dist +++ b/infection.json.dist @@ -1,20 +1,20 @@ { - "timeout": 120, + "timeout": 300, "source": { "directories": [ "src" ] }, "logs": { - "text": "infection-log.txt" + "text": "./var/infection.log", + "summary": "./var/infection-summary.log", + "json": "./var/infection.json", + "perMutator": "./var/infection-per-mutator.md" }, "mutators": { - "@default": true, - "InstanceOf_": false, - "ArrayItemRemoval": { - "ignore": [ - "WyriHaximus\\AsyncTestUtilities\\AsyncTestCase::provideEventLoop" - ] - } + "@default": true + }, + "phpUnit": { + "configDir": "./etc/qa/" } } diff --git a/phpunit.xml.dist b/phpunit.xml.dist deleted file mode 100644 index d9b3788..0000000 --- a/phpunit.xml.dist +++ /dev/null @@ -1,13 +0,0 @@ - - - - - tests/ - - - - - src/ - - - diff --git a/src/AsyncTestCase.php b/src/AsyncTestCase.php index ce761c5..8bc5aaf 100644 --- a/src/AsyncTestCase.php +++ b/src/AsyncTestCase.php @@ -5,18 +5,14 @@ namespace WyriHaximus\AsyncTestUtilities; use PHPUnit\Framework\MockObject\Rule\InvokedCount; -use React\EventLoop\Loop; -use ReflectionClass; +use WyriHaximus\React\PHPUnit\RunTestsInFibersTrait; use WyriHaximus\TestUtilities\TestCase; -use function React\Async\async; -use function React\Async\await; - abstract class AsyncTestCase extends TestCase { - private const INVOKE_ARRAY = ['__invoke']; + use RunTestsInFibersTrait; - private string|null $realTestName = null; + private const INVOKE_ARRAY = ['__invoke']; /** @deprecated With the move to fibers there is no need for these rarely used methods anymore. (Unless proven otherwise of course.) */ final protected function expectCallableExactly(int $amount): callable @@ -48,69 +44,4 @@ private function getCallableMock(InvokedCount $invokedCount): callable /** @psalm-suppress InvalidReturnStatement */ return $mock; } - - /** @codeCoverageIgnore Invoked before code coverage data is being collected. */ - final public function setName(string $name): void - { - /** @psalm-suppress InternalMethod */ - parent::setName($name); - - $this->realTestName = $name; - } - - /** @internal */ - final protected function runAsyncTest(mixed ...$args): mixed - { - /** - * @psalm-suppress InternalMethod - * @psalm-suppress PossiblyNullArgument - */ - parent::setName($this->realTestName); - - $timeout = 30; - $reflectionClass = new ReflectionClass($this::class); - foreach ($reflectionClass->getAttributes() as $classAttribute) { - $classTimeout = $classAttribute->newInstance(); - if (! ($classTimeout instanceof TimeOut)) { - continue; - } - - $timeout = $classTimeout->timeout; - } - - /** - * @psalm-suppress InternalMethod - * @psalm-suppress PossiblyNullArgument - */ - foreach ($reflectionClass->getMethod($this->realTestName)->getAttributes() as $methodAttribute) { - $methodTimeout = $methodAttribute->newInstance(); - if (! ($methodTimeout instanceof TimeOut)) { - continue; - } - - $timeout = $methodTimeout->timeout; - } - - $timeout = Loop::addTimer($timeout, static fn () => Loop::stop()); - - try { - /** - * @psalm-suppress MixedArgument - * @psalm-suppress UndefinedInterfaceMethod - */ - return await(async( - fn (): mixed => ([$this, $this->realTestName])(...$args), - )()); - } finally { - Loop::cancelTimer($timeout); - } - } - - final protected function runTest(): mixed - { - /** @psalm-suppress InternalMethod */ - parent::setName('runAsyncTest'); - - return parent::runTest(); - } } diff --git a/src/TimeOut.php b/src/TimeOut.php index 6f20edd..57d13dd 100644 --- a/src/TimeOut.php +++ b/src/TimeOut.php @@ -5,12 +5,18 @@ namespace WyriHaximus\AsyncTestUtilities; use Attribute; +use WyriHaximus\React\PHPUnit\TimeOutInterface; #[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_CLASS)] -final readonly class TimeOut +final readonly class TimeOut implements TimeOutInterface { public function __construct( public int|float $timeout, ) { } + + public function timeout(): int|float + { + return $this->timeout; + } } diff --git a/tests/AsyncTestCaseTest.php b/tests/AsyncTestCaseTest.php index 144b143..2738f1b 100644 --- a/tests/AsyncTestCaseTest.php +++ b/tests/AsyncTestCaseTest.php @@ -39,15 +39,13 @@ public function testExpectCallableExactly(): void { $callable = $this->expectCallableExactly(3); - Loop::futureTick($callable); - Loop::futureTick($callable); - Loop::futureTick($callable); - Loop::run(); + $callable(); + $callable(); + $callable(); } public function testExpectCallableOnce(): void { - Loop::futureTick($this->expectCallableOnce()); - Loop::run(); + $this->expectCallableOnce()(); } }