diff options
Diffstat (limited to 'deps/v8/test/mjsunit/es8/async-await-basic.js')
-rw-r--r-- | deps/v8/test/mjsunit/es8/async-await-basic.js | 392 |
1 files changed, 392 insertions, 0 deletions
diff --git a/deps/v8/test/mjsunit/es8/async-await-basic.js b/deps/v8/test/mjsunit/es8/async-await-basic.js new file mode 100644 index 0000000000..41da67f7cd --- /dev/null +++ b/deps/v8/test/mjsunit/es8/async-await-basic.js @@ -0,0 +1,392 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax + +// Do not install `AsyncFunction` constructor on global object + +function assertThrowsAsync(run, errorType, message) { + var actual; + var hadValue = false; + var hadError = false; + var promise = run(); + + if (typeof promise !== "object" || typeof promise.then !== "function") { + throw new MjsUnitAssertionError( + "Expected " + run.toString() + + " to return a Promise, but it returned " + PrettyPrint(promise)); + } + + promise.then(function(value) { hadValue = true; actual = value; }, + function(error) { hadError = true; actual = error; }); + + assertFalse(hadValue || hadError); + + %RunMicrotasks(); + + if (!hadError) { + throw new MjsUnitAssertionError( + "Expected " + run + "() to throw " + errorType.name + + ", but did not throw."); + } + if (!(actual instanceof errorType)) + throw new MjsUnitAssertionError( + "Expected " + run + "() to throw " + errorType.name + + ", but threw '" + actual + "'"); + if (message !== void 0 && actual.message !== message) + throw new MjsUnitAssertionError( + "Expected " + run + "() to throw '" + message + "', but threw '" + + actual.message + "'"); +}; + +function assertEqualsAsync(expected, run, msg) { + var actual; + var hadValue = false; + var hadError = false; + var promise = run(); + + if (typeof promise !== "object" || typeof promise.then !== "function") { + throw new MjsUnitAssertionError( + "Expected " + run.toString() + + " to return a Promise, but it returned " + PrettyPrint(promise)); + } + + promise.then(function(value) { hadValue = true; actual = value; }, + function(error) { hadError = true; actual = error; }); + + assertFalse(hadValue || hadError); + + %RunMicrotasks(); + + if (hadError) throw actual; + + assertTrue( + hadValue, "Expected '" + run.toString() + "' to produce a value"); + + assertEquals(expected, actual, msg); +}; + +assertEquals(undefined, this.AsyncFunction); +let AsyncFunction = (async function() {}).constructor; + +// The AsyncFunction Constructor is the %AsyncFunction% intrinsic object and +// is a subclass of Function. +// (https://tc39.github.io/ecmascript-asyncawait/#async-function-constructor) +assertEquals(Object.getPrototypeOf(AsyncFunction), Function); +assertEquals(Object.getPrototypeOf(AsyncFunction.prototype), + Function.prototype); +assertTrue(async function() {} instanceof Function); + + +// Let functionPrototype be the intrinsic object %AsyncFunctionPrototype%. +async function asyncFunctionForProto() {} +assertEquals(AsyncFunction.prototype, + Object.getPrototypeOf(asyncFunctionForProto)); +assertEquals(AsyncFunction.prototype, + Object.getPrototypeOf(async function() {})); +assertEquals(AsyncFunction.prototype, Object.getPrototypeOf(async () => {})); +assertEquals(AsyncFunction.prototype, + Object.getPrototypeOf({ async method() {} }.method)); +assertEquals(AsyncFunction.prototype, Object.getPrototypeOf(AsyncFunction())); +assertEquals(AsyncFunction.prototype, + Object.getPrototypeOf(new AsyncFunction())); + +// AsyncFunctionCreate does not produce an object with a Prototype +assertEquals(undefined, asyncFunctionForProto.prototype); +assertEquals(false, asyncFunctionForProto.hasOwnProperty("prototype")); +assertEquals(undefined, (async function() {}).prototype); +assertEquals(false, (async function() {}).hasOwnProperty("prototype")); +assertEquals(undefined, (async() => {}).prototype); +assertEquals(false, (async() => {}).hasOwnProperty("prototype")); +assertEquals(undefined, ({ async method() {} }).method.prototype); +assertEquals(false, ({ async method() {} }).method.hasOwnProperty("prototype")); +assertEquals(undefined, AsyncFunction().prototype); +assertEquals(false, AsyncFunction().hasOwnProperty("prototype")); +assertEquals(undefined, (new AsyncFunction()).prototype); +assertEquals(false, (new AsyncFunction()).hasOwnProperty("prototype")); + +assertEquals(1, async function(a) { await 1; }.length); +assertEquals(2, async function(a, b) { await 1; }.length); +assertEquals(1, async function(a, b = 2) { await 1; }.length); +assertEquals(2, async function(a, b, ...c) { await 1; }.length); + +assertEquals(1, (async(a) => await 1).length); +assertEquals(2, (async(a, b) => await 1).length); +assertEquals(1, (async(a, b = 2) => await 1).length); +assertEquals(2, (async(a, b, ...c) => await 1).length); + +assertEquals(1, ({ async f(a) { await 1; } }).f.length); +assertEquals(2, ({ async f(a, b) { await 1; } }).f.length); +assertEquals(1, ({ async f(a, b = 2) { await 1; } }).f.length); +assertEquals(2, ({ async f(a, b, ...c) { await 1; } }).f.length); + +assertEquals(1, AsyncFunction("a", "await 1").length); +assertEquals(2, AsyncFunction("a", "b", "await 1").length); +assertEquals(1, AsyncFunction("a", "b = 2", "await 1").length); +assertEquals(2, AsyncFunction("a", "b", "...c", "await 1").length); + +assertEquals(1, (new AsyncFunction("a", "await 1")).length); +assertEquals(2, (new AsyncFunction("a", "b", "await 1")).length); +assertEquals(1, (new AsyncFunction("a", "b = 2", "await 1")).length); +assertEquals(2, (new AsyncFunction("a", "b", "...c", "await 1")).length); + +// AsyncFunction.prototype[ @@toStringTag ] +var descriptor = + Object.getOwnPropertyDescriptor(AsyncFunction.prototype, + Symbol.toStringTag); +assertEquals("AsyncFunction", descriptor.value); +assertEquals(false, descriptor.enumerable); +assertEquals(false, descriptor.writable); +assertEquals(true, descriptor.configurable); + +assertEquals(1, AsyncFunction.length); + +// Let F be ! FunctionAllocate(functionPrototype, Strict, "non-constructor") +async function asyncNonConstructorDecl() {} +assertThrows(() => new asyncNonConstructorDecl(), TypeError); +assertThrows(() => asyncNonConstructorDecl.caller, TypeError); +assertThrows(() => asyncNonConstructorDecl.arguments, TypeError); + +assertThrows(() => new (async function() {}), TypeError); +assertThrows(() => (async function() {}).caller, TypeError); +assertThrows(() => (async function() {}).arguments, TypeError); + +assertThrows( + () => new ({ async nonConstructor() {} }).nonConstructor(), TypeError); +assertThrows( + () => ({ async nonConstructor() {} }).nonConstructor.caller, TypeError); +assertThrows( + () => ({ async nonConstructor() {} }).nonConstructor.arguments, TypeError); + +assertThrows(() => new (() => "not a constructor!"), TypeError); +assertThrows(() => (() => 1).caller, TypeError); +assertThrows(() => (() => 1).arguments, TypeError); + +assertThrows(() => new (AsyncFunction()), TypeError); +assertThrows(() => AsyncFunction().caller, TypeError); +assertThrows(() => AsyncFunction().arguments, TypeError); + +assertThrows(() => new (new AsyncFunction()), TypeError); +assertThrows(() => (new AsyncFunction()).caller, TypeError); +assertThrows(() => (new AsyncFunction()).arguments, TypeError); + +// Normal completion +async function asyncDecl() { return "test"; } +assertEqualsAsync("test", asyncDecl); +assertEqualsAsync("test2", async function() { return "test2"; }); +assertEqualsAsync("test3", async () => "test3"); +assertEqualsAsync("test4", () => ({ async f() { return "test4"; } }).f()); +assertEqualsAsync("test5", () => AsyncFunction("no", "return 'test' + no;")(5)); +assertEqualsAsync("test6", + () => (new AsyncFunction("no", "return 'test' + no;"))(6)); + +class MyError extends Error {}; + +// Throw completion +async function asyncDeclThrower(e) { throw new MyError(e); } +assertThrowsAsync(() => asyncDeclThrower("boom!"), MyError, "boom!"); +assertThrowsAsync( + () => (async function(e) { throw new MyError(e); })("boom!!!"), + MyError, "boom!!!"); +assertThrowsAsync( + () => (async e => { throw new MyError(e) })("boom!!"), MyError, "boom!!"); +assertThrowsAsync( + () => ({ async thrower(e) { throw new MyError(e); } }).thrower("boom!1!"), + MyError, "boom!1!"); +assertThrowsAsync( + () => AsyncFunction("msg", "throw new MyError(msg)")("boom!2!!"), + MyError, "boom!2!!"); +assertThrowsAsync( + () => (new AsyncFunction("msg", "throw new MyError(msg)"))("boom!2!!!"), + MyError, "boom!2!!!"); + +function resolveLater(value) { return Promise.resolve(value); } +function rejectLater(error) { return Promise.reject(error); } + +// Resume after Normal completion +var log = []; +async function resumeAfterNormal(value) { + log.push("start:" + value); + value = await resolveLater(value + 1); + log.push("resume:" + value); + value = await resolveLater(value + 1); + log.push("resume:" + value); + return value + 1; +} + +assertEqualsAsync(4, () => resumeAfterNormal(1)); +assertEquals("start:1 resume:2 resume:3", log.join(" ")); + +var O = { + async resumeAfterNormal(value) { + log.push("start:" + value); + value = await resolveLater(value + 1); + log.push("resume:" + value); + value = await resolveLater(value + 1); + log.push("resume:" + value); + return value + 1; + } +}; +log = []; +assertEqualsAsync(5, () => O.resumeAfterNormal(2)); +assertEquals("start:2 resume:3 resume:4", log.join(" ")); + +var resumeAfterNormalArrow = async (value) => { + log.push("start:" + value); + value = await resolveLater(value + 1); + log.push("resume:" + value); + value = await resolveLater(value + 1); + log.push("resume:" + value); + return value + 1; +}; +log = []; +assertEqualsAsync(6, () => resumeAfterNormalArrow(3)); +assertEquals("start:3 resume:4 resume:5", log.join(" ")); + +var resumeAfterNormalEval = AsyncFunction("value", ` + log.push("start:" + value); + value = await resolveLater(value + 1); + log.push("resume:" + value); + value = await resolveLater(value + 1); + log.push("resume:" + value); + return value + 1;`); +log = []; +assertEqualsAsync(7, () => resumeAfterNormalEval(4)); +assertEquals("start:4 resume:5 resume:6", log.join(" ")); + +var resumeAfterNormalNewEval = new AsyncFunction("value", ` + log.push("start:" + value); + value = await resolveLater(value + 1); + log.push("resume:" + value); + value = await resolveLater(value + 1); + log.push("resume:" + value); + return value + 1;`); +log = []; +assertEqualsAsync(8, () => resumeAfterNormalNewEval(5)); +assertEquals("start:5 resume:6 resume:7", log.join(" ")); + +// Resume after Throw completion +async function resumeAfterThrow(value) { + log.push("start:" + value); + try { + value = await rejectLater("throw1"); + } catch (e) { + log.push("resume:" + e); + } + try { + value = await rejectLater("throw2"); + } catch (e) { + log.push("resume:" + e); + } + return value + 1; +} + +log = []; +assertEqualsAsync(2, () => resumeAfterThrow(1)); +assertEquals("start:1 resume:throw1 resume:throw2", log.join(" ")); + +var O = { + async resumeAfterThrow(value) { + log.push("start:" + value); + try { + value = await rejectLater("throw1"); + } catch (e) { + log.push("resume:" + e); + } + try { + value = await rejectLater("throw2"); + } catch (e) { + log.push("resume:" + e); + } + return value + 1; + } +} +log = []; +assertEqualsAsync(3, () => O.resumeAfterThrow(2)); +assertEquals("start:2 resume:throw1 resume:throw2", log.join(" ")); + +var resumeAfterThrowArrow = async (value) => { + log.push("start:" + value); + try { + value = await rejectLater("throw1"); + } catch (e) { + log.push("resume:" + e); + } + try { + value = await rejectLater("throw2"); + } catch (e) { + log.push("resume:" + e); + } + return value + 1; +}; + +log = []; + +assertEqualsAsync(4, () => resumeAfterThrowArrow(3)); +assertEquals("start:3 resume:throw1 resume:throw2", log.join(" ")); + +var resumeAfterThrowEval = AsyncFunction("value", ` + log.push("start:" + value); + try { + value = await rejectLater("throw1"); + } catch (e) { + log.push("resume:" + e); + } + try { + value = await rejectLater("throw2"); + } catch (e) { + log.push("resume:" + e); + } + return value + 1;`); +log = []; +assertEqualsAsync(5, () => resumeAfterThrowEval(4)); +assertEquals("start:4 resume:throw1 resume:throw2", log.join(" ")); + +var resumeAfterThrowNewEval = new AsyncFunction("value", ` + log.push("start:" + value); + try { + value = await rejectLater("throw1"); + } catch (e) { + log.push("resume:" + e); + } + try { + value = await rejectLater("throw2"); + } catch (e) { + log.push("resume:" + e); + } + return value + 1;`); +log = []; +assertEqualsAsync(6, () => resumeAfterThrowNewEval(5)); +assertEquals("start:5 resume:throw1 resume:throw2", log.join(" ")); + +async function foo() {} +assertEquals("async function foo() {}", foo.toString()); +assertEquals("async function () {}", async function () {}.toString()); +assertEquals("async x => x", (async x => x).toString()); +assertEquals("async x => { return x }", (async x => { return x }).toString()); +class AsyncMethod { async foo() { } } +assertEquals("async foo() { }", + Function.prototype.toString.call(AsyncMethod.prototype.foo)); +assertEquals("async foo() { }", + Function.prototype.toString.call({async foo() { }}.foo)); + +// Async functions are not constructible +assertThrows(() => class extends (async function() {}) {}, TypeError); + +// Regress v8:5148 +assertEqualsAsync("1", () => (async({ a = NaN }) => a)({ a: "1" })); +assertEqualsAsync( + "10", () => (async(foo, { a = NaN }) => foo + a)("1", { a: "0" })); +assertEqualsAsync("2", () => (async({ a = "2" }) => a)({ a: undefined })); +assertEqualsAsync( + "20", () => (async(foo, { a = "0" }) => foo + a)("2", { a: undefined })); +assertThrows(() => eval("async({ foo = 1 })"), SyntaxError); +assertThrows(() => eval("async(a, { foo = 1 })"), SyntaxError); + +// https://bugs.chromium.org/p/chromium/issues/detail?id=638019 +async function gaga() { + let i = 1; + while (i-- > 0) { await 42 } +} +assertDoesNotThrow(gaga); |