| OLD | NEW | 
 | (Empty) | 
|    1 // Copyright 2016 the V8 project authors. All rights reserved. |  | 
|    2 // Use of this source code is governed by a BSD-style license that can be |  | 
|    3 // found in the LICENSE file. |  | 
|    4  |  | 
|    5 // Flags: --harmony-async-await --allow-natives-syntax |  | 
|    6  |  | 
|    7 // Do not install `AsyncFunction` constructor on global object |  | 
|    8  |  | 
|    9 function assertThrowsAsync(run, errorType, message) { |  | 
|   10   var actual; |  | 
|   11   var hadValue = false; |  | 
|   12   var hadError = false; |  | 
|   13   var promise = run(); |  | 
|   14  |  | 
|   15   if (typeof promise !== "object" || typeof promise.then !== "function") { |  | 
|   16     throw new MjsUnitAssertionError( |  | 
|   17         "Expected " + run.toString() + |  | 
|   18         " to return a Promise, but it returned " + PrettyPrint(promise)); |  | 
|   19   } |  | 
|   20  |  | 
|   21   promise.then(function(value) { hadValue = true; actual = value; }, |  | 
|   22                function(error) { hadError = true; actual = error; }); |  | 
|   23  |  | 
|   24   assertFalse(hadValue || hadError); |  | 
|   25  |  | 
|   26   %RunMicrotasks(); |  | 
|   27  |  | 
|   28   if (!hadError) { |  | 
|   29     throw new MjsUnitAssertionError( |  | 
|   30         "Expected " + run + "() to throw " + errorType.name + |  | 
|   31         ", but did not throw."); |  | 
|   32   } |  | 
|   33   if (!(actual instanceof errorType)) |  | 
|   34     throw new MjsUnitAssertionError( |  | 
|   35         "Expected " + run + "() to throw " + errorType.name + |  | 
|   36         ", but threw '" + actual + "'"); |  | 
|   37   if (message !== void 0 && actual.message !== message) |  | 
|   38     throw new MjsUnitAssertionError( |  | 
|   39         "Expected " + run + "() to throw '" + message + "', but threw '" + |  | 
|   40         actual.message + "'"); |  | 
|   41 }; |  | 
|   42  |  | 
|   43 function assertEqualsAsync(expected, run, msg) { |  | 
|   44   var actual; |  | 
|   45   var hadValue = false; |  | 
|   46   var hadError = false; |  | 
|   47   var promise = run(); |  | 
|   48  |  | 
|   49   if (typeof promise !== "object" || typeof promise.then !== "function") { |  | 
|   50     throw new MjsUnitAssertionError( |  | 
|   51         "Expected " + run.toString() + |  | 
|   52         " to return a Promise, but it returned " + PrettyPrint(promise)); |  | 
|   53   } |  | 
|   54  |  | 
|   55   promise.then(function(value) { hadValue = true; actual = value; }, |  | 
|   56                function(error) { hadError = true; actual = error; }); |  | 
|   57  |  | 
|   58   assertFalse(hadValue || hadError); |  | 
|   59  |  | 
|   60   %RunMicrotasks(); |  | 
|   61  |  | 
|   62   if (hadError) throw actual; |  | 
|   63  |  | 
|   64   assertTrue( |  | 
|   65       hadValue, "Expected '" + run.toString() + "' to produce a value"); |  | 
|   66  |  | 
|   67   assertEquals(expected, actual, msg); |  | 
|   68 }; |  | 
|   69  |  | 
|   70 assertEquals(undefined, this.AsyncFunction); |  | 
|   71 let AsyncFunction = (async function() {}).constructor; |  | 
|   72  |  | 
|   73 // The AsyncFunction Constructor is the %AsyncFunction% intrinsic object and |  | 
|   74 // is a subclass of Function. |  | 
|   75 // (https://tc39.github.io/ecmascript-asyncawait/#async-function-constructor) |  | 
|   76 assertEquals(Object.getPrototypeOf(AsyncFunction), Function); |  | 
|   77 assertEquals(Object.getPrototypeOf(AsyncFunction.prototype), |  | 
|   78              Function.prototype); |  | 
|   79 assertTrue(async function() {} instanceof Function); |  | 
|   80  |  | 
|   81  |  | 
|   82 // Let functionPrototype be the intrinsic object %AsyncFunctionPrototype%. |  | 
|   83 async function asyncFunctionForProto() {} |  | 
|   84 assertEquals(AsyncFunction.prototype, |  | 
|   85              Object.getPrototypeOf(asyncFunctionForProto)); |  | 
|   86 assertEquals(AsyncFunction.prototype, |  | 
|   87              Object.getPrototypeOf(async function() {})); |  | 
|   88 assertEquals(AsyncFunction.prototype, Object.getPrototypeOf(async () => {})); |  | 
|   89 assertEquals(AsyncFunction.prototype, |  | 
|   90              Object.getPrototypeOf({ async method() {} }.method)); |  | 
|   91 assertEquals(AsyncFunction.prototype, Object.getPrototypeOf(AsyncFunction())); |  | 
|   92 assertEquals(AsyncFunction.prototype, |  | 
|   93              Object.getPrototypeOf(new AsyncFunction())); |  | 
|   94  |  | 
|   95 // AsyncFunctionCreate does not produce an object with a Prototype |  | 
|   96 assertEquals(undefined, asyncFunctionForProto.prototype); |  | 
|   97 assertEquals(false, asyncFunctionForProto.hasOwnProperty("prototype")); |  | 
|   98 assertEquals(undefined, (async function() {}).prototype); |  | 
|   99 assertEquals(false, (async function() {}).hasOwnProperty("prototype")); |  | 
|  100 assertEquals(undefined, (async() => {}).prototype); |  | 
|  101 assertEquals(false, (async() => {}).hasOwnProperty("prototype")); |  | 
|  102 assertEquals(undefined, ({ async method() {} }).method.prototype); |  | 
|  103 assertEquals(false, ({ async method() {} }).method.hasOwnProperty("prototype")); |  | 
|  104 assertEquals(undefined, AsyncFunction().prototype); |  | 
|  105 assertEquals(false, AsyncFunction().hasOwnProperty("prototype")); |  | 
|  106 assertEquals(undefined, (new AsyncFunction()).prototype); |  | 
|  107 assertEquals(false, (new AsyncFunction()).hasOwnProperty("prototype")); |  | 
|  108  |  | 
|  109 assertEquals(1, async function(a) { await 1; }.length); |  | 
|  110 assertEquals(2, async function(a, b) { await 1; }.length); |  | 
|  111 assertEquals(1, async function(a, b = 2) { await 1; }.length); |  | 
|  112 assertEquals(2, async function(a, b, ...c) { await 1; }.length); |  | 
|  113  |  | 
|  114 assertEquals(1, (async(a) => await 1).length); |  | 
|  115 assertEquals(2, (async(a, b) => await 1).length); |  | 
|  116 assertEquals(1, (async(a, b = 2) => await 1).length); |  | 
|  117 assertEquals(2, (async(a, b, ...c) => await 1).length); |  | 
|  118  |  | 
|  119 assertEquals(1, ({ async f(a) { await 1; } }).f.length); |  | 
|  120 assertEquals(2, ({ async f(a, b) { await 1; } }).f.length); |  | 
|  121 assertEquals(1, ({ async f(a, b = 2) { await 1; } }).f.length); |  | 
|  122 assertEquals(2, ({ async f(a, b, ...c) { await 1; } }).f.length); |  | 
|  123  |  | 
|  124 assertEquals(1, AsyncFunction("a", "await 1").length); |  | 
|  125 assertEquals(2, AsyncFunction("a", "b", "await 1").length); |  | 
|  126 assertEquals(1, AsyncFunction("a", "b = 2", "await 1").length); |  | 
|  127 assertEquals(2, AsyncFunction("a", "b", "...c", "await 1").length); |  | 
|  128  |  | 
|  129 assertEquals(1, (new AsyncFunction("a", "await 1")).length); |  | 
|  130 assertEquals(2, (new AsyncFunction("a", "b", "await 1")).length); |  | 
|  131 assertEquals(1, (new AsyncFunction("a", "b = 2", "await 1")).length); |  | 
|  132 assertEquals(2, (new AsyncFunction("a", "b", "...c", "await 1")).length); |  | 
|  133  |  | 
|  134 // AsyncFunction.prototype[ @@toStringTag ] |  | 
|  135 var descriptor = |  | 
|  136     Object.getOwnPropertyDescriptor(AsyncFunction.prototype, |  | 
|  137                                     Symbol.toStringTag); |  | 
|  138 assertEquals("AsyncFunction", descriptor.value); |  | 
|  139 assertEquals(false, descriptor.enumerable); |  | 
|  140 assertEquals(false, descriptor.writable); |  | 
|  141 assertEquals(true, descriptor.configurable); |  | 
|  142  |  | 
|  143 assertEquals(1, AsyncFunction.length); |  | 
|  144  |  | 
|  145 // Let F be ! FunctionAllocate(functionPrototype, Strict, "non-constructor") |  | 
|  146 async function asyncNonConstructorDecl() {} |  | 
|  147 assertThrows(() => new asyncNonConstructorDecl(), TypeError); |  | 
|  148 assertThrows(() => asyncNonConstructorDecl.caller, TypeError); |  | 
|  149 assertThrows(() => asyncNonConstructorDecl.arguments, TypeError); |  | 
|  150  |  | 
|  151 assertThrows(() => new (async function() {}), TypeError); |  | 
|  152 assertThrows(() => (async function() {}).caller, TypeError); |  | 
|  153 assertThrows(() => (async function() {}).arguments, TypeError); |  | 
|  154  |  | 
|  155 assertThrows( |  | 
|  156     () => new ({ async nonConstructor() {} }).nonConstructor(), TypeError); |  | 
|  157 assertThrows( |  | 
|  158     () => ({ async nonConstructor() {} }).nonConstructor.caller, TypeError); |  | 
|  159 assertThrows( |  | 
|  160     () => ({ async nonConstructor() {} }).nonConstructor.arguments, TypeError); |  | 
|  161  |  | 
|  162 assertThrows(() => new (() => "not a constructor!"), TypeError); |  | 
|  163 assertThrows(() => (() => 1).caller, TypeError); |  | 
|  164 assertThrows(() => (() => 1).arguments, TypeError); |  | 
|  165  |  | 
|  166 assertThrows(() => new (AsyncFunction()), TypeError); |  | 
|  167 assertThrows(() => AsyncFunction().caller, TypeError); |  | 
|  168 assertThrows(() => AsyncFunction().arguments, TypeError); |  | 
|  169  |  | 
|  170 assertThrows(() => new (new AsyncFunction()), TypeError); |  | 
|  171 assertThrows(() => (new AsyncFunction()).caller, TypeError); |  | 
|  172 assertThrows(() => (new AsyncFunction()).arguments, TypeError); |  | 
|  173  |  | 
|  174 // Normal completion |  | 
|  175 async function asyncDecl() { return "test"; } |  | 
|  176 assertEqualsAsync("test", asyncDecl); |  | 
|  177 assertEqualsAsync("test2", async function() { return "test2"; }); |  | 
|  178 assertEqualsAsync("test3", async () => "test3"); |  | 
|  179 assertEqualsAsync("test4", () => ({ async f() { return "test4"; } }).f()); |  | 
|  180 assertEqualsAsync("test5", () => AsyncFunction("no", "return 'test' + no;")(5)); |  | 
|  181 assertEqualsAsync("test6", |  | 
|  182                   () => (new AsyncFunction("no", "return 'test' + no;"))(6)); |  | 
|  183  |  | 
|  184 class MyError extends Error {}; |  | 
|  185  |  | 
|  186 // Throw completion |  | 
|  187 async function asyncDeclThrower(e) { throw new MyError(e); } |  | 
|  188 assertThrowsAsync(() => asyncDeclThrower("boom!"), MyError, "boom!"); |  | 
|  189 assertThrowsAsync( |  | 
|  190   () => (async function(e) { throw new MyError(e); })("boom!!!"), |  | 
|  191   MyError, "boom!!!"); |  | 
|  192 assertThrowsAsync( |  | 
|  193   () => (async e => { throw new MyError(e) })("boom!!"), MyError, "boom!!"); |  | 
|  194 assertThrowsAsync( |  | 
|  195   () => ({ async thrower(e) { throw new MyError(e); } }).thrower("boom!1!"), |  | 
|  196   MyError, "boom!1!"); |  | 
|  197 assertThrowsAsync( |  | 
|  198   () => AsyncFunction("msg", "throw new MyError(msg)")("boom!2!!"), |  | 
|  199   MyError, "boom!2!!"); |  | 
|  200 assertThrowsAsync( |  | 
|  201   () => (new AsyncFunction("msg", "throw new MyError(msg)"))("boom!2!!!"), |  | 
|  202   MyError, "boom!2!!!"); |  | 
|  203  |  | 
|  204 function resolveLater(value) { return Promise.resolve(value); } |  | 
|  205 function rejectLater(error) { return Promise.reject(error); } |  | 
|  206  |  | 
|  207 // Resume after Normal completion |  | 
|  208 var log = []; |  | 
|  209 async function resumeAfterNormal(value) { |  | 
|  210   log.push("start:" + value); |  | 
|  211   value = await resolveLater(value + 1); |  | 
|  212   log.push("resume:" + value); |  | 
|  213   value = await resolveLater(value + 1); |  | 
|  214   log.push("resume:" + value); |  | 
|  215   return value + 1; |  | 
|  216 } |  | 
|  217  |  | 
|  218 assertEqualsAsync(4, () => resumeAfterNormal(1)); |  | 
|  219 assertEquals("start:1 resume:2 resume:3", log.join(" ")); |  | 
|  220  |  | 
|  221 var O = { |  | 
|  222   async resumeAfterNormal(value) { |  | 
|  223     log.push("start:" + value); |  | 
|  224     value = await resolveLater(value + 1); |  | 
|  225     log.push("resume:" + value); |  | 
|  226     value = await resolveLater(value + 1); |  | 
|  227     log.push("resume:" + value); |  | 
|  228     return value + 1; |  | 
|  229   } |  | 
|  230 }; |  | 
|  231 log = []; |  | 
|  232 assertEqualsAsync(5, () => O.resumeAfterNormal(2)); |  | 
|  233 assertEquals("start:2 resume:3 resume:4", log.join(" ")); |  | 
|  234  |  | 
|  235 var resumeAfterNormalArrow = async (value) => { |  | 
|  236   log.push("start:" + value); |  | 
|  237   value = await resolveLater(value + 1); |  | 
|  238   log.push("resume:" + value); |  | 
|  239   value = await resolveLater(value + 1); |  | 
|  240   log.push("resume:" + value); |  | 
|  241   return value + 1; |  | 
|  242 }; |  | 
|  243 log = []; |  | 
|  244 assertEqualsAsync(6, () => resumeAfterNormalArrow(3)); |  | 
|  245 assertEquals("start:3 resume:4 resume:5", log.join(" ")); |  | 
|  246  |  | 
|  247 var resumeAfterNormalEval = AsyncFunction("value", ` |  | 
|  248     log.push("start:" + value); |  | 
|  249     value = await resolveLater(value + 1); |  | 
|  250     log.push("resume:" + value); |  | 
|  251     value = await resolveLater(value + 1); |  | 
|  252     log.push("resume:" + value); |  | 
|  253     return value + 1;`); |  | 
|  254 log = []; |  | 
|  255 assertEqualsAsync(7, () => resumeAfterNormalEval(4)); |  | 
|  256 assertEquals("start:4 resume:5 resume:6", log.join(" ")); |  | 
|  257  |  | 
|  258 var resumeAfterNormalNewEval = new AsyncFunction("value", ` |  | 
|  259     log.push("start:" + value); |  | 
|  260     value = await resolveLater(value + 1); |  | 
|  261     log.push("resume:" + value); |  | 
|  262     value = await resolveLater(value + 1); |  | 
|  263     log.push("resume:" + value); |  | 
|  264     return value + 1;`); |  | 
|  265 log = []; |  | 
|  266 assertEqualsAsync(8, () => resumeAfterNormalNewEval(5)); |  | 
|  267 assertEquals("start:5 resume:6 resume:7", log.join(" ")); |  | 
|  268  |  | 
|  269 // Resume after Throw completion |  | 
|  270 async function resumeAfterThrow(value) { |  | 
|  271   log.push("start:" + value); |  | 
|  272   try { |  | 
|  273     value = await rejectLater("throw1"); |  | 
|  274   } catch (e) { |  | 
|  275     log.push("resume:" + e); |  | 
|  276   } |  | 
|  277   try { |  | 
|  278     value = await rejectLater("throw2"); |  | 
|  279   } catch (e) { |  | 
|  280     log.push("resume:" + e); |  | 
|  281   } |  | 
|  282   return value + 1; |  | 
|  283 } |  | 
|  284  |  | 
|  285 log = []; |  | 
|  286 assertEqualsAsync(2, () => resumeAfterThrow(1)); |  | 
|  287 assertEquals("start:1 resume:throw1 resume:throw2", log.join(" ")); |  | 
|  288  |  | 
|  289 var O = { |  | 
|  290   async resumeAfterThrow(value) { |  | 
|  291     log.push("start:" + value); |  | 
|  292     try { |  | 
|  293       value = await rejectLater("throw1"); |  | 
|  294     } catch (e) { |  | 
|  295       log.push("resume:" + e); |  | 
|  296     } |  | 
|  297     try { |  | 
|  298       value = await rejectLater("throw2"); |  | 
|  299     } catch (e) { |  | 
|  300       log.push("resume:" + e); |  | 
|  301     } |  | 
|  302     return value + 1; |  | 
|  303   } |  | 
|  304 } |  | 
|  305 log = []; |  | 
|  306 assertEqualsAsync(3, () => O.resumeAfterThrow(2)); |  | 
|  307 assertEquals("start:2 resume:throw1 resume:throw2", log.join(" ")); |  | 
|  308  |  | 
|  309 var resumeAfterThrowArrow = async (value) => { |  | 
|  310   log.push("start:" + value); |  | 
|  311   try { |  | 
|  312     value = await rejectLater("throw1"); |  | 
|  313   } catch (e) { |  | 
|  314     log.push("resume:" + e); |  | 
|  315   } |  | 
|  316   try { |  | 
|  317     value = await rejectLater("throw2"); |  | 
|  318   } catch (e) { |  | 
|  319     log.push("resume:" + e); |  | 
|  320   } |  | 
|  321  return value + 1; |  | 
|  322 }; |  | 
|  323  |  | 
|  324 log = []; |  | 
|  325  |  | 
|  326 assertEqualsAsync(4, () => resumeAfterThrowArrow(3)); |  | 
|  327 assertEquals("start:3 resume:throw1 resume:throw2", log.join(" ")); |  | 
|  328  |  | 
|  329 var resumeAfterThrowEval = AsyncFunction("value", ` |  | 
|  330     log.push("start:" + value); |  | 
|  331     try { |  | 
|  332       value = await rejectLater("throw1"); |  | 
|  333     } catch (e) { |  | 
|  334       log.push("resume:" + e); |  | 
|  335     } |  | 
|  336     try { |  | 
|  337       value = await rejectLater("throw2"); |  | 
|  338     } catch (e) { |  | 
|  339       log.push("resume:" + e); |  | 
|  340     } |  | 
|  341     return value + 1;`); |  | 
|  342 log = []; |  | 
|  343 assertEqualsAsync(5, () => resumeAfterThrowEval(4)); |  | 
|  344 assertEquals("start:4 resume:throw1 resume:throw2", log.join(" ")); |  | 
|  345  |  | 
|  346 var resumeAfterThrowNewEval = new AsyncFunction("value", ` |  | 
|  347     log.push("start:" + value); |  | 
|  348     try { |  | 
|  349       value = await rejectLater("throw1"); |  | 
|  350     } catch (e) { |  | 
|  351       log.push("resume:" + e); |  | 
|  352     } |  | 
|  353     try { |  | 
|  354       value = await rejectLater("throw2"); |  | 
|  355     } catch (e) { |  | 
|  356       log.push("resume:" + e); |  | 
|  357     } |  | 
|  358     return value + 1;`); |  | 
|  359 log = []; |  | 
|  360 assertEqualsAsync(6, () => resumeAfterThrowNewEval(5)); |  | 
|  361 assertEquals("start:5 resume:throw1 resume:throw2", log.join(" ")); |  | 
|  362  |  | 
|  363 async function foo() {} |  | 
|  364 assertEquals("async function foo() {}", foo.toString()); |  | 
|  365 assertEquals("async function () {}", async function () {}.toString()); |  | 
|  366 assertEquals("async x => x", (async x => x).toString()); |  | 
|  367 assertEquals("async x => { return x }", (async x => { return x }).toString()); |  | 
|  368 class AsyncMethod { async foo() { } } |  | 
|  369 assertEquals("async foo() { }", |  | 
|  370              Function.prototype.toString.call(AsyncMethod.prototype.foo)); |  | 
|  371 assertEquals("async foo() { }", |  | 
|  372              Function.prototype.toString.call({async foo() { }}.foo)); |  | 
|  373  |  | 
|  374 // Async functions are not constructible |  | 
|  375 assertThrows(() => class extends (async function() {}) {}, TypeError); |  | 
|  376  |  | 
|  377 // Regress v8:5148 |  | 
|  378 assertEqualsAsync("1", () => (async({ a = NaN }) => a)({ a: "1" })); |  | 
|  379 assertEqualsAsync( |  | 
|  380     "10", () => (async(foo, { a = NaN }) => foo + a)("1", { a: "0" })); |  | 
|  381 assertEqualsAsync("2", () => (async({ a = "2" }) => a)({ a: undefined })); |  | 
|  382 assertEqualsAsync( |  | 
|  383     "20", () => (async(foo, { a = "0" }) => foo + a)("2", { a: undefined })); |  | 
|  384 assertThrows(() => eval("async({ foo = 1 })"), SyntaxError); |  | 
|  385 assertThrows(() => eval("async(a, { foo = 1 })"), SyntaxError); |  | 
|  386  |  | 
|  387 // https://bugs.chromium.org/p/chromium/issues/detail?id=638019 |  | 
|  388 async function gaga() { |  | 
|  389   let i = 1; |  | 
|  390   while (i-- > 0) { await 42 } |  | 
|  391 } |  | 
|  392 assertDoesNotThrow(gaga); |  | 
| OLD | NEW |