1 // 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
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.
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.
28 // Flags: --harmony-promises --allow-natives-syntax
30 var asyncAssertsExpected = 0;
32 function assertAsyncRan() { ++asyncAssertsExpected }
34 function assertAsync(b, s) {
38 %AbortJS(s + " FAILED!") // Simply throwing here will have no effect.
40 --asyncAssertsExpected
43 function assertAsyncDone(iteration) {
44 var iteration = iteration || 0
48 if (asyncAssertsExpected === 0)
49 assertAsync(true, "all")
50 else if (iteration > 10) // Shouldn't take more.
51 assertAsync(false, "all")
53 assertAsyncDone(iteration + 1)
61 assertThrows(function() { Promise(function() {}) }, TypeError)
65 assertTrue(new Promise(function() {}) instanceof Promise)
69 assertThrows(function() { new Promise(5) }, TypeError)
73 assertDoesNotThrow(function() { new Promise(function() { throw 5 }) })
77 (new Promise(function() { throw 5 })).chain(
79 function(r) { assertAsync(r === 5, "new-throw") }
86 Promise.accept(5).chain(undefined, assertUnreachable).chain(
87 function(x) { assertAsync(x === 5, "resolved/chain-nohandler") },
94 Promise.reject(5).chain(assertUnreachable, undefined).chain(
96 function(r) { assertAsync(r === 5, "rejected/chain-nohandler") }
102 Promise.accept(5).then(undefined, assertUnreachable).chain(
103 function(x) { assertAsync(x === 5, "resolved/then-nohandler-undefined") },
107 Promise.accept(6).then(null, assertUnreachable).chain(
108 function(x) { assertAsync(x === 6, "resolved/then-nohandler-null") },
115 Promise.reject(5).then(assertUnreachable, undefined).chain(
117 function(r) { assertAsync(r === 5, "rejected/then-nohandler-undefined") }
120 Promise.reject(6).then(assertUnreachable, null).chain(
122 function(r) { assertAsync(r === 6, "rejected/then-nohandler-null") }
128 var p1 = Promise.accept(5)
129 var p2 = Promise.accept(p1)
130 var p3 = Promise.accept(p2)
132 function(x) { assertAsync(x === p2, "resolved/chain") },
139 var p1 = Promise.accept(5)
140 var p2 = Promise.accept(p1)
141 var p3 = Promise.accept(p2)
143 function(x) { assertAsync(x === 5, "resolved/then") },
150 var p1 = Promise.reject(5)
151 var p2 = Promise.accept(p1)
152 var p3 = Promise.accept(p2)
154 function(x) { assertAsync(x === p2, "rejected/chain") },
161 var p1 = Promise.reject(5)
162 var p2 = Promise.accept(p1)
163 var p3 = Promise.accept(p2)
166 function(x) { assertAsync(x === 5, "rejected/then") }
172 var p1 = Promise.accept(5)
173 var p2 = Promise.accept(p1)
174 var p3 = Promise.accept(p2)
175 p3.chain(function(x) { return x }, assertUnreachable).chain(
176 function(x) { assertAsync(x === p1, "resolved/chain/chain") },
183 var p1 = Promise.accept(5)
184 var p2 = Promise.accept(p1)
185 var p3 = Promise.accept(p2)
186 p3.chain(function(x) { return x }, assertUnreachable).then(
187 function(x) { assertAsync(x === 5, "resolved/chain/then") },
194 var p1 = Promise.accept(5)
195 var p2 = Promise.accept(p1)
196 var p3 = Promise.accept(p2)
197 p3.chain(function(x) { return 6 }, assertUnreachable).chain(
198 function(x) { assertAsync(x === 6, "resolved/chain/chain2") },
205 var p1 = Promise.accept(5)
206 var p2 = Promise.accept(p1)
207 var p3 = Promise.accept(p2)
208 p3.chain(function(x) { return 6 }, assertUnreachable).then(
209 function(x) { assertAsync(x === 6, "resolved/chain/then2") },
216 var p1 = Promise.accept(5)
217 var p2 = Promise.accept(p1)
218 var p3 = Promise.accept(p2)
219 p3.then(function(x) { return x + 1 }, assertUnreachable).chain(
220 function(x) { assertAsync(x === 6, "resolved/then/chain") },
227 var p1 = Promise.accept(5)
228 var p2 = Promise.accept(p1)
229 var p3 = Promise.accept(p2)
230 p3.then(function(x) { return x + 1 }, assertUnreachable).then(
231 function(x) { assertAsync(x === 6, "resolved/then/then") },
238 var p1 = Promise.accept(5)
239 var p2 = Promise.accept(p1)
240 var p3 = Promise.accept(p2)
241 p3.then(function(x){ return Promise.accept(x+1) }, assertUnreachable).chain(
242 function(x) { assertAsync(x === 6, "resolved/then/chain2") },
249 var p1 = Promise.accept(5)
250 var p2 = Promise.accept(p1)
251 var p3 = Promise.accept(p2)
252 p3.then(function(x) { return Promise.accept(x+1) }, assertUnreachable).then(
253 function(x) { assertAsync(x === 6, "resolved/then/then2") },
260 var p1 = Promise.accept(5)
261 var p2 = Promise.accept(p1)
262 var p3 = Promise.accept(p2)
263 p3.chain(function(x) { throw 6 }, assertUnreachable).chain(
265 function(x) { assertAsync(x === 6, "resolved/chain-throw/chain") }
271 var p1 = Promise.accept(5)
272 var p2 = Promise.accept(p1)
273 var p3 = Promise.accept(p2)
274 p3.chain(function(x) { throw 6 }, assertUnreachable).then(
276 function(x) { assertAsync(x === 6, "resolved/chain-throw/then") }
282 var p1 = Promise.accept(5)
283 var p2 = Promise.accept(p1)
284 var p3 = Promise.accept(p2)
285 p3.then(function(x) { throw 6 }, assertUnreachable).chain(
287 function(x) { assertAsync(x === 6, "resolved/then-throw/chain") }
293 var p1 = Promise.accept(5)
294 var p2 = Promise.accept(p1)
295 var p3 = Promise.accept(p2)
296 p3.then(function(x) { throw 6 }, assertUnreachable).then(
298 function(x) { assertAsync(x === 6, "resolved/then-throw/then") }
304 var p1 = Promise.accept(5)
305 var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}
306 var p3 = Promise.accept(p2)
308 function(x) { assertAsync(x === p2, "resolved/thenable/chain") },
315 var p1 = Promise.accept(5)
316 var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}
317 var p3 = Promise.accept(p2)
319 function(x) { assertAsync(x === 5, "resolved/thenable/then") },
326 var p1 = Promise.reject(5)
327 var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}
328 var p3 = Promise.accept(p2)
330 function(x) { assertAsync(x === p2, "rejected/thenable/chain") },
337 var p1 = Promise.reject(5)
338 var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}
339 var p3 = Promise.accept(p2)
342 function(x) { assertAsync(x === 5, "rejected/thenable/then") }
348 var deferred = Promise.defer()
349 var p1 = deferred.promise
350 var p2 = Promise.accept(p1)
351 var p3 = Promise.accept(p2)
353 function(x) { assertAsync(x === p2, "chain/resolve") },
361 var deferred = Promise.defer()
362 var p1 = deferred.promise
363 var p2 = Promise.accept(p1)
364 var p3 = Promise.accept(p2)
366 function(x) { assertAsync(x === 5, "then/resolve") },
374 var deferred = Promise.defer()
375 var p1 = deferred.promise
376 var p2 = Promise.accept(p1)
377 var p3 = Promise.accept(p2)
379 function(x) { assertAsync(x === p2, "chain/reject") },
387 var deferred = Promise.defer()
388 var p1 = deferred.promise
389 var p2 = Promise.accept(p1)
390 var p3 = Promise.accept(p2)
393 function(x) { assertAsync(x === 5, "then/reject") }
400 var deferred = Promise.defer()
401 var p1 = deferred.promise
402 var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}
403 var p3 = Promise.accept(p2)
405 function(x) { assertAsync(x === p2, "chain/resolve/thenable") },
413 var deferred = Promise.defer()
414 var p1 = deferred.promise
415 var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}
416 var p3 = Promise.accept(p2)
418 function(x) { assertAsync(x === 5, "then/resolve/thenable") },
426 var deferred = Promise.defer()
427 var p1 = deferred.promise
428 var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}
429 var p3 = Promise.accept(p2)
431 function(x) { assertAsync(x === p2, "chain/reject/thenable") },
439 var deferred = Promise.defer()
440 var p1 = deferred.promise
441 var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}
442 var p3 = Promise.accept(p2)
445 function(x) { assertAsync(x === 5, "then/reject/thenable") }
452 var p1 = Promise.accept(5)
453 var p2 = Promise.accept(p1)
454 var deferred = Promise.defer()
455 var p3 = deferred.promise
457 function(x) { assertAsync(x === p2, "chain/resolve2") },
465 var p1 = Promise.accept(5)
466 var p2 = Promise.accept(p1)
467 var deferred = Promise.defer()
468 var p3 = deferred.promise
470 function(x) { assertAsync(x === 5, "then/resolve2") },
478 var p1 = Promise.accept(5)
479 var p2 = Promise.accept(p1)
480 var deferred = Promise.defer()
481 var p3 = deferred.promise
484 function(x) { assertAsync(x === 5, "chain/reject2") }
491 var p1 = Promise.accept(5)
492 var p2 = Promise.accept(p1)
493 var deferred = Promise.defer()
494 var p3 = deferred.promise
497 function(x) { assertAsync(x === 5, "then/reject2") }
504 var p1 = Promise.accept(5)
505 var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}
506 var deferred = Promise.defer()
507 var p3 = deferred.promise
509 function(x) { assertAsync(x === p2, "chain/resolve/thenable2") },
517 var p1 = Promise.accept(5)
518 var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}
519 var deferred = Promise.defer()
520 var p3 = deferred.promise
522 function(x) { assertAsync(x === 5, "then/resolve/thenable2") },
530 var p1 = Promise.accept(0)
531 var p2 = p1.chain(function(x) { return p2 }, assertUnreachable)
534 function(r) { assertAsync(r instanceof TypeError, "cyclic/chain") }
540 var p1 = Promise.accept(0)
541 var p2 = p1.then(function(x) { return p2 }, assertUnreachable)
544 function(r) { assertAsync(r instanceof TypeError, "cyclic/then") }
550 var deferred = Promise.defer()
551 var p = deferred.promise
554 function(x) { assertAsync(x === p, "cyclic/deferred/chain") },
561 var deferred = Promise.defer()
562 var p = deferred.promise
566 function(r) { assertAsync(r instanceof TypeError, "cyclic/deferred/then") }
572 Promise.all({}).chain(
574 function(r) { assertAsync(r instanceof TypeError, "all/no-array") }
580 Promise.all([]).chain(
581 function(x) { assertAsync(x.length === 0, "all/resolve/empty") },
588 var deferred1 = Promise.defer()
589 var p1 = deferred1.promise
590 var deferred2 = Promise.defer()
591 var p2 = deferred2.promise
592 var deferred3 = Promise.defer()
593 var p3 = deferred3.promise
594 Promise.all([p1, p2, p3]).chain(
596 assertAsync(x.length === 3, "all/resolve")
597 assertAsync(x[0] === 1, "all/resolve/0")
598 assertAsync(x[1] === 2, "all/resolve/1")
599 assertAsync(x[2] === 3, "all/resolve/2")
613 var deferred = Promise.defer()
614 var p1 = deferred.promise
615 var p2 = Promise.accept(2)
616 var p3 = Promise.defer().promise
617 Promise.all([p1, p2, p3]).chain(
625 var deferred1 = Promise.defer()
626 var p1 = deferred1.promise
627 var deferred2 = Promise.defer()
628 var p2 = deferred2.promise
629 var deferred3 = Promise.defer()
630 var p3 = deferred3.promise
631 Promise.all([p1, p2, p3]).chain(
633 function(x) { assertAsync(x === 2, "all/reject") }
642 Promise.race([]).chain(
649 var p1 = Promise.accept(1)
650 var p2 = Promise.accept(2)
651 var p3 = Promise.accept(3)
652 Promise.race([p1, p2, p3]).chain(
653 function(x) { assertAsync(x === 1, "resolved/one") },
660 var p1 = Promise.accept(1)
661 var p2 = Promise.accept(2)
662 var p3 = Promise.accept(3)
663 Promise.race([0, p1, p2, p3]).chain(
664 function(x) { assertAsync(x === 0, "resolved-const/one") },
671 Promise.race({}).chain(
673 function(r) { assertAsync(r instanceof TypeError, "one/no-array") }
679 var deferred1 = Promise.defer()
680 var p1 = deferred1.promise
681 var deferred2 = Promise.defer()
682 var p2 = deferred2.promise
683 var deferred3 = Promise.defer()
684 var p3 = deferred3.promise
685 Promise.race([p1, p2, p3]).chain(
686 function(x) { assertAsync(x === 3, "one/resolve") },
695 var deferred = Promise.defer()
696 var p1 = deferred.promise
697 var p2 = Promise.accept(2)
698 var p3 = Promise.defer().promise
699 Promise.race([p1, p2, p3]).chain(
700 function(x) { assertAsync(x === 2, "resolved/one") },
708 var deferred1 = Promise.defer()
709 var p1 = deferred1.promise
710 var deferred2 = Promise.defer()
711 var p2 = deferred2.promise
712 var deferred3 = Promise.defer()
713 var p3 = deferred3.promise
714 Promise.race([p1, p2, p3]).chain(
715 function(x) { assertAsync(x === 3, "one/resolve/reject") },
724 var deferred1 = Promise.defer()
725 var p1 = deferred1.promise
726 var deferred2 = Promise.defer()
727 var p2 = deferred2.promise
728 var deferred3 = Promise.defer()
729 var p3 = deferred3.promise
730 Promise.race([p1, p2, p3]).chain(
732 function(x) { assertAsync(x === 3, "one/reject/resolve") }
741 function MyPromise(resolver) {
743 var promise = new Promise(function(resolve, reject) {
745 function(x) { log += "x" + x; resolve(x) },
746 function(r) { log += "r" + r; reject(r) }
749 promise.__proto__ = MyPromise.prototype
753 MyPromise.__proto__ = Promise
754 MyPromise.defer = function() {
756 return this.__proto__.defer.call(this)
759 MyPromise.prototype.__proto__ = Promise.prototype
760 MyPromise.prototype.chain = function(resolve, reject) {
762 return this.__proto__.__proto__.chain.call(this, resolve, reject)
766 var p1 = new MyPromise(function(resolve, reject) { resolve(1) })
767 var p2 = new MyPromise(function(resolve, reject) { reject(2) })
768 var d3 = MyPromise.defer()
769 assertTrue(d3.promise instanceof Promise, "subclass/instance")
770 assertTrue(d3.promise instanceof MyPromise, "subclass/instance-my3")
771 assertTrue(log === "nx1nr2dn", "subclass/create")
774 var p4 = MyPromise.resolve(4)
775 var p5 = MyPromise.reject(5)
776 assertTrue(p4 instanceof Promise, "subclass/instance4")
777 assertTrue(p4 instanceof MyPromise, "subclass/instance-my4")
778 assertTrue(p5 instanceof Promise, "subclass/instance5")
779 assertTrue(p5 instanceof MyPromise, "subclass/instance-my5")
781 assertTrue(log === "nx4nr5x3", "subclass/resolve")
784 var d6 = MyPromise.defer()
785 d6.promise.chain(function(x) {
786 return new Promise(function(resolve) { resolve(x) })
787 }).chain(function() {})
789 assertTrue(log === "dncncnx6", "subclass/chain")
792 Promise.all([11, Promise.accept(12), 13, MyPromise.accept(14), 15, 16])
793 assertTrue(log === "nx14n", "subclass/all/arg")
796 MyPromise.all([21, Promise.accept(22), 23, MyPromise.accept(24), 25, 26])
797 assertTrue(log === "nx24nnx21nnx23nnnx25nnx26n", "subclass/all/self")