Bug 1185106 - Part 11.3: Add semantics test for async/await. r=efaust.,till draft
authorMariusz Kierski <mkierski@mozilla.com>
Mon, 29 Aug 2016 02:06:19 +0900
changeset 430948 ef39283242084d573148fce168a69ce274c3d379
parent 430947 bcebf593fff32286c09215bacff86822f35b52d8
child 430949 a14def6ea642dea7a71c7314c93f70657aac525a
push id33945
push userarai_a@mac.com
push dateFri, 28 Oct 2016 11:34:02 +0000
reviewersefaust
bugs1185106
milestone52.0a1
Bug 1185106 - Part 11.3: Add semantics test for async/await. r=efaust.,till MozReview-Commit-ID: E1WPuMsz3Jk
js/src/tests/ecma_7/AsyncFunctions/BoundNames.js
js/src/tests/ecma_7/AsyncFunctions/methods.js
js/src/tests/ecma_7/AsyncFunctions/semantics.js
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_7/AsyncFunctions/BoundNames.js
@@ -0,0 +1,28 @@
+var BUGNUMBER = 1185106;
+var summary = "Bound names of async functions";
+
+print(BUGNUMBER + ": " + summary);
+
+var test = `
+
+async function test() {}
+assertEq(test.name, "test");
+
+var test2 = (async function test2() {});
+assertEq(test2.name, "test2");
+
+var anon = async function() {}
+assertEq(anon.name, "");
+
+if (typeof Reflect !== "undefined" && Reflect.parse) {
+  var tree = Reflect.parse("export default async function() {}", { target: "module" });
+  assertEq(tree.body[0].declaration.id.name, "*default*");
+}
+
+`;
+
+if (asyncFunctionsEnabled())
+    eval(test);
+
+if (typeof reportCompare === "function")
+    reportCompare(true, true);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_7/AsyncFunctions/methods.js
@@ -0,0 +1,60 @@
+// |reftest| skip-if(!xulRuntime.shell) -- needs drainJobQueue
+var BUGNUMBER = 1185106;
+var summary = "async methods semantics";
+
+print(BUGNUMBER + ": " + summary);
+
+var test = `
+
+class X {
+  constructor() {
+    this.value = 42;
+  }
+  async getValue() {
+    return this.value;
+  }
+  setValue(value) {
+    this.value = value;
+  }
+  async increment() {
+    var value = await this.getValue();
+    this.setValue(value + 1);
+    return this.getValue();
+  }
+  async getBaseClassName() {
+    return 'X';
+  }
+  static async getStaticValue() {
+    return 44;
+  }
+}
+
+class Y extends X {
+  async getBaseClassName() {
+    return super.getBaseClassName();
+  }
+}
+
+var objLiteral = {
+  async get() {
+    return 45;
+  },
+  someStuff: 5
+};
+
+var x = new X();
+var y = new Y();
+
+assertEventuallyEq(x.getValue(), 42);
+assertEventuallyEq(x.increment(), 43);
+assertEventuallyEq(X.getStaticValue(), 44);
+assertEventuallyEq(objLiteral.get(), 45);
+assertEventuallyEq(y.getBaseClassName(), 'X');
+
+`;
+
+if (asyncFunctionsEnabled())
+    eval(test);
+
+if (typeof reportCompare === "function")
+    reportCompare(true, true);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_7/AsyncFunctions/semantics.js
@@ -0,0 +1,176 @@
+// |reftest| skip-if(!xulRuntime.shell) -- needs drainJobQueue
+var BUGNUMBER = 1185106;
+var summary = "async functions semantics";
+
+print(BUGNUMBER + ": " + summary);
+
+var test = `
+
+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
+assertThrows(() => {
+  async function Person() {
+
+  }
+  new Person();
+}, TypeError);
+
+`;
+
+if (asyncFunctionsEnabled())
+    eval(test);
+
+if (typeof reportCompare === "function")
+    reportCompare(true, true);