Somehow missed this with earlier checkin of fluent interface.
[castle.git] / Tools / Castle.DynamicProxy2 / Castle.DynamicProxy.Tests / GenericInterfaceProxyTestCase.cs
blobee54b56fed622efbfdd472da7a7693eeba95f42b
1 // Copyright 2004-2007 Castle Project - http://www.castleproject.org/
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle.DynamicProxy.Tests
17 using System;
18 using System.Collections;
19 using System.Reflection;
20 using Castle.DynamicProxy.Generators;
21 using Castle.DynamicProxy.Tests.GenInterfaces;
22 using Castle.DynamicProxy.Tests.Interceptors;
23 using NUnit.Framework;
25 [TestFixture]
26 public class GenericInterfaceProxyTestCase : BasePEVerifyTestCase
28 private LogInvocationInterceptor logger;
30 public override void Init()
32 base.Init();
33 logger = new LogInvocationInterceptor();
36 [Test]
37 public void ProxyWithGenericArgument()
39 GenInterface<int> proxy =
40 generator.CreateInterfaceProxyWithTarget<GenInterface<int>>(
41 new GenInterfaceImpl<int>(), logger);
43 Assert.IsNotNull(proxy);
45 Assert.AreEqual(1, proxy.DoSomething(1));
47 Assert.AreEqual("DoSomething ", logger.LogContents);
50 #if !MONO
52 [Test]
53 public void ProxyWithGenericArgumentAndGenericMethod()
55 GenInterfaceWithGenMethods<int> proxy =
56 generator.CreateInterfaceProxyWithTarget<GenInterfaceWithGenMethods<int>>(
57 new GenInterfaceWithGenMethodsImpl<int>(), logger);
59 Assert.IsNotNull(proxy);
61 proxy.DoSomething<long>(10L, 1);
63 Assert.AreEqual("DoSomething ", logger.LogContents);
66 [Test]
67 public void ProxyWithGenericArgumentAndGenericMethodAndGenericReturn()
69 GenInterfaceWithGenMethodsAndGenReturn<int> proxy =
70 generator.CreateInterfaceProxyWithTarget<GenInterfaceWithGenMethodsAndGenReturn<int>>(
71 new GenInterfaceWithGenMethodsAndGenReturnImpl<int>(), logger);
73 Assert.IsNotNull(proxy);
75 Assert.AreEqual(10L, proxy.DoSomething<long>(10L, 1));
77 Assert.AreEqual("DoSomething ", logger.LogContents);
80 [Test]
81 public void ProxyWithGenInterfaceWithGenericArrays()
83 IGenInterfaceWithGenArray<int> proxy =
84 generator.CreateInterfaceProxyWithTarget<IGenInterfaceWithGenArray<int>>(
85 new GenInterfaceWithGenArray<int>(), logger);
87 Assert.IsNotNull(proxy);
89 int[] items = new int[] {1, 2, 3};
90 proxy.CopyTo(items);
91 items = proxy.CreateItems();
92 Assert.IsNotNull(items);
93 Assert.AreEqual(3, items.Length);
95 Assert.AreEqual("CopyTo CreateItems ", logger.LogContents);
98 [Test]
99 public void ProxyWithGenInterfaceWithBase()
101 IGenInterfaceHierarchySpecialization<int> proxy =
102 generator.CreateInterfaceProxyWithTarget<IGenInterfaceHierarchySpecialization<int>>(
103 new GenInterfaceHierarchy<int>(), logger);
105 Assert.IsNotNull(proxy);
107 proxy.Add();
108 proxy.Add(1);
109 Assert.IsNotNull(proxy.FetchAll());
111 Assert.AreEqual("Add Add FetchAll ", logger.LogContents);
114 [Test]
115 [ExpectedException(typeof(GeneratorException),
116 "DynamicProxy cannot create an interface (with target) proxy for 'InterfaceWithExplicitImpl`1' as the target 'GenExplicitImplementation`1' has an explicit implementation of one of the methods exposed by the interface. The runtime prevents use from invoking the private method on the target. Method Castle.DynamicProxy.Tests.GenInterfaces.InterfaceWithExplicitImpl<T>.GetEnum1"
118 public void ProxyWithGenExplicitImplementation()
120 DisableVerification();
121 generator.CreateInterfaceProxyWithTarget<InterfaceWithExplicitImpl<int>> (
122 new GenExplicitImplementation<int>(), logger);
125 [Test]
126 public void TwoGenericsInterfaceWithoutTarget()
128 generator.CreateInterfaceProxyWithoutTarget(typeof(GenInterface<object>),
129 new Type[] {typeof(InterfaceWithExplicitImpl<int>)},
130 new LogInvocationInterceptor());
133 [Test]
134 public void NonGenInterfaceWithParentGenClassImplementingGenInterface()
136 generator.CreateInterfaceProxyWithoutTarget(typeof(IUserRepository),
137 new Type[] {typeof(InterfaceWithExplicitImpl<int>)},
138 new LogInvocationInterceptor());
141 [Test]
142 public void WithoutTarget()
144 generator.CreateInterfaceProxyWithoutTarget(typeof(InterfaceWithExplicitImpl<int>), new LogInvocationInterceptor());
147 [Test]
148 public void MethodInfoClosedInGenIfcGenMethodRefTypeNoTarget()
150 KeepDataInterceptor interceptor = new KeepDataInterceptor();
151 GenInterfaceWithGenMethods<ArrayList> proxy =
152 generator.CreateInterfaceProxyWithoutTarget<GenInterfaceWithGenMethods<ArrayList>>(interceptor);
154 proxy.DoSomething(1, null);
155 GenericTestUtility.CheckMethodInfoIsClosed(interceptor.Invocation.GetConcreteMethod(), typeof(void), typeof(int),
156 typeof(ArrayList));
157 Assert.AreEqual(interceptor.Invocation.GetConcreteMethod(),
158 interceptor.Invocation.GetConcreteMethodInvocationTarget());
160 proxy.DoSomething(new Hashtable(), new ArrayList());
161 GenericTestUtility.CheckMethodInfoIsClosed(interceptor.Invocation.GetConcreteMethod(), typeof(void),
162 typeof(Hashtable), typeof(ArrayList));
163 Assert.AreEqual(interceptor.Invocation.GetConcreteMethod(),
164 interceptor.Invocation.GetConcreteMethodInvocationTarget());
167 [Test]
168 public void MethodInfoClosedInGenIfcGenMethodValueTypeNoTarget()
170 KeepDataInterceptor interceptor = new KeepDataInterceptor();
171 GenInterfaceWithGenMethods<int> proxy =
172 generator.CreateInterfaceProxyWithoutTarget<GenInterfaceWithGenMethods<int>>(interceptor);
174 proxy.DoSomething(1, 1);
175 GenericTestUtility.CheckMethodInfoIsClosed(interceptor.Invocation.GetConcreteMethod(), typeof(void), typeof(int),
176 typeof(int));
177 Assert.AreEqual(interceptor.Invocation.GetConcreteMethod(),
178 interceptor.Invocation.GetConcreteMethodInvocationTarget());
180 proxy.DoSomething(new Hashtable(), 1);
181 GenericTestUtility.CheckMethodInfoIsClosed(interceptor.Invocation.GetConcreteMethod(), typeof(void),
182 typeof(Hashtable), typeof(int));
183 Assert.AreEqual(interceptor.Invocation.GetConcreteMethod(),
184 interceptor.Invocation.GetConcreteMethodInvocationTarget());
187 [Test]
188 public void MethodInfoClosedInGenIfcNongenMethodRefTypeNoTarget()
190 KeepDataInterceptor interceptor = new KeepDataInterceptor();
191 IGenInterfaceHierarchyBase<ArrayList> proxy =
192 generator.CreateInterfaceProxyWithoutTarget<IGenInterfaceHierarchyBase<ArrayList>>(interceptor);
194 proxy.Get();
195 GenericTestUtility.CheckMethodInfoIsClosed(interceptor.Invocation.GetConcreteMethod(), typeof(ArrayList));
196 Assert.AreEqual(interceptor.Invocation.GetConcreteMethod(),
197 interceptor.Invocation.GetConcreteMethodInvocationTarget());
199 proxy.Add(null);
200 GenericTestUtility.CheckMethodInfoIsClosed(interceptor.Invocation.GetConcreteMethod(), typeof(void),
201 typeof(ArrayList));
202 Assert.AreEqual(interceptor.Invocation.GetConcreteMethod(),
203 interceptor.Invocation.GetConcreteMethodInvocationTarget());
206 [Test]
207 public void MethodInfoClosedInGenIfcNongenMethodValueTypeNoTarget()
209 KeepDataInterceptor interceptor = new KeepDataInterceptor();
210 IGenInterfaceHierarchyBase<int> proxy =
211 generator.CreateInterfaceProxyWithoutTarget<IGenInterfaceHierarchyBase<int>>(interceptor);
213 proxy.Get();
214 GenericTestUtility.CheckMethodInfoIsClosed(interceptor.Invocation.GetConcreteMethod(), typeof(int));
215 Assert.AreEqual(interceptor.Invocation.GetConcreteMethod(),
216 interceptor.Invocation.GetConcreteMethodInvocationTarget());
218 proxy.Add(0);
219 GenericTestUtility.CheckMethodInfoIsClosed(interceptor.Invocation.GetConcreteMethod(), typeof(void), typeof(int));
220 Assert.AreEqual(interceptor.Invocation.GetConcreteMethod(),
221 interceptor.Invocation.GetConcreteMethodInvocationTarget());
224 [Test]
225 public void MethodInfoClosedInNongenIfcGenMethodNoTarget()
227 KeepDataInterceptor interceptor = new KeepDataInterceptor();
228 OnlyGenMethodsInterface proxy = generator.CreateInterfaceProxyWithoutTarget<OnlyGenMethodsInterface>(interceptor);
230 proxy.DoSomething(1);
231 GenericTestUtility.CheckMethodInfoIsClosed(interceptor.Invocation.GetConcreteMethod(), typeof(int), typeof(int));
232 Assert.AreEqual(interceptor.Invocation.GetConcreteMethod(),
233 interceptor.Invocation.GetConcreteMethodInvocationTarget());
235 proxy.DoSomething(new Hashtable());
236 GenericTestUtility.CheckMethodInfoIsClosed(interceptor.Invocation.GetConcreteMethod(), typeof(Hashtable),
237 typeof(Hashtable));
238 Assert.AreEqual(interceptor.Invocation.GetConcreteMethod(),
239 interceptor.Invocation.GetConcreteMethodInvocationTarget());
242 [Test]
243 public void MethodInfoClosedInGenIfcGenMethodRefTypeWithTarget()
245 KeepDataInterceptor interceptor = new KeepDataInterceptor();
246 GenInterfaceWithGenMethods<ArrayList> target = new GenInterfaceWithGenMethodsImpl<ArrayList>();
247 GenInterfaceWithGenMethods<ArrayList> proxy =
248 generator.CreateInterfaceProxyWithTarget<GenInterfaceWithGenMethods<ArrayList>>(target, interceptor);
250 proxy.DoSomething(1, null);
251 GenericTestUtility.CheckMethodInfoIsClosed(interceptor.Invocation.GetConcreteMethod(), typeof(void), typeof(int),
252 typeof(ArrayList));
253 GenericTestUtility.CheckMethodInfoIsClosed(interceptor.Invocation.GetConcreteMethodInvocationTarget(), typeof(void),
254 typeof(int), typeof(ArrayList));
255 Assert.AreNotEqual(interceptor.Invocation.GetConcreteMethod(),
256 interceptor.Invocation.GetConcreteMethodInvocationTarget());
258 proxy.DoSomething(new Hashtable(), new ArrayList());
259 GenericTestUtility.CheckMethodInfoIsClosed(interceptor.Invocation.GetConcreteMethod(), typeof(void),
260 typeof(Hashtable), typeof(ArrayList));
261 GenericTestUtility.CheckMethodInfoIsClosed(interceptor.Invocation.GetConcreteMethodInvocationTarget(), typeof(void),
262 typeof(Hashtable), typeof(ArrayList));
263 Assert.AreNotEqual(interceptor.Invocation.GetConcreteMethod(),
264 interceptor.Invocation.GetConcreteMethodInvocationTarget());
267 [Test]
268 public void MethodInfoClosedInGenIfcGenMethodValueTypeWithTarget()
270 KeepDataInterceptor interceptor = new KeepDataInterceptor();
271 GenInterfaceWithGenMethods<int> target = new GenInterfaceWithGenMethodsImpl<int>();
272 GenInterfaceWithGenMethods<int> proxy =
273 generator.CreateInterfaceProxyWithTarget<GenInterfaceWithGenMethods<int>>(target, interceptor);
275 proxy.DoSomething(1, 1);
276 GenericTestUtility.CheckMethodInfoIsClosed(interceptor.Invocation.GetConcreteMethod(), typeof(void), typeof(int),
277 typeof(int));
278 GenericTestUtility.CheckMethodInfoIsClosed(interceptor.Invocation.GetConcreteMethodInvocationTarget(), typeof(void),
279 typeof(int), typeof(int));
280 Assert.AreNotEqual(interceptor.Invocation.GetConcreteMethod(),
281 interceptor.Invocation.GetConcreteMethodInvocationTarget());
283 proxy.DoSomething(new Hashtable(), 1);
284 GenericTestUtility.CheckMethodInfoIsClosed(interceptor.Invocation.GetConcreteMethod(), typeof(void),
285 typeof(Hashtable), typeof(int));
286 GenericTestUtility.CheckMethodInfoIsClosed(interceptor.Invocation.GetConcreteMethodInvocationTarget(), typeof(void),
287 typeof(Hashtable), typeof(int));
288 Assert.AreNotEqual(interceptor.Invocation.GetConcreteMethod(),
289 interceptor.Invocation.GetConcreteMethodInvocationTarget());
292 [Test]
293 public void MethodInfoClosedInGenIfcNongenMethodRefTypeWithTarget()
295 KeepDataInterceptor interceptor = new KeepDataInterceptor();
296 IGenInterfaceHierarchyBase<ArrayList> target = new GenInterfaceHierarchy<ArrayList>();
297 IGenInterfaceHierarchyBase<ArrayList> proxy =
298 generator.CreateInterfaceProxyWithTarget<IGenInterfaceHierarchyBase<ArrayList>>(target, interceptor);
300 proxy.Add(null);
301 GenericTestUtility.CheckMethodInfoIsClosed(interceptor.Invocation.GetConcreteMethod(), typeof(void),
302 typeof(ArrayList));
303 GenericTestUtility.CheckMethodInfoIsClosed(interceptor.Invocation.GetConcreteMethodInvocationTarget(), typeof(void),
304 typeof(ArrayList));
305 Assert.AreNotEqual(interceptor.Invocation.GetConcreteMethod(),
306 interceptor.Invocation.GetConcreteMethodInvocationTarget());
308 proxy.Get();
309 GenericTestUtility.CheckMethodInfoIsClosed(interceptor.Invocation.GetConcreteMethod(), typeof(ArrayList));
310 GenericTestUtility.CheckMethodInfoIsClosed(interceptor.Invocation.GetConcreteMethodInvocationTarget(),
311 typeof(ArrayList));
312 Assert.AreNotEqual(interceptor.Invocation.GetConcreteMethod(),
313 interceptor.Invocation.GetConcreteMethodInvocationTarget());
316 [Test]
317 public void MethodInfoClosedInGenIfcNongenMethodValueTypeWithTarget()
319 KeepDataInterceptor interceptor = new KeepDataInterceptor();
320 IGenInterfaceHierarchyBase<int> target = new GenInterfaceHierarchy<int>();
321 IGenInterfaceHierarchyBase<int> proxy =
322 generator.CreateInterfaceProxyWithTarget<IGenInterfaceHierarchyBase<int>>(target, interceptor);
324 proxy.Add(0);
325 GenericTestUtility.CheckMethodInfoIsClosed(interceptor.Invocation.GetConcreteMethod(), typeof(void), typeof(int));
326 GenericTestUtility.CheckMethodInfoIsClosed(interceptor.Invocation.GetConcreteMethodInvocationTarget(), typeof(void),
327 typeof(int));
328 Assert.AreNotEqual(interceptor.Invocation.GetConcreteMethod(),
329 interceptor.Invocation.GetConcreteMethodInvocationTarget());
331 proxy.Get();
332 GenericTestUtility.CheckMethodInfoIsClosed(interceptor.Invocation.GetConcreteMethod(), typeof(int));
333 GenericTestUtility.CheckMethodInfoIsClosed(interceptor.Invocation.GetConcreteMethodInvocationTarget(), typeof(int));
334 Assert.AreNotEqual(interceptor.Invocation.GetConcreteMethod(),
335 interceptor.Invocation.GetConcreteMethodInvocationTarget());
338 [Test]
339 public void MethodInfoClosedInNongenIfcGenMethodWithTarget()
341 KeepDataInterceptor interceptor = new KeepDataInterceptor();
342 OnlyGenMethodsInterface target = new OnlyGenMethodsInterfaceImpl();
343 OnlyGenMethodsInterface proxy =
344 generator.CreateInterfaceProxyWithTarget<OnlyGenMethodsInterface>(target, interceptor);
346 proxy.DoSomething(1);
347 GenericTestUtility.CheckMethodInfoIsClosed(interceptor.Invocation.GetConcreteMethod(), typeof(int), typeof(int));
348 GenericTestUtility.CheckMethodInfoIsClosed(interceptor.Invocation.GetConcreteMethodInvocationTarget(), typeof(int),
349 typeof(int));
350 Assert.AreNotEqual(interceptor.Invocation.GetConcreteMethod(),
351 interceptor.Invocation.GetConcreteMethodInvocationTarget());
353 proxy.DoSomething(new Hashtable());
354 GenericTestUtility.CheckMethodInfoIsClosed(interceptor.Invocation.GetConcreteMethod(), typeof(Hashtable),
355 typeof(Hashtable));
356 GenericTestUtility.CheckMethodInfoIsClosed(interceptor.Invocation.GetConcreteMethodInvocationTarget(),
357 typeof(Hashtable), typeof(Hashtable));
358 Assert.AreNotEqual(interceptor.Invocation.GetConcreteMethod(),
359 interceptor.Invocation.GetConcreteMethodInvocationTarget());
362 [Test]
363 [ExpectedException(typeof(ArgumentException))]
364 public void ThrowsWhenProxyingGenericTypeDefNoTarget()
366 KeepDataInterceptor interceptor = new KeepDataInterceptor();
367 object o = generator.CreateInterfaceProxyWithoutTarget(typeof(IGenInterfaceHierarchyBase<>), interceptor);
370 [Test(Description = "There is a strange CLR bug resulting from our loading the tokens of methods in generic types. "
371 + "This test ensures we do not trigger it.")]
372 [Ignore("Currently, we trigger the bug, and work around it - see MethodFinder")]
373 public void TypeGetMethodsIsStable()
375 ProxyWithGenInterfaceWithBase();
376 Assert.AreEqual(4, typeof(IGenInterfaceHierarchyBase<int>).GetMethods().Length);
379 [Test(Description = "There is a strange CLR bug resulting from our loading the tokens of methods in generic types. "
380 + "This test ensures we correctly work around it.")]
381 public void MethodFinderIsStable()
383 ProxyWithGenInterfaceWithBase();
384 Assert.AreEqual(4,
385 MethodFinder.GetAllInstanceMethods(typeof(IGenInterfaceHierarchyBase<int>),
386 BindingFlags.Public | BindingFlags.Instance).Length);
389 [Test(Description = "There is a strange CLR bug resulting from our loading the tokens of methods in generic types. "
391 "This test ensures we do not trigger it across AppDomains. If we do, MethodFinder must provide a cross-AppDomain workaround."
393 public void TypeGetMethodsIsStableInDifferentAppDomains()
395 ProxyWithGenInterfaceWithBase();
396 AppDomain newDomain =
397 AppDomain.CreateDomain("NewDomain", AppDomain.CurrentDomain.Evidence, AppDomain.CurrentDomain.SetupInformation);
400 newDomain.DoCallBack(delegate { Assert.AreEqual(4, typeof(IGenInterfaceHierarchyBase<int>).GetMethods().Length); });
402 finally
404 AppDomain.Unload(newDomain);
407 #endif