summaryrefslogtreecommitdiff
path: root/deps/v8/test/mjsunit/harmony/for-await-of.js
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/mjsunit/harmony/for-await-of.js')
-rw-r--r--deps/v8/test/mjsunit/harmony/for-await-of.js1264
1 files changed, 1264 insertions, 0 deletions
diff --git a/deps/v8/test/mjsunit/harmony/for-await-of.js b/deps/v8/test/mjsunit/harmony/for-await-of.js
new file mode 100644
index 0000000000..efcfdab2ea
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/for-await-of.js
@@ -0,0 +1,1264 @@
+// Copyright 2017 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-async-iteration --allow-natives-syntax
+
+let testFailed = false;
+let testFailure;
+(async function() {
+ const kNext = 1;
+ const kThrow = 2;
+ const kReturn = 4;
+ const kReturnPrimitive = kReturn | 32;
+
+ function async(iterable, features = kNext, log = []) {
+ // Helper to turn a synchronous iterable into an asynchronous iterable,
+ // without using the [Async-from-Sync Iterator].
+ let it = iterable[Symbol.iterator]();
+ let methods = {
+ next(sentValue) {
+ return new Promise(function(resolve, reject) {
+ let {value, done} = it.next(sentValue);
+ Promise.resolve(value).then(function(value) {
+ log.push('.next() -> resolved ' + value);
+ resolve({value, done});
+ }, function(value) {
+ log.push('.next() -> rejected ' + value);
+ reject(value);
+ });
+ });
+ },
+
+ throw(sentValue) {
+ return new Promise(function(resolve, reject) {
+ let throwMethod = it.throw;
+ if (typeof throwMethod !== 'function') {
+ log.push('.throw(' + sentValue + ')');
+ return reject(sentValue);
+ }
+
+ let {value, done} = throwMethod.call(it, sentValue);
+ Promise.resolve(value).then(function(value) {
+ log.push('.throw() -> resolved ' + value);
+ resolve({ value, done });
+ }, function(value) {
+ log.push('.throw() -> rejected ' + value);
+ reject(value);
+ });
+ });
+ },
+
+ return(sentValue) {
+ return new Promise(function(resolve, reject) {
+ let returnMethod = it.return;
+ if (typeof returnMethod !== 'function') {
+ log.push('.return(' + sentValue + ')');
+ if ((features & kReturnPrimitive) === kReturnPrimitive)
+ return resolve(sentValue);
+ return resolve({value: sentValue, done: true});
+ }
+
+ let {value, done} = returnMethod.call(it, sentValue);
+ Promise.resolve(value).then(function(value) {
+ log.push('.return() -> resolved ' + value);
+ if ((features & kReturnPrimitive) === kReturnPrimitive)
+ return resolve(value);
+ resolve({ value, done });
+ }, function(value) {
+ log.push('.return() -> rejected ' + value);
+ reject(value);
+ });
+ });
+ }
+ };
+
+
+ return {
+ [Symbol.asyncIterator]() {
+ log.push('[Symbol.asyncIterator]()')
+ return this;
+ },
+
+ next: (features & kNext) ? methods.next : undefined,
+ throw: (features & kThrow) ? methods.throw : undefined,
+ return: (features & kReturn) ? methods.return : undefined
+ };
+ }
+
+ let testDone;
+ let test;
+ async function testBindingIdentifierVarDeclarationStatement() {
+ let sum = 0;
+ testDone = false;
+ for await (var value of async([100, 200, 300, 400, 500])) sum += value;
+ testDone = true;
+ return sum;
+ }
+
+ test = testBindingIdentifierVarDeclarationStatement();
+ assertFalse(testDone);
+ assertEquals(1500, await test);
+ assertTrue(testDone);
+
+ async function testBindingIdentifierVarDeclarationBlockStatement() {
+ let sum = 0;
+ testDone = false;
+ for await (var value of async([100, 200, 300, 400, 500])) {
+ 'use strict';
+ let strict = (function() { return this === undefined; })();
+ assertFalse(strict);
+ sum += value;
+ }
+ testDone = true;
+ return sum;
+ }
+
+ test = testBindingIdentifierVarDeclarationBlockStatement();
+ assertFalse(testDone);
+ assertEquals(1500, await test);
+ assertTrue(testDone);
+
+ async function testObjectBindingPatternVarDeclarationStatement() {
+ let sum = 0, keys = [];
+ let collection = [
+ {key: 'first', value: 10}, {key: undefined, value: 20}, {value: 30},
+ {key: 'last', value: 40}
+ ];
+ testDone = false;
+ for await (var {key = 'unknown', value} of async(collection))
+ keys.push(key), sum += value;
+ testDone = true;
+ return {keys, sum};
+ }
+
+ test = testObjectBindingPatternVarDeclarationStatement();
+ assertFalse(testDone);
+ assertEquals(
+ {keys: ['first', 'unknown', 'unknown', 'last'], sum: 100}, await test);
+ assertTrue(testDone);
+
+ async function testObjectBindingPatternVarDeclarationBlockStatement() {
+ let sum = 0, keys = [];
+ let collection = [
+ {key: 'first', value: 10}, {key: undefined, value: 20}, {value: 30},
+ {key: 'last', value: 40}
+ ];
+ testDone = false;
+ for await (var {key = 'unknown', value} of async(collection)) {
+ 'use strict';
+ let strict = (function() { return this === undefined; })();
+ assertFalse(strict);
+ keys.push(key);
+ sum += value;
+ }
+ testDone = true;
+ return {keys, sum};
+ }
+
+ test = testObjectBindingPatternVarDeclarationBlockStatement();
+ assertFalse(testDone);
+ assertEquals(
+ {keys: ['first', 'unknown', 'unknown', 'last'], sum: 100}, await test);
+ assertTrue(testDone);
+
+ async function testArrayBindingPatternVarDeclarationStatement() {
+ let sum = 0, keys = [];
+ let collection = [['first', 10], [undefined, 20], [, 30], ['last', 40]];
+ testDone = false;
+ for await (var [key = 'unknown', value] of async(collection))
+ keys.push(key), sum += value;
+ testDone = true;
+ return {keys, sum};
+ }
+
+ test = testArrayBindingPatternVarDeclarationStatement();
+ assertFalse(testDone);
+ assertEquals(
+ {keys: ['first', 'unknown', 'unknown', 'last'], sum: 100}, await test);
+ assertTrue(testDone);
+
+ async function testArrayBindingPatternVarDeclarationBlockStatement() {
+ let sum = 0, keys = [];
+ let collection = [['first', 10], [undefined, 20], [, 30], ['last', 40]];
+ testDone = false;
+ for await (var [key = 'unknown', value] of async(collection)) {
+ 'use strict';
+ let strict = (function() { return this === undefined; })();
+ assertFalse(strict);
+ keys.push(key);
+ sum += value;
+ }
+ testDone = true;
+ return {keys, sum};
+ }
+
+ test = testArrayBindingPatternVarDeclarationBlockStatement();
+ assertFalse(testDone);
+ assertEquals(
+ {keys: ['first', 'unknown', 'unknown', 'last'], sum: 100}, await test);
+ assertTrue(testDone);
+
+ // --------------------------------------------------------------------------
+
+ async function testBindingIdentifierLetDeclarationStatement() {
+ let sum = 0;
+ testDone = false;
+ for await (let value of async([100, 200, 300, 400, 500])) sum += value;
+ testDone = true;
+ return sum;
+ }
+
+ test = testBindingIdentifierLetDeclarationStatement();
+ assertFalse(testDone);
+ assertEquals(1500, await test);
+ assertTrue(testDone);
+
+ async function testBindingIdentifierLetDeclarationBlockStatement() {
+ let sum = 0;
+ testDone = false;
+ for await (let value of async([100, 200, 300, 400, 500])) {
+ 'use strict';
+ let strict = (function() { return this === undefined; })();
+ assertFalse(strict);
+ sum += value;
+ }
+ testDone = true;
+ return sum;
+ }
+
+ test = testBindingIdentifierLetDeclarationBlockStatement();
+ assertFalse(testDone);
+ assertEquals(1500, await test);
+ assertTrue(testDone);
+
+ async function testObjectBindingPatternLetDeclarationStatement() {
+ let sum = 0, keys = [];
+ let collection = [
+ {key: 'first', value: 10}, {key: undefined, value: 20}, {value: 30},
+ {key: 'last', value: 40}
+ ];
+ testDone = false;
+ for await (let {key = 'unknown', value} of async(collection))
+ keys.push(key), sum += value;
+ testDone = true;
+ return {keys, sum};
+ }
+
+ test = testObjectBindingPatternLetDeclarationStatement();
+ assertFalse(testDone);
+ assertEquals(
+ {keys: ['first', 'unknown', 'unknown', 'last'], sum: 100}, await test);
+ assertTrue(testDone);
+
+ async function testObjectBindingPatternLetDeclarationBlockStatement() {
+ let sum = 0, keys = [];
+ let collection = [
+ {key: 'first', value: 10}, {key: undefined, value: 20}, {value: 30},
+ {key: 'last', value: 40}
+ ];
+ testDone = false;
+ for await (let {key = 'unknown', value} of async(collection)) {
+ 'use strict';
+ let strict = (function() { return this === undefined; })();
+ assertFalse(strict);
+ keys.push(key);
+ sum += value;
+ }
+ testDone = true;
+ return {keys, sum};
+ }
+
+ let threwEarly = false;
+ test = testObjectBindingPatternLetDeclarationBlockStatement();
+ assertFalse(testDone);
+ assertEquals(
+ {keys: ['first', 'unknown', 'unknown', 'last'], sum: 100}, await test);
+ assertTrue(testDone);
+
+ async function testObjectBindingPatternTDZLetDeclarationStatement() {
+ // See https://codereview.chromium.org/1218543003
+ let sum = 0;
+ testDone = false;
+ let value = { value: 1 };
+ try {
+ for await (let {value} of async([value])) sum += value;
+ } catch (error) {
+ threwEarly = true;
+ throw { sum, error, toString() { return 'TestError' } };
+ }
+ }
+
+ test = testObjectBindingPatternTDZLetDeclarationStatement();
+ assertTrue(threwEarly, 'Async function promise should be rejected');
+ try {
+ await test;
+ } catch (e) {
+ assertEquals('TestError', e.toString());
+ assertEquals(0, e.sum);
+ assertInstanceof(e.error, ReferenceError);
+ testDone = true;
+ }
+ assertTrue(testDone, 'Awaited promise should be rejected');
+
+ async function testObjectBindingPatternTDZLetDeclarationBlockStatement() {
+ // See https://codereview.chromium.org/1218543003
+ let sum = 0;
+ testDone = false;
+ let value = { value: 1 };
+ try {
+ for await (let {value} of async([value])) {
+ sum += value;
+ }
+ } catch (error) {
+ threwEarly = true;
+ throw { sum, error, toString() { return 'TestError' } };
+ }
+ }
+
+ threwEarly = false;
+ test = testObjectBindingPatternTDZLetDeclarationBlockStatement();
+ assertTrue(threwEarly, 'Async function promise should be rejected');
+ try {
+ await test;
+ } catch (e) {
+ assertEquals('TestError', e.toString());
+ assertEquals(0, e.sum);
+ assertInstanceof(e.error, ReferenceError);
+ testDone = true;
+ }
+ assertTrue(testDone, 'Awaited promise should be rejected');
+
+ async function testArrayBindingPatternLetDeclarationStatement() {
+ let sum = 0, keys = [];
+ let collection = [['first', 10], [undefined, 20], [, 30], ['last', 40]];
+ testDone = false;
+ for await (let [key = 'unknown', value] of async(collection))
+ keys.push(key), sum += value;
+ testDone = true;
+ return {keys, sum};
+ }
+
+ test = testArrayBindingPatternLetDeclarationStatement();
+ assertFalse(testDone);
+ assertEquals(
+ {keys: ['first', 'unknown', 'unknown', 'last'], sum: 100}, await test);
+ assertTrue(testDone);
+
+ async function testArrayBindingPatternLetDeclarationBlockStatement() {
+ let sum = 0, keys = [];
+ let collection = [['first', 10], [undefined, 20], [, 30], ['last', 40]];
+ testDone = false;
+ for await (let [key = 'unknown', value] of async(collection)) {
+ 'use strict';
+ let strict = (function() { return this === undefined; })();
+ assertFalse(strict);
+ keys.push(key);
+ sum += value;
+ }
+ testDone = true;
+ return {keys, sum};
+ }
+
+ test = testArrayBindingPatternLetDeclarationBlockStatement();
+ assertFalse(testDone);
+ assertEquals(
+ {keys: ['first', 'unknown', 'unknown', 'last'], sum: 100}, await test);
+ assertTrue(testDone);
+
+ async function testArrayBindingPatternTDZLetDeclarationStatement() {
+ // See https://codereview.chromium.org/1218543003
+ let sum = 0;
+ testDone = false;
+ let value = [1];
+ try {
+ for await (let [value] of async([value])) sum += value;
+ } catch (error) {
+ threwEarly = true;
+ throw { sum, error, toString() { return 'TestError' } };
+ }
+ }
+
+ threwEarly = false;
+ test = testArrayBindingPatternTDZLetDeclarationStatement();
+ assertTrue(threwEarly, 'Async function promise should be rejected');
+ try {
+ await test;
+ } catch (e) {
+ assertEquals('TestError', e.toString());
+ assertEquals(0, e.sum);
+ assertInstanceof(e.error, ReferenceError);
+ testDone = true;
+ }
+ assertTrue(testDone, 'Awaited promise should be rejected');
+
+ async function testArrayBindingPatternTDZLetDeclarationBlockStatement() {
+ // See https://codereview.chromium.org/1218543003
+ let sum = 0;
+ testDone = false;
+ let value = [1];
+ try {
+ for await (let [value] of async([value])) {
+ sum += value;
+ }
+ } catch (error) {
+ threwEarly = true;
+ throw { sum, error, toString() { return 'TestError' } };
+ }
+ }
+
+ threwEarly = false;
+ test = testArrayBindingPatternTDZLetDeclarationBlockStatement();
+ assertTrue(threwEarly, 'Async function promise should be rejected');
+ try {
+ await test;
+ } catch (e) {
+ assertEquals('TestError', e.toString());
+ assertEquals(0, e.sum);
+ assertInstanceof(e.error, ReferenceError);
+ testDone = true;
+ }
+ assertTrue(testDone, 'Awaited promise should be rejected');
+
+ // --------------------------------------------------------------------------
+
+ async function testBindingIdentifierConstDeclarationStatement() {
+ let sum = 0;
+ testDone = false;
+ for await (let value of async([100, 200, 300, 400, 500])) sum += value;
+ testDone = true;
+ return sum;
+ }
+
+ test = testBindingIdentifierConstDeclarationStatement();
+ assertFalse(testDone);
+ assertEquals(1500, await test);
+ assertTrue(testDone);
+
+ async function testBindingIdentifierConstDeclarationBlockStatement() {
+ let sum = 0;
+ testDone = false;
+ for await (const value of async([100, 200, 300, 400, 500])) {
+ 'use strict';
+ let strict = (function() { return this === undefined; })();
+ assertFalse(strict);
+ sum += value;
+ }
+ testDone = true;
+ return sum;
+ }
+
+ test = testBindingIdentifierConstDeclarationBlockStatement();
+ assertFalse(testDone);
+ assertEquals(1500, await test);
+ assertTrue(testDone);
+
+ async function testObjectBindingPatternConstDeclarationStatement() {
+ let sum = 0, keys = [];
+ let collection = [
+ {key: 'first', value: 10}, {key: undefined, value: 20}, {value: 30},
+ {key: 'last', value: 40}
+ ];
+ testDone = false;
+ for await (const {key = 'unknown', value} of async(collection))
+ keys.push(key), sum += value;
+ testDone = true;
+ return {keys, sum};
+ }
+
+ test = testObjectBindingPatternConstDeclarationStatement();
+ assertFalse(testDone);
+ assertEquals(
+ {keys: ['first', 'unknown', 'unknown', 'last'], sum: 100}, await test);
+ assertTrue(testDone);
+
+ async function testObjectBindingPatternConstDeclarationBlockStatement() {
+ let sum = 0, keys = [];
+ let collection = [
+ {key: 'first', value: 10}, {key: undefined, value: 20}, {value: 30},
+ {key: 'last', value: 40}
+ ];
+ testDone = false;
+ for await (const {key = 'unknown', value} of async(collection)) {
+ 'use strict';
+ let strict = (function() { return this === undefined; })();
+ assertFalse(strict);
+ keys.push(key);
+ sum += value;
+ }
+ testDone = true;
+ return {keys, sum};
+ }
+
+ test = testObjectBindingPatternConstDeclarationBlockStatement();
+ assertFalse(testDone);
+ assertEquals(
+ {keys: ['first', 'unknown', 'unknown', 'last'], sum: 100}, await test);
+ assertTrue(testDone);
+
+ async function testObjectBindingPatternTDZConstDeclarationStatement() {
+ // See https://codereview.chromium.org/1218543003
+ let sum = 0;
+ testDone = false;
+ const value = { value: 1 };
+ try {
+ for await (const {value} of async([value])) sum += value;
+ } catch (error) {
+ threwEarly = true;
+ throw { sum, error, toString() { return 'TestError' } };
+ }
+ }
+
+ threwEarly = false;
+ test = testObjectBindingPatternTDZConstDeclarationStatement();
+ assertTrue(threwEarly, 'Async function promise should be rejected');
+ try {
+ await test;
+ } catch (e) {
+ assertEquals('TestError', e.toString());
+ assertEquals(0, e.sum);
+ assertInstanceof(e.error, ReferenceError);
+ testDone = true;
+ }
+ assertTrue(testDone, 'Awaited promise should be rejected');
+
+ async function testObjectBindingPatternTDZConstDeclarationBlockStatement() {
+ // See https://codereview.chromium.org/1218543003
+ let sum = 0;
+ testDone = false;
+ const value = { value: 1 };
+ try {
+ for await (const {value} of async([value])) {
+ sum += value;
+ }
+ } catch (error) {
+ threwEarly = true;
+ throw { sum, error, toString() { return 'TestError' } };
+ }
+ }
+
+ threwEarly = false;
+ test = testObjectBindingPatternTDZConstDeclarationBlockStatement();
+ assertTrue(threwEarly, 'Async function promise should be rejected');
+ try {
+ await test;
+ } catch (e) {
+ assertEquals('TestError', e.toString());
+ assertEquals(0, e.sum);
+ assertInstanceof(e.error, ReferenceError);
+ testDone = true;
+ }
+ assertTrue(testDone, 'Awaited promise should be rejected');
+
+ async function testArrayBindingPatternConstDeclarationStatement() {
+ let sum = 0, keys = [];
+ let collection = [['first', 10], [undefined, 20], [, 30], ['last', 40]];
+ testDone = false;
+ for await (const [key = 'unknown', value] of async(collection))
+ keys.push(key), sum += value;
+ testDone = true;
+ return {keys, sum};
+ }
+
+ test = testArrayBindingPatternConstDeclarationStatement();
+ assertFalse(testDone);
+ assertEquals(
+ {keys: ['first', 'unknown', 'unknown', 'last'], sum: 100}, await test);
+ assertTrue(testDone);
+
+ async function testArrayBindingPatternConstDeclarationBlockStatement() {
+ let sum = 0, keys = [];
+ let collection = [['first', 10], [undefined, 20], [, 30], ['last', 40]];
+ testDone = false;
+ for await (const [key = 'unknown', value] of async(collection)) {
+ 'use strict';
+ let strict = (function() { return this === undefined; })();
+ assertFalse(strict);
+ keys.push(key);
+ sum += value;
+ }
+ testDone = true;
+ return {keys, sum};
+ }
+
+ test = testArrayBindingPatternLetDeclarationBlockStatement();
+ assertFalse(testDone);
+ assertEquals(
+ {keys: ['first', 'unknown', 'unknown', 'last'], sum: 100}, await test);
+ assertTrue(testDone);
+
+ async function testArrayBindingPatternTDZConstDeclarationStatement() {
+ // See https://codereview.chromium.org/1218543003
+ let sum = 0;
+ testDone = false;
+ const value = [1];
+ try {
+ for await (const [value] of async([value])) sum += value;
+ } catch (error) {
+ threwEarly = true;
+ throw { sum, error, toString() { return 'TestError' } };
+ }
+ }
+
+ threwEarly = false;
+ test = testArrayBindingPatternTDZConstDeclarationStatement();
+ assertTrue(threwEarly, 'Async function promise should be rejected');
+ try {
+ await test;
+ } catch (e) {
+ assertEquals('TestError', e.toString());
+ assertEquals(0, e.sum);
+ assertInstanceof(e.error, ReferenceError);
+ testDone = true;
+ }
+ assertTrue(testDone, 'Awaited promise should be rejected');
+
+ async function testArrayBindingPatternTDZConstDeclarationBlockStatement() {
+ // See https://codereview.chromium.org/1218543003
+ let sum = 0;
+ testDone = false;
+ const value = [1];
+ try {
+ for await (const [value] of async([value])) {
+ sum += value;
+ }
+ } catch (error) {
+ threwEarly = true;
+ throw { sum, error, toString() { return 'TestError' } };
+ }
+ }
+
+ threwEarly = false;
+ test = testArrayBindingPatternTDZConstDeclarationBlockStatement();
+ assertTrue(threwEarly, 'Async function promise should be rejected');
+ try {
+ await test;
+ } catch (e) {
+ assertEquals('TestError', e.toString());
+ assertEquals(0, e.sum);
+ assertInstanceof(e.error, ReferenceError);
+ testDone = true;
+ }
+ assertTrue(testDone, 'Awaited promise should be rejected');
+
+ // --------------------------------------------------------------------------
+
+ async function testBindingIdentifierLHSStatement() {
+ let sum = 0;
+ let value;
+ testDone = false;
+ for await (value of async([100, 200, 300, 400, 500])) sum += value;
+ testDone = true;
+ return sum;
+ }
+
+ test = testBindingIdentifierLHSStatement();
+ assertFalse(testDone);
+ assertEquals(1500, await test);
+ assertTrue(testDone);
+
+ async function testBindingIdentifierLHSBlockStatement() {
+ let sum = 0;
+ let value;
+ testDone = false;
+ for await (value of async([100, 200, 300, 400, 500])) {
+ 'use strict';
+ let strict = (function() { return this === undefined; })();
+ assertFalse(strict);
+ sum += value;
+ }
+ testDone = true;
+ return sum;
+ }
+
+ test = testBindingIdentifierLHSStatement();
+ assertFalse(testDone);
+ assertEquals(1500, await test);
+ assertTrue(testDone);
+
+ async function testObjectBindingPatternLHSStatement() {
+ let sum = 0;
+ let keys = [];
+ let value;
+ let key;
+ let collection = [
+ {key: 'first', value: 1}, {key: undefined, value: 2}, {value: 3},
+ {key: 'last', value: 4}
+ ];
+ testDone = false;
+ for await ({key = 'unknown', value} of async(collection))
+ keys.push(key), sum += value;
+ testDone = true;
+ return {keys, sum};
+ }
+
+ test = testObjectBindingPatternLHSStatement();
+ assertFalse(testDone);
+ assertEquals(
+ {keys: ['first', 'unknown', 'unknown', 'last'], sum: 10}, await test);
+ assertTrue(testDone);
+
+ async function testObjectBindingPatternLHSBlockStatement() {
+ let sum = 0;
+ let keys = [];
+ let value;
+ let key;
+ let collection = [
+ {key: 'first', value: 1}, {key: undefined, value: 2}, {value: 3},
+ {key: 'last', value: 4}
+ ];
+ testDone = false;
+ for await ({key = 'unknown', value} of async(collection)) {
+ 'use strict';
+ let strict = (function() { return this === undefined; })();
+ assertFalse(strict);
+ keys.push(key);
+ sum += value;
+ }
+ testDone = true;
+ return {keys, sum};
+ }
+
+ test = testObjectBindingPatternLHSBlockStatement();
+ assertFalse(testDone);
+ assertEquals(
+ {keys: ['first', 'unknown', 'unknown', 'last'], sum: 10}, await test);
+ assertTrue(testDone);
+
+ async function testArrayBindingPatternLHSStatement() {
+ let sum = 0;
+ let keys = [];
+ let value;
+ let key;
+ let collection = [['first', 1], [undefined, 2], [, 3], ['last', 4]];
+ testDone = false;
+ for await ([key = 'unknown', value] of async(collection)) {
+ 'use strict';
+ let strict = (function() { return this === undefined; })();
+ assertFalse(strict);
+ keys.push(key);
+ sum += value;
+ }
+ testDone = true;
+ return {keys, sum};
+ }
+
+ test = testArrayBindingPatternLHSStatement();
+ assertFalse(testDone);
+ assertEquals(
+ {keys: ['first', 'unknown', 'unknown', 'last'], sum: 10}, await test);
+ assertTrue(testDone);
+
+ async function testArrayBindingPatternLHSBlockStatement() {
+ let sum = 0;
+ let keys = [];
+ let value;
+ let key;
+ let collection = [
+ {key: 'first', value: 1}, {key: undefined, value: 2}, {value: 3},
+ {key: 'last', value: 4}
+ ];
+ testDone = false;
+ for await ({key = 'unknown', value} of async(collection)) {
+ 'use strict';
+ let strict = (function() { return this === undefined; })();
+ assertFalse(strict);
+ keys.push(key);
+ sum += value;
+ }
+ testDone = true;
+ return {keys, sum};
+ }
+
+ test = testArrayBindingPatternLHSBlockStatement();
+ assertFalse(testDone);
+ assertEquals(
+ {keys: ['first', 'unknown', 'unknown', 'last'], sum: 10}, await test);
+ assertTrue(testDone);
+
+ // --------------------------------------------------------------------------
+
+ async function testBreakStatementReturnMethodNotPresent() {
+ let log = [];
+ let collection = [1, 2, 3, 4, 5];
+ let sum = 0;
+ let i = 0;
+ testDone = false;
+ for await (var x of async(collection, kNext, log)) {
+ sum += x;
+ if (++i === 3) break;
+ }
+ testDone = true;
+ return { sum, log };
+ }
+
+ test = testBreakStatementReturnMethodNotPresent();
+ assertFalse(testDone);
+ assertEquals({sum: 6, log: ['[Symbol.asyncIterator]()',
+ '.next() -> resolved 1',
+ '.next() -> resolved 2',
+ '.next() -> resolved 3']},
+ await test);
+ assertTrue(testDone);
+
+ async function testBreakStatementReturnMethodPresent() {
+ let log = [];
+ let collection = [1, 2, 3, 4, 5];
+ let sum = 0;
+ let i = 0;
+ testDone = false;
+ for await (var x of async(collection, kNext|kReturn, log)) {
+ sum += x;
+ if (++i === 2) break;
+ }
+ testDone = true;
+ return { sum, log };
+ }
+
+ test = testBreakStatementReturnMethodPresent();
+ assertFalse(testDone);
+ assertEquals({sum: 3, log: ['[Symbol.asyncIterator]()',
+ '.next() -> resolved 1',
+ '.next() -> resolved 2',
+ '.return(undefined)']},
+ await test);
+ assertTrue(testDone);
+
+ async function testBreakStatementReturnMethodAwaitIterResult() {
+ let log = [];
+ let collection = [1, 2, 3, 4, 5];
+ let sync_iter = collection[Symbol.iterator]();
+ sync_iter.return = function() {
+ return {
+ value: new Promise(function(resolve, reject) {
+ Promise.resolve().then(function() {
+ resolve('break!');
+ });
+ }),
+ done: true
+ };
+ };
+
+ let sum = 0;
+ let i = 0;
+ testDone = false;
+ for await (var x of async(sync_iter, kNext|kReturn, log)) {
+ sum += x;
+ if (++i === 2) break;
+ }
+ testDone = true;
+ return { sum, log };
+ }
+
+ test = testBreakStatementReturnMethodAwaitIterResult();
+ assertFalse(testDone);
+ assertEquals({sum: 3,
+ log: ['[Symbol.asyncIterator]()',
+ '.next() -> resolved 1',
+ '.next() -> resolved 2',
+ '.return() -> resolved break!' ]},
+ await test);
+ assertTrue(testDone);
+
+ async function testBreakStatementReturnMethodAwaitRejection(log) {
+ let collection = [1, 2, 3, 4, 5];
+ let sync_iter = collection[Symbol.iterator]();
+ let sum = 0;
+ sync_iter.return = function() {
+ return {
+ value: new Promise(function(resolve, reject) {
+ Promise.resolve().then(function() {
+ reject('break! ' + sum);
+ });
+ }),
+ done: true
+ };
+ };
+
+ let i = 0;
+ testDone = false;
+ for await (var x of async(sync_iter, kNext|kReturn, log)) {
+ sum += x;
+ if (++i === 2) break;
+ }
+ return { sum, log };
+ }
+
+ let log = [];
+ test = testBreakStatementReturnMethodAwaitRejection(log);
+ assertFalse(testDone);
+ try {
+ await test;
+ } catch (e) {
+ assertEquals(log, ['[Symbol.asyncIterator]()',
+ '.next() -> resolved 1',
+ '.next() -> resolved 2',
+ '.return() -> rejected break! 3']);
+ assertEquals('break! 3', e);
+ testDone = true;
+ }
+ assertTrue(testDone, 'Promise should be rejected');
+
+ async function testBreakStatementReturnMethodPrimitiveValue(log) {
+ let collection = [1, 2, 3, 4, 5];
+ let sync_iter = collection[Symbol.iterator]();
+ sync_iter.return = function() {
+ return { value: 'break! primitive!', done: true };
+ }
+ let sum = 0;
+ let i = 0;
+ testDone = false;
+ for await (var x of async(sync_iter, kNext|kReturnPrimitive, log)) {
+ sum += x;
+ if (++i === 2) break;
+ }
+ return { sum, log };
+ }
+ log = [];
+ test = testBreakStatementReturnMethodPrimitiveValue(log);
+ assertFalse(testDone);
+ try {
+ await test;
+ } catch (e) {
+ assertEquals(['[Symbol.asyncIterator]()',
+ '.next() -> resolved 1',
+ '.next() -> resolved 2',
+ '.return() -> resolved break! primitive!'],
+ log);
+ assertInstanceof(e, TypeError);
+ testDone = true;
+ }
+ assertTrue(testDone, 'Promise should be rejected');
+
+ async function testReturnStatementReturnMethodNotPresent() {
+ let log = [];
+ let collection = [1, 2, 3, 4, 5];
+ let sum = 0;
+ let i = 0;
+ testDone = false;
+ for await (var x of async(collection, kNext, log)) {
+ sum += x;
+ if (++i === 3) {
+ testDone = true;
+ return { sum, log };
+ }
+ }
+ }
+
+ test = testReturnStatementReturnMethodNotPresent();
+ assertFalse(testDone);
+ assertEquals({sum: 6, log: ['[Symbol.asyncIterator]()',
+ '.next() -> resolved 1',
+ '.next() -> resolved 2',
+ '.next() -> resolved 3']},
+ await test);
+ assertTrue(testDone);
+
+ async function testReturnStatementReturnMethodPresent() {
+ let log = [];
+ let collection = [1, 2, 3, 4, 5];
+ let sum = 0;
+ let i = 0;
+ testDone = false;
+ for await (var x of async(collection, kNext|kReturn, log)) {
+ sum += x;
+ if (++i === 2) {
+ testDone = true;
+ return { sum, log };
+ }
+ }
+ }
+
+ test = testReturnStatementReturnMethodPresent();
+ assertFalse(testDone);
+ assertEquals({sum: 3, log: ['[Symbol.asyncIterator]()',
+ '.next() -> resolved 1',
+ '.next() -> resolved 2',
+ '.return(undefined)']},
+ await test);
+ assertTrue(testDone);
+
+ async function testReturnStatementReturnMethodAwaitIterResult() {
+ let log = [];
+ let collection = [1, 2, 3, 4, 5];
+ let sync_iter = collection[Symbol.iterator]();
+ sync_iter.return = function() {
+ return {
+ value: new Promise(function(resolve, reject) {
+ Promise.resolve().then(function() {
+ testDone = true;
+ resolve('return!');
+ });
+ }),
+ done: true
+ };
+ };
+
+ let sum = 0;
+ let i = 0;
+ testDone = false;
+ for await (var x of async(sync_iter, kNext|kReturn, log)) {
+ sum += x;
+ if (++i === 2) return { sum, log };
+ }
+ }
+
+ test = testReturnStatementReturnMethodAwaitIterResult();
+ assertFalse(testDone);
+ assertEquals({sum: 3,
+ log: ['[Symbol.asyncIterator]()',
+ '.next() -> resolved 1',
+ '.next() -> resolved 2',
+ '.return() -> resolved return!' ]},
+ await test);
+ assertTrue(testDone);
+
+ async function testReturnStatementReturnMethodAwaitRejection(log) {
+ let collection = [1, 2, 3, 4, 5];
+ let sync_iter = collection[Symbol.iterator]();
+ let sum = 0;
+ sync_iter.return = function() {
+ return {
+ value: new Promise(function(resolve, reject) {
+ Promise.resolve().then(function() {
+ reject('return! ' + sum);
+ });
+ }),
+ done: true
+ };
+ };
+
+ let i = 0;
+ testDone = false;
+ for await (var x of async(sync_iter, kNext|kReturn, log)) {
+ sum += x;
+ if (++i === 2) return { sum, log };
+ }
+ }
+
+ log = [];
+ test = testReturnStatementReturnMethodAwaitRejection(log);
+ assertFalse(testDone);
+ try {
+ await test;
+ } catch (e) {
+ assertEquals('return! 3', e);
+ assertEquals(['[Symbol.asyncIterator]()',
+ '.next() -> resolved 1',
+ '.next() -> resolved 2',
+ '.return() -> rejected return! 3'],
+ log);
+ testDone = true;
+ }
+ assertTrue(testDone, 'Promise should be rejected');
+
+ async function testReturnStatementReturnMethodPrimitiveValue(log) {
+ let collection = [1, 2, 3, 4, 5];
+ let sync_iter = collection[Symbol.iterator]();
+ sync_iter.return = function() {
+ return { value: 'return! primitive!', done: true };
+ }
+ let sum = 0;
+ let i = 0;
+ testDone = false;
+ for await (var x of async(sync_iter, kNext|kReturnPrimitive, log)) {
+ sum += x;
+ if (++i === 2) break;
+ }
+ return { sum, log };
+ }
+ log = [];
+ test = testReturnStatementReturnMethodPrimitiveValue(log);
+ assertFalse(testDone);
+ try {
+ await test;
+ } catch (e) {
+ assertEquals(['[Symbol.asyncIterator]()',
+ '.next() -> resolved 1',
+ '.next() -> resolved 2',
+ '.return() -> resolved return! primitive!'],
+ log);
+ assertInstanceof(e, TypeError);
+ testDone = true;
+ }
+ assertTrue(testDone, 'Promise should be rejected');
+
+ async function testThrowStatementReturnMethodNotPresent() {
+ let log = [];
+ let collection = [1, 2, 3, 4, 5];
+ let sum = 0;
+ let i = 0;
+ testDone = false;
+ for await (var x of async(collection, kNext|kThrow, log)) {
+ sum += x;
+ if (++i === 3) {
+ throw { sum, log, toString() { return 'TestError'; } };
+ }
+ }
+ return { sum, log };
+ }
+
+ test = testThrowStatementReturnMethodNotPresent();
+ assertFalse(testDone);
+ try {
+ await test;
+ } catch (e) {
+ assertEquals('TestError', e.toString());
+ assertEquals(6, e.sum);
+ assertEquals(['[Symbol.asyncIterator]()', '.next() -> resolved 1',
+ '.next() -> resolved 2', '.next() -> resolved 3'
+ ], e.log);
+ testDone = true;
+ }
+ assertTrue(testDone, 'Awaited Promise should be rejected');
+
+ async function testThrowStatementReturnMethodPresent() {
+ let log = [];
+ let collection = [1, 2, 3, 4, 5];
+ let sum = 0;
+ let i = 0;
+ testDone = false;
+ for await (var x of async(collection, kNext|kThrow|kReturn, log)) {
+ sum += x;
+ if (++i === 2) {
+ throw { sum, log, toString() { return 'TestError2'; } };
+ }
+ }
+ return { sum, log };
+ }
+
+ test = testThrowStatementReturnMethodPresent();
+ assertFalse(testDone);
+ try {
+ await test;
+ } catch (e) {
+ assertEquals('TestError2', e.toString());
+ assertEquals(3, e.sum);
+ assertEquals(['[Symbol.asyncIterator]()', '.next() -> resolved 1',
+ '.next() -> resolved 2', '.return(undefined)'
+ ], e.log);
+ testDone = true;
+ }
+ assertTrue(testDone, 'Awaited Promise should be rejected');
+
+ async function testThrowStatementReturnMethodAwaitIterResult(log) {
+ let collection = [1, 2, 3, 4, 5];
+ let sync_iter = collection[Symbol.iterator]();
+ sync_iter.return = function() {
+ return {
+ value: new Promise(function(resolve, reject) {
+ Promise.resolve().then(function() {
+ testDone = true;
+ resolve('throw!');
+ });
+ }),
+ done: true
+ };
+ };
+
+ let sum = 0;
+ let i = 0;
+ testDone = false;
+ for await (var x of async(sync_iter, kNext|kReturn, log)) {
+ sum += x;
+ if (++i === 2) throw 'Boo!!';
+ }
+ }
+
+ log = [];
+ test = testThrowStatementReturnMethodAwaitIterResult(log);
+ assertFalse(testDone);
+
+ try {
+ await test;
+ } catch (e) {
+ assertEquals('Boo!!', e);
+ assertEquals(['[Symbol.asyncIterator]()',
+ '.next() -> resolved 1',
+ '.next() -> resolved 2',
+ '.return() -> resolved throw!' ], log);
+ testDone = true;
+ }
+ assertTrue(testDone, 'Awaited Promise should be rejected');
+
+ async function testThrowStatementReturnMethodAwaitRejection(log) {
+ let collection = [1, 2, 3, 4, 5];
+ let sync_iter = collection[Symbol.iterator]();
+ let sum = 0;
+ sync_iter.return = function() {
+ return {
+ value: new Promise(function(resolve, reject) {
+ Promise.resolve().then(function() {
+ reject('return! ' + sum);
+ });
+ }),
+ done: true
+ };
+ };
+
+ let i = 0;
+ testDone = false;
+ for await (var x of async(sync_iter, kNext|kReturn, log)) {
+ sum += x;
+ if (++i === 2) throw 'Boo!!';
+ }
+ }
+
+ log = [];
+ test = testThrowStatementReturnMethodAwaitRejection(log);
+ assertFalse(testDone);
+ try {
+ await test;
+ } catch (e) {
+ assertEquals('Boo!!', e);
+ assertEquals(['[Symbol.asyncIterator]()',
+ '.next() -> resolved 1',
+ '.next() -> resolved 2',
+ '.return() -> rejected return! 3'],
+ log);
+ testDone = true;
+ }
+ assertTrue(testDone, 'Promise should be rejected');
+
+ async function testThrowStatementReturnMethodPrimitiveValue(log) {
+ let collection = [1, 2, 3, 4, 5];
+ let sync_iter = collection[Symbol.iterator]();
+ sync_iter.return = function() {
+ return { value: 'return! primitive!', done: true };
+ }
+ let sum = 0;
+ let i = 0;
+ testDone = false;
+ for await (var x of async(sync_iter, kNext|kReturnPrimitive, log)) {
+ sum += x;
+ if (++i === 2) throw 'Boo!!';
+ }
+ }
+ log = [];
+ test = testThrowStatementReturnMethodPrimitiveValue(log);
+ assertFalse(testDone);
+ try {
+ await test;
+ } catch (e) {
+ assertEquals(['[Symbol.asyncIterator]()',
+ '.next() -> resolved 1',
+ '.next() -> resolved 2',
+ '.return() -> resolved return! primitive!'],
+ log);
+
+ // AsyncIteratorClose does not require Throw completions to be of type
+ // Object
+ assertEquals('Boo!!', e);
+ testDone = true;
+ }
+ assertTrue(testDone, 'Promise should be rejected');
+})().catch(function(error) {
+ testFailed = true;
+ testFailure = error;
+});
+
+%RunMicrotasks();
+
+if (testFailed) {
+ throw testFailure;
+}