Index: test/mjsunit/harmony/for-await-of.js |
diff --git a/test/mjsunit/harmony/for-await-of.js b/test/mjsunit/harmony/for-await-of.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..563614d5aa1c37db50dc889336a9d84a968e06b4 |
--- /dev/null |
+++ b/test/mjsunit/harmony/for-await-of.js |
@@ -0,0 +1,693 @@ |
+// Copyright 2016 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; |
+ |
+ 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 + ")"); |
+ return resolve({value: sentValue, done: true}); |
+ } |
+ |
+ let {value, done} = returnMethod.call(it, sentValue); |
+ Promise.resolve(value).then(function(value) { |
+ log.push(".return() -> resolved " + 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}; |
+ } |
+ |
+ test = testObjectBindingPatternLetDeclarationBlockStatement(); |
+ assertFalse(testDone); |
+ assertEquals( |
+ {keys: ['first', 'unknown', 'unknown', 'last'], sum: 100}, await test); |
+ assertTrue(testDone); |
+ |
+ 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 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'; |
+ // Ensure strict mode applies to block with use-strict-directive |
+ 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 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 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 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 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) { |
+ testDone = true; |
+ throw { sum, log, toString() { return "TestError"; } }; |
+ } |
+ } |
+ return { sum, log }; |
+ } |
+ |
+ test = testReturnStatementReturnMethodNotPresent(); |
+ assertFalse(testDone); |
+ try { |
+ assertUnreachable("Awaited Promise should be rejected"); |
+ } catch (e) { |
+ assertEquals("TestError", e.toString()); |
+ assertEquals(6, e.sum); |
+ assertEquals(["[Symbol.asyncIterator]()", ".next() -> resolved 1", |
+ ".next() -> resolved 2", ".next() -> resolved 3" |
+ ], e.log); |
+ assertTrue(testDone); |
+ } |
+ |
+})().then(undefined, function(error) { |
+ testFailed = true; |
+ testFailure = error; |
+}); |
+ |
+%RunMicrotasks(); |
+ |
+if (testFailed) { |
+ throw testFailure; |
+} |