예제 #1
0
        public void Contravariant_ShouldDisableForOpenGeneric()
        {
            // Arrange
            var targets = new TargetContainer();

            // test shows that contravariance still works for Action<> but is disabled for all IContravariant<>
            targets.SetOption <Options.EnableContravariance>(false, typeof(IContravariant <>));

            // Act & Assert
            Assert.False(targets.GetOption(typeof(IContravariant <>), Options.EnableContravariance.Default).Value);
            var result1 = new TargetTypeSelector(typeof(IContravariant <BaseClassGrandchild>), targets).ToArray();
            var result2 = new TargetTypeSelector(typeof(Action <BaseClassGrandchild>), targets).ToArray();

            Assert.Equal(
                new[]
            {
                typeof(IContravariant <BaseClassGrandchild>),
                typeof(IContravariant <>)
            },
                result1
                );

            Assert.Equal(
                new[]
            {
                typeof(Action <BaseClassGrandchild>),
                typeof(Action <BaseClassChild>),
                typeof(Action <BaseClass>),
                typeof(Action <object>),
                typeof(Action <>)
            },
                result2);
        }
        public void Covariant_ShouldIncludeAllDerivedRegistrations_MostRecentToLeast()
        {
            // Arrange
            var targets = new TargetContainer();

            targets.RegisterType <Covariant <BaseClass>, ICovariant <BaseClass> >();
            targets.RegisterType <Covariant <BaseClassChild>, ICovariant <BaseClassChild> >();
            targets.RegisterType <Covariant <BaseClassGrandchild>, ICovariant <BaseClassGrandchild> >();

            // Act
            var result = new TargetTypeSelector(typeof(ICovariant <BaseClass>), targets).ToArray();

            LogActual(result);

            // Assert
            // here, the order of the covariant types is determined by the order of registration.
            // the selector processes them in reverse chronological order.
            Assert.Equal(new[]
            {
                typeof(ICovariant <BaseClass>),
                typeof(ICovariant <BaseClassGrandchild>),
                typeof(ICovariant <BaseClassChild>),
                typeof(ICovariant <>)
            }, result);
        }
예제 #3
0
        public void Basic_ShouldHandleNestedGenerics(Type type, Type[] expected)
        {
            // Arrange & Act
            var result = new TargetTypeSelector(type).ToArray();

            LogExpectedOrder(expected);
            LogActual(result);

            // Assert
            Assert.Equal(expected, result);
        }
예제 #4
0
        public void Contravariant_ShouldReturnCorrectCombinationForNested(Type type, Type[] expected)
        {
            // Arrange & Act
            var result = new TargetTypeSelector(type).ToArray();

            LogExpectedOrder(expected);
            LogActual(result);

            // Assert

            // verify that the expected types are compatible with the target type
            Assert.All(expected.Where(t => !t.IsGenericTypeDefinition && !t.ContainsGenericParameters),
                       t => t.IsAssignableFrom(type));
            Assert.Equal(expected, result);
        }
        public void Covariant_ShouldBeCorrectForFuncObjectDelegate()
        {
            // Arrange
            var targets    = new TargetContainer();
            var funcTarget = Target.ForObject(new Func <string>(() => "Hello World")); // <-- expected behaviour is that the presence of this registration

            // will cause the Func<string> to be included in the search list.
            targets.Register(funcTarget);

            // Act
            var result = new TargetTypeSelector(typeof(Func <object>), targets).ToArray();

            LogActual(result);

            // Assert
            Assert.Equal(new[] { typeof(Func <object>), typeof(Func <string>), typeof(Func <>) }, result);
        }
예제 #6
0
        public void Contravariant_ShouldDisableForClosedGeneric()
        {
            // Arrange
            var targets = new TargetContainer();

            targets.SetOption <Options.EnableContravariance, IContravariant <BaseClassGrandchild> >(false);

            // Act & Assert
            var result = new TargetTypeSelector(typeof(IContravariant <BaseClassGrandchild>), targets).ToArray();

            Assert.Equal(
                new[]
            {
                typeof(IContravariant <BaseClassGrandchild>),
                typeof(IContravariant <>)
            },
                result);
        }
