comparison UnitTests/CS/Patterns/DuckTypingTest.cs @ 0:f990fcb411a9

Копия текущей версии из github
author cin
date Thu, 27 Mar 2014 21:46:09 +0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:f990fcb411a9
1 using System;
2
3 using NUnit.Framework;
4
5 using BLToolkit.Patterns;
6
7 namespace Patterns
8 {
9 [TestFixture]
10 public class DuckTypingTest
11 {
12 public interface TestInterface
13 {
14 int Method(int value);
15 void Method(int v1, out int v2);
16
17 int Prop { get; }
18
19 event EventHandler Event;
20
21 void CallEvent();
22 }
23
24 public interface TestInterface2
25 {
26 int Method(int value);
27 void I2Method(int v1, out int v2);
28 }
29
30 public class TestClass
31 {
32 public static int Field;
33
34 public int Method(int value)
35 {
36 return value + 2;
37 }
38
39 public void Method(int v1, out int v2)
40 {
41 v2 = v1;
42 }
43
44 public void I2Method(int v1, out int v2)
45 {
46 v2 = v1;
47 }
48
49 public int Prop
50 {
51 get { return 22; }
52 }
53
54 public event EventHandler Event;
55
56 public void CallEvent()
57 {
58 Event(this, EventArgs.Empty);
59 }
60 }
61
62 [Test]
63 public void Test()
64 {
65 var duck = DuckTyping.Implement<TestInterface> (new TestClass());
66 var same = DuckTyping.Implement<TestInterface> (duck);
67 var duck2 = DuckTyping.Implement<TestInterface2>(same);
68
69 Assert.AreSame(duck, same);
70
71 int value;
72 duck.Method(33, out value);
73
74 Assert.AreEqual(33, value);
75 Assert.AreEqual(42, duck.Method(40));
76 Assert.AreEqual(22, duck.Prop);
77
78 duck.Event += duck_Event;
79
80 duck.CallEvent();
81
82 Assert.AreEqual(55, eventValue);
83
84 duck2.I2Method(33, out value);
85
86 Assert.AreEqual(33, value);
87 Assert.AreEqual(42, duck2.Method(40));
88 }
89
90 int eventValue;
91
92 void duck_Event(object sender, EventArgs e)
93 {
94 eventValue = 55;
95 }
96
97 public class Child1 : TestClass
98 {
99 public new int Method(int value)
100 {
101 return value + 5;
102 }
103 }
104
105 public class Child2 : TestClass
106 {
107 public new int Method(int value)
108 {
109 return value + 10;
110 }
111 }
112
113 [Test]
114 public void BulkTest()
115 {
116 var ducks = DuckTyping.Implement<TestInterface,TestClass>(new Child1(), new Child2());
117
118 Assert.IsNotEmpty(ducks);
119 Assert.AreEqual(42, ducks[0].Method(40));
120 Assert.AreEqual(42, ducks[1].Method(40));
121 }
122
123 [Test]
124 public void BulkTest2()
125 {
126 var ducks = DuckTyping.Implement<TestInterface>(new Child1(), new Child2());
127
128 Assert.IsNotEmpty(ducks);
129 Assert.AreEqual(45, ducks[0].Method(40));
130 Assert.AreEqual(50, ducks[1].Method(40));
131 }
132
133 [Test]
134 public void InheritanceTest()
135 {
136 var duck1 = DuckTyping.Implement<TestInterface>(new Child1());
137 var duck2 = DuckTyping.Implement<TestInterface>(new Child2());
138
139 Assert.AreNotSame(duck1, duck2);
140 Assert.AreEqual(45, duck1.Method(40));
141 Assert.AreEqual(50, duck2.Method(40));
142 }
143
144 [Test]
145 public void InheritanceTest2()
146 {
147 var duck1 = DuckTyping.Implement<TestInterface,TestClass>(new Child1());
148 var duck2 = DuckTyping.Implement<TestInterface,TestClass>(new Child2());
149
150 Assert.AreNotSame(duck1, duck2);
151 Assert.AreEqual(42, duck1.Method(40));
152 Assert.AreEqual(42, duck2.Method(40));
153 }
154
155 public class StaticClass
156 {
157 public static int Method(int value)
158 {
159 return value + 3;
160 }
161 }
162
163 [Test]
164 public void StaticTest()
165 {
166 DuckTyping.AllowStaticMembers = true;
167
168 var duck = DuckTyping.Implement<TestInterface,StaticClass>(new StaticClass());
169
170 Assert.AreEqual(43, duck.Method(40));
171 }
172
173 public struct TestStruct
174 {
175 public int Method(int value)
176 {
177 return value + 3;
178 }
179 }
180
181 [Test]
182 public void StructTest()
183 {
184 DuckTyping.AllowStaticMembers = true;
185
186 var duck = DuckTyping.Implement<TestInterface>(new TestStruct());
187
188 Assert.AreEqual(43, duck.Method(40));
189 }
190
191
192 public interface GenericInterface<T>
193 {
194 T Method(T value);
195 }
196
197 public class GenericClass<T>
198 {
199 public T Method(T value)
200 {
201 return value;
202 }
203
204 public void I2Method(int v1, out int v2)
205 {
206 v2 = v1 + 2;
207 }
208 }
209
210 [Test]
211 public void GenericInterfaceTest()
212 {
213 var o = new GenericClass<int>();
214 var duck = DuckTyping.Implement<GenericInterface<int>>(o);
215 var duck2 = DuckTyping.Implement<TestInterface2> (o);
216
217 Assert.AreEqual(40, duck .Method(40));
218 Assert.AreEqual(40, duck2.Method(40));
219
220 int value;
221 duck2.I2Method (33, out value);
222 Assert.AreEqual(35, value);
223 }
224
225 [Test, ExpectedException(typeof(ArgumentNullException))]
226 public void InvalidArgTest1()
227 {
228 TestInterface o = null;
229
230 var duck1 = DuckTyping.Implement<TestInterface>(o);
231 var duck2 = (TestInterface)DuckTyping.Implement(typeof(TestInterface), o);
232 }
233
234 interface NonPublicInterface
235 {
236 }
237
238 [Test, ExpectedException(typeof(ArgumentException))]
239 public void InvalidArgTest2()
240 {
241 var duck = (NonPublicInterface)DuckTyping.Implement(typeof(NonPublicInterface), new TestClass());
242 }
243
244 [Test, ExpectedException(typeof(ArgumentException))]
245 public void InvalidArgTest3()
246 {
247 var duck = (Child1)DuckTyping.Implement(typeof(Child1), new Child2());
248 }
249
250 [Test, ExpectedException(typeof(ArgumentException))]
251 public void InvalidArgTest4()
252 {
253 var duck = (TestInterface)DuckTyping.Implement(typeof(TestInterface), typeof(TestInterface), new TestClass());
254 }
255
256 #region Aggregate
257
258 public interface IAggregatable
259 {
260 int Method1();
261 int Method2();
262 }
263
264 public interface IClass1
265 {
266 int Method1();
267 int Method3();
268 }
269
270 public interface IClass2
271 {
272 int Method2();
273 }
274
275 public class AggregateClass1: IClass1
276 {
277 public int Method1() { return 1; }
278 public int Method3() { return 3; }
279 }
280
281 public class AggregateClass2: IClass2
282 {
283 public int Method2() { return 2; }
284 }
285
286 [Test]
287 public void AggregateTest()
288 {
289 var duck = DuckTyping.Aggregate<IAggregatable>(new AggregateClass1(), new AggregateClass2());
290
291 Assert.IsNotNull(duck);
292
293 Assert.AreEqual(1, duck.Method1());
294 Assert.AreEqual(2, duck.Method2());
295
296 // It is still possible to get access
297 // to an interface of an underlying object.
298 //
299 var cls2 = DuckTyping.Implement<IClass2>(duck);
300
301 Assert.IsNotNull(cls2);
302 Assert.AreEqual(2, cls2.Method2());
303
304 // Even to switch from one aggregated object to another
305 //
306 var cls1 = DuckTyping.Implement<IClass1>(cls2);
307
308 Assert.IsNotNull(cls1);
309 Assert.AreEqual(1, cls1.Method1());
310 Assert.AreEqual(3, cls1.Method3());
311 }
312
313 [Test]
314 public void MissedMethodsAggregateTest()
315 {
316 var duck = DuckTyping.Aggregate<IClass1>(new Version(1,0), Guid.NewGuid());
317
318 Assert.That(duck, Is.Not.Null);
319
320 // Neither System.Guid nor System.Version will ever have Method1.
321 //
322 Assert.That(duck.Method1(), Is.EqualTo(0));
323 }
324
325 #endregion
326 }
327 }