diff --git a/test/built-ins/Iterator/prototype/flatMap/flattens-iteratable.js b/test/built-ins/Iterator/prototype/flatMap/flattens-iteratable.js new file mode 100644 index 00000000000..41ad4268dcf --- /dev/null +++ b/test/built-ins/Iterator/prototype/flatMap/flattens-iteratable.js @@ -0,0 +1,30 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Iterator.prototype.flatMap flattens iterables returned by the mapper +info: | + %Iterator.prototype%.flatMap ( mapper ) + +includes: [iterators.js, compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ + +function* g() { + yield 0; + yield 1; + yield 2; + yield 3; +} + +let iter = g().flatMap((v, count) => { + let result = []; + for (let i = 0; i < v; ++i) { + result.push(v); + } + return result; +}); + +assert.compareArray(Array.from(iter), [1, 2, 2, 3, 3, 3]); diff --git a/test/built-ins/Iterator/prototype/flatMap/flattens-iterator.js b/test/built-ins/Iterator/prototype/flatMap/flattens-iterator.js new file mode 100644 index 00000000000..1ef2029d98f --- /dev/null +++ b/test/built-ins/Iterator/prototype/flatMap/flattens-iterator.js @@ -0,0 +1,42 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Iterator.prototype.flatMap flattens non-iterable iterators returned by the mapper +info: | + %Iterator.prototype%.flatMap ( mapper ) + +includes: [iterators.js, compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ + +function* g() { + yield 0; + yield 1; + yield 2; + yield 3; +} + +let iter = g().flatMap((v, count) => { + let i = 0; + return { + next: function() { + if (i < v) { + ++i; + return { + value: v, + done: false + }; + } else { + return { + value: undefined, + done: true + }; + } + } + }; +}); + +assert.compareArray(Array.from(iter), [1, 2, 2, 3, 3, 3]); diff --git a/test/built-ins/Iterator/prototype/flatMap/flattens-only-depth-1.js b/test/built-ins/Iterator/prototype/flatMap/flattens-only-depth-1.js new file mode 100644 index 00000000000..16ecfd93e50 --- /dev/null +++ b/test/built-ins/Iterator/prototype/flatMap/flattens-only-depth-1.js @@ -0,0 +1,34 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Iterator.prototype.flatMap does not flatten recursively +info: | + %Iterator.prototype%.flatMap ( mapper ) + +includes: [iterators.js, compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ + +let arr = [ + { + [Symbol.iterator]: function() { + throw new Test262Error; + } + }, + { + next: function() { + throw new Test262Error; + } + } +]; + +function* g() { + yield arr; +} + +let iter = g().flatMap(v => v); + +assert.compareArray(Array.from(iter), arr); diff --git a/test/built-ins/Iterator/prototype/flatMap/iterable-primitives-are-not-flattened.js b/test/built-ins/Iterator/prototype/flatMap/iterable-primitives-are-not-flattened.js new file mode 100644 index 00000000000..a04916dc6db --- /dev/null +++ b/test/built-ins/Iterator/prototype/flatMap/iterable-primitives-are-not-flattened.js @@ -0,0 +1,35 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Iterator.prototype.flatMap does not respect the iterability of any primitive +info: | + %Iterator.prototype%.flatMap ( mapper ) + +includes: [iterators.js, compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ + +function* g() { + yield 0; +} + +Number.prototype[Symbol.iterator] = function* () { + let i = 0; + let target = this >>> 0; + while (i < target) { + yield i; + ++i; + } +}; + +assert.compareArray(Array.from(5), [0, 1, 2, 3, 4]); + +assert.throws(TypeError, function () { + for(let unused of g().flatMap(v => 5)); +}); + +let iter = g().flatMap(v => new Number(5)); +assert.compareArray(Array.from(iter), [0, 1, 2, 3, 4]); diff --git a/test/built-ins/Iterator/prototype/flatMap/iterable-to-iterator-fallback.js b/test/built-ins/Iterator/prototype/flatMap/iterable-to-iterator-fallback.js new file mode 100644 index 00000000000..12d9803efc8 --- /dev/null +++ b/test/built-ins/Iterator/prototype/flatMap/iterable-to-iterator-fallback.js @@ -0,0 +1,33 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Iterator.prototype.flatMap falls back to treating mapper return values as iterators if the Symbol.iterator property is not callable +info: | + %Iterator.prototype%.flatMap ( mapper ) + +includes: [iterators.js, compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ + +function* g() { + yield 0; +} + +function* h() { + yield 0; + yield 1; + yield 2; +} + +let iter = g().flatMap(v => { + let n = h(); + return { + [Symbol.iterator]: 0, + next: () => n.next() + }; +}); + +assert.compareArray(Array.from(iter), [0, 1, 2]); diff --git a/test/built-ins/Iterator/prototype/flatMap/mapper-args.js b/test/built-ins/Iterator/prototype/flatMap/mapper-args.js index b7c24c396b0..d8f30ee528e 100644 --- a/test/built-ins/Iterator/prototype/flatMap/mapper-args.js +++ b/test/built-ins/Iterator/prototype/flatMap/mapper-args.js @@ -15,6 +15,8 @@ function* g() { yield 'a'; yield 'b'; yield 'c'; + yield 'd'; + yield 'e'; } let assertionCount = 0; @@ -22,22 +24,31 @@ let iter = g().flatMap((v, count) => { switch (v) { case 'a': assert.sameValue(count, 0); - break; + ++assertionCount; + return [0]; case 'b': assert.sameValue(count, 1); - break; + ++assertionCount; + return [0]; case 'c': assert.sameValue(count, 2); - break; + ++assertionCount; + return [1, 2]; + case 'd': + assert.sameValue(count, 3); + ++assertionCount; + return [3, 4, 5]; + case 'e': + assert.sameValue(count, 4); + ++assertionCount; + return [6, 7, 8, 9]; default: throw new Error; } - ++assertionCount; - return [v]; }); assert.sameValue(assertionCount, 0); for (let i of iter); -assert.sameValue(assertionCount, 3); +assert.sameValue(assertionCount, 5); diff --git a/test/built-ins/Iterator/prototype/flatMap/strings-are-not-flattened.js b/test/built-ins/Iterator/prototype/flatMap/strings-are-not-flattened.js new file mode 100644 index 00000000000..0ee5c93243c --- /dev/null +++ b/test/built-ins/Iterator/prototype/flatMap/strings-are-not-flattened.js @@ -0,0 +1,24 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Iterator.prototype.flatMap does not respect the iterability of primitive strings +info: | + %Iterator.prototype%.flatMap ( mapper ) + +includes: [iterators.js, compareArray.js] +features: [iterator-helpers] +flags: [] +---*/ + +function* g() { + yield 0; +} + +assert.throws(TypeError, function () { + for(let unused of g().flatMap(v => 'string')); +}); + +let iter = g().flatMap(v => new String('string')); +assert.compareArray(Array.from(iter), ['s', 't', 'r', 'i', 'n', 'g']);