deps: update v8 to 4.3.61.21
[platform/upstream/nodejs.git] / deps / v8 / test / mjsunit / es6 / promises.js
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
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
28 // Flags: --allow-natives-syntax --harmony-tostring
29
30 // Make sure we don't rely on functions patchable by monkeys.
31 var call = Function.prototype.call.call.bind(Function.prototype.call)
32 var observe = Object.observe;
33 var getOwnPropertyNames = Object.getOwnPropertyNames;
34 var defineProperty = Object.defineProperty;
35 var numberPrototype = Number.prototype;
36 var symbolIterator = Symbol.iterator;
37
38
39 (function() {
40   // Test before clearing global (fails otherwise)
41   assertEquals("[object Promise]",
42       Object.prototype.toString.call(new Promise(function() {})));
43 })();
44
45
46 function clear(o) {
47   if (o === null || (typeof o !== 'object' && typeof o !== 'function')) return
48   clear(o.__proto__)
49   var properties = getOwnPropertyNames(o)
50   for (var i in properties) {
51     clearProp(o, properties[i])
52   }
53 }
54
55 function clearProp(o, name) {
56   var poisoned = {caller: 0, callee: 0, arguments: 0}
57   try {
58     var x = o[name]
59     o[name] = undefined
60     clear(x)
61   } catch(e) {} // assertTrue(name in poisoned) }
62 }
63
64 // Find intrinsics and null them out.
65 var globals = Object.getOwnPropertyNames(this)
66 var whitelist = {Promise: true, TypeError: true}
67 for (var i in globals) {
68   var name = globals[i]
69   if (name in whitelist || name[0] === name[0].toLowerCase()) delete globals[i]
70 }
71 for (var i in globals) {
72   if (globals[i]) clearProp(this, globals[i])
73 }
74
75
76 var asyncAssertsExpected = 0;
77
78 function assertAsyncRan() { ++asyncAssertsExpected }
79
80 function assertAsync(b, s) {
81   if (b) {
82     print(s, "succeeded")
83   } else {
84     %AbortJS(s + " FAILED!")  // Simply throwing here will have no effect.
85   }
86   --asyncAssertsExpected
87 }
88
89 function assertAsyncDone(iteration) {
90   var iteration = iteration || 0
91   var dummy = {}
92   observe(dummy,
93     function() {
94       if (asyncAssertsExpected === 0)
95         assertAsync(true, "all")
96       else if (iteration > 10)  // Shouldn't take more.
97         assertAsync(false, "all")
98       else
99         assertAsyncDone(iteration + 1)
100     }
101   )
102   dummy.dummy = dummy
103 }
104
105
106 (function() {
107   assertThrows(function() { Promise(function() {}) }, TypeError)
108 })();
109
110 (function() {
111   assertTrue(new Promise(function() {}) instanceof Promise)
112 })();
113
114 (function() {
115   assertThrows(function() { new Promise(5) }, TypeError)
116 })();
117
118 (function() {
119   assertDoesNotThrow(function() { new Promise(function() { throw 5 }) })
120 })();
121
122 (function() {
123   (new Promise(function() { throw 5 })).chain(
124     assertUnreachable,
125     function(r) { assertAsync(r === 5, "new-throw") }
126   )
127   assertAsyncRan()
128 })();
129
130 (function() {
131   Promise.accept(5);
132   Promise.accept(5).chain(undefined, assertUnreachable).chain(
133     function(x) { assertAsync(x === 5, "resolved/chain-nohandler") },
134     assertUnreachable
135   )
136   assertAsyncRan()
137 })();
138
139 (function() {
140   Promise.reject(5).chain(assertUnreachable, undefined).chain(
141     assertUnreachable,
142     function(r) { assertAsync(r === 5, "rejected/chain-nohandler") }
143   )
144   assertAsyncRan()
145 })();
146
147 (function() {
148   Promise.accept(5).then(undefined, assertUnreachable).chain(
149     function(x) { assertAsync(x === 5, "resolved/then-nohandler-undefined") },
150     assertUnreachable
151   )
152   assertAsyncRan()
153   Promise.accept(6).then(null, assertUnreachable).chain(
154     function(x) { assertAsync(x === 6, "resolved/then-nohandler-null") },
155     assertUnreachable
156   )
157   assertAsyncRan()
158 })();
159
160 (function() {
161   Promise.reject(5).then(assertUnreachable, undefined).chain(
162     assertUnreachable,
163     function(r) { assertAsync(r === 5, "rejected/then-nohandler-undefined") }
164   )
165   assertAsyncRan()
166   Promise.reject(6).then(assertUnreachable, null).chain(
167     assertUnreachable,
168     function(r) { assertAsync(r === 6, "rejected/then-nohandler-null") }
169   )
170   assertAsyncRan()
171 })();
172
173 (function() {
174   var p1 = Promise.accept(5)
175   var p2 = Promise.accept(p1)
176   var p3 = Promise.accept(p2)
177   p3.chain(
178     function(x) { assertAsync(x === p2, "resolved/chain") },
179     assertUnreachable
180   )
181   assertAsyncRan()
182 })();
183
184 (function() {
185   var p1 = Promise.accept(5)
186   var p2 = Promise.accept(p1)
187   var p3 = Promise.accept(p2)
188   p3.then(
189     function(x) { assertAsync(x === 5, "resolved/then") },
190     assertUnreachable
191   )
192   assertAsyncRan()
193 })();
194
195 (function() {
196   var p1 = Promise.reject(5)
197   var p2 = Promise.accept(p1)
198   var p3 = Promise.accept(p2)
199   p3.chain(
200     function(x) { assertAsync(x === p2, "rejected/chain") },
201     assertUnreachable
202   )
203   assertAsyncRan()
204 })();
205
206 (function() {
207   var p1 = Promise.reject(5)
208   var p2 = Promise.accept(p1)
209   var p3 = Promise.accept(p2)
210   p3.then(
211     assertUnreachable,
212     function(x) { assertAsync(x === 5, "rejected/then") }
213   )
214   assertAsyncRan()
215 })();
216
217 (function() {
218   var p1 = Promise.accept(5)
219   var p2 = Promise.accept(p1)
220   var p3 = Promise.accept(p2)
221   p3.chain(function(x) { return x }, assertUnreachable).chain(
222     function(x) { assertAsync(x === p1, "resolved/chain/chain") },
223     assertUnreachable
224   )
225   assertAsyncRan()
226 })();
227
228 (function() {
229   var p1 = Promise.accept(5)
230   var p2 = Promise.accept(p1)
231   var p3 = Promise.accept(p2)
232   p3.chain(function(x) { return x }, assertUnreachable).then(
233     function(x) { assertAsync(x === 5, "resolved/chain/then") },
234     assertUnreachable
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 6 }, assertUnreachable).chain(
244     function(x) { assertAsync(x === 6, "resolved/chain/chain2") },
245     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 6 }, assertUnreachable).then(
255     function(x) { assertAsync(x === 6, "resolved/chain/then2") },
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.then(function(x) { return x + 1 }, assertUnreachable).chain(
266     function(x) { assertAsync(x === 6, "resolved/then/chain") },
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.then(function(x) { return x + 1 }, assertUnreachable).then(
277     function(x) { assertAsync(x === 6, "resolved/then/then") },
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 Promise.accept(x+1) }, assertUnreachable).chain(
288     function(x) { assertAsync(x === 6, "resolved/then/chain2") },
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 Promise.accept(x+1) }, assertUnreachable).then(
299     function(x) { assertAsync(x === 6, "resolved/then/then2") },
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.chain(function(x) { throw 6 }, assertUnreachable).chain(
310     assertUnreachable,
311     function(x) { assertAsync(x === 6, "resolved/chain-throw/chain") }
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.chain(function(x) { throw 6 }, assertUnreachable).then(
321     assertUnreachable,
322     function(x) { assertAsync(x === 6, "resolved/chain-throw/then") }
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.then(function(x) { throw 6 }, assertUnreachable).chain(
332     assertUnreachable,
333     function(x) { assertAsync(x === 6, "resolved/then-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.then(function(x) { throw 6 }, assertUnreachable).then(
343     assertUnreachable,
344     function(x) { assertAsync(x === 6, "resolved/then-throw/then") }
345   )
346   assertAsyncRan()
347 })();
348
349 (function() {
350   var p1 = Promise.accept(5)
351   var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}
352   var p3 = Promise.accept(p2)
353   p3.chain(
354     function(x) { assertAsync(x === p2, "resolved/thenable/chain") },
355     assertUnreachable
356   )
357   assertAsyncRan()
358 })();
359
360 (function() {
361   var p1 = Promise.accept(5)
362   var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}
363   var p3 = Promise.accept(p2)
364   p3.then(
365     function(x) { assertAsync(x === 5, "resolved/thenable/then") },
366     assertUnreachable
367   )
368   assertAsyncRan()
369 })();
370
371 (function() {
372   var p1 = Promise.reject(5)
373   var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}
374   var p3 = Promise.accept(p2)
375   p3.chain(
376     function(x) { assertAsync(x === p2, "rejected/thenable/chain") },
377     assertUnreachable
378   )
379   assertAsyncRan()
380 })();
381
382 (function() {
383   var p1 = Promise.reject(5)
384   var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}
385   var p3 = Promise.accept(p2)
386   p3.then(
387     assertUnreachable,
388     function(x) { assertAsync(x === 5, "rejected/thenable/then") }
389   )
390   assertAsyncRan()
391 })();
392
393 (function() {
394   var deferred = Promise.defer()
395   var p1 = deferred.promise
396   var p2 = Promise.accept(p1)
397   var p3 = Promise.accept(p2)
398   p3.chain(
399     function(x) { assertAsync(x === p2, "chain/resolve") },
400     assertUnreachable
401   )
402   deferred.resolve(5)
403   assertAsyncRan()
404 })();
405
406 (function() {
407   var deferred = Promise.defer()
408   var p1 = deferred.promise
409   var p2 = Promise.accept(p1)
410   var p3 = Promise.accept(p2)
411   p3.then(
412     function(x) { assertAsync(x === 5, "then/resolve") },
413     assertUnreachable
414   )
415   deferred.resolve(5)
416   assertAsyncRan()
417 })();
418
419 (function() {
420   var deferred = Promise.defer()
421   var p1 = deferred.promise
422   var p2 = Promise.accept(p1)
423   var p3 = Promise.accept(p2)
424   p3.chain(
425     function(x) { assertAsync(x === p2, "chain/reject") },
426     assertUnreachable
427   )
428   deferred.reject(5)
429   assertAsyncRan()
430 })();
431
432 (function() {
433   var deferred = Promise.defer()
434   var p1 = deferred.promise
435   var p2 = Promise.accept(p1)
436   var p3 = Promise.accept(p2)
437   p3.then(
438     assertUnreachable,
439     function(x) { assertAsync(x === 5, "then/reject") }
440   )
441   deferred.reject(5)
442   assertAsyncRan()
443 })();
444
445 (function() {
446   var deferred = Promise.defer()
447   var p1 = deferred.promise
448   var p2 = p1.then(1, 2)
449   p2.then(
450     function(x) { assertAsync(x === 5, "then/resolve-non-function") },
451     assertUnreachable
452   )
453   deferred.resolve(5)
454   assertAsyncRan()
455 })();
456
457 (function() {
458   var deferred = Promise.defer()
459   var p1 = deferred.promise
460   var p2 = p1.then(1, 2)
461   p2.then(
462     assertUnreachable,
463     function(x) { assertAsync(x === 5, "then/reject-non-function") }
464   )
465   deferred.reject(5)
466   assertAsyncRan()
467 })();
468
469 (function() {
470   var deferred = Promise.defer()
471   var p1 = deferred.promise
472   var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}
473   var p3 = Promise.accept(p2)
474   p3.chain(
475     function(x) { assertAsync(x === p2, "chain/resolve/thenable") },
476     assertUnreachable
477   )
478   deferred.resolve(5)
479   assertAsyncRan()
480 })();
481
482 (function() {
483   var deferred = Promise.defer()
484   var p1 = deferred.promise
485   var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}
486   var p3 = Promise.accept(p2)
487   p3.then(
488     function(x) { assertAsync(x === 5, "then/resolve/thenable") },
489     assertUnreachable
490   )
491   deferred.resolve(5)
492   assertAsyncRan()
493 })();
494
495 (function() {
496   var deferred = Promise.defer()
497   var p1 = deferred.promise
498   var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}
499   var p3 = Promise.accept(p2)
500   p3.chain(
501     function(x) { assertAsync(x === p2, "chain/reject/thenable") },
502     assertUnreachable
503   )
504   deferred.reject(5)
505   assertAsyncRan()
506 })();
507
508 (function() {
509   var deferred = Promise.defer()
510   var p1 = deferred.promise
511   var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}
512   var p3 = Promise.accept(p2)
513   p3.then(
514     assertUnreachable,
515     function(x) { assertAsync(x === 5, "then/reject/thenable") }
516   )
517   deferred.reject(5)
518   assertAsyncRan()
519 })();
520
521 (function() {
522   var p1 = Promise.accept(5)
523   var p2 = Promise.accept(p1)
524   var deferred = Promise.defer()
525   var p3 = deferred.promise
526   p3.chain(
527     function(x) { assertAsync(x === p2, "chain/resolve2") },
528     assertUnreachable
529   )
530   deferred.resolve(p2)
531   assertAsyncRan()
532 })();
533
534 (function() {
535   var p1 = Promise.accept(5)
536   var p2 = Promise.accept(p1)
537   var deferred = Promise.defer()
538   var p3 = deferred.promise
539   p3.then(
540     function(x) { assertAsync(x === 5, "then/resolve2") },
541     assertUnreachable
542   )
543   deferred.resolve(p2)
544   assertAsyncRan()
545 })();
546
547 (function() {
548   var p1 = Promise.accept(5)
549   var p2 = Promise.accept(p1)
550   var deferred = Promise.defer()
551   var p3 = deferred.promise
552   p3.chain(
553     assertUnreachable,
554     function(x) { assertAsync(x === 5, "chain/reject2") }
555   )
556   deferred.reject(5)
557   assertAsyncRan()
558 })();
559
560 (function() {
561   var p1 = Promise.accept(5)
562   var p2 = Promise.accept(p1)
563   var deferred = Promise.defer()
564   var p3 = deferred.promise
565   p3.then(
566     assertUnreachable,
567     function(x) { assertAsync(x === 5, "then/reject2") }
568   )
569   deferred.reject(5)
570   assertAsyncRan()
571 })();
572
573 (function() {
574   var p1 = Promise.accept(5)
575   var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}
576   var deferred = Promise.defer()
577   var p3 = deferred.promise
578   p3.chain(
579     function(x) { assertAsync(x === p2, "chain/resolve/thenable2") },
580     assertUnreachable
581   )
582   deferred.resolve(p2)
583   assertAsyncRan()
584 })();
585
586 (function() {
587   var p1 = Promise.accept(5)
588   var p2 = {then: function(onResolve, onReject) { onResolve(p1) }}
589   var deferred = Promise.defer()
590   var p3 = deferred.promise
591   p3.then(
592     function(x) { assertAsync(x === 5, "then/resolve/thenable2") },
593     assertUnreachable
594   )
595   deferred.resolve(p2)
596   assertAsyncRan()
597 })();
598
599 (function() {
600   var p1 = Promise.accept(0)
601   var p2 = p1.chain(function(x) { return p2 }, assertUnreachable)
602   p2.chain(
603     assertUnreachable,
604     function(r) { assertAsync(r instanceof TypeError, "cyclic/chain") }
605   )
606   assertAsyncRan()
607 })();
608
609 (function() {
610   var p1 = Promise.accept(0)
611   var p2 = p1.then(function(x) { return p2 }, assertUnreachable)
612   p2.chain(
613     assertUnreachable,
614     function(r) { assertAsync(r instanceof TypeError, "cyclic/then") }
615   )
616   assertAsyncRan()
617 })();
618
619 (function() {
620   var deferred = Promise.defer()
621   var p = deferred.promise
622   deferred.resolve(p)
623   p.chain(
624     function(x) { assertAsync(x === p, "cyclic/deferred/chain") },
625     assertUnreachable
626   )
627   assertAsyncRan()
628 })();
629
630 (function() {
631   var deferred = Promise.defer()
632   var p = deferred.promise
633   deferred.resolve(p)
634   p.then(
635     assertUnreachable,
636     function(r) { assertAsync(r instanceof TypeError, "cyclic/deferred/then") }
637   )
638   assertAsyncRan()
639 })();
640
641 (function() {
642   Promise.all([]).chain(
643     function(x) { assertAsync(x.length === 0, "all/resolve/empty") },
644     assertUnreachable
645   )
646   assertAsyncRan()
647 })();
648
649 (function() {
650   function testPromiseAllNonIterable(value) {
651     Promise.all(value).chain(
652         assertUnreachable,
653         function(r) {
654           assertAsync(r instanceof TypeError, 'all/non iterable');
655         });
656     assertAsyncRan();
657   }
658   testPromiseAllNonIterable(null);
659   testPromiseAllNonIterable(undefined);
660   testPromiseAllNonIterable({});
661   testPromiseAllNonIterable(42);
662 })();
663
664 (function() {
665   var deferred = Promise.defer();
666   var p = deferred.promise;
667   function* f() {
668     yield 1;
669     yield p;
670     yield 3;
671   }
672   Promise.all(f()).chain(
673       function(x) {
674         assertAsync(x.length === 3, "all/resolve/iterable");
675         assertAsync(x[0] === 1, "all/resolve/iterable/0");
676         assertAsync(x[1] === 2, "all/resolve/iterable/1");
677         assertAsync(x[2] === 3, "all/resolve/iterable/2");
678       },
679       assertUnreachable);
680   deferred.resolve(2);
681   assertAsyncRan();
682   assertAsyncRan();
683   assertAsyncRan();
684   assertAsyncRan();
685 })();
686
687
688 (function() {
689   var deferred1 = Promise.defer()
690   var p1 = deferred1.promise
691   var deferred2 = Promise.defer()
692   var p2 = deferred2.promise
693   var deferred3 = Promise.defer()
694   var p3 = deferred3.promise
695   Promise.all([p1, p2, p3]).chain(
696     function(x) {
697       assertAsync(x.length === 3, "all/resolve")
698       assertAsync(x[0] === 1, "all/resolve/0")
699       assertAsync(x[1] === 2, "all/resolve/1")
700       assertAsync(x[2] === 3, "all/resolve/2")
701     },
702     assertUnreachable
703   )
704   deferred1.resolve(1)
705   deferred3.resolve(3)
706   deferred2.resolve(2)
707   assertAsyncRan()
708   assertAsyncRan()
709   assertAsyncRan()
710   assertAsyncRan()
711 })();
712
713 (function() {
714   var deferred = Promise.defer()
715   var p1 = deferred.promise
716   var p2 = Promise.accept(2)
717   var p3 = Promise.defer().promise
718   Promise.all([p1, p2, p3]).chain(
719     assertUnreachable,
720     assertUnreachable
721   )
722   deferred.resolve(1)
723 })();
724
725 (function() {
726   var deferred1 = Promise.defer()
727   var p1 = deferred1.promise
728   var deferred2 = Promise.defer()
729   var p2 = deferred2.promise
730   var deferred3 = Promise.defer()
731   var p3 = deferred3.promise
732   Promise.all([p1, p2, p3]).chain(
733     assertUnreachable,
734     function(x) { assertAsync(x === 2, "all/reject") }
735   )
736   deferred1.resolve(1)
737   deferred3.resolve(3)
738   deferred2.reject(2)
739   assertAsyncRan()
740 })();
741
742
743 (function() {
744   'use strict';
745   var getCalls = 0;
746   var funcCalls = 0;
747   var nextCalls = 0;
748   defineProperty(numberPrototype, symbolIterator, {
749     get: function() {
750       assertEquals('number', typeof this);
751       getCalls++;
752       return function() {
753         assertEquals('number', typeof this);
754         funcCalls++;
755         var n = this;
756         var i = 0
757         return {
758           next() {
759             nextCalls++;
760             return {value: i++, done: i > n};
761           }
762         };
763       };
764     },
765     configurable: true
766   });
767
768   Promise.all(3).chain(
769       function(x) {
770         assertAsync(x.length === 3, "all/iterable/number/length");
771         assertAsync(x[0] === 0, "all/iterable/number/0");
772         assertAsync(x[1] === 1, "all/iterable/number/1");
773         assertAsync(x[2] === 2, "all/iterable/number/2");
774       },
775       assertUnreachable);
776   delete numberPrototype[symbolIterator];
777
778   assertEquals(getCalls, 1);
779   assertEquals(funcCalls, 1);
780   assertEquals(nextCalls, 3 + 1);  // + 1 for {done: true}
781   assertAsyncRan();
782   assertAsyncRan();
783   assertAsyncRan();
784   assertAsyncRan();
785 })();
786
787
788 (function() {
789   Promise.race([]).chain(
790     assertUnreachable,
791     assertUnreachable
792   )
793 })();
794
795 (function() {
796   var p1 = Promise.accept(1)
797   var p2 = Promise.accept(2)
798   var p3 = Promise.accept(3)
799   Promise.race([p1, p2, p3]).chain(
800     function(x) { assertAsync(x === 1, "resolved/one") },
801     assertUnreachable
802   )
803   assertAsyncRan()
804 })();
805
806 (function() {
807   var p1 = Promise.accept(1)
808   var p2 = Promise.accept(2)
809   var p3 = Promise.accept(3)
810   Promise.race([0, p1, p2, p3]).chain(
811     function(x) { assertAsync(x === 0, "resolved-const/one") },
812     assertUnreachable
813   )
814   assertAsyncRan()
815 })();
816
817 (function() {
818   var deferred1 = Promise.defer()
819   var p1 = deferred1.promise
820   var deferred2 = Promise.defer()
821   var p2 = deferred2.promise
822   var deferred3 = Promise.defer()
823   var p3 = deferred3.promise
824   Promise.race([p1, p2, p3]).chain(
825     function(x) { assertAsync(x === 3, "one/resolve") },
826     assertUnreachable
827   )
828   deferred3.resolve(3)
829   deferred1.resolve(1)
830   assertAsyncRan()
831 })();
832
833 (function() {
834   var deferred = Promise.defer()
835   var p1 = deferred.promise
836   var p2 = Promise.accept(2)
837   var p3 = Promise.defer().promise
838   Promise.race([p1, p2, p3]).chain(
839     function(x) { assertAsync(x === 2, "resolved/one") },
840     assertUnreachable
841   )
842   deferred.resolve(1)
843   assertAsyncRan()
844 })();
845
846 (function() {
847   var deferred1 = Promise.defer()
848   var p1 = deferred1.promise
849   var deferred2 = Promise.defer()
850   var p2 = deferred2.promise
851   var deferred3 = Promise.defer()
852   var p3 = deferred3.promise
853   Promise.race([p1, p2, p3]).chain(
854     function(x) { assertAsync(x === 3, "one/resolve/reject") },
855     assertUnreachable
856   )
857   deferred3.resolve(3)
858   deferred1.reject(1)
859   assertAsyncRan()
860 })();
861
862 (function() {
863   var deferred1 = Promise.defer()
864   var p1 = deferred1.promise
865   var deferred2 = Promise.defer()
866   var p2 = deferred2.promise
867   var deferred3 = Promise.defer()
868   var p3 = deferred3.promise
869   Promise.race([p1, p2, p3]).chain(
870     assertUnreachable,
871     function(x) { assertAsync(x === 3, "one/reject/resolve") }
872   )
873   deferred3.reject(3)
874   deferred1.resolve(1)
875   assertAsyncRan()
876 })();
877
878
879 (function() {
880   function testPromiseRaceNonIterable(value) {
881     Promise.race(value).chain(
882         assertUnreachable,
883         function(r) {
884           assertAsync(r instanceof TypeError, 'race/non iterable');
885         });
886     assertAsyncRan();
887   }
888   testPromiseRaceNonIterable(null);
889   testPromiseRaceNonIterable(undefined);
890   testPromiseRaceNonIterable({});
891   testPromiseRaceNonIterable(42);
892 })();
893
894
895 (function() {
896   var deferred1 = Promise.defer()
897   var p1 = deferred1.promise
898   var deferred2 = Promise.defer()
899   var p2 = deferred2.promise
900   var deferred3 = Promise.defer()
901   var p3 = deferred3.promise
902   function* f() {
903     yield p1;
904     yield p2;
905     yield p3;
906   }
907   Promise.race(f()).chain(
908     function(x) { assertAsync(x === 3, "race/iterable/resolve/reject") },
909     assertUnreachable
910   )
911   deferred3.resolve(3)
912   deferred1.reject(1)
913   assertAsyncRan()
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     assertUnreachable,
930     function(x) { assertAsync(x === 3, "race/iterable/reject/resolve") }
931   )
932   deferred3.reject(3)
933   deferred1.resolve(1)
934   assertAsyncRan()
935 })();
936
937 (function() {
938   'use strict';
939   var getCalls = 0;
940   var funcCalls = 0;
941   var nextCalls = 0;
942   defineProperty(numberPrototype, symbolIterator, {
943     get: function() {
944       assertEquals('number', typeof this);
945       getCalls++;
946       return function() {
947         assertEquals('number', typeof this);
948         funcCalls++;
949         var n = this;
950         var i = 0
951         return {
952           next() {
953             nextCalls++;
954             return {value: i++, done: i > n};
955           }
956         };
957       };
958     },
959     configurable: true
960   });
961
962   Promise.race(3).chain(
963       function(x) {
964         assertAsync(x === 0, "race/iterable/number");
965       },
966       assertUnreachable);
967   delete numberPrototype[symbolIterator];
968
969   assertEquals(getCalls, 1);
970   assertEquals(funcCalls, 1);
971   assertEquals(nextCalls, 3 + 1);  // + 1 for {done: true}
972   assertAsyncRan();
973 })();
974
975 (function() {
976   var log
977   function MyPromise(resolver) {
978     log += "n"
979     var promise = new Promise(function(resolve, reject) {
980       resolver(
981         function(x) { log += "x" + x; resolve(x) },
982         function(r) { log += "r" + r; reject(r) }
983       )
984     })
985     promise.__proto__ = MyPromise.prototype
986     return promise
987   }
988
989   MyPromise.__proto__ = Promise
990   MyPromise.defer = function() {
991     log += "d"
992     return call(this.__proto__.defer, this)
993   }
994
995   MyPromise.prototype.__proto__ = Promise.prototype
996   MyPromise.prototype.chain = function(resolve, reject) {
997     log += "c"
998     return call(this.__proto__.__proto__.chain, this, resolve, reject)
999   }
1000
1001   log = ""
1002   var p1 = new MyPromise(function(resolve, reject) { resolve(1) })
1003   var p2 = new MyPromise(function(resolve, reject) { reject(2) })
1004   var d3 = MyPromise.defer()
1005   assertTrue(d3.promise instanceof Promise, "subclass/instance")
1006   assertTrue(d3.promise instanceof MyPromise, "subclass/instance-my3")
1007   assertTrue(log === "nx1nr2dn", "subclass/create")
1008
1009   log = ""
1010   var p4 = MyPromise.resolve(4)
1011   var p5 = MyPromise.reject(5)
1012   assertTrue(p4 instanceof Promise, "subclass/instance4")
1013   assertTrue(p4 instanceof MyPromise, "subclass/instance-my4")
1014   assertTrue(p5 instanceof Promise, "subclass/instance5")
1015   assertTrue(p5 instanceof MyPromise, "subclass/instance-my5")
1016   d3.resolve(3)
1017   assertTrue(log === "nx4nr5x3", "subclass/resolve")
1018
1019   log = ""
1020   var d6 = MyPromise.defer()
1021   d6.promise.chain(function(x) {
1022     return new Promise(function(resolve) { resolve(x) })
1023   }).chain(function() {})
1024   d6.resolve(6)
1025   assertTrue(log === "dncncnx6", "subclass/chain")
1026
1027   log = ""
1028   Promise.all([11, Promise.accept(12), 13, MyPromise.accept(14), 15, 16])
1029   assertTrue(log === "nx14n", "subclass/all/arg")
1030
1031   log = ""
1032   MyPromise.all([21, Promise.accept(22), 23, MyPromise.accept(24), 25, 26])
1033   assertTrue(log === "nx24nnx21nnx23nnnx25nnx26n", "subclass/all/self")
1034 })();
1035
1036
1037 assertAsyncDone()