From 6a9a2c1198ba3ac005daab8acff8653056870d44 Mon Sep 17 00:00:00 2001 From: "KONTUR\\sivukhin" Date: Thu, 8 Aug 2019 20:13:05 +0500 Subject: [PATCH 1/6] Support Func<> types in fields marked with [Injected] attribute --- .../Impl/GroboTestAction.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/GroboContainer.NUnitExtensions/Impl/GroboTestAction.cs b/GroboContainer.NUnitExtensions/Impl/GroboTestAction.cs index cdbdce9..adb27f9 100644 --- a/GroboContainer.NUnitExtensions/Impl/GroboTestAction.cs +++ b/GroboContainer.NUnitExtensions/Impl/GroboTestAction.cs @@ -152,7 +152,19 @@ private static void InvokeWrapperMethod([CanBeNull] MethodInfo wrapperMethod, [N private static void InjectFixtureFields([NotNull] GroboTestSuiteContextData suiteContext, [NotNull] object testFixture) { foreach (var fieldInfo in testFixture.GetType().GetFieldsForInjection()) - fieldInfo.SetValue(testFixture, suiteContext.Container.Get(fieldInfo.FieldType)); + fieldInfo.SetValue(testFixture, InstantiateField(suiteContext, fieldInfo)); + } + + private static object InstantiateField([NotNull] GroboTestSuiteContextData suiteContext, [NotNull] FieldInfo fieldInfo) + { + var fieldType = fieldInfo.FieldType; + if (fieldType.IsGenericType) + { + var genericFieldType = fieldType.GetGenericTypeDefinition(); + if (supportedFactoryFuncTypes.Contains(genericFieldType)) + return suiteContext.Container.GetCreationFunc(fieldType); + } + return suiteContext.Container.Get(fieldType); } private static void EnsureAppDomainInitialization() @@ -188,6 +200,7 @@ private static void OnAppDomainUnload() private static readonly object appDomainInitializationLock = new object(); private static readonly ConditionalWeakTable setUpedFixtures = new ConditionalWeakTable(); private static readonly ConcurrentDictionary suiteDescriptors = new ConcurrentDictionary(); + private static readonly Type[] supportedFactoryFuncTypes = {typeof(Func<>), typeof(Func<,>), typeof(Func<,,>), typeof(Func<,,,>), typeof(Func<,,,,>)}; private class SuiteDescriptor { From 75a2c3bbd25f41173676ce19cc1e503d501a1965 Mon Sep 17 00:00:00 2001 From: "KONTUR\\sivukhin" Date: Thu, 8 Aug 2019 20:13:23 +0500 Subject: [PATCH 2/6] Add tests for Func support in Injected attribute --- .../InjectedAttribute_TestFactories.cs | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 GroboContainer.NUnitExtensions.Tests/Container/InjectedAttribute_TestFactories.cs diff --git a/GroboContainer.NUnitExtensions.Tests/Container/InjectedAttribute_TestFactories.cs b/GroboContainer.NUnitExtensions.Tests/Container/InjectedAttribute_TestFactories.cs new file mode 100644 index 0000000..5fbdde2 --- /dev/null +++ b/GroboContainer.NUnitExtensions.Tests/Container/InjectedAttribute_TestFactories.cs @@ -0,0 +1,92 @@ +using System; +using System.Linq; + +using JetBrains.Annotations; + +using NUnit.Framework; + +namespace GroboContainer.NUnitExtensions.Tests.Container +{ + [GroboTestFixture] + public class InjectedAttribute_TestFactories : InjectedAttributeTestBase + { + [GroboSetUp] + public void SetUp() + { + GroboTestMachineryTrace.ClearTrace(); + } + + [Test] + public void TestSimpleFactory() + { + var service = factory(); + Assert.That(service, Is.Not.Null); + service.Foo(41); + Assert.That(GroboTestMachineryTrace.TraceLines, Is.EqualTo(new[] {"ServiceWithNoDependencies.Foo(p=41)"})); + } + + [Test] + public void TestFactoryFromString() + { + var service = factoryFromString("qxx"); + Assert.That(service, Is.Not.Null); + service.Hoo(42); + Assert.That(GroboTestMachineryTrace.TraceLines, Is.EqualTo(new[] {"ServiceDependingOnString.Hoo(p=qxx, q=42)"})); + } + + [Test] + public void TestFactory4() + { + var service = factory4(new[] {"qxx"}, new[] {1}, new[] {2.5}, new short[] {3}); + Assert.That(service, Is.Not.Null); + service.Qoo(43); + Assert.That(GroboTestMachineryTrace.TraceLines, Is.EqualTo(new[] {"ServiceDependingOnManyStrings.Qoo(a=qxx, b=1, c=2,5, d=3, p=43)"})); + } + + [Injected] + private Func factory; + + [Injected] + private Func factoryFromString; + + [Injected] + private Func factory2; + + [Injected] + private Func factory3; + + [Injected] + private Func factory4; + } + + public interface IServiceWithManyDependencies + { + void Qoo(int p); + } + + public class ServiceWithManyDependencies : IServiceWithManyDependencies + { + private readonly string[] a; + private readonly int[] b; + private readonly double[] c; + private readonly short[] d; + + public ServiceWithManyDependencies(string[] a, int[] b, double[] c, short[] d) + { + this.a = a; + this.b = b; + this.c = c; + this.d = d; + } + + public void Qoo(int p) + { + GroboTestMachineryTrace.Log($"ServiceDependingOnManyStrings.Qoo(" + + $"a={(a == null ? "null" : string.Join(", ", a))}, " + + $"b={(b == null ? "null" : string.Join(", ", b))}, " + + $"c={(c == null ? "null" : string.Join(", ", c))}, " + + $"d={(d == null ? "null" : string.Join(", ", d))}, " + + $"p={p})"); + } + } +} \ No newline at end of file From e36bb87e94315955d5f63fece7f24e8b808840bb Mon Sep 17 00:00:00 2001 From: "KONTUR\\sivukhin" Date: Thu, 8 Aug 2019 20:18:17 +0500 Subject: [PATCH 3/6] Get rid of double dependency because of non-invariant culture --- .../InjectedAttribute_TestFactories.cs | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/GroboContainer.NUnitExtensions.Tests/Container/InjectedAttribute_TestFactories.cs b/GroboContainer.NUnitExtensions.Tests/Container/InjectedAttribute_TestFactories.cs index 5fbdde2..8618592 100644 --- a/GroboContainer.NUnitExtensions.Tests/Container/InjectedAttribute_TestFactories.cs +++ b/GroboContainer.NUnitExtensions.Tests/Container/InjectedAttribute_TestFactories.cs @@ -37,10 +37,10 @@ public void TestFactoryFromString() [Test] public void TestFactory4() { - var service = factory4(new[] {"qxx"}, new[] {1}, new[] {2.5}, new short[] {3}); + var service = factory4(new[] {"qxx"}, new[] {1}, new short[] {2}, new byte[] {3}); Assert.That(service, Is.Not.Null); service.Qoo(43); - Assert.That(GroboTestMachineryTrace.TraceLines, Is.EqualTo(new[] {"ServiceDependingOnManyStrings.Qoo(a=qxx, b=1, c=2,5, d=3, p=43)"})); + Assert.That(GroboTestMachineryTrace.TraceLines, Is.EqualTo(new[] {"ServiceDependingOnManyStrings.Qoo(a=qxx, b=1, c=2, d=3, p=43)"})); } [Injected] @@ -50,13 +50,7 @@ public void TestFactory4() private Func factoryFromString; [Injected] - private Func factory2; - - [Injected] - private Func factory3; - - [Injected] - private Func factory4; + private Func factory4; } public interface IServiceWithManyDependencies @@ -68,10 +62,10 @@ public class ServiceWithManyDependencies : IServiceWithManyDependencies { private readonly string[] a; private readonly int[] b; - private readonly double[] c; - private readonly short[] d; + private readonly short[] c; + private readonly byte[] d; - public ServiceWithManyDependencies(string[] a, int[] b, double[] c, short[] d) + public ServiceWithManyDependencies(string[] a, int[] b, short[] c, byte[] d) { this.a = a; this.b = b; From 25d31afd0d7d36da53a84dd7b5f8312b93fefc0e Mon Sep 17 00:00:00 2001 From: Andrew Kostousov Date: Fri, 9 Aug 2019 01:15:18 +0500 Subject: [PATCH 4/6] NotNull --- GroboContainer.NUnitExtensions/Impl/GroboTestAction.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/GroboContainer.NUnitExtensions/Impl/GroboTestAction.cs b/GroboContainer.NUnitExtensions/Impl/GroboTestAction.cs index adb27f9..cefcc10 100644 --- a/GroboContainer.NUnitExtensions/Impl/GroboTestAction.cs +++ b/GroboContainer.NUnitExtensions/Impl/GroboTestAction.cs @@ -155,6 +155,7 @@ private static void InjectFixtureFields([NotNull] GroboTestSuiteContextData suit fieldInfo.SetValue(testFixture, InstantiateField(suiteContext, fieldInfo)); } + [NotNull] private static object InstantiateField([NotNull] GroboTestSuiteContextData suiteContext, [NotNull] FieldInfo fieldInfo) { var fieldType = fieldInfo.FieldType; @@ -273,4 +274,4 @@ private static ContainerConfiguration GetContainerConfiguration([NotNull] string private static int order; } } -} \ No newline at end of file +} From 8afc8955cbffee008d5e20c4f7a8d21d166c3515 Mon Sep 17 00:00:00 2001 From: "KONTUR\\sivukhin" Date: Fri, 9 Aug 2019 10:23:31 +0500 Subject: [PATCH 5/6] Provide informative error message for all unsupported types derived from Delegate --- .../Impl/GroboTestAction.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/GroboContainer.NUnitExtensions/Impl/GroboTestAction.cs b/GroboContainer.NUnitExtensions/Impl/GroboTestAction.cs index cefcc10..b31d901 100644 --- a/GroboContainer.NUnitExtensions/Impl/GroboTestAction.cs +++ b/GroboContainer.NUnitExtensions/Impl/GroboTestAction.cs @@ -159,11 +159,12 @@ private static void InjectFixtureFields([NotNull] GroboTestSuiteContextData suit private static object InstantiateField([NotNull] GroboTestSuiteContextData suiteContext, [NotNull] FieldInfo fieldInfo) { var fieldType = fieldInfo.FieldType; - if (fieldType.IsGenericType) + if (typeof(Delegate).IsAssignableFrom(fieldType)) { - var genericFieldType = fieldType.GetGenericTypeDefinition(); - if (supportedFactoryFuncTypes.Contains(genericFieldType)) + if (fieldType.IsGenericType && supportedFactoryFuncTypes.Contains(fieldType.GetGenericTypeDefinition())) return suiteContext.Container.GetCreationFunc(fieldType); + throw new InvalidOperationException($"Unable to instantiate injected field '{fieldInfo.Name}' of delegate type '{fieldType}'. " + + $"Following delegate types are supported: {string.Join(", ", supportedFactoryFuncTypes.Select(x => x.Name))}"); } return suiteContext.Container.Get(fieldType); } @@ -248,7 +249,7 @@ public void Destroy([NotNull] string suiteName) private static ContainerConfiguration GetContainerConfiguration([NotNull] string suiteName, [NotNull] Assembly testAssembly) { const string containerConfiguratorTypeName = "GroboTestMachineryContainerConfigurator"; - var containerConfiguratorTypes = testAssembly.GetExportedTypes().Where(t=> t.IsClass && t.Name == containerConfiguratorTypeName).ToList(); + var containerConfiguratorTypes = testAssembly.GetExportedTypes().Where(t => t.IsClass && t.Name == containerConfiguratorTypeName).ToList(); if (!containerConfiguratorTypes.Any()) throw new InvalidOperationException($"Failed to get container configuration for test suite {suiteName}. There is no {containerConfiguratorTypeName} type in test assembly: {testAssembly}"); if (containerConfiguratorTypes.Count > 1) @@ -274,4 +275,4 @@ private static ContainerConfiguration GetContainerConfiguration([NotNull] string private static int order; } } -} +} \ No newline at end of file From 20ca5e1e6113e0385197ba067dbf0baffd3f8db4 Mon Sep 17 00:00:00 2001 From: "KONTUR\\sivukhin" Date: Fri, 9 Aug 2019 10:23:38 +0500 Subject: [PATCH 6/6] Cleanup usings --- .../Container/InjectedAttribute_TestFactories.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/GroboContainer.NUnitExtensions.Tests/Container/InjectedAttribute_TestFactories.cs b/GroboContainer.NUnitExtensions.Tests/Container/InjectedAttribute_TestFactories.cs index 8618592..fa1cc76 100644 --- a/GroboContainer.NUnitExtensions.Tests/Container/InjectedAttribute_TestFactories.cs +++ b/GroboContainer.NUnitExtensions.Tests/Container/InjectedAttribute_TestFactories.cs @@ -1,7 +1,4 @@ using System; -using System.Linq; - -using JetBrains.Annotations; using NUnit.Framework;