Exemple #1
0
        public void CanMixGenericMethod()
        {
            var config = new CiladorConfigType();

            config.WeaveConfig = new WeaveConfigTypeBase[]
            {
                new InterfaceMixinConfigType
                {
                    InterfaceMixinMap = new InterfaceMixinMapType[]
                    {
                        new InterfaceMixinMapType
                        {
                            Interface = typeof(IEmptyInterface).GetShortAssemblyQualifiedName(),
                            Mixin     = typeof(GenericMethodMixin).GetShortAssemblyQualifiedName()
                        }
                    }
                },
            };

            var assembly   = ModuleWeaverHelper.WeaveAndLoadTestTarget("Cilador.Fody.TestMixinTargets", config);
            var targetType = assembly.GetType(typeof(EmptyInterfaceTarget).FullName);

            Assert.That(typeof(IEmptyInterface).IsAssignableFrom(targetType));
            targetType.ValidateMemberCountsAre(1, 2, 0, 0, 0, 0);
            Assert.That(targetType.GetConstructor(new Type[0]) != null, "Lost existing default constructor");

            // simple generic method
            var method = targetType.GetMethod("GenericMethod", TestContent.BindingFlagsForWeavedMembers);

            Assert.That(method, Is.Not.Null);
            Assert.That(method.ContainsGenericParameters);
            TypeValidatorBase.ValidateParameters(
                method,
                GenericParameterTypeValidator.Named("T"),
                GenericParameterTypeValidator.Named("T"));

            var genericParameters = method.GetGenericArguments();

            Assert.That(genericParameters, Is.Not.Null);
            Assert.That(genericParameters.Length, Is.EqualTo(1));

            var instance = Activator.CreateInstance(targetType, new object[0]);

            Assert.That(instance is IEmptyInterface);

            var genericInstanceMethod = method.MakeGenericMethod(typeof(int));

            Assert.That(!genericInstanceMethod.ContainsGenericParameters);
            TypeValidatorBase.ValidateParameters(
                genericInstanceMethod,
                NonGenericTypeValidator.ForType <int>(),
                NonGenericTypeValidator.ForType <int>());
            Assert.That(genericInstanceMethod.Invoke(instance, new object[] { 94387 }), Is.EqualTo(94387));

            genericInstanceMethod = method.MakeGenericMethod(typeof(object));
            Assert.That(!genericInstanceMethod.ContainsGenericParameters);
            TypeValidatorBase.ValidateParameters(
                genericInstanceMethod,
                NonGenericTypeValidator.ForType <object>(),
                NonGenericTypeValidator.ForType <object>());
            var someObject = new object();

            Assert.That(genericInstanceMethod.Invoke(instance, new object[] { someObject }), Is.SameAs(someObject));

            // generic method with constraints
            method = targetType.GetMethod("GenericMethodWithConstraints", TestContent.BindingFlagsForWeavedMembers);
            Assert.That(method, Is.Not.Null);
            Assert.That(method.ContainsGenericParameters);
            TypeValidatorBase.ValidateParameters(
                method,
                new GenericTypeValidator(typeof(Tuple <, , , , ,>),
                                         GenericParameterTypeValidator.Named("TClass"),
                                         GenericParameterTypeValidator.Named("TStruct"),
                                         GenericParameterTypeValidator.Named("TNew"),
                                         GenericParameterTypeValidator.Named("TClassNew"),
                                         GenericParameterTypeValidator.Named("TDisposable"),
                                         GenericParameterTypeValidator.Named("TTClass")),
                GenericParameterTypeValidator.Named("TClass"),
                GenericParameterTypeValidator.Named("TStruct"),
                GenericParameterTypeValidator.Named("TNew"),
                GenericParameterTypeValidator.Named("TClassNew"),
                GenericParameterTypeValidator.Named("TDisposable"),
                GenericParameterTypeValidator.Named("TTClass"));

            genericParameters = method.GetGenericArguments();
            Assert.That(genericParameters, Is.Not.Null);
            Assert.That(genericParameters.Length, Is.EqualTo(6));

            instance = Activator.CreateInstance(targetType, new object[0]);
            Assert.That(instance is IEmptyInterface);

            genericInstanceMethod = method.MakeGenericMethod(
                typeof(Stream),
                typeof(DictionaryEntry),
                typeof(DictionaryEntry),
                typeof(object),
                typeof(StringWriter),
                typeof(FileStream));
            Assert.That(!genericInstanceMethod.ContainsGenericParameters);
            TypeValidatorBase.ValidateParameters(
                genericInstanceMethod,
                new GenericTypeValidator(typeof(Tuple <, , , , ,>),
                                         NonGenericTypeValidator.ForType <Stream>(),
                                         NonGenericTypeValidator.ForType <DictionaryEntry>(),
                                         NonGenericTypeValidator.ForType <DictionaryEntry>(),
                                         NonGenericTypeValidator.ForType <object>(),
                                         NonGenericTypeValidator.ForType <StringWriter>(),
                                         NonGenericTypeValidator.ForType <FileStream>()),
                NonGenericTypeValidator.ForType <Stream>(),
                NonGenericTypeValidator.ForType <DictionaryEntry>(),
                NonGenericTypeValidator.ForType <DictionaryEntry>(),
                NonGenericTypeValidator.ForType <object>(),
                NonGenericTypeValidator.ForType <StringWriter>(),
                NonGenericTypeValidator.ForType <FileStream>());
        }
Exemple #2
0
        public void CanMixGenericNestedType()
        {
            var config = new CiladorConfigType();

            config.WeaveConfig = new WeaveConfigTypeBase[]
            {
                new InterfaceMixinConfigType
                {
                    InterfaceMixinMap = new InterfaceMixinMapType[]
                    {
                        new InterfaceMixinMapType
                        {
                            Interface = typeof(IEmptyInterface).GetShortAssemblyQualifiedName(),
                            Mixin     = typeof(GenericNestedTypeMixin).GetShortAssemblyQualifiedName()
                        }
                    }
                },
            };

            var assembly   = ModuleWeaverHelper.WeaveAndLoadTestTarget("Cilador.Fody.TestMixinTargets", config);
            var targetType = assembly.GetType(typeof(EmptyInterfaceTarget).FullName);

            Assert.That(typeof(IEmptyInterface).IsAssignableFrom(targetType));
            targetType.ValidateMemberCountsAre(1, 0, 0, 0, 0, 6);
            Assert.That(targetType.GetConstructor(new Type[0]) != null, "Lost existing default constructor");

            // basic nested generic type
            var type = targetType.GetNestedType("GenericType`1", TestContent.BindingFlagsForWeavedMembers);

            Assert.That(type, Is.Not.Null);
            Assert.That(type.ContainsGenericParameters);
            TypeValidatorBase.ValidateType(
                type,
                new GenericTypeValidator(
                    type,
                    GenericParameterTypeValidator.Named("T")));

            var method = type.GetMethod("GetThing", TestContent.BindingFlagsForWeavedMembers);

            Assert.That(method, Is.Not.Null);
            Assert.That(method.ContainsGenericParameters);
            TypeValidatorBase.ValidateParameters(
                method,
                GenericParameterTypeValidator.Named("T"),
                GenericParameterTypeValidator.Named("T"));

            var genericInstanceType = type.MakeGenericType(typeof(int));

            Assert.That(!genericInstanceType.ContainsGenericParameters);
            Assert.That(genericInstanceType.IsConstructedGenericType);

            var instance = Activator.CreateInstance(genericInstanceType, new object[0]);

            var genericInstanceMethod = genericInstanceType.GetMethod("GetThing", TestContent.BindingFlagsForWeavedMembers);

            Assert.That(genericInstanceMethod, Is.Not.Null);
            Assert.That(!genericInstanceMethod.ContainsGenericParameters);
            TypeValidatorBase.ValidateParameters(
                genericInstanceMethod,
                NonGenericTypeValidator.ForType <int>(),
                NonGenericTypeValidator.ForType <int>());
            Assert.That(genericInstanceMethod.Invoke(instance, new object[] { 556 }), Is.EqualTo(556));

            genericInstanceType = type.MakeGenericType(typeof(object));
            Assert.That(!genericInstanceType.ContainsGenericParameters);
            Assert.That(genericInstanceType.IsConstructedGenericType);

            instance = Activator.CreateInstance(genericInstanceType, new object[0]);

            genericInstanceMethod = genericInstanceType.GetMethod("GetThing", TestContent.BindingFlagsForWeavedMembers);
            Assert.That(genericInstanceMethod, Is.Not.Null);
            Assert.That(!genericInstanceMethod.ContainsGenericParameters);
            TypeValidatorBase.ValidateParameters(
                genericInstanceMethod,
                NonGenericTypeValidator.ForType <object>(),
                NonGenericTypeValidator.ForType <object>());
            var someObject = new object();

            Assert.That(genericInstanceMethod.Invoke(instance, new object[] { someObject }), Is.SameAs(someObject));

            // nested generic type with constraints
            type = targetType.GetNestedType("GenericTypeWithConstraints`6", TestContent.BindingFlagsForWeavedMembers);
            Assert.That(type, Is.Not.Null);
            Assert.That(type.ContainsGenericParameters);
            TypeValidatorBase.ValidateType(
                type,
                new GenericTypeValidator(
                    type,
                    GenericParameterTypeValidator.Named("TClass"),
                    GenericParameterTypeValidator.Named("TStruct"),
                    GenericParameterTypeValidator.Named("TNew"),
                    GenericParameterTypeValidator.Named("TClassNew"),
                    GenericParameterTypeValidator.Named("TDisposable"),
                    GenericParameterTypeValidator.Named("TTClass")));

            genericInstanceType = type.MakeGenericType(
                typeof(Stream),
                typeof(DictionaryEntry),
                typeof(DictionaryEntry),
                typeof(object),
                typeof(StringWriter),
                typeof(FileStream));
            Assert.That(!genericInstanceType.ContainsGenericParameters);
            Assert.That(genericInstanceType.IsConstructedGenericType);

            instance = Activator.CreateInstance(genericInstanceType, new object[0]);

            genericInstanceMethod = genericInstanceType.GetMethod("GetThings", TestContent.BindingFlagsForWeavedMembers);
            Assert.That(genericInstanceMethod, Is.Not.Null);
            Assert.That(!genericInstanceMethod.ContainsGenericParameters);
            TypeValidatorBase.ValidateParameters(
                genericInstanceMethod,
                new GenericTypeValidator(typeof(Tuple <, , , , ,>),
                                         NonGenericTypeValidator.ForType <Stream>(),
                                         NonGenericTypeValidator.ForType <DictionaryEntry>(),
                                         NonGenericTypeValidator.ForType <DictionaryEntry>(),
                                         NonGenericTypeValidator.ForType <object>(),
                                         NonGenericTypeValidator.ForType <StringWriter>(),
                                         NonGenericTypeValidator.ForType <FileStream>()),
                NonGenericTypeValidator.ForType <Stream>(),
                NonGenericTypeValidator.ForType <DictionaryEntry>(),
                NonGenericTypeValidator.ForType <DictionaryEntry>(),
                NonGenericTypeValidator.ForType <object>(),
                NonGenericTypeValidator.ForType <StringWriter>(),
                NonGenericTypeValidator.ForType <FileStream>());

            // nested generic type with open generic method
            type = targetType.GetNestedType("GenericTypeWithGenericMethod`1", TestContent.BindingFlagsForWeavedMembers);
            Assert.That(type, Is.Not.Null);
            Assert.That(type.ContainsGenericParameters);
            TypeValidatorBase.ValidateType(
                type,
                new GenericTypeValidator(
                    type,
                    GenericParameterTypeValidator.Named("TType")));

            method = type.GetMethod("GetThings", TestContent.BindingFlagsForWeavedMembers);
            Assert.That(method, Is.Not.Null);
            Assert.That(method.ContainsGenericParameters);
            TypeValidatorBase.ValidateParameters(
                method,
                new GenericTypeValidator(typeof(Tuple <,>),
                                         GenericParameterTypeValidator.Named("TType"),
                                         GenericParameterTypeValidator.Named("TMethod")),
                GenericParameterTypeValidator.Named("TType"),
                GenericParameterTypeValidator.Named("TMethod"));

            genericInstanceType = type.MakeGenericType(typeof(int));
            Assert.That(!genericInstanceType.ContainsGenericParameters);
            Assert.That(genericInstanceType.IsConstructedGenericType);

            instance = Activator.CreateInstance(genericInstanceType, new object[0]);

            var genericInstanceGenericMethod = genericInstanceType.GetMethod("GetThings", TestContent.BindingFlagsForWeavedMembers);

            Assert.That(genericInstanceGenericMethod, Is.Not.Null);
            Assert.That(genericInstanceGenericMethod.ContainsGenericParameters);
            TypeValidatorBase.ValidateParameters(
                genericInstanceGenericMethod,
                new GenericTypeValidator(typeof(Tuple <,>),
                                         NonGenericTypeValidator.ForType <int>(),
                                         GenericParameterTypeValidator.Named("TMethod")),
                NonGenericTypeValidator.ForType <int>(),
                GenericParameterTypeValidator.Named("TMethod"));

            genericInstanceMethod = genericInstanceGenericMethod.MakeGenericMethod(typeof(object));
            Assert.That(!genericInstanceMethod.ContainsGenericParameters);
            TypeValidatorBase.ValidateParameters(
                genericInstanceMethod,
                new GenericTypeValidator(typeof(Tuple <,>),
                                         NonGenericTypeValidator.ForType <int>(),
                                         NonGenericTypeValidator.ForType <object>()),
                NonGenericTypeValidator.ForType <int>(),
                NonGenericTypeValidator.ForType <object>());
            someObject = new object();
            var things = (Tuple <int, object>)genericInstanceMethod.Invoke(instance, new object[] { 45866, someObject });

            Assert.That(things.Item1, Is.EqualTo(45866));
            Assert.That(things.Item2, Is.SameAs(someObject));

            // generic type with multiple parameters
            type = targetType.GetNestedType("GenericTypeWithMultipleParameters`2", TestContent.BindingFlagsForWeavedMembers);
            Assert.That(type, Is.Not.Null);
            TypeValidatorBase.ValidateType(
                type,
                new GenericTypeValidator(
                    type,
                    GenericParameterTypeValidator.Named("T1"),
                    GenericParameterTypeValidator.Named("T2")));

            TypeValidatorBase.ValidatePropertyTypeAndAccessors(
                type.GetProperty("Thing1"),
                TypeValidatorBase.PropertyAccessorExpectations.Both,
                GenericParameterTypeValidator.Named("T1"));

            TypeValidatorBase.ValidatePropertyTypeAndAccessors(
                type.GetProperty("Thing2"),
                TypeValidatorBase.PropertyAccessorExpectations.Both,
                GenericParameterTypeValidator.Named("T2"));

            genericInstanceType = type.MakeGenericType(typeof(int), typeof(string));
            Assert.That(!genericInstanceType.ContainsGenericParameters);
            Assert.That(genericInstanceType.IsConstructedGenericType);

            instance = Activator.CreateInstance(genericInstanceType, new object[0]);

            var genericInstanceProperty = genericInstanceType.GetProperty("Thing1", TestContent.BindingFlagsForWeavedMembers);

            TypeValidatorBase.ValidatePropertyTypeAndAccessors(
                genericInstanceProperty,
                TypeValidatorBase.PropertyAccessorExpectations.Both,
                NonGenericTypeValidator.ForType <int>());
            genericInstanceProperty.SetValue(instance, 48008);
            Assert.That(genericInstanceProperty.GetValue(instance), Is.EqualTo(48008));

            genericInstanceProperty = genericInstanceType.GetProperty("Thing2", TestContent.BindingFlagsForWeavedMembers);
            TypeValidatorBase.ValidatePropertyTypeAndAccessors(
                genericInstanceProperty,
                TypeValidatorBase.PropertyAccessorExpectations.Both,
                NonGenericTypeValidator.ForType <string>());
            genericInstanceProperty.SetValue(instance, "SAdfiohoqiweAsiohnewlroi asoidfh inra6f");
            Assert.That(genericInstanceProperty.GetValue(instance), Is.EqualTo("SAdfiohoqiweAsiohnewlroi asoidfh inra6f"));

            instance = Activator.CreateInstance(genericInstanceType, new object[] { 34543, "ALKJEWklnrpioewhfioehgiu" });

            genericInstanceProperty = genericInstanceType.GetProperty("Thing1", TestContent.BindingFlagsForWeavedMembers);
            TypeValidatorBase.ValidatePropertyTypeAndAccessors(
                genericInstanceProperty,
                TypeValidatorBase.PropertyAccessorExpectations.Both,
                NonGenericTypeValidator.ForType <int>());
            Assert.That(genericInstanceProperty.GetValue(instance), Is.EqualTo(34543));

            genericInstanceProperty = genericInstanceType.GetProperty("Thing2", TestContent.BindingFlagsForWeavedMembers);
            TypeValidatorBase.ValidatePropertyTypeAndAccessors(
                genericInstanceProperty,
                TypeValidatorBase.PropertyAccessorExpectations.Both,
                NonGenericTypeValidator.ForType <string>());
            Assert.That(genericInstanceProperty.GetValue(instance), Is.EqualTo("ALKJEWklnrpioewhfioehgiu"));

            // partially closed generic type
            type = targetType.GetNestedType("PartiallyClosedGenericType`1", TestContent.BindingFlagsForWeavedMembers);
            Assert.That(type, Is.Not.Null);
            TypeValidatorBase.ValidateType(
                type,
                new GenericTypeValidator(
                    type,
                    GenericParameterTypeValidator.Named("T3")));

            TypeValidatorBase.ValidatePropertyTypeAndAccessors(
                type.GetProperty("Thing1"),
                TypeValidatorBase.PropertyAccessorExpectations.Both,
                NonGenericTypeValidator.ForType <int>());

            TypeValidatorBase.ValidatePropertyTypeAndAccessors(
                type.GetProperty("Thing2"),
                TypeValidatorBase.PropertyAccessorExpectations.Both,
                GenericParameterTypeValidator.Named("T3"));

            genericInstanceType = type.MakeGenericType(typeof(string));
            Assert.That(!genericInstanceType.ContainsGenericParameters);
            Assert.That(genericInstanceType.IsConstructedGenericType);

            instance = Activator.CreateInstance(genericInstanceType, new object[0]);

            genericInstanceProperty = genericInstanceType.GetProperty(
                "Thing1",
                BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
            TypeValidatorBase.ValidatePropertyTypeAndAccessors(
                genericInstanceProperty,
                TypeValidatorBase.PropertyAccessorExpectations.Both,
                NonGenericTypeValidator.ForType <int>());
            genericInstanceProperty.SetValue(instance, 5446);
            Assert.That(genericInstanceProperty.GetValue(instance), Is.EqualTo(5446));

            genericInstanceProperty = genericInstanceType.BaseType.GetProperty(
                "Thing2",
                BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
            TypeValidatorBase.ValidatePropertyTypeAndAccessors(
                genericInstanceProperty,
                TypeValidatorBase.PropertyAccessorExpectations.Both,
                NonGenericTypeValidator.ForType <string>());
            genericInstanceProperty.SetValue(instance, "AFioenAjeiona aesoing ijeng inuia eabruibeg uybvwaytvr  b");
            Assert.That(genericInstanceProperty.GetValue(instance), Is.EqualTo("AFioenAjeiona aesoing ijeng inuia eabruibeg uybvwaytvr  b"));


            // type with method with partially closed generic type
            type = targetType.GetNestedType("TypeWithPartiallyClosedGenericMethod", TestContent.BindingFlagsForWeavedMembers);
            Assert.That(type, Is.Not.Null);
            Assert.That(!type.IsGenericType);

            instance = Activator.CreateInstance(type);

            var returnTypeGenericDefinition = targetType.GetNestedType("GenericTypeWithMultipleParameters`2", TestContent.BindingFlagsForWeavedMembers);

            method = type.GetMethod("GetThing", TestContent.BindingFlagsForWeavedMembers);
            Assert.That(method, Is.Not.Null);
            TypeValidatorBase.ValidateParameters(
                method,
                new GenericTypeValidator(
                    returnTypeGenericDefinition,
                    NonGenericTypeValidator.ForType <int>(),
                    GenericParameterTypeValidator.Named("T4")),
                GenericParameterTypeValidator.Named("T4"));

            genericInstanceMethod = method.MakeGenericMethod(new Type[] { typeof(string) });
            var returnValue = genericInstanceMethod.Invoke(instance, new object[] { "Eoahio eioua bueagingnpiuw nufib fuiwebyu" });
            var genericInstanceReturnType = returnTypeGenericDefinition.MakeGenericType(new Type[] { typeof(int), typeof(string) });

            Assert.That(returnValue.GetType(), Is.EqualTo(genericInstanceReturnType));
            Assert.That(genericInstanceReturnType.GetProperty("Thing1").GetValue(returnValue), Is.EqualTo(297387));
            Assert.That(genericInstanceReturnType.GetProperty("Thing2").GetValue(returnValue), Is.EqualTo("Eoahio eioua bueagingnpiuw nufib fuiwebyu"));

            method = type.GetMethod("GetOtherThing", TestContent.BindingFlagsForWeavedMembers);
            Assert.That(method, Is.Not.Null);
            TypeValidatorBase.ValidateParameters(
                method,
                new GenericTypeValidator(
                    returnTypeGenericDefinition,
                    GenericParameterTypeValidator.Named("T5"),
                    NonGenericTypeValidator.ForType <int>()),
                GenericParameterTypeValidator.Named("T5"));

            genericInstanceMethod     = method.MakeGenericMethod(new Type[] { typeof(string) });
            returnValue               = genericInstanceMethod.Invoke(instance, new object[] { "Eaiosn4oil ifhiu 3ybusabu 3byuvsdf yuvaytithomn gfd" });
            genericInstanceReturnType = returnTypeGenericDefinition.MakeGenericType(new Type[] { typeof(string), typeof(int) });
            Assert.That(returnValue.GetType(), Is.EqualTo(genericInstanceReturnType));
            Assert.That(genericInstanceReturnType.GetProperty("Thing1").GetValue(returnValue), Is.EqualTo("Eaiosn4oil ifhiu 3ybusabu 3byuvsdf yuvaytithomn gfd"));
            Assert.That(genericInstanceReturnType.GetProperty("Thing2").GetValue(returnValue), Is.EqualTo(789437));
        }