From 0c27ed7bd80ad48c20683f661b0f9207a55fe61a Mon Sep 17 00:00:00 2001 From: Jared Nance Date: Sun, 12 Aug 2018 20:07:46 -0700 Subject: [PATCH] fix(#241): TypeLocator bug -- add tests --- src/JsonApiDotNetCore/Graph/TypeLocator.cs | 24 ++++-- test/UnitTests/Graph/TypeLocator_Tests.cs | 99 ++++++++++++++++++++++ 2 files changed, 117 insertions(+), 6 deletions(-) create mode 100644 test/UnitTests/Graph/TypeLocator_Tests.cs diff --git a/src/JsonApiDotNetCore/Graph/TypeLocator.cs b/src/JsonApiDotNetCore/Graph/TypeLocator.cs index 5bdb029e50..223845859a 100644 --- a/src/JsonApiDotNetCore/Graph/TypeLocator.cs +++ b/src/JsonApiDotNetCore/Graph/TypeLocator.cs @@ -45,7 +45,6 @@ private static Type[] GetAssemblyTypes(Assembly assembly) return types; } - /// /// Get all implementations of . in the assembly /// @@ -80,15 +79,28 @@ public static List GetIdentifableTypes(Assembly assembly) /// public static (Type implementation, Type registrationInterface) GetGenericInterfaceImplementation(Assembly assembly, Type openGenericInterfaceType, params Type[] genericInterfaceArguments) { + if(assembly == null) throw new ArgumentNullException(nameof(assembly)); + if(openGenericInterfaceType == null) throw new ArgumentNullException(nameof(openGenericInterfaceType)); + if(genericInterfaceArguments == null) throw new ArgumentNullException(nameof(genericInterfaceArguments)); + if(genericInterfaceArguments.Length == 0) throw new ArgumentException("No arguments supplied for the generic interface.", nameof(genericInterfaceArguments)); + if(openGenericInterfaceType.IsGenericType == false) throw new ArgumentException("Requested type is not a generic type.", nameof(openGenericInterfaceType)); + foreach (var type in assembly.GetTypes()) { var interfaces = type.GetInterfaces(); foreach (var interfaceType in interfaces) - if (interfaceType.GetTypeInfo().IsGenericType && interfaceType.GetGenericTypeDefinition() == openGenericInterfaceType) - return ( - type, - interfaceType.MakeGenericType(genericInterfaceArguments) - ); + { + if (interfaceType.IsGenericType) + { + var genericTypeDefinition = interfaceType.GetGenericTypeDefinition(); + if(genericTypeDefinition == openGenericInterfaceType.GetGenericTypeDefinition()) { + return ( + type, + genericTypeDefinition.MakeGenericType(genericInterfaceArguments) + ); + } + } + } } return (null, null); diff --git a/test/UnitTests/Graph/TypeLocator_Tests.cs b/test/UnitTests/Graph/TypeLocator_Tests.cs new file mode 100644 index 0000000000..f0d1ce04ad --- /dev/null +++ b/test/UnitTests/Graph/TypeLocator_Tests.cs @@ -0,0 +1,99 @@ +using System; +using JsonApiDotNetCore.Graph; +using JsonApiDotNetCore.Models; +using Xunit; + +namespace UnitTests.Internal +{ + public class TypeLocator_Tests + { + [Fact] + public void GetGenericInterfaceImplementation_Gets_Implementation() + { + // arrange + var assembly = GetType().Assembly; + var openGeneric = typeof(IGenericInterface<>); + var genericArg = typeof(int); + + var expectedImplementation = typeof(Implementation); + var expectedInterface = typeof(IGenericInterface); + + // act + var result = TypeLocator.GetGenericInterfaceImplementation( + assembly, + openGeneric, + genericArg + ); + + // assert + Assert.NotNull(result); + Assert.Equal(expectedImplementation, result.implementation); + Assert.Equal(expectedInterface, result.registrationInterface); + } + + [Fact] + public void GetDerivedGenericTypes_Gets_Implementation() + { + // arrange + var assembly = GetType().Assembly; + var openGeneric = typeof(BaseType<>); + var genericArg = typeof(int); + + var expectedImplementation = typeof(DerivedType); + + // act + var results = TypeLocator.GetDerivedGenericTypes( + assembly, + openGeneric, + genericArg + ); + + // assert + Assert.NotNull(results); + var result = Assert.Single(results); + Assert.Equal(expectedImplementation, result); + } + + [Fact] + public void GetIdType_Correctly_Identifies_JsonApiResource() + { + // arrange + var type = typeof(Model); + var exextedIdType = typeof(int); + + // act + var result = TypeLocator.GetIdType(type); + + // assert + Assert.NotNull(result); + Assert.True(result.isJsonApiResource); + Assert.Equal(exextedIdType, result.idType); + } + + [Fact] + public void GetIdType_Correctly_Identifies_NonJsonApiResource() + { + // arrange + var type = typeof(DerivedType); + Type exextedIdType = null; + + // act + var result = TypeLocator.GetIdType(type); + + // assert + Assert.NotNull(result); + Assert.False(result.isJsonApiResource); + Assert.Equal(exextedIdType, result.idType); + } + } + + + public interface IGenericInterface { } + public class Implementation : IGenericInterface { } + + + public class BaseType { } + public class DerivedType : BaseType { } + + public class Model : Identifiable { } +} \ No newline at end of file