Skip to content

Commit 9062a3e

Browse files
authored
Merge pull request #10 from unexpectedjs/ssimonsen/fixing-expected-index-for-moves
Fixing expectedIndex for move items
2 parents 84b6161 + c036641 commit 9062a3e

File tree

6 files changed

+96
-13
lines changed

6 files changed

+96
-13
lines changed

.github/dependabot.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Please see the documentation for all configuration options:
2+
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
3+
4+
version: 2
5+
updates:
6+
- package-ecosystem: "npm"
7+
directory: "/"
8+
schedule:
9+
interval: "daily"

.github/workflows/ci.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: Checks
2+
3+
on: [push]
4+
5+
jobs:
6+
ci:
7+
runs-on: ubuntu-latest
8+
9+
strategy:
10+
matrix:
11+
node-version: [12, 14, 16, 18, 20, 22, 24]
12+
13+
steps:
14+
- uses: actions/checkout@v2
15+
- name: Use Node.js ${{ matrix.node-version }}
16+
uses: actions/setup-node@v1
17+
with:
18+
node-version: ${{ matrix.node-version }}
19+
- run: npm install
20+
- run: npm run ci

lib/arrayChanges.js

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ module.exports = function arrayChanges(actual, expected, equal, similar, options
5959
return i;
6060
}
6161

62+
63+
function findMoveTargetWithId(id) {
64+
return mutatedArray.find(function (diffItem) {
65+
return diffItem.type === 'moveTarget' && diffItem.id === id;
66+
});
67+
}
68+
6269
var removes = itemsDiff.filter(function (diffItem) {
6370
return diffItem.type === 'remove';
6471
});
@@ -76,15 +83,13 @@ module.exports = function arrayChanges(actual, expected, equal, similar, options
7683
return diffItem.type === 'move';
7784
});
7885

