Skip to content

Commit 8ae0c4b

Browse files
feat(deepMerge): enhance merging logic for built-in objects
1 parent a272d3b commit 8ae0c4b

2 files changed

Lines changed: 92 additions & 2 deletions

File tree

packages/helpers/src/merge.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { isEqual, isObject, isUndefined } from './is.js';
1+
import { isEqual, isPlainObject, isUndefined } from './is.js';
22

33
/**
44
* Deeply merges two objects.
@@ -11,7 +11,7 @@ export function deepMerge(target, source) {
1111
return target;
1212
}
1313

14-
if (!isObject(source) || !isObject(target) || isEqual(target, source)) {
14+
if (!isPlainObject(source) || !isPlainObject(target) || isEqual(target, source)) {
1515
return source;
1616
}
1717

packages/helpers/src/merge.test.js

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,5 +85,95 @@ describe('helpers', () => {
8585

8686
expect(result).toStrictEqual({ a: { b: { c: 1, d: 2 } } });
8787
});
88+
89+
describe('Built-in objects', () => {
90+
it('should overwrite RegExp objects instead of merging', () => {
91+
const target = { r: /abc/i };
92+
const source = { r: /def/g };
93+
const result = deepMerge(target, source);
94+
95+
expect(result.r).toBeInstanceOf(RegExp);
96+
expect(result.r).toStrictEqual(/def/g);
97+
expect(result.r).toBe(source.r);
98+
});
99+
100+
it('should overwrite Map objects instead of merging', () => {
101+
const map1 = new Map([['a', 1]]);
102+
const map2 = new Map([['b', 2]]);
103+
const target = { m: map1 };
104+
const source = { m: map2 };
105+
const result = deepMerge(target, source);
106+
107+
expect(result.m).toBeInstanceOf(Map);
108+
expect(Array.from(result.m.entries())).toStrictEqual([['b', 2]]);
109+
expect(result.m).toBe(map2);
110+
});
111+
112+
it('should overwrite Set objects instead of merging', () => {
113+
const set1 = new Set([1, 2]);
114+
const set2 = new Set([3, 4]);
115+
const target = { s: set1 };
116+
const source = { s: set2 };
117+
const result = deepMerge(target, source);
118+
119+
expect(result.s).toBeInstanceOf(Set);
120+
expect(Array.from(result.s)).toStrictEqual([3, 4]);
121+
expect(result.s).toBe(set2);
122+
});
123+
124+
describe('Date objects', () => {
125+
it('should overwrite Date objects instead of merging', () => {
126+
const date1 = new Date('2020-01-01T00:00:00Z');
127+
const date2 = new Date('2021-01-01T00:00:00Z');
128+
const target = { a: date1 };
129+
const source = { a: date2 };
130+
const result = deepMerge(target, source);
131+
132+
expect(result.a).toBeInstanceOf(Date);
133+
expect(result.a).toStrictEqual(date2);
134+
expect(result.a).toBe(date2);
135+
});
136+
137+
it('should handle Date in nested objects', () => {
138+
const date1 = new Date('2020-01-01T00:00:00Z');
139+
const date2 = new Date('2021-01-01T00:00:00Z');
140+
const target = { nested: { d: date1 } };
141+
const source = { nested: { d: date2 } };
142+
const result = deepMerge(target, source);
143+
144+
expect(result.nested.d).toBeInstanceOf(Date);
145+
expect(result.nested.d).toStrictEqual(date2);
146+
expect(result.nested.d).toBe(date2);
147+
});
148+
149+
it('should return the source Date reference when both are Date objects with the same value', () => {
150+
const date = '2022-05-05T12:00:00Z';
151+
const target = { a: new Date(date) };
152+
const source = { a: new Date(date) };
153+
const result = deepMerge(target, source);
154+
155+
expect(result.a).toBe(source.a);
156+
});
157+
158+
it('should overwrite Date object with primitive value', () => {
159+
const date = new Date('2020-01-01T00:00:00Z');
160+
const target = { a: date };
161+
const source = { a: '2021-01-01' };
162+
const result = deepMerge(target, source);
163+
164+
expect(result).toStrictEqual({ a: '2021-01-01' });
165+
});
166+
167+
it('should overwrite primitive value with Date object', () => {
168+
const date = new Date('2020-01-01T00:00:00Z');
169+
const target = { a: '2021-01-01' };
170+
const source = { a: date };
171+
const result = deepMerge(target, source);
172+
173+
expect(result).toStrictEqual({ a: date });
174+
expect(result.a).toBe(date);
175+
});
176+
});
177+
});
88178
});
89179
});

0 commit comments

Comments
 (0)