Skip to content

Commit 07c6c60

Browse files
add date, Map, Set & cyclic refs support
1 parent ab9aa01 commit 07c6c60

File tree

5 files changed

+271
-55
lines changed

5 files changed

+271
-55
lines changed

benchmark.js

Lines changed: 48 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,49 +5,74 @@ import { diff as deepObjDiff } from "deep-object-diff";
55
import { diff as justDiff } from "just-diff";
66
import deepDiff from "deep-diff";
77

8-
const lhs = {
9-
foo: {
10-
bar: {
11-
a: ["a", "b"],
12-
b: 2,
13-
c: ["x", "y"],
14-
e: 100, // deleted
8+
const obj1 = {
9+
id: 8,
10+
title: "Microsoft Surface Laptop 4",
11+
description: "Style and speed. Stand out on ...",
12+
price: 1499,
13+
discountPercentage: 10.23,
14+
rating: 4.43,
15+
stock: { inStock: true, count: 68 },
16+
brand: "Microsoft Surface",
17+
category: "laptops",
18+
resources: {
19+
images: {
20+
thumbnail: "https://cdn.dummyjson.com/product-images/8/thumbnail.jpg",
21+
items: [
22+
"https://cdn.dummyjson.com/product-images/8/1.jpg",
23+
"https://cdn.dummyjson.com/product-images/8/2.jpg",
24+
"https://cdn.dummyjson.com/product-images/8/3.jpg",
25+
"https://cdn.dummyjson.com/product-images/8/4.jpg",
26+
"https://cdn.dummyjson.com/product-images/8/thumbnail.jpg",
27+
],
1528
},
1629
},
17-
buzz: "world",
18-
date: new Date("2024-01-01"),
30+
createdAt: new Date("2024-01-01"),
31+
updatedAt: new Date("2024-01-02"),
1932
};
2033

21-
const rhs = {
22-
foo: {
23-
bar: {
24-
a: ["a"], // index 1 ('b') deleted
25-
b: 2, // unchanged
26-
c: ["x", "y", "z"], // 'z' added
27-
d: "Hello, world!", // added
34+
const obj2 = {
35+
id: 8,
36+
title: "Microsoft Surface Laptop 4",
37+
description: "Style and speed. Stand out on.",
38+
price: 1599,
39+
discountPercentage: 10.23,
40+
rating: 4.43,
41+
stock: { inStock: true, count: 18 },
42+
brand: "Microsoft Surface",
43+
category: "laptops",
44+
resources: {
45+
images: {
46+
thumbnail: "https://cdn.dummyjson.com/product-images/8/thumbnail.jpg",
47+
items: [
48+
"https://cdn.dummyjson.com/product-images/8/1.jpg",
49+
"https://cdn.dummyjson.com/product-images/8/2.jpg",
50+
"https://cdn.dummyjson.com/product-images/8/3.jpg",
51+
"https://cdn.dummyjson.com/product-images/8/4.jpg",
52+
],
2853
},
2954
},
30-
buzz: "fizz", // updated
31-
date: new Date("2024-01-02"),
55+
createdAt: new Date("2024-01-01"),
56+
updatedAt: new Date("2024-01-03"),
3257
};
3358

3459
const bench = new Bench({ time: 100, now: hrtimeNow });
3560

3661
bench
3762
.add("diff", () => {
38-
diff(lhs, rhs);
63+
diff(obj1, obj2);
3964
})
4065
.add("microdiff", () => {
41-
mdiff(lhs, rhs);
66+
mdiff(obj1, obj2);
4267
})
4368
.add("deep-object-diff", () => {
44-
deepObjDiff(lhs, rhs);
69+
deepObjDiff(obj1, obj2);
4570
})
4671
.add("just-diff", () => {
47-
justDiff(lhs, rhs);
72+
justDiff(obj1, obj2);
4873
})
4974
.add("deep-diff", () => {
50-
deepDiff(lhs, rhs);
75+
deepDiff(obj1, obj2);
5176
});
5277

5378
await bench.warmup();

packages/obj-diff/__tests__/diff.test.ts

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,21 @@ describe("diff", () => {
3737
expect(diff(Object.create(null), Object.create(null))).toEqual([]);
3838
});
3939

40+
test("dates", () => {
41+
expect(
42+
diff({ date: new Date("2024-01-01") }, { date: new Date("2024-01-01") })
43+
).toEqual([]);
44+
expect(
45+
diff({ date: new Date("2024-01-01") }, { date: new Date("2024-01-02") })
46+
).toEqual([
47+
{
48+
p: ["date"],
49+
t: 2,
50+
v: new Date("2024-01-02"),
51+
},
52+
]);
53+
});
54+
4055
test("array", () => {
4156
expect(diff([], [1])).toEqual([{ t: 1, p: [0], v: 1 }]);
4257
expect(diff([1], [2])).toEqual([{ t: 2, p: [0], v: 2 }]);
@@ -182,5 +197,156 @@ describe("diff", () => {
182197
v: "fizz",
183198
},
184199
]);
200+
201+
const obj1 = {
202+
id: 8,
203+
title: "Microsoft Surface Laptop 4",
204+
description: "Style and speed. Stand out on ...",
205+
price: 1499,
206+
discountPercentage: 10.23,
207+
rating: 4.43,
208+
stock: { inStock: true, count: 68 },
209+
brand: "Microsoft Surface",
210+
category: "laptops",
211+
resources: {
212+
images: {
213+
thumbnail: "https://cdn.dummyjson.com/product-images/8/thumbnail.jpg",
214+
items: [
215+
"https://cdn.dummyjson.com/product-images/8/1.jpg",
216+
"https://cdn.dummyjson.com/product-images/8/2.jpg",
217+
"https://cdn.dummyjson.com/product-images/8/3.jpg",
218+
"https://cdn.dummyjson.com/product-images/8/4.jpg",
219+
"https://cdn.dummyjson.com/product-images/8/thumbnail.jpg",
220+
],
221+
},
222+
},
223+
createdAt: new Date("2024-01-01"),
224+
updatedAt: new Date("2024-01-02"),
225+
};
226+
227+
const obj2 = {
228+
id: 8,
229+
title: "Microsoft Surface Laptop 4",
230+
description: "Style and speed. Stand out on.",
231+
price: 1599,
232+
discountPercentage: 10.23,
233+
rating: 4.43,
234+
stock: { inStock: true, count: 18 },
235+
brand: "Microsoft Surface",
236+
category: "laptops",
237+
resources: {
238+
images: {
239+
thumbnail: "https://cdn.dummyjson.com/product-images/8/thumbnail.jpg",
240+
items: [
241+
"https://cdn.dummyjson.com/product-images/8/1.jpg",
242+
"https://cdn.dummyjson.com/product-images/8/2.jpg",
243+
"https://cdn.dummyjson.com/product-images/8/3.jpg",
244+
"https://cdn.dummyjson.com/product-images/8/4.jpg",
245+
],
246+
},
247+
},
248+
createdAt: new Date("2024-01-01"),
249+
updatedAt: new Date("2024-01-03"),
250+
};
251+
252+
expect(diff(obj1, obj2)).toEqual([
253+
{
254+
p: ["description"],
255+
t: 2,
256+
v: "Style and speed. Stand out on.",
257+
},
258+
{
259+
p: ["price"],
260+
t: 2,
261+
v: 1599,
262+
},
263+
{
264+
p: ["stock", "count"],
265+
t: 2,
266+
v: 18,
267+
},
268+
{
269+
p: ["resources", "images", "items", 4],
270+
t: 0,
271+
},
272+
{
273+
p: ["updatedAt"],
274+
t: 2,
275+
v: new Date("2024-01-03"),
276+
},
277+
]);
278+
});
279+
280+
test("circular refs", () => {
281+
let obj1 = {};
282+
obj1.a = obj1;
283+
expect(diff(obj1, obj1)).toEqual([]);
284+
285+
obj1 = { a: { b: 2, c: [1, 2, 3] } };
286+
obj1.b = obj1;
287+
const obj2 = { a: { b: 2, c: [1, 5, 3] } };
288+
obj2.b = obj2;
289+
expect(diff(obj1, obj2)).toEqual([
290+
{
291+
p: ["a", "c", 1],
292+
t: 2,
293+
v: 5,
294+
},
295+
]);
296+
});
297+
298+
test("Map", () => {
299+
expect(
300+
diff(
301+
{
302+
m: new Map([
303+
["x", 1],
304+
["y", 2],
305+
]),
306+
},
307+
{
308+
m: new Map([
309+
["x", 1],
310+
["y", 2],
311+
]),
312+
}
313+
)
314+
).toEqual([]);
315+
316+
expect(
317+
diff(
318+
{
319+
m: new Map([
320+
["x", 1],
321+
["y", 2],
322+
]),
323+
},
324+
{
325+
m: new Map([
326+
["x", 5],
327+
["y", 2],
328+
]),
329+
}
330+
)
331+
).toEqual([
332+
{
333+
t: 2,
334+
p: ["m"],
335+
v: new Map([
336+
["x", 5],
337+
["y", 2],
338+
]),
339+
},
340+
]);
341+
});
342+
343+
test("Set", () => {
344+
let a = { s: new Set([1, 2, 3]) };
345+
let b = { s: new Set([1, 2, 3]) };
346+
expect(diff(a, b)).toEqual([]);
347+
348+
a = { s: new Set([1, 3, 5, 2, 4]) };
349+
b = { s: new Set([1, 2, 3]) };
350+
expect(diff(a, b)).toEqual([{ t: 2, p: ["s"], v: new Set([1, 2, 3]) }]);
185351
});
186352
});

packages/obj-diff/package.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,6 @@
4242
"access": "public",
4343
"provenance": true
4444
},
45-
"dependencies": {
46-
"@opentf/std": "^0.10.0"
47-
},
4845
"devDependencies": {
4946
"@types/jest": "^29.5.12",
5047
"tsup": "^8.0.2",

0 commit comments

Comments
 (0)