232 lines
5.9 KiB
PHP
232 lines
5.9 KiB
PHP
<?php
|
|
|
|
namespace React\Promise\PromiseTest;
|
|
|
|
use React\Promise;
|
|
|
|
trait CancelTestTrait
|
|
{
|
|
/**
|
|
* @return \React\Promise\PromiseAdapter\PromiseAdapterInterface
|
|
*/
|
|
abstract public function getPromiseTestAdapter(callable $canceller = null);
|
|
|
|
/** @test */
|
|
public function cancelShouldCallCancellerWithResolverArguments()
|
|
{
|
|
$mock = $this->createCallableMock();
|
|
$mock
|
|
->expects($this->once())
|
|
->method('__invoke')
|
|
->with($this->isType('callable'), $this->isType('callable'), $this->isType('callable'));
|
|
|
|
$adapter = $this->getPromiseTestAdapter($mock);
|
|
|
|
$adapter->promise()->cancel();
|
|
}
|
|
|
|
/** @test */
|
|
public function cancelShouldFulfillPromiseIfCancellerFulfills()
|
|
{
|
|
$adapter = $this->getPromiseTestAdapter(function ($resolve) {
|
|
$resolve(1);
|
|
});
|
|
|
|
$mock = $this->createCallableMock();
|
|
$mock
|
|
->expects($this->once())
|
|
->method('__invoke')
|
|
->with($this->identicalTo(1));
|
|
|
|
$adapter->promise()
|
|
->then($mock, $this->expectCallableNever());
|
|
|
|
$adapter->promise()->cancel();
|
|
}
|
|
|
|
/** @test */
|
|
public function cancelShouldRejectPromiseIfCancellerRejects()
|
|
{
|
|
$adapter = $this->getPromiseTestAdapter(function ($resolve, $reject) {
|
|
$reject(1);
|
|
});
|
|
|
|
$mock = $this->createCallableMock();
|
|
$mock
|
|
->expects($this->once())
|
|
->method('__invoke')
|
|
->with($this->identicalTo(1));
|
|
|
|
$adapter->promise()
|
|
->then($this->expectCallableNever(), $mock);
|
|
|
|
$adapter->promise()->cancel();
|
|
}
|
|
|
|
/** @test */
|
|
public function cancelShouldRejectPromiseWithExceptionIfCancellerThrows()
|
|
{
|
|
$e = new \Exception();
|
|
|
|
$adapter = $this->getPromiseTestAdapter(function () use ($e) {
|
|
throw $e;
|
|
});
|
|
|
|
$mock = $this->createCallableMock();
|
|
$mock
|
|
->expects($this->once())
|
|
->method('__invoke')
|
|
->with($this->identicalTo($e));
|
|
|
|
$adapter->promise()
|
|
->then($this->expectCallableNever(), $mock);
|
|
|
|
$adapter->promise()->cancel();
|
|
}
|
|
|
|
/** @test */
|
|
public function cancelShouldProgressPromiseIfCancellerNotifies()
|
|
{
|
|
$adapter = $this->getPromiseTestAdapter(function ($resolve, $reject, $progress) {
|
|
$progress(1);
|
|
});
|
|
|
|
$mock = $this->createCallableMock();
|
|
$mock
|
|
->expects($this->once())
|
|
->method('__invoke')
|
|
->with($this->identicalTo(1));
|
|
|
|
$adapter->promise()
|
|
->then($this->expectCallableNever(), $this->expectCallableNever(), $mock);
|
|
|
|
$adapter->promise()->cancel();
|
|
}
|
|
|
|
/** @test */
|
|
public function cancelShouldCallCancellerOnlyOnceIfCancellerResolves()
|
|
{
|
|
$mock = $this->createCallableMock();
|
|
$mock
|
|
->expects($this->once())
|
|
->method('__invoke')
|
|
->will($this->returnCallback(function ($resolve) {
|
|
$resolve();
|
|
}));
|
|
|
|
$adapter = $this->getPromiseTestAdapter($mock);
|
|
|
|
$adapter->promise()->cancel();
|
|
$adapter->promise()->cancel();
|
|
}
|
|
|
|
/** @test */
|
|
public function cancelShouldHaveNoEffectIfCancellerDoesNothing()
|
|
{
|
|
$adapter = $this->getPromiseTestAdapter(function () {});
|
|
|
|
$adapter->promise()
|
|
->then($this->expectCallableNever(), $this->expectCallableNever());
|
|
|
|
$adapter->promise()->cancel();
|
|
$adapter->promise()->cancel();
|
|
}
|
|
|
|
/** @test */
|
|
public function cancelShouldCallCancellerFromDeepNestedPromiseChain()
|
|
{
|
|
$mock = $this->createCallableMock();
|
|
$mock
|
|
->expects($this->once())
|
|
->method('__invoke');
|
|
|
|
$adapter = $this->getPromiseTestAdapter($mock);
|
|
|
|
$promise = $adapter->promise()
|
|
->then(function () {
|
|
return new Promise\Promise(function () {});
|
|
})
|
|
->then(function () {
|
|
$d = new Promise\Deferred();
|
|
|
|
return $d->promise();
|
|
})
|
|
->then(function () {
|
|
return new Promise\Promise(function () {});
|
|
});
|
|
|
|
$promise->cancel();
|
|
}
|
|
|
|
/** @test */
|
|
public function cancelCalledOnChildrenSouldOnlyCancelWhenAllChildrenCancelled()
|
|
{
|
|
$adapter = $this->getPromiseTestAdapter($this->expectCallableNever());
|
|
|
|
$child1 = $adapter->promise()
|
|
->then()
|
|
->then();
|
|
|
|
$adapter->promise()
|
|
->then();
|
|
|
|
$child1->cancel();
|
|
}
|
|
|
|
/** @test */
|
|
public function cancelShouldTriggerCancellerWhenAllChildrenCancel()
|
|
{
|
|
$adapter = $this->getPromiseTestAdapter($this->expectCallableOnce());
|
|
|
|
$child1 = $adapter->promise()
|
|
->then()
|
|
->then();
|
|
|
|
$child2 = $adapter->promise()
|
|
->then();
|
|
|
|
$child1->cancel();
|
|
$child2->cancel();
|
|
}
|
|
|
|
/** @test */
|
|
public function cancelShouldNotTriggerCancellerWhenCancellingOneChildrenMultipleTimes()
|
|
{
|
|
$adapter = $this->getPromiseTestAdapter($this->expectCallableNever());
|
|
|
|
$child1 = $adapter->promise()
|
|
->then()
|
|
->then();
|
|
|
|
$child2 = $adapter->promise()
|
|
->then();
|
|
|
|
$child1->cancel();
|
|
$child1->cancel();
|
|
}
|
|
|
|
/** @test */
|
|
public function cancelShouldTriggerCancellerOnlyOnceWhenCancellingMultipleTimes()
|
|
{
|
|
$adapter = $this->getPromiseTestAdapter($this->expectCallableOnce());
|
|
|
|
$adapter->promise()->cancel();
|
|
$adapter->promise()->cancel();
|
|
}
|
|
|
|
/** @test */
|
|
public function cancelShouldAlwaysTriggerCancellerWhenCalledOnRootPromise()
|
|
{
|
|
$adapter = $this->getPromiseTestAdapter($this->expectCallableOnce());
|
|
|
|
$adapter->promise()
|
|
->then()
|
|
->then();
|
|
|
|
$adapter->promise()
|
|
->then();
|
|
|
|
$adapter->promise()->cancel();
|
|
}
|
|
}
|