Skip to content

Commit

Permalink
Also handle cloneProtoObject in mergeObject (#45)
Browse files Browse the repository at this point in the history
  • Loading branch information
segevfiner authored Dec 22, 2024
1 parent be5193b commit bc2075c
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 5 deletions.
20 changes: 15 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,21 @@ function deepmergeConstructor (options) {
}

for (i = 0, il = sourceKeys.length; i < il; ++i) {
isNotPrototypeKey(key = sourceKeys[i]) &&
(
(key in target && (targetKeys.indexOf(key) !== -1 && (result[key] = _deepmerge(target[key], source[key])), true)) ||
(result[key] = clone(source[key]))
)
if (!isNotPrototypeKey(key = sourceKeys[i])) {
continue
}

if (key in target) {
if (targetKeys.indexOf(key) !== -1) {
if (cloneProtoObject && isMergeableObject(source[key]) && Object.getPrototypeOf(source[key]) !== JSON_PROTO) {
result[key] = cloneProtoObject(source[key])
} else {
result[key] = _deepmerge(target[key], source[key])
}
}
} else {
result[key] = clone(source[key])
}
}
return result
}
Expand Down
23 changes: 23 additions & 0 deletions test/merge-proto-objects.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ const { Readable } = require('node:stream')
const deepmerge = require('../index')
const { test } = require('tape')

class Foo {
constructor (foo) {
this.foo = foo
}
}

test('merge nested objects should be immutable', function (t) {
t.plan(3)
const src = {
Expand Down Expand Up @@ -86,6 +92,23 @@ test('should not merge the buffers when cloned by reference', async t => {
t.same(result.logger.buffer, Buffer.of(1, 2, 3))
})

test('should clone by reference with proto object in both source and target', async t => {
t.plan(4)
const foo2 = new Foo(2)
const result = deepmerge({
cloneProtoObject (x) {
t.ok(x instanceof Foo)
return x
}
})(
{ foo: new Foo(1) },
{ foo: foo2 }
)
t.equal(typeof result.foo, 'object')
t.ok(result.foo instanceof Foo)
t.same(result.foo, foo2)
})

test('doc example', async t => {
const stream = process.stdout

Expand Down

0 comments on commit bc2075c

Please sign in to comment.