blob: 30fdfa5489035ea4495dc1ce18d93dabe380460c [file] [edit]
function shouldBe(actual, expected) {
if (actual !== expected)
throw new Error("bad value: " + String(actual) + ", expected " + String(expected));
}
function arrayEq(a, b) {
if (a.length !== b.length)
return false;
for (let i = 0; i < a.length; i++) {
if (a[i] !== b[i])
return false;
}
return true;
}
// All indexing type combinations across receiver and multiple arguments.
for (let i = 0; i < testLoopCount; i++) {
shouldBe([].concat([1, 2], [3, 4]).join(","), "1,2,3,4");
shouldBe([0].concat([1, 2], [3], [4, 5, 6]).join(","), "0,1,2,3,4,5,6");
shouldBe([1, 2].concat([1.5, 2.5], [3, 4]).join(","), "1,2,1.5,2.5,3,4");
shouldBe([0.5].concat([1.5], [2.5, 3.5]).join(","), "0.5,1.5,2.5,3.5");
shouldBe(["a"].concat([1, 2], [1.5]).join(","), "a,1,2,1.5");
shouldBe(["a", "b"].concat(["c"], [1, 2]).join(","), "a,b,c,1,2");
shouldBe([].concat([], []).length, 0);
shouldBe([].concat([], [1], []).join(","), "1");
}
// Undecided (allocated but unset) arrays as sources.
for (let i = 0; i < testLoopCount; i++) {
let und = new Array(2);
let r = [1].concat(und, [2]);
shouldBe(r.length, 4);
shouldBe(1 in r, false);
shouldBe(2 in r, false);
shouldBe(r[3], 2);
r = [].concat(new Array(3), new Array(2));
shouldBe(r.length, 5);
shouldBe(0 in r, false);
}
// Self concat only reads the sources.
for (let i = 0; i < testLoopCount; i++) {
let s = [1, 2];
shouldBe(s.concat(s, s).join(","), "1,2,1,2,1,2");
shouldBe(s.length, 2);
}
// The result must not share storage with any (copy-on-write) source.
for (let i = 0; i < testLoopCount; i++) {
let a = [1, 2, 3];
let r = [].concat(a, [4]);
r[0] = 99;
shouldBe(a[0], 1);
let r2 = [].concat(a, []);
r2[1] = 88;
shouldBe(a[1], 2);
}
// Many arguments.
{
let args = [];
let expected = [];
for (let i = 0; i < 64; i++) {
args.push([i, i + 0.5]);
expected.push(i, i + 0.5);
}
for (let i = 0; i < testLoopCount; i++) {
let r = Array.prototype.concat.apply([], args);
if (!arrayEq(r, expected))
throw new Error("bad many-args result");
}
}
// Total size crossing the sparse array threshold must still produce a correct result.
{
let big1 = new Array(50000).fill(1);
let big2 = new Array(60000).fill(2);
let r = [].concat(big1, big2, [3]);
shouldBe(r.length, 110001);
shouldBe(r[0], 1);
shouldBe(r[49999], 1);
shouldBe(r[50000], 2);
shouldBe(r[109999], 2);
shouldBe(r[110000], 3);
}