Skip to content

Commit

Permalink
add Await generator support
Browse files Browse the repository at this point in the history
  • Loading branch information
ShockedPlot7560 committed Oct 3, 2023
1 parent 83b6f08 commit 628619a
Show file tree
Hide file tree
Showing 5 changed files with 180 additions and 4 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
"react/promise": "^3.0",
"webmozart/assert": "^1.11",
"pocketmine/callback-validator": "^1.0",
"respect/stringifier": "^2.0"
"respect/stringifier": "^2.0",
"sof3/await-generator": "^3.6"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "*",
Expand Down
55 changes: 54 additions & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/PmmpUnit.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ private function finish(bool $close = true) : void {
$this->getLogger()->error("Fatal errors occurred during unit test:");
$i = 0;
foreach ($fatalErrors as $error) {
$this->getLogger()->error(++$i . ") " . $error->test->__toString() . ": " . str_replace("§", "&", $error->throwable->getMessage()));
$this->getLogger()->error(++$i . ") " . $error->test->__toString() . ": " . str_replace("§", "&", $error->throwable->getMessage()) . " (line: " . $error->throwable->getLine() . ")");
$this->getLogger()->logException($error->throwable);
}
}
Expand All @@ -143,7 +143,7 @@ private function finish(bool $close = true) : void {
$this->getLogger()->emergency("Failed tests:");
$i = 0;
foreach ($failedTests as $error) {
$this->getLogger()->emergency(++$i . ") " . $error->test->__toString() . ": " . str_replace("§", "&", $error->throwable->getMessage()));
$this->getLogger()->emergency(++$i . ") " . $error->test->__toString() . ": " . str_replace("§", "&", $error->throwable->getMessage()) . " (line: " . $error->throwable->getLine() . ")");
}
}

Expand Down
63 changes: 63 additions & 0 deletions src/utils/AwaitGeneratorDecorator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

namespace ShockedPlot7560\PmmpUnit\utils;

use Closure;
use DaveRandom\CallbackValidator\CallbackType;
use DaveRandom\CallbackValidator\ReturnType;
use Generator;
use React\Promise\Deferred;
use React\Promise\PromiseInterface;
use SOFe\AwaitGenerator\Await;
use Throwable;

class AwaitGeneratorDecorator implements PromiseInterface {

Check failure on line 14 in src/utils/AwaitGeneratorDecorator.php

View workflow job for this annotation

GitHub Actions / PHPStan analysis (ubuntu-20.04, 8.1)

Class ShockedPlot7560\PmmpUnit\utils\AwaitGeneratorDecorator implements generic interface React\Promise\PromiseInterface but does not specify its types: T

Check failure on line 14 in src/utils/AwaitGeneratorDecorator.php

View workflow job for this annotation

GitHub Actions / PHPStan analysis (ubuntu-20.04, 8.2)

Class ShockedPlot7560\PmmpUnit\utils\AwaitGeneratorDecorator implements generic interface React\Promise\PromiseInterface but does not specify its types: T
private Deferred $delegate;

Check failure on line 15 in src/utils/AwaitGeneratorDecorator.php

View workflow job for this annotation

GitHub Actions / PHPStan analysis (ubuntu-20.04, 8.1)

Property ShockedPlot7560\PmmpUnit\utils\AwaitGeneratorDecorator::$delegate with generic class React\Promise\Deferred does not specify its types: T

Check failure on line 15 in src/utils/AwaitGeneratorDecorator.php

View workflow job for this annotation

GitHub Actions / PHPStan analysis (ubuntu-20.04, 8.2)

Property ShockedPlot7560\PmmpUnit\utils\AwaitGeneratorDecorator::$delegate with generic class React\Promise\Deferred does not specify its types: T

public function __construct(
Closure|Generator $generateGenerator
) {
$this->delegate = new Deferred();

if ($generateGenerator instanceof Closure) {
$type = new CallbackType(new ReturnType('Generator'));
$type->isSatisfiedBy($generateGenerator);
}

try {
Await::f2c(function () use ($generateGenerator) {
if ($generateGenerator instanceof Closure) {
$generateGenerator = $generateGenerator();
}
$result = yield from $generateGenerator;
$this->delegate->resolve($result);
});
} catch (Throwable $e) {
$this->delegate->reject($e);
}
}

public function then(?callable $onFulfilled = null, ?callable $onRejected = null) : PromiseInterface {

Check failure on line 40 in src/utils/AwaitGeneratorDecorator.php

View workflow job for this annotation

GitHub Actions / PHPStan analysis (ubuntu-20.04, 8.1)

Conditional return type uses subject type mixed which is not part of PHPDoc @template tags.

Check failure on line 40 in src/utils/AwaitGeneratorDecorator.php

View workflow job for this annotation

GitHub Actions / PHPStan analysis (ubuntu-20.04, 8.2)

Conditional return type uses subject type mixed which is not part of PHPDoc @template tags.
return $this->delegate->promise()->then($onFulfilled, $onRejected);
}

public function catch(callable $onRejected) : PromiseInterface {
return $this->delegate->promise()->catch($onRejected);
}

public function finally(callable $onFulfilledOrRejected) : PromiseInterface {
return $this->delegate->promise()->finally($onFulfilledOrRejected);
}

public function cancel() : void {
$this->delegate->promise()->cancel();
}

public function otherwise(callable $onRejected) : PromiseInterface {
return $this->delegate->promise()->otherwise($onRejected);
}

public function always(callable $onFulfilledOrRejected) : PromiseInterface {
return $this->delegate->promise()->always($onFulfilledOrRejected);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

namespace ShockedPlot7560\PmmpUnit\tests\normal;

use Exception;
use Generator;
use pocketmine\scheduler\Task;
use React\Promise\PromiseInterface;
use ShockedPlot7560\PmmpUnit\framework\TestCase;
use ShockedPlot7560\PmmpUnit\PmmpUnit;
use ShockedPlot7560\PmmpUnit\utils\AwaitGeneratorDecorator;
use SOFe\AwaitGenerator\Await;

class AwaitGeneratorDecoratorTest extends TestCase {
public function testClosureCallback() : PromiseInterface {

Check failure on line 15 in tests/pmmpunit/suitetest/normal/tests/AwaitGeneratorDecoratorTest.php

View workflow job for this annotation

GitHub Actions / PHPStan analysis (ubuntu-20.04, 8.1)

Method ShockedPlot7560\PmmpUnit\tests\normal\AwaitGeneratorDecoratorTest::testClosureCallback() return type with generic interface React\Promise\PromiseInterface does not specify its types: T

Check failure on line 15 in tests/pmmpunit/suitetest/normal/tests/AwaitGeneratorDecoratorTest.php

View workflow job for this annotation

GitHub Actions / PHPStan analysis (ubuntu-20.04, 8.2)

Method ShockedPlot7560\PmmpUnit\tests\normal\AwaitGeneratorDecoratorTest::testClosureCallback() return type with generic interface React\Promise\PromiseInterface does not specify its types: T
$start = microtime(true);

$decorator = new AwaitGeneratorDecorator(function () : Generator {
return $this->sleep();
});

return $decorator->then(function () use ($start) : void {
$this->assertTrue(microtime(true) - $start >= 0.9);
});
}

public function testGeneratorCallback() : PromiseInterface {

Check failure on line 27 in tests/pmmpunit/suitetest/normal/tests/AwaitGeneratorDecoratorTest.php

View workflow job for this annotation

GitHub Actions / PHPStan analysis (ubuntu-20.04, 8.1)

Method ShockedPlot7560\PmmpUnit\tests\normal\AwaitGeneratorDecoratorTest::testGeneratorCallback() return type with generic interface React\Promise\PromiseInterface does not specify its types: T

Check failure on line 27 in tests/pmmpunit/suitetest/normal/tests/AwaitGeneratorDecoratorTest.php

View workflow job for this annotation

GitHub Actions / PHPStan analysis (ubuntu-20.04, 8.2)

Method ShockedPlot7560\PmmpUnit\tests\normal\AwaitGeneratorDecoratorTest::testGeneratorCallback() return type with generic interface React\Promise\PromiseInterface does not specify its types: T
$start = microtime(true);

$decorator = new AwaitGeneratorDecorator($this->sleep());

return $decorator->then(function () use ($start) : void {
$this->assertTrue(microtime(true) - $start >= 0.9);
});
}

private function sleep() : Generator {
yield from Await::promise(function ($resolve, $reject) {
$task = new class($resolve, $reject) extends Task {
private $resolve;
private $reject;

public function __construct($resolve, $reject) {
$this->resolve = $resolve;
$this->reject = $reject;
}

public function onRun() : void {
($this->resolve)();
}

public function onCancel() : void {
($this->reject)(new Exception("Task cancelled"));
}
};
PmmpUnit::getInstance()->getScheduler()->scheduleDelayedTask($task, 20);
});
}
}

0 comments on commit 628619a

Please sign in to comment.