123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367 |
- package goja
- import (
- "testing"
- )
- func TestArrayProtoProp(t *testing.T) {
- const SCRIPT = `
- Object.defineProperty(Array.prototype, '0', {value: 42, configurable: true, writable: false})
- var a = []
- a[0] = 1
- a[0]
- `
- testScript(SCRIPT, valueInt(42), t)
- }
- func TestArrayDelete(t *testing.T) {
- const SCRIPT = `
- var a = [1, 2];
- var deleted = delete a[0];
- var undef = a[0] === undefined;
- var len = a.length;
- deleted && undef && len === 2;
- `
- testScript(SCRIPT, valueTrue, t)
- }
- func TestArrayDeleteNonexisting(t *testing.T) {
- const SCRIPT = `
- Array.prototype[0] = 42;
- var a = [];
- delete a[0] && a[0] === 42;
- `
- testScript(SCRIPT, valueTrue, t)
- }
- func TestArraySetLength(t *testing.T) {
- const SCRIPT = `
- var a = [1, 2];
- var assert0 = a.length == 2;
- a.length = "1";
- a.length = 1.0;
- a.length = 1;
- var assert1 = a.length == 1;
- a.length = 2;
- var assert2 = a.length == 2;
- assert0 && assert1 && assert2 && a[1] === undefined;
- `
- testScript(SCRIPT, valueTrue, t)
- }
- func TestArrayReverseNonOptimisable(t *testing.T) {
- const SCRIPT = `
- var a = [];
- Object.defineProperty(a, "0", {get: function() {return 42}, set: function(v) {Object.defineProperty(a, "0", {value: v + 1, writable: true, configurable: true})}, configurable: true})
- a[1] = 43;
- a.reverse();
- a.length === 2 && a[0] === 44 && a[1] === 42;
- `
- testScript(SCRIPT, valueTrue, t)
- }
- func TestArrayPushNonOptimisable(t *testing.T) {
- const SCRIPT = `
- Object.defineProperty(Object.prototype, "0", {value: 42});
- var a = [];
- var thrown = false;
- try {
- a.push(1);
- } catch (e) {
- thrown = e instanceof TypeError;
- }
- thrown;
- `
- testScript(SCRIPT, valueTrue, t)
- }
- func TestArraySetLengthWithPropItems(t *testing.T) {
- const SCRIPT = `
- var a = [1,2,3,4];
- var thrown = false;
- Object.defineProperty(a, "2", {value: 42, configurable: false, writable: false});
- try {
- Object.defineProperty(a, "length", {value: 0, writable: false});
- } catch (e) {
- thrown = e instanceof TypeError;
- }
- thrown && a.length === 3;
- `
- testScript(SCRIPT, valueTrue, t)
- }
- func TestArrayFrom(t *testing.T) {
- const SCRIPT = `
- function checkDestHoles(dest, prefix) {
- assert(dest !== source, prefix + ": dest !== source");
- assert.sameValue(dest.length, 3, prefix + ": dest.length");
- assert.sameValue(dest[0], 1, prefix + ": [0]");
- assert.sameValue(dest[1], undefined, prefix + ": [1]");
- assert(dest.hasOwnProperty("1"), prefix + ': hasOwnProperty("1")');
- assert.sameValue(dest[2], 3, prefix + ": [2]");
- }
- function checkDest(dest, prefix) {
- assert(dest !== source, prefix + ": dest !== source");
- assert.sameValue(dest.length, 3, prefix + ": dest.length");
- assert.sameValue(dest[0], 1, prefix + ": [0]");
- assert.sameValue(dest[1], 2, prefix + ": [1]");
- assert.sameValue(dest[2], 3, prefix + ": [2]");
- }
- var source = [1,2,3];
- var srcHoles = [1,,3];
- checkDest(Array.from(source), "std source/std dest");
- checkDestHoles(Array.from(srcHoles), "std source (holes)/std dest");
- function Iter() {
- this.idx = 0;
- }
- Iter.prototype.next = function() {
- if (this.idx < source.length) {
- return {value: source[this.idx++]};
- } else {
- return {done: true};
- }
- }
- var src = {};
- src[Symbol.iterator] = function() {
- return new Iter();
- }
- checkDest(Array.from(src), "iter src/std dest");
- src = {0: 1, 2: 3, length: 3};
- checkDestHoles(Array.from(src), "arrayLike src/std dest");
- function A() {}
- A.from = Array.from;
- checkDest(A.from(source), "std src/cust dest");
- checkDestHoles(A.from(srcHoles), "std src (holes)/cust dest");
- checkDestHoles(A.from(src), "arrayLike src/cust dest");
- function T2() {
- Object.defineProperty(this, 0, {
- configurable: false,
- writable: true,
- enumerable: true
- });
- }
- assert.throws(TypeError, function() {
- Array.from.call(T2, source);
- });
- `
- testScriptWithTestLib(SCRIPT, _undefined, t)
- }
- func TestArrayOf(t *testing.T) {
- const SCRIPT = `
- function T1() {
- Object.preventExtensions(this);
- }
-
- assert.throws(TypeError, function() {
- Array.of.call(T1, 'Bob');
- });
- function T2() {
- Object.defineProperty(this, 0, {
- configurable: false,
- writable: true,
- enumerable: true
- });
- }
-
- assert.throws(TypeError, function() {
- Array.of.call(T2, 'Bob');
- })
- result = Array.of.call(undefined);
- assert(
- result instanceof Array,
- 'this is not a constructor'
- );
- result = Array.of.call(Math.cos);
- assert(
- result instanceof Array,
- 'this is a builtin function with no [[Construct]] slot'
- );
- `
- testScriptWithTestLib(SCRIPT, _undefined, t)
- }
- func TestUnscopables(t *testing.T) {
- const SCRIPT = `
- var keys = [];
- var _length;
- with (Array.prototype) {
- _length = length;
- keys.push('something');
- }
- _length === 0 && keys.length === 1 && keys[0] === "something";
- `
- testScript(SCRIPT, valueTrue, t)
- }
- func TestArraySort(t *testing.T) {
- const SCRIPT = `
- assert.throws(TypeError, function() {
- [1,2].sort(null);
- }, "null compare function");
- assert.throws(TypeError, function() {
- [1,2].sort({});
- }, "non-callable compare function");
- `
- testScriptWithTestLib(SCRIPT, _undefined, t)
- }
- func TestArraySortNonStdArray(t *testing.T) {
- const SCRIPT = `
- const array = [undefined, 'c', /*hole*/, 'b', undefined, /*hole*/, 'a', 'd'];
- Object.defineProperty(array, '2', {
- get() {
- array.pop();
- array.pop();
- return this.foo;
- },
- set(v) {
- this.foo = v;
- }
- });
- array.sort();
- assert.sameValue(array[0], 'b');
- assert.sameValue(array[1], 'c');
- assert.sameValue(array[3], undefined);
- assert.sameValue(array[4], undefined);
- assert.sameValue('5' in array, false);
- assert.sameValue(array.hasOwnProperty('5'), false);
- assert.sameValue(array.length, 6);
- assert.sameValue(array.foo, undefined);
- assert.sameValue(array[2], undefined);
- assert.sameValue(array.length, 4);
- `
- testScriptWithTestLib(SCRIPT, _undefined, t)
- }
- func TestArrayConcat(t *testing.T) {
- const SCRIPT = `
- var concat = Array.prototype.concat;
- var array = [1, 2];
- var sparseArray = [1, , 2];
- var nonSpreadableArray = [1, 2];
- nonSpreadableArray[Symbol.isConcatSpreadable] = false;
- var arrayLike = { 0: 1, 1: 2, length: 2 };
- var spreadableArrayLike = { 0: 1, 1: 2, length: 2 };
- spreadableArrayLike[Symbol.isConcatSpreadable] = true;
- assert(looksNative(concat));
- assert(deepEqual(array.concat(), [1, 2]), '#1');
- assert(deepEqual(sparseArray.concat(), [1, , 2]), '#2');
- assert(deepEqual(nonSpreadableArray.concat(), [[1, 2]]), '#3');
- assert(deepEqual(concat.call(arrayLike), [{ 0: 1, 1: 2, length: 2 }]), '#4');
- assert(deepEqual(concat.call(spreadableArrayLike), [1, 2]), '#5');
- assert(deepEqual([].concat(array), [1, 2]), '#6');
- assert(deepEqual([].concat(sparseArray), [1, , 2]), '#7');
- assert(deepEqual([].concat(nonSpreadableArray), [[1, 2]]), '#8');
- assert(deepEqual([].concat(arrayLike), [{ 0: 1, 1: 2, length: 2 }]), '#9');
- assert(deepEqual([].concat(spreadableArrayLike), [1, 2]), '#10');
- assert(deepEqual(array.concat(sparseArray, nonSpreadableArray, arrayLike, spreadableArrayLike), [
- 1, 2, 1, , 2, [1, 2], { 0: 1, 1: 2, length: 2 }, 1, 2,
- ]), '#11');
- array = [];
- array.constructor = {};
- array.constructor[Symbol.species] = function () {
- return { foo: 1 };
- }
- assert.sameValue(array.concat().foo, 1, '@@species');
- `
- testScriptWithTestLibX(SCRIPT, _undefined, t)
- }
- func TestArrayFlat(t *testing.T) {
- const SCRIPT = `
- var array = [1, [2,3,[4,5,6]], [[[[7,8,9]]]]];
- assert(deepEqual(array.flat(), [1,2,3,[4,5,6],[[[7,8,9]]]]), '#1');
- assert(deepEqual(array.flat(1), [1,2,3,[4,5,6],[[[7,8,9]]]]), '#2');
- assert(deepEqual(array.flat(3), [1,2,3,4,5,6,[7,8,9]]), '#3');
- assert(deepEqual(array.flat(4), [1,2,3,4,5,6,7,8,9]), '#4');
- assert(deepEqual(array.flat(10), [1,2,3,4,5,6,7,8,9]), '#5');
- `
- testScriptWithTestLibX(SCRIPT, _undefined, t)
- }
- func TestArrayFlatMap(t *testing.T) {
- const SCRIPT = `
- var double = function(x) {
- if (isNaN(x)) {
- return x
- }
- return x * 2
- }
- var array = [1, [2,3,[4,5,6]], [[[[7,8,9]]]]];
- assert(deepEqual(array.flatMap(double), [2,2,3,[4,5,6],[[[7,8,9]]]]), '#1');
- `
- testScriptWithTestLibX(SCRIPT, _undefined, t)
- }
- func TestArrayProto(t *testing.T) {
- const SCRIPT = `
- const a = Array.prototype;
- a.push(1, 2, 3, 4, 5);
- assert.sameValue(a.length, 5);
- assert.sameValue(a[0], 1);
- a.length = 3;
- assert.sameValue(a.length, 3);
- assert(compareArray(a, [1, 2, 3]));
- a.shift();
- assert.sameValue(a.length, 2);
- assert(compareArray(a, [2, 3]));
- `
- testScriptWithTestLib(SCRIPT, _undefined, t)
- }
- func TestArrayToSpliced(t *testing.T) {
- const SCRIPT = `
- const a = [1, 2, 3];
- a.push(4)
- assert(compareArray(a, [1, 2, 3, 4]));
- const b = a.toSpliced(2)
- assert(compareArray(a, [1, 2, 3, 4]));
- assert(compareArray(b, [1, 2]));
- a.push(5)
- const c = a.toSpliced(1, 2);
- assert(compareArray(a, [1, 2, 3, 4, 5]));
- assert(compareArray(c, [1, 4, 5]));
- assert(compareArray(a.toSpliced(4, 2, 'a', 'b'), [1, 2, 3, 4, 'a', 'b']));
- assert(compareArray(a, [1, 2, 3, 4, 5]));
- assert(compareArray(a.toSpliced(-2, 2), [1, 2, 3]));
- assert(compareArray(a, [1, 2, 3, 4, 5]));
- assert(compareArray(a.toSpliced(2, 10), [1, 2]));
- assert(compareArray(a, [1, 2, 3, 4, 5]));
- assert(compareArray(a.toSpliced(1, 0, 'a'), [1, 'a', 2, 3, 4, 5]));
- assert(compareArray(a, [1, 2, 3, 4, 5]));
- `
- testScriptWithTestLib(SCRIPT, _undefined, t)
- }
|