Skip to content

Commit

Permalink
Add tests for Promise::any() and Promise::all()
Browse files Browse the repository at this point in the history
  • Loading branch information
roxblnfk committed Sep 14, 2023
1 parent 35a857d commit d25a629
Show file tree
Hide file tree
Showing 4 changed files with 274 additions and 2 deletions.
106 changes: 106 additions & 0 deletions tests/Unit/Promise/FunctionAllTestCase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<?php

declare(strict_types=1);

namespace Promise;

use React\Promise\Deferred;
use Temporal\Promise;
use Temporal\Tests\Unit\Promise\BaseFunction;

/**
* Got from reactphp/promise and modified
* @license MIT
* @link https://github.com/reactphp/promise/blob/f913fb8cceba1e6644b7b90c4bfb678ed8a3ef38/tests/FunctionAllTest.php
*/
final class FunctionAllTestCase extends BaseFunction
{
public function testResolveEmptyInput(): void
{
$mock = $this->createCallableMock();
$mock
->expects($this->once())
->method('__invoke')
->with($this->identicalTo([]));

Promise::all([])
->then($mock);
}

public function testResolveValuesArray(): void
{
$mock = $this->createCallableMock();
$mock
->expects($this->once())
->method('__invoke')
->with($this->identicalTo([1, 2, 3]));

Promise::all([1, 2, 3])
->then($mock);
}

public function testResolvePromisesArray(): void
{
$mock = $this->createCallableMock();
$mock
->expects($this->once())
->method('__invoke')
->with($this->identicalTo([1, 2, 3]));

Promise::all([Promise::resolve(1), Promise::resolve(2), Promise::resolve(3)])
->then($mock);
}

public function testResolveSparseArrayInput(): void
{
$mock = $this->createCallableMock();
$mock
->expects($this->once())
->method('__invoke')
->with($this->identicalTo([null, 1, null, 1, 1]));

Promise::all([null, 1, null, 1, 1])
->then($mock);
}

public function testRejectIfAnyInputPromiseRejects(): void
{
$e = new \Exception();
$mock = $this->createCallableMock();
$mock
->expects($this->once())
->method('__invoke')
->with($this->identicalTo($e));

Promise::all([Promise::resolve(1), Promise::reject($e), Promise::resolve(3)])
->then($this->expectCallableNever(), $mock);
}

public function testAcceptAPromiseForAnArray(): void
{
$mock = $this->createCallableMock();
$mock
->expects($this->once())
->method('__invoke')
->with($this->identicalTo([1, 2, 3]));

Promise::all([Promise::resolve(1), Promise::resolve(2), Promise::resolve(3)])
->then($mock);
}

public function testPreserveTheOrderOfArrayWhenResolvingAsyncPromises(): void
{
$mock = $this->createCallableMock();
$mock
->expects($this->once())
->method('__invoke')
->with($this->identicalTo([1, 2, 3]));

$deferred = new Deferred();

Promise::all([Promise::resolve(1), $deferred->promise(), Promise::resolve(3)])
->then($mock);

$deferred->resolve(2);
}
}
166 changes: 166 additions & 0 deletions tests/Unit/Promise/FunctionAnyTestCase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
<?php

declare(strict_types=1);

namespace Promise;

use React\Promise\Deferred;
use React\Promise\Exception\LengthException;
use Temporal\Internal\Promise\Reasons;
use Temporal\Promise;
use Temporal\Tests\Unit\Promise\BaseFunction;

/**
* Got from reactphp/promise and modified
* @license MIT
* @link https://github.com/reactphp/promise/blob/f913fb8cceba1e6644b7b90c4bfb678ed8a3ef38/tests/FunctionAnyTest.php
*/
final class FunctionAnyTestCase extends BaseFunction
{
public function testRejectWithLengthExceptionWithEmptyInputArray(): void
{
$mock = $this->createCallableMock();
$mock
->expects($this->once())
->method('__invoke')
->with(
$this->callback(function ($exception) {
return $exception instanceof LengthException &&
'Input array must contain at least 1 item but contains only 0 items.' === $exception->getMessage();
})
);

Promise::any([])
->then($this->expectCallableNever(), $mock);
}

public function testResolveWithAnInputValue(): void
{
$mock = $this->createCallableMock();
$mock
->expects($this->once())
->method('__invoke')
->with($this->identicalTo(1));

Promise::any([1, 2, 3])
->then($mock);
}

public function testResolveWithAPromisedInputValue(): void
{
$mock = $this->createCallableMock();
$mock
->expects($this->once())
->method('__invoke')
->with($this->identicalTo(1));

Promise::any([Promise::resolve(1), Promise::resolve(2), Promise::resolve(3)])
->then($mock);
}

public function testRejectWithAllRejectedInputValuesIfAllInputsAreRejected(): void
{
$e1 = new \Exception();
$e2 = new \Exception();
$e3 = new \Exception();

$mock = $this->createCallableMock();
$mock
->expects($this->once())
->method('__invoke')
->with($this->callback(fn (Reasons $e): bool => \iterator_to_array($e) === [0 => $e1, 1 => $e2, 2 => $e3]));

Promise::any([Promise::reject($e1), Promise::reject($e2), Promise::reject($e3)])
->then($this->expectCallableNever(), $mock);
}

public function testResolveWhenFirstInputPromiseResolves(): void
{
$mock = $this->createCallableMock();
$mock
->expects($this->once())
->method('__invoke')
->with($this->identicalTo(1));

Promise::any([Promise::resolve(1), Promise::reject(new \Exception()), Promise::reject(new \Exception())])
->then($mock);
}

public function testNotRelyOnArryIndexesWhenUnwrappingToASingleResolutionValue(): void
{
$mock = $this->createCallableMock();
$mock
->expects($this->once())
->method('__invoke')
->with($this->identicalTo(2));

$d1 = new Deferred();
$d2 = new Deferred();

Promise::any(['abc' => $d1->promise(), 1 => $d2->promise()])
->then($mock);

$d2->resolve(2);
$d1->resolve(1);
}

public function testRejectWhenInputPromiseRejects(): void
{
$e = new \Exception();
$mock = $this->createCallableMock();
$mock
->expects($this->once())
->method('__invoke')
// ->with($this->identicalTo(null));
->with($this->callback(fn (Reasons $reason): bool => \iterator_to_array($reason) === [$e]));

Promise::any([Promise::reject($e)])
->then($this->expectCallableNever(), $mock)
->then(null, fn(\Throwable $e) => null);
}

public function testCancelInputPromise(): void
{
$mock = $this->creteCancellableMock();
$mock
->expects($this->once())
->method('cancel');

Promise::any([$mock])->cancel();
}

public function testCancelInputArrayPromises(): void
{
$mock1 = $this->creteCancellableMock();
$mock1
->expects($this->once())
->method('cancel');

$mock2 = $this->creteCancellableMock();
$mock2
->expects($this->once())
->method('cancel');

Promise::any([$mock1, $mock2])->cancel();
}

public function testNotCancelOtherPendingInputArrayPromisesIfOnePromiseFulfills(): void
{
$e = new \Exception();
$mock = $this->createCallableMock();
$mock
->expects($this->never())
->method('__invoke');


$deferred = new Deferred($mock);
$deferred->resolve($e);

$mock2 = $this->creteCancellableMock();
$mock2
->expects($this->never())
->method('cancel');

Promise::some([$deferred->promise(), $mock2], 1)->cancel();
}
}
2 changes: 1 addition & 1 deletion tests/Unit/Promise/FunctionReduceTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* @license MIT
* @link https://github.com/reactphp/promise/blob/f913fb8cceba1e6644b7b90c4bfb678ed8a3ef38/tests/FunctionReduceTest.php
*/
class FunctionReduceTestCase extends BaseFunction
final class FunctionReduceTestCase extends BaseFunction
{
public function testReduceValuesWithoutInitialValue(): void
{
Expand Down
2 changes: 1 addition & 1 deletion tests/Unit/Promise/FunctionSomeTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* @license MIT
* @link https://github.com/reactphp/promise/blob/f913fb8cceba1e6644b7b90c4bfb678ed8a3ef38/tests/FunctionSomeTest.php
*/
class FunctionSomeTestCase extends BaseFunction
final class FunctionSomeTestCase extends BaseFunction
{
public function testRejectWithLengthExceptionWithEmptyInputArray(): void
{
Expand Down

0 comments on commit d25a629

Please sign in to comment.