Skip to content

Commit

Permalink
Bugfix for CQ.Extend updating poco properties
Browse files Browse the repository at this point in the history
  • Loading branch information
jamietre committed Mar 18, 2013
1 parent f206cec commit cd7e965
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 59 deletions.
1 change: 1 addition & 0 deletions source/CsQuery.Tests/Csquery.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@
<Compile Include="Implementation\RangeSortedDictionary.cs" />
<Compile Include="Miscellaneous\Miscellaneous2.cs" />
<Compile Include="Mocks\MockAsyncResult.cs" />
<Compile Include="Utility\Extend.cs" />
<Compile Include="Utility\Support.cs" />
<Compile Include="Utility\FastActivator.cs" />
<Compile Include="Examples\Tables.cs" />
Expand Down
148 changes: 148 additions & 0 deletions source/CsQuery.Tests/Utility/Extend.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using System.Dynamic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NUnit.Framework;
using Assert = NUnit.Framework.Assert;
using Description = NUnit.Framework.DescriptionAttribute;
using TestContext = Microsoft.VisualStudio.TestTools.UnitTesting.TestContext;
using CsQuery;
using CsQuery.Utility;
using CsQuery.ExtensionMethods;

namespace CsQuery.Tests.Utility
{

/// <summary>
/// Basic JSON class tests
/// </summary>
[TestFixture, TestClass]
public class Extend_
{

[Test,TestMethod]
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");
}

[Test, TestMethod]
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");

}


[Test, TestMethod]
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");

}

[Test,TestMethod]
public void ExtendEnumerable()
{
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
}


#region Test data structures

protected class TestExpando
{
public string Property1 { get; set; }
public string Field1;
}

protected class TestClass1
{
public string Prop1 { get; set; }
public string Prop2 { get; set; }
}
protected class TestClass2
{
public string Prop2;
public string Prop3;
}
protected class TestClass3
{
public List<string> list = new List<string>(new string[] {"item1","item2"});
public List<object> listMixed= new List<object>();
public TestClass3() {
listMixed.Add(3);
listMixed.Add("hello");
TestClass1 tc1 = new TestClass1();
tc1.Prop1="TC1 value1";
tc1.Prop2 = null;
listMixed.Add(tc1);
listMixed.Add(999);

}
public double floatingPointProp = 123.33;
public string stringProp = "asdad";
}

#endregion
}
}
58 changes: 1 addition & 57 deletions source/CsQuery.Tests/Utility/JSON.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,63 +147,7 @@ public void TestJsObject()
}


[Test,TestMethod]
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");

}
[Test,TestMethod]
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
}



#region Test data structures

Expand Down
2 changes: 1 addition & 1 deletion source/CsQuery/Objects.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1569,7 +1569,7 @@ private static void AddExtendKVP(bool deep, HashSet<object> parents, object targ
{
continue;
}
propInfo.GetSetMethod().Invoke(value, null);
propInfo.GetSetMethod().Invoke(target,new object[] {value});

}
else if (member is FieldInfo)
Expand Down
2 changes: 1 addition & 1 deletion source/CsQuery/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]

[assembly: AssemblyVersion("1.3.5.64")]
[assembly: AssemblyVersion("1.3.5.68")]
//[assembly: AssemblyFileVersion("1.3.3")]

1 change: 1 addition & 0 deletions source/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Please see the main [readme](https://github.com/jamietre/CsQuery/blob/master/REA
- [Issue #82](https://github.com/jamietre/CsQuery/issues/82) `DomObject.Text` property not returning correct text when nested text nodes are present
- Index not being updated correctly for some node removals
- `this[int index]` indexer property not implemented on `DomDocument`. Moved implementation from `DomElement` to `DomContainer` to ensure it's available for all container nodes.
- Fix bug in `CsQuery.Extend` when updating POCO properties

**Performance improvements**

Expand Down

0 comments on commit cd7e965

Please sign in to comment.