Browse Source

fix: deep equality check

pull/1/head
DoneDeal0 2 years ago
parent
commit
ec1c7166b9
  1. 33
      src/object-diff.ts
  2. 3
      src/utils.ts
  3. 329
      test/object-diff.test.ts
  4. 1
      test/utils.test.ts

33
src/object-diff.ts

@ -62,11 +62,12 @@ function getPreviousMatch(
prevSubValues: [string, any][] | null, prevSubValues: [string, any][] | null,
nextSubProperty: any nextSubProperty: any
): any | undefined { ): any | undefined {
const previousMatch = if (!prevSubValues) {
prevSubValues && return undefined;
prevSubValues.find(([subPreviousKey]) => }
isEqual(subPreviousKey, nextSubProperty) const previousMatch = prevSubValues.find(([subPreviousKey]) =>
); isEqual(subPreviousKey, nextSubProperty)
);
return previousMatch ? previousMatch[1] : undefined; return previousMatch ? previousMatch[1] : undefined;
} }
@ -88,18 +89,16 @@ function getSubPropertiesDiff(
subDiff = data; subDiff = data;
} }
} }
if (prevSubValues) { if (previousMatch) {
if (previousMatch) { subPropertiesDiff.push({
subPropertiesDiff.push({ name: nextSubProperty,
name: nextSubProperty, previousValue: previousMatch,
previousValue: previousMatch, currentValue: nextSubValue,
currentValue: nextSubValue, status: isEqual(previousMatch, nextSubValue)
status: isEqual(previousMatch, nextSubValue) ? STATUS.EQUAL
? STATUS.EQUAL : STATUS.UPDATED,
: STATUS.UPDATED, ...(!!subDiff && { subDiff }),
...(!!subDiff && { subDiff }), });
});
}
} }
}); });
return subPropertiesDiff; return subPropertiesDiff;

3
src/utils.ts

@ -1,6 +1,9 @@
export function isEqual(a: any, b: any): boolean { export function isEqual(a: any, b: any): boolean {
if (typeof a !== typeof b) return false; if (typeof a !== typeof b) return false;
if (Array.isArray(a)) { if (Array.isArray(a)) {
if (a.length !== b.length) {
return false;
}
return a.every((v, i) => JSON.stringify(v) === JSON.stringify(b[i])); return a.every((v, i) => JSON.stringify(v) === JSON.stringify(b[i]));
} }
if (typeof a === "object") { if (typeof a === "object") {

329
test/object-diff.test.ts

@ -1,189 +1,154 @@
import { getObjectDiff } from "../src/object-diff"; import { getObjectDiff } from "../src/object-diff";
describe("getObjectDiff", () => { describe("getObjectDiff", () => {
// it("returns an empty diff if no objects are provided", () => { it("returns an empty diff if no objects are provided", () => {
// expect(getObjectDiff(null, null)).toStrictEqual({ expect(getObjectDiff(null, null)).toStrictEqual({
// type: "object", type: "object",
// status: "equal", status: "equal",
// diff: [], diff: [],
// }); });
// }); });
// it("consider previous object as completely deleted if no next object is provided", () => { it("consider previous object as completely deleted if no next object is provided", () => {
// expect( expect(
// getObjectDiff( getObjectDiff(
// { name: "joe", age: 54, hobbies: ["golf", "football"] }, { name: "joe", age: 54, hobbies: ["golf", "football"] },
// null null
// ) )
// ).toStrictEqual({ ).toStrictEqual({
// type: "object", type: "object",
// status: "deleted", status: "deleted",
// diff: [ diff: [
// { {
// property: "name", property: "name",
// previousValue: "joe", previousValue: "joe",
// currentValue: undefined, currentValue: undefined,
// status: "deleted", status: "deleted",
// }, },
// { {
// property: "age", property: "age",
// previousValue: 54, previousValue: 54,
// currentValue: undefined, currentValue: undefined,
// status: "deleted", status: "deleted",
// }, },
// { {
// property: "hobbies", property: "hobbies",
// previousValue: ["golf", "football"], previousValue: ["golf", "football"],
// currentValue: undefined, currentValue: undefined,
// status: "deleted", status: "deleted",
// }, },
// ], ],
// }); });
// }); });
// it("consider next object as completely added if no previous object is provided", () => { it("consider next object as completely added if no previous object is provided", () => {
// expect( expect(
// getObjectDiff(null, { getObjectDiff(null, {
// name: "joe", name: "joe",
// age: 54, age: 54,
// hobbies: ["golf", "football"], hobbies: ["golf", "football"],
// }) })
// ).toStrictEqual({ ).toStrictEqual({
// type: "object", type: "object",
// status: "added", status: "added",
// diff: [ diff: [
// { {
// property: "name", property: "name",
// previousValue: undefined, previousValue: undefined,
// currentValue: "joe", currentValue: "joe",
// status: "added", status: "added",
// }, },
// { {
// property: "age", property: "age",
// previousValue: undefined, previousValue: undefined,
// currentValue: 54, currentValue: 54,
// status: "added", status: "added",
// }, },
// { {
// property: "hobbies", property: "hobbies",
// previousValue: undefined, previousValue: undefined,
// currentValue: ["golf", "football"], currentValue: ["golf", "football"],
// status: "added", status: "added",
// }, },
// ], ],
// }); });
// }); });
// it("detects changed between two objects", () => { it("detects changed between two objects", () => {
// expect( expect(
// getObjectDiff( getObjectDiff(
// { {
// id: 54, id: 54,
// user: { user: {
// name: "joe", name: "joe",
// member: true, member: true,
// hobbies: ["golf", "football"], hobbies: ["golf", "football"],
// age: 66, age: 66,
// },
// },
// {
// id: 54,
// user: {
// name: "joe",
// member: false,
// hobbies: ["golf", "chess"],
// age: 66,
// },
// }
// )
// ).toStrictEqual({
// type: "object",
// status: "updated",
// diff: [
// {
// property: "id",
// previousValue: 54,
// currentValue: 54,
// status: "equal",
// },
// {
// property: "user",
// previousValue: {
// name: "joe",
// member: true,
// hobbies: ["golf", "football"],
// age: 66,
// },
// currentValue: {
// name: "joe",
// member: false,
// hobbies: ["golf", "chess"],
// age: 66,
// },
// status: "updated",
// subPropertiesDiff: [
// {
// name: "name",
// previousValue: "joe",
// currentValue: "joe",
// status: "equal",
// },
// {
// name: "member",
// previousValue: true,
// currentValue: false,
// status: "updated",
// },
// {
// name: "hobbies",
// previousValue: ["golf", "football"],
// currentValue: ["golf", "chess"],
// status: "updated",
// },
// {
// name: "age",
// previousValue: 66,
// currentValue: 66,
// status: "equal",
// },
// ],
// },
// ],
// });
// });
it("detects changed between two deep nested objects", () => {
console.log(
"res",
JSON.stringify(
getObjectDiff(
{
id: 54,
user: {
name: "joe",
data: {
member: true,
hobbies: {
football: ["psg"],
rugby: ["france"],
},
},
},
}, },
{ },
id: 54, {
user: { id: 54,
name: "joe", user: {
data: { name: "joe",
member: true, member: false,
hobbies: { hobbies: ["golf", "chess"],
football: ["psg", "nantes"], age: 66,
rugby: ["france"], },
}, }
},
},
}
),
null,
2
) )
); ).toStrictEqual({
type: "object",
status: "updated",
diff: [
{
property: "id",
previousValue: 54,
currentValue: 54,
status: "equal",
},
{
property: "user",
previousValue: {
name: "joe",
member: true,
hobbies: ["golf", "football"],
age: 66,
},
currentValue: {
name: "joe",
member: false,
hobbies: ["golf", "chess"],
age: 66,
},
status: "updated",
subPropertiesDiff: [
{
name: "name",
previousValue: "joe",
currentValue: "joe",
status: "equal",
},
{
name: "member",
previousValue: true,
currentValue: false,
status: "updated",
},
{
name: "hobbies",
previousValue: ["golf", "football"],
currentValue: ["golf", "chess"],
status: "updated",
},
{
name: "age",
previousValue: 66,
currentValue: 66,
status: "equal",
},
],
},
],
});
});
it("detects changed between two deep nested objects", () => {
expect( expect(
getObjectDiff( getObjectDiff(
{ {
@ -293,7 +258,7 @@ describe("getObjectDiff", () => {
name: "football", name: "football",
previousValue: ["psg"], previousValue: ["psg"],
currentValue: ["psg", "nantes"], currentValue: ["psg", "nantes"],
status: "updated", // error the algo says it's equal... status: "updated",
}, },
{ {
name: "rugby", name: "rugby",

1
test/utils.test.ts

@ -38,6 +38,7 @@ describe("isEqual", () => {
] ]
) )
).toBeFalsy(); ).toBeFalsy();
expect(isEqual(["psg"], ["psg", "nantes"])).toBeFalsy();
}); });
}); });

Loading…
Cancel
Save