1 // Copyright 2004-2007 Castle Project - http://www.castleproject.org/
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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
.Test
18 using System
.Collections
;
20 using System
.Reflection
;
22 using NUnit
.Framework
;
24 using Castle
.DynamicProxy
;
25 using Castle
.DynamicProxy
.Test
.Classes
;
26 using Castle
.DynamicProxy
.Test
.Interceptors
;
27 using Castle
.DynamicProxy
.Test
.ClassInterfaces
;
30 public class ProxyGeneratorTestCase
32 private ProxyGenerator _generator
;
37 _generator
= new ProxyGenerator();
41 public void ProxyForClass()
43 object proxy
= _generator
.CreateClassProxy(
44 typeof(ServiceClass
), new ResultModifiedInvocationHandler( ) );
46 Assert
.IsNotNull( proxy
);
47 Assert
.IsTrue( typeof(ServiceClass
).IsAssignableFrom( proxy
.GetType() ) );
49 ServiceClass inter
= (ServiceClass
) proxy
;
51 Assert
.AreEqual( 44, inter
.Sum( 20, 25 ) );
52 Assert
.AreEqual( true, inter
.Valid
);
56 public void ProxyForClassWithInterfaces()
58 object proxy
= _generator
.CreateClassProxy( typeof(ServiceClass
), new Type
[] { typeof(IDisposable) }
,
59 new ResultModifiedInvocationHandler( ) );
61 Assert
.IsNotNull( proxy
);
62 Assert
.IsTrue( typeof(ServiceClass
).IsAssignableFrom( proxy
.GetType() ) );
63 Assert
.IsTrue( typeof(IDisposable
).IsAssignableFrom( proxy
.GetType() ) );
65 ServiceClass inter
= (ServiceClass
) proxy
;
67 Assert
.AreEqual( 44, inter
.Sum( 20, 25 ) );
68 Assert
.AreEqual( true, inter
.Valid
);
72 public void ProxyForClassWithSuperClass()
74 object proxy
= _generator
.CreateClassProxy(
75 typeof(SpecializedServiceClass
), new ResultModifiedInvocationHandler( ) );
77 Assert
.IsNotNull( proxy
);
78 Assert
.IsTrue( typeof(ServiceClass
).IsAssignableFrom( proxy
.GetType() ) );
79 Assert
.IsTrue( typeof(SpecializedServiceClass
).IsAssignableFrom( proxy
.GetType() ) );
81 SpecializedServiceClass inter
= (SpecializedServiceClass
) proxy
;
83 Assert
.AreEqual( 44, inter
.Sum( 20, 25 ) );
84 Assert
.AreEqual( -6, inter
.Subtract( 20, 25 ) );
85 Assert
.AreEqual( true, inter
.Valid
);
89 public void ProxyForClassWhichImplementsInterfaces()
91 object proxy
= _generator
.CreateClassProxy(
92 typeof(MyInterfaceImpl
), new ResultModifiedInvocationHandler( ) );
94 Assert
.IsNotNull( proxy
);
95 Assert
.IsTrue( typeof(MyInterfaceImpl
).IsAssignableFrom( proxy
.GetType() ) );
96 Assert
.IsTrue( typeof(IMyInterface
).IsAssignableFrom( proxy
.GetType() ) );
98 IMyInterface inter
= (IMyInterface
) proxy
;
100 Assert
.AreEqual( 44, inter
.Calc( 20, 25 ) );
104 public void ProxyingClassWithoutVirtualMethods()
106 NoVirtualMethodClass proxy
= (NoVirtualMethodClass
) _generator
.CreateClassProxy(
107 typeof(NoVirtualMethodClass
), new StandardInterceptor( ) );
108 Assert
.IsNotNull(proxy
);
112 public void ProxyingClassWithSealedMethods()
114 SealedMethodsClass proxy
= (SealedMethodsClass
) _generator
.CreateClassProxy(
115 typeof(SealedMethodsClass
), new StandardInterceptor() );
116 Assert
.IsNotNull(proxy
);
120 public void HashtableProxy()
122 object proxy
= _generator
.CreateClassProxy(
123 typeof(Hashtable
), new HashtableInterceptor() );
125 Assert
.IsTrue( typeof(Hashtable
).IsAssignableFrom( proxy
.GetType() ) );
127 object value = (proxy
as Hashtable
)["key"];
129 Assert
.IsTrue(value is String
);
130 Assert
.AreEqual("default", value.ToString());
133 [Test
, ExpectedException(typeof(ArgumentException
))]
134 public void CreateClassProxyInvalidBaseClass()
136 _generator
.CreateClassProxy(
137 typeof(ICloneable
), new StandardInterceptor( ) );
140 [Test
, ExpectedException(typeof(ArgumentNullException
))]
141 public void CreateClassProxyNullBaseClass()
143 _generator
.CreateClassProxy(
144 null, new StandardInterceptor( ) );
147 [Test
, ExpectedException(typeof(ArgumentNullException
))]
148 public void CreateClassProxyNullInterceptor()
150 _generator
.CreateClassProxy(
151 typeof(SpecializedServiceClass
), null );
155 public void TestGenerationSimpleInterface()
157 object proxy
= _generator
.CreateProxy(
158 typeof(IMyInterface
), new ResultModifiedInvocationHandler(), new MyInterfaceImpl() );
160 Assert
.IsNotNull( proxy
);
161 Assert
.IsTrue( typeof(IMyInterface
).IsAssignableFrom( proxy
.GetType() ) );
163 IMyInterface inter
= (IMyInterface
) proxy
;
165 Assert
.AreEqual( 44, inter
.Calc( 20, 25 ) );
168 Assert
.AreEqual( "opa", inter
.Name
);
170 inter
.Started
= true;
171 Assert
.AreEqual( true, inter
.Started
);
175 public void UsingCache()
177 object proxy
= _generator
.CreateProxy(
178 typeof(IMyInterface
), new StandardInterceptor(), new MyInterfaceImpl() );
180 Assert
.IsNotNull( proxy
);
181 Assert
.IsTrue( typeof(IMyInterface
).IsAssignableFrom( proxy
.GetType() ) );
183 proxy
= _generator
.CreateProxy(
184 typeof(IMyInterface
), new StandardInterceptor(), new MyInterfaceImpl() );
188 public void TestGenerationWithInterfaceHeritage()
190 object proxy
= _generator
.CreateProxy(
191 typeof(IMySecondInterface
), new StandardInterceptor( ), new MySecondInterfaceImpl() );
193 Assert
.IsNotNull( proxy
);
194 Assert
.IsTrue( typeof(IMyInterface
).IsAssignableFrom( proxy
.GetType() ) );
195 Assert
.IsTrue( typeof(IMySecondInterface
).IsAssignableFrom( proxy
.GetType() ) );
197 IMySecondInterface inter
= (IMySecondInterface
) proxy
;
200 inter
.Name
= "hammett";
201 Assert
.AreEqual( "hammett", inter
.Name
);
203 inter
.Address
= "pereira leite, 44";
204 Assert
.AreEqual( "pereira leite, 44", inter
.Address
);
206 Assert
.AreEqual( 45, inter
.Calc( 20, 25 ) );
210 public void ClassWithConstructors()
212 object proxy
= _generator
.CreateClassProxy(
213 typeof(ClassWithConstructors
),
214 new StandardInterceptor(),
217 Assert
.IsNotNull( proxy
);
219 ClassWithConstructors objProxy
= (ClassWithConstructors
) proxy
;
221 Assert
.IsNotNull( objProxy
.List
);
222 Assert
.IsNull( objProxy
.Dictionary
);
224 proxy
= _generator
.CreateClassProxy(
225 typeof(ClassWithConstructors
),
226 new StandardInterceptor(),
227 new ArrayList(), new Hashtable() );
229 Assert
.IsNotNull( proxy
);
230 objProxy
= (ClassWithConstructors
) proxy
;
232 Assert
.IsNotNull( objProxy
.List
);
233 Assert
.IsNotNull( objProxy
.Dictionary
);
237 public void TestEnumProperties()
239 ServiceStatusImpl service
= new ServiceStatusImpl();
241 object proxy
= _generator
.CreateProxy(
242 typeof(IServiceStatus
), new StandardInterceptor( ), service
);
244 Assert
.IsNotNull( proxy
);
245 Assert
.IsTrue( typeof(IServiceStatus
).IsAssignableFrom( proxy
.GetType() ) );
247 IServiceStatus inter
= (IServiceStatus
) proxy
;
248 Assert
.AreEqual( State
.Invalid
, inter
.ActualState
);
250 inter
.ChangeState( State
.Valid
);
251 Assert
.AreEqual( State
.Valid
, inter
.ActualState
);
255 public void TestAttributesForInterfaceProxies()
257 ServiceStatusImpl service
= new ServiceStatusImpl();
259 object proxy
= _generator
.CreateProxy(
260 typeof(IServiceStatus
), new MyInterfaceProxy( ), service
);
262 Assert
.IsNotNull( proxy
);
263 Assert
.IsTrue( typeof(IServiceStatus
).IsAssignableFrom( proxy
.GetType() ) );
265 IServiceStatus inter
= (IServiceStatus
) proxy
;
267 Assert
.AreEqual( State
.Invalid
, inter
.ActualState
);
269 inter
.ChangeState( State
.Valid
);
270 Assert
.AreEqual( State
.Valid
, inter
.ActualState
);
274 public void ProxyForClassWithGuidProperty()
276 object proxy
= _generator
.CreateClassProxy(
277 typeof(ClassWithGuid
), new StandardInterceptor() );
279 Assert
.IsNotNull( proxy
);
280 Assert
.IsTrue( typeof(ClassWithGuid
).IsAssignableFrom( proxy
.GetType() ) );
282 ClassWithGuid inter
= (ClassWithGuid
) proxy
;
284 Assert
.IsNotNull( inter
.GooId
);
288 public void ProxyingClassWithSByteEnum()
290 ClassWithSByteEnum proxy
= (ClassWithSByteEnum
)
291 _generator
.CreateClassProxy(
292 typeof(ClassWithSByteEnum
), new StandardInterceptor() );
293 Assert
.IsNotNull(proxy
);
297 public void ProxyForMarshalByRefClass()
299 ClassMarshalByRef proxy
= (ClassMarshalByRef
)
300 _generator
.CreateClassProxy(
301 typeof(ClassMarshalByRef
), new StandardInterceptor());
303 Assert
.IsNotNull(proxy
);
305 object o
= new object();
306 Assert
.AreEqual(o
, proxy
.Ping(o
));
309 Assert
.AreEqual(i
, proxy
.Pong(i
));
313 [Category("DotNetOnly")]
314 public void ProxyForRefAndOutClassWithPrimitiveTypeParams()
316 LogInvokeInterceptor interceptor
= new LogInvokeInterceptor();
318 RefAndOutClass proxy
= (RefAndOutClass
)
319 _generator
.CreateClassProxy(
320 typeof(RefAndOutClass
), interceptor
);
322 Assert
.IsNotNull(proxy
);
325 proxy
.RefInt(ref int1
);
326 Assert
.AreEqual(-2, int1
);
329 proxy
.RefChar(ref c
);
330 Assert
.AreEqual('a', c
);
333 proxy
.OutChar(out c
);
334 Assert
.AreEqual('b', c
);
337 proxy
.OutInt(out int2
);
338 Assert
.AreEqual(2, int2
);
340 Assert
.AreEqual("RefInt RefChar OutChar OutInt ", interceptor
.LogContents
);
344 [Category("DotNetOnly")]
345 public void ProxyForRefAndOutClassWithReferenceTypeParams()
347 LogInvokeInterceptor interceptor
= new LogInvokeInterceptor();
349 RefAndOutClass proxy
= (RefAndOutClass
)
350 _generator
.CreateClassProxy(
351 typeof(RefAndOutClass
), interceptor
);
353 Assert
.IsNotNull(proxy
);
355 string string1
= "foobar";
356 proxy
.RefString(ref string1
);
357 Assert
.AreEqual("foobar_string", string1
);
360 proxy
.OutString(out string2
);
361 Assert
.AreEqual("string", string2
);
363 Assert
.AreEqual("RefString OutString ", interceptor
.LogContents
);
367 [Category("DotNetOnly")]
368 public void ProxyForRefAndOutClassWithStructTypeParams()
370 LogInvokeInterceptor interceptor
= new LogInvokeInterceptor();
372 RefAndOutClass proxy
= (RefAndOutClass
)
373 _generator
.CreateClassProxy(
374 typeof(RefAndOutClass
), interceptor
);
376 Assert
.IsNotNull(proxy
);
378 DateTime dt1
= new DateTime(1999, 1, 1);
379 proxy
.RefDateTime(ref dt1
);
380 Assert
.AreEqual(new DateTime(2000, 1, 1), dt1
);
383 proxy
.OutDateTime(out dt2
);
384 Assert
.AreEqual(new DateTime(2005, 1, 1), dt2
);
386 Assert
.AreEqual("RefDateTime OutDateTime ", interceptor
.LogContents
);
390 [Category("DotNetOnly")]
391 public void ProxyForRefAndOutClassWithEnumTypeParams()
393 LogInvokeInterceptor interceptor
= new LogInvokeInterceptor();
395 RefAndOutClass proxy
= (RefAndOutClass
)
396 _generator
.CreateClassProxy(
397 typeof(RefAndOutClass
), interceptor
);
399 Assert
.IsNotNull(proxy
);
401 SByteEnum value1
= SByteEnum
.One
;
402 proxy
.RefSByteEnum(ref value1
);
403 Assert
.AreEqual(SByteEnum
.Two
, value1
);
406 proxy
.OutSByteEnum(out value2
);
407 Assert
.AreEqual(SByteEnum
.Two
, value2
);
409 Assert
.AreEqual("RefSByteEnum OutSByteEnum ", interceptor
.LogContents
);
413 [Category("DotNetOnly")]
414 public void ProxyForRefAndOutClassWithPrimitiveTypeParamsWhereInterceptorModifiesTheValues()
416 RefAndOutInterceptor interceptor
= new RefAndOutInterceptor();
418 RefAndOutClass proxy
= (RefAndOutClass
)
419 _generator
.CreateClassProxy(
420 typeof(RefAndOutClass
), interceptor
);
422 Assert
.IsNotNull(proxy
);
425 proxy
.RefInt(ref arg1
);
426 Assert
.AreEqual(98, arg1
);
429 proxy
.OutInt(out arg2
);
430 Assert
.AreEqual(102, arg2
);
432 Assert
.AreEqual("RefInt OutInt ", interceptor
.LogContents
);
436 [Category("DotNetOnly")]
437 public void ProxyForRefAndOutClassWithReferenceTypeParamsWhereInterceptorModifiesTheValues()
439 RefAndOutInterceptor interceptor
= new RefAndOutInterceptor();
441 RefAndOutClass proxy
= (RefAndOutClass
)
442 _generator
.CreateClassProxy(
443 typeof(RefAndOutClass
), interceptor
);
445 Assert
.IsNotNull(proxy
);
447 string string1
= "foobar";
448 proxy
.RefString(ref string1
);
449 Assert
.AreEqual("foobar_string_xxx", string1
);
452 proxy
.OutString(out string2
);
453 Assert
.AreEqual("string_xxx", string2
);
455 Assert
.AreEqual("RefString OutString ", interceptor
.LogContents
);
459 [Category("DotNetOnly")]
460 public void ProxyForRefAndOutClassWithStructTypeParamsWhereInterceptorModifiesTheValues()
462 RefAndOutInterceptor interceptor
= new RefAndOutInterceptor();
464 RefAndOutClass proxy
= (RefAndOutClass
)
465 _generator
.CreateClassProxy(
466 typeof(RefAndOutClass
), interceptor
);
468 Assert
.IsNotNull(proxy
);
470 DateTime dt1
= new DateTime(1999, 1, 1);
471 proxy
.RefDateTime(ref dt1
);
472 Assert
.AreEqual(new DateTime(2000, 2, 1), dt1
);
475 proxy
.OutDateTime(out dt2
);
476 Assert
.AreEqual(new DateTime(2005, 2, 1), dt2
);
478 Assert
.AreEqual("RefDateTime OutDateTime ", interceptor
.LogContents
);
482 [Category("DotNetOnly")]
483 public void ProxyForRefAndOutClassWithEnumTypeParamsWhereInterceptorModifiesTheValues()
485 RefAndOutInterceptor interceptor
= new RefAndOutInterceptor();
487 RefAndOutClass proxy
= (RefAndOutClass
)
488 _generator
.CreateClassProxy(
489 typeof(RefAndOutClass
), interceptor
);
491 Assert
.IsNotNull(proxy
);
493 SByteEnum value1
= SByteEnum
.One
;
494 proxy
.RefSByteEnum(ref value1
);
495 Assert
.AreEqual(SByteEnum
.One
, value1
);
498 proxy
.OutSByteEnum(out value2
);
499 Assert
.AreEqual(SByteEnum
.One
, value2
);
501 Assert
.AreEqual("RefSByteEnum OutSByteEnum ", interceptor
.LogContents
);
505 public void ProtectedProperties()
507 object proxy
= _generator
.CreateClassProxy(
508 typeof(ClassWithProtectedMethods
), new StandardInterceptor() );
510 Assert
.IsTrue( proxy
is ClassWithProtectedMethods
);
514 public void Indexer()
516 object proxy
= _generator
.CreateClassProxy(
517 typeof(ClassWithIndexer
), new StandardInterceptor() );
519 Assert
.IsTrue( proxy
is ClassWithIndexer
);
523 public void Indexer2()
525 IndexerInterface proxy
= (IndexerInterface
)
526 _generator
.CreateProxy( typeof(IndexerInterface
),
527 new StandardInterceptor(), new IndexerClass() );
529 Assert
.IsNotNull( proxy
);
531 string dummy
= proxy
["1"];
536 public void ReflectionTest()
538 object proxy
= _generator
.CreateClassProxy(
539 typeof(MySerializableClass
), new StandardInterceptor() );
541 Type type
= proxy
.GetType();
543 Assert
.IsNotNull(type
);
545 PropertyInfo info
= type
.GetProperty("Current", BindingFlags
.DeclaredOnly
|BindingFlags
.Public
|BindingFlags
.Instance
);
547 Assert
.IsNotNull(info
);
551 public void MethodsAreInterceptedInChain()
553 LogInvocationInterceptor interceptor
= new LogInvocationInterceptor();
555 object proxy
= _generator
.CreateClassProxy(
556 typeof(ServiceClass2
), interceptor
);
558 ServiceClass2 obj
= (ServiceClass2
) proxy
;
563 Assert
.AreEqual(4, interceptor
.Invocations
.Length
);
564 Assert
.AreEqual("DoOtherThing", interceptor
.Invocations
[0]);
565 Assert
.AreEqual("DoSomethingElse", interceptor
.Invocations
[1]);
566 Assert
.AreEqual("DoOtherThing", interceptor
.Invocations
[2]);
567 Assert
.AreEqual("DoSomethingElse", interceptor
.Invocations
[3]);
571 /// See http://support.castleproject.org/browse/DYNPROXY-42
574 public void NameBugReportedTest()
576 ProxyGenerator proxyGenerator
= new ProxyGenerator();
577 Castle
.DynamicProxy
.Test
.ClassInterfaces
.C
.IBubu bubuC
= (Castle
.DynamicProxy
.Test
.ClassInterfaces
.C
.IBubu
)
578 proxyGenerator
.CreateProxy(typeof(Castle
.DynamicProxy
.Test
.ClassInterfaces
.C
.IBubu
), new SimpleInterceptor(), new object());
581 Castle
.DynamicProxy
.Test
.ClassInterfaces
.D
.IBubu bubuD
= (Castle
.DynamicProxy
.Test
.ClassInterfaces
.D
.IBubu
)
582 proxyGenerator
.CreateProxy(typeof(Castle
.DynamicProxy
.Test
.ClassInterfaces
.D
.IBubu
), new SimpleInterceptor(), new object());
587 public void IDataReaderProxyGeneration()
589 IDataReader reader
= IDataReaderProxy
.NewInstance( new DummyReader() );