• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 --promise-extra
29
30// Make sure we don't rely on functions patchable by monkeys.
31var call = Function.prototype.call.call.bind(Function.prototype.call)
32var getOwnPropertyNames = Object.getOwnPropertyNames;
33var defineProperty = Object.defineProperty;
34var numberPrototype = Number.prototype;
35var symbolIterator = Symbol.iterator;
36
37
38(function() {
39  // Test before clearing global (fails otherwise)
40  assertEquals("[object Promise]",
41      Object.prototype.toString.call(new Promise(function() {})));
42})();
43
44
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) {
50    // Do not clobber Object.prototype.toString, which is used by tests.
51    if (properties[i] === "toString") continue;
52    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)
67var whitelist = {
68  Promise: true,
69  TypeError: true,
70  String: true,
71  JSON: true,
72  Error: true,
73  MjsUnitAssertionError: true
74};
75
76for (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
98function 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!");
110    }
111  }
112  %EnqueueMicrotask(runAssertion);
113}
114
115function 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}
126
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)
198  // Note: Chain now has then-style semantics, here and in future tests.
199  p3.chain(
200    function(x) { assertAsync(x === 5, "resolved/chain") },
201    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(
222    assertUnreachable,
223    function(x) { assertAsync(x === 5, "rejected/chain") }
224  )
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(
244    function(x) { assertAsync(x === 5, "resolved/chain/chain") },
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 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(
376    function(x) { assertAsync(x === 5, "resolved/thenable/chain") },
377    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(
398    assertUnreachable,
399    function(x) { assertAsync(x === 5, "rejected/thenable/chain") }
400  )
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(
421    function(x) { assertAsync(x === 5, "chain/resolve") },
422    assertUnreachable
423  )
424  deferred.resolve(5)
425  assertAsyncRan()
426})();
427
428(function() {
429  var deferred = Promise.defer()
430  var p1 = deferred.promise
431  var p2 = Promise.resolve(p1)
432  var p3 = Promise.resolve(p2)
433  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(
447    assertUnreachable,
448    function(x) { assertAsync(x === 5, "chain/reject") }
449  )
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(
497    function(x) { assertAsync(x === 5, "chain/resolve/thenable") },
498    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(
523    assertUnreachable,
524    function(x) { assertAsync(x === 5, "chain/reject/thenable") }
525  )
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(
549    function(x) { assertAsync(x === 5, "chain/resolve2") },
550    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(
601    function(x) { assertAsync(x === 5, "chain/resolve/thenable2") },
602    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(
646    assertUnreachable,
647    function(r) { assertAsync(r instanceof TypeError, "cyclic/deferred/then") }
648  )
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() {
664  Promise.all([]).chain(
665    function(x) { assertAsync(x.length === 0, "all/resolve/empty") },
666    assertUnreachable
667  )
668  assertAsyncRan()
669})();
670
671(function() {
672  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() {
711  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() {
765  '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() {
810  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() {
839  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
899
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
996(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)
1033  assertTrue(p4 instanceof MyPromise, "subclass/instance4")
1034  assertTrue(p4 instanceof MyPromise, "subclass/instance-my4")
1035  assertTrue(p5 instanceof MyPromise, "subclass/instance5")
1036  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])
1050
1051  assertTrue(log === "nx14", "subclass/all/arg")
1052
1053  log = ""
1054  MyPromise.all([21, Promise.accept(22), 23, MyPromise.accept(24), 25, 26])
1055  assertTrue(log === "nx24nnx21nnx[object Promise]nnx23nnnx25nnx26n",
1056             "subclass/all/self")
1057})();
1058
1059(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})();
1116
1117assertAsyncDone()
1118