Codebase list php-react-promise / 2aceaaf
php-react-promise_2.5.1.orig.tar.gz mirabilos authored 5 years ago mirabilos committed 5 years ago
16 changed file(s) with 241 addition(s) and 93 deletion(s). Raw diff Collapse all Expand all
1414 - composer install
1515
1616 script:
17 - phpunit -v --coverage-text --coverage-clover=./build/logs/clover.xml
17 - ./vendor/bin/phpunit -v --coverage-text --coverage-clover=./build/logs/clover.xml
1818
1919 after_script:
2020 - if [ -f ./build/logs/clover.xml ]; then travis_retry composer require satooshi/php-coveralls --no-interaction --update-with-dependencies; fi
0 CHANGELOG
1 =========
0 CHANGELOG for 2.x
1 =================
2
3 * 2.5.1 (2017-03-25)
4
5 * Fix circular references when resolving with a promise which follows
6 itself (#94).
7
8 * 2.5.0 (2016-12-22)
9
10 * Revert automatic cancellation of pending collection promises once the
11 output promise resolves. This was introduced in 42d86b7 (PR #36, released
12 in [v2.3.0](https://github.com/reactphp/promise/releases/tag/v2.3.0)) and
13 was both unintended and backward incompatible.
14
15 If you need automatic cancellation, you can use something like:
16
17 ```php
18 function allAndCancel(array $promises)
19 {
20 return \React\Promise\all($promises)
21 ->always(function() use ($promises) {
22 foreach ($promises as $promise) {
23 if ($promise instanceof \React\Promise\CancellablePromiseInterface) {
24 $promise->cancel();
25 }
26 }
27 });
28 }
29 ```
30 * `all()` and `map()` functions now preserve the order of the array (#77).
31 * Fix circular references when resolving a promise with itself (#71).
232
333 * 2.4.1 (2016-05-03)
434
6393 when initialized with a promise instead of a value/reason.
6494 * BC break: `Deferred::resolve()` and `Deferred::reject()` no longer return
6595 a promise.
66
67 * 1.0.4 (2013-04-03)
68
69 * Trigger PHP errors when invalid callback is passed.
70 * Fully resolve rejection value before calling rejection handler.
71 * Add `When::lazy()` to create lazy promises which will be initialized once
72 a consumer calls the `then()` method.
73
74 * 1.0.3 (2012-11-17)
75
76 * Add `PromisorInterface` for objects that have a `promise()` method.
77
78 * 1.0.2 (2012-11-14)
79
80 * Fix bug in `When::any()` not correctly unwrapping to a single result
81 value.
82 * `$promiseOrValue` argument of `When::resolve()` and When::reject() is now
83 optional.
84
85 * 1.0.1 (2012-11-13)
86
87 * Prevent deep recursion which was reaching `xdebug.max_nesting_level`
88 default of 100.
89
90 * 1.0.0 (2012-11-07)
91
92 * First tagged release.
66 ],
77 "require": {
88 "php": ">=5.4.0"
9 },
10 "require-dev": {
11 "phpunit/phpunit": "~4.8"
912 },
1013 "autoload": {
1114 "psr-4": {
1821 "React\\Promise\\": "tests/fixtures"
1922 }
2023 },
21 "extra": {
22 "branch-alias": {
23 "dev-master": "2.0-dev"
24 }
25 }
24 "keywords": [
25 "promise",
26 "promises"
27 ]
2628 }
4141 return $this->promise()->cancel();
4242 }
4343
44 private function promise()
44 /**
45 * @internal
46 * @see Promise::settle()
47 */
48 public function promise()
4549 {
4650 if (null === $this->promise) {
4751 try {
2121 public function then(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null)
2222 {
2323 if (null !== $this->result) {
24 return $this->result()->then($onFulfilled, $onRejected, $onProgress);
24 return $this->result->then($onFulfilled, $onRejected, $onProgress);
2525 }
2626
2727 if (null === $this->canceller) {
4242 public function done(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null)
4343 {
4444 if (null !== $this->result) {
45 return $this->result()->done($onFulfilled, $onRejected, $onProgress);
45 return $this->result->done($onFulfilled, $onRejected, $onProgress);
4646 }
4747
4848 $this->handlers[] = function (ExtendedPromiseInterface $promise) use ($onFulfilled, $onRejected) {
154154
155155 private function settle(ExtendedPromiseInterface $promise)
156156 {
157 $promise = $this->unwrap($promise);
158
157159 $handlers = $this->handlers;
158160
159161 $this->progressHandlers = $this->handlers = [];
164166 }
165167 }
166168
167 private function result()
168 {
169 while ($this->result instanceof self && null !== $this->result->result) {
170 $this->result = $this->result->result;
171 }
172
173 return $this->result;
169 private function unwrap($promise)
170 {
171 $promise = $this->extract($promise);
172
173 while ($promise instanceof self && null !== $promise->result) {
174 $promise = $this->extract($promise->result);
175 }
176
177 return $promise;
178 }
179
180 private function extract($promise)
181 {
182 if ($promise instanceof LazyPromise) {
183 $promise = $promise->promise();
184 }
185
186 if ($promise === $this) {
187 return new RejectedPromise(
188 new \LogicException('Cannot resolve a promise with itself.')
189 );
190 }
191
192 return $promise;
174193 }
175194
176195 private function call(callable $callback)
5353 return;
5454 }
5555
56 $fulfiller = function ($value) use ($cancellationQueue, $resolve) {
57 $cancellationQueue();
58 $resolve($value);
59 };
60
61 $rejecter = function ($reason) use ($cancellationQueue, $reject) {
62 $cancellationQueue();
63 $reject($reason);
64 };
65
6656 foreach ($array as $promiseOrValue) {
6757 $cancellationQueue->enqueue($promiseOrValue);
6858
6959 resolve($promiseOrValue)
70 ->done($fulfiller, $rejecter, $notify);
60 ->done($resolve, $reject, $notify);
7161 }
7262 }, $reject, $notify);
7363 }, $cancellationQueue);
114104 $reasons = [];
115105
116106 foreach ($array as $i => $promiseOrValue) {
117 $fulfiller = function ($val) use ($i, &$values, &$toResolve, $toReject, $resolve, $cancellationQueue) {
107 $fulfiller = function ($val) use ($i, &$values, &$toResolve, $toReject, $resolve) {
118108 if ($toResolve < 1 || $toReject < 1) {
119109 return;
120110 }
122112 $values[$i] = $val;
123113
124114 if (0 === --$toResolve) {
125 $cancellationQueue();
126115 $resolve($values);
127116 }
128117 };
129118
130 $rejecter = function ($reason) use ($i, &$reasons, &$toReject, $toResolve, $reject, $cancellationQueue) {
119 $rejecter = function ($reason) use ($i, &$reasons, &$toReject, $toResolve, $reject) {
131120 if ($toResolve < 1 || $toReject < 1) {
132121 return;
133122 }
135124 $reasons[$i] = $reason;
136125
137126 if (0 === --$toReject) {
138 $cancellationQueue();
139127 $reject($reasons);
140128 }
141129 };
167155
168156 foreach ($array as $i => $promiseOrValue) {
169157 $cancellationQueue->enqueue($promiseOrValue);
158 $values[$i] = null;
170159
171160 resolve($promiseOrValue)
172161 ->then($mapFunc)
7373 {
7474 $this->setExpectedException('\Exception', 'test');
7575
76 $mock = $this->getMock('React\Promise\CancellablePromiseInterface');
76 $mock = $this
77 ->getMockBuilder('React\Promise\CancellablePromiseInterface')
78 ->getMock();
7779 $mock
7880 ->expects($this->once())
7981 ->method('cancel')
9393 all(resolve(1))
9494 ->then($mock);
9595 }
96
97 /** @test */
98 public function shouldPreserveTheOrderOfArrayWhenResolvingAsyncPromises()
99 {
100 $mock = $this->createCallableMock();
101 $mock
102 ->expects($this->once())
103 ->method('__invoke')
104 ->with($this->identicalTo([1, 2, 3]));
105
106 $deferred = new Deferred();
107
108 all([resolve(1), $deferred->promise(), resolve(3)])
109 ->then($mock);
110
111 $deferred->resolve(2);
112 }
96113 }
149149 /** @test */
150150 public function shouldCancelInputPromise()
151151 {
152 $mock = $this->getMock('React\Promise\CancellablePromiseInterface');
152 $mock = $this
153 ->getMockBuilder('React\Promise\CancellablePromiseInterface')
154 ->getMock();
153155 $mock
154156 ->expects($this->once())
155157 ->method('cancel');
160162 /** @test */
161163 public function shouldCancelInputArrayPromises()
162164 {
163 $mock1 = $this->getMock('React\Promise\CancellablePromiseInterface');
165 $mock1 = $this
166 ->getMockBuilder('React\Promise\CancellablePromiseInterface')
167 ->getMock();
164168 $mock1
165169 ->expects($this->once())
166170 ->method('cancel');
167171
168 $mock2 = $this->getMock('React\Promise\CancellablePromiseInterface');
172 $mock2 = $this
173 ->getMockBuilder('React\Promise\CancellablePromiseInterface')
174 ->getMock();
169175 $mock2
170176 ->expects($this->once())
171177 ->method('cancel');
174180 }
175181
176182 /** @test */
177 public function shouldCancelOtherPendingInputArrayPromisesIfOnePromiseFulfills()
183 public function shouldNotCancelOtherPendingInputArrayPromisesIfOnePromiseFulfills()
178184 {
179185 $mock = $this->createCallableMock();
180186 $mock
185191 $deferred = New Deferred($mock);
186192 $deferred->resolve();
187193
188 $mock2 = $this->getMock('React\Promise\CancellablePromiseInterface');
194 $mock2 = $this
195 ->getMockBuilder('React\Promise\CancellablePromiseInterface')
196 ->getMock();
189197 $mock2
190 ->expects($this->once())
198 ->expects($this->never())
191199 ->method('cancel');
192200
193201 some([$deferred->promise(), $mock2], 1)->cancel();
108108 }
109109
110110 /** @test */
111 public function shouldPreserveTheOrderOfArrayWhenResolvingAsyncPromises()
112 {
113 $mock = $this->createCallableMock();
114 $mock
115 ->expects($this->once())
116 ->method('__invoke')
117 ->with($this->identicalTo([2, 4, 6]));
118
119 $deferred = new Deferred();
120
121 map(
122 [resolve(1), $deferred->promise(), resolve(3)],
123 $this->mapper()
124 )->then($mock);
125
126 $deferred->resolve(2);
127 }
128
129 /** @test */
111130 public function shouldRejectWhenInputContainsRejection()
112131 {
113132 $mock = $this->createCallableMock();
140159 /** @test */
141160 public function shouldCancelInputPromise()
142161 {
143 $mock = $this->getMock('React\Promise\CancellablePromiseInterface');
162 $mock = $this
163 ->getMockBuilder('React\Promise\CancellablePromiseInterface')
164 ->getMock();
144165 $mock
145166 ->expects($this->once())
146167 ->method('cancel');
154175 /** @test */
155176 public function shouldCancelInputArrayPromises()
156177 {
157 $mock1 = $this->getMock('React\Promise\CancellablePromiseInterface');
178 $mock1 = $this
179 ->getMockBuilder('React\Promise\CancellablePromiseInterface')
180 ->getMock();
158181 $mock1
159182 ->expects($this->once())
160183 ->method('cancel');
161184
162 $mock2 = $this->getMock('React\Promise\CancellablePromiseInterface');
185 $mock2 = $this
186 ->getMockBuilder('React\Promise\CancellablePromiseInterface')
187 ->getMock();
163188 $mock2
164189 ->expects($this->once())
165190 ->method('cancel');
136136 /** @test */
137137 public function shouldCancelInputPromise()
138138 {
139 $mock = $this->getMock('React\Promise\CancellablePromiseInterface');
139 $mock = $this
140 ->getMockBuilder('React\Promise\CancellablePromiseInterface')
141 ->getMock();
140142 $mock
141143 ->expects($this->once())
142144 ->method('cancel');
147149 /** @test */
148150 public function shouldCancelInputArrayPromises()
149151 {
150 $mock1 = $this->getMock('React\Promise\CancellablePromiseInterface');
152 $mock1 = $this
153 ->getMockBuilder('React\Promise\CancellablePromiseInterface')
154 ->getMock();
151155 $mock1
152156 ->expects($this->once())
153157 ->method('cancel');
154158
155 $mock2 = $this->getMock('React\Promise\CancellablePromiseInterface');
159 $mock2 = $this
160 ->getMockBuilder('React\Promise\CancellablePromiseInterface')
161 ->getMock();
156162 $mock2
157163 ->expects($this->once())
158164 ->method('cancel');
161167 }
162168
163169 /** @test */
164 public function shouldCancelOtherPendingInputArrayPromisesIfOnePromiseFulfills()
170 public function shouldNotCancelOtherPendingInputArrayPromisesIfOnePromiseFulfills()
165171 {
166172 $mock = $this->createCallableMock();
167173 $mock
171177 $deferred = New Deferred($mock);
172178 $deferred->resolve();
173179
174 $mock2 = $this->getMock('React\Promise\CancellablePromiseInterface');
180 $mock2 = $this
181 ->getMockBuilder('React\Promise\CancellablePromiseInterface')
182 ->getMock();
175183 $mock2
176 ->expects($this->once())
184 ->expects($this->never())
177185 ->method('cancel');
178186
179187 race([$deferred->promise(), $mock2])->cancel();
180188 }
181189
182190 /** @test */
183 public function shouldCancelOtherPendingInputArrayPromisesIfOnePromiseRejects()
191 public function shouldNotCancelOtherPendingInputArrayPromisesIfOnePromiseRejects()
184192 {
185193 $mock = $this->createCallableMock();
186194 $mock
190198 $deferred = New Deferred($mock);
191199 $deferred->reject();
192200
193 $mock2 = $this->getMock('React\Promise\CancellablePromiseInterface');
201 $mock2 = $this
202 ->getMockBuilder('React\Promise\CancellablePromiseInterface')
203 ->getMock();
194204 $mock2
195 ->expects($this->once())
205 ->expects($this->never())
196206 ->method('cancel');
197207
198208 race([$deferred->promise(), $mock2])->cancel();
306306 /** @test */
307307 public function shouldCancelInputPromise()
308308 {
309 $mock = $this->getMock('React\Promise\CancellablePromiseInterface');
309 $mock = $this
310 ->getMockBuilder('React\Promise\CancellablePromiseInterface')
311 ->getMock();
310312 $mock
311313 ->expects($this->once())
312314 ->method('cancel');
321323 /** @test */
322324 public function shouldCancelInputArrayPromises()
323325 {
324 $mock1 = $this->getMock('React\Promise\CancellablePromiseInterface');
326 $mock1 = $this
327 ->getMockBuilder('React\Promise\CancellablePromiseInterface')
328 ->getMock();
325329 $mock1
326330 ->expects($this->once())
327331 ->method('cancel');
328332
329 $mock2 = $this->getMock('React\Promise\CancellablePromiseInterface');
333 $mock2 = $this
334 ->getMockBuilder('React\Promise\CancellablePromiseInterface')
335 ->getMock();
330336 $mock2
331337 ->expects($this->once())
332338 ->method('cancel');
161161 /** @test */
162162 public function returnsExtendePromiseForSimplePromise()
163163 {
164 $promise = $this->getMock('React\Promise\PromiseInterface');
164 $promise = $this
165 ->getMockBuilder('React\Promise\PromiseInterface')
166 ->getMock();
165167
166168 $this->assertInstanceOf('React\Promise\ExtendedPromiseInterface', resolve($promise));
167169 }
183183 /** @test */
184184 public function shouldCancelInputPromise()
185185 {
186 $mock = $this->getMock('React\Promise\CancellablePromiseInterface');
186 $mock = $this
187 ->getMockBuilder('React\Promise\CancellablePromiseInterface')
188 ->getMock();
187189 $mock
188190 ->expects($this->once())
189191 ->method('cancel');
194196 /** @test */
195197 public function shouldCancelInputArrayPromises()
196198 {
197 $mock1 = $this->getMock('React\Promise\CancellablePromiseInterface');
199 $mock1 = $this
200 ->getMockBuilder('React\Promise\CancellablePromiseInterface')
201 ->getMock();
198202 $mock1
199203 ->expects($this->once())
200204 ->method('cancel');
201205
202 $mock2 = $this->getMock('React\Promise\CancellablePromiseInterface');
206 $mock2 = $this
207 ->getMockBuilder('React\Promise\CancellablePromiseInterface')
208 ->getMock();
203209 $mock2
204210 ->expects($this->once())
205211 ->method('cancel');
208214 }
209215
210216 /** @test */
211 public function shouldCancelOtherPendingInputArrayPromisesIfEnoughPromisesFulfill()
217 public function shouldNotCancelOtherPendingInputArrayPromisesIfEnoughPromisesFulfill()
212218 {
213219 $mock = $this->createCallableMock();
214220 $mock
218224 $deferred = New Deferred($mock);
219225 $deferred->resolve();
220226
221 $mock2 = $this->getMock('React\Promise\CancellablePromiseInterface');
227 $mock2 = $this
228 ->getMockBuilder('React\Promise\CancellablePromiseInterface')
229 ->getMock();
222230 $mock2
223 ->expects($this->once())
231 ->expects($this->never())
224232 ->method('cancel');
225233
226234 some([$deferred->promise(), $mock2], 1);
227235 }
228236
229237 /** @test */
230 public function shouldCancelOtherPendingInputArrayPromisesIfEnoughPromisesReject()
238 public function shouldNotCancelOtherPendingInputArrayPromisesIfEnoughPromisesReject()
231239 {
232240 $mock = $this->createCallableMock();
233241 $mock
237245 $deferred = New Deferred($mock);
238246 $deferred->reject();
239247
240 $mock2 = $this->getMock('React\Promise\CancellablePromiseInterface');
248 $mock2 = $this
249 ->getMockBuilder('React\Promise\CancellablePromiseInterface')
250 ->getMock();
241251 $mock2
242 ->expects($this->once())
252 ->expects($this->never())
243253 ->method('cancel');
244254
245255 some([$deferred->promise(), $mock2], 2);
111111 $adapter->resolve(2);
112112 }
113113
114 /**
115 * @test
116 */
117 public function resolveShouldRejectWhenResolvedWithItself()
118 {
119 $adapter = $this->getPromiseTestAdapter();
120
121 $mock = $this->createCallableMock();
122 $mock
123 ->expects($this->once())
124 ->method('__invoke')
125 ->with(new \LogicException('Cannot resolve a promise with itself.'));
126
127 $adapter->promise()
128 ->then(
129 $this->expectCallableNever(),
130 $mock
131 );
132
133 $adapter->resolve($adapter->promise());
134 }
135
136 /**
137 * @test
138 */
139 public function resolveShouldRejectWhenResolvedWithAPromiseWhichFollowsItself()
140 {
141 $adapter1 = $this->getPromiseTestAdapter();
142 $adapter2 = $this->getPromiseTestAdapter();
143
144 $mock = $this->createCallableMock();
145 $mock
146 ->expects($this->once())
147 ->method('__invoke')
148 ->with(new \LogicException('Cannot resolve a promise with itself.'));
149
150 $promise1 = $adapter1->promise();
151
152 $promise2 = $adapter2->promise();
153
154 $promise2->then(
155 $this->expectCallableNever(),
156 $mock
157 );
158
159 $adapter1->resolve($promise2);
160 $adapter2->resolve($promise1);
161 }
162
114163 /** @test */
115164 public function doneShouldInvokeFulfillmentHandler()
116165 {
3535
3636 public function createCallableMock()
3737 {
38 return $this->getMock('React\\Promise\Stub\CallableStub');
38 return $this
39 ->getMockBuilder('React\\Promise\Stub\CallableStub')
40 ->getMock();
3941 }
4042 }