<?php
namespace React\Promise\PromiseTest;
trait PromiseFulfilledTestTrait
{
/**
* @return \React\Promise\PromiseAdapter\PromiseAdapterInterface
*/
abstract public function getPromiseTestAdapter(callable $canceller = null);
/** @test */
public function fulfilledPromiseShouldBeImmutable()
{
$adapter = $this->getPromiseTestAdapter();
$mock = $this->createCallableMock();
$mock
->expects($this->once())
->method('__invoke')
->with($this->identicalTo(1));
$adapter->resolve(1);
$adapter->resolve(2);
$adapter->promise()
->then(
$mock,
$this->expectCallableNever()
);
}
/** @test */
public function fulfilledPromiseShouldInvokeNewlyAddedCallback()
{
$adapter = $this->getPromiseTestAdapter();
$adapter->resolve(1);
$mock = $this->createCallableMock();
$mock
->expects($this->once())
->method('__invoke')
->with($this->identicalTo(1));
$adapter->promise()
->then($mock, $this->expectCallableNever());
}
/** @test */
public function thenShouldForwardResultWhenCallbackIsNull()
{
$adapter = $this->getPromiseTestAdapter();
$mock = $this->createCallableMock();
$mock
->expects($this->once())
->method('__invoke')
->with($this->identicalTo(1));
$adapter->resolve(1);
$adapter->promise()
->then(
null,
$this->expectCallableNever()
)
->then(
$mock,
$this->expectCallableNever()
);
}
/** @test */
public function thenShouldForwardCallbackResultToNextCallback()
{
$adapter = $this->getPromiseTestAdapter();
$mock = $this->createCallableMock();
$mock
->expects($this->once())
->method('__invoke')
->with($this->identicalTo(2));
$adapter->resolve(1);
$adapter->promise()
->then(
function ($val) {
return $val + 1;
},
$this->expectCallableNever()
)
->then(
$mock,
$this->expectCallableNever()
);
}
/** @test */
public function thenShouldForwardPromisedCallbackResultValueToNextCallback()
{
$adapter = $this->getPromiseTestAdapter();
$mock = $this->createCallableMock();
$mock
->expects($this->once())
->method('__invoke')
->with($this->identicalTo(2));
$adapter->resolve(1);
$adapter->promise()
->then(
function ($val) {
return \React\Promise\resolve($val + 1);
},
$this->expectCallableNever()
)
->then(
$mock,
$this->expectCallableNever()
);
}
/** @test */
public function thenShouldSwitchFromCallbacksToErrbacksWhenCallbackReturnsARejection()
{
$adapter = $this->getPromiseTestAdapter();
$mock = $this->createCallableMock();
$mock
->expects($this->once())
->method('__invoke')
->with($this->identicalTo(2));
$adapter->resolve(1);
$adapter->promise()
->then(
function ($val) {
return \React\Promise\reject($val + 1);
},
$this->expectCallableNever()
)
->then(
$this->expectCallableNever(),
$mock
);
}
/** @test */
public function thenShouldSwitchFromCallbacksToErrbacksWhenCallbackThrows()
{
$adapter = $this->getPromiseTestAdapter();
$exception = new \Exception();
$mock = $this->createCallableMock();
$mock
->expects($this->once())
->method('__invoke')
->will($this->throwException($exception));
$mock2 = $this->createCallableMock();
$mock2
->expects($this->once())
->method('__invoke')
->with($this->identicalTo($exception));
$adapter->resolve(1);
$adapter->promise()
->then(
$mock,
$this->expectCallableNever()
)
->then(
$this->expectCallableNever(),
$mock2
);
}
/** @test */
public function cancelShouldReturnNullForFulfilledPromise()
{
$adapter = $this->getPromiseTestAdapter();
$adapter->resolve();
$this->assertNull($adapter->promise()->cancel());
}
/** @test */
public function cancelShouldHaveNoEffectForFulfilledPromise()
{
$adapter = $this->getPromiseTestAdapter($this->expectCallableNever());
$adapter->resolve();
$adapter->promise()->cancel();
}
/** @test */
public function doneShouldInvokeFulfillmentHandlerForFulfilledPromise()
{
$adapter = $this->getPromiseTestAdapter();
$mock = $this->createCallableMock();
$mock
->expects($this->once())
->method('__invoke')
->with($this->identicalTo(1));
$adapter->resolve(1);
$this->assertNull($adapter->promise()->done($mock));
}
/** @test */
public function doneShouldThrowExceptionThrownFulfillmentHandlerForFulfilledPromise()
{
$adapter = $this->getPromiseTestAdapter();
$this->setExpectedException('\Exception', 'UnhandledRejectionException');
$adapter->resolve(1);
$this->assertNull($adapter->promise()->done(function () {
throw new \Exception('UnhandledRejectionException');
}));
}
/** @test */
public function doneShouldThrowUnhandledRejectionExceptionWhenFulfillmentHandlerRejectsForFulfilledPromise()
{
$adapter = $this->getPromiseTestAdapter();
$this->setExpectedException('React\\Promise\\UnhandledRejectionException');
$adapter->resolve(1);
$this->assertNull($adapter->promise()->done(function () {
return \React\Promise\reject();
}));
}
/** @test */
public function otherwiseShouldNotInvokeRejectionHandlerForFulfilledPromise()
{
$adapter = $this->getPromiseTestAdapter();
$adapter->resolve(1);
$adapter->promise()->otherwise($this->expectCallableNever());
}
/** @test */
public function alwaysShouldNotSuppressValueForFulfilledPromise()
{
$adapter = $this->getPromiseTestAdapter();
$value = new \stdClass();
$mock = $this->createCallableMock();
$mock
->expects($this->once())
->method('__invoke')
->with($this->identicalTo($value));
$adapter->resolve($value);
$adapter->promise()
->always(function () {})
->then($mock);
}
/** @test */
public function alwaysShouldNotSuppressValueWhenHandlerReturnsANonPromiseForFulfilledPromise()
{
$adapter = $this->getPromiseTestAdapter();
$value = new \stdClass();
$mock = $this->createCallableMock();
$mock
->expects($this->once())
->method('__invoke')
->with($this->identicalTo($value));
$adapter->resolve($value);
$adapter->promise()
->always(function () {
return 1;
})
->then($mock);
}
/** @test */
public function alwaysShouldNotSuppressValueWhenHandlerReturnsAPromiseForFulfilledPromise()
{
$adapter = $this->getPromiseTestAdapter();
$value = new \stdClass();
$mock = $this->createCallableMock();
$mock
->expects($this->once())
->method('__invoke')
->with($this->identicalTo($value));
$adapter->resolve($value);
$adapter->promise()
->always(function () {
return \React\Promise\resolve(1);
})
->then($mock);
}
/** @test */
public function alwaysShouldRejectWhenHandlerThrowsForFulfilledPromise()
{
$adapter = $this->getPromiseTestAdapter();
$exception = new \Exception();
$mock = $this->createCallableMock();
$mock
->expects($this->once())
->method('__invoke')
->with($this->identicalTo($exception));
$adapter->resolve(1);
$adapter->promise()
->always(function () use ($exception) {
throw $exception;
})
->then(null, $mock);
}
/** @test */
public function alwaysShouldRejectWhenHandlerRejectsForFulfilledPromise()
{
$adapter = $this->getPromiseTestAdapter();
$exception = new \Exception();
$mock = $this->createCallableMock();
$mock
->expects($this->once())
->method('__invoke')
->with($this->identicalTo($exception));
$adapter->resolve(1);
$adapter->promise()
->always(function () use ($exception) {
return \React\Promise\reject($exception);
})
->then(null, $mock);
}
}