2024-09-18 13:29:44 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace Appwrite\Tests\Async;
|
|
|
|
|
|
2025-08-16 14:59:05 +00:00
|
|
|
use Appwrite\Tests\Async\Exceptions\Critical;
|
2024-09-18 13:29:44 +00:00
|
|
|
use PHPUnit\Framework\Constraint\Constraint;
|
|
|
|
|
|
|
|
|
|
final class Eventually extends Constraint
|
|
|
|
|
{
|
2024-09-25 11:32:09 +00:00
|
|
|
public function __construct(private int $timeoutMs, private int $waitMs)
|
2024-09-18 13:29:44 +00:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function evaluate(mixed $probe, string $description = '', bool $returnResult = false): ?bool
|
|
|
|
|
{
|
|
|
|
|
if (!is_callable($probe)) {
|
|
|
|
|
throw new \Exception('Probe must be a callable');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$start = microtime(true);
|
|
|
|
|
$lastException = null;
|
|
|
|
|
|
|
|
|
|
do {
|
|
|
|
|
try {
|
|
|
|
|
$probe();
|
|
|
|
|
return true;
|
2025-08-16 14:59:05 +00:00
|
|
|
} catch (Critical $exception) {
|
|
|
|
|
throw $exception;
|
2024-09-18 13:29:44 +00:00
|
|
|
} catch (\Exception $exception) {
|
|
|
|
|
$lastException = $exception;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
usleep($this->waitMs * 1000);
|
|
|
|
|
} while (microtime(true) - $start < $this->timeoutMs / 1000);
|
|
|
|
|
|
|
|
|
|
if ($returnResult) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
throw $lastException;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected function failureDescription(mixed $other): string
|
|
|
|
|
{
|
|
|
|
|
return 'the given probe was satisfied within ' . $this->timeoutMs . 'ms.';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function toString(): string
|
|
|
|
|
{
|
|
|
|
|
return 'Eventually';
|
|
|
|
|
}
|
|
|
|
|
}
|