PageRenderTime 114ms CodeModel.GetById 81ms app.highlight 16ms RepoModel.GetById 14ms app.codeStats 0ms

/src/UnitTests/AOP/MethodBodyInterceptionTests.cs

http://github.com/philiplaureano/LinFu
C# | 288 lines | 224 code | 64 blank | 0 comment | 6 complexity | 0e00c8205b43eb0eb6de5d16cca4f670 MD5 | raw file
  1using System;
  2using System.Linq;
  3using LinFu.AOP.Cecil.Extensions;
  4using LinFu.AOP.Interfaces;
  5using LinFu.IoC.Reflection;
  6using LinFu.Reflection.Emit;
  7using Mono.Cecil;
  8using Xunit;
  9using SampleLibrary.AOP;
 10
 11namespace LinFu.UnitTests.AOP
 12{
 13    public class MethodBodyInterceptionTests
 14    {
 15        private void Test(Action<object> testInstance)
 16        {
 17            var libraryFileName = "SampleLibrary.dll";
 18            var typeName = "SampleClassWithNonVirtualMethod";
 19            Func<MethodReference, bool> methodFilter = m => m.Name == "DoSomething";
 20
 21            Test(libraryFileName, typeName, methodFilter, type => Test(type, testInstance));
 22        }
 23
 24        private void Test(string libraryFileName, string typeName, Func<MethodReference, bool> methodFilter,
 25            Action<Type> testTargetType)
 26        {
 27            var assembly = AssemblyDefinition.ReadAssembly(libraryFileName);
 28            var module = assembly.MainModule;
 29
 30            var targetType = (from TypeDefinition t in module.Types
 31                where t.Name == typeName
 32                select t).First();
 33
 34            Assert.NotNull(targetType);
 35
 36            ModifyType(targetType, methodFilter);
 37
 38            var modifiedTargetType = CreateModifiedType(assembly, typeName);
 39
 40            testTargetType(modifiedTargetType);
 41        }
 42
 43        private void Test(Type modifiedTargetType, Action<object> testInstance)
 44        {
 45            var instance = Activator.CreateInstance(modifiedTargetType);
 46            testInstance(instance);
 47        }
 48
 49        private Type CreateModifiedType(AssemblyDefinition assembly, string typeName)
 50        {
 51            var modifiedAssembly = assembly.ToAssembly();
 52
 53            return (from t in modifiedAssembly.GetTypes()
 54                where t.Name == typeName
 55                select t).First();
 56        }
 57
 58        private void ModifyType(TypeDefinition targetType, Func<MethodReference, bool> methodFilter)
 59        {
 60            targetType.InterceptMethodBody(methodFilter);
 61        }
 62
 63        [Fact]
 64        public void ShouldImplementIModifiableTypeOnModifiedSampleClass()
 65        {
 66            Action<object> condition = instance =>
 67            {
 68                Assert.NotNull(instance);
 69                Assert.True(instance is IModifiableType);
 70            };
 71
 72            Test(condition);
 73        }
 74
 75        [Fact]
 76        public void ShouldInterceptStaticMethodWithAroundInvokeProvider()
 77        {
 78            Func<MethodReference, bool> methodFilter = m => m.Name == "DoSomething";
 79
 80            var aroundInvoke = new SampleAroundInvoke();
 81            var provider = new SampleAroundInvokeProvider(aroundInvoke);
 82
 83            AroundMethodBodyRegistry.AddProvider(provider);
 84            Action<Type> doTest = type =>
 85            {
 86                var doSomethingMethod = type.GetMethod("DoSomething");
 87                Assert.NotNull(doSomethingMethod);
 88
 89                doSomethingMethod.Invoke(null, new object[0]);
 90                Assert.True(aroundInvoke.BeforeInvokeWasCalled);
 91                Assert.True(aroundInvoke.AfterInvokeWasCalled);
 92            };
 93
 94            Test("SampleLibrary.dll", "SampleStaticClassWithStaticMethod", methodFilter, doTest);
 95        }
 96
 97        [Fact]
 98        public void ShouldInvokeAroundInvokeProviderIfInterceptionIsEnabled()
 99        {
100            var aroundInvoke = new SampleAroundInvoke();
101            var provider = new SampleAroundInvokeProvider(aroundInvoke);
102            Action<object> condition = instance =>
103            {
104                Assert.NotNull(instance);
105
106                var modifiedInstance = (IModifiableType) instance;
107                modifiedInstance.AroundMethodBodyProvider = provider;
108
109                instance.Invoke("DoSomething");
110
111                Assert.True(aroundInvoke.BeforeInvokeWasCalled);
112                Assert.True(aroundInvoke.AfterInvokeWasCalled);
113            };
114
115            Test(condition);
116        }
117
118        [Fact]
119        public void ShouldInvokeClassAroundInvokeProviderIfInterceptionIsEnabled()
120        {
121            var aroundInvoke = new SampleAroundInvoke();
122            var provider = new SampleAroundInvokeProvider(aroundInvoke);
123
124            Action<object> condition = instance =>
125            {
126                Assert.NotNull(instance);
127
128                AroundMethodBodyRegistry.AddProvider(provider);
129                instance.Invoke("DoSomething");
130
131                Assert.True(aroundInvoke.BeforeInvokeWasCalled);
132                Assert.True(aroundInvoke.AfterInvokeWasCalled);
133            };
134
135            Test(condition);
136        }
137
138        [Fact]
139        public void ShouldInvokeClassMethodReplacementProviderIfInterceptionIsEnabled()
140        {
141            Func<MethodReference, bool> methodFilter = m => m.Name == "DoSomething";
142            var replacement = new SampleMethodReplacement();
143            var provider = new SampleMethodReplacementProvider(replacement);
144
145            MethodBodyReplacementProviderRegistry.SetProvider(provider);
146            Action<Type> doTest = type =>
147            {
148                var doSomethingMethod = type.GetMethod("DoSomething");
149                Assert.NotNull(doSomethingMethod);
150
151                doSomethingMethod.Invoke(null, new object[0]);
152            };
153
154            Test("SampleLibrary.dll", "SampleStaticClassWithStaticMethod", methodFilter, doTest);
155            Assert.True(replacement.HasBeenCalled);
156        }
157
158        [Fact]
159        public void ShouldInvokeMethodBodyReplacementIfInterceptionIsEnabled()
160        {
161            var sampleInterceptor = new SampleInterceptor();
162            var sampleProvider = new SampleMethodReplacementProvider(sampleInterceptor);
163
164            Action<object> condition = instance =>
165            {
166                Assert.NotNull(instance);
167                Assert.True(instance is IModifiableType);
168
169                var modifiableType = (IModifiableType) instance;
170                modifiableType.MethodBodyReplacementProvider = sampleProvider;
171                modifiableType.IsInterceptionDisabled = false;
172
173                instance.Invoke("DoSomething");
174            };
175
176            Test(condition);
177            Assert.True(sampleInterceptor.HasBeenInvoked);
178        }
179
180        [Fact]
181        public void ShouldNotImplementIModifiableTypeOnStaticClasses()
182        {
183            Func<MethodReference, bool> methodFilter = m => m.Name == "DoSomething";
184
185            var aroundInvoke = new SampleAroundInvoke();
186            var provider = new SampleAroundInvokeProvider(aroundInvoke);
187
188            AroundMethodBodyRegistry.AddProvider(provider);
189            Action<Type> doTest = type =>
190            {
191                var doSomethingMethod = type.GetMethod("DoSomething");
192                Assert.NotNull(doSomethingMethod);
193                Assert.DoesNotContain(typeof(IModifiableType), type.GetInterfaces());
194            };
195
196            Test("SampleLibrary.dll", "SampleStaticClassWithStaticMethod", methodFilter, doTest);
197        }
198
199        [Fact]
200        public void ShouldNotInvokeAroundInvokeProviderIfInterceptionIsDisabled()
201        {
202            var aroundInvoke = new SampleAroundInvoke();
203            var provider = new SampleAroundInvokeProvider(aroundInvoke);
204            Action<object> condition = instance =>
205            {
206                Assert.NotNull(instance);
207
208                var modifiedInstance = (IModifiableType) instance;
209                modifiedInstance.AroundMethodBodyProvider = provider;
210                modifiedInstance.IsInterceptionDisabled = true;
211
212                instance.Invoke("DoSomething");
213
214                Assert.False(aroundInvoke.BeforeInvokeWasCalled);
215                Assert.False(aroundInvoke.AfterInvokeWasCalled);
216            };
217
218            Test(condition);
219        }
220
221        [Fact]
222        public void ShouldNotInvokeClassAroundInvokeProviderIfInterceptionIsDisabled()
223        {
224            var aroundInvoke = new SampleAroundInvoke();
225            var provider = new SampleAroundInvokeProvider(aroundInvoke);
226
227            Action<object> condition = instance =>
228            {
229                Assert.NotNull(instance);
230
231                var modified = (IModifiableType) instance;
232                modified.IsInterceptionDisabled = true;
233
234                AroundMethodBodyRegistry.AddProvider(provider);
235                instance.Invoke("DoSomething");
236
237                Assert.False(aroundInvoke.BeforeInvokeWasCalled);
238                Assert.False(aroundInvoke.AfterInvokeWasCalled);
239            };
240
241            Test(condition);
242        }
243
244        [Fact]
245        public void ShouldNotInvokeClassMethodReplacementProviderIfInterceptionIsDisabled()
246        {
247            var sampleInterceptor = new SampleInterceptor();
248            var sampleProvider = new SampleMethodReplacementProvider(sampleInterceptor);
249            MethodBodyReplacementProviderRegistry.SetProvider(sampleProvider);
250
251            Action<object> condition = instance =>
252            {
253                Assert.NotNull(instance);
254
255                var modified = (IModifiableType) instance;
256                modified.IsInterceptionDisabled = true;
257
258
259                instance.Invoke("DoSomething");
260                Assert.False(sampleInterceptor.HasBeenInvoked);
261            };
262
263            Test(condition);
264        }
265
266        [Fact]
267        public void ShouldNotInvokeMethodBodyReplacementIfInterceptionIsDisabled()
268        {
269            var sampleInterceptor = new SampleInterceptor();
270            var sampleProvider = new SampleMethodReplacementProvider(sampleInterceptor);
271
272            Action<object> condition = instance =>
273            {
274                Assert.NotNull(instance);
275                Assert.True(instance is IModifiableType);
276
277                var modifiableType = (IModifiableType) instance;
278                modifiableType.MethodBodyReplacementProvider = sampleProvider;
279                modifiableType.IsInterceptionDisabled = true;
280
281                instance.Invoke("DoSomething");
282            };
283
284            Test(condition);
285            Assert.False(sampleInterceptor.HasBeenInvoked);
286        }
287    }
288}