Completed
Push — master ( 298e09...565401 )
by Ivannis Suárez
02:36
created

PromiseInterfaceTestCase::defaultResolveValue()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
/**
4
 * This file is part of the Cubiche package.
5
 *
6
 * Copyright (c) Cubiche
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
namespace Cubiche\Core\Async\Tests\Units\Promise;
12
13
use Cubiche\Core\Async\Promise\PromiseInterface;
14
use Cubiche\Core\Async\Promise\State;
15
use Cubiche\Core\Async\Tests\Units\TestCase;
16
17
/**
18
 * Promise Interface Test Case Class.
19
 *
20
 * @author Ivannis Suárez Jerez <[email protected]>
21
 * @author Karel Osorio Ramírez <[email protected]>
22
 */
23
abstract class PromiseInterfaceTestCase extends TestCase
24
{
25
    protected $defaultRejectReason;
26
27
    /**
28
     * @return mixed
29
     */
30
    protected function defaultResolveValue()
31
    {
32
        return 'foo';
33
    }
34
35
    /**
36
     * @return mixed
37
     */
38
    protected function defaultRejectReason()
39
    {
40
        if ($this->defaultRejectReason === null) {
41
            $this->defaultRejectReason = new \Exception();
42
        }
43
44
        return $this->defaultRejectReason;
45
    }
46
47
    /**
48
     * Test class.
49
     */
50
    public function testClass()
51
    {
52
        $this
53
            ->testedClass
54
                ->implements(PromiseInterface::class)
55
        ;
56
    }
57
58
    /**
59
     * Test then.
60
     *
61
     * @param PromiseInterface $promise
62
     *
63
     * @dataProvider promiseDataProvider
64
     */
65
    public function testThen(PromiseInterface $promise)
66
    {
67
        $this
68
            ->given($promise)
69
            ->when($then = $promise->then())
70
            ->then()
71
                ->object($then)
72
                    ->isInstanceOf(PromiseInterface::class)
73
                ->boolean($promise->state()->equals($then->state()))
74
                    ->isTrue();
75
76
        if ($promise->state()->equals(State::FULFILLED())) {
77
            $this->fulfilledThenTest($promise);
78
        }
79
80
        if ($promise->state()->equals(State::REJECTED())) {
81
            $this->rejectedThenTest($promise);
82
        }
83
84
        if ($promise->state()->equals(State::PENDING())) {
85
            $this->pendingThenTest($promise);
86
        }
87
    }
88
89
    /**
90
     * @param PromiseInterface $promise
91
     */
92
    protected function fulfilledThenTest(PromiseInterface $promise)
93
    {
94
        $this
95
            ->given(
96
                $onFulfilled = $this->delegateMock(),
97
                $onRejected = $this->delegateMock(),
98
                $onNotify = $this->delegateMock(),
99
                $value = $this->defaultResolveValue()
100
            )
101
            ->when($promise->then($onFulfilled, $onRejected, $onNotify))
102
            ->then()
103
                ->delegateCall($onFulfilled)
104
                    ->withArguments($value)
105
                    ->once()
106
                ->delegateCall($onRejected)
107
                    ->never()
108
                ->delegateCall($onNotify)
109
                    ->never();
110
111
        $this
112
            ->given(
113
                $onFulfilled = $this->delegateMockWithReturn('bar'),
114
                $onFulfilledThen = $this->delegateMock()
115
            )
116
            ->when($promise->then($onFulfilled)->then($onFulfilledThen))
117
            ->then()
118
                ->delegateCall($onFulfilled)
119
                    ->withArguments($value)
120
                    ->once()
121
                ->delegateCall($onFulfilledThen)
122
                    ->withArguments('bar')
123
                    ->once();
124
125
        $this
126
            ->given(
127
                $e = new \Exception(),
128
                $onFulfilled = $this->delegateMockWithException($e),
129
                $onRejectedThen = $this->delegateMock(),
130
                $onFulfilledThen = $this->delegateMock()
131
            )
132
            ->when($promise->then($onFulfilled)->then($onFulfilledThen, $onRejectedThen))
133
            ->then()
134
                ->delegateCall($onFulfilled)
135
                    ->withArguments($value)
136
                    ->once()
137
                ->delegateCall($onFulfilledThen)
138
                    ->never()
139
                ->delegateCall($onRejectedThen)
140
                    ->withArguments($e)
141
                    ->once();
142
    }
143
144
    /**
145
     * @param PromiseInterface $promise
146
     */
147
    protected function rejectedThenTest(PromiseInterface $promise)
148
    {
149
        $this
150
            ->given(
151
                $onFulfilled = $this->delegateMock(),
152
                $onRejected = $this->delegateMock(),
153
                $onNotify = $this->delegateMock(),
154
                $reason = $this->defaultRejectReason()
155
            )
156
            ->when($promise->then($onFulfilled, $onRejected, $onNotify))
157
            ->then()
158
                ->delegateCall($onFulfilled)
159
                    ->never()
160
                ->delegateCall($onRejected)
161
                    ->withArguments($reason)
162
                    ->once()
163
                ->delegateCall($onNotify)
164
                    ->never()
165
        ;
166
167
        $this
168
            ->given(
169
                $e = new \Exception(),
170
                $onRejected = $this->delegateMockWithException($e),
171
                $onRejectedThen = $this->delegateMock(),
172
                $onFulfilledThen = $this->delegateMock()
173
            )
174
            ->when($promise->then(null, $onRejected)->then($onFulfilledThen, $onRejectedThen))
175
            ->then()
176
                ->delegateCall($onRejected)
177
                    ->withArguments($reason)
178
                    ->once()
179
                ->delegateCall($onFulfilledThen)
180
                    ->never()
181
                ->delegateCall($onRejectedThen)
182
                     ->withArguments($e)
183
                     ->once();
184
    }
185
186
    /**
187
     * @param PromiseInterface $promise
188
     */
189
    protected function pendingThenTest(PromiseInterface $promise)
190
    {
191
        $this
192
            ->given(
193
                $onFulfilled = $this->delegateMock(),
194
                $onRejected = $this->delegateMock(),
195
                $onNotify = $this->delegateMock()
196
            )
197
            ->when($promise->then($onFulfilled, $onRejected, $onNotify))
198
            ->then()
199
                ->delegateCall($onFulfilled)
200
                    ->never()
201
                ->delegateCall($onRejected)
202
                    ->never()
203
                ->delegateCall($onNotify)
204
                    ->never();
205
    }
206
207
    /**
208
     * Test otherwise.
209
     *
210
     * @param PromiseInterface $promise
211
     *
212
     * @dataProvider promiseDataProvider
213
     */
214
    public function testOtherwise(PromiseInterface $promise)
215
    {
216
        $this
217
            ->given(
218
                $promise,
219
                $catch = $this->delegateMock()
220
            )
221
            ->when($otherwise = $promise->otherwise($catch))
222
            ->then()
223
                ->object($otherwise)
224
                    ->isInstanceOf(PromiseInterface::class)
225
                ->boolean($promise->state()->equals($otherwise->state()))
226
                    ->isTrue();
227
228
        if ($promise->state()->equals(State::FULFILLED())) {
229
            $this
230
                ->then()
231
                    ->delegateCall($catch)
232
                        ->never()
233
            ;
234
        }
235
236 View Code Duplication
        if ($promise->state()->equals(State::REJECTED())) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
237
            $this
238
                ->given($reason = $this->defaultRejectReason())
239
                ->then()
240
                    ->delegateCall($catch)
241
                        ->withArguments($reason)
242
                        ->once()
243
            ;
244
        }
245
    }
246
247
    /**
248
     * Test always.
249
     *
250
     * @param PromiseInterface $promise
251
     *
252
     * @dataProvider promiseDataProvider
253
     */
254
    public function testAlways(PromiseInterface $promise)
255
    {
256
        $this
257
            ->given(
258
                $promise,
259
                $finally = $this->delegateMock(),
260
                $onNotify = $this->delegateMock()
261
            )
262
            ->when($always = $promise->always($finally, $onNotify))
263
            ->then()
264
                ->object($always)
265
                    ->isInstanceOf(PromiseInterface::class)
266
                ->boolean($promise->state()->equals($always->state()))
267
                    ->isTrue();
268
269
        if ($promise->state()->equals(State::FULFILLED())) {
270
            $this
271
                ->given($value = $this->defaultResolveValue())
272
                ->then()
273
                    ->delegateCall($finally)
274
                        ->withArguments($value, null)
275
                        ->once()
276
            ;
277
        }
278
279 View Code Duplication
        if ($promise->state()->equals(State::REJECTED())) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
280
            $this
281
                ->given($reason = $this->defaultRejectReason())
282
                ->then()
283
                    ->delegateCall($finally)
284
                        ->withArguments(null, $reason)
285
                        ->once()
286
            ;
287
        }
288
    }
289
290
    /**
291
     * @return array
292
     */
293
    abstract protected function promiseDataProvider();
294
}
295