1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Text;
5: using Xunit;
6: using System.Collections.ObjectModel;
7:
8: namespace Binder
9: {
10: public class ObjectBinderFacts
11: {
12: public class The_Copy_Method
13: {
14:
15: [Fact]
16: public void throws_if_source_is_null()
17: {
18:
19: Exception ex = Record.Exception(() => ObjectBinder.Copy<Destination>(null));
20:
21: Assert.IsType<ArgumentNullException>(ex);
22: Assert.Equal("source", ((ArgumentNullException)ex).ParamName);
23: }
24:
25: [Fact]
26: public void will_copy_assignable_scalar_property()
27: {
28: var source = new Source();
29:
30: var res = ObjectBinder.Copy<Destination>(source);
31:
32: Assert.Equal(source.A, res.A);
33: Assert.Equal(source.B, res.B);
34: Assert.Equal(source.C, res.C);
35: Assert.Equal(source.D, res.D);
36: Assert.Equal(source.E, res.E);
37:
38: }
39:
40: [Fact]
41: public void will_copy_assignable_generic_list_property()
42: {
43: var source = new Source();
44:
45: var res = ObjectBinder.Copy<Destination>(source);
46:
47: Assert.Equal(source.F.Count, res.F.Count);
48: Assert.Equal(source.F[0], res.F[0]);
49: Assert.Equal(source.F[1], res.F[1]);
50:
51: }
52:
53: [Fact]
54: public void will_copy_assignable_array_property()
55: {
56: var source = new Source();
57:
58: var res = ObjectBinder.Copy<Destination>(source);
59:
60: Assert.Equal(source.N.Length, res.N.Length);
61: Assert.Equal(source.N[0], res.N[0]);
62: Assert.Equal(source.N[1], res.N[1]);
63:
64: }
65:
66: [Fact]
67: public void will_copy_unassignable_array_property()
68: {
69: var source = new Source();
70:
71: var res = ObjectBinder.Copy<Destination>(source);
72:
73: Assert.Equal(source.O.Length, res.O.Length);
74: Assert.Equal(source.O[0].Value, res.O[0].Value);
75: Assert.Equal(source.O[1].Value, res.O[1].Value);
76:
77: }
78:
79: [Fact]
80: public void will_copy_assignable_generic_dictionary_property()
81: {
82: var source = new Source();
83:
84: var res = ObjectBinder.Copy<Destination>(source);
85:
86: Assert.Equal(source.J.Count, res.J.Count);
87: Assert.Equal(source.J["a"], res.J["a"]);
88: Assert.Equal(source.J["b"], res.J["b"]);
89:
90: }
91:
92: [Fact]
93: public void will_copy_unassignable_generic_dictionary_with_assignable_keys_and_values()
94: {
95: var source = new Source();
96:
97: var res = ObjectBinder.Copy<Destination>(source);
98:
99: Assert.Equal(source.K.Count, res.K.Count);
100: Assert.Equal(source.K["a"], res.K["a"]);
101: Assert.Equal(source.K["b"], res.K["b"]);
102:
103: }
104:
105: [Fact]
106: public void will_copy_unassignable_generic_dictionary_with_assignable_keys_and_unassignable_values()
107: {
108: var source = new Source();
109:
110: var res = ObjectBinder.Copy<Destination>(source);
111:
112: Assert.Equal(source.L.Count, res.L.Count);
113: Assert.Equal(source.L["a"].Value, res.L["a"].Value);
114: Assert.Equal(source.L["b"].Value, res.L["b"].Value);
115:
116: }
117:
118: [Fact]
119: public void will_copy_unassignable_generic_dictionary_with_unassignable_keys_and_unassignable_values()
120: {
121: var source = new Source();
122:
123: var res = ObjectBinder.Copy<Destination>(source);
124:
125: Assert.Equal(source.M.Count, res.M.Count);
126: Assert.Equal(source.M[new SomeObject { Value = 1 }].Value, res.M[new OtherObject { Value = 1 }].Value);
127: Assert.Equal(source.M[new SomeObject { Value = 2 }].Value, res.M[new OtherObject { Value = 2 }].Value);
128:
129: }
130:
131: [Fact]
132: public void will_copy_unassignable_generic_list_with_assignable_values()
133: {
134: var source = new Source();
135:
136: var res = ObjectBinder.Copy<Destination>(source);
137:
138: Assert.Equal(source.G.Count, res.G.Count);
139: Assert.Equal(source.G[0], res.G[0]);
140: Assert.Equal(source.G[1], res.G[1]);
141:
142: }
143:
144: [Fact]
145: public void will_copy_unassignable_object_property()
146: {
147: var source = new Source();
148:
149: var res = ObjectBinder.Copy<Destination>(source);
150:
151: Assert.Equal(source.H.Value, res.H.Value);
152:
153: }
154:
155: [Fact]
156: public void will_copy_unassignable_generic_list_properties()
157: {
158: var source = new Source();
159:
160: var res = ObjectBinder.Copy<Destination>(source);
161:
162: Assert.Equal(source.I.Count, res.I.Count);
163: Assert.Equal(source.I[0].Value, res.I[0].Value);
164: Assert.Equal(source.I[1].Value, res.I[1].Value);
165:
166: }
167:
168: [Fact]
169: public void will_return_object_with_default_values_if_no_properties_match()
170: {
171: var source = new Source();
172:
173: var res = ObjectBinder.Copy<SomeObject>(source);
174:
175: Assert.Equal(0, res.Value);
176: }
177:
178: class SomeObject
179: {
180: public int Value { get; set; }
181:
182: public override int GetHashCode()
183: {
184: return Value;
185: }
186:
187: public override bool Equals(object obj)
188: {
189: var some = obj as SomeObject;
190: if (obj == null) return false;
191: return some.Value == Value;
192: }
193: }
194:
195: class OtherObject
196: {
197: public int Value { get; set; }
198:
199: public override int GetHashCode()
200: {
201: return Value;
202: }
203:
204: public override bool Equals(object obj)
205: {
206: var some = obj as OtherObject;
207: if (obj == null) return false;
208: return some.Value == Value;
209: }
210: }
211:
212: class OtherDictionary<TKey, TValue> : Dictionary<TKey, TValue>
213: {
214:
215: }
216:
217: class Source
218: {
219: public Source()
220: {
221: A = "String";
222: B = 5;
223: C = Guid.NewGuid();
224: D = 5.5;
225: E = 'a';
226: F = new List<int> { 1, 2 };
227: G = new List<string> { "a", "b" };
228: H = new SomeObject();
229: I = new List<SomeObject> { new SomeObject { Value = 1 }, new SomeObject { Value = 2 } };
230: J = new Dictionary<string, int> { { "a", 1 }, { "b", 2 } };
231: K = new Dictionary<string, int> { { "a", 1 }, { "b", 2 } };
232: L = new Dictionary<string, SomeObject> { { "a", new SomeObject { Value = 1 } }, { "b", new SomeObject { Value = 2 } } };
233: M = new Dictionary<SomeObject, SomeObject> {
234: { new SomeObject { Value = 1 }, new SomeObject { Value = 10 } },
235: { new SomeObject { Value = 2 }, new SomeObject { Value = 20 } }
236: };
237: N = new[] { 1, 2 };
238: O = new[] { new SomeObject { Value = 1 }, new SomeObject { Value = 2 } };
239: }
240:
241: // Assignable
242: public string A { get; set; }
243: public int B { get; set; }
244: public Guid C { get; set; }
245: public double D { get; set; }
246: public char E { get; set; }
247: public List<int> F { get; set; }
248: public Dictionary<string, int> J { get; set; }
249: public int[] N { get; set; }
250:
251: // Not assignable
252: public List<string> G { get; set; }
253: public SomeObject H { get; set; }
254: public List<SomeObject> I { get; set; }
255: public Dictionary<string, int> K { get; set; }
256: public Dictionary<string, SomeObject> L { get; set; }
257: public Dictionary<SomeObject, SomeObject> M { get; set; }
258: public SomeObject[] O { get; set; }
259: }
260:
261:
262: class Destination
263: {
264: public string A { get; set; }
265: public int B { get; set; }
266: public Guid C { get; set; }
267: public double D { get; set; }
268: public char E { get; set; }
269: public List<int> F { get; set; }
270: public Dictionary<string, int> J { get; set; }
271: public int[] N { get; set; }
272:
273: public Collection<string> G { get; set; }
274: public OtherObject H { get; set; }
275: public List<OtherObject> I { get; set; }
276: public OtherDictionary<string, int> K { get; set; }
277: public Dictionary<string, OtherObject> L { get; set; }
278: public Dictionary<OtherObject, OtherObject> M { get; set; }
279: public OtherObject[] O { get; set; }
280: }
281: }
282: }
283: }