Mercurial > pub > bltoolkit
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 } |