79-
86+
var ids = 0;
8087
moves.forEach(function (diffItem) {
8188
var moveFromIndex = offsetIndex(diffItem.from + 1) - 1;
8289
var removed = mutatedArray.slice(moveFromIndex, diffItem.howMany + moveFromIndex);
8390
removed.forEach(function (v, index) {
8491
v.type = 'moveSource';
85-
v.expectedIndex = offsetIndex(diffItem.to + index);
86-
v.expected = expected[v.expectedIndex];
87-
v.equal = equal(v.value, v.expected);
92+
v.id = ids++;
8893
});
8994
var added = removed.map(function (v, index) {
9095
return extend({}, v, { last: false, type: 'moveTarget' });
@@ -93,7 +98,6 @@ module.exports = function arrayChanges(actual, expected, equal, similar, options
9398
Array.prototype.splice.apply(mutatedArray, [insertIndex, 0].concat(added));
9499
});
95100

96-
97101
var inserts = itemsDiff.filter(function (diffItem) {
98102
return diffItem.type === 'insert';
99103
});
@@ -114,14 +118,27 @@ module.exports = function arrayChanges(actual, expected, equal, similar, options
114118
var offset = 0;
115119
mutatedArray.forEach(function (diffItem, index) {
116120
var type = diffItem.type;
117-
if (type === 'remove' || type === 'moveSource') {
121+
if (type === 'moveTarget') {
122+
diffItem.expected = expected[offset + index];
123+
diffItem.expectedIndex = offset + index;
124+
diffItem.equal = equal(diffItem.value, diffItem.expected);
125+
} else if (type === 'remove' || type === 'moveSource') {
118126
offset -= 1;
119127
} else if (type === 'similar') {
120128
diffItem.expected = expected[offset + index];
121129
diffItem.expectedIndex = offset + index;
122130
}
123131
});
124132

133+
mutatedArray.forEach(function (diffItem) {
134+
if (diffItem.type === 'moveSource') {
135+
var moveTarget = findMoveTargetWithId(diffItem.id);
136+
diffItem.expected = moveTarget.expected;
137+
diffItem.expectedIndex = moveTarget.expectedIndex;
138+
diffItem.equal = moveTarget.equal;
139+
}
140+
});
141+
125142
var conflicts = mutatedArray.reduce(function (conflicts, item) {
126143
return item.type === 'similar' || item.type === 'moveSource' || item.type === 'moveTarget' ? conflicts : conflicts + 1;
127144
}, 0);

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
"main": "./lib/arrayChanges.js",
66
"scripts": {
77
"lint": "eslint .",
8-
"test": "mocha && npm run lint",
9-
"travis": "npm test && npm run coverage && (<coverage/lcov.info coveralls || true)",
8+
"test": "mocha",
9+
"ci": "npm run lint && npm test && npm run coverage && (<coverage/lcov.info coveralls || true)",
1010
"coverage": "NODE_ENV=development istanbul cover _mocha -- --reporter dot && echo google-chrome coverage/lcov-report/index.html",
1111
"prepublish": "(echo '/*!' && <LICENSE sed -e's/^/ * /' | sed -e's/\\s+$//' && echo ' */' && browserify -p bundle-collapser/plugin -e lib/arrayChanges -s weknowhow.arrayChanges) > array-changes.js"
1212
},

test/arrayChanges.spec.js

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,11 @@ describe('array-changes', function () {
109109
expect(arrayChanges([1, 2, 3, 0], [0, 1, 2, 3], function (a, b) {
110110
return a === b;
111111
}), 'to equal', [
112-
{ type: 'moveTarget', value: 0, actualIndex: 3, expected: 0, expectedIndex: 0, equal: true, last: false },
112+
{ type: 'moveTarget', value: 0, actualIndex: 3, expected: 0, expectedIndex: 0, id: 0, equal: true, last: false },
113113
{ type: 'equal', value: 1, actualIndex: 0, expected: 1, expectedIndex: 1 },
114114
{ type: 'equal', value: 2, actualIndex: 1, expected: 2, expectedIndex: 2 },
115115
{ type: 'equal', value: 3, actualIndex: 2, expected: 3, expectedIndex: 3 },
116-
{ type: 'moveSource', value: 0, actualIndex: 3, expected: 0, expectedIndex: 0, equal: true, last: true }
116+
{ type: 'moveSource', value: 0, actualIndex: 3, expected: 0, expectedIndex: 0, id: 0, equal: true, last: true }
117117
]);
118118
});
119119

@@ -122,9 +122,9 @@ describe('array-changes', function () {
122122
return a === b;
123123
}), 'to equal', [
124124
{ type: 'equal', value: 0, actualIndex: 0, expected: 0, expectedIndex: 0 },
125-
{ type: 'moveTarget', value: 2, actualIndex: 2, expected: 2, expectedIndex: 1, equal: true, last: false },
125+
{ type: 'moveTarget', value: 2, actualIndex: 2, expected: 2, expectedIndex: 1, id: 0, equal: true, last: false },
126126
{ type: 'equal', value: 1, actualIndex: 1, expected: 1, expectedIndex: 2 },
127-
{ type: 'moveSource', value: 2, actualIndex: 2, expected: 2, expectedIndex: 1, equal: true },
127+
{ type: 'moveSource', value: 2, actualIndex: 2, expected: 2, expectedIndex: 1, id: 0, equal: true },
128128
{ type: 'equal', value: 3, actualIndex: 3, expected: 3, expectedIndex: 3, last: true }
129129
]);
130130
});
@@ -451,6 +451,7 @@ describe('array-changes', function () {
451451
expected: { kind: 1, type: 'tag', name: 'p', children: [{ data: 'Hello world 2025', type: 'text' }], attribs: {} },
452452
actualIndex: 1,
453453
expectedIndex: 0,
454+
id: 0,
454455
equal: false,
455456
last: false
456457
},
@@ -467,9 +468,46 @@ describe('array-changes', function () {
467468
expected: { kind: 1, type: 'tag', name: 'p', children: [{ data: 'Hello world 2025', type: 'text' }], attribs: {} },
468469
actualIndex: 1,
469470
expectedIndex: 0,
471+
id: 0,
470472
equal: false,
471473
last: true
472474
}
473475
]);
474476
});
477+
478+
it("handles moves where no items are similar", function () {
479+
var a = ['a', 'b', 'c'];
480+
var b = ['c', 'b', 'a'];
481+
482+
expect(arrayChanges(a, b, function (a, b) {
483+
return expect.equal(a, b);
484+
}, function () {
485+
return false;
486+
}), 'to equal', [
487+
{ type: 'moveTarget', value: 'c', actualIndex: 2, last: false, expected: 'c', expectedIndex: 0, id: 1, equal: true },
488+
{ type: 'moveTarget', value: 'b', actualIndex: 1, last: false, expected: 'b', expectedIndex: 1, id: 0, equal: true },
489+
{ type: 'equal', value: 'a', actualIndex: 0, expected: 'a', expectedIndex: 2 },
490+
{ type: 'moveSource', value: 'b', actualIndex: 1, expected: 'b', expectedIndex: 1, id: 0, equal: true },
491+
{ type: 'moveSource', value: 'c', actualIndex: 2, expected: 'c', expectedIndex: 0, id: 1, equal: true, last: true }
492+
]);
493+
});
494+
495+
it("handles moves with a mix of equal and similar items", function () {
496+
var a = ['aaa', 'bbb', 'ccc', 'dddd'];
497+
var b = ['ddd', 'ccc', 'bbb', 'aaa'];
498+
499+
expect(arrayChanges(a, b, function (a, b) {
500+
return expect.equal(a, b);
501+
}, function (a, b) {
502+
return expect.equal(a.slice(0, 3), b.slice(0, 3));
503+
}), 'to equal', [
504+
{ type: 'moveTarget', value: 'dddd', actualIndex: 3, id: 2, last: false, expected: 'ddd', expectedIndex: 0, equal: false },
505+
{ type: 'moveTarget', value: 'ccc', actualIndex: 2, id: 1, last: false, expected: 'ccc', expectedIndex: 1, equal: true },
506+
{ type: 'moveTarget', value: 'bbb', actualIndex: 1, id: 0, last: false, expected: 'bbb', expectedIndex: 2, equal: true },
507+
{ type: 'equal', value: 'aaa', actualIndex: 0, expected: 'aaa', expectedIndex: 3 },
508+
{ type: 'moveSource', value: 'bbb', actualIndex: 1, id: 0, expected: 'bbb', expectedIndex: 2, equal: true },
509+
{ type: 'moveSource', value: 'ccc', actualIndex: 2, id: 1, expected: 'ccc', expectedIndex: 1, equal: true },
510+
{ type: 'moveSource', value: 'dddd', actualIndex: 3, id: 2, expected: 'ddd', expectedIndex: 0, equal: false, last: true }
511+
]);
512+
});
475513
});

test/arraydiff.spec.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ describe('arraydiff', function () {
2727
var out = before.slice();
2828
for (var i = 0; i < diff.length; i++) {
2929
var item = diff[i];
30-
// console.log 'applying:', out, item
3130
if (item.type === 'insert') {
3231
insert(out, item.index, item.values);
3332
} else if (item.type === 'remove') {

0 commit comments

Comments
 (0)