Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Oct 17, 2021. It is now read-only.

Commit 02eaf44

Browse files
authored
Merge pull request #3 from awcjack/real-fix
fix: handle reorder and add simple array option
2 parents 696052b + 2a15a80 commit 02eaf44

File tree

5 files changed

+144
-28
lines changed

5 files changed

+144
-28
lines changed

‎src/added/index.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import _ from "lodash"
22
import { isEmpty, isObject, properObject } from '../utils';
33

4-
const addedDiff = (lhs, rhs) => {
4+
const addedDiff = (lhs, rhs,simpleArray=true) => {
55

66
if (lhs === rhs || !isObject(lhs) || !isObject(rhs)) return {};
77

@@ -11,24 +11,26 @@ const addedDiff = (lhs, rhs) => {
1111
return Object.keys(r).reduce((acc, key) => {
1212
if (l.hasOwnProperty(key)) {
1313
if (Array.isArray(l[key]) && Array.isArray(r[key])) {
14-
//const allKeys = _.merge(l[key], r[key]) ?? []
1514
const newFields = _.uniq(_.difference(r[key], l[key]))
1615
if (newFields.length === 0) {
1716
return acc
1817
}
19-
const newFieldsIndex = _.map(newFields, o => ({
18+
if (simpleArray) {
19+
return { ...acc, [key]: { after: _.uniq(_.difference(r[key], l[key])) } }
20+
}
21+
const newFieldsIndices = _.map(newFields, o => ({
2022
content: o,
21-
index: []
23+
indices: []
2224
}))
2325
for (let i = 0; i < r[key].length; i++) {
2426
const index = _.findIndex(newFields, o => _.isEqual(o, r[key][i]))
2527
if (index !== -1) {
26-
newFieldsIndex[index].index.push(i)
28+
newFieldsIndices[index].indices.push(i)
2729
}
2830
}
29-
return { ...acc, [key]: { after: newFieldsIndex } }
31+
return { ...acc, [key]: { after: newFieldsIndices } }
3032
}
31-
const difference = addedDiff(l[key], r[key]);
33+
const difference = addedDiff(l[key], r[key],simpleArray);
3234

3335
if (isObject(difference) && isEmpty(difference)) return acc;
3436

‎src/deleted/index.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import _ from "lodash"
22
import { isEmpty, isObject, properObject } from '../utils';
33

4-
const deletedDiff = (lhs, rhs) => {
4+
const deletedDiff = (lhs, rhs,simpleArray=true) => {
55
if (lhs === rhs || !isObject(lhs) || !isObject(rhs)) return {};
66

77
const l = properObject(lhs);
@@ -14,19 +14,22 @@ const deletedDiff = (lhs, rhs) => {
1414
if (oldFields.length === 0) {
1515
return acc
1616
}
17-
const oldFieldsIndex = _.map(oldFields, o => ({
17+
if (simpleArray) {
18+
return { ...acc, [key]: { before: _.uniq(_.difference(l[key], r[key])) } }
19+
}
20+
const oldFieldsIndices = _.map(oldFields, o => ({
1821
content: o,
19-
index: []
22+
indices: []
2023
}))
2124
for (let i = 0; i < l[key].length; i++) {
2225
const index = _.findIndex(oldFields, o => _.isEqual(o, l[key][i]))
2326
if (index !== -1) {
24-
oldFieldsIndex[index].index.push(i)
27+
oldFieldsIndices[index].indices.push(i)
2528
}
2629
}
27-
return { ...acc, [key]: { before: oldFieldsIndex } }
30+
return { ...acc, [key]: { before: oldFieldsIndices } }
2831
}
29-
const difference = deletedDiff(l[key], r[key]);
32+
const difference = deletedDiff(l[key], r[key],simpleArray);
3033

3134
if (isObject(difference) && isEmpty(difference)) return acc;
3235

‎src/detailed/index.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ import addedDiff from '../added';
22
import deletedDiff from '../deleted';
33
import updatedDiff from '../updated';
44

5-
const detailedDiff = (lhs, rhs) => ({
6-
added: addedDiff(lhs, rhs),
7-
deleted: deletedDiff(lhs, rhs),
8-
updated: updatedDiff(lhs, rhs),
5+
const detailedDiff = (lhs, rhs,simpleArray=true) => ({
6+
added: addedDiff(lhs, rhs,simpleArray),
7+
deleted: deletedDiff(lhs, rhs,simpleArray),
8+
updated: updatedDiff(lhs, rhs,simpleArray),
99
});
1010

1111
export default detailedDiff;

‎src/detailed/index.test.js

Lines changed: 83 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ describe('.detailedDiff', () => {
154154
test.each([
155155
[{}, { a: ["a", "b"] }],
156156
])('returns right hand side value when different to left hand side value (%s, %s)', (lhs, rhs) => {
157-
expect(detailedDiff(lhs, rhs)).toEqual({ "added": { a: { after: ["a", "b"] } }, "deleted": {}, "updated": {} });
157+
expect(detailedDiff(lhs, rhs,false)).toEqual({ "added": { a: { after: ["a", "b"] } }, "deleted": {}, "updated": {} });
158158
});
159159
});
160160

@@ -165,7 +165,7 @@ describe('.detailedDiff', () => {
165165
[{ a: ["a"] }, { a: ["a", "b", "b", "b"] }, [1, 2, 3]],
166166
[{ a: ["a"] }, { a: ["b", "a", "b", "b"] }, [0, 2, 3]],
167167
])('returns inserted array element content and position of right hand side (%s, %s)', (lhs, rhs, indexes) => {
168-
expect(detailedDiff(lhs, rhs)).toEqual({ "added": { a: { after: [{ content: "b", index: indexes }] } }, "deleted": {}, "updated": {} });
168+
expect(detailedDiff(lhs, rhs,false)).toEqual({ "added": { a: { after: [{ content: "b", indices: indexes }] } }, "deleted": {}, "updated": {} });
169169
});
170170
});
171171

@@ -176,15 +176,45 @@ describe('.detailedDiff', () => {
176176
[{ a: ["a", "b", "b", "b"] }, { a: ["a"] }, [1, 2, 3]],
177177
[{ a: ["b", "a", "b", "b"] }, { a: ["a"] }, [0, 2, 3]],
178178
])('returns removed array element content and position of right hand side (%s, %s)', (lhs, rhs, indexes) => {
179-
expect(detailedDiff(lhs, rhs)).toEqual({ "added": {}, "deleted": { a: { before: [{ content: "b", index: indexes }] } }, "updated": {} });
179+
expect(detailedDiff(lhs, rhs,false)).toEqual({ "added": {}, "deleted": { a: { before: [{ content: "b", indices: indexes }] } }, "updated": {} });
180180
});
181181
});
182182

183183
describe('change array field (pull one insert one)', () => {
184184
test.each([
185185
[{ a: ["a", "c"] }, { a: ["a", "b"] }],
186186
])('returns inserted and removed array element of right hand side (%s, %s)', (lhs, rhs) => {
187-
expect(detailedDiff(lhs, rhs)).toEqual({ "added": { a: { after: [{ content: "b", index: [1] }] } }, "deleted": { a: { before: [{ content: "c", index: [1] }] } }, "updated": {} });
187+
expect(detailedDiff(lhs, rhs, false)).toEqual({ "added": { a: { after: [{ content: "b", indices: [1] }] } }, "deleted": { a: { before: [{ content: "c", indices: [1] }] } }, "updated": {} });
188+
});
189+
});
190+
191+
describe('add array *element* (simple array)', () => {
192+
test.each([
193+
[{ a: ["a"] }, { a: ["a", "b"] }, [1]],
194+
[{ a: ["a"] }, { a: ["a", "b", "b"] }, [1, 2]],
195+
[{ a: ["a"] }, { a: ["a", "b", "b", "b"] }, [1, 2, 3]],
196+
[{ a: ["a"] }, { a: ["b", "a", "b", "b"] }, [0, 2, 3]],
197+
])('returns inserted array element content and position of right hand side (%s, %s)', (lhs, rhs, indexes) => {
198+
expect(detailedDiff(lhs, rhs)).toEqual({ "added": { a: { after: ["b"] } }, "deleted": {}, "updated": {} });
199+
});
200+
});
201+
202+
describe('remove array element (simple array)', () => {
203+
test.each([
204+
[{ a: ["a", "b"] }, { a: ["a"] }, [1]],
205+
[{ a: ["a", "b", "b"] }, { a: ["a"] }, [1, 2]],
206+
[{ a: ["a", "b", "b", "b"] }, { a: ["a"] }, [1, 2, 3]],
207+
[{ a: ["b", "a", "b", "b"] }, { a: ["a"] }, [0, 2, 3]],
208+
])('returns removed array element content and position of right hand side (%s, %s)', (lhs, rhs, indexes) => {
209+
expect(detailedDiff(lhs, rhs)).toEqual({ "added": {}, "deleted": { a: { before: ["b"] } }, "updated": {} });
210+
});
211+
});
212+
213+
describe('change array field (pull one insert one) (simple array)', () => {
214+
test.each([
215+
[{ a: ["a", "c"] }, { a: ["a", "b"] }],
216+
])('returns inserted and removed array element of right hand side (%s, %s)', (lhs, rhs) => {
217+
expect(detailedDiff(lhs, rhs)).toEqual({ "added": { a: { after: ["b"] } }, "deleted": { a: { before: ["c"] } }, "updated": {} });
188218
});
189219
});
190220
});
@@ -198,7 +228,7 @@ describe('.detailedDiff', () => {
198228
[{ a: { a: ["a"] } }, { a: { a: ["a", "b", "b", "b"] } }, [1, 2, 3]],
199229
[{ a: { a: ["a"] } }, { a: { a: ["b", "a", "b", "b"] } }, [0, 2, 3]],
200230
])('returns inserted array element content and position of right hand side (%s, %s)', (lhs, rhs, indexes) => {
201-
expect(detailedDiff(lhs, rhs)).toEqual({ "added": { a: { a: { after: [{ content: "b", index: indexes }] } } }, "deleted": {}, "updated": {} });
231+
expect(detailedDiff(lhs, rhs,false)).toEqual({ "added": { a: { a: { after: [{ content: "b", indices: indexes }] } } }, "deleted": {}, "updated": {} });
202232
});
203233
});
204234

@@ -209,15 +239,61 @@ describe('.detailedDiff', () => {
209239
[{ a: { a: ["a", "b", "b", "b"] } }, { a: { a: ["a"] } }, [1, 2, 3]],
210240
[{ a: { a: ["b", "a", "b", "b"] } }, { a: { a: ["a"] } }, [0, 2, 3]],
211241
])('returns removed array element content and position of right hand side (%s, %s)', (lhs, rhs, indexes) => {
212-
expect(detailedDiff(lhs, rhs)).toEqual({ "added": {}, "deleted": { a: { a: { before: [{ content: "b", index: indexes }] } } }, "updated": {} });
242+
expect(detailedDiff(lhs, rhs,false)).toEqual({ "added": {}, "deleted": { a: { a: { before: [{ content: "b", indices: indexes }] } } }, "updated": {} });
213243
});
214244
});
215245

216246
describe('change array field (pull one insert one) not in root', () => {
217247
test.each([
218248
[{ a: { a: ["a", "c"] } }, { a: { a: ["a", "b"] } }],
219249
])('returns inserted and removed array element of right hand side (%s, %s)', (lhs, rhs) => {
220-
expect(detailedDiff(lhs, rhs)).toEqual({ "added": { a: { a: { after: [{ content: "b", index: [1] }] } } }, "deleted": { a: { a: { before: [{ content: "c", index: [1] }] } } }, "updated": {} });
250+
expect(detailedDiff(lhs, rhs, false)).toEqual({ "added": { a: { a: { after: [{ content: "b", indices: [1] }] } } }, "deleted": { a: { a: { before: [{ content: "c", indices: [1] }] } } }, "updated": {} });
251+
});
252+
});
253+
254+
describe('reorder not in root', () => {
255+
test.each([
256+
[{ a: { a: ["a", "b", "c"] } }, { a: { a: ["a", "c", "b"] } }],
257+
])('returns inserted and removed array element of right hand side (%s, %s)', (lhs, rhs) => {
258+
expect(detailedDiff(lhs, rhs, false)).toEqual({ "added": {}, "deleted": {}, "updated": { a: { a: { after: { b: [{ counter: 0, newIndex: 2 }], c: [{ counter: 0, newIndex: 1 }] } } } } });
259+
});
260+
});
261+
262+
describe('add array *element* not in root (simple array)', () => {
263+
test.each([
264+
[{ a: { a: ["a"] } }, { a: { a: ["a", "b"] } }, [1]],
265+
[{ a: { a: ["a"] } }, { a: { a: ["a", "b", "b"] } }, [1, 2]],
266+
[{ a: { a: ["a"] } }, { a: { a: ["a", "b", "b", "b"] } }, [1, 2, 3]],
267+
[{ a: { a: ["a"] } }, { a: { a: ["b", "a", "b", "b"] } }, [0, 2, 3]],
268+
])('returns inserted array element content and position of right hand side (%s, %s)', (lhs, rhs, indexes) => {
269+
expect(detailedDiff(lhs, rhs)).toEqual({ "added": { a: { a: { after: ["b"] } } }, "deleted": {}, "updated": {} });
270+
});
271+
});
272+
273+
describe('remove array element not in root (simple array)', () => {
274+
test.each([
275+
[{ a: { a: ["a", "b"] } }, { a: { a: ["a"] } }, [1]],
276+
[{ a: { a: ["a", "b", "b"] } }, { a: { a: ["a"] } }, [1, 2]],
277+
[{ a: { a: ["a", "b", "b", "b"] } }, { a: { a: ["a"] } }, [1, 2, 3]],
278+
[{ a: { a: ["b", "a", "b", "b"] } }, { a: { a: ["a"] } }, [0, 2, 3]],
279+
])('returns removed array element content and position of right hand side (%s, %s)', (lhs, rhs, indexes) => {
280+
expect(detailedDiff(lhs, rhs)).toEqual({ "added": {}, "deleted": { a: { a: { before: ["b"] } } }, "updated": {} });
281+
});
282+
});
283+
284+
describe('change array field (pull one insert one) not in root (simple array)', () => {
285+
test.each([
286+
[{ a: { a: ["a", "c"] } }, { a: { a: ["a", "b"] } }],
287+
])('returns inserted and removed array element of right hand side (%s, %s)', (lhs, rhs) => {
288+
expect(detailedDiff(lhs, rhs)).toEqual({ "added": { a: { a: { after: ["b"] } } }, "deleted": { a: { a: { before: ["c"] } } }, "updated": {} });
289+
});
290+
});
291+
292+
describe('reorder not in root (simple array)', () => {
293+
test.each([
294+
[{ a: { a: ["a", "b", "c"] } }, { a: { a: ["a", "c", "b"] } }],
295+
])('returns inserted and removed array element of right hand side (%s, %s)', (lhs, rhs) => {
296+
expect(detailedDiff(lhs, rhs)).toEqual({ "added": {}, "deleted": {}, "updated": {}});
221297
});
222298
});
223299
});

‎src/updated/index.js

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
import _ from "lodash"
12
import { isDate, isEmpty, isObject, properObject } from '../utils';
23

3-
const updatedDiff = (lhs, rhs) => {
4+
const updatedDiff = (lhs, rhs,simpleArray=true) => {
45

56
if (lhs === rhs) return {};
67

@@ -17,10 +18,44 @@ const updatedDiff = (lhs, rhs) => {
1718
return Object.keys(r).reduce((acc, key) => {
1819

1920
if (l.hasOwnProperty(key)) {
20-
if (Array.isArray(l[key], r[key])) {
21-
return acc
21+
if (Array.isArray(l[key]) && Array.isArray(r[key])) {
22+
if (_.isEqual(l[key], r[key])) {
23+
return acc
24+
}
25+
const leftArray = _.cloneDeep(l[key])
26+
const rightArray = _.cloneDeep(r[key])
27+
const addedFields = _.uniq(_.difference(r[key], l[key]))
28+
const deletedFields = _.uniq(_.difference(l[key], r[key]))
29+
_.pullAll(leftArray, deletedFields)
30+
_.pullAll(rightArray, addedFields)
31+
if (_.isEqual(leftArray, rightArray) || simpleArray) {
32+
return acc
33+
} else {
34+
const allKeys = _.uniq(rightArray)
35+
const allKeysCounter = _.reduce(allKeys, (acc, curr) => (acc[curr] = 0, acc), {})
36+
const allKeysObject = _.reduce(allKeys, (acc, curr) => (acc[curr] = [], acc), {})
37+
for (let i = 0; i < leftArray.length; i++) {
38+
if (!_.isEqual(leftArray[i], rightArray[i])) {
39+
let index = _.findIndex(r[key], value => _.isEqual(value, rightArray[i]))
40+
for (let j = 0; j < allKeysCounter[rightArray[i]]; j++) {
41+
index = _.findIndex(r[key], value => _.isEqual(value, rightArray[i], index + 1))
42+
}
43+
allKeysObject[rightArray[i]].push({
44+
counter: allKeysCounter[rightArray[i]],
45+
newIndex: index
46+
})
47+
}
48+
allKeysCounter[rightArray[i]] = allKeysCounter[rightArray[i]]++
49+
}
50+
for (const key of Object.keys(allKeysObject)) {
51+
if (_.isEmpty(allKeysObject[key])) {
52+
delete allKeysObject[key]
53+
}
54+
}
55+
return { ...acc, [key]: { after: allKeysObject } }
56+
}
2257
}
23-
const difference = updatedDiff(l[key], r[key]);
58+
const difference = updatedDiff(l[key], r[key],simpleArray);
2459

2560
if (isObject(difference) && isEmpty(difference) && !isDate(difference)) return acc;
2661

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /