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); }
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); }
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); }
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); }
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); }
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); }