semantics.js (3620B)
1 // |reftest| skip-if(!xulRuntime.shell) -- needs drainJobQueue 2 var BUGNUMBER = 1185106; 3 var summary = "async functions semantics"; 4 5 print(BUGNUMBER + ": " + summary); 6 7 async function empty() { 8 } 9 assertEventuallyEq(empty(), undefined); 10 11 async function simpleReturn() { 12 return 1; 13 } 14 assertEventuallyEq(simpleReturn(), 1); 15 16 async function simpleAwait() { 17 var result = await 2; 18 return result; 19 } 20 assertEventuallyEq(simpleAwait(), 2); 21 22 async function simpleAwaitAsync() { 23 var result = await simpleReturn(); 24 return 2 + result; 25 } 26 assertEventuallyEq(simpleAwaitAsync(), 3); 27 28 async function returnOtherAsync() { 29 return 1 + await simpleAwaitAsync(); 30 } 31 assertEventuallyEq(returnOtherAsync(), 4); 32 33 async function simpleThrower() { 34 throw new Error(); 35 } 36 assertEventuallyThrows(simpleThrower(), Error); 37 38 async function delegatedThrower() { 39 var val = await simpleThrower(); 40 return val; 41 } 42 43 async function tryCatch() { 44 try { 45 await delegatedThrower(); 46 return 'FAILED'; 47 } catch (_) { 48 return 5; 49 } 50 } 51 assertEventuallyEq(tryCatch(), 5); 52 53 async function tryCatchThrow() { 54 try { 55 await delegatedThrower(); 56 return 'FAILED'; 57 } catch (_) { 58 return delegatedThrower(); 59 } 60 } 61 assertEventuallyThrows(tryCatchThrow(), Error); 62 63 async function wellFinally() { 64 try { 65 await delegatedThrower(); 66 } catch (_) { 67 return 'FAILED'; 68 } finally { 69 return 6; 70 } 71 } 72 assertEventuallyEq(wellFinally(), 6); 73 74 async function finallyMayFail() { 75 try { 76 await delegatedThrower(); 77 } catch (_) { 78 return 5; 79 } finally { 80 return delegatedThrower(); 81 } 82 } 83 assertEventuallyThrows(finallyMayFail(), Error); 84 85 async function embedded() { 86 async function inner() { 87 return 7; 88 } 89 return await inner(); 90 } 91 assertEventuallyEq(embedded(), 7); 92 93 // recursion, it works! 94 async function fib(n) { 95 return (n == 0 || n == 1) ? n : await fib(n - 1) + await fib(n - 2); 96 } 97 assertEventuallyEq(fib(6), 8); 98 99 // mutual recursion 100 async function isOdd(n) { 101 async function isEven(n) { 102 return n === 0 || await isOdd(n - 1); 103 } 104 return n !== 0 && await isEven(n - 1); 105 } 106 assertEventuallyEq(isOdd(12).then(v => v ? "oops" : 12), 12); 107 108 // recursion, take three! 109 var hardcoreFib = async function fib2(n) { 110 return (n == 0 || n == 1) ? n : await fib2(n - 1) + await fib2(n - 2); 111 } 112 assertEventuallyEq(hardcoreFib(7), 13); 113 114 var asyncExpr = async function() { 115 return 10; 116 } 117 assertEventuallyEq(asyncExpr(), 10); 118 119 var namedAsyncExpr = async function simple() { 120 return 11; 121 } 122 assertEventuallyEq(namedAsyncExpr(), 11); 123 124 async function executionOrder() { 125 var value = 0; 126 async function first() { 127 return (value = value === 0 ? 1 : value); 128 } 129 async function second() { 130 return (value = value === 0 ? 2 : value); 131 } 132 async function third() { 133 return (value = value === 0 ? 3 : value); 134 } 135 return await first() + await second() + await third() + 6; 136 } 137 assertEventuallyEq(executionOrder(), 9); 138 139 async function miscellaneous() { 140 if (arguments.length === 3 && 141 arguments.callee.name === "miscellaneous") 142 return 14; 143 } 144 assertEventuallyEq(miscellaneous(1, 2, 3), 14); 145 146 function thrower() { 147 throw 15; 148 } 149 150 async function defaultArgs(arg = thrower()) { 151 } 152 assertEventuallyEq(defaultArgs().catch(e => e), 15); 153 154 let arrowAwaitExpr = async () => await 2; 155 assertEventuallyEq(arrowAwaitExpr(), 2); 156 157 let arrowAwaitBlock = async () => { return await 2; }; 158 assertEventuallyEq(arrowAwaitBlock(), 2); 159 160 // Async functions are not constructible 161 assertThrowsInstanceOf(() => { 162 async function Person() { 163 164 } 165 new Person(); 166 }, TypeError); 167 168 if (typeof reportCompare === "function") 169 reportCompare(true, true);