1<?php
2
3namespace React\Promise;
4
5use React\Promise\PromiseAdapter\CallbackPromiseAdapter;
6
7class RejectedPromiseTest extends TestCase
8{
9    use PromiseTest\PromiseSettledTestTrait,
10        PromiseTest\PromiseRejectedTestTrait;
11
12    public function getPromiseTestAdapter(callable $canceller = null)
13    {
14        $promise = null;
15
16        return new CallbackPromiseAdapter([
17            'promise' => function () use (&$promise) {
18                if (!$promise) {
19                    throw new \LogicException('RejectedPromise must be rejected before obtaining the promise');
20                }
21
22                return $promise;
23            },
24            'resolve' => function () {
25                throw new \LogicException('You cannot call resolve() for React\Promise\RejectedPromise');
26            },
27            'reject' => function ($reason = null) use (&$promise) {
28                if (!$promise) {
29                    $promise = new RejectedPromise($reason);
30                }
31            },
32            'notify' => function () {
33                // no-op
34            },
35            'settle' => function ($reason = null) use (&$promise) {
36                if (!$promise) {
37                    $promise = new RejectedPromise($reason);
38                }
39            },
40        ]);
41    }
42
43    /** @test */
44    public function shouldThrowExceptionIfConstructedWithAPromise()
45    {
46        $this->setExpectedException('\InvalidArgumentException');
47
48        return new RejectedPromise(new RejectedPromise());
49    }
50
51    /** @test */
52    public function shouldNotLeaveGarbageCyclesWhenRemovingLastReferenceToRejectedPromiseWithAlwaysFollowers()
53    {
54        gc_collect_cycles();
55        $promise = new RejectedPromise(1);
56        $promise->always(function () {
57            throw new \RuntimeException();
58        });
59        unset($promise);
60
61        $this->assertSame(0, gc_collect_cycles());
62    }
63
64    /** @test */
65    public function shouldNotLeaveGarbageCyclesWhenRemovingLastReferenceToRejectedPromiseWithThenFollowers()
66    {
67        gc_collect_cycles();
68        $promise = new RejectedPromise(1);
69        $promise = $promise->then(null, function () {
70            throw new \RuntimeException();
71        });
72        unset($promise);
73
74        $this->assertSame(0, gc_collect_cycles());
75    }
76}
77