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. 31 var call = Function.prototype.call.call.bind(Function.prototype.call) 32 var getOwnPropertyNames = Object.getOwnPropertyNames; 33 var defineProperty = Object.defineProperty; 34 var numberPrototype = Number.prototype; 35 var 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 45 function 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 56 function 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. 66 var globals = Object.getOwnPropertyNames(this) 67 var whitelist = { 68 Promise: true, 69 TypeError: true, 70 String: true, 71 JSON: true, 72 Error: true, 73 MjsUnitAssertionError: true 74 }; 75 76 for (var i in globals) { 77 var name = globals[i] 78 if (name in whitelist || name[0] === name[0].toLowerCase()) delete globals[i] 79 } 80 for (var i in globals) { 81 if (globals[i]) clearProp(this, globals[i]) 82 } 83 84 85 var asyncAssertsExpected = 0; 86 87 function assertAsyncRan() { ++asyncAssertsExpected } 88 89 function 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 98 function 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 115 function 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 1117 assertAsyncDone() 1118