public void ExtendPocoFromDynamic() { TestClass1 t1 = new TestClass1(); t1.Prop1 = "value1"; t1.Prop2 = "value2"; dynamic t2 = new JsObject(); t2.Prop2 = "class2value2"; t2.Prop3 = "class2vlaue3"; CQ.Extend(t1, t2); Assert.AreEqual("value1", t1.Prop1, "Target prop1 unchanged"); Assert.AreEqual("class2value2", t1.Prop2, "Target prop2 updated"); }
public void Extend2() { dynamic test = "{ prop1: 'val1', prop2: 'val2',prop3: 'original'}".ParseJSON(); dynamic test2 = "{ prop1: 'from_enum1'}".ParseJSON(); dynamic test3 = "{ prop2: 'from_enum2'}".ParseJSON(); // will not work -- regular enumerables treated like objects //var enumer = new List<IDynamicMetaObjectProvider>(); var enumer = new object[2]; enumer[0] = test2; enumer[1] = test3; var merged = CQ.Extend(null, test, enumer); Assert.AreEqual("{prop1: 'from_enum1', prop2: 'from_enum2', prop3: 'original'}".ParseJSON(), merged, "Merged with an enumerable parameter"); Assert.AreNotEqual("{prop1: 'from_enum1', prop2: 'from_enum2'}".ParseJSON(), merged, "Sanity check"); // TODO: Test copying from an object with properties that return errors }
public void ExtendPoco() { // Test "extending" regular objects (property copy) TestClass1 t1 = new TestClass1(); t1.Prop1 = "value1"; t1.Prop2 = "value2"; TestClass2 t2 = new TestClass2(); t2.Prop2 = "class2value2"; t2.Prop3 = "class2vlaue3"; CQ.Extend(t1, t2); Assert.AreEqual("value1", t1.Prop1, "Target prop1 unchanged"); Assert.AreEqual("class2value2", t1.Prop2, "Target prop2 updated"); }
public void Extend() { var test = new TestExpando(); test.Field1 = "Value from Real Object"; test.Property1 = "ValueFromProp"; dynamic test2 = new ExpandoObject(); test2.ExField1 = "Value from Expando"; var exField2 = new string[] { "el1", "el2" }; test2.ExField2 = exField2; dynamic target = CQ.Extend(null, test); Assert.AreEqual("Value from Real Object", target.Field1, "Appended a regular object field to an expando object"); Assert.AreEqual("ValueFromProp", target.Property1, "Appended a regular object property to an expando object"); CQ.Extend(target, test2); Assert.AreEqual("Value from Expando", target.ExField1, "Appended an expando object property to an expando object"); Assert.AreEqual(exField2, target.ExField2, "Appended a regular object property to an expando object"); // Test "extending" regular objects (property copy) TestClass1 t1 = new TestClass1(); t1.Prop1 = "value1"; t1.Prop2 = "value2"; TestClass2 t2 = new TestClass2(); t2.Prop2 = "class2value2"; t2.Prop3 = "class2vlaue3"; CQ.Extend(t1, t2); Assert.AreEqual("value1", t1.Prop1, "Target prop1 unchanged"); Assert.AreEqual("class2value2", t1.Prop2, "Target prop2 updated"); }
public void ExtendExpando() { var test = new TestExpando(); test.Field1 = "Value from Real Object"; test.Property1 = "ValueFromProp"; dynamic test2 = new ExpandoObject(); test2.ExField1 = "Value from Expando"; var exField2 = new string[] { "el1", "el2" }; test2.ExField2 = exField2; dynamic target = CQ.Extend(null, test); Assert.AreEqual("Value from Real Object", target.Field1, "Appended a regular object field to an expando object"); Assert.AreEqual("ValueFromProp", target.Property1, "Appended a regular object property to an expando object"); CQ.Extend(target, test2); Assert.AreEqual("Value from Expando", target.ExField1, "Appended an expando object property to an expando object"); Assert.AreEqual(exField2, target.ExField2, "Appended a regular object property to an expando object"); }
public void Extend() { dynamic settings = CQ.ParseJSON("{ 'xnumber1': 5, 'xnumber2': 7, 'xstring1': 'peter', 'xstring2': 'pan' }"); dynamic options = CQ.ParseJSON("{ 'xnumber2': 1, 'xstring2': 'x', 'xxx': 'newstring'}"); dynamic optionsCopy = CQ.ParseJSON("{ 'xnumber2': 1, 'xstring2': 'x', 'xxx': 'newstring' }"); dynamic merged = CQ.ParseJSON("{ 'xnumber1': 5, 'xnumber2': 1, 'xstring1': 'peter', 'xstring2': 'x', 'xxx': 'newstring' }"); dynamic deep1 = CQ.ParseJSON("{ 'foo': { 'bar': true } }"); dynamic deep1copy = CQ.ParseJSON("{ 'foo': { 'bar': true } }"); dynamic deep2 = CQ.ParseJSON("{ 'foo': { 'baz': true }, 'foo2': 'document' }"); dynamic deep2copy = CQ.ParseJSON("{ 'foo': { 'baz': true }, 'foo2': 'document' }"); dynamic deepmerged = CQ.ParseJSON("{ 'foo': { 'bar': true, 'baz': true }, 'foo2': 'document' }"); var arr = new int[] { 1, 2, 3 }; dynamic nestedarray = new ExpandoObject(); nestedarray.arr = arr; CQ.Extend(settings, options); Assert.AreEqual(merged, settings, "Check if extended: settings must be extended"); Assert.AreEqual(optionsCopy, options, "Check if not modified: options must not be modified"); CQ.Extend(settings, null, options); Assert.AreEqual(settings, merged, "Check if extended: settings must be extended"); Assert.AreEqual(optionsCopy, options, "Check if not modified: options must not be modified"); // Test deep copying CQ.Extend(true, deep1, deep2); Assert.AreEqual(deepmerged.foo, deep1.foo, "Check if foo: settings must be extended"); Assert.AreEqual(deep2copy.foo, deep2.foo, "Check if not deep2: options must not be modified"); // n/a //Assert.AreEqual(document, deep1.foo2, "Make sure that a deep clone was not attempted on the document"); var nullUndef = CQ.Extend(null, options, CQ.ParseJSON("{ 'xnumber2': null }")); Assert.IsTrue(nullUndef.xnumber2 == null, "Check to make sure null values are copied"); nullUndef = CQ.Extend(null, options, CQ.ParseJSON("{ 'xnumber0': null }")); Assert.IsTrue(nullUndef.xnumber0 == null, "Check to make sure null values are inserted"); // Test nested arrays dynamic extendedArr = CQ.Extend(true, null, nestedarray); Assert.AreNotSame(extendedArr.arr, arr, "Deep extend of object must clone child array"); Assert.AreNotSame(extendedArr.arr, arr, "Deep extend of object must clone child array"); // #5991 dynamic emptyArrObj = CQ.ParseJSON("{ arr: {} }"); dynamic extendedArr2 = CQ.Extend(true, emptyArrObj, nestedarray); Assert.IsTrue(extendedArr2.arr is IEnumerable, "Cloned array heve to be an Array"); dynamic simpleArrObj = new ExpandoObject(); simpleArrObj.arr = arr; emptyArrObj = CQ.ParseJSON("{ arr: {} }"); dynamic result = CQ.Extend(true, simpleArrObj, emptyArrObj); Assert.IsTrue(!(result.arr is Array), "Cloned object heve to be an plain object"); dynamic empty = new JsObject(); dynamic optionsWithLength = CQ.ParseJSON("{ 'foo': { 'length': -1 } }"); CQ.Extend(true, empty, optionsWithLength); Assert.AreEqual(empty.foo, optionsWithLength.foo, "The length property must copy correctly"); //? not really relevant empty = new JsObject(); dynamic optionsWithDate = new JsObject(); optionsWithDate.foo = new JsObject(); optionsWithDate.foo.date = new DateTime(); CQ.Extend(true, empty, optionsWithDate); Assert.AreEqual(empty.foo, optionsWithDate.foo, "Dates copy correctly"); var customObject = DateTime.Now; dynamic optionsWithCustomObject = new { foo = new { date = customObject } }; empty = CQ.Extend(true, null, optionsWithCustomObject); Assert.IsTrue(empty.foo != null && empty.foo.date == customObject, "Custom objects copy correctly (no methods)"); //// Makes the class a little more realistic //myKlass.prototype = { someMethod: function(){} }; //empty = {}; //jQuery.extend(true, empty, optionsWithCustomObject); //ok( empty.foo && empty.foo.date === customObject, "Custom objects copy correctly" ); dynamic ret = CQ.Extend(true, CQ.ParseJSON("{'foo': 4 }"), new { foo = 5 }); Assert.IsTrue(ret.foo == 5, "Wrapped numbers copy correctly"); nullUndef = CQ.Extend(null, options, "{ 'xnumber2': null }"); Assert.IsTrue(nullUndef.xnumber2 == null, "Check to make sure null values are copied"); // nullUndef = jQuery.extend({}, options, { xnumber2: undefined }); // ok( nullUndef.xnumber2 === options.xnumber2, "Check to make sure undefined values are not copied"); nullUndef = CQ.Extend(null, options, "{ 'xnumber0': null }"); Assert.IsTrue(nullUndef.xnumber0 == null, "Check to make sure null values are inserted"); dynamic target = new ExpandoObject(); dynamic recursive = new ExpandoObject(); recursive.bar = 5; recursive.foo = target; CQ.Extend(true, target, recursive); dynamic compare = CQ.ParseJSON("{ 'bar':5 }"); Assert.AreEqual(target, compare, "Check to make sure a recursive obj doesn't go never-ending loop by not copying it over"); // These next checks don't really apply as they are specific to javascript nuances, but can't hurt ret = CQ.Extend(true, CQ.ParseJSON(" { 'foo': [] }"), CQ.ParseJSON("{ 'foo': [0] }")); // 1907 // arrays are returned as List<object> when casting to expando object Assert.AreEqual(1, ret.foo.Count, "Check to make sure a value with coersion 'false' copies over when necessary to fix #1907"); ret = CQ.Extend(true, CQ.ParseJSON("{ 'foo': '1,2,3' }"), CQ.ParseJSON("{ 'foo': [1, 2, 3] }")); Assert.IsTrue(!(ret.foo is string), "Check to make sure values equal with coersion (but not actually equal) overwrite correctly"); dynamic obj = CQ.ParseJSON("{ 'foo':null }"); CQ.Extend(true, obj, CQ.ParseJSON("{ 'foo':'notnull' }")); Assert.AreEqual(obj.foo, "notnull", "Make sure a null value can be overwritten"); // function func() {} // jQuery.extend(func, { key: "value" } ); // equals( func.key, "value", "Verify a function can be extended" ); dynamic defaults = CQ.ParseJSON("{ 'xnumber1': 5, 'xnumber2': 7, 'xstring1': 'peter', 'xstring2': 'pan' }"); dynamic defaultsCopy = CQ.ParseJSON(" { xnumber1: 5, xnumber2: 7, xstring1: 'peter', xstring2: 'pan' }"); dynamic options1 = CQ.ParseJSON("{ xnumber2: 1, xstring2: 'x' }"); dynamic options1Copy = CQ.ParseJSON(" { xnumber2: 1, xstring2: 'x' }"); dynamic options2 = CQ.ParseJSON(" { xstring2: 'xx', xxx: 'newstringx'}"); dynamic options2Copy = CQ.ParseJSON(" { xstring2: 'xx', xxx: 'newstringx'}"); dynamic merged2 = CQ.ParseJSON(" { xnumber1: 5, xnumber2: 1, xstring1: 'peter', xstring2: 'xx', xxx: 'newstringx' }"); ret = CQ.Extend(true, CQ.ParseJSON(" { foo:'bar' }"), CQ.ParseJSON("{ foo:null }")); Assert.IsTrue(ret.foo == null, "Make sure a null value doesn't crash with deep extend, for #1908"); settings = CQ.Extend(null, defaults, options1, options2); Assert.AreEqual(merged2, settings, "Check if extended: settings must be extended"); Assert.AreEqual(defaults, defaultsCopy, "Check if not modified: options1 must not be modified"); Assert.AreEqual(options1, options1Copy, "Check if not modified: options1 must not be modified"); Assert.AreEqual(options2, options2Copy, "Check if not modified: options2 must not be modified"); }