mirror of https://github.com/tc39/test262.git
Array.fromAsync various remaining coverage (#3809)
This contains a few more tests for Array.fromAsync, in addition to what has already been merged and what is under review at #3791. This covers the following items from the testing plan at #3725: - Success cases - Creates promise - Create new array/arraylike in promise (with length = length property) - Input - Invalid input values - nonconforming object (arraylike without length, missing keys) - Covered by polyfill tests - Result promise rejects if length access fails (non-iterable input) - Unaffected by globalThis.Symbol mutation (non-iterable) - this-value - this-value is a constructor - this-value is not a constructor - If this is a constructor, and items doesn't have a Symbol.iterator, returns a new instance of this - Iterator closed when property creation on this fails - Returned promise rejects when ^ - Other tests - Error is thrown for all CreateDataProperty fails - Non-writable properties are overwritten by CreateDataProperty - Input with missing values Co-authored-by: Ms2ger <Ms2ger@igalia.com>
This commit is contained in:
parent
daefac0814
commit
92500bfffb
|
@ -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: Array-like object with holes treats the holes as undefined
|
||||
info: |
|
||||
3.k.vii.2. Let _kValue_ be ? Get(_arrayLike_, _Pk_).
|
||||
features: [Array.fromAsync]
|
||||
flags: [async]
|
||||
includes: [asyncHelpers.js, compareArray.js]
|
||||
---*/
|
||||
|
||||
asyncTest(async function () {
|
||||
const arrayLike = Object.create(null);
|
||||
arrayLike.length = 5;
|
||||
arrayLike[0] = 0;
|
||||
arrayLike[1] = 1;
|
||||
arrayLike[2] = 2;
|
||||
arrayLike[4] = 4;
|
||||
|
||||
const array = await Array.fromAsync(arrayLike);
|
||||
assert.compareArray(array, [0, 1, 2, undefined, 4], "holes in array-like treated as undefined");
|
||||
});
|
|
@ -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: Rejects on array-like object whose length cannot be gotten
|
||||
info: |
|
||||
3.k.iii. Let _len_ be ? LengthOfArrayLike(_arrayLike_).
|
||||
features: [Array.fromAsync]
|
||||
flags: [async]
|
||||
includes: [asyncHelpers.js]
|
||||
---*/
|
||||
|
||||
asyncTest(async function () {
|
||||
await assert.throwsAsync(Test262Error, () => Array.fromAsync({
|
||||
get length() {
|
||||
throw new Test262Error('accessing length property fails');
|
||||
}
|
||||
}), "Promise should be rejected if array-like length getter throws");
|
||||
|
||||
await assert.throwsAsync(TypeError, () => Array.fromAsync({
|
||||
length: 1n,
|
||||
0: 0
|
||||
}), "Promise should be rejected if array-like length can't be converted to a number");
|
||||
});
|
|
@ -0,0 +1,31 @@
|
|||
// 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: >
|
||||
Promise is rejected if the length of the array-like to copy is out of range
|
||||
info: |
|
||||
j. If _iteratorRecord_ is not *undefined*, then
|
||||
...
|
||||
k. Else,
|
||||
...
|
||||
iv. If IsConstructor(_C_) is *true*, then
|
||||
...
|
||||
v. Else,
|
||||
1. Let _A_ be ? ArrayCreate(_len_).
|
||||
|
||||
ArrayCreate, step 1:
|
||||
1. If _length_ > 2³² - 1, throw a *RangeError* exception.
|
||||
includes: [asyncHelpers.js]
|
||||
flags: [async]
|
||||
features: [Array.fromAsync]
|
||||
---*/
|
||||
|
||||
asyncTest(async function () {
|
||||
const notConstructor = {};
|
||||
|
||||
await assert.throwsAsync(RangeError, () => Array.fromAsync.call(notConstructor, {
|
||||
length: 4294967296 // 2³²
|
||||
}), "Array-like with excessive length");
|
||||
});
|
|
@ -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: >
|
||||
Treats an asyncItems object that isn't an array-like as a 0-length array-like
|
||||
info: |
|
||||
3.k.iii. Let _len_ be ? LengthOfArrayLike(_arrayLike_).
|
||||
features: [Array.fromAsync]
|
||||
flags: [async]
|
||||
includes: [asyncHelpers.js, compareArray.js]
|
||||
---*/
|
||||
|
||||
asyncTest(async function () {
|
||||
const notArrayLike = Object.create(null);
|
||||
notArrayLike[0] = 0;
|
||||
notArrayLike[1] = 1;
|
||||
notArrayLike[2] = 2;
|
||||
|
||||
const array = await Array.fromAsync(notArrayLike);
|
||||
assert.compareArray(array, [], "non-array-like object is treated as 0-length array-like");
|
||||
});
|
|
@ -0,0 +1,40 @@
|
|||
// 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: >
|
||||
Use the intrinsic @@iterator and @@asyncIterator to check iterability
|
||||
includes: [compareArray.js, asyncHelpers.js]
|
||||
flags: [async]
|
||||
features: [Array.fromAsync]
|
||||
---*/
|
||||
|
||||
asyncTest(async function () {
|
||||
// Replace the user-reachable Symbol.iterator and Symbol.asyncIterator with
|
||||
// fake symbol keys
|
||||
const originalSymbol = globalThis.Symbol;
|
||||
const fakeIteratorSymbol = Symbol("iterator");
|
||||
const fakeAsyncIteratorSymbol = Symbol("asyncIterator");
|
||||
globalThis.Symbol = {
|
||||
iterator: fakeIteratorSymbol,
|
||||
asyncIterator: fakeAsyncIteratorSymbol,
|
||||
};
|
||||
|
||||
const input = {
|
||||
length: 3,
|
||||
0: 0,
|
||||
1: 1,
|
||||
2: 2,
|
||||
[fakeIteratorSymbol]() {
|
||||
throw new Test262Error("The fake Symbol.iterator method should not be called");
|
||||
},
|
||||
[fakeAsyncIteratorSymbol]() {
|
||||
throw new Test262Error("The fake Symbol.asyncIterator method should not be called");
|
||||
}
|
||||
};
|
||||
const output = await Array.fromAsync(input);
|
||||
assert.compareArray(output, [0, 1, 2]);
|
||||
|
||||
globalThis.Symbol = originalSymbol;
|
||||
});
|
|
@ -0,0 +1,22 @@
|
|||
// 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 returns a Promise that resolves to an Array in the normal case
|
||||
info: |
|
||||
1. Let _C_ be the *this* value.
|
||||
...
|
||||
3.e. If IsConstructor(_C_) is *true*, then
|
||||
i. Let _A_ be ? Construct(_C_).
|
||||
features: [Array.fromAsync]
|
||||
flags: [async]
|
||||
includes: [asyncHelpers.js]
|
||||
---*/
|
||||
|
||||
asyncTest(async function () {
|
||||
const promise = Array.fromAsync([0, 1, 2]);
|
||||
const array = await promise;
|
||||
assert(Array.isArray(array), "Array.fromAsync returns a Promise that resolves to an Array");
|
||||
});
|
|
@ -0,0 +1,35 @@
|
|||
// 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 returns a Promise
|
||||
info: |
|
||||
5. Return _promiseCapability_.[[Promise]].
|
||||
flags: [async]
|
||||
includes: [asyncHelpers.js]
|
||||
features: [Array.fromAsync]
|
||||
---*/
|
||||
|
||||
asyncTest(async function () {
|
||||
let p = Array.fromAsync([0, 1, 2]);
|
||||
|
||||
assert(p instanceof Promise, "Array.fromAsync returns a Promise");
|
||||
assert.sameValue(
|
||||
Object.getPrototypeOf(p),
|
||||
Promise.prototype,
|
||||
"Array.fromAsync returns an object with prototype Promise.prototype"
|
||||
);
|
||||
|
||||
p = Array.fromAsync([0, 1, 2], () => {
|
||||
throw new Test262Error("this will make the Promise reject");
|
||||
})
|
||||
assert(p instanceof Promise, "Array.fromAsync returns a Promise even on error");
|
||||
assert.sameValue(
|
||||
Object.getPrototypeOf(p),
|
||||
Promise.prototype,
|
||||
"Array.fromAsync returns an object with prototype Promise.prototype even on error"
|
||||
);
|
||||
|
||||
await assert.throwsAsync(Test262Error, () => p, "Prevent unhandled rejection");
|
||||
});
|
|
@ -0,0 +1,75 @@
|
|||
// 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: >
|
||||
Order of user-observable operations on a custom this-value and its instances
|
||||
includes: [compareArray.js, asyncHelpers.js]
|
||||
flags: [async]
|
||||
features: [Array.fromAsync]
|
||||
---*/
|
||||
|
||||
function formatPropertyName(propertyKey, objectName = "") {
|
||||
switch (typeof propertyKey) {
|
||||
case "symbol":
|
||||
if (Symbol.keyFor(propertyKey) !== undefined) {
|
||||
return `${objectName}[Symbol.for('${Symbol.keyFor(propertyKey)}')]`;
|
||||
} else if (propertyKey.description.startsWith('Symbol.')) {
|
||||
return `${objectName}[${propertyKey.description}]`;
|
||||
} else {
|
||||
return `${objectName}[Symbol('${propertyKey.description}')]`
|
||||
}
|
||||
case "string":
|
||||
if (propertyKey !== String(Number(propertyKey)))
|
||||
return objectName ? `${objectName}.${propertyKey}` : propertyKey;
|
||||
// fall through
|
||||
default:
|
||||
// integer or string integer-index
|
||||
return `${objectName}[${propertyKey}]`;
|
||||
}
|
||||
}
|
||||
|
||||
asyncTest(async function () {
|
||||
const expectedCalls = [
|
||||
"construct MyArray",
|
||||
"defineProperty A[0]",
|
||||
"defineProperty A[1]",
|
||||
"set A.length"
|
||||
];
|
||||
const actualCalls = [];
|
||||
|
||||
function MyArray(...args) {
|
||||
actualCalls.push("construct MyArray");
|
||||
return new Proxy(Object.create(null), {
|
||||
set(target, key, value) {
|
||||
actualCalls.push(`set ${formatPropertyName(key, "A")}`);
|
||||
return Reflect.set(target, key, value);
|
||||
},
|
||||
defineProperty(target, key, descriptor) {
|
||||
actualCalls.push(`defineProperty ${formatPropertyName(key, "A")}`);
|
||||
return Reflect.defineProperty(target, key, descriptor);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let result = await Array.fromAsync.call(MyArray, [1, 2]);
|
||||
assert.compareArray(expectedCalls, actualCalls, "order of operations for array argument");
|
||||
|
||||
actualCalls.splice(0); // reset
|
||||
|
||||
// Note https://github.com/tc39/proposal-array-from-async/issues/35
|
||||
const expectedCallsForArrayLike = [
|
||||
"construct MyArray",
|
||||
"construct MyArray",
|
||||
"defineProperty A[0]",
|
||||
"defineProperty A[1]",
|
||||
"set A.length"
|
||||
];
|
||||
result = await Array.fromAsync.call(MyArray, {
|
||||
length: 2,
|
||||
0: 1,
|
||||
1: 2
|
||||
});
|
||||
assert.compareArray(expectedCallsForArrayLike, actualCalls, "order of operations for array-like argument");
|
||||
});
|
|
@ -0,0 +1,33 @@
|
|||
// 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: >
|
||||
Rejects the promise if setting the length fails on an instance of a custom
|
||||
this-value
|
||||
info: |
|
||||
3.j.ii.4.a. Perform ? Set(_A_, *"length"*, 𝔽(_k_), *true*).
|
||||
...
|
||||
3.k.viii. Perform ? Set(_A_, *"length"*, 𝔽(_len_), *true*)
|
||||
includes: [asyncHelpers.js]
|
||||
flags: [async]
|
||||
features: [Array.fromAsync]
|
||||
---*/
|
||||
|
||||
asyncTest(async function () {
|
||||
class MyArray {
|
||||
set length(v) {
|
||||
throw new Test262Error("setter of length property throws")
|
||||
}
|
||||
}
|
||||
|
||||
await assert.throwsAsync(Test262Error, () => Array.fromAsync.call(MyArray, [0, 1, 2]), "Promise rejected if setting length fails");
|
||||
|
||||
await assert.throwsAsync(Test262Error, () => Array.fromAsync.call(MyArray, {
|
||||
length: 3,
|
||||
0: 0,
|
||||
1: 1,
|
||||
2: 2
|
||||
}), "Promise rejected if setting length from array-like fails");
|
||||
});
|
|
@ -0,0 +1,50 @@
|
|||
// 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: >
|
||||
Overwrites non-writable element properties on an instance of a custom
|
||||
this-value
|
||||
info: |
|
||||
3.j.ii.8. Let _defineStatus_ be CreateDataPropertyOrThrow(_A_, _Pk_, _mappedValue_).
|
||||
...
|
||||
3.k.vii.6. Perform ? CreateDataPropertyOrThrow(_A_, _Pk_, _mappedValue_).
|
||||
includes: [asyncHelpers.js]
|
||||
flags: [async]
|
||||
features: [Array.fromAsync]
|
||||
---*/
|
||||
|
||||
asyncTest(async function () {
|
||||
function MyArray() {
|
||||
this.length = 4;
|
||||
for (let ix = 0; ix < this.length; ix++) {
|
||||
Object.defineProperty(this, ix, {
|
||||
enumerable: true,
|
||||
writable: false,
|
||||
configurable: true,
|
||||
value: 99
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let result = await Array.fromAsync.call(MyArray, [0, 1, 2]);
|
||||
assert.sameValue(result.length, 3, "Length property is overwritten");
|
||||
assert.sameValue(result[0], 0, "Read-only element 0 is overwritten");
|
||||
assert.sameValue(result[1], 1, "Read-only element 1 is overwritten");
|
||||
assert.sameValue(result[2], 2, "Read-only element 2 is overwritten");
|
||||
assert.sameValue(result[3], 99, "Element 3 is not overwritten");
|
||||
|
||||
result = await Array.fromAsync.call(MyArray, {
|
||||
length: 3,
|
||||
0: 0,
|
||||
1: 1,
|
||||
2: 2,
|
||||
3: 3 // ignored
|
||||
});
|
||||
assert.sameValue(result.length, 3, "Length property is overwritten");
|
||||
assert.sameValue(result[0], 0, "Read-only element 0 is overwritten");
|
||||
assert.sameValue(result[1], 1, "Read-only element 1 is overwritten");
|
||||
assert.sameValue(result[2], 2, "Read-only element 2 is overwritten");
|
||||
assert.sameValue(result[3], 99, "Element 3 is not overwritten");
|
||||
});
|
|
@ -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: >
|
||||
Promise is rejected if length property on an instance of a custom this-value
|
||||
is non-writable
|
||||
info: |
|
||||
3.j.ii.4.a. Perform ? Set(_A_, *"length"*, 𝔽(_k_), *true*).
|
||||
...
|
||||
3.k.viii. Perform ? Set(_A_, *"length"*, 𝔽(_len_), *true*).
|
||||
|
||||
Note that there is no difference between strict mode and sloppy mode, because
|
||||
we are not following runtime evaluation semantics.
|
||||
includes: [asyncHelpers.js]
|
||||
flags: [async]
|
||||
features: [Array.fromAsync]
|
||||
---*/
|
||||
|
||||
asyncTest(async function () {
|
||||
function MyArray() {
|
||||
Object.defineProperty(this, "length", {
|
||||
enumerable: true,
|
||||
writable: false,
|
||||
configurable: true,
|
||||
value: 99
|
||||
});
|
||||
}
|
||||
|
||||
await assert.throwsAsync(TypeError, () => Array.fromAsync.call(MyArray, [0, 1, 2]), "Setting read-only length fails");
|
||||
await assert.throwsAsync(TypeError, () => Array.fromAsync.call(MyArray, {
|
||||
length: 3,
|
||||
0: 0,
|
||||
1: 1,
|
||||
2: 2
|
||||
}), "Setting read-only length fails in array-like case");
|
||||
});
|
|
@ -0,0 +1,43 @@
|
|||
// 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: >
|
||||
Closes an async iterator if setting an element fails on an instance of a
|
||||
custom this-value
|
||||
info: |
|
||||
3.j.ii.8. Let _defineStatus_ be CreateDataPropertyOrThrow(_A_, _Pk_, _mappedValue_).
|
||||
9. If _defineStatus_ is an abrupt completion, return ? AsyncIteratorClose(_iteratorRecord_, _defineStatus_).
|
||||
includes: [asyncHelpers.js]
|
||||
flags: [async]
|
||||
features: [Array.fromAsync]
|
||||
---*/
|
||||
|
||||
asyncTest(async function () {
|
||||
function MyArray() {
|
||||
Object.defineProperty(this, 0, {
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
configurable: false,
|
||||
value: 0
|
||||
});
|
||||
}
|
||||
|
||||
let closed = false;
|
||||
const iterator = {
|
||||
next() {
|
||||
return Promise.resolve({ value: 1, done: false });
|
||||
},
|
||||
return() {
|
||||
closed = true;
|
||||
return Promise.resolve({ done: true });
|
||||
},
|
||||
[Symbol.asyncIterator]() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
await assert.throwsAsync(TypeError, () => Array.fromAsync.call(MyArray, iterator), "Promise rejected if defining element fails");
|
||||
assert(closed, "element define failure should close iterator");
|
||||
});
|
|
@ -0,0 +1,43 @@
|
|||
// 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: >
|
||||
Closes a sync iterator if setting an element fails on an instance of a custom
|
||||
this-value
|
||||
info: |
|
||||
3.j.ii.8. Let _defineStatus_ be CreateDataPropertyOrThrow(_A_, _Pk_, _mappedValue_).
|
||||
9. If _defineStatus_ is an abrupt completion, return ? AsyncIteratorClose(_iteratorRecord_, _defineStatus_).
|
||||
includes: [asyncHelpers.js]
|
||||
flags: [async]
|
||||
features: [Array.fromAsync]
|
||||
---*/
|
||||
|
||||
asyncTest(async function () {
|
||||
function MyArray() {
|
||||
Object.defineProperty(this, 0, {
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
configurable: false,
|
||||
value: 0
|
||||
});
|
||||
}
|
||||
|
||||
let closed = false;
|
||||
const iterator = {
|
||||
next() {
|
||||
return { value: 1, done: false };
|
||||
},
|
||||
return() {
|
||||
closed = true;
|
||||
return { done: true };
|
||||
},
|
||||
[Symbol.iterator]() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
await assert.throwsAsync(TypeError, () => Array.fromAsync.call(MyArray, iterator), "Promise rejected if defining element fails");
|
||||
assert(closed, "element define failure should close iterator");
|
||||
});
|
|
@ -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: >
|
||||
Rejects the promise if setting an element fails on an instance of a custom
|
||||
this-value
|
||||
info: |
|
||||
3.j.ii.8. Let _defineStatus_ be CreateDataPropertyOrThrow(_A_, _Pk_, _mappedValue_).
|
||||
9. If _defineStatus_ is an abrupt completion, return ? AsyncIteratorClose(_iteratorRecord_, _defineStatus_).
|
||||
includes: [asyncHelpers.js]
|
||||
flags: [async]
|
||||
features: [Array.fromAsync]
|
||||
---*/
|
||||
|
||||
asyncTest(async function () {
|
||||
function MyArray() {
|
||||
Object.defineProperty(this, 0, {
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
configurable: false,
|
||||
value: 0
|
||||
});
|
||||
}
|
||||
|
||||
await assert.throwsAsync(TypeError, () => Array.fromAsync.call(MyArray, [0, 1, 2]), "Promise rejected if defining element fails");
|
||||
});
|
|
@ -0,0 +1,53 @@
|
|||
// 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: >
|
||||
Constructs the this-value once if asyncItems is iterable, twice if not, and
|
||||
length and element properties are set correctly on the result
|
||||
info: |
|
||||
3.e. If IsConstructor(_C_) is *true*, then
|
||||
i. Let _A_ be ? Construct(_C_).
|
||||
...
|
||||
j. If _iteratorRecord_ is not *undefined*, then
|
||||
...
|
||||
k. Else,
|
||||
...
|
||||
iv. If IsConstructor(_C_) is *true*, then
|
||||
1. Let _A_ be ? Construct(_C_, « 𝔽(_len_) »).
|
||||
includes: [compareArray.js, asyncHelpers.js]
|
||||
flags: [async]
|
||||
features: [Array.fromAsync]
|
||||
---*/
|
||||
|
||||
asyncTest(async function () {
|
||||
const constructorCalls = [];
|
||||
|
||||
function MyArray(...args) {
|
||||
constructorCalls.push(args);
|
||||
}
|
||||
|
||||
let result = await Array.fromAsync.call(MyArray, [1, 2]);
|
||||
assert(result instanceof MyArray, "result is an instance of the constructor this-value");
|
||||
assert.sameValue(result.length, 2, "length is set on result");
|
||||
assert.sameValue(result[0], 1, "element 0 is set on result");
|
||||
assert.sameValue(result[1], 2, "element 1 is set on result");
|
||||
assert.sameValue(constructorCalls.length, 1, "constructor is called once");
|
||||
assert.compareArray(constructorCalls[0], [], "constructor is called with no arguments");
|
||||
|
||||
constructorCalls.splice(0); // reset
|
||||
|
||||
result = await Array.fromAsync.call(MyArray, {
|
||||
length: 2,
|
||||
0: 1,
|
||||
1: 2
|
||||
});
|
||||
assert(result instanceof MyArray, "result is an instance of the constructor this-value");
|
||||
assert.sameValue(result.length, 2, "length is set on result");
|
||||
assert.sameValue(result[0], 1, "element 0 is set on result");
|
||||
assert.sameValue(result[1], 2, "element 1 is set on result");
|
||||
assert.sameValue(constructorCalls.length, 2, "constructor is called twice");
|
||||
assert.compareArray(constructorCalls[0], [], "constructor is called first with no arguments");
|
||||
assert.compareArray(constructorCalls[1], [2], "constructor is called second with a length argument");
|
||||
});
|
|
@ -0,0 +1,48 @@
|
|||
// 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: >
|
||||
Constructs an intrinsic Array if this-value is not a constructor, and length
|
||||
and element properties are set accordingly.
|
||||
info: |
|
||||
3.e. If IsConstructor(_C_) is *true*, then
|
||||
...
|
||||
f. Else,
|
||||
i. Let _A_ be ! ArrayCreate(0).
|
||||
|
||||
...
|
||||
j. If _iteratorRecord_ is not *undefined*, then
|
||||
...
|
||||
k. Else,
|
||||
...
|
||||
iv. If IsConstructor(_C_) is *true*, then
|
||||
...
|
||||
v. Else,
|
||||
1. Let _A_ be ? ArrayCreate(_len_).
|
||||
includes: [compareArray.js, asyncHelpers.js]
|
||||
flags: [async]
|
||||
features: [Array.fromAsync]
|
||||
---*/
|
||||
|
||||
asyncTest(async function () {
|
||||
const thisValue = {
|
||||
length: 4000,
|
||||
0: 32,
|
||||
1: 64,
|
||||
2: 128
|
||||
};
|
||||
|
||||
let result = await Array.fromAsync.call(thisValue, [1, 2]);
|
||||
assert(Array.isArray(result), "result is an intrinsic Array");
|
||||
assert.compareArray(result, [1, 2], "result is not disrupted by properties of this-value");
|
||||
|
||||
result = await Array.fromAsync.call(thisValue, {
|
||||
length: 2,
|
||||
0: 1,
|
||||
1: 2
|
||||
});
|
||||
assert(Array.isArray(result), "result is an intrinsic Array");
|
||||
assert.compareArray(result, [1, 2], "result is not disrupted by properties of this-value");
|
||||
});
|
Loading…
Reference in New Issue