async-await.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. describe("parsing freestanding async functions", () => {
  2. test("simple", () => {
  3. expect(`async function foo() {}`).toEval();
  4. // Although it does not create an async function it is valid.
  5. expect(`async
  6. function foo() {}`).toEval();
  7. });
  8. test("await expression", () => {
  9. expect(`async function foo() { await bar(); }`).toEval();
  10. expect(`async function foo() { await; }`).not.toEval();
  11. expect(`function foo() { await bar(); }`).not.toEval();
  12. expect(`function foo() { await; }`).toEval();
  13. expect(`\\u0061sync function foo() { await bar(); }`).not.toEval();
  14. expect(`\\u0061sync function foo() { \\u0061wait bar(); }`).not.toEval();
  15. expect(`async function foo() { \\u0061wait bar(); }`).not.toEval();
  16. });
  17. });
  18. describe("parsing object literal async functions", () => {
  19. test("simple", () => {
  20. expect(`x = { async foo() { } }`).toEval();
  21. expect(`x = { async
  22. foo() { } }`).not.toEval();
  23. });
  24. test("property on object called async", () => {
  25. expect(`x = { async() { } }`).toEval();
  26. expect(`x = { async() { await 4; } }`).not.toEval();
  27. expect(`x = { async: 3 }`).toEval();
  28. expect(`x = { async: await 3, }`).not.toEval();
  29. });
  30. test("await expression", () => {
  31. expect(`x = { foo() { await bar(); } }`).not.toEval();
  32. expect(`x = { foo() { await; } }`).toEval();
  33. expect(`x = { async foo() { await bar(); } }`).toEval();
  34. expect(`x = { async foo() { await; } }`).not.toEval();
  35. });
  36. });
  37. describe("parsing classes with async methods", () => {
  38. test("simple", () => {
  39. expect(`class Foo { async foo() {} }`).toEval();
  40. expect(`class Foo { static async foo() {} }`).toEval();
  41. expect(`class Foo { async foo() { await bar(); } }`).toEval();
  42. expect(`class Foo { async foo() { await; } }`).not.toEval();
  43. expect(`class Foo { async constructor() {} }`).not.toEval();
  44. });
  45. });
  46. test("function expression names equal to 'await'", () => {
  47. expect(`async function foo() { (function await() {}); }`).toEval();
  48. expect(`async function foo() { function await() {} }`).not.toEval();
  49. });
  50. test("async function cannot use await in default parameters", () => {
  51. expect("async function foo(x = await 3) {}").not.toEval();
  52. expect("async function foo(x = await 3) {}").not.toEval();
  53. // Even as a reference to some variable it is not allowed
  54. expect(`
  55. var await = 4;
  56. async function foo(x = await) {}
  57. `).not.toEval();
  58. });
  59. describe("async arrow functions", () => {
  60. test("basic syntax", () => {
  61. expect("async () => await 3;").toEval();
  62. expect("async param => await param();").toEval();
  63. expect("async (param) => await param();").toEval();
  64. expect("async (a, b) => await a();").toEval();
  65. expect("async () => { await 3; }").toEval();
  66. expect("async param => { await param(); }").toEval();
  67. expect("async (param) => { await param(); }").toEval();
  68. expect("async (a, b) => { await a(); }").toEval();
  69. expect(`async
  70. () => await 3;`).not.toEval();
  71. expect("async async => await async()").toEval();
  72. expect("async => async").toEval();
  73. expect("async => await async()").not.toEval();
  74. expect("async (b = await) => await b;").not.toEval();
  75. expect("async (b = await 3) => await b;").not.toEval();
  76. // Cannot escape the async keyword and get an async arrow function.
  77. expect("\\u0061sync () => await 3").not.toEval();
  78. expect("for (async of => {};false;) {}").toEval();
  79. expect("for (async of []) {}").not.toEval();
  80. expect("for (\\u0061sync of []) {}").toEval();
  81. expect("for (\\u0061sync of => {};false;) {}").not.toEval();
  82. expect("for (\\u0061sync => {};false;) {}").toEval();
  83. });
  84. test("async within a for-loop", () => {
  85. let called = false;
  86. // Unfortunately we cannot really test the more horrible case above.
  87. for (
  88. const f = async of => {
  89. return of;
  90. };
  91. ;
  92. ) {
  93. expect(f(43)).toBeInstanceOf(Promise);
  94. called = true;
  95. break;
  96. }
  97. expect(called).toBeTrue();
  98. });
  99. });
  100. test("basic functionality", () => {
  101. test("simple", () => {
  102. let executionValue = null;
  103. let resultValue = null;
  104. async function foo() {
  105. executionValue = "someValue";
  106. return "otherValue";
  107. }
  108. const returnValue = foo();
  109. expect(returnValue).toBeInstanceOf(Promise);
  110. returnValue.then(result => {
  111. resultValue = result;
  112. });
  113. runQueuedPromiseJobs();
  114. expect(executionValue).toBe("someValue");
  115. expect(resultValue).toBe("otherValue");
  116. });
  117. test("await", () => {
  118. let resultValue = null;
  119. async function foo() {
  120. return "someValue";
  121. }
  122. async function bar() {
  123. resultValue = await foo();
  124. }
  125. bar();
  126. runQueuedPromiseJobs();
  127. expect(resultValue).toBe("someValue");
  128. });
  129. });
  130. describe("non async function declaration usage of async still works", () => {
  131. test("async as a function", () => {
  132. function async(value = 4) {
  133. return value;
  134. }
  135. expect(async(0)).toBe(0);
  136. // We use eval here since it otherwise cannot find the async function.
  137. const evalResult = eval("async(1)");
  138. expect(evalResult).toBe(1);
  139. });
  140. test("async as a variable", () => {
  141. let async = 3;
  142. const evalResult = eval("async >= 2");
  143. expect(evalResult).toBeTrue();
  144. });
  145. test("async with line ending does not create a function", () => {
  146. expect(() => {
  147. // The ignore is needed otherwise prettier puts a ';' after async.
  148. // prettier-ignore
  149. async
  150. function f() {}
  151. }).toThrowWithMessage(ReferenceError, "'async' is not defined");
  152. expect(`async
  153. function f() { await 3; }`).not.toEval();
  154. });
  155. });
  156. describe("await cannot be used in class static init blocks", () => {
  157. test("directly", () => {
  158. expect("class A{ static { await; } }").not.toEval();
  159. expect("class A{ static { let await = 3; } }").not.toEval();
  160. expect("class A{ static { call(await); } }").not.toEval();
  161. expect("class A{ static { for(const await = 1; false ;) {} } }").not.toEval();
  162. });
  163. test("via declaration", () => {
  164. expect("class A{ static { class await {} } }").not.toEval();
  165. expect("class A{ static { function await() {} } }").not.toEval();
  166. expect("class A{ static { function* await() {} } }").not.toEval();
  167. expect("class A{ static { async function* await() {} } }").not.toEval();
  168. });
  169. });