diff --git a/src/object-diff.ts b/src/object-diff.ts index 3893619..d5189ff 100644 --- a/src/object-diff.ts +++ b/src/object-diff.ts @@ -62,11 +62,12 @@ function getPreviousMatch( prevSubValues: [string, any][] | null, nextSubProperty: any ): any | undefined { - const previousMatch = - prevSubValues && - prevSubValues.find(([subPreviousKey]) => - isEqual(subPreviousKey, nextSubProperty) - ); + if (!prevSubValues) { + return undefined; + } + const previousMatch = prevSubValues.find(([subPreviousKey]) => + isEqual(subPreviousKey, nextSubProperty) + ); return previousMatch ? previousMatch[1] : undefined; } @@ -88,18 +89,16 @@ function getSubPropertiesDiff( subDiff = data; } } - if (prevSubValues) { - if (previousMatch) { - subPropertiesDiff.push({ - name: nextSubProperty, - previousValue: previousMatch, - currentValue: nextSubValue, - status: isEqual(previousMatch, nextSubValue) - ? STATUS.EQUAL - : STATUS.UPDATED, - ...(!!subDiff && { subDiff }), - }); - } + if (previousMatch) { + subPropertiesDiff.push({ + name: nextSubProperty, + previousValue: previousMatch, + currentValue: nextSubValue, + status: isEqual(previousMatch, nextSubValue) + ? STATUS.EQUAL + : STATUS.UPDATED, + ...(!!subDiff && { subDiff }), + }); } }); return subPropertiesDiff; diff --git a/src/utils.ts b/src/utils.ts index 55681d5..c526893 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,6 +1,9 @@ export function isEqual(a: any, b: any): boolean { if (typeof a !== typeof b) return false; if (Array.isArray(a)) { + if (a.length !== b.length) { + return false; + } return a.every((v, i) => JSON.stringify(v) === JSON.stringify(b[i])); } if (typeof a === "object") { diff --git a/test/object-diff.test.ts b/test/object-diff.test.ts index a65b170..c561d9a 100644 --- a/test/object-diff.test.ts +++ b/test/object-diff.test.ts @@ -1,189 +1,154 @@ import { getObjectDiff } from "../src/object-diff"; describe("getObjectDiff", () => { - // it("returns an empty diff if no objects are provided", () => { - // expect(getObjectDiff(null, null)).toStrictEqual({ - // type: "object", - // status: "equal", - // diff: [], - // }); - // }); - // it("consider previous object as completely deleted if no next object is provided", () => { - // expect( - // getObjectDiff( - // { name: "joe", age: 54, hobbies: ["golf", "football"] }, - // null - // ) - // ).toStrictEqual({ - // type: "object", - // status: "deleted", - // diff: [ - // { - // property: "name", - // previousValue: "joe", - // currentValue: undefined, - // status: "deleted", - // }, - // { - // property: "age", - // previousValue: 54, - // currentValue: undefined, - // status: "deleted", - // }, - // { - // property: "hobbies", - // previousValue: ["golf", "football"], - // currentValue: undefined, - // status: "deleted", - // }, - // ], - // }); - // }); - // it("consider next object as completely added if no previous object is provided", () => { - // expect( - // getObjectDiff(null, { - // name: "joe", - // age: 54, - // hobbies: ["golf", "football"], - // }) - // ).toStrictEqual({ - // type: "object", - // status: "added", - // diff: [ - // { - // property: "name", - // previousValue: undefined, - // currentValue: "joe", - // status: "added", - // }, - // { - // property: "age", - // previousValue: undefined, - // currentValue: 54, - // status: "added", - // }, - // { - // property: "hobbies", - // previousValue: undefined, - // currentValue: ["golf", "football"], - // status: "added", - // }, - // ], - // }); - // }); - // it("detects changed between two objects", () => { - // expect( - // getObjectDiff( - // { - // id: 54, - // user: { - // name: "joe", - // member: true, - // hobbies: ["golf", "football"], - // 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"], - }, - }, - }, + it("returns an empty diff if no objects are provided", () => { + expect(getObjectDiff(null, null)).toStrictEqual({ + type: "object", + status: "equal", + diff: [], + }); + }); + it("consider previous object as completely deleted if no next object is provided", () => { + expect( + getObjectDiff( + { name: "joe", age: 54, hobbies: ["golf", "football"] }, + null + ) + ).toStrictEqual({ + type: "object", + status: "deleted", + diff: [ + { + property: "name", + previousValue: "joe", + currentValue: undefined, + status: "deleted", + }, + { + property: "age", + previousValue: 54, + currentValue: undefined, + status: "deleted", + }, + { + property: "hobbies", + previousValue: ["golf", "football"], + currentValue: undefined, + status: "deleted", + }, + ], + }); + }); + it("consider next object as completely added if no previous object is provided", () => { + expect( + getObjectDiff(null, { + name: "joe", + age: 54, + hobbies: ["golf", "football"], + }) + ).toStrictEqual({ + type: "object", + status: "added", + diff: [ + { + property: "name", + previousValue: undefined, + currentValue: "joe", + status: "added", + }, + { + property: "age", + previousValue: undefined, + currentValue: 54, + status: "added", + }, + { + property: "hobbies", + previousValue: undefined, + currentValue: ["golf", "football"], + status: "added", + }, + ], + }); + }); + it("detects changed between two objects", () => { + expect( + getObjectDiff( + { + id: 54, + user: { + name: "joe", + member: true, + hobbies: ["golf", "football"], + age: 66, }, - { - id: 54, - user: { - name: "joe", - data: { - member: true, - hobbies: { - football: ["psg", "nantes"], - rugby: ["france"], - }, - }, - }, - } - ), - null, - 2 + }, + { + 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", () => { expect( getObjectDiff( { @@ -293,7 +258,7 @@ describe("getObjectDiff", () => { name: "football", previousValue: ["psg"], currentValue: ["psg", "nantes"], - status: "updated", // error the algo says it's equal... + status: "updated", }, { name: "rugby", diff --git a/test/utils.test.ts b/test/utils.test.ts index b751386..babe049 100644 --- a/test/utils.test.ts +++ b/test/utils.test.ts @@ -38,6 +38,7 @@ describe("isEqual", () => { ] ) ).toBeFalsy(); + expect(isEqual(["psg"], ["psg", "nantes"])).toBeFalsy(); }); });