Skip to content

Commit

Permalink
Merge branch '2.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
jsor committed Mar 25, 2017
2 parents dffdcec + 62785ae commit f5b9d6a
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 15 deletions.
39 changes: 24 additions & 15 deletions src/Promise.php
Expand Up @@ -20,7 +20,7 @@ public function __construct(callable $resolver, callable $canceller = null)
public function then(callable $onFulfilled = null, callable $onRejected = null)
{
if (null !== $this->result) {
return $this->result()->then($onFulfilled, $onRejected);
return $this->result->then($onFulfilled, $onRejected);
}

if (null === $this->canceller) {
Expand All @@ -41,7 +41,7 @@ public function then(callable $onFulfilled = null, callable $onRejected = null)
public function done(callable $onFulfilled = null, callable $onRejected = null)
{
if (null !== $this->result) {
return $this->result()->done($onFulfilled, $onRejected);
return $this->result->done($onFulfilled, $onRejected);
}

$this->handlers[] = function (PromiseInterface $promise) use ($onFulfilled, $onRejected) {
Expand Down Expand Up @@ -117,15 +117,7 @@ private function reject($reason = null)

private function settle(PromiseInterface $result)
{
if ($result instanceof LazyPromise) {
$result = $result->promise();
}

if ($result === $this) {
$result = new RejectedPromise(
new \LogicException('Cannot resolve a promise with itself.')
);
}
$result = $this->unwrap($result);

$handlers = $this->handlers;

Expand All @@ -138,13 +130,30 @@ private function settle(PromiseInterface $result)
}
}

private function result()
private function unwrap($promise)
{
while ($this->result instanceof self && null !== $this->result->result) {
$this->result = $this->result->result;
$promise = $this->extract($promise);

while ($promise instanceof self && null !== $promise->result) {
$promise = $this->extract($promise->result);
}

return $promise;
}

private function extract($promise)
{
if ($promise instanceof LazyPromise) {
$promise = $promise->promise();
}

if ($promise === $this) {
return new RejectedPromise(
new \LogicException('Cannot resolve a promise with itself.')
);
}

return $this->result;
return $promise;
}

private function call(callable $callback)
Expand Down
27 changes: 27 additions & 0 deletions tests/PromiseTest/ResolveTestTrait.php
Expand Up @@ -134,6 +134,33 @@ public function resolveShouldRejectWhenResolvedWithItself()
$adapter->resolve($adapter->promise());
}

/**
* @test
*/
public function resolveShouldRejectWhenResolvedWithAPromiseWhichFollowsItself()
{
$adapter1 = $this->getPromiseTestAdapter();
$adapter2 = $this->getPromiseTestAdapter();

$mock = $this->createCallableMock();
$mock
->expects($this->once())
->method('__invoke')
->with(new \LogicException('Cannot resolve a promise with itself.'));

$promise1 = $adapter1->promise();

$promise2 = $adapter2->promise();

$promise2->then(
$this->expectCallableNever(),
$mock
);

$adapter1->resolve($promise2);
$adapter2->resolve($promise1);
}

/** @test */
public function doneShouldInvokeFulfillmentHandler()
{
Expand Down

0 comments on commit f5b9d6a

Please sign in to comment.