From 57c21c0696892bb45b30fa0894d9edeed97c907d Mon Sep 17 00:00:00 2001 From: Sune Simonsen Date: Wed, 30 Jul 2025 11:48:08 +0200 Subject: [PATCH] Upgrade array-changes to fix structural moves --- lib/arrayChanges.js | 24 ++++++++++++++++++++++++ lib/assertions.js | 2 +- lib/types.js | 2 +- package.json | 2 +- test/assertions/to-equal.spec.js | 20 ++++++++++++++++++++ test/assertions/to-satisfy.spec.js | 20 ++++++++++++++++++++ test/assertions/when-sorted.spec.js | 18 ++++++++++++++++++ 7 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 lib/arrayChanges.js diff --git a/lib/arrayChanges.js b/lib/arrayChanges.js new file mode 100644 index 000000000..338b8416f --- /dev/null +++ b/lib/arrayChanges.js @@ -0,0 +1,24 @@ +const arrayChanges = require('array-changes'); + +module.exports = function (...args) { + return arrayChanges(...args).map((change) => { + if (change.type === 'moveSource' && change.equal === false) { + return { + type: 'remove', + value: change.value, + actualIndex: change.actualIndex, + last: change.last, + }; + } + + if (change.type === 'moveTarget' && change.equal === false) { + return { + type: 'insert', + value: change.expected, + actualIndex: change.actualIndex, + }; + } + + return change; + }); +}; diff --git a/lib/assertions.js b/lib/assertions.js index 8d7691c32..f7fd29b21 100644 --- a/lib/assertions.js +++ b/lib/assertions.js @@ -1,5 +1,5 @@ const utils = require('./utils'); -const arrayChanges = require('array-changes'); +const arrayChanges = require('./arrayChanges'); const arrayChangesAsync = require('array-changes-async'); const throwIfNonUnexpectedError = require('./throwIfNonUnexpectedError'); const objectIs = utils.objectIs; diff --git a/lib/types.js b/lib/types.js index 0a4e1fc1d..ba92668e0 100644 --- a/lib/types.js +++ b/lib/types.js @@ -1,7 +1,7 @@ const utils = require('./utils'); const isRegExp = utils.isRegExp; const leftPad = utils.leftPad; -const arrayChanges = require('array-changes'); +const arrayChanges = require('./arrayChanges'); const ukkonen = require('ukkonen'); const detectIndent = require('detect-indent'); const defaultDepth = require('./defaultDepth'); diff --git a/package.json b/package.json index 91c544e42..28cba6009 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ }, "main": "./build/lib/index.js", "dependencies": { - "array-changes": "3.0.1", + "array-changes": "^3.2.1", "array-changes-async": "3.0.1", "detect-indent": "3.0.1", "diff": "^5.0.0", diff --git a/test/assertions/to-equal.spec.js b/test/assertions/to-equal.spec.js index f7c22adde..1f30ca6b2 100644 --- a/test/assertions/to-equal.spec.js +++ b/test/assertions/to-equal.spec.js @@ -595,4 +595,24 @@ describe('to equal assertion', () => { expect(errors[0], 'to equal', errors[1]); }); }); + + it('handles moving of objects with similar structures', () => { + expect( + function () { + expect([42, { name: 'John', age: 34 }], 'to equal', [ + { name: 'Jane', age: 24, children: 2 }, + 42, + ]); + }, + 'to throw exception', + "expected [ 42, { name: 'John', age: 34 } ]\n" + + "to equal [ { name: 'Jane', age: 24, children: 2 }, 42 ]\n" + + '\n' + + '[\n' + + " // missing { name: 'Jane', age: 24, children: 2 }\n" + + ' 42,\n' + + " { name: 'John', age: 34 } // should be removed\n" + + ']' + ); + }); }); diff --git a/test/assertions/to-satisfy.spec.js b/test/assertions/to-satisfy.spec.js index cf7b258f4..2bade43c3 100644 --- a/test/assertions/to-satisfy.spec.js +++ b/test/assertions/to-satisfy.spec.js @@ -2904,4 +2904,24 @@ describe('to satisfy assertion', () => { ); }); }); + + it('handles moving of objects with similar structures', () => { + expect( + function () { + expect([42, { name: 'John', age: 34 }], 'to satisfy', [ + { name: 'Jane', age: 24, children: 2 }, + 42, + ]); + }, + 'to throw exception', + "expected [ 42, { name: 'John', age: 34 } ]\n" + + "to satisfy [ { name: 'Jane', age: 24, children: 2 }, 42 ]\n" + + '\n' + + '[\n' + + " // missing { name: 'Jane', age: 24, children: 2 }\n" + + ' 42,\n' + + " { name: 'John', age: 34 } // should be removed\n" + + ']' + ); + }); }); diff --git a/test/assertions/when-sorted.spec.js b/test/assertions/when-sorted.spec.js index be9ede2b9..9ab31bb30 100644 --- a/test/assertions/when-sorted.spec.js +++ b/test/assertions/when-sorted.spec.js @@ -22,4 +22,22 @@ describe('when sorted assertion', () => { it("should also work without the 'when'", () => { expect(['c', 'd', 'a'], 'sorted', 'to equal', ['a', 'c', 'd']); }); + + describe('when failing', () => { + it('shows an error describing what is wrong', () => { + expect( + () => expect(['c', 'a', 'b'], 'sorted', 'to equal', ['c', 'b', 'a']), + 'to throw', + "expected [ 'c', 'a', 'b' ] sorted to equal [ 'c', 'b', 'a' ]\n" + + '\n' + + '[\n' + + '┌───▷\n' + + '│ ┌─▷\n' + + "│ │ 'a',\n" + + "│ └── 'b', // should be moved\n" + + "└──── 'c' // should be moved\n" + + ']' + ); + }); + }); });