blob: 4eb539cbd56e657bc793d407274ef242bcf657fc [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// Copyright 2013 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
Ben Murdochda12d292016-06-02 14:46:10 +010028// Flags: --allow-natives-syntax --promise-extra
Ben Murdochb8a8cc12014-11-26 15:28:44 +000029
30// Make sure we don't rely on functions patchable by monkeys.
31var call = Function.prototype.call.call.bind(Function.prototype.call)
Emily Bernierd0a1eb72015-03-24 16:35:39 -040032var getOwnPropertyNames = Object.getOwnPropertyNames;
33var defineProperty = Object.defineProperty;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000034var numberPrototype = Number.prototype;
35var symbolIterator = Symbol.iterator;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040036
37
38(function() {
39 // Test before clearing global (fails otherwise)
40 assertEquals("[object Promise]",
41 Object.prototype.toString.call(new Promise(function() {})));
42})();
43
Ben Murdochb8a8cc12014-11-26 15:28:44 +000044
45function clear(o) {
46 if (o === null || (typeof o !== 'object' && typeof o !== 'function')) return
47 clear(o.__proto__)
48 var properties = getOwnPropertyNames(o)
49 for (var i in properties) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000050 // Do not clobber Object.prototype.toString, which is used by tests.
51 if (properties[i] === "toString") continue;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000052 clearProp(o, properties[i])
53 }
54}
55
56function clearProp(o, name) {
57 var poisoned = {caller: 0, callee: 0, arguments: 0}
58 try {
59 var x = o[name]
60 o[name] = undefined
61 clear(x)
62 } catch(e) {} // assertTrue(name in poisoned) }
63}
64
65// Find intrinsics and null them out.
66var globals = Object.getOwnPropertyNames(this)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000067var whitelist = {
68 Promise: true,
69 TypeError: true,
70 String: true,
71 JSON: true,
72 Error: true,
73 MjsUnitAssertionError: true
74};
75
Ben Murdochb8a8cc12014-11-26 15:28:44 +000076for (var i in globals) {
77 var name = globals[i]
78 if (name in whitelist || name[0] === name[0].toLowerCase()) delete globals[i]
79}
80for (var i in globals) {
81 if (globals[i]) clearProp(this, globals[i])
82}
83
84
85var asyncAssertsExpected = 0;
86
87function assertAsyncRan() { ++asyncAssertsExpected }
88
89function assertAsync(b, s) {
90 if (b) {
91 print(s, "succeeded")
92 } else {
93 %AbortJS(s + " FAILED!") // Simply throwing here will have no effect.
94 }
95 --asyncAssertsExpected
96}
97
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000098function assertLater(f, name) {
99 assertFalse(f()); // should not be true synchronously
100 ++asyncAssertsExpected;
101 var iterations = 0;
102 function runAssertion() {
103 if (f()) {
104 print(name, "succeeded");
105 --asyncAssertsExpected;
106 } else if (iterations++ < 10) {
107 %EnqueueMicrotask(runAssertion);
108 } else {
109 %AbortJS(name + " FAILED!");
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000110 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000111 }
112 %EnqueueMicrotask(runAssertion);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000113}
114
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000115function assertAsyncDone(iteration) {
116 var iteration = iteration || 0;
117 %EnqueueMicrotask(function() {
118 if (asyncAssertsExpected === 0)
119 assertAsync(true, "all")
120 else if (iteration > 10) // Shouldn't take more.
121 assertAsync(false, "all... " + asyncAssertsExpected)
122 else
123 assertAsyncDone(iteration + 1)
124 });
125}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000126
127(function() {
128 assertThrows(function() { Promise(function() {}) }, TypeError)
129})();
130
131(function() {
132 assertTrue(new Promise(function() {}) instanceof Promise)
133})();
134
135(function() {
136 assertThrows(function() { new Promise(5) }, TypeError)
137})();
138
139(function() {
140 assertDoesNotThrow(function() { new Promise(function() { throw 5 }) })
141})();
142
143(function() {
144 (new Promise(function() { throw 5 })).chain(
145 assertUnreachable,
146 function(r) { assertAsync(r === 5, "new-throw") }
147 )
148 assertAsyncRan()
149})();
150
151(function() {
152 Promise.accept(5);
153 Promise.accept(5).chain(undefined, assertUnreachable).chain(
154 function(x) { assertAsync(x === 5, "resolved/chain-nohandler") },
155 assertUnreachable
156 )
157 assertAsyncRan()
158})();
159
160(function() {
161 Promise.reject(5).chain(assertUnreachable, undefined).chain(
162 assertUnreachable,
163 function(r) { assertAsync(r === 5, "rejected/chain-nohandler") }
164 )
165 assertAsyncRan()
166})();
167
168(function() {
169 Promise.accept(5).then(undefined, assertUnreachable).chain(
170 function(x) { assertAsync(x === 5, "resolved/then-nohandler-undefined") },
171 assertUnreachable
172 )
173 assertAsyncRan()
174 Promise.accept(6).then(null, assertUnreachable).chain(
175 function(x) { assertAsync(x === 6, "resolved/then-nohandler-null") },
176 assertUnreachable
177 )
178 assertAsyncRan()
179})();
180
181(function() {
182 Promise.reject(5).then(assertUnreachable, undefined).chain(
183 assertUnreachable,
184 function(r) { assertAsync(r === 5, "rejected/then-nohandler-undefined") }
185 )
186 assertAsyncRan()
187 Promise.reject(6).then(assertUnreachable, null).chain(
188 assertUnreachable,
189 function(r) { assertAsync(r === 6, "rejected/then-nohandler-null") }
190 )
191 assertAsyncRan()
192})();
193
194(function() {
195 var p1 = Promise.accept(5)
196 var p2 = Promise.accept(p1)
197 var p3 = Promise.accept(p2)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000198 // Note: Chain now has then-style semantics, here and in future tests.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000199 p3.chain(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000200 function(x) { assertAsync(x === 5, "resolved/chain") },
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000201 assertUnreachable
202 )
203 assertAsyncRan()
204})();
205
206(function() {
207 var p1 = Promise.accept(5)
208 var p2 = Promise.accept(p1)
209 var p3 = Promise.accept(p2)
210 p3.then(
211 function(x) { assertAsync(x === 5, "resolved/then") },
212 assertUnreachable
213 )
214 assertAsyncRan()
215})();
216
217(function() {
218 var p1 = Promise.reject(5)
219 var p2 = Promise.accept(p1)
220 var p3 = Promise.accept(p2)
221 p3.chain(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000222 assertUnreachable,
223 function(x) { assertAsync(x === 5, "rejected/chain") }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000224 )
225 assertAsyncRan()
226})();
227
228(function() {
229 var p1 = Promise.reject(5)
230 var p2 = Promise.accept(p1)
231 var p3 = Promise.accept(p2)
232 p3.then(
233 assertUnreachable,
234 function(x) { assertAsync(x === 5, "rejected/then") }
235 )
236 assertAsyncRan()
237})();
238
239(function() {
240 var p1 = Promise.accept(5)
241 var p2 = Promise.accept(p1)
242 var p3 = Promise.accept(p2)
243 p3.chain(function(x) { return x }, assertUnreachable).chain(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000244 function(x) { assertAsync(x === 5, "resolved/chain/chain") },
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000245 assertUnreachable
246 )
247 assertAsyncRan()
248})();
249
250(function() {
251 var p1 = Promise.accept(5)
252 var p2 = Promise.accept(p1)
253 var p3 = Promise.accept(p2)
254 p3.chain(function(x) { return x }, assertUnreachable).then(
255 function(x) { assertAsync(x === 5, "resolved/chain/then") },
256 assertUnreachable
257 )
258 assertAsyncRan()
259})();
260
261(function() {
262 var p1 = Promise.accept(5)
263 var p2 = Promise.accept(p1)
264 var p3 = Promise.accept(p2)
265 p3.chain(function(x) { return 6 }, assertUnreachable).chain(
266 function(x) { assertAsync(x === 6, "resolved/chain/chain2") },
267 assertUnreachable
268 )
269 assertAsyncRan()
270})();
271
272(function() {
273 var p1 = Promise.accept(5)
274 var p2 = Promise.accept(p1)
275 var p3 = Promise.accept(p2)
276 p3.chain(function(x) { return 6 }, assertUnreachable).then(
277 function(x) { assertAsync(x === 6, "resolved/chain/then2") },
278 assertUnreachable
279 )
280 assertAsyncRan()
281})();
282
283(function() {
284 var p1 = Promise.accept(5)
285 var p2 = Promise.accept(p1)
286 var p3 = Promise.accept(p2)
287 p3.then(function(x) { return x + 1 }, assertUnreachable).chain(
288 function(x) { assertAsync(x === 6, "resolved/then/chain") },
289 assertUnreachable
290 )
291 assertAsyncRan()
292})();
293
294(function() {
295 var p1 = Promise.accept(5)
296 var p2 = Promise.accept(p1)
297 var p3 = Promise.accept(p2)
298 p3.then(function(x) { return x + 1 }, assertUnreachable).then(
299 function(x) { assertAsync(x === 6, "resolved/then/then") },
300 assertUnreachable
301 )
302 assertAsyncRan()
303})();
304
305(function() {
306 var p1 = Promise.accept(5)
307 var p2 = Promise.accept(p1)
308 var p3 = Promise.accept(p2)
309 p3.then(function(x){ return Promise.accept(x+1) }, assertUnreachable).chain(
310 function(x) { assertAsync(x === 6, "resolved/then/chain2") },
311 assertUnreachable
312 )
313 assertAsyncRan()
314})();
315
316(function() {
317 var p1 = Promise.accept(5)
318 var p2 = Promise.accept(p1)
319 var p3 = Promise.accept(p2)
320 p3.then(function(x) { return Promise.accept(x+1) }, assertUnreachable).then(
321 function(x) { assertAsync(x === 6, "resolved/then/then2") },
322 assertUnreachable
323 )
324 assertAsyncRan()
325})();
326
327(function() {
328 var p1 = Promise.accept(5)
329 var p2 = Promise.accept(p1)
330 var p3 = Promise.accept(p2)
331 p3.chain(function(x) { throw 6 }, assertUnreachable).chain(
332 assertUnreachable,
333 function(x) { assertAsync(x === 6, "resolved/chain-throw/chain") }
334 )
335 assertAsyncRan()
336})();
337
338(function() {
339 var p1 = Promise.accept(5)
340 var p2 = Promise.accept(p1)
341 var p3 = Promise.accept(p2)
342 p3.chain(function(x) { throw 6 }, assertUnreachable).then(
343 assertUnreachable,
344 function(x) { assertAsync(x === 6, "resolved/chain-throw/then") }
345 )
346 assertAsyncRan()
347})();
348
349(function() {
350 var p1 = Promise.accept(5)
351 var p2 = Promise.accept(p1)
352 var p3 = Promise.accept(p2)
353 p3.then(function(x) { throw 6 }, assertUnreachable).chain(
354 assertUnreachable,
355 function(x) { assertAsync(x === 6, "resolved/then-throw/chain") }
356 )
357 assertAsyncRan()
358})();
359
360(function() {
361 var p1 = Promise.accept(5)
362 var p2 = Promise.accept(p1)
363 var p3 = Promise.accept(p2)
364 p3.then(function(x) { throw 6 }, assertUnreachable).then(
365 assertUnreachable,
366 function(x) { assertAsync(x === 6, "resolved/then-throw/then") }
367 )
368 assertAsyncRan()
369})();
370
371(function() {
372 var p1 = Promise.accept(5)
373 var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}
374 var p3 = Promise.accept(p2)
375 p3.chain(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000376 function(x) { assertAsync(x === 5, "resolved/thenable/chain") },
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000377 assertUnreachable
378 )
379 assertAsyncRan()
380})();
381
382(function() {
383 var p1 = Promise.accept(5)
384 var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}
385 var p3 = Promise.accept(p2)
386 p3.then(
387 function(x) { assertAsync(x === 5, "resolved/thenable/then") },
388 assertUnreachable
389 )
390 assertAsyncRan()
391})();
392
393(function() {
394 var p1 = Promise.reject(5)
395 var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}
396 var p3 = Promise.accept(p2)
397 p3.chain(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000398 assertUnreachable,
399 function(x) { assertAsync(x === 5, "rejected/thenable/chain") }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000400 )
401 assertAsyncRan()
402})();
403
404(function() {
405 var p1 = Promise.reject(5)
406 var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}
407 var p3 = Promise.accept(p2)
408 p3.then(
409 assertUnreachable,
410 function(x) { assertAsync(x === 5, "rejected/thenable/then") }
411 )
412 assertAsyncRan()
413})();
414
415(function() {
416 var deferred = Promise.defer()
417 var p1 = deferred.promise
418 var p2 = Promise.accept(p1)
419 var p3 = Promise.accept(p2)
420 p3.chain(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000421 function(x) { assertAsync(x === 5, "chain/resolve") },
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000422 assertUnreachable
423 )
424 deferred.resolve(5)
425 assertAsyncRan()
426})();
427
428(function() {
429 var deferred = Promise.defer()
430 var p1 = deferred.promise
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000431 var p2 = Promise.resolve(p1)
432 var p3 = Promise.resolve(p2)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000433 p3.then(
434 function(x) { assertAsync(x === 5, "then/resolve") },
435 assertUnreachable
436 )
437 deferred.resolve(5)
438 assertAsyncRan()
439})();
440
441(function() {
442 var deferred = Promise.defer()
443 var p1 = deferred.promise
444 var p2 = Promise.accept(p1)
445 var p3 = Promise.accept(p2)
446 p3.chain(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000447 assertUnreachable,
448 function(x) { assertAsync(x === 5, "chain/reject") }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000449 )
450 deferred.reject(5)
451 assertAsyncRan()
452})();
453
454(function() {
455 var deferred = Promise.defer()
456 var p1 = deferred.promise
457 var p2 = Promise.accept(p1)
458 var p3 = Promise.accept(p2)
459 p3.then(
460 assertUnreachable,
461 function(x) { assertAsync(x === 5, "then/reject") }
462 )
463 deferred.reject(5)
464 assertAsyncRan()
465})();
466
467(function() {
468 var deferred = Promise.defer()
469 var p1 = deferred.promise
470 var p2 = p1.then(1, 2)
471 p2.then(
472 function(x) { assertAsync(x === 5, "then/resolve-non-function") },
473 assertUnreachable
474 )
475 deferred.resolve(5)
476 assertAsyncRan()
477})();
478
479(function() {
480 var deferred = Promise.defer()
481 var p1 = deferred.promise
482 var p2 = p1.then(1, 2)
483 p2.then(
484 assertUnreachable,
485 function(x) { assertAsync(x === 5, "then/reject-non-function") }
486 )
487 deferred.reject(5)
488 assertAsyncRan()
489})();
490
491(function() {
492 var deferred = Promise.defer()
493 var p1 = deferred.promise
494 var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}
495 var p3 = Promise.accept(p2)
496 p3.chain(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000497 function(x) { assertAsync(x === 5, "chain/resolve/thenable") },
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000498 assertUnreachable
499 )
500 deferred.resolve(5)
501 assertAsyncRan()
502})();
503
504(function() {
505 var deferred = Promise.defer()
506 var p1 = deferred.promise
507 var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}
508 var p3 = Promise.accept(p2)
509 p3.then(
510 function(x) { assertAsync(x === 5, "then/resolve/thenable") },
511 assertUnreachable
512 )
513 deferred.resolve(5)
514 assertAsyncRan()
515})();
516
517(function() {
518 var deferred = Promise.defer()
519 var p1 = deferred.promise
520 var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}
521 var p3 = Promise.accept(p2)
522 p3.chain(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000523 assertUnreachable,
524 function(x) { assertAsync(x === 5, "chain/reject/thenable") }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000525 )
526 deferred.reject(5)
527 assertAsyncRan()
528})();
529
530(function() {
531 var deferred = Promise.defer()
532 var p1 = deferred.promise
533 var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}
534 var p3 = Promise.accept(p2)
535 p3.then(
536 assertUnreachable,
537 function(x) { assertAsync(x === 5, "then/reject/thenable") }
538 )
539 deferred.reject(5)
540 assertAsyncRan()
541})();
542
543(function() {
544 var p1 = Promise.accept(5)
545 var p2 = Promise.accept(p1)
546 var deferred = Promise.defer()
547 var p3 = deferred.promise
548 p3.chain(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000549 function(x) { assertAsync(x === 5, "chain/resolve2") },
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000550 assertUnreachable
551 )
552 deferred.resolve(p2)
553 assertAsyncRan()
554})();
555
556(function() {
557 var p1 = Promise.accept(5)
558 var p2 = Promise.accept(p1)
559 var deferred = Promise.defer()
560 var p3 = deferred.promise
561 p3.then(
562 function(x) { assertAsync(x === 5, "then/resolve2") },
563 assertUnreachable
564 )
565 deferred.resolve(p2)
566 assertAsyncRan()
567})();
568
569(function() {
570 var p1 = Promise.accept(5)
571 var p2 = Promise.accept(p1)
572 var deferred = Promise.defer()
573 var p3 = deferred.promise
574 p3.chain(
575 assertUnreachable,
576 function(x) { assertAsync(x === 5, "chain/reject2") }
577 )
578 deferred.reject(5)
579 assertAsyncRan()
580})();
581
582(function() {
583 var p1 = Promise.accept(5)
584 var p2 = Promise.accept(p1)
585 var deferred = Promise.defer()
586 var p3 = deferred.promise
587 p3.then(
588 assertUnreachable,
589 function(x) { assertAsync(x === 5, "then/reject2") }
590 )
591 deferred.reject(5)
592 assertAsyncRan()
593})();
594
595(function() {
596 var p1 = Promise.accept(5)
597 var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}
598 var deferred = Promise.defer()
599 var p3 = deferred.promise
600 p3.chain(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000601 function(x) { assertAsync(x === 5, "chain/resolve/thenable2") },
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000602 assertUnreachable
603 )
604 deferred.resolve(p2)
605 assertAsyncRan()
606})();
607
608(function() {
609 var p1 = Promise.accept(5)
610 var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}
611 var deferred = Promise.defer()
612 var p3 = deferred.promise
613 p3.then(
614 function(x) { assertAsync(x === 5, "then/resolve/thenable2") },
615 assertUnreachable
616 )
617 deferred.resolve(p2)
618 assertAsyncRan()
619})();
620
621(function() {
622 var p1 = Promise.accept(0)
623 var p2 = p1.chain(function(x) { return p2 }, assertUnreachable)
624 p2.chain(
625 assertUnreachable,
626 function(r) { assertAsync(r instanceof TypeError, "cyclic/chain") }
627 )
628 assertAsyncRan()
629})();
630
631(function() {
632 var p1 = Promise.accept(0)
633 var p2 = p1.then(function(x) { return p2 }, assertUnreachable)
634 p2.chain(
635 assertUnreachable,
636 function(r) { assertAsync(r instanceof TypeError, "cyclic/then") }
637 )
638 assertAsyncRan()
639})();
640
641(function() {
642 var deferred = Promise.defer()
643 var p = deferred.promise
644 deferred.resolve(p)
645 p.chain(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000646 assertUnreachable,
647 function(r) { assertAsync(r instanceof TypeError, "cyclic/deferred/then") }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000648 )
649 assertAsyncRan()
650})();
651
652(function() {
653 var deferred = Promise.defer()
654 var p = deferred.promise
655 deferred.resolve(p)
656 p.then(
657 assertUnreachable,
658 function(r) { assertAsync(r instanceof TypeError, "cyclic/deferred/then") }
659 )
660 assertAsyncRan()
661})();
662
663(function() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000664 Promise.all([]).chain(
665 function(x) { assertAsync(x.length === 0, "all/resolve/empty") },
666 assertUnreachable
667 )
668 assertAsyncRan()
669})();
670
671(function() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000672 function testPromiseAllNonIterable(value) {
673 Promise.all(value).chain(
674 assertUnreachable,
675 function(r) {
676 assertAsync(r instanceof TypeError, 'all/non iterable');
677 });
678 assertAsyncRan();
679 }
680 testPromiseAllNonIterable(null);
681 testPromiseAllNonIterable(undefined);
682 testPromiseAllNonIterable({});
683 testPromiseAllNonIterable(42);
684})();
685
686(function() {
687 var deferred = Promise.defer();
688 var p = deferred.promise;
689 function* f() {
690 yield 1;
691 yield p;
692 yield 3;
693 }
694 Promise.all(f()).chain(
695 function(x) {
696 assertAsync(x.length === 3, "all/resolve/iterable");
697 assertAsync(x[0] === 1, "all/resolve/iterable/0");
698 assertAsync(x[1] === 2, "all/resolve/iterable/1");
699 assertAsync(x[2] === 3, "all/resolve/iterable/2");
700 },
701 assertUnreachable);
702 deferred.resolve(2);
703 assertAsyncRan();
704 assertAsyncRan();
705 assertAsyncRan();
706 assertAsyncRan();
707})();
708
709
710(function() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000711 var deferred1 = Promise.defer()
712 var p1 = deferred1.promise
713 var deferred2 = Promise.defer()
714 var p2 = deferred2.promise
715 var deferred3 = Promise.defer()
716 var p3 = deferred3.promise
717 Promise.all([p1, p2, p3]).chain(
718 function(x) {
719 assertAsync(x.length === 3, "all/resolve")
720 assertAsync(x[0] === 1, "all/resolve/0")
721 assertAsync(x[1] === 2, "all/resolve/1")
722 assertAsync(x[2] === 3, "all/resolve/2")
723 },
724 assertUnreachable
725 )
726 deferred1.resolve(1)
727 deferred3.resolve(3)
728 deferred2.resolve(2)
729 assertAsyncRan()
730 assertAsyncRan()
731 assertAsyncRan()
732 assertAsyncRan()
733})();
734
735(function() {
736 var deferred = Promise.defer()
737 var p1 = deferred.promise
738 var p2 = Promise.accept(2)
739 var p3 = Promise.defer().promise
740 Promise.all([p1, p2, p3]).chain(
741 assertUnreachable,
742 assertUnreachable
743 )
744 deferred.resolve(1)
745})();
746
747(function() {
748 var deferred1 = Promise.defer()
749 var p1 = deferred1.promise
750 var deferred2 = Promise.defer()
751 var p2 = deferred2.promise
752 var deferred3 = Promise.defer()
753 var p3 = deferred3.promise
754 Promise.all([p1, p2, p3]).chain(
755 assertUnreachable,
756 function(x) { assertAsync(x === 2, "all/reject") }
757 )
758 deferred1.resolve(1)
759 deferred3.resolve(3)
760 deferred2.reject(2)
761 assertAsyncRan()
762})();
763
764(function() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000765 'use strict';
766 var getCalls = 0;
767 var funcCalls = 0;
768 var nextCalls = 0;
769 defineProperty(numberPrototype, symbolIterator, {
770 get: function() {
771 assertEquals('number', typeof this);
772 getCalls++;
773 return function() {
774 assertEquals('number', typeof this);
775 funcCalls++;
776 var n = this;
777 var i = 0
778 return {
779 next() {
780 nextCalls++;
781 return {value: i++, done: i > n};
782 }
783 };
784 };
785 },
786 configurable: true
787 });
788
789 Promise.all(3).chain(
790 function(x) {
791 assertAsync(x.length === 3, "all/iterable/number/length");
792 assertAsync(x[0] === 0, "all/iterable/number/0");
793 assertAsync(x[1] === 1, "all/iterable/number/1");
794 assertAsync(x[2] === 2, "all/iterable/number/2");
795 },
796 assertUnreachable);
797 delete numberPrototype[symbolIterator];
798
799 assertEquals(getCalls, 1);
800 assertEquals(funcCalls, 1);
801 assertEquals(nextCalls, 3 + 1); // + 1 for {done: true}
802 assertAsyncRan();
803 assertAsyncRan();
804 assertAsyncRan();
805 assertAsyncRan();
806})();
807
808
809(function() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000810 Promise.race([]).chain(
811 assertUnreachable,
812 assertUnreachable
813 )
814})();
815
816(function() {
817 var p1 = Promise.accept(1)
818 var p2 = Promise.accept(2)
819 var p3 = Promise.accept(3)
820 Promise.race([p1, p2, p3]).chain(
821 function(x) { assertAsync(x === 1, "resolved/one") },
822 assertUnreachable
823 )
824 assertAsyncRan()
825})();
826
827(function() {
828 var p1 = Promise.accept(1)
829 var p2 = Promise.accept(2)
830 var p3 = Promise.accept(3)
831 Promise.race([0, p1, p2, p3]).chain(
832 function(x) { assertAsync(x === 0, "resolved-const/one") },
833 assertUnreachable
834 )
835 assertAsyncRan()
836})();
837
838(function() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000839 var deferred1 = Promise.defer()
840 var p1 = deferred1.promise
841 var deferred2 = Promise.defer()
842 var p2 = deferred2.promise
843 var deferred3 = Promise.defer()
844 var p3 = deferred3.promise
845 Promise.race([p1, p2, p3]).chain(
846 function(x) { assertAsync(x === 3, "one/resolve") },
847 assertUnreachable
848 )
849 deferred3.resolve(3)
850 deferred1.resolve(1)
851 assertAsyncRan()
852})();
853
854(function() {
855 var deferred = Promise.defer()
856 var p1 = deferred.promise
857 var p2 = Promise.accept(2)
858 var p3 = Promise.defer().promise
859 Promise.race([p1, p2, p3]).chain(
860 function(x) { assertAsync(x === 2, "resolved/one") },
861 assertUnreachable
862 )
863 deferred.resolve(1)
864 assertAsyncRan()
865})();
866
867(function() {
868 var deferred1 = Promise.defer()
869 var p1 = deferred1.promise
870 var deferred2 = Promise.defer()
871 var p2 = deferred2.promise
872 var deferred3 = Promise.defer()
873 var p3 = deferred3.promise
874 Promise.race([p1, p2, p3]).chain(
875 function(x) { assertAsync(x === 3, "one/resolve/reject") },
876 assertUnreachable
877 )
878 deferred3.resolve(3)
879 deferred1.reject(1)
880 assertAsyncRan()
881})();
882
883(function() {
884 var deferred1 = Promise.defer()
885 var p1 = deferred1.promise
886 var deferred2 = Promise.defer()
887 var p2 = deferred2.promise
888 var deferred3 = Promise.defer()
889 var p3 = deferred3.promise
890 Promise.race([p1, p2, p3]).chain(
891 assertUnreachable,
892 function(x) { assertAsync(x === 3, "one/reject/resolve") }
893 )
894 deferred3.reject(3)
895 deferred1.resolve(1)
896 assertAsyncRan()
897})();
898
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000899
900(function() {
901 function testPromiseRaceNonIterable(value) {
902 Promise.race(value).chain(
903 assertUnreachable,
904 function(r) {
905 assertAsync(r instanceof TypeError, 'race/non iterable');
906 });
907 assertAsyncRan();
908 }
909 testPromiseRaceNonIterable(null);
910 testPromiseRaceNonIterable(undefined);
911 testPromiseRaceNonIterable({});
912 testPromiseRaceNonIterable(42);
913})();
914
915
916(function() {
917 var deferred1 = Promise.defer()
918 var p1 = deferred1.promise
919 var deferred2 = Promise.defer()
920 var p2 = deferred2.promise
921 var deferred3 = Promise.defer()
922 var p3 = deferred3.promise
923 function* f() {
924 yield p1;
925 yield p2;
926 yield p3;
927 }
928 Promise.race(f()).chain(
929 function(x) { assertAsync(x === 3, "race/iterable/resolve/reject") },
930 assertUnreachable
931 )
932 deferred3.resolve(3)
933 deferred1.reject(1)
934 assertAsyncRan()
935})();
936
937(function() {
938 var deferred1 = Promise.defer()
939 var p1 = deferred1.promise
940 var deferred2 = Promise.defer()
941 var p2 = deferred2.promise
942 var deferred3 = Promise.defer()
943 var p3 = deferred3.promise
944 function* f() {
945 yield p1;
946 yield p2;
947 yield p3;
948 }
949 Promise.race(f()).chain(
950 assertUnreachable,
951 function(x) { assertAsync(x === 3, "race/iterable/reject/resolve") }
952 )
953 deferred3.reject(3)
954 deferred1.resolve(1)
955 assertAsyncRan()
956})();
957
958(function() {
959 'use strict';
960 var getCalls = 0;
961 var funcCalls = 0;
962 var nextCalls = 0;
963 defineProperty(numberPrototype, symbolIterator, {
964 get: function() {
965 assertEquals('number', typeof this);
966 getCalls++;
967 return function() {
968 assertEquals('number', typeof this);
969 funcCalls++;
970 var n = this;
971 var i = 0
972 return {
973 next() {
974 nextCalls++;
975 return {value: i++, done: i > n};
976 }
977 };
978 };
979 },
980 configurable: true
981 });
982
983 Promise.race(3).chain(
984 function(x) {
985 assertAsync(x === 0, "race/iterable/number");
986 },
987 assertUnreachable);
988 delete numberPrototype[symbolIterator];
989
990 assertEquals(getCalls, 1);
991 assertEquals(funcCalls, 1);
992 assertEquals(nextCalls, 3 + 1); // + 1 for {done: true}
993 assertAsyncRan();
994})();
995
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000996(function() {
997 var log
998 function MyPromise(resolver) {
999 log += "n"
1000 var promise = new Promise(function(resolve, reject) {
1001 resolver(
1002 function(x) { log += "x" + x; resolve(x) },
1003 function(r) { log += "r" + r; reject(r) }
1004 )
1005 })
1006 promise.__proto__ = MyPromise.prototype
1007 return promise
1008 }
1009
1010 MyPromise.__proto__ = Promise
1011 MyPromise.defer = function() {
1012 log += "d"
1013 return call(this.__proto__.defer, this)
1014 }
1015
1016 MyPromise.prototype.__proto__ = Promise.prototype
1017 MyPromise.prototype.chain = function(resolve, reject) {
1018 log += "c"
1019 return call(this.__proto__.__proto__.chain, this, resolve, reject)
1020 }
1021
1022 log = ""
1023 var p1 = new MyPromise(function(resolve, reject) { resolve(1) })
1024 var p2 = new MyPromise(function(resolve, reject) { reject(2) })
1025 var d3 = MyPromise.defer()
1026 assertTrue(d3.promise instanceof Promise, "subclass/instance")
1027 assertTrue(d3.promise instanceof MyPromise, "subclass/instance-my3")
1028 assertTrue(log === "nx1nr2dn", "subclass/create")
1029
1030 log = ""
1031 var p4 = MyPromise.resolve(4)
1032 var p5 = MyPromise.reject(5)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001033 assertTrue(p4 instanceof MyPromise, "subclass/instance4")
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001034 assertTrue(p4 instanceof MyPromise, "subclass/instance-my4")
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001035 assertTrue(p5 instanceof MyPromise, "subclass/instance5")
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001036 assertTrue(p5 instanceof MyPromise, "subclass/instance-my5")
1037 d3.resolve(3)
1038 assertTrue(log === "nx4nr5x3", "subclass/resolve")
1039
1040 log = ""
1041 var d6 = MyPromise.defer()
1042 d6.promise.chain(function(x) {
1043 return new Promise(function(resolve) { resolve(x) })
1044 }).chain(function() {})
1045 d6.resolve(6)
1046 assertTrue(log === "dncncnx6", "subclass/chain")
1047
1048 log = ""
1049 Promise.all([11, Promise.accept(12), 13, MyPromise.accept(14), 15, 16])
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001050
1051 assertTrue(log === "nx14", "subclass/all/arg")
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001052
1053 log = ""
1054 MyPromise.all([21, Promise.accept(22), 23, MyPromise.accept(24), 25, 26])
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001055 assertTrue(log === "nx24nnx21nnx[object Promise]nnx23nnnx25nnx26n",
1056 "subclass/all/self")
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001057})();
1058
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001059(function() {
1060 'use strict';
1061
1062 class Pact extends Promise { }
1063 class Vow extends Pact { }
1064 class Oath extends Vow { }
1065
1066 Oath.constructor = Vow;
1067
1068 assertTrue(Pact.resolve(Pact.resolve()).constructor === Pact,
1069 "subclass/resolve/own");
1070
1071 assertTrue(Pact.resolve(Promise.resolve()).constructor === Pact,
1072 "subclass/resolve/ancestor");
1073
1074 assertTrue(Pact.resolve(Vow.resolve()).constructor === Pact,
1075 "subclass/resolve/descendant"); var vow = Vow.resolve();
1076
1077 vow.constructor = Oath;
1078 assertTrue(Oath.resolve(vow) === vow,
1079 "subclass/resolve/descendant with transplanted own constructor");
1080}());
1081
1082(function() {
1083 var thenCalled = false;
1084
1085 var resolve;
1086 var promise = new Promise(function(res) { resolve = res; });
1087 resolve({ then() { thenCalled = true; throw new Error(); } });
1088 assertLater(function() { return thenCalled; }, "resolve-with-thenable");
1089});
1090
1091(function() {
1092 var calledWith;
1093
1094 var resolve;
1095 var p1 = (new Promise(function(res) { resolve = res; }));
1096 var p2 = p1.then(function(v) {
1097 return {
1098 then(resolve, reject) { resolve({ then() { calledWith = v }}); }
1099 };
1100 });
1101
1102 resolve({ then(resolve) { resolve(2); } });
1103 assertLater(function() { return calledWith === 2; },
1104 "resolve-with-thenable2");
1105})();
1106
1107(function() {
1108 var p = Promise.resolve();
1109 var callCount = 0;
1110 defineProperty(p, "constructor", {
1111 get: function() { ++callCount; return Promise; }
1112 });
1113 p.then();
1114 assertEquals(1, callCount);
1115})();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001116
1117assertAsyncDone()