array-changes
Advanced tools
Comparing version 1.3.0 to 1.3.1
@@ -24,2 +24,6 @@ var arrayDiff = require('arraydiff-papandreou'); | ||
equal = equal || function (a, b) { | ||
return a === b; | ||
}; | ||
similar = similar || function (a, b) { | ||
@@ -33,5 +37,12 @@ return false; | ||
var removeTable = []; | ||
function offsetIndex(index) { | ||
return index + (removeTable[index - 1] || 0); | ||
var offsetIndex = 0; | ||
var i; | ||
for (i = 0; i < mutatedArray.length && offsetIndex < index; i += 1) { | ||
if (mutatedArray[i].type !== 'remove') { | ||
offsetIndex++; | ||
} | ||
} | ||
return i; | ||
} | ||
@@ -43,3 +54,2 @@ | ||
var removesByIndex = {}; | ||
var removedItems = 0; | ||
@@ -52,15 +62,4 @@ removes.forEach(function (diffItem) { | ||
removedItems += diffItem.howMany; | ||
removesByIndex[diffItem.index] = removedItems; | ||
}); | ||
function updateRemoveTable() { | ||
removedItems = 0; | ||
Array.prototype.forEach.call(actual, function (_, index) { | ||
removedItems += removesByIndex[index] || 0; | ||
removeTable[index] = removedItems; | ||
}); | ||
} | ||
updateRemoveTable(); | ||
var moves = itemsDiff.filter(function (diffItem) { | ||
@@ -70,5 +69,5 @@ return diffItem.type === 'move'; | ||
var movedItems = 0; | ||
moves.forEach(function (diffItem) { | ||
var moveFromIndex = offsetIndex(diffItem.from); | ||
var moveFromIndex = offsetIndex(diffItem.from + 1) - 1; | ||
var removed = mutatedArray.slice(moveFromIndex, diffItem.howMany + moveFromIndex); | ||
@@ -81,8 +80,7 @@ var added = removed.map(function (v) { | ||
}); | ||
Array.prototype.splice.apply(mutatedArray, [offsetIndex(diffItem.to), 0].concat(added)); | ||
movedItems += diffItem.howMany; | ||
removesByIndex[diffItem.from] = movedItems; | ||
updateRemoveTable(); | ||
var insertIndex = offsetIndex(diffItem.to); | ||
Array.prototype.splice.apply(mutatedArray, [insertIndex, 0].concat(added)); | ||
}); | ||
var inserts = itemsDiff.filter(function (diffItem) { | ||
@@ -101,3 +99,4 @@ return diffItem.type === 'insert'; | ||
} | ||
Array.prototype.splice.apply(mutatedArray, [offsetIndex(diffItem.index), 0].concat(added)); | ||
var insertIndex = offsetIndex(diffItem.index); | ||
Array.prototype.splice.apply(mutatedArray, [insertIndex, 0].concat(added)); | ||
}); | ||
@@ -120,3 +119,4 @@ | ||
for (var i = 0, c = 0; i < Math.max(actual.length, expected.length) && c <= conflicts; i += 1) { | ||
var c, i; | ||
for (i = 0, c = 0; i < Math.max(actual.length, expected.length) && c <= conflicts; i += 1) { | ||
if ( | ||
@@ -123,0 +123,0 @@ i >= actual.length || i >= expected.length || (!equal(actual[i], expected[i], i, i) && !similar(actual[i], expected[i], i, i)) |
{ | ||
"name": "array-changes", | ||
"version": "1.3.0", | ||
"version": "1.3.1", | ||
"description": "Array diffing", | ||
"main": "./lib/arrayChanges.js", | ||
"scripts": { | ||
"lint": "jshint .", | ||
"lint": "eslint .", | ||
"test": "mocha && npm run lint", | ||
@@ -32,10 +32,13 @@ "travis": "npm test && npm run coverage && (<coverage/lcov.info coveralls || true)", | ||
"bundle-collapser": "1.2.1", | ||
"chance-generators": "1.18.0", | ||
"coveralls": "2.11.6", | ||
"eslint": "2.7.0", | ||
"eslint-config-onelint": "1.0.2", | ||
"istanbul": "0.4.2", | ||
"jshint": "2.9.1", | ||
"mocha": "2.3.4", | ||
"sinon": "1.17.2", | ||
"unexpected": "10.7.0", | ||
"unexpected-check": "1.11.0", | ||
"unexpected-sinon": "10.0.0" | ||
} | ||
} |
/*global describe, it, Symbol*/ | ||
var arrayChanges = require('../lib/arrayChanges'); | ||
var expect = require('unexpected').clone().use(require('unexpected-sinon')); | ||
var expect = require('unexpected').clone() | ||
.use(require('unexpected-sinon')) | ||
.use(require('unexpected-check')); | ||
var sinon = require('sinon'); | ||
var generators = require('chance-generators'); | ||
function toArguments() { | ||
@@ -10,3 +14,41 @@ return arguments; | ||
function executeDiff(changes) { | ||
var result = []; | ||
changes.forEach(function (item) { | ||
switch (item.type) { | ||
case 'moveTarget': | ||
case 'insert': | ||
result.push(item.value); | ||
break; | ||
case 'equal': | ||
case 'similar': | ||
if (typeof item.expected === 'number') { | ||
result.push(item.expected); | ||
} | ||
break; | ||
} | ||
}); | ||
return result; | ||
} | ||
expect.addAssertion('<array> when diffed with <array> <assertion>', function (expect, actual, expected) { | ||
expect.errorMode = 'nested'; | ||
return expect.shift(arrayChanges(actual, expected)); | ||
}); | ||
expect.addAssertion('<array> when executing the diff <assertion>', function (expect, diff) { | ||
expect.errorMode = 'nested'; | ||
return expect.shift(executeDiff(diff)); | ||
}); | ||
describe('array-changes', function () { | ||
var g; | ||
beforeEach(function () { | ||
g = generators(42); | ||
}); | ||
it('returns an empty change-list when the two arrays are both empty', function () { | ||
@@ -266,2 +308,16 @@ expect(arrayChanges([], [], function (a, b) { | ||
} | ||
it('produces a valid plan', function () { | ||
var arrays = g.array(g.natural({ max: 10 }), g.natural({ max: 10 })); | ||
expect(function (actual, expected) { | ||
expect( | ||
actual, | ||
'when diffed with', | ||
expected, | ||
'when executing the diff', | ||
'to equal', | ||
expected | ||
); | ||
}, 'to be valid for all', arrays, arrays); | ||
}); | ||
}); |
11
541
24321
12