diff --git a/test/built-ins/Array/fromAsync/async-iterable-async-mapped-awaits-once.js b/test/built-ins/Array/fromAsync/async-iterable-async-mapped-awaits-once.js new file mode 100644 index 0000000000..c4ae9dd180 --- /dev/null +++ b/test/built-ins/Array/fromAsync/async-iterable-async-mapped-awaits-once.js @@ -0,0 +1,30 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Async-iterable awaits each input once with mapping callback +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + async function* generateInput () { + yield* [ 0, 1, 2 ]; + } + const input = generateInput(); + let awaitCounter = 0; + await Array.fromAsync(input, v => { + return { + // This “then” method should occur three times: + // one for each value from the input. + then (resolve, reject) { + awaitCounter ++; + resolve(v); + }, + }; + }); + assert.sameValue(awaitCounter, 3); +}); diff --git a/test/built-ins/Array/fromAsync/async-iterable-input-does-not-await-input.js b/test/built-ins/Array/fromAsync/async-iterable-input-does-not-await-input.js new file mode 100644 index 0000000000..3d27141605 --- /dev/null +++ b/test/built-ins/Array/fromAsync/async-iterable-input-does-not-await-input.js @@ -0,0 +1,38 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Async-iterable input does not await input values. +includes: [compareArray.js, asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const prom = Promise.resolve({}); + const expected = [ prom ]; + + function createInput () { + return { + // The following async iterator will yield one value + // (the promise named “prom”). + [Symbol.asyncIterator]() { + let i = 0; + return { + async next() { + if (i > 0) { + return { done: true }; + } + i++; + return { value: prom, done: false } + }, + }; + }, + }; + } + + const input = createInput(); + const output = await Array.fromAsync(input); + assert.compareArray(output, expected); +}); diff --git a/test/built-ins/Array/fromAsync/async-iterable-input-iteration-err.js b/test/built-ins/Array/fromAsync/async-iterable-input-iteration-err.js new file mode 100644 index 0000000000..2670434baf --- /dev/null +++ b/test/built-ins/Array/fromAsync/async-iterable-input-iteration-err.js @@ -0,0 +1,20 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Array.fromAsync promise rejects if iteration of input fails. +flags: [async] +features: [Array.fromAsync] +includes: [asyncHelpers.js] +---*/ + +asyncTest(async function () { + async function *generateInput () { + throw new Test262Error('This error should be propagated.'); + } + const input = generateInput(); + const outputPromise = Array.fromAsync(input); + await assert.throwsAsync(Test262Error, () => outputPromise); +}); diff --git a/test/built-ins/Array/fromAsync/async-iterable-input.js b/test/built-ins/Array/fromAsync/async-iterable-input.js new file mode 100644 index 0000000000..6c159d9109 --- /dev/null +++ b/test/built-ins/Array/fromAsync/async-iterable-input.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Async-iterable input is transferred to the output array. +includes: [compareArray.js, asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expected = [ 0, 1, 2 ]; + + async function* generateInput () { + yield* expected; + } + + const input = generateInput(); + const output = await Array.fromAsync(input); + assert.compareArray(output, expected); +}); diff --git a/test/built-ins/Array/fromAsync/non-iterable-input-does-not-use-array-prototype.js b/test/built-ins/Array/fromAsync/non-iterable-input-does-not-use-array-prototype.js new file mode 100644 index 0000000000..14206d1225 --- /dev/null +++ b/test/built-ins/Array/fromAsync/non-iterable-input-does-not-use-array-prototype.js @@ -0,0 +1,46 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Non-iterable input does not use Array.prototype +includes: [compareArray.js, asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { +const arrayIterator = [].values(); +const IntrinsicArrayIteratorPrototype = +Object.getPrototypeOf(arrayIterator); +const intrinsicArrayIteratorPrototypeNext = +IntrinsicArrayIteratorPrototype.next; + +try { +// Temporarily mutate the array iterator prototype to have an invalid +// “next” method. Just like Array.from, the fromAsync function should +// still work on non-iterable arraylike arguments. +IntrinsicArrayIteratorPrototype.next = function fakeNext () { + throw new Test262Error( + 'This fake next function should not be called; ' + + 'instead, each element should have been directly accessed.', + ); +}; + +const expected = [ 0, 1, 2 ]; +const input = { + length: 3, + 0: 0, + 1: 1, + 2: 2, +}; +const output = await Array.fromAsync(input); +assert.compareArray(output, expected); +} + +finally { +// Reset the intrinsic array iterator +IntrinsicArrayIteratorPrototype.next = + intrinsicArrayIteratorPrototypeNext; +} +}); diff --git a/test/built-ins/Array/fromAsync/non-iterable-input-element-access-err.js b/test/built-ins/Array/fromAsync/non-iterable-input-element-access-err.js new file mode 100644 index 0000000000..09f594c4e8 --- /dev/null +++ b/test/built-ins/Array/fromAsync/non-iterable-input-element-access-err.js @@ -0,0 +1,21 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Result promise rejects if element access fails +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const input = { + length: 1, + get 0 () { + throw new Test262Error; + }, + }; + const outputPromise = Array.fromAsync(input); + assert.throwsAsync(Test262Error, () => outputPromise); +}); diff --git a/test/built-ins/Array/fromAsync/non-iterable-input-with-thenable-async-mapped-awaits-callback-result-once.js b/test/built-ins/Array/fromAsync/non-iterable-input-with-thenable-async-mapped-awaits-callback-result-once.js new file mode 100644 index 0000000000..13c69c9d45 --- /dev/null +++ b/test/built-ins/Array/fromAsync/non-iterable-input-with-thenable-async-mapped-awaits-callback-result-once.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Non-iterable input with thenable result with async mapped awaits each callback result once. +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + let awaitCounter = 0; + const input = { + length: 3, + 0: 0, + 1: Promise.resolve(1), + 2: Promise.resolve(2), + 3: Promise.resolve(3), // This is ignored because the length is 3. + }; + await Array.fromAsync(input, async v => { + return { + // This “then” method should occur three times: + // one for each value from the input. + then (resolve, reject) { + awaitCounter ++; + resolve(v); + }, + }; + }); + assert.sameValue(awaitCounter, 3); +}); diff --git a/test/built-ins/Array/fromAsync/non-iterable-input-with-thenable-async-mapped-callback-err.js b/test/built-ins/Array/fromAsync/non-iterable-input-with-thenable-async-mapped-callback-err.js new file mode 100644 index 0000000000..6d29d2fa49 --- /dev/null +++ b/test/built-ins/Array/fromAsync/non-iterable-input-with-thenable-async-mapped-callback-err.js @@ -0,0 +1,27 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Non-iterable input with thenable result promise rejects if async map function callback throws. +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expectedValue = {}; + const inputThenable = { + then (resolve, reject) { + resolve(expectedValue); + }, + }; + const input = { + length: 1, + 0: inputThenable, + }; + const outputPromise = Array.fromAsync(input, async v => { + throw new Test262Error; + }); + assert.throwsAsync(Test262Error, () => outputPromise); +}); diff --git a/test/built-ins/Array/fromAsync/non-iterable-input-with-thenable-element-rejects.js b/test/built-ins/Array/fromAsync/non-iterable-input-with-thenable-element-rejects.js new file mode 100644 index 0000000000..cf8ad3d1df --- /dev/null +++ b/test/built-ins/Array/fromAsync/non-iterable-input-with-thenable-element-rejects.js @@ -0,0 +1,26 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Non-iterable input with thenable result promise rejects if thenable element rejects. +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expectedValue = {}; + const expected = [ expectedValue ]; + const inputThenable = { + then (resolve, reject) { + reject(new Test262Error); + }, + }; + const input = { + length: 1, + 0: inputThenable, + }; + const output = Array.fromAsync(input); + await assert.throwsAsync(Test262Error, () => output); +}); diff --git a/test/built-ins/Array/fromAsync/non-iterable-input-with-thenable-sync-mapped-callback-err.js b/test/built-ins/Array/fromAsync/non-iterable-input-with-thenable-sync-mapped-callback-err.js new file mode 100644 index 0000000000..8eacb723ec --- /dev/null +++ b/test/built-ins/Array/fromAsync/non-iterable-input-with-thenable-sync-mapped-callback-err.js @@ -0,0 +1,21 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Non iterable result promise rejects if sync map function callback throws. +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const input = { + length: 1, + 0: 0, + }; + const outputPromise = Array.fromAsync(input, v => { + throw new Test262Error; + }); + assert.throwsAsync(Test262Error, () => outputPromise); +}); diff --git a/test/built-ins/Array/fromAsync/non-iterable-input-with-thenable.js b/test/built-ins/Array/fromAsync/non-iterable-input-with-thenable.js new file mode 100644 index 0000000000..1fd840d5b1 --- /dev/null +++ b/test/built-ins/Array/fromAsync/non-iterable-input-with-thenable.js @@ -0,0 +1,24 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Non iterable input with thenables is transferred to the output array. +includes: [compareArray.js, asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expected = [ 0, 1, 2 ]; + const input = { + length: 3, + 0: 0, + 1: Promise.resolve(1), + 2: Promise.resolve(2), + 3: Promise.resolve(3), // This is ignored because the length is 3. + }; + const output = await Array.fromAsync(input); + assert.compareArray(output, expected); +}); diff --git a/test/built-ins/Array/fromAsync/non-iterable-input.js b/test/built-ins/Array/fromAsync/non-iterable-input.js new file mode 100644 index 0000000000..a212cc5d2e --- /dev/null +++ b/test/built-ins/Array/fromAsync/non-iterable-input.js @@ -0,0 +1,24 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Non iterable input without thenables is transferred to the output array. +includes: [compareArray.js, asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expected = [ 0, 1, 2 ]; + const input = { + length: 3, + 0: 0, + 1: 1, + 2: 2, + 3: 3, // This is ignored because the length is 3. + }; + const output = await Array.fromAsync(input); + assert.compareArray(output, expected); +}); diff --git a/test/built-ins/Array/fromAsync/non-iterable-sync-mapped-callback-err.js b/test/built-ins/Array/fromAsync/non-iterable-sync-mapped-callback-err.js new file mode 100644 index 0000000000..30e25c20bd --- /dev/null +++ b/test/built-ins/Array/fromAsync/non-iterable-sync-mapped-callback-err.js @@ -0,0 +1,27 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Non iterable input with thenables awaits each input once without mapping callback +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expectedValue = {}; + const inputThenable = { + then (resolve, reject) { + resolve(expectedValue); + }, + }; + const input = { + length: 1, + 0: inputThenable, + }; + const outputPromise = Array.fromAsync(input, v => { + throw new Test262Error; + }); + await assert.throwsAsync(Test262Error, () => outputPromise); +}); diff --git a/test/built-ins/Array/fromAsync/non-iterable-with-non-promise-thenable.js b/test/built-ins/Array/fromAsync/non-iterable-with-non-promise-thenable.js new file mode 100644 index 0000000000..5a80053068 --- /dev/null +++ b/test/built-ins/Array/fromAsync/non-iterable-with-non-promise-thenable.js @@ -0,0 +1,26 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Non iterable input with non-promise thenables works. +includes: [compareArray.js, asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expectedValue = {}; + const expected = [ expectedValue ]; + const inputThenable = { + then (resolve, reject) { + resolve(expectedValue); + }, + }; + const input = { + length: 1, + 0: inputThenable, + }; + const output = await Array.fromAsync(input); + assert.compareArray(output, expected); +}); diff --git a/test/built-ins/Array/fromAsync/non-iterable-with-thenable-async-mapped-awaits-once.js b/test/built-ins/Array/fromAsync/non-iterable-with-thenable-async-mapped-awaits-once.js new file mode 100644 index 0000000000..187f479e2f --- /dev/null +++ b/test/built-ins/Array/fromAsync/non-iterable-with-thenable-async-mapped-awaits-once.js @@ -0,0 +1,29 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Non-iterable input with thenables awaits each input once without mapping callback +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expectedValue = {}; + const expected = [ expectedValue ]; + let awaitCounter = 0; + const inputThenable = { + then (resolve, reject) { + awaitCounter++; + resolve(expectedValue); + }, + }; + const input = { + length: 1, + 0: inputThenable, + }; + await Array.fromAsync(input, async v => v); + assert.sameValue(awaitCounter, 1); +}); diff --git a/test/built-ins/Array/fromAsync/non-iterable-with-thenable-awaits-once.js b/test/built-ins/Array/fromAsync/non-iterable-with-thenable-awaits-once.js new file mode 100644 index 0000000000..7a0cb00582 --- /dev/null +++ b/test/built-ins/Array/fromAsync/non-iterable-with-thenable-awaits-once.js @@ -0,0 +1,27 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Non-iterable with thenables awaits each input value once without mapping callback. +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expectedValue = {}; + let awaitCounter = 0; + const inputThenable = { + then (resolve, reject) { + awaitCounter ++; + resolve(expectedValue); + }, + }; + const input = { + length: 1, + 0: inputThenable, + }; + await Array.fromAsync(input); + assert.sameValue(awaitCounter, 1); +}); diff --git a/test/built-ins/Array/fromAsync/non-iterable-with-thenable-sync-mapped-awaits-once.js b/test/built-ins/Array/fromAsync/non-iterable-with-thenable-sync-mapped-awaits-once.js new file mode 100644 index 0000000000..5e23cf559a --- /dev/null +++ b/test/built-ins/Array/fromAsync/non-iterable-with-thenable-sync-mapped-awaits-once.js @@ -0,0 +1,28 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Non-iterable input with thenables awaits each input once with mapping callback +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expectedValue = {}; + let awaitCounter = 0; + const inputThenable = { + then (resolve, reject) { + awaitCounter++; + resolve(expectedValue); + }, + }; + const input = { + length: 1, + 0: inputThenable, + }; + await Array.fromAsync(input, v => v); + assert.sameValue(awaitCounter, 1); +}); diff --git a/test/built-ins/Array/fromAsync/non-iterable-with-thenable-then-method-err.js b/test/built-ins/Array/fromAsync/non-iterable-with-thenable-then-method-err.js new file mode 100644 index 0000000000..68f9eae8ce --- /dev/null +++ b/test/built-ins/Array/fromAsync/non-iterable-with-thenable-then-method-err.js @@ -0,0 +1,24 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Non-iterable input with thenable result promise is rejected if element's then method throws. +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const inputThenable = { + then (resolve, reject) { + throw new Test262Error; + }, + }; + const input = { + length: 1, + 0: inputThenable, + }; + const outputPromise = Array.fromAsync(input); + assert.throwsAsync(Test262Error, () => outputPromise); +}); diff --git a/test/built-ins/Array/fromAsync/sync-iterable-input-with-non-promise-thenable.js b/test/built-ins/Array/fromAsync/sync-iterable-input-with-non-promise-thenable.js new file mode 100644 index 0000000000..0abfe52b72 --- /dev/null +++ b/test/built-ins/Array/fromAsync/sync-iterable-input-with-non-promise-thenable.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Sync-iterable input with non-promise thenables works. +includes: [compareArray.js, asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expectedValue = {}; + const expected = [ expectedValue ]; + const inputThenable = { + then (resolve, reject) { + resolve(expectedValue); + }, + }; + const input = [ inputThenable ].values(); + const output = await Array.fromAsync(input); + assert.compareArray(output, expected); +}); diff --git a/test/built-ins/Array/fromAsync/sync-iterable-input-with-thenable.js b/test/built-ins/Array/fromAsync/sync-iterable-input-with-thenable.js new file mode 100644 index 0000000000..8a9bf7c7f4 --- /dev/null +++ b/test/built-ins/Array/fromAsync/sync-iterable-input-with-thenable.js @@ -0,0 +1,17 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Sync-iterable input with thenables is transferred to the output array. +includes: [compareArray.js, asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expected = [ 0, 1, 2 ]; + const input = [ 0, Promise.resolve(1), Promise.resolve(2) ].values(); + const output = await Array.fromAsync(input); + assert.compareArray(output, expected); +}); diff --git a/test/built-ins/Array/fromAsync/sync-iterable-input.js b/test/built-ins/Array/fromAsync/sync-iterable-input.js new file mode 100644 index 0000000000..e2ec5524ac --- /dev/null +++ b/test/built-ins/Array/fromAsync/sync-iterable-input.js @@ -0,0 +1,17 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Sync-iterable input with no promises is transferred to the output array. +includes: [compareArray.js, asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expected = [ 0, 1, 2 ]; + const input = [ 0, 1, 2 ].values(); + const output = await Array.fromAsync(input); + assert.compareArray(output, expected); +}); diff --git a/test/built-ins/Array/fromAsync/sync-iterable-iteration-err.js b/test/built-ins/Array/fromAsync/sync-iterable-iteration-err.js new file mode 100644 index 0000000000..c3b94994f9 --- /dev/null +++ b/test/built-ins/Array/fromAsync/sync-iterable-iteration-err.js @@ -0,0 +1,19 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Sync iterable result promise rejects if iteration of input fails. +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + function *generateInput () { + throw new Test262Error; + } + const input = generateInput(); + const outputPromise = Array.fromAsync(input); + await assert.throwsAsync(Test262Error, () => outputPromise); +}); diff --git a/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-async-mapped-awaits-once.js b/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-async-mapped-awaits-once.js new file mode 100644 index 0000000000..443fd8f214 --- /dev/null +++ b/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-async-mapped-awaits-once.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Sync-iterable input with thenables awaits each input once with async mapping callback. +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expectedValue = {}; + let awaitCounter = 0; + const inputThenable = { + then (resolve, reject) { + awaitCounter++; + resolve(expectedValue); + }, + }; + const input = [ inputThenable ].values(); + await Array.fromAsync(input, async v => v); + assert.sameValue(awaitCounter, 1); +}); diff --git a/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-async-mapped-callback-err.js b/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-async-mapped-callback-err.js new file mode 100644 index 0000000000..dae13c0118 --- /dev/null +++ b/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-async-mapped-callback-err.js @@ -0,0 +1,18 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Sync-iterable input with thenable result promise rejects if async map function callback throws. +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const input = [ Promise.resolve(0) ].values(); + const outputPromise = Array.fromAsync(input, async v => { + throw new Test262Error; + }); + await assert.throwsAsync(Test262Error, () => outputPromise); +}); diff --git a/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-awaits-once.js b/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-awaits-once.js new file mode 100644 index 0000000000..5d30f8dc13 --- /dev/null +++ b/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-awaits-once.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Sync-iterable input with thenables awaits each input once without mapping callback +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expectedValue = {}; + let awaitCounter = 0; + const inputThenable = { + then (resolve, reject) { + awaitCounter++; + resolve(expectedValue); + }, + }; + const input = [ inputThenable ].values(); + await Array.fromAsync(input); + assert.sameValue(awaitCounter, 1); +}); diff --git a/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-element-rejects.js b/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-element-rejects.js new file mode 100644 index 0000000000..53179d2f3e --- /dev/null +++ b/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-element-rejects.js @@ -0,0 +1,21 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Result promise rejects if then method of input fails. +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const inputThenable = { + then (resolve, reject) { + reject(new Test262Error); + }, + }; + const input = [ inputThenable ].values(); + const output = Array.fromAsync(input); + await assert.throwsAsync(Test262Error, () => output); +}); diff --git a/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-sync-mapped-awaits-once.js b/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-sync-mapped-awaits-once.js new file mode 100644 index 0000000000..a9ab3282ae --- /dev/null +++ b/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-sync-mapped-awaits-once.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: > + Sync-iterable input with mapfn awaits each input once with sync mapping callback +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expectedValue = {}; + let awaitCounter = 0; + const inputThenable = { + then (resolve, reject) { + awaitCounter++; + resolve(expectedValue); + }, + }; + const input = [ inputThenable ].values(); + await Array.fromAsync(input, v => v); + assert.sameValue(awaitCounter, 1); +}); diff --git a/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-sync-mapped-callback-err.js b/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-sync-mapped-callback-err.js new file mode 100644 index 0000000000..023d6aae2a --- /dev/null +++ b/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-sync-mapped-callback-err.js @@ -0,0 +1,18 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Sync-iterable input with thenable result promise rejects if sync map function callback throws. +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const input = [ Promise.resolve(0) ].values(); + const outputPromise = Array.fromAsync(input, v => { + throw new Test262Error; + }); + await assert.throwsAsync(Test262Error, () => outputPromise); +}); diff --git a/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-then-method-err.js b/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-then-method-err.js new file mode 100644 index 0000000000..965fe38c67 --- /dev/null +++ b/test/built-ins/Array/fromAsync/sync-iterable-with-thenable-then-method-err.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.fromasync +description: Result promise rejects if then method of input fails. +includes: [asyncHelpers.js] +flags: [async] +features: [Array.fromAsync] +---*/ + +asyncTest(async function () { + const expectedValue = {}; + const expected = [ expectedValue ]; + const inputThenable = { + then (resolve, reject) { + throw new Test262Error(); + }, + }; + const input = [ inputThenable ].values(); + const output = Array.fromAsync(input); + await assert.throwsAsync(Test262Error, () => output); +});