// |reftest| skip-if(!xulRuntime.shell) -- needs drainJobQueue var BUGNUMBER = 1185106; var summary = "async functions semantics"; print(BUGNUMBER + ": " + summary); async function empty() { } assertEventuallyEq(empty(), undefined); async function simpleReturn() { return 1; } assertEventuallyEq(simpleReturn(), 1); async function simpleAwait() { var result = await 2; return result; } assertEventuallyEq(simpleAwait(), 2); async function simpleAwaitAsync() { var result = await simpleReturn(); return 2 + result; } assertEventuallyEq(simpleAwaitAsync(), 3); async function returnOtherAsync() { return 1 + await simpleAwaitAsync(); } assertEventuallyEq(returnOtherAsync(), 4); async function simpleThrower() { throw new Error(); } assertEventuallyThrows(simpleThrower(), Error); async function delegatedThrower() { var val = await simpleThrower(); return val; } async function tryCatch() { try { await delegatedThrower(); return 'FAILED'; } catch (_) { return 5; } } assertEventuallyEq(tryCatch(), 5); async function tryCatchThrow() { try { await delegatedThrower(); return 'FAILED'; } catch (_) { return delegatedThrower(); } } assertEventuallyThrows(tryCatchThrow(), Error); async function wellFinally() { try { await delegatedThrower(); } catch (_) { return 'FAILED'; } finally { return 6; } } assertEventuallyEq(wellFinally(), 6); async function finallyMayFail() { try { await delegatedThrower(); } catch (_) { return 5; } finally { return delegatedThrower(); } } assertEventuallyThrows(finallyMayFail(), Error); async function embedded() { async function inner() { return 7; } return await inner(); } assertEventuallyEq(embedded(), 7); // recursion, it works! async function fib(n) { return (n == 0 || n == 1) ? n : await fib(n - 1) + await fib(n - 2); } assertEventuallyEq(fib(6), 8); // mutual recursion async function isOdd(n) { async function isEven(n) { return n === 0 || await isOdd(n - 1); } return n !== 0 && await isEven(n - 1); } assertEventuallyEq(isOdd(12).then(v => v ? "oops" : 12), 12); // recursion, take three! var hardcoreFib = async function fib2(n) { return (n == 0 || n == 1) ? n : await fib2(n - 1) + await fib2(n - 2); } assertEventuallyEq(hardcoreFib(7), 13); var asyncExpr = async function() { return 10; } assertEventuallyEq(asyncExpr(), 10); var namedAsyncExpr = async function simple() { return 11; } assertEventuallyEq(namedAsyncExpr(), 11); async function executionOrder() { var value = 0; async function first() { return (value = value === 0 ? 1 : value); } async function second() { return (value = value === 0 ? 2 : value); } async function third() { return (value = value === 0 ? 3 : value); } return await first() + await second() + await third() + 6; } assertEventuallyEq(executionOrder(), 9); async function miscellaneous() { if (arguments.length === 3 && arguments.callee.name === "miscellaneous") return 14; } assertEventuallyEq(miscellaneous(1, 2, 3), 14); function thrower() { throw 15; } async function defaultArgs(arg = thrower()) { } assertEventuallyEq(defaultArgs().catch(e => e), 15); let arrowAwaitExpr = async () => await 2; assertEventuallyEq(arrowAwaitExpr(), 2); let arrowAwaitBlock = async () => { return await 2; }; assertEventuallyEq(arrowAwaitBlock(), 2); // Async functions are not constructible assertThrowsInstanceOf(() => { async function Person() { } new Person(); }, TypeError); if (typeof reportCompare === "function") reportCompare(true, true);