gristlabs_grist-core/test/common/arraySplice.js
Paul Fitzpatrick bcbf57d590 (core) bump mocha version to allow parallel tests; move more tests to core
Summary:
This uses a newer version of mocha in grist-core so that tests can be run in parallel. That allows more tests to be moved without slowing things down overall. Tests moved are venerable browser tests; only the ones that "just work" or worked without too much trouble to are moved, in order to keep the diff from growing too large. Will wrestle with more in follow up.

Parallelism is at the file level, rather than the individual test.

The newer version of mocha isn't needed for grist-saas repo; tests are parallelized in our internal CI by other means. I've chosen to allocate files to workers in a cruder way than our internal CI, based on initial characters rather than an automated process. The automated process would need some reworking to be compatible with mocha running in parallel mode.

Test Plan: this diff was tested first on grist-core, then ported to grist-saas so saas repo history will correctly track history of moved files.

Reviewers: jarek

Reviewed By: jarek

Subscribers: jarek

Differential Revision: https://phab.getgrist.com/D3927
2023-06-27 02:55:34 -04:00

618 lines
25 KiB
JavaScript

var _ = require('underscore');
var assert = require('chai').assert;
var gutil = require('app/common/gutil');
var utils = require('../utils');
/**
* Set env ENABLE_TIMING_TESTS=1 to run the timing tests.
* These tests rely on mocha's reported timings to allow you to compare the performance of
* different implementations.
*/
var ENABLE_TIMING_TESTS = Boolean(process.env.ENABLE_TIMING_TESTS);
//----------------------------------------------------------------------
// Following recommendations such as here:
// http://stackoverflow.com/questions/7032550/javascript-insert-an-array-inside-another-array
// However, this won't work for large arrToInsert because .apply has a limit on length of args.
function spliceApplyConcat(target, start, arrToInsert) {
target.splice.apply(target, [start, 0].concat(arrToInsert));
return target;
}
//----------------------------------------------------------------------
// Seems like could be faster, but disturbingly mutates the last argument.
// However, this won't work for large arrToInsert because .apply has a limit on length of args.
function spliceApplyUnshift(target, start, arrToInsert) {
var spliceArgs = arrToInsert;
spliceArgs.unshift(start, 0);
try {
target.splice.apply(target, spliceArgs);
} finally {
spliceArgs.splice(0, 2);
}
return target;
}
//----------------------------------------------------------------------
// This is from the same stackoverflow answer, but builds a new array instead of mutating target.
function nonSpliceUsingSlice(target, start, arrToInsert) {
return target.slice(0, start).concat(arrToInsert, target.slice(start));
}
//----------------------------------------------------------------------
// A simple manual implementation, that performs reasonably well in all environments.
function spliceManualWithTailCopy(target, start, arrToInsert) {
var insLen = arrToInsert.length;
if (insLen === 1) {
target.splice(start, 0, arrToInsert[0]);
} else if (insLen > 1) {
var i, len, tail = target.slice(start);
for (i = 0; i < insLen; i++, start++) {
target[start] = arrToInsert[i];
}
for (i = 0, len = tail.length; i < len; i++, start++) {
target[start] = tail[i];
}
}
return target;
}
//----------------------------------------------------------------------
function spliceCopyWithTail(helpers) {
var copyForward = helpers.copyForward;
return function(target, start, arrToInsert) {
var tail = target.slice(start), insLen = arrToInsert.length;
copyForward(target, start, arrToInsert, 0, insLen);
copyForward(target, start + insLen, tail, 0, tail.length);
return target;
};
}
//----------------------------------------------------------------------
// This implementation avoids creating a copy of the tail, but fills in the array
// non-contiguously.
function spliceFwdBackCopy(helpers) {
var copyForward = helpers.copyForward,
copyBackward = helpers.copyBackward;
return function(target, start, arrayToInsert) {
var count = arrayToInsert.length;
copyBackward(target, start + count, target, start, target.length - start);
copyForward(target, start, arrayToInsert, 0, count);
return target;
};
}
//----------------------------------------------------------------------
// This implementation tries to be smarter by avoiding allocations, appending to the array
// contiguously, then filling in the gap.
function spliceAppendCopy(helpers) {
var appendFunc = helpers.append,
copyForward = helpers.copyForward,
copyBackward = helpers.copyBackward;
return function(target, start, arrToInsert) {
var origLen = target.length;
var tailLen = origLen - start;
var insLen = arrToInsert.length;
if (insLen > tailLen) {
appendFunc(target, arrToInsert, tailLen, insLen - tailLen);
appendFunc(target, target, start, tailLen);
copyForward(target, start, arrToInsert, 0, tailLen);
} else {
appendFunc(target, target, origLen - insLen, insLen);
copyBackward(target, start + insLen, target, start, tailLen - insLen);
copyForward(target, start, arrToInsert, 0, insLen);
}
return target;
};
}
//----------------------------------------------------------------------
// This implementation only appends, but requires splicing out the tail from the original.
// It is consistently slower on Node.
function spliceAppendOnly(helpers) {
var appendFunc = helpers.append;
return function(target, start, arrToInsert) {
var tail = target.splice(start, target.length);
appendFunc(target, arrToInsert, 0, arrToInsert.length);
appendFunc(target, tail, 0, tail.length);
return target;
};
}
//----------------------------------------------------------------------
// COPY-FORWARD FUNCTIONS
//----------------------------------------------------------------------
var copyForward = {
gutil: gutil.arrayCopyForward,
copyForward1: function(toArray, toStart, fromArray, fromStart, count) {
for (var end = toStart + count; toStart < end; ++toStart, ++fromStart) {
toArray[toStart] = fromArray[fromStart];
}
},
copyForward8: function(toArray, toStart, fromArray, fromStart, count) {
var end = toStart + count;
for (var xend = end - 7; toStart < xend; fromStart += 8, toStart += 8) {
toArray[toStart] = fromArray[fromStart];
toArray[toStart+1] = fromArray[fromStart+1];
toArray[toStart+2] = fromArray[fromStart+2];
toArray[toStart+3] = fromArray[fromStart+3];
toArray[toStart+4] = fromArray[fromStart+4];
toArray[toStart+5] = fromArray[fromStart+5];
toArray[toStart+6] = fromArray[fromStart+6];
toArray[toStart+7] = fromArray[fromStart+7];
}
for (; toStart < end; ++fromStart, ++toStart) {
toArray[toStart] = fromArray[fromStart];
}
},
copyForward64: function(toArray, toStart, fromArray, fromStart, count) {
var end = toStart + count;
for (var xend = end - 63; toStart < xend; fromStart += 64, toStart += 64) {
toArray[toStart]=fromArray[fromStart]; toArray[toStart+1]=fromArray[fromStart+1];
toArray[toStart+2]=fromArray[fromStart+2]; toArray[toStart+3]=fromArray[fromStart+3];
toArray[toStart+4]=fromArray[fromStart+4]; toArray[toStart+5]=fromArray[fromStart+5];
toArray[toStart+6]=fromArray[fromStart+6]; toArray[toStart+7]=fromArray[fromStart+7];
toArray[toStart+8]=fromArray[fromStart+8]; toArray[toStart+9]=fromArray[fromStart+9];
toArray[toStart+10]=fromArray[fromStart+10]; toArray[toStart+11]=fromArray[fromStart+11];
toArray[toStart+12]=fromArray[fromStart+12]; toArray[toStart+13]=fromArray[fromStart+13];
toArray[toStart+14]=fromArray[fromStart+14]; toArray[toStart+15]=fromArray[fromStart+15];
toArray[toStart+16]=fromArray[fromStart+16]; toArray[toStart+17]=fromArray[fromStart+17];
toArray[toStart+18]=fromArray[fromStart+18]; toArray[toStart+19]=fromArray[fromStart+19];
toArray[toStart+20]=fromArray[fromStart+20]; toArray[toStart+21]=fromArray[fromStart+21];
toArray[toStart+22]=fromArray[fromStart+22]; toArray[toStart+23]=fromArray[fromStart+23];
toArray[toStart+24]=fromArray[fromStart+24]; toArray[toStart+25]=fromArray[fromStart+25];
toArray[toStart+26]=fromArray[fromStart+26]; toArray[toStart+27]=fromArray[fromStart+27];
toArray[toStart+28]=fromArray[fromStart+28]; toArray[toStart+29]=fromArray[fromStart+29];
toArray[toStart+30]=fromArray[fromStart+30]; toArray[toStart+31]=fromArray[fromStart+31];
toArray[toStart+32]=fromArray[fromStart+32]; toArray[toStart+33]=fromArray[fromStart+33];
toArray[toStart+34]=fromArray[fromStart+34]; toArray[toStart+35]=fromArray[fromStart+35];
toArray[toStart+36]=fromArray[fromStart+36]; toArray[toStart+37]=fromArray[fromStart+37];
toArray[toStart+38]=fromArray[fromStart+38]; toArray[toStart+39]=fromArray[fromStart+39];
toArray[toStart+40]=fromArray[fromStart+40]; toArray[toStart+41]=fromArray[fromStart+41];
toArray[toStart+42]=fromArray[fromStart+42]; toArray[toStart+43]=fromArray[fromStart+43];
toArray[toStart+44]=fromArray[fromStart+44]; toArray[toStart+45]=fromArray[fromStart+45];
toArray[toStart+46]=fromArray[fromStart+46]; toArray[toStart+47]=fromArray[fromStart+47];
toArray[toStart+48]=fromArray[fromStart+48]; toArray[toStart+49]=fromArray[fromStart+49];
toArray[toStart+50]=fromArray[fromStart+50]; toArray[toStart+51]=fromArray[fromStart+51];
toArray[toStart+52]=fromArray[fromStart+52]; toArray[toStart+53]=fromArray[fromStart+53];
toArray[toStart+54]=fromArray[fromStart+54]; toArray[toStart+55]=fromArray[fromStart+55];
toArray[toStart+56]=fromArray[fromStart+56]; toArray[toStart+57]=fromArray[fromStart+57];
toArray[toStart+58]=fromArray[fromStart+58]; toArray[toStart+59]=fromArray[fromStart+59];
toArray[toStart+60]=fromArray[fromStart+60]; toArray[toStart+61]=fromArray[fromStart+61];
toArray[toStart+62]=fromArray[fromStart+62]; toArray[toStart+63]=fromArray[fromStart+63];
}
for (; toStart < end; ++fromStart, ++toStart) {
toArray[toStart] = fromArray[fromStart];
}
}
};
//----------------------------------------------------------------------
// COPY-BACKWARD FUNCTIONS
//----------------------------------------------------------------------
var copyBackward = {
gutil: gutil.arrayCopyBackward,
copyBackward1: function(toArray, toStart, fromArray, fromStart, count) {
for (var i = toStart + count - 1, j = fromStart + count - 1; i >= toStart; --i, --j) {
toArray[i] = fromArray[j];
}
},
copyBackward8: function(toArray, toStart, fromArray, fromStart, count) {
var i = toStart + count - 1, j = fromStart + count - 1;
for (var xStart = toStart + 7; i >= xStart; i -= 8, j -= 8) {
toArray[i] = fromArray[j];
toArray[i-1] = fromArray[j-1];
toArray[i-2] = fromArray[j-2];
toArray[i-3] = fromArray[j-3];
toArray[i-4] = fromArray[j-4];
toArray[i-5] = fromArray[j-5];
toArray[i-6] = fromArray[j-6];
toArray[i-7] = fromArray[j-7];
}
for ( ; i >= toStart; --i, --j) {
toArray[i] = fromArray[j];
}
},
copyBackward64: function(toArray, toStart, fromArray, fromStart, count) {
var i = toStart + count - 1, j = fromStart + count - 1;
for (var xStart = toStart + 63; i >= xStart; i -= 64, j -= 64) {
toArray[i]=fromArray[j]; toArray[i-1]=fromArray[j-1];
toArray[i-2]=fromArray[j-2]; toArray[i-3]=fromArray[j-3];
toArray[i-4]=fromArray[j-4]; toArray[i-5]=fromArray[j-5];
toArray[i-6]=fromArray[j-6]; toArray[i-7]=fromArray[j-7];
toArray[i-8]=fromArray[j-8]; toArray[i-9]=fromArray[j-9];
toArray[i-10]=fromArray[j-10]; toArray[i-11]=fromArray[j-11];
toArray[i-12]=fromArray[j-12]; toArray[i-13]=fromArray[j-13];
toArray[i-14]=fromArray[j-14]; toArray[i-15]=fromArray[j-15];
toArray[i-16]=fromArray[j-16]; toArray[i-17]=fromArray[j-17];
toArray[i-18]=fromArray[j-18]; toArray[i-19]=fromArray[j-19];
toArray[i-20]=fromArray[j-20]; toArray[i-21]=fromArray[j-21];
toArray[i-22]=fromArray[j-22]; toArray[i-23]=fromArray[j-23];
toArray[i-24]=fromArray[j-24]; toArray[i-25]=fromArray[j-25];
toArray[i-26]=fromArray[j-26]; toArray[i-27]=fromArray[j-27];
toArray[i-28]=fromArray[j-28]; toArray[i-29]=fromArray[j-29];
toArray[i-30]=fromArray[j-30]; toArray[i-31]=fromArray[j-31];
toArray[i-32]=fromArray[j-32]; toArray[i-33]=fromArray[j-33];
toArray[i-34]=fromArray[j-34]; toArray[i-35]=fromArray[j-35];
toArray[i-36]=fromArray[j-36]; toArray[i-37]=fromArray[j-37];
toArray[i-38]=fromArray[j-38]; toArray[i-39]=fromArray[j-39];
toArray[i-40]=fromArray[j-40]; toArray[i-41]=fromArray[j-41];
toArray[i-42]=fromArray[j-42]; toArray[i-43]=fromArray[j-43];
toArray[i-44]=fromArray[j-44]; toArray[i-45]=fromArray[j-45];
toArray[i-46]=fromArray[j-46]; toArray[i-47]=fromArray[j-47];
toArray[i-48]=fromArray[j-48]; toArray[i-49]=fromArray[j-49];
toArray[i-50]=fromArray[j-50]; toArray[i-51]=fromArray[j-51];
toArray[i-52]=fromArray[j-52]; toArray[i-53]=fromArray[j-53];
toArray[i-54]=fromArray[j-54]; toArray[i-55]=fromArray[j-55];
toArray[i-56]=fromArray[j-56]; toArray[i-57]=fromArray[j-57];
toArray[i-58]=fromArray[j-58]; toArray[i-59]=fromArray[j-59];
toArray[i-60]=fromArray[j-60]; toArray[i-61]=fromArray[j-61];
toArray[i-62]=fromArray[j-62]; toArray[i-63]=fromArray[j-63];
}
for ( ; i >= toStart; --i, --j) {
toArray[i] = fromArray[j];
}
}
};
//----------------------------------------------------------------------
// APPEND FUNCTIONS.
//----------------------------------------------------------------------
var append = {
gutil: gutil.arrayAppend,
append1: function(toArray, fromArray, fromStart, count) {
var end = fromStart + count;
for (var i = fromStart; i < end; i++) {
toArray.push(fromArray[i]);
}
},
appendCopy1: function(toArray, fromArray, fromStart, count) {
if (count === 1) {
toArray.push(fromArray[fromStart]);
} else if (count > 1) {
var len = toArray.length;
toArray.length = len + count;
copyForward.copyForward1(toArray, len, fromArray, fromStart, count);
}
},
append8: function(toArray, fromArray, fromStart, count) {
var end = fromStart + count;
for (var xend = end - 7; fromStart < xend; fromStart += 8) {
toArray.push(
fromArray[fromStart],
fromArray[fromStart + 1],
fromArray[fromStart + 2],
fromArray[fromStart + 3],
fromArray[fromStart + 4],
fromArray[fromStart + 5],
fromArray[fromStart + 6],
fromArray[fromStart + 7]);
}
for ( ; fromStart < end; ++fromStart) {
toArray.push(fromArray[fromStart]);
}
},
append64: function(toArray, fromArray, fromStart, count) {
var end = fromStart + count;
for (var xend = end - 63; fromStart < xend; fromStart += 64) {
toArray.push(
fromArray[fromStart], fromArray[fromStart + 1],
fromArray[fromStart + 2], fromArray[fromStart + 3],
fromArray[fromStart + 4], fromArray[fromStart + 5],
fromArray[fromStart + 6], fromArray[fromStart + 7],
fromArray[fromStart + 8], fromArray[fromStart + 9],
fromArray[fromStart + 10], fromArray[fromStart + 11],
fromArray[fromStart + 12], fromArray[fromStart + 13],
fromArray[fromStart + 14], fromArray[fromStart + 15],
fromArray[fromStart + 16], fromArray[fromStart + 17],
fromArray[fromStart + 18], fromArray[fromStart + 19],
fromArray[fromStart + 20], fromArray[fromStart + 21],
fromArray[fromStart + 22], fromArray[fromStart + 23],
fromArray[fromStart + 24], fromArray[fromStart + 25],
fromArray[fromStart + 26], fromArray[fromStart + 27],
fromArray[fromStart + 28], fromArray[fromStart + 29],
fromArray[fromStart + 30], fromArray[fromStart + 31],
fromArray[fromStart + 32], fromArray[fromStart + 33],
fromArray[fromStart + 34], fromArray[fromStart + 35],
fromArray[fromStart + 36], fromArray[fromStart + 37],
fromArray[fromStart + 38], fromArray[fromStart + 39],
fromArray[fromStart + 40], fromArray[fromStart + 41],
fromArray[fromStart + 42], fromArray[fromStart + 43],
fromArray[fromStart + 44], fromArray[fromStart + 45],
fromArray[fromStart + 46], fromArray[fromStart + 47],
fromArray[fromStart + 48], fromArray[fromStart + 49],
fromArray[fromStart + 50], fromArray[fromStart + 51],
fromArray[fromStart + 52], fromArray[fromStart + 53],
fromArray[fromStart + 54], fromArray[fromStart + 55],
fromArray[fromStart + 56], fromArray[fromStart + 57],
fromArray[fromStart + 58], fromArray[fromStart + 59],
fromArray[fromStart + 60], fromArray[fromStart + 61],
fromArray[fromStart + 62], fromArray[fromStart + 63]
);
}
for ( ; fromStart < end; ++fromStart) {
toArray.push(fromArray[fromStart]);
}
},
appendSlice64: function(toArray, fromArray, fromStart, count) {
var end = fromStart + count;
for ( ; fromStart < end; fromStart += 64) {
Array.prototype.push.apply(toArray, fromArray.slice(fromStart, Math.min(fromStart + 64, end)));
}
}
};
//----------------------------------------------------------------------
var helpers1 = {
copyForward: copyForward.copyForward1,
copyBackward: copyBackward.copyBackward1,
append: append.append1,
};
var helpers8 = {
copyForward: copyForward.copyForward8,
copyBackward: copyBackward.copyBackward8,
append: append.append8,
};
var helpers64 = {
copyForward: copyForward.copyForward64,
copyBackward: copyBackward.copyBackward64,
append: append.append64,
};
var allArraySpliceFuncs = {
spliceApplyConcat: spliceApplyConcat,
spliceApplyUnshift: spliceApplyUnshift,
nonSpliceUsingSlice: nonSpliceUsingSlice,
spliceGutil: gutil.arraySplice,
spliceManualWithTailCopy: spliceManualWithTailCopy,
spliceCopyWithTail1: spliceCopyWithTail(helpers1),
spliceCopyWithTail8: spliceCopyWithTail(helpers8),
spliceCopyWithTail64: spliceCopyWithTail(helpers64),
spliceFwdBackCopy1: spliceFwdBackCopy(helpers1),
spliceFwdBackCopy8: spliceFwdBackCopy(helpers8),
spliceFwdBackCopy64: spliceFwdBackCopy(helpers64),
spliceAppendCopy1: spliceAppendCopy(helpers1),
spliceAppendCopy8: spliceAppendCopy(helpers8),
spliceAppendCopy64: spliceAppendCopy(helpers64),
spliceAppendOnly1: spliceAppendOnly(helpers1),
spliceAppendOnly8: spliceAppendOnly(helpers8),
spliceAppendOnly64: spliceAppendOnly(helpers64),
};
var timedArraySpliceFuncs = {
// The following two naive implementations cannot cope with large arrays, and raise
// "RangeError: Maximum call stack size exceeded".
//spliceApplyConcat: spliceApplyConcat,
//spliceApplyUnshift: spliceApplyUnshift,
// This isn't a real splice, it doesn't modify the array.
//nonSpliceUsingSlice: nonSpliceUsingSlice,
// The implementations commented out below are the slower ones.
spliceGutil: gutil.arraySplice,
spliceManualWithTailCopy: spliceManualWithTailCopy,
spliceCopyWithTail1: spliceCopyWithTail(helpers1),
//spliceCopyWithTail8: spliceCopyWithTail(helpers8),
//spliceCopyWithTail64: spliceCopyWithTail(helpers64),
//spliceFwdBackCopy1: spliceFwdBackCopy(helpers1),
//spliceFwdBackCopy8: spliceFwdBackCopy(helpers8),
//spliceFwdBackCopy64: spliceFwdBackCopy(helpers64),
spliceAppendCopy1: spliceAppendCopy(helpers1),
spliceAppendCopy8: spliceAppendCopy(helpers8),
spliceAppendCopy64: spliceAppendCopy(helpers64),
//spliceAppendOnly1: spliceAppendOnly(helpers1),
//spliceAppendOnly8: spliceAppendOnly(helpers8),
//spliceAppendOnly64: spliceAppendOnly(helpers64),
};
//----------------------------------------------------------------------
describe("array copy functions", function() {
it("copyForward should copy correctly", function() {
_.each(copyForward, function(copyFunc, name) {
var data = _.range(10000);
copyFunc(data, 0, data, 1, 9999);
copyFunc(data, 0, data, 1, 9999);
assert.equal(data[0], 2);
assert.equal(data[1], 3);
assert.equal(data[9996], 9998);
assert.equal(data[9997], 9999);
assert.equal(data[9998], 9999);
assert.equal(data[9999], 9999);
});
});
it("copyBackward should copy correctly", function() {
_.each(copyBackward, function(copyFunc, name) {
var data = _.range(10000);
copyFunc(data, 1, data, 0, 9999);
copyFunc(data, 1, data, 0, 9999);
assert.equal(data[0], 0);
assert.equal(data[1], 0);
assert.equal(data[2], 0);
assert.equal(data[3], 1);
assert.equal(data[9998], 9996);
assert.equal(data[9999], 9997);
});
});
it("arrayAppend should append correctly", function() {
_.each(append, function(appendFunc, name) {
var out = [];
var data = _.range(20000);
appendFunc(out, data, 100, 1);
appendFunc(out, data, 100, 1000);
appendFunc(out, data, 100, 10000);
assert.deepEqual(out.slice(0, 4), [100, 100, 101, 102]);
assert.deepEqual(out.slice(1000, 1004), [1099, 100, 101, 102]);
assert.deepEqual(out.slice(11000), [10099]);
});
});
// See ENABLE_TIMING_TESTS flag on top of this file.
if (ENABLE_TIMING_TESTS) {
describe("timing", function() {
var a1m = _.range(1000000);
describe("copyForward", function() {
var reps = 40;
_.each(copyForward, function(copyFunc, name) {
var b1m = a1m.slice(0);
it(name, function() {
utils.repeat(reps, copyFunc, b1m, 0, b1m, 1, 999999);
// Make sure it actually worked. These checks shouldn't affect timings much.
assert.deepEqual(b1m.slice(0, 10), _.range(reps, reps + 10));
assert.equal(b1m[999999-reps-1], 999998);
assert.equal(b1m[999999-reps], 999999);
assert.deepEqual(b1m.slice(1000000-reps), _.times(reps, _.constant(999999)));
});
});
});
describe("copyBackward", function() {
var reps = 40;
_.each(copyBackward, function(copyFunc, name) {
var b1m = a1m.slice(0);
it(name, function() {
utils.repeat(reps, copyFunc, b1m, 1, b1m, 0, 999999);
// Make sure it actually worked. These checks shouldn't affect timings much.
assert.deepEqual(b1m.slice(0, reps), _.times(reps, _.constant(0)));
assert.equal(b1m[reps], 0);
assert.equal(b1m[reps + 1], 1);
assert.deepEqual(b1m.slice(999990), _.range(999990-reps, 1000000-reps));
});
});
});
describe("append", function() {
var data = _.range(1000000);
function chunkedAppend(appendFunc, data, chunk) {
var out = [];
var count = data.length / chunk;
for (var i = 0; i < count; i++) {
appendFunc(out, data, i * chunk, chunk);
}
return out;
}
_.each(append, function(appendFunc, name) {
it(name, function() {
var out1 = chunkedAppend(appendFunc, data, 1);
var out2 = chunkedAppend(appendFunc, data, 1000);
var out3 = chunkedAppend(appendFunc, data, 1000000);
// Make sure it actually worked. Keep the checks short to avoid affecting timings.
assert.deepEqual(out1.slice(0, 10), data.slice(0, 10));
assert.deepEqual(out1.slice(data.length - 10), data.slice(data.length - 10));
assert.deepEqual(out2.slice(0, 10), data.slice(0, 10));
assert.deepEqual(out2.slice(data.length - 10), data.slice(data.length - 10));
assert.deepEqual(out3.slice(0, 10), data.slice(0, 10));
assert.deepEqual(out3.slice(data.length - 10), data.slice(data.length - 10));
});
});
});
});
}
});
describe('arraySplice', function() {
// Make sure all our functions produce the same results as spliceApplyConcat for simple cases.
var refSpliceFunc = spliceApplyConcat;
it("all candidate functions should be correct for simpler cases", function() {
_.each(allArraySpliceFuncs, function(spliceFunc, name) {
var a10 = _.range(10), a100 = _.range(100);
function checkSpliceFunc(target, start, arrToInsert) {
assert.deepEqual(spliceFunc(target.slice(0), start, arrToInsert),
refSpliceFunc(target.slice(0), start, arrToInsert),
"splice function incorrect for " + name);
}
checkSpliceFunc(a10, 5, a100);
checkSpliceFunc(a100, 50, a10);
checkSpliceFunc(a100, 90, a10);
checkSpliceFunc(a100, 0, a10);
checkSpliceFunc(a100, 100, a10);
checkSpliceFunc(a10, 0, a100);
checkSpliceFunc(a10, 10, a100);
checkSpliceFunc(a10, 1, a10);
checkSpliceFunc(a10, 5, a10);
checkSpliceFunc(a10, 5, []);
assert.deepEqual(spliceFunc(a10.slice(0), 5, a10),
[0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 5, 6, 7, 8, 9]);
});
});
// See ENABLE_TIMING_TESTS flag on top of this file.
if (ENABLE_TIMING_TESTS) {
describe("timing", function() {
var a1 = _.range(1);
var a1k = _.range(1000);
var a1m = _.range(1000000);
describe("insert-one", function() {
_.each(timedArraySpliceFuncs, function(spliceFunc, name) {
var b1m = a1m.slice(0);
it(name, function() {
utils.repeat(40, spliceFunc, b1m, 500000, a1);
});
});
});
describe("insert-1k", function() {
_.each(timedArraySpliceFuncs, function(spliceFunc, name) {
var b1m = a1m.slice(0);
it(name, function() {
utils.repeat(40, spliceFunc, b1m, 500000, a1k);
});
});
});
describe("insert-1m", function() {
_.each(timedArraySpliceFuncs, function(spliceFunc, name) {
var b1m = a1m.slice(0);
it(name, function() {
utils.repeat(4, spliceFunc, b1m, 500000, a1m);
});
});
});
});
}
});