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 // Let functionPrototype be the intrinsic object %AsyncFunctionPrototype%. |
| 74 async function asyncFunctionForProto() {} |
| 75 assertEquals(AsyncFunction.prototype, |
| 76 Object.getPrototypeOf(asyncFunctionForProto)); |
| 77 assertEquals(AsyncFunction.prototype, |
| 78 Object.getPrototypeOf(async function() {})); |
| 79 assertEquals(AsyncFunction.prototype, Object.getPrototypeOf(async () => {})); |
| 80 assertEquals(AsyncFunction.prototype, |
| 81 Object.getPrototypeOf({ async method() {} }.method)); |
| 82 assertEquals(AsyncFunction.prototype, Object.getPrototypeOf(AsyncFunction())); |
| 83 assertEquals(AsyncFunction.prototype, |
| 84 Object.getPrototypeOf(new AsyncFunction())); |
| 85 |
| 86 // AsyncFunctionCreate does not produce an object with a Prototype |
| 87 assertEquals(undefined, asyncFunctionForProto.prototype); |
| 88 assertEquals(false, asyncFunctionForProto.hasOwnProperty("prototype")); |
| 89 assertEquals(undefined, (async function() {}).prototype); |
| 90 assertEquals(false, (async function() {}).hasOwnProperty("prototype")); |
| 91 assertEquals(undefined, (async() => {}).prototype); |
| 92 assertEquals(false, (async() => {}).hasOwnProperty("prototype")); |
| 93 assertEquals(undefined, ({ async method() {} }).method.prototype); |
| 94 assertEquals(false, ({ async method() {} }).method.hasOwnProperty("prototype")); |
| 95 assertEquals(undefined, AsyncFunction().prototype); |
| 96 assertEquals(false, AsyncFunction().hasOwnProperty("prototype")); |
| 97 assertEquals(undefined, (new AsyncFunction()).prototype); |
| 98 assertEquals(false, (new AsyncFunction()).hasOwnProperty("prototype")); |
| 99 |
| 100 assertEquals(1, async function(a) { await 1; }.length); |
| 101 assertEquals(2, async function(a, b) { await 1; }.length); |
| 102 assertEquals(1, async function(a, b = 2) { await 1; }.length); |
| 103 assertEquals(2, async function(a, b, ...c) { await 1; }.length); |
| 104 |
| 105 assertEquals(1, (async(a) => await 1).length); |
| 106 assertEquals(2, (async(a, b) => await 1).length); |
| 107 assertEquals(1, (async(a, b = 2) => await 1).length); |
| 108 assertEquals(2, (async(a, b, ...c) => await 1).length); |
| 109 |
| 110 assertEquals(1, ({ async f(a) { await 1; } }).f.length); |
| 111 assertEquals(2, ({ async f(a, b) { await 1; } }).f.length); |
| 112 assertEquals(1, ({ async f(a, b = 2) { await 1; } }).f.length); |
| 113 assertEquals(2, ({ async f(a, b, ...c) { await 1; } }).f.length); |
| 114 |
| 115 assertEquals(1, AsyncFunction("a", "await 1").length); |
| 116 assertEquals(2, AsyncFunction("a", "b", "await 1").length); |
| 117 assertEquals(1, AsyncFunction("a", "b = 2", "await 1").length); |
| 118 assertEquals(2, AsyncFunction("a", "b", "...c", "await 1").length); |
| 119 |
| 120 assertEquals(1, (new AsyncFunction("a", "await 1")).length); |
| 121 assertEquals(2, (new AsyncFunction("a", "b", "await 1")).length); |
| 122 assertEquals(1, (new AsyncFunction("a", "b = 2", "await 1")).length); |
| 123 assertEquals(2, (new AsyncFunction("a", "b", "...c", "await 1")).length); |
| 124 |
| 125 // AsyncFunction.prototype[ @@toStringTag ] |
| 126 var descriptor = |
| 127 Object.getOwnPropertyDescriptor(AsyncFunction.prototype, |
| 128 Symbol.toStringTag); |
| 129 assertEquals("AsyncFunction", descriptor.value); |
| 130 assertEquals(false, descriptor.enumerable); |
| 131 assertEquals(false, descriptor.writable); |
| 132 assertEquals(true, descriptor.configurable); |
| 133 |
| 134 assertEquals(1, AsyncFunction.length); |
| 135 |
| 136 // Let F be ! FunctionAllocate(functionPrototype, Strict, "non-constructor") |
| 137 async function asyncNonConstructorDecl() {} |
| 138 assertThrows( |
| 139 () => new asyncNonConstructorDecl(), TypeError); |
| 140 assertThrows( |
| 141 () => new (async function() {}), TypeError); |
| 142 assertThrows( |
| 143 () => new ({ async nonConstructor() {} }).nonConstructor(), TypeError); |
| 144 assertThrows( |
| 145 () => new (() => "not a constructor!"), TypeError); |
| 146 assertThrows( |
| 147 () => new (AsyncFunction()), TypeError); |
| 148 assertThrows( |
| 149 () => new (new AsyncFunction()), TypeError); |
| 150 |
| 151 // Normal completion |
| 152 async function asyncDecl() { return "test"; } |
| 153 assertEqualsAsync("test", asyncDecl); |
| 154 assertEqualsAsync("test2", async function() { return "test2"; }); |
| 155 assertEqualsAsync("test3", async () => "test3"); |
| 156 assertEqualsAsync("test4", () => ({ async f() { return "test4"; } }).f()); |
| 157 assertEqualsAsync("test5", () => AsyncFunction("no", "return 'test' + no;")(5)); |
| 158 assertEqualsAsync("test6", |
| 159 () => (new AsyncFunction("no", "return 'test' + no;"))(6)); |
| 160 |
| 161 class MyError extends Error {}; |
| 162 |
| 163 // Throw completion |
| 164 async function asyncDeclThrower(e) { throw new MyError(e); } |
| 165 assertThrowsAsync(() => asyncDeclThrower("boom!"), MyError, "boom!"); |
| 166 assertThrowsAsync( |
| 167 () => (async function(e) { throw new MyError(e); })("boom!!!"), |
| 168 MyError, "boom!!!"); |
| 169 assertThrowsAsync( |
| 170 () => (async e => { throw new MyError(e) })("boom!!"), MyError, "boom!!"); |
| 171 assertThrowsAsync( |
| 172 () => ({ async thrower(e) { throw new MyError(e); } }).thrower("boom!1!"), |
| 173 MyError, "boom!1!"); |
| 174 assertThrowsAsync( |
| 175 () => AsyncFunction("msg", "throw new MyError(msg)")("boom!2!!"), |
| 176 MyError, "boom!2!!"); |
| 177 assertThrowsAsync( |
| 178 () => (new AsyncFunction("msg", "throw new MyError(msg)"))("boom!2!!!"), |
| 179 MyError, "boom!2!!!"); |
| 180 |
| 181 function resolveLater(value) { return Promise.resolve(value); } |
| 182 function rejectLater(error) { return Promise.reject(error); } |
| 183 |
| 184 // Resume after Normal completion |
| 185 var log = []; |
| 186 async function resumeAfterNormal(value) { |
| 187 log.push("start:" + value); |
| 188 value = await resolveLater(value + 1); |
| 189 log.push("resume:" + value); |
| 190 value = await resolveLater(value + 1); |
| 191 log.push("resume:" + value); |
| 192 return value + 1; |
| 193 } |
| 194 |
| 195 assertEqualsAsync(4, () => resumeAfterNormal(1)); |
| 196 assertEquals("start:1 resume:2 resume:3", log.join(" ")); |
| 197 |
| 198 var O = { |
| 199 async resumeAfterNormal(value) { |
| 200 log.push("start:" + value); |
| 201 value = await resolveLater(value + 1); |
| 202 log.push("resume:" + value); |
| 203 value = await resolveLater(value + 1); |
| 204 log.push("resume:" + value); |
| 205 return value + 1; |
| 206 } |
| 207 }; |
| 208 log = []; |
| 209 assertEqualsAsync(5, () => O.resumeAfterNormal(2)); |
| 210 assertEquals("start:2 resume:3 resume:4", log.join(" ")); |
| 211 |
| 212 var resumeAfterNormalArrow = async (value) => { |
| 213 log.push("start:" + value); |
| 214 value = await resolveLater(value + 1); |
| 215 log.push("resume:" + value); |
| 216 value = await resolveLater(value + 1); |
| 217 log.push("resume:" + value); |
| 218 return value + 1; |
| 219 }; |
| 220 log = []; |
| 221 assertEqualsAsync(6, () => resumeAfterNormalArrow(3)); |
| 222 assertEquals("start:3 resume:4 resume:5", log.join(" ")); |
| 223 |
| 224 var resumeAfterNormalEval = AsyncFunction("value", ` |
| 225 log.push("start:" + value); |
| 226 value = await resolveLater(value + 1); |
| 227 log.push("resume:" + value); |
| 228 value = await resolveLater(value + 1); |
| 229 log.push("resume:" + value); |
| 230 return value + 1;`); |
| 231 log = []; |
| 232 assertEqualsAsync(7, () => resumeAfterNormalEval(4)); |
| 233 assertEquals("start:4 resume:5 resume:6", log.join(" ")); |
| 234 |
| 235 var resumeAfterNormalNewEval = new AsyncFunction("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 log = []; |
| 243 assertEqualsAsync(8, () => resumeAfterNormalNewEval(5)); |
| 244 assertEquals("start:5 resume:6 resume:7", log.join(" ")); |
| 245 |
| 246 // Resume after Throw completion |
| 247 async function resumeAfterThrow(value) { |
| 248 log.push("start:" + value); |
| 249 try { |
| 250 value = await rejectLater("throw1"); |
| 251 } catch (e) { |
| 252 log.push("resume:" + e); |
| 253 } |
| 254 try { |
| 255 value = await rejectLater("throw2"); |
| 256 } catch (e) { |
| 257 log.push("resume:" + e); |
| 258 } |
| 259 return value + 1; |
| 260 } |
| 261 |
| 262 log = []; |
| 263 assertEqualsAsync(2, () => resumeAfterThrow(1)); |
| 264 assertEquals("start:1 resume:throw1 resume:throw2", log.join(" ")); |
| 265 |
| 266 var O = { |
| 267 async resumeAfterThrow(value) { |
| 268 log.push("start:" + value); |
| 269 try { |
| 270 value = await rejectLater("throw1"); |
| 271 } catch (e) { |
| 272 log.push("resume:" + e); |
| 273 } |
| 274 try { |
| 275 value = await rejectLater("throw2"); |
| 276 } catch (e) { |
| 277 log.push("resume:" + e); |
| 278 } |
| 279 return value + 1; |
| 280 } |
| 281 } |
| 282 log = []; |
| 283 assertEqualsAsync(3, () => O.resumeAfterThrow(2)); |
| 284 assertEquals("start:2 resume:throw1 resume:throw2", log.join(" ")); |
| 285 |
| 286 var resumeAfterThrowArrow = async (value) => { |
| 287 log.push("start:" + value); |
| 288 try { |
| 289 value = await rejectLater("throw1"); |
| 290 } catch (e) { |
| 291 log.push("resume:" + e); |
| 292 } |
| 293 try { |
| 294 value = await rejectLater("throw2"); |
| 295 } catch (e) { |
| 296 log.push("resume:" + e); |
| 297 } |
| 298 return value + 1; |
| 299 }; |
| 300 |
| 301 log = []; |
| 302 |
| 303 assertEqualsAsync(4, () => resumeAfterThrowArrow(3)); |
| 304 assertEquals("start:3 resume:throw1 resume:throw2", log.join(" ")); |
| 305 |
| 306 var resumeAfterThrowEval = AsyncFunction("value", ` |
| 307 log.push("start:" + value); |
| 308 try { |
| 309 value = await rejectLater("throw1"); |
| 310 } catch (e) { |
| 311 log.push("resume:" + e); |
| 312 } |
| 313 try { |
| 314 value = await rejectLater("throw2"); |
| 315 } catch (e) { |
| 316 log.push("resume:" + e); |
| 317 } |
| 318 return value + 1;`); |
| 319 log = []; |
| 320 assertEqualsAsync(5, () => resumeAfterThrowEval(4)); |
| 321 assertEquals("start:4 resume:throw1 resume:throw2", log.join(" ")); |
| 322 |
| 323 var resumeAfterThrowNewEval = new AsyncFunction("value", ` |
| 324 log.push("start:" + value); |
| 325 try { |
| 326 value = await rejectLater("throw1"); |
| 327 } catch (e) { |
| 328 log.push("resume:" + e); |
| 329 } |
| 330 try { |
| 331 value = await rejectLater("throw2"); |
| 332 } catch (e) { |
| 333 log.push("resume:" + e); |
| 334 } |
| 335 return value + 1;`); |
| 336 log = []; |
| 337 assertEqualsAsync(6, () => resumeAfterThrowNewEval(5)); |
| 338 assertEquals("start:5 resume:throw1 resume:throw2", log.join(" ")); |
OLD | NEW |