ticks-with-async-iter-resolved-promise-and-constructor-lookup-two.js (2319B)
1 // |reftest| async 2 // Copyright (C) 2019 André Bargull. All rights reserved. 3 // This code is governed by the BSD license found in the LICENSE file. 4 5 /*--- 6 esid: sec-runtime-semantics-forin-div-ofbodyevaluation-lhs-stmt-iterator-lhskind-labelset 7 description: > 8 Ensure the number of ticks and Promise constructor lookups is correct with custom async iterator. 9 info: | 10 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation ( lhs, stmt, iteratorRecord, iterationKind, 11 lhsKind, labelSet [ , iteratorKind ] ) 12 25.6.4.5.1 PromiseResolve 13 6.2.3.1 Await 14 15 includes: [compareArray.js] 16 flags: [async] 17 features: [async-iteration] 18 ---*/ 19 20 // The expected event log. 21 var expected = [ 22 // Before entering loop. 23 "pre", 24 25 // Await 26 // -> PromiseResolve 27 "constructor", 28 29 // Await promise resolved. 30 "tick 1", 31 32 // In loop body. 33 "loop", 34 35 // Await 36 // -> PromiseResolve 37 "constructor", 38 39 // Await promise resolved 40 "tick 2", 41 42 // After exiting loop. 43 "post", 44 ]; 45 46 // The actual event log. 47 var actual = []; 48 49 // Custom async iterator returning the result of the synchronous iterator wrapped in a Promise. 50 function toAsyncIterator(iterable) { 51 return { 52 [Symbol.asyncIterator]() { 53 var iter = iterable[Symbol.iterator](); 54 return { 55 next() { 56 return Promise.resolve(iter.next()); 57 } 58 }; 59 } 60 }; 61 } 62 63 // Test function using for-await with a single, already resolved Promise. 64 async function f() { 65 var p = Promise.resolve(0); 66 actual.push("pre"); 67 for await (var x of toAsyncIterator([p])) { 68 actual.push("loop"); 69 } 70 actual.push("post"); 71 } 72 73 // Count the number of ticks needed to complete the loop and compare the actual log. 74 Promise.resolve(0) 75 .then(() => actual.push("tick 1")) 76 .then(() => actual.push("tick 2")) 77 .then(() => { 78 assert.compareArray(actual, expected, "Ticks and constructor lookups"); 79 }).then($DONE, $DONE); 80 81 // Redefine `Promise.constructor` in order to intercept "constructor" lookups from PromiseResolve. 82 // (Perform last so that the lookups from SpeciesConstructor in `then` aren't logged.) 83 Object.defineProperty(Promise.prototype, "constructor", { 84 get() { 85 actual.push("constructor"); 86 return Promise; 87 }, 88 configurable: true, 89 }); 90 91 // Start the asynchronous function. 92 f();