diff --git a/reflections/shape/shape-test.js b/reflections/shape/shape-test.js index 7ead2ca..0ba54fe 100644 --- a/reflections/shape/shape-test.js +++ b/reflections/shape/shape-test.js @@ -711,6 +711,41 @@ QUnit.test("assignDeepList", function(){ ], "assigned right"); }); +QUnit.test("assignDeep copy #150", function() { + var obj = {}; + var objMap = {prop: { foo: 'bar' }}; + getSetReflections.setKeyValue(objMap.prop,canSymbol.for("can.onValue"), function(){}); + shapeReflections.assignDeep(obj, objMap); + QUnit.notEqual(obj.prop, objMap.prop, "copy without referencing"); +}); + +QUnit.test("assign-deep with a constructor #150", function() { + var Example = {}; + getSetReflections.setKeyValue(Example,canSymbol.for("can.new"), function(){ + return this; + }); + + var objMap = {}; + + shapeReflections.assignDeep(objMap, {nested: Example}); + ok(objMap.nested === Example); +}); + +QUnit.test("assign-deep with duplicate objects #150", function() { + var me = { + name: "Justin" + }; + + var references = { + husband: me, + friend: me + }; + + var ref = {}; + shapeReflections.assignDeep(ref, references); + ok(ref.husband === ref.friend, "multiple properties point to the same thing"); +}); + /*QUnit.test("getAllEnumerableKeys", function(){ diff --git a/reflections/shape/shape.js b/reflections/shape/shape.js index 17235fc..88ac4af 100644 --- a/reflections/shape/shape.js +++ b/reflections/shape/shape.js @@ -813,18 +813,29 @@ shapeReflections = { return target; }, assignDeepMap: function(target, source) { - + var hasOwnKey = fastHasOwnKey(target); var getKeyValue = target[getKeyValueSymbol] || shiftedGetKeyValue; var setKeyValue = target[setKeyValueSymbol] || shiftedSetKeyValue; + var serialized = new Map(); + var serializedNewVal; shapeReflections.eachKey(source, function(newVal, key){ if(!hasOwnKey(key)) { - // set no matter what - getSetReflections.setKeyValue(target, key, newVal); + if (newVal && (typeReflections.isConstructorLike(newVal) || typeReflections.isPrimitive(newVal) || typeReflections.isPlainObject(newVal) === false)) { + // set no matter what + getSetReflections.setKeyValue(target, key, newVal); + } else { + serializedNewVal = serialized.get(newVal); + if (!serializedNewVal) { + serializedNewVal = shapeReflections.serialize(newVal); + serialized.set(newVal, serializedNewVal); + } + setKeyValue.call(target, key, serializedNewVal); + } } else { var curVal = getKeyValue.call(target, key); - + // if either was primitive, no recursive update possible if(newVal === curVal) { // do nothing