1<?php
2
3namespace React\Promise;
4
5use React\Promise\PromiseAdapter\CallbackPromiseAdapter;
6
7class LazyPromiseTest extends TestCase
8{
9    use PromiseTest\FullTestTrait;
10
11    public function getPromiseTestAdapter(callable $canceller = null)
12    {
13        $d = new Deferred($canceller);
14
15        $factory = function () use ($d) {
16            return $d->promise();
17        };
18
19        return new CallbackPromiseAdapter([
20            'promise'  => function () use ($factory) {
21                return new LazyPromise($factory);
22            },
23            'resolve' => [$d, 'resolve'],
24            'reject'  => [$d, 'reject'],
25            'notify'  => [$d, 'progress'],
26            'settle'  => [$d, 'resolve'],
27        ]);
28    }
29
30    /** @test */
31    public function shouldNotCallFactoryIfThenIsNotInvoked()
32    {
33        $factory = $this->createCallableMock();
34        $factory
35            ->expects($this->never())
36            ->method('__invoke');
37
38        new LazyPromise($factory);
39    }
40
41    /** @test */
42    public function shouldCallFactoryIfThenIsInvoked()
43    {
44        $factory = $this->createCallableMock();
45        $factory
46            ->expects($this->once())
47            ->method('__invoke');
48
49        $p = new LazyPromise($factory);
50        $p->then();
51    }
52
53    /** @test */
54    public function shouldReturnPromiseFromFactory()
55    {
56        $factory = $this->createCallableMock();
57        $factory
58            ->expects($this->once())
59            ->method('__invoke')
60            ->will($this->returnValue(new FulfilledPromise(1)));
61
62        $onFulfilled = $this->createCallableMock();
63        $onFulfilled
64            ->expects($this->once())
65            ->method('__invoke')
66            ->with($this->identicalTo(1));
67
68        $p = new LazyPromise($factory);
69
70        $p->then($onFulfilled);
71    }
72
73    /** @test */
74    public function shouldReturnPromiseIfFactoryReturnsNull()
75    {
76        $factory = $this->createCallableMock();
77        $factory
78            ->expects($this->once())
79            ->method('__invoke')
80            ->will($this->returnValue(null));
81
82        $p = new LazyPromise($factory);
83        $this->assertInstanceOf('React\\Promise\\PromiseInterface', $p->then());
84    }
85
86    /** @test */
87    public function shouldReturnRejectedPromiseIfFactoryThrowsException()
88    {
89        $exception = new \Exception();
90
91        $factory = $this->createCallableMock();
92        $factory
93            ->expects($this->once())
94            ->method('__invoke')
95            ->will($this->throwException($exception));
96
97        $onRejected = $this->createCallableMock();
98        $onRejected
99            ->expects($this->once())
100            ->method('__invoke')
101            ->with($this->identicalTo($exception));
102
103        $p = new LazyPromise($factory);
104
105        $p->then($this->expectCallableNever(), $onRejected);
106    }
107}
108