Skip to content

Commit

Permalink
Implement await for value
Browse files Browse the repository at this point in the history
  • Loading branch information
akondas committed Jan 22, 2024
1 parent 80d8b1f commit 968d92f
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 2 deletions.
1 change: 0 additions & 1 deletion .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
'increment_style' => ['style' => 'pre'],
'single_quote' => true,
'trim_array_spaces' => true,
'single_blank_line_before_namespace' => true,
'yoda_style' => false,
'global_namespace_import' => [
'import_classes' => false,
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.2",
"phpstan/phpstan": "^0.12.69",
"phpstan/phpstan": "^1.10",
"phpunit/phpunit": "^9.5"
},
"autoload": {
Expand Down
23 changes: 23 additions & 0 deletions src/Await.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,27 @@ public function until(callable $condition): void
}
}
}

/**
* @template T
*
* @param callable(): T $closure
*
* @return T
*/
public function for(callable $closure)
{
$start = microtime(true);
while (true) {
usleep($this->pollInterval);
try {
return $closure();
} catch (\Throwable $throwable) {
}

if (Duration::seconds(microtime(true) - $start) > $this->waitTime) {
throw new TimeoutException('Closure was not able to return value in the specified wait time');
}
}
}
}
30 changes: 30 additions & 0 deletions tests/AwaitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Akondas\Exspecto\Tests;

use function Akondas\Exspecto\await;

use Akondas\Exspecto\Duration;
use Akondas\Exspecto\Exception\TimeoutException;
use PHPUnit\Framework\TestCase;
Expand Down Expand Up @@ -37,4 +38,33 @@ public function testAwaitTimeout(): void
return false;
});
}

public function testReturnValue(): void
{
$iterations = 5;
$start = microtime(true);

$value = await()->atMost(1)->pollInterval(10)->for(function () use (&$iterations): string {
if (--$iterations === 0) {
return 'success';
}

throw new \RuntimeException('not yet');
});

$duration = Duration::seconds(microtime(true) - $start);

self::assertSame('success', $value);
self::assertGreaterThanOrEqual(Duration::milliseconds(50), $duration);
self::assertLessThanOrEqual(Duration::milliseconds(60), $duration);
}

public function testReturnValueTimeout(): void
{
$this->expectException(TimeoutException::class);

await()->atMost(100, Duration::MILLISECONDS)->pollInterval(30)->for(function (): string {
throw new \RuntimeException('not yet');
});
}
}
1 change: 1 addition & 0 deletions tests/DurationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class DurationTest extends TestCase
{
/**
* @param int|float $duration
*
* @dataProvider durationsProvider
*/
public function testFromUnit($duration, string $unit, int $expected): void
Expand Down

0 comments on commit 968d92f

Please sign in to comment.