Skip to content

Commit b159f54

Browse files
committedNov 26, 2018
Support symbol properties and keys in cloneWithShallow()
1 parent 9fa34af commit b159f54

File tree

2 files changed

+34
-13
lines changed

2 files changed

+34
-13
lines changed
 

‎lib/index.js

+10-10
Original file line numberDiff line numberDiff line change
@@ -201,19 +201,21 @@ exports.cloneWithShallow = function (source, keys) {
201201

202202
const storage = internals.store(source, keys); // Move shallow copy items to storage
203203
const copy = exports.clone(source); // Deep copy the rest
204-
internals.restore(copy, source, storage); // Shallow copy the stored items and restore
204+
internals.restore(copy, source, storage); // Shallow copy the stored items and restore
205205
return copy;
206206
};
207207

208208

209209
internals.store = function (source, keys) {
210210

211-
const storage = {};
211+
const storage = new Map();
212212
for (let i = 0; i < keys.length; ++i) {
213213
const key = keys[i];
214214
const value = exports.reach(source, key);
215-
if (value !== undefined) {
216-
storage[key] = value;
215+
if (typeof value === 'object' ||
216+
typeof value === 'function') {
217+
218+
storage.set(key, value);
217219
internals.reachSet(source, key, undefined);
218220
}
219221
}
@@ -224,18 +226,16 @@ internals.store = function (source, keys) {
224226

225227
internals.restore = function (copy, source, storage) {
226228

227-
const keys = Object.keys(storage);
228-
for (let i = 0; i < keys.length; ++i) {
229-
const key = keys[i];
230-
internals.reachSet(copy, key, storage[key]);
231-
internals.reachSet(source, key, storage[key]);
229+
for (const [key, value] of storage) {
230+
internals.reachSet(copy, key, value);
231+
internals.reachSet(source, key, value);
232232
}
233233
};
234234

235235

236236
internals.reachSet = function (obj, key, value) {
237237

238-
const path = key.split('.');
238+
const path = Array.isArray(key) ? key : key.split('.');
239239
let ref = obj;
240240
for (let i = 0; i < path.length; ++i) {
241241
const segment = path[i];

‎test/index.js

+24-3
Original file line numberDiff line numberDiff line change
@@ -749,14 +749,16 @@ describe('cloneWithShallow()', () => {
749749
},
750750
c: {
751751
d: 6
752-
}
752+
},
753+
e() {}
753754
};
754755

755-
const copy = Hoek.cloneWithShallow(source, ['c']);
756+
const copy = Hoek.cloneWithShallow(source, ['c', 'e']);
756757
expect(copy).to.equal(source);
757758
expect(copy).to.not.shallow.equal(source);
758759
expect(copy.a).to.not.shallow.equal(source.a);
759-
expect(copy.b).to.equal(source.b);
760+
expect(copy.c).to.shallow.equal(source.c);
761+
expect(copy.e).to.shallow.equal(source.e);
760762
});
761763

762764
it('returns immutable value', () => {
@@ -791,6 +793,25 @@ describe('cloneWithShallow()', () => {
791793
expect(copy.a).to.not.shallow.equal(source.a);
792794
expect(copy.b).to.equal(source.b);
793795
});
796+
797+
it('supports symbols', () => {
798+
799+
const sym = Symbol();
800+
const source = {
801+
a: {
802+
b: 5
803+
},
804+
[sym]: {
805+
d: 6
806+
}
807+
};
808+
809+
const copy = Hoek.cloneWithShallow(source, [[sym]]);
810+
expect(copy).to.equal(source);
811+
expect(copy).to.not.shallow.equal(source);
812+
expect(copy.a).to.not.shallow.equal(source.a);
813+
expect(copy[sym]).to.equal(source[sym]);
814+
});
794815
});
795816

796817
describe('applyToDefaultsWithShallow()', () => {

0 commit comments

Comments
 (0)
Please sign in to comment.