Skip to content

Commit 3c0a811

Browse files
authored
Implement await for value (#4)
* Implement await for value * Change for to on
1 parent 80d8b1f commit 3c0a811

File tree

5 files changed

+55
-2
lines changed

5 files changed

+55
-2
lines changed

.php-cs-fixer.dist.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
'increment_style' => ['style' => 'pre'],
3030
'single_quote' => true,
3131
'trim_array_spaces' => true,
32-
'single_blank_line_before_namespace' => true,
3332
'yoda_style' => false,
3433
'global_namespace_import' => [
3534
'import_classes' => false,

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
},
2222
"require-dev": {
2323
"friendsofphp/php-cs-fixer": "^3.2",
24-
"phpstan/phpstan": "^0.12.69",
24+
"phpstan/phpstan": "^1.10",
2525
"phpunit/phpunit": "^9.5"
2626
},
2727
"autoload": {

src/Await.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,27 @@ public function until(callable $condition): void
4848
}
4949
}
5050
}
51+
52+
/**
53+
* @template T
54+
*
55+
* @param callable(): T $closure
56+
*
57+
* @return T
58+
*/
59+
public function on(callable $closure)
60+
{
61+
$start = microtime(true);
62+
while (true) {
63+
usleep($this->pollInterval);
64+
try {
65+
return $closure();
66+
} catch (\Throwable $throwable) {
67+
}
68+
69+
if (Duration::seconds(microtime(true) - $start) > $this->waitTime) {
70+
throw new TimeoutException('Closure was not able to return value in the specified wait time');
71+
}
72+
}
73+
}
5174
}

tests/AwaitTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Akondas\Exspecto\Tests;
66

77
use function Akondas\Exspecto\await;
8+
89
use Akondas\Exspecto\Duration;
910
use Akondas\Exspecto\Exception\TimeoutException;
1011
use PHPUnit\Framework\TestCase;
@@ -37,4 +38,33 @@ public function testAwaitTimeout(): void
3738
return false;
3839
});
3940
}
41+
42+
public function testReturnValue(): void
43+
{
44+
$iterations = 5;
45+
$start = microtime(true);
46+
47+
$value = await()->atMost(1)->pollInterval(10)->on(function () use (&$iterations): string {
48+
if (--$iterations === 0) {
49+
return 'success';
50+
}
51+
52+
throw new \RuntimeException('not yet');
53+
});
54+
55+
$duration = Duration::seconds(microtime(true) - $start);
56+
57+
self::assertSame('success', $value);
58+
self::assertGreaterThanOrEqual(Duration::milliseconds(50), $duration);
59+
self::assertLessThanOrEqual(Duration::milliseconds(60), $duration);
60+
}
61+
62+
public function testReturnValueTimeout(): void
63+
{
64+
$this->expectException(TimeoutException::class);
65+
66+
await()->atMost(100, Duration::MILLISECONDS)->pollInterval(30)->on(function (): string {
67+
throw new \RuntimeException('not yet');
68+
});
69+
}
4070
}

tests/DurationTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ class DurationTest extends TestCase
1111
{
1212
/**
1313
* @param int|float $duration
14+
*
1415
* @dataProvider durationsProvider
1516
*/
1617
public function testFromUnit($duration, string $unit, int $expected): void

0 commit comments

Comments
 (0)