Add some Array.from async tests (#3791)

This PR adds some more tests for Array.fromAsync proposal.
It includes most of the tests defined in https://github.com/es-shims/array-from-async/blob/main/test.mjs

See:#3725
This commit is contained in:
Aditi 2023-04-08 05:17:19 +05:30 committed by GitHub
parent 0178aa2114
commit f756ff63c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 724 additions and 0 deletions

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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;
}
});

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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);
});