mirror of https://github.com/tc39/test262.git
refactor coverage for flatMap
This commit is contained in:
parent
28a46da5c6
commit
258da539bc
|
@ -0,0 +1,68 @@
|
|||
// Copyright (C) 2018 Leo Balter. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.flatMap
|
||||
description: >
|
||||
Does not flatten array-like objects nested into the main array
|
||||
info: |
|
||||
FlattenIntoArray(target, source, sourceLen, start, depth [ , mapperFunction, thisArg ])
|
||||
|
||||
1. Let targetIndex be start.
|
||||
2. Let sourceIndex be 0.
|
||||
3. Repeat, while sourceIndex < sourceLen
|
||||
a. Let P be ! ToString(sourceIndex).
|
||||
b. Let exists be ? HasProperty(source, P).
|
||||
c. If exists is true, then
|
||||
i. Let element be ? Get(source, P).
|
||||
ii. If mapperFunction is present, then
|
||||
1. Assert: thisArg is present.
|
||||
2. Set element to ? Call(mapperFunction, thisArg , « element, sourceIndex, source »).
|
||||
iii. Let shouldFlatten be false.
|
||||
iv. If depth > 0, then
|
||||
1. Set shouldFlatten to ? IsArray(element).
|
||||
v. If shouldFlatten is true, then
|
||||
1. Let elementLen be ? ToLength(? Get(element, "length")).
|
||||
2. Set targetIndex to ? FlattenIntoArray(target, element, elementLen, targetIndex, depth - 1).
|
||||
vi. Else,
|
||||
1. If targetIndex ≥ 253-1, throw a TypeError exception.
|
||||
2. Perform ? CreateDataPropertyOrThrow(target, ! ToString(targetIndex), element).
|
||||
3. Increase targetIndex by 1.
|
||||
includes: [compareArray.js]
|
||||
features: [Array.prototype.flatMap, Int32Array]
|
||||
---*/
|
||||
|
||||
function fn(e) {
|
||||
return e;
|
||||
}
|
||||
|
||||
var obj1 = {
|
||||
length: 1,
|
||||
0: 'a',
|
||||
toString() { return 'obj1'; }
|
||||
};
|
||||
|
||||
var obj2 = new Int32Array(2);
|
||||
|
||||
var obj3 = {
|
||||
get length() { throw "should not even consider the length property" },
|
||||
toString() { return 'obj3'; }
|
||||
};
|
||||
|
||||
var arr = [obj1, obj2, obj3];
|
||||
var actual = arr.flatMap(fn);
|
||||
assert.compareArray(actual, arr, 'returns a similar array');
|
||||
assert.notSameValue(actual, arr, 'not the same array');
|
||||
|
||||
var arrLike = {
|
||||
length: 4,
|
||||
0: obj1,
|
||||
1: obj2,
|
||||
2: obj3,
|
||||
get 3() { return arrLike },
|
||||
toString() { return 'obj4'; }
|
||||
};
|
||||
|
||||
actual = [].flatMap.call(arrLike, fn);
|
||||
assert.compareArray(actual, [obj1, obj2, obj3, arrLike], 'returns a similar array');
|
||||
assert.notSameValue(actual, arrLike, 'not the same object');
|
||||
assert.sameValue(Object.getPrototypeOf(actual), Array.prototype);
|
60
test/built-ins/Array/prototype/flatMap/array-like-objects-poisoned-length.js
vendored
Normal file
60
test/built-ins/Array/prototype/flatMap/array-like-objects-poisoned-length.js
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
// Copyright (C) 2018 Leo Balter. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.flatMap
|
||||
description: >
|
||||
Observe abrupt completion in poisoned lengths of array-like objects
|
||||
info: |
|
||||
Array.prototype.flatMap ( mapperFunction [ , thisArg ] )
|
||||
|
||||
1. Let O be ? ToObject(this value).
|
||||
2. Let sourceLen be ? ToLength(? Get(O, "length")).
|
||||
features: [Array.prototype.flatMap, Symbol.toPrimitive]
|
||||
---*/
|
||||
|
||||
assert.sameValue(typeof Array.prototype.flatMap, 'function');
|
||||
|
||||
function fn(e) {
|
||||
return e;
|
||||
}
|
||||
|
||||
var arr = {
|
||||
length: Symbol(),
|
||||
};
|
||||
assert.throws(TypeError, function() {
|
||||
[].flatMap.call(arr, fn);
|
||||
}, 'length is a symbol');
|
||||
|
||||
arr = {
|
||||
get length() { throw new Test262Error() }
|
||||
};
|
||||
assert.throws(Test262Error, function() {
|
||||
[].flatMap.call(arr, fn);
|
||||
}, 'custom get error');
|
||||
|
||||
arr = {
|
||||
length: {
|
||||
valueOf() { throw new Test262Error() }
|
||||
}
|
||||
};
|
||||
assert.throws(Test262Error, function() {
|
||||
[].flatMap.call(arr, fn);
|
||||
}, 'custom valueOf error');
|
||||
|
||||
arr = {
|
||||
length: {
|
||||
toString() { throw new Test262Error() }
|
||||
}
|
||||
};
|
||||
assert.throws(Test262Error, function() {
|
||||
[].flatMap.call(arr, fn);
|
||||
}, 'custom toString error');
|
||||
|
||||
arr = {
|
||||
length: {
|
||||
[Symbol.toPrimitive]() { throw new Test262Error() }
|
||||
}
|
||||
};
|
||||
assert.throws(Test262Error, function() {
|
||||
[].flatMap.call(arr, fn);
|
||||
}, 'custom Symbol.toPrimitive error');
|
|
@ -0,0 +1,50 @@
|
|||
// Copyright (C) 2018 Leo Balter. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.flatMap
|
||||
description: >
|
||||
array-like objects can be flattened (typedArrays)
|
||||
info: |
|
||||
Array.prototype.flatMap ( mapperFunction [ , thisArg ] )
|
||||
|
||||
1. Let O be ? ToObject(this value).
|
||||
2. Let sourceLen be ? ToLength(? Get(O, "length")).
|
||||
...
|
||||
5. Let A be ? ArraySpeciesCreate(O, 0).
|
||||
...
|
||||
|
||||
ArraySpeciesCreate ( originalArray, length )
|
||||
|
||||
3. Let isArray be ? IsArray(originalArray).
|
||||
4. If isArray is false, return ? ArrayCreate(length).
|
||||
5. Let C be ? Get(originalArray, "constructor").
|
||||
includes: [compareArray.js]
|
||||
features: [Array.prototype.flatMap, Int32Array]
|
||||
---*/
|
||||
|
||||
function same(e) {
|
||||
return e;
|
||||
}
|
||||
|
||||
var ta;
|
||||
var actual;
|
||||
|
||||
ta = new Int32Array([1, 0, 42]);
|
||||
|
||||
Object.defineProperty(ta, 'constructor', {
|
||||
get() { throw "it should not object the typedarray ctor"; }
|
||||
});
|
||||
actual = [].flatMap.call(ta, same);
|
||||
assert.compareArray(actual, [1, 0, 42], 'compare returned array');
|
||||
assert.sameValue(Object.getPrototypeOf(actual), Array.prototype, 'returned object is an array #1');
|
||||
assert.sameValue(actual instanceof Int32Array, false, 'returned object is not an instance of Int32Array #1');
|
||||
|
||||
ta = new Int32Array(0);
|
||||
|
||||
Object.defineProperty(ta, 'constructor', {
|
||||
get() { throw "it should not object the typedarray ctor"; }
|
||||
});
|
||||
actual = [].flatMap.call(ta, same);
|
||||
assert.compareArray(actual, [], 'compare returned empty array');
|
||||
assert.sameValue(Object.getPrototypeOf(actual), Array.prototype, 'returned object is an array #2');
|
||||
assert.sameValue(actual instanceof Int32Array, false, 'returned object is not an instance of Int32Array #2');
|
|
@ -3,33 +3,83 @@
|
|||
/*---
|
||||
esid: sec-array.prototype.flatMap
|
||||
description: >
|
||||
array-like objects can be flattened
|
||||
array-like objects can be flattened
|
||||
info: |
|
||||
Array.prototype.flatMap ( mapperFunction [ , thisArg ] )
|
||||
|
||||
1. Let O be ? ToObject(this value).
|
||||
2. Let sourceLen be ? ToLength(? Get(O, "length")).
|
||||
...
|
||||
5. Let A be ? ArraySpeciesCreate(O, 0).
|
||||
...
|
||||
|
||||
ArraySpeciesCreate ( originalArray, length )
|
||||
|
||||
3. Let isArray be ? IsArray(originalArray).
|
||||
4. If isArray is false, return ? ArrayCreate(length).
|
||||
|
||||
FlattenIntoArray(target, source, sourceLen, start, depth [ , mapperFunction, thisArg ])
|
||||
|
||||
1. Let targetIndex be start.
|
||||
2. Let sourceIndex be 0.
|
||||
3. Repeat, while sourceIndex < sourceLen
|
||||
a. Let P be ! ToString(sourceIndex).
|
||||
b. Let exists be ? HasProperty(source, P).
|
||||
c. If exists is true, then
|
||||
...
|
||||
** Skip if property does not exist **
|
||||
includes: [compareArray.js]
|
||||
features: [Array.prototype.flatMap]
|
||||
---*/
|
||||
|
||||
function getArgumentsObject() {
|
||||
return arguments;
|
||||
function fn(e) {
|
||||
return [39, e * 2]; // returns an array to observe it being flattened after
|
||||
}
|
||||
|
||||
function double(e) {
|
||||
return [e * 2];
|
||||
}
|
||||
|
||||
var a = getArgumentsObject(1, 2);
|
||||
var actual = [].flatMap.call(a, double);
|
||||
assert.compareArray(actual, [2, 4], 'arguments objects');
|
||||
var a;
|
||||
var actual;
|
||||
|
||||
a = {
|
||||
length: 1,
|
||||
length: 3,
|
||||
0: 1,
|
||||
// property 1 will be fully skipped
|
||||
2: 21,
|
||||
get 3() { throw 'it should not get this property'; }
|
||||
};
|
||||
actual = [].flatMap.call(a, double);
|
||||
assert.compareArray(actual, [2], 'array-like objects');
|
||||
actual = [].flatMap.call(a, fn);
|
||||
assert.compareArray(actual, [39, 2, 39, 42], 'array-like flattened object, number length');
|
||||
assert.sameValue(Object.getPrototypeOf(actual), Array.prototype, 'returned object is an array #1');
|
||||
|
||||
a = {
|
||||
length: void 0,
|
||||
0: 1,
|
||||
length: undefined,
|
||||
get 0() { throw 'it should not get this property'; },
|
||||
};
|
||||
actual = [].flatMap.call(a, double);
|
||||
actual = [].flatMap.call(a, fn);
|
||||
assert.compareArray(actual, [], 'array-like objects; undefined length');
|
||||
assert.sameValue(Object.getPrototypeOf(actual), Array.prototype, 'returned object is an array #2');
|
||||
|
||||
var called = false;
|
||||
a = {
|
||||
get length() {
|
||||
if (!called) {
|
||||
called = true;
|
||||
return 2;
|
||||
} else {
|
||||
throw 'is should get the length only once';
|
||||
}
|
||||
},
|
||||
0: 21,
|
||||
1: 19.5,
|
||||
get 2() { throw 'it should not get this property'; },
|
||||
};
|
||||
actual = [].flatMap.call(a, fn);
|
||||
assert.compareArray(actual, [39, 42, 39, 39], 'array-like flattened objects; custom get length');
|
||||
assert.sameValue(Object.getPrototypeOf(actual), Array.prototype, 'returned object is an array #3');
|
||||
|
||||
a = {
|
||||
length: 10001,
|
||||
[10000]: 7,
|
||||
};
|
||||
actual = [].flatMap.call(a, fn);
|
||||
assert.compareArray(actual, [39, 14], 'array-like flattened object, long length simulating shallow array');
|
||||
assert.sameValue(Object.getPrototypeOf(actual), Array.prototype, 'returned object is an array #4');
|
||||
|
|
|
@ -3,12 +3,48 @@
|
|||
/*---
|
||||
esid: sec-array.prototype.flatMap
|
||||
description: >
|
||||
non callable argument should throw TypeError Exception
|
||||
features: [Array.prototype.flatMap]
|
||||
non callable argument should throw TypeError Exception
|
||||
info: |
|
||||
Array.prototype.flatMap ( mapperFunction [ , thisArg ] )
|
||||
|
||||
1. Let O be ? ToObject(this value).
|
||||
2. Let sourceLen be ? ToLength(? Get(O, "length")).
|
||||
3. If IsCallable(mapperFunction) is false, throw a TypeError exception.
|
||||
...
|
||||
features: [Array.prototype.flatMap, Symbol]
|
||||
---*/
|
||||
|
||||
assert.sameValue(typeof Array.prototype.flatMap, "function");
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
[].flatMap({});
|
||||
}, 'non callable argument');
|
||||
}, 'non callable argument, object');
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
[].flatMap(0);
|
||||
}, 'non callable argument, number');
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
[].flatMap();
|
||||
}, 'non callable argument, implict undefined');
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
[].flatMap(undefined);
|
||||
}, 'non callable argument, undefined');
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
[].flatMap(null);
|
||||
}, 'non callable argument, null');
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
[].flatMap(false);
|
||||
}, 'non callable argument, boolean');
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
[].flatMap('');
|
||||
}, 'non callable argument, string');
|
||||
|
||||
var s = Symbol();
|
||||
assert.throws(TypeError, function() {
|
||||
[].flatMap(s);
|
||||
}, 'non callable argument, symbol');
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
// Copyright (C) 2018 Shilpi Jain and Michael Ficarra. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.flatMap
|
||||
description: >
|
||||
Behavior when `constructor` property is neither an Object nor undefined
|
||||
- if IsConstructor(C) is false, throw a TypeError exception.
|
||||
features: [Array.prototype.flatMap]
|
||||
---*/
|
||||
|
||||
assert.sameValue(typeof Array.prototype.flatMap, 'function');
|
||||
|
||||
var a = [];
|
||||
a.constructor = null;
|
||||
assert.throws(TypeError, function() {
|
||||
a.flatMap();
|
||||
}, 'null value');
|
||||
|
||||
a = [];
|
||||
a.constructor = 1;
|
||||
assert.throws(TypeError, function() {
|
||||
a.flatMap();
|
||||
}, 'number value');
|
||||
|
||||
a = [];
|
||||
a.constructor = 'string';
|
||||
assert.throws(TypeError, function() {
|
||||
a.flatMap();
|
||||
}, 'string value');
|
||||
|
||||
a = [];
|
||||
a.constructor = true;
|
||||
assert.throws(TypeError, function() {
|
||||
a.flatMap();
|
||||
}, 'boolean value');
|
|
@ -0,0 +1,74 @@
|
|||
// Copyright (C) 2018 Shilpi Jain and Michael Ficarra. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.flatMap
|
||||
description: >
|
||||
Assert behavior if this value has a custom non-object constructor property
|
||||
info: |
|
||||
Array.prototype.flatMap ( mapperFunction [ , thisArg ] )
|
||||
|
||||
1. Let O be ? ToObject(this value).
|
||||
2. Let sourceLen be ? ToLength(? Get(O, "length")).
|
||||
...
|
||||
5. Let A be ? ArraySpeciesCreate(O, 0).
|
||||
...
|
||||
|
||||
ArraySpeciesCreate ( originalArray, length )
|
||||
|
||||
3. Let isArray be ? IsArray(originalArray).
|
||||
4. If isArray is false, return ? ArrayCreate(length).
|
||||
5. Let C be ? Get(originalArray, "constructor").
|
||||
6. If IsConstructor(C) is true, then
|
||||
a. Let thisRealm be the current Realm Record.
|
||||
b. Let realmC be ? GetFunctionRealm(C).
|
||||
c. If thisRealm and realmC are not the same Realm Record, then
|
||||
i. If SameValue(C, realmC.[[Intrinsics]].[[%Array%]]) is true, set C to undefined.
|
||||
7. If Type(C) is Object, then
|
||||
a. Set C to ? Get(C, @@species).
|
||||
b. If C is null, set C to undefined.
|
||||
8. If C is undefined, return ? ArrayCreate(length).
|
||||
9. If IsConstructor(C) is false, throw a TypeError exception.
|
||||
features: [Array.prototype.flatMap, Symbol]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
assert.sameValue(typeof Array.prototype.flatMap, 'function');
|
||||
|
||||
var a = [];
|
||||
var mapperFn = function() {};
|
||||
|
||||
a.constructor = null;
|
||||
assert.throws(TypeError, function() {
|
||||
a.flatMap(mapperFn);
|
||||
}, 'null value');
|
||||
|
||||
a = [];
|
||||
a.constructor = 1;
|
||||
assert.throws(TypeError, function() {
|
||||
a.flatMap(mapperFn);
|
||||
}, 'number value');
|
||||
|
||||
a = [];
|
||||
a.constructor = 'string';
|
||||
assert.throws(TypeError, function() {
|
||||
a.flatMap(mapperFn);
|
||||
}, 'string value');
|
||||
|
||||
a = [];
|
||||
a.constructor = true;
|
||||
assert.throws(TypeError, function() {
|
||||
a.flatMap(mapperFn);
|
||||
}, 'boolean value');
|
||||
|
||||
a = [];
|
||||
a.constructor = Symbol();
|
||||
assert.throws(TypeError, function() {
|
||||
a.flatMap(mapperFn);
|
||||
}, 'symbol value');
|
||||
|
||||
a = [];
|
||||
a.constructor = undefined;
|
||||
var actual = a.flatMap(mapperFn);
|
||||
assert.compareArray(actual, [], 'undefined value does not throw');
|
||||
assert.sameValue(Object.getPrototypeOf(actual), Array.prototype);
|
||||
assert.notSameValue(actual, a, 'returns a new array');
|
129
test/built-ins/Array/prototype/flatMap/this-value-ctor-object-species-bad-throws.js
vendored
Normal file
129
test/built-ins/Array/prototype/flatMap/this-value-ctor-object-species-bad-throws.js
vendored
Normal file
|
@ -0,0 +1,129 @@
|
|||
// Copyright (C) 2018 Leo Balter. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.flatMap
|
||||
description: >
|
||||
Assert behavior if this value has a custom object constructor property species
|
||||
info: |
|
||||
Array.prototype.flatMap ( mapperFunction [ , thisArg ] )
|
||||
|
||||
1. Let O be ? ToObject(this value).
|
||||
2. Let sourceLen be ? ToLength(? Get(O, "length")).
|
||||
...
|
||||
5. Let A be ? ArraySpeciesCreate(O, 0).
|
||||
...
|
||||
|
||||
ArraySpeciesCreate ( originalArray, length )
|
||||
|
||||
3. Let isArray be ? IsArray(originalArray).
|
||||
4. If isArray is false, return ? ArrayCreate(length).
|
||||
5. Let C be ? Get(originalArray, "constructor").
|
||||
6. If IsConstructor(C) is true, then
|
||||
a. Let thisRealm be the current Realm Record.
|
||||
b. Let realmC be ? GetFunctionRealm(C).
|
||||
c. If thisRealm and realmC are not the same Realm Record, then
|
||||
i. If SameValue(C, realmC.[[Intrinsics]].[[%Array%]]) is true, set C to undefined.
|
||||
7. If Type(C) is Object, then
|
||||
a. Set C to ? Get(C, @@species).
|
||||
b. If C is null, set C to undefined.
|
||||
8. If C is undefined, return ? ArrayCreate(length).
|
||||
9. If IsConstructor(C) is false, throw a TypeError exception.
|
||||
10. Return ? Construct(C, « length »).
|
||||
features: [Array.prototype.flatMap, Symbol, Symbol.species]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
assert.sameValue(typeof Array.prototype.flatMap, 'function');
|
||||
|
||||
var arr = [[42, 1], [42, 2]];
|
||||
var mapperFn = function(e) { return e; };
|
||||
|
||||
arr.constructor = {};
|
||||
var actual = arr.flatMap(mapperFn);
|
||||
assert.compareArray(actual, [42, 1, 42, 2], 'undefined species does not throw');
|
||||
assert.sameValue(Object.getPrototypeOf(actual), Array.prototype);
|
||||
|
||||
var called = 0;
|
||||
arr.constructor = {
|
||||
get [Symbol.species]() {
|
||||
called++;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
assert.throws(TypeError, function() {
|
||||
arr.flatMap(mapperFn);
|
||||
}, 'throw TypeError if @@species is a number');
|
||||
assert.sameValue(called, 1, 'got species once');
|
||||
|
||||
called = 0;
|
||||
arr.constructor = {
|
||||
get [Symbol.species]() {
|
||||
called++;
|
||||
return '';
|
||||
}
|
||||
};
|
||||
assert.throws(TypeError, function() {
|
||||
arr.flatMap(mapperFn);
|
||||
}, 'throw TypeError if @@species is a string');
|
||||
assert.sameValue(called, 1, 'got species once');
|
||||
|
||||
called = 0;
|
||||
arr.constructor = {
|
||||
get [Symbol.species]() {
|
||||
called++;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
assert.throws(TypeError, function() {
|
||||
arr.flatMap(mapperFn);
|
||||
}, 'throw TypeError if @@species is a boolean');
|
||||
assert.sameValue(called, 1, 'got species once');
|
||||
|
||||
called = 0;
|
||||
arr.constructor = {
|
||||
get [Symbol.species]() {
|
||||
called++;
|
||||
return {};
|
||||
}
|
||||
};
|
||||
assert.throws(TypeError, function() {
|
||||
arr.flatMap(mapperFn);
|
||||
}, 'throw TypeError if @@species is an object');
|
||||
assert.sameValue(called, 1, 'got species once');
|
||||
|
||||
called = 0;
|
||||
arr.constructor = {
|
||||
get [Symbol.species]() {
|
||||
called++;
|
||||
return [];
|
||||
}
|
||||
};
|
||||
assert.throws(TypeError, function() {
|
||||
arr.flatMap(mapperFn);
|
||||
}, 'throw TypeError if @@species is an array');
|
||||
assert.sameValue(called, 1, 'got species once');
|
||||
|
||||
called = 0;
|
||||
arr.constructor = {
|
||||
get [Symbol.species]() {
|
||||
called++;
|
||||
return Symbol();
|
||||
}
|
||||
};
|
||||
assert.throws(TypeError, function() {
|
||||
arr.flatMap(mapperFn);
|
||||
}, 'throw TypeError if @@species is a symbol');
|
||||
assert.sameValue(called, 1, 'got species once');
|
||||
|
||||
called = 0;
|
||||
arr.constructor = {
|
||||
get [Symbol.species]() {
|
||||
called++;
|
||||
throw new Test262Error
|
||||
}
|
||||
};
|
||||
assert.throws(Test262Error, function() {
|
||||
arr.flatMap(mapperFn);
|
||||
}, 'Return abrupt completion from getting the @@species');
|
||||
assert.sameValue(called, 1, 'got species once');
|
|
@ -0,0 +1,58 @@
|
|||
// Copyright (C) 2018 Leo Balter. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.flatMap
|
||||
description: >
|
||||
Assert behavior if this value has a poisoned custom species constructor
|
||||
info: |
|
||||
Array.prototype.flatMap ( mapperFunction [ , thisArg ] )
|
||||
|
||||
1. Let O be ? ToObject(this value).
|
||||
2. Let sourceLen be ? ToLength(? Get(O, "length")).
|
||||
...
|
||||
5. Let A be ? ArraySpeciesCreate(O, 0).
|
||||
6. Perform ? FlattenIntoArray(A, O, sourceLen, 0, 1, mapperFunction, T).
|
||||
7. Return A.
|
||||
|
||||
ArraySpeciesCreate ( originalArray, length )
|
||||
|
||||
3. Let isArray be ? IsArray(originalArray).
|
||||
4. If isArray is false, return ? ArrayCreate(length).
|
||||
5. Let C be ? Get(originalArray, "constructor").
|
||||
6. If IsConstructor(C) is true, then
|
||||
...
|
||||
7. If Type(C) is Object, then
|
||||
a. Set C to ? Get(C, @@species).
|
||||
b. If C is null, set C to undefined.
|
||||
8. If C is undefined, return ? ArrayCreate(length).
|
||||
9. If IsConstructor(C) is false, throw a TypeError exception.
|
||||
10. Return ? Construct(C, « length »).
|
||||
features: [Array.prototype.flatMap, Symbol, Symbol.species]
|
||||
---*/
|
||||
|
||||
assert.sameValue(typeof Array.prototype.flatMap, 'function');
|
||||
|
||||
var arr = [];
|
||||
var mapperFn = function(e) { return e; };
|
||||
|
||||
var called = 0;
|
||||
var ctorCalled = 0;
|
||||
function ctor(len) {
|
||||
assert.sameValue(new.target, ctor, 'new target is defined');
|
||||
assert.sameValue(len, 0, 'first argument is always 0');
|
||||
ctorCalled++;
|
||||
throw new Test262Error();
|
||||
}
|
||||
|
||||
arr.constructor = {
|
||||
get [Symbol.species]() {
|
||||
called++;
|
||||
return ctor;
|
||||
}
|
||||
};
|
||||
assert.throws(Test262Error, function() {
|
||||
arr.flatMap(mapperFn);
|
||||
}, 'Return abrupt completion from species custom ctor');
|
||||
assert.sameValue(called, 1, 'got species once');
|
||||
assert.sameValue(ctorCalled, 1, 'called custom ctor once');
|
94
test/built-ins/Array/prototype/flatMap/this-value-ctor-object-species-custom-ctor.js
vendored
Normal file
94
test/built-ins/Array/prototype/flatMap/this-value-ctor-object-species-custom-ctor.js
vendored
Normal file
|
@ -0,0 +1,94 @@
|
|||
// Copyright (C) 2018 Leo Balter. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.flatMap
|
||||
description: >
|
||||
Assert behavior if this value has a custom species constructor
|
||||
info: |
|
||||
Array.prototype.flatMap ( mapperFunction [ , thisArg ] )
|
||||
|
||||
1. Let O be ? ToObject(this value).
|
||||
2. Let sourceLen be ? ToLength(? Get(O, "length")).
|
||||
...
|
||||
5. Let A be ? ArraySpeciesCreate(O, 0).
|
||||
6. Perform ? FlattenIntoArray(A, O, sourceLen, 0, 1, mapperFunction, T).
|
||||
7. Return A.
|
||||
|
||||
ArraySpeciesCreate ( originalArray, length )
|
||||
|
||||
3. Let isArray be ? IsArray(originalArray).
|
||||
4. If isArray is false, return ? ArrayCreate(length).
|
||||
5. Let C be ? Get(originalArray, "constructor").
|
||||
6. If IsConstructor(C) is true, then
|
||||
...
|
||||
7. If Type(C) is Object, then
|
||||
a. Set C to ? Get(C, @@species).
|
||||
b. If C is null, set C to undefined.
|
||||
8. If C is undefined, return ? ArrayCreate(length).
|
||||
9. If IsConstructor(C) is false, throw a TypeError exception.
|
||||
10. Return ? Construct(C, « length »).
|
||||
|
||||
FlattenIntoArray(target, source, sourceLen, start, depth [ , mapperFunction, thisArg ])
|
||||
|
||||
3. Repeat, while sourceIndex < sourceLen
|
||||
a. Let P be ! ToString(sourceIndex).
|
||||
b. Let exists be ? HasProperty(source, P).
|
||||
c. If exists is true, then
|
||||
...
|
||||
vi. Else,
|
||||
...
|
||||
2. Perform ? CreateDataPropertyOrThrow(target, ! ToString(targetIndex), element).
|
||||
features: [Array.prototype.flatMap, Symbol, Symbol.species]
|
||||
includes: [propertyHelper.js]
|
||||
---*/
|
||||
|
||||
assert.sameValue(typeof Array.prototype.flatMap, 'function');
|
||||
|
||||
var arr = [[42, 1], [42, 2]];
|
||||
var mapperFn = function(e) { return e; };
|
||||
|
||||
var called = 0;
|
||||
var ctorCalled = 0;
|
||||
function ctor(len) {
|
||||
assert.sameValue(new.target, ctor, 'new target is defined');
|
||||
assert.sameValue(len, 0, 'first argument is always 0');
|
||||
ctorCalled++;
|
||||
}
|
||||
|
||||
arr.constructor = {
|
||||
get [Symbol.species]() {
|
||||
called++;
|
||||
return ctor;
|
||||
}
|
||||
};
|
||||
var actual = arr.flatMap(mapperFn);
|
||||
assert(actual instanceof ctor, 'returned value is an instance of custom ctor');
|
||||
assert.sameValue(called, 1, 'got species once');
|
||||
assert.sameValue(ctorCalled, 1, 'called custom ctor once');
|
||||
|
||||
assert.sameValue(Object.prototype.hasOwnProperty.call(actual, 'length'), false, 'it does not define an own length property');
|
||||
verifyProperty(actual, '0', {
|
||||
configurable: true,
|
||||
writable: true,
|
||||
enumerable: true,
|
||||
value: 42
|
||||
});
|
||||
verifyProperty(actual, '1', {
|
||||
configurable: true,
|
||||
writable: true,
|
||||
enumerable: true,
|
||||
value: 1
|
||||
});
|
||||
verifyProperty(actual, '2', {
|
||||
configurable: true,
|
||||
writable: true,
|
||||
enumerable: true,
|
||||
value: 42
|
||||
});
|
||||
verifyProperty(actual, '3', {
|
||||
configurable: true,
|
||||
writable: true,
|
||||
enumerable: true,
|
||||
value: 2
|
||||
});
|
|
@ -0,0 +1,141 @@
|
|||
// Copyright (C) 2018 Leo Balter. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.flatMap
|
||||
description: >
|
||||
Assert behavior if this value has a custom object constructor property
|
||||
info: |
|
||||
Array.prototype.flatMap ( mapperFunction [ , thisArg ] )
|
||||
|
||||
1. Let O be ? ToObject(this value).
|
||||
2. Let sourceLen be ? ToLength(? Get(O, "length")).
|
||||
...
|
||||
5. Let A be ? ArraySpeciesCreate(O, 0).
|
||||
...
|
||||
|
||||
ArraySpeciesCreate ( originalArray, length )
|
||||
|
||||
3. Let isArray be ? IsArray(originalArray).
|
||||
4. If isArray is false, return ? ArrayCreate(length).
|
||||
5. Let C be ? Get(originalArray, "constructor").
|
||||
6. If IsConstructor(C) is true, then
|
||||
a. Let thisRealm be the current Realm Record.
|
||||
b. Let realmC be ? GetFunctionRealm(C).
|
||||
c. If thisRealm and realmC are not the same Realm Record, then
|
||||
i. If SameValue(C, realmC.[[Intrinsics]].[[%Array%]]) is true, set C to undefined.
|
||||
7. If Type(C) is Object, then
|
||||
a. Set C to ? Get(C, @@species).
|
||||
b. If C is null, set C to undefined.
|
||||
8. If C is undefined, return ? ArrayCreate(length).
|
||||
9. If IsConstructor(C) is false, throw a TypeError exception.
|
||||
10. Return ? Construct(C, « length »).
|
||||
features: [Array.prototype.flatMap, Symbol, Symbol.species]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
assert.sameValue(typeof Array.prototype.flatMap, 'function');
|
||||
|
||||
var arr = [[42, 1], [42, 2]];
|
||||
var mapperFn = function(e) { return e; };
|
||||
|
||||
arr.constructor = {};
|
||||
var actual = arr.flatMap(mapperFn);
|
||||
assert.compareArray(actual, [42, 1, 42, 2], 'undefined species does not throw');
|
||||
assert.sameValue(Object.getPrototypeOf(actual), Array.prototype);
|
||||
|
||||
var called = 0;
|
||||
arr.constructor = {
|
||||
get [Symbol.species]() {
|
||||
called++;
|
||||
return null;
|
||||
}
|
||||
};
|
||||
actual = arr.flatMap(mapperFn);
|
||||
assert.compareArray(actual, [42, 1, 42, 2], 'null species value does not throw');
|
||||
assert.sameValue(Object.getPrototypeOf(actual), Array.prototype);
|
||||
assert.sameValue(called, 1, 'got species once');
|
||||
|
||||
called = 0;
|
||||
arr.constructor = {
|
||||
get [Symbol.species]() {
|
||||
called++;
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
actual = arr.flatMap(mapperFn);
|
||||
assert.compareArray(actual, [42, 1, 42, 2], 'undefined species value does not throw');
|
||||
assert.sameValue(Object.getPrototypeOf(actual), Array.prototype);
|
||||
assert.sameValue(called, 1, 'got species once');
|
||||
|
||||
called = 0;
|
||||
arr.constructor = {
|
||||
get [Symbol.species]() {
|
||||
called++;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
assert.throws(TypeError, function() {
|
||||
arr.flatMap(mapperFn);
|
||||
}, 'throw TypeError if @@species is a number');
|
||||
assert.sameValue(called, 1, 'got species once');
|
||||
|
||||
called = 0;
|
||||
arr.constructor = {
|
||||
get [Symbol.species]() {
|
||||
called++;
|
||||
return '';
|
||||
}
|
||||
};
|
||||
assert.throws(TypeError, function() {
|
||||
arr.flatMap(mapperFn);
|
||||
}, 'throw TypeError if @@species is a string');
|
||||
assert.sameValue(called, 1, 'got species once');
|
||||
|
||||
called = 0;
|
||||
arr.constructor = {
|
||||
get [Symbol.species]() {
|
||||
called++;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
assert.throws(TypeError, function() {
|
||||
arr.flatMap(mapperFn);
|
||||
}, 'throw TypeError if @@species is a boolean');
|
||||
assert.sameValue(called, 1, 'got species once');
|
||||
|
||||
called = 0;
|
||||
arr.constructor = {
|
||||
get [Symbol.species]() {
|
||||
called++;
|
||||
return {};
|
||||
}
|
||||
};
|
||||
assert.throws(TypeError, function() {
|
||||
arr.flatMap(mapperFn);
|
||||
}, 'throw TypeError if @@species is an object');
|
||||
assert.sameValue(called, 1, 'got species once');
|
||||
|
||||
called = 0;
|
||||
arr.constructor = {
|
||||
get [Symbol.species]() {
|
||||
called++;
|
||||
return [];
|
||||
}
|
||||
};
|
||||
assert.throws(TypeError, function() {
|
||||
arr.flatMap(mapperFn);
|
||||
}, 'throw TypeError if @@species is an array');
|
||||
assert.sameValue(called, 1, 'got species once');
|
||||
|
||||
called = 0;
|
||||
arr.constructor = {
|
||||
get [Symbol.species]() {
|
||||
called++;
|
||||
return Symbol();
|
||||
}
|
||||
};
|
||||
assert.throws(TypeError, function() {
|
||||
arr.flatMap(mapperFn);
|
||||
}, 'throw TypeError if @@species is a symbol');
|
||||
assert.sameValue(called, 1, 'got species once');
|
|
@ -3,20 +3,23 @@
|
|||
/*---
|
||||
esid: sec-array.prototype.flatMap
|
||||
description: >
|
||||
null or undefined should throw TypeError Exception
|
||||
Throw a TypeError if this value is null or undefined
|
||||
info: |
|
||||
Array.prototype.flatMap ( mapperFunction [ , thisArg ] )
|
||||
|
||||
1. Let O be ? ToObject(this value).
|
||||
...
|
||||
features: [Array.prototype.flatMap]
|
||||
---*/
|
||||
|
||||
assert.sameValue(typeof Array.prototype.flatMap, 'function');
|
||||
|
||||
var mapperFn = function() {};
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
[].flatMap.call(null);
|
||||
[].flatMap.call(null, mapperFn);
|
||||
}, 'null value');
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
[].flatMap.call();
|
||||
}, 'missing');
|
||||
|
||||
assert.throws(TypeError, function() {
|
||||
[].flatMap.call(void 0);
|
||||
[].flatMap.call(undefined, mapperFn);
|
||||
}, 'undefined');
|
|
@ -5,28 +5,41 @@ esid: sec-array.prototype.flatMap
|
|||
description: >
|
||||
Behavior when thisArg is provided
|
||||
Array.prototype.flatMap ( mapperFunction [ , thisArg ] )
|
||||
includes: [compareArray.js]
|
||||
flags: [onlyStrict]
|
||||
includes: [compareArray.js]
|
||||
features: [Array.prototype.flatMap]
|
||||
---*/
|
||||
|
||||
var a = {};
|
||||
var actual;
|
||||
|
||||
assert(compareArray([1].flatMap(function() {
|
||||
actual = [1].flatMap(function() {
|
||||
return [this];
|
||||
}, "TestString"), ["TestString"]));
|
||||
assert(compareArray([1].flatMap(function() {
|
||||
}, "TestString");
|
||||
assert.compareArray(actual, ["TestString"]);
|
||||
|
||||
actual = [1].flatMap(function() {
|
||||
return [this];
|
||||
}, 1), [1]));
|
||||
assert(compareArray([1].flatMap(function() {
|
||||
}, 1);
|
||||
assert.compareArray(actual, [1]);
|
||||
|
||||
actual = [1].flatMap(function() {
|
||||
return [this];
|
||||
}, null), [null]));
|
||||
assert(compareArray([1].flatMap(function() {
|
||||
}, null);
|
||||
assert.compareArray(actual, [null]);
|
||||
|
||||
actual = [1].flatMap(function() {
|
||||
return [this];
|
||||
}, true), [true]));
|
||||
assert(compareArray([1].flatMap(function() {
|
||||
}, true);
|
||||
assert.compareArray(actual, [true]);
|
||||
|
||||
actual = [1].flatMap(function() {
|
||||
return [this];
|
||||
}, a), [a]));
|
||||
assert(compareArray([1].flatMap(function() {
|
||||
}, a);
|
||||
assert.compareArray(actual, [a]);
|
||||
|
||||
actual = [1].flatMap(function() {
|
||||
return [this];
|
||||
}, void 0), [undefined]));
|
||||
}, void 0);
|
||||
assert.compareArray(actual, [undefined]);
|
||||
|
||||
|
|
Loading…
Reference in New Issue