You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
231 lines
5.9 KiB
231 lines
5.9 KiB
<?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(); |
|
} |
|
}
|
|
|