The theory of having separate assertion mechanisms for whether you're dealing with asynchronous or blocking code had some merits. In practice the differentiating systems are confusing and leads to complexities in development. Realistically we could have a single assert mechanism with all of the appropriate method signatures changing to support async and blocking constructs. For example, the stringEquals method could be refactored to the following signature:
stringEquals(string $expected, string|Promise|Generator|Coroutine $actual) : ?Promise
This puts slightly more onus on the testing code to ensure they yield Promises from assert that would only be returned if the $actual parameter was an async construct. Alternatively we could always return a Promise even if blocking constructs are used to force yield to always be called.
The theory of having separate assertion mechanisms for whether you're dealing with asynchronous or blocking code had some merits. In practice the differentiating systems are confusing and leads to complexities in development. Realistically we could have a single assert mechanism with all of the appropriate method signatures changing to support async and blocking constructs. For example, the
stringEqualsmethod could be refactored to the following signature:This puts slightly more onus on the testing code to ensure they yield Promises from assert that would only be returned if the
$actualparameter was an async construct. Alternatively we could always return a Promise even if blocking constructs are used to force yield to always be called.