OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 | 86 |
87 function assertAsync(b, s) { | 87 function assertAsync(b, s) { |
88 if (b) { | 88 if (b) { |
89 print(s, "succeeded") | 89 print(s, "succeeded") |
90 } else { | 90 } else { |
91 %AbortJS(s + " FAILED!") // Simply throwing here will have no effect. | 91 %AbortJS(s + " FAILED!") // Simply throwing here will have no effect. |
92 } | 92 } |
93 --asyncAssertsExpected | 93 --asyncAssertsExpected |
94 } | 94 } |
95 | 95 |
| 96 function assertLater(f, name) { |
| 97 assertFalse(f()); // should not be true synchronously |
| 98 ++asyncAssertsExpected; |
| 99 var iterations = 0; |
| 100 function runAssertion() { |
| 101 if (f()) { |
| 102 print(name, "succeeded"); |
| 103 --asyncAssertsExpected; |
| 104 } else if (iterations++ < 10) { |
| 105 %EnqueueMicrotask(runAssertion); |
| 106 } else { |
| 107 %AbortJS(name + " FAILED!"); |
| 108 } |
| 109 } |
| 110 %EnqueueMicrotask(runAssertion); |
| 111 } |
| 112 |
96 function assertAsyncDone(iteration) { | 113 function assertAsyncDone(iteration) { |
97 var iteration = iteration || 0; | 114 var iteration = iteration || 0; |
98 %EnqueueMicrotask(function() { | 115 %EnqueueMicrotask(function() { |
99 if (asyncAssertsExpected === 0) | 116 if (asyncAssertsExpected === 0) |
100 assertAsync(true, "all") | 117 assertAsync(true, "all") |
101 else if (iteration > 10) // Shouldn't take more. | 118 else if (iteration > 10) // Shouldn't take more. |
102 assertAsync(false, "all") | 119 assertAsync(false, "all... " + asyncAssertsExpected) |
103 else | 120 else |
104 assertAsyncDone(iteration + 1) | 121 assertAsyncDone(iteration + 1) |
105 }); | 122 }); |
106 } | 123 } |
107 | 124 |
108 (function() { | 125 (function() { |
109 assertThrows(function() { Promise(function() {}) }, TypeError) | 126 assertThrows(function() { Promise(function() {}) }, TypeError) |
110 })(); | 127 })(); |
111 | 128 |
112 (function() { | 129 (function() { |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 var p1 = Promise.reject(5) | 226 var p1 = Promise.reject(5) |
210 var p2 = Promise.accept(p1) | 227 var p2 = Promise.accept(p1) |
211 var p3 = Promise.accept(p2) | 228 var p3 = Promise.accept(p2) |
212 p3.then( | 229 p3.then( |
213 assertUnreachable, | 230 assertUnreachable, |
214 function(x) { assertAsync(x === 5, "rejected/then") } | 231 function(x) { assertAsync(x === 5, "rejected/then") } |
215 ) | 232 ) |
216 assertAsyncRan() | 233 assertAsyncRan() |
217 })(); | 234 })(); |
218 | 235 |
| 236 /* TODO(caitp): remove tests once PromiseChain is removed, per bug 3237 |
219 (function() { | 237 (function() { |
220 var p1 = Promise.accept(5) | 238 var p1 = Promise.accept(5) |
221 var p2 = Promise.accept(p1) | 239 var p2 = Promise.accept(p1) |
222 var p3 = Promise.accept(p2) | 240 var p3 = Promise.accept(p2) |
223 p3.chain(function(x) { return x }, assertUnreachable).chain( | 241 p3.chain(function(x) { return x }, assertUnreachable).chain( |
224 function(x) { assertAsync(x === p1, "resolved/chain/chain") }, | 242 function(x) { assertAsync(x === p1, "resolved/chain/chain") }, |
225 assertUnreachable | 243 assertUnreachable |
226 ) | 244 ) |
227 assertAsyncRan() | 245 assertAsyncRan() |
228 })(); | 246 })();*/ |
229 | 247 |
230 (function() { | 248 (function() { |
231 var p1 = Promise.accept(5) | 249 var p1 = Promise.accept(5) |
232 var p2 = Promise.accept(p1) | 250 var p2 = Promise.accept(p1) |
233 var p3 = Promise.accept(p2) | 251 var p3 = Promise.accept(p2) |
234 p3.chain(function(x) { return x }, assertUnreachable).then( | 252 p3.chain(function(x) { return x }, assertUnreachable).then( |
235 function(x) { assertAsync(x === 5, "resolved/chain/then") }, | 253 function(x) { assertAsync(x === 5, "resolved/chain/then") }, |
236 assertUnreachable | 254 assertUnreachable |
237 ) | 255 ) |
238 assertAsyncRan() | 256 assertAsyncRan() |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
513 var p2 = {then: function(onResolve, onReject) { onResolve(p1) }} | 531 var p2 = {then: function(onResolve, onReject) { onResolve(p1) }} |
514 var p3 = Promise.accept(p2) | 532 var p3 = Promise.accept(p2) |
515 p3.then( | 533 p3.then( |
516 assertUnreachable, | 534 assertUnreachable, |
517 function(x) { assertAsync(x === 5, "then/reject/thenable") } | 535 function(x) { assertAsync(x === 5, "then/reject/thenable") } |
518 ) | 536 ) |
519 deferred.reject(5) | 537 deferred.reject(5) |
520 assertAsyncRan() | 538 assertAsyncRan() |
521 })(); | 539 })(); |
522 | 540 |
| 541 /* TODO(caitp): remove tests once PromiseChain is removed, per bug v8:3237 |
523 (function() { | 542 (function() { |
524 var p1 = Promise.accept(5) | 543 var p1 = Promise.accept(5) |
525 var p2 = Promise.accept(p1) | 544 var p2 = Promise.accept(p1) |
526 var deferred = Promise.defer() | 545 var deferred = Promise.defer() |
527 var p3 = deferred.promise | 546 var p3 = deferred.promise |
528 p3.chain( | 547 p3.chain( |
529 function(x) { assertAsync(x === p2, "chain/resolve2") }, | 548 function(x) { assertAsync(x === p2, "chain/resolve2") }, |
530 assertUnreachable | 549 assertUnreachable |
531 ) | 550 ) |
532 deferred.resolve(p2) | 551 deferred.resolve(p2) |
533 assertAsyncRan() | 552 assertAsyncRan() |
534 })(); | 553 })(); */ |
535 | 554 |
536 (function() { | 555 (function() { |
537 var p1 = Promise.accept(5) | 556 var p1 = Promise.accept(5) |
538 var p2 = Promise.accept(p1) | 557 var p2 = Promise.accept(p1) |
539 var deferred = Promise.defer() | 558 var deferred = Promise.defer() |
540 var p3 = deferred.promise | 559 var p3 = deferred.promise |
541 p3.then( | 560 p3.then( |
542 function(x) { assertAsync(x === 5, "then/resolve2") }, | 561 function(x) { assertAsync(x === 5, "then/resolve2") }, |
543 assertUnreachable | 562 assertUnreachable |
544 ) | 563 ) |
(...skipping 20 matching lines...) Expand all Loading... |
565 var deferred = Promise.defer() | 584 var deferred = Promise.defer() |
566 var p3 = deferred.promise | 585 var p3 = deferred.promise |
567 p3.then( | 586 p3.then( |
568 assertUnreachable, | 587 assertUnreachable, |
569 function(x) { assertAsync(x === 5, "then/reject2") } | 588 function(x) { assertAsync(x === 5, "then/reject2") } |
570 ) | 589 ) |
571 deferred.reject(5) | 590 deferred.reject(5) |
572 assertAsyncRan() | 591 assertAsyncRan() |
573 })(); | 592 })(); |
574 | 593 |
| 594 /* TODO(caitp): remove tests once PromiseChain is removed, per bug v8:3237 |
575 (function() { | 595 (function() { |
576 var p1 = Promise.accept(5) | 596 var p1 = Promise.accept(5) |
577 var p2 = {then: function(onResolve, onReject) { onResolve(p1) }} | 597 var p2 = {then: function(onResolve, onReject) { onResolve(p1) }} |
578 var deferred = Promise.defer() | 598 var deferred = Promise.defer() |
579 var p3 = deferred.promise | 599 var p3 = deferred.promise |
580 p3.chain( | 600 p3.chain( |
581 function(x) { assertAsync(x === p2, "chain/resolve/thenable2") }, | 601 function(x) { assertAsync(x === p2, "chain/resolve/thenable2") }, |
582 assertUnreachable | 602 assertUnreachable |
583 ) | 603 ) |
584 deferred.resolve(p2) | 604 deferred.resolve(p2) |
585 assertAsyncRan() | 605 assertAsyncRan() |
586 })(); | 606 })(); */ |
587 | 607 |
588 (function() { | 608 (function() { |
589 var p1 = Promise.accept(5) | 609 var p1 = Promise.accept(5) |
590 var p2 = {then: function(onResolve, onReject) { onResolve(p1) }} | 610 var p2 = {then: function(onResolve, onReject) { onResolve(p1) }} |
591 var deferred = Promise.defer() | 611 var deferred = Promise.defer() |
592 var p3 = deferred.promise | 612 var p3 = deferred.promise |
593 p3.then( | 613 p3.then( |
594 function(x) { assertAsync(x === 5, "then/resolve/thenable2") }, | 614 function(x) { assertAsync(x === 5, "then/resolve/thenable2") }, |
595 assertUnreachable | 615 assertUnreachable |
596 ) | 616 ) |
(...skipping 14 matching lines...) Expand all Loading... |
611 (function() { | 631 (function() { |
612 var p1 = Promise.accept(0) | 632 var p1 = Promise.accept(0) |
613 var p2 = p1.then(function(x) { return p2 }, assertUnreachable) | 633 var p2 = p1.then(function(x) { return p2 }, assertUnreachable) |
614 p2.chain( | 634 p2.chain( |
615 assertUnreachable, | 635 assertUnreachable, |
616 function(r) { assertAsync(r instanceof TypeError, "cyclic/then") } | 636 function(r) { assertAsync(r instanceof TypeError, "cyclic/then") } |
617 ) | 637 ) |
618 assertAsyncRan() | 638 assertAsyncRan() |
619 })(); | 639 })(); |
620 | 640 |
| 641 /* TODO(caitp): remove tests once PromiseChain is removed, per bug v8:3237 |
621 (function() { | 642 (function() { |
622 var deferred = Promise.defer() | 643 var deferred = Promise.defer() |
623 var p = deferred.promise | 644 var p = deferred.promise |
624 deferred.resolve(p) | 645 deferred.resolve(p) |
625 p.chain( | 646 p.chain( |
626 function(x) { assertAsync(x === p, "cyclic/deferred/chain") }, | 647 function(x) { assertAsync(x === p, "cyclic/deferred/chain") }, |
627 assertUnreachable | 648 assertUnreachable |
628 ) | 649 ) |
629 assertAsyncRan() | 650 assertAsyncRan() |
630 })(); | 651 })();*/ |
631 | 652 |
| 653 /* TODO(caitp): remove tests once PromiseChain is removed, per bug v8:3237 |
632 (function() { | 654 (function() { |
633 var deferred = Promise.defer() | 655 var deferred = Promise.defer() |
634 var p = deferred.promise | 656 var p = deferred.promise |
635 deferred.resolve(p) | 657 deferred.resolve(p) |
636 p.then( | 658 p.then( |
637 assertUnreachable, | 659 assertUnreachable, |
638 function(r) { assertAsync(r instanceof TypeError, "cyclic/deferred/then") } | 660 function(r) { assertAsync(r instanceof TypeError, "cyclic/deferred/then") } |
639 ) | 661 ) |
640 assertAsyncRan() | 662 assertAsyncRan() |
641 })(); | 663 })();*/ |
642 | 664 |
643 (function() { | 665 (function() { |
644 Promise.all([]).chain( | 666 Promise.all([]).chain( |
645 function(x) { assertAsync(x.length === 0, "all/resolve/empty") }, | 667 function(x) { assertAsync(x.length === 0, "all/resolve/empty") }, |
646 assertUnreachable | 668 assertUnreachable |
647 ) | 669 ) |
648 assertAsyncRan() | 670 assertAsyncRan() |
649 })(); | 671 })(); |
650 | 672 |
651 (function() { | 673 (function() { |
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1052 "subclass/resolve/ancestor"); | 1074 "subclass/resolve/ancestor"); |
1053 | 1075 |
1054 assertTrue(Pact.resolve(Vow.resolve()).constructor === Pact, | 1076 assertTrue(Pact.resolve(Vow.resolve()).constructor === Pact, |
1055 "subclass/resolve/descendant"); var vow = Vow.resolve(); | 1077 "subclass/resolve/descendant"); var vow = Vow.resolve(); |
1056 | 1078 |
1057 vow.constructor = Oath; | 1079 vow.constructor = Oath; |
1058 assertTrue(Oath.resolve(vow) === vow, | 1080 assertTrue(Oath.resolve(vow) === vow, |
1059 "subclass/resolve/descendant with transplanted own constructor"); | 1081 "subclass/resolve/descendant with transplanted own constructor"); |
1060 }()); | 1082 }()); |
1061 | 1083 |
| 1084 (function() { |
| 1085 var thenCalled = false; |
| 1086 |
| 1087 var resolve; |
| 1088 var promise = new Promise(function(res) { resolve = res; }); |
| 1089 resolve({ then() { thenCalled = true; throw new Error(); } }); |
| 1090 assertLater(function() { return thenCalled; }, "resolve-with-thenable"); |
| 1091 }); |
| 1092 |
| 1093 (function() { |
| 1094 var calledWith; |
| 1095 |
| 1096 var resolve; |
| 1097 var p1 = (new Promise(function(res) { resolve = res; })); |
| 1098 var p2 = p1.then(function(v) { |
| 1099 return { |
| 1100 then(resolve, reject) { resolve({ then() { calledWith = v }}); } |
| 1101 }; |
| 1102 }); |
| 1103 |
| 1104 resolve({ then(resolve) { resolve(2); } }); |
| 1105 assertLater(function() { return calledWith === 2; }, |
| 1106 "resolve-with-thenable2"); |
| 1107 })(); |
| 1108 |
| 1109 (function() { |
| 1110 var p = Promise.resolve(); |
| 1111 var callCount = 0; |
| 1112 defineProperty(p, "constructor", { |
| 1113 get: function() { ++callCount; return Promise; } |
| 1114 }); |
| 1115 p.then(); |
| 1116 assertEquals(1, callCount); |
| 1117 })(); |
| 1118 |
1062 assertAsyncDone() | 1119 assertAsyncDone() |
OLD | NEW |