예제 #7
0
        public void Contravariant_ShouldReturnCorrectCombination(Type type, Type[] expectedOrder, Type[] expectedInAnyOrder)
        {
            // Arrange and Act
            var result = new TargetTypeSelector(type).ToArray();

            LogExpectedOrder(expectedOrder);
            LogOthers(expectedInAnyOrder);
            LogActual(result);

            // Assert

            // assert that instances of each closed generic search type can be assigned to the search type
            // - this is double-checking our type compatibility assertions before checking that the results
            // are the ones we expect.
            Assert.All(result.Where(t => !t.IsGenericTypeDefinition && !t.ContainsGenericParameters),
                       t => type.IsAssignableFrom(t));

            // check that the the types whose order was specified are actually in the specified order
            Assert.Equal(expectedOrder, result.Where(rt => expectedOrder.Contains(rt)));

            HashSet <Type> expectedSet = new HashSet <Type>(expectedOrder.Concat(expectedInAnyOrder ?? Enumerable.Empty <Type>()));
            HashSet <Type> resultSet   = new HashSet <Type>(result);

            HashSet <Type> expectedMissing    = new HashSet <Type>(expectedSet);
            HashSet <Type> resultsNotExpected = new HashSet <Type>(resultSet);

            expectedMissing.ExceptWith(resultSet);
            resultsNotExpected.ExceptWith(expectedSet);

            if (expectedMissing.Count != 0)
            {
                LogTypes(expectedMissing.ToArray(), "Missing expected types");
            }
            if (resultsNotExpected.Count != 0)
            {
                LogTypes(resultsNotExpected.ToArray(), "Unexpected result types");
            }

            // if this fails, the previous two logging calls should output the types which are missing/extra
            Assert.True(expectedSet.SetEquals(resultSet));
        }
        public void Covariant_ShouldBeCorrectForFuncIEnumerableCharDelegate()
        {
            // Arrange
            var targets    = new TargetContainer();
            var funcTarget = Target.ForObject(new Func <string>(() => "Hello World"));

            targets.Register(funcTarget);

            // Act
            var result = new TargetTypeSelector(typeof(Func <IEnumerable <char> >), targets).ToArray();

            LogActual(result);

            // Assert
            Assert.Equal(new[] {
                typeof(Func <IEnumerable <char> >),
                typeof(Func <string>),
                typeof(Func <>).MakeGenericType(typeof(IEnumerable <>)),
                typeof(Func <>)
            }, result);
        }
예제 #9
0
        public void Contravariant_ShouldBeDisabledGlobally()
        {
            // Arrange
            // we need a target container to set options
            var targets = new TargetContainer();

            targets.SetOption <Options.EnableContravariance>(false);

            // Act
            var result = new TargetTypeSelector(typeof(IContravariant <BaseClassGrandchild>), targets).ToArray();

            // Assert

            //should only calculate the exact type and the open generic
            Assert.Equal(
                new[]
            {
                typeof(IContravariant <BaseClassGrandchild>),
                typeof(IContravariant <>)
            },
                result);
        }
        public void MixedVariance_ShouldMixContravarianceWithCovariance()
        {
            // Arrange
            TargetContainer targets = new TargetContainer();

            targets.RegisterObject <Func <BaseClass, BaseClassChild> >(bc => new BaseClassChild());

            // Act
            var result = new TargetTypeSelector(typeof(Func <BaseClassChild, BaseClass>), targets).ToArray();

            LogActual(result);

            // Assert
            Assert.Equal(new[]
            {
                typeof(Func <BaseClassChild, BaseClass>),
                typeof(Func <BaseClass, BaseClass>),
                typeof(Func <BaseClass, BaseClassChild>),
                typeof(Func <object, BaseClass>),
                typeof(Func <,>)
            },
                         result);
        }