diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Extensions/TypeExtensions.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Extensions/TypeExtensions.cs index 55ad50d0..37122fe6 100644 --- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Extensions/TypeExtensions.cs +++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Extensions/TypeExtensions.cs @@ -107,6 +107,13 @@ public static bool IsReferentialType(this Type type) return isReferential; } + private static HashSet jObjects = new HashSet + { + typeof(JObject), + typeof(JToken), + typeof(JArray), + }; + /// /// Checks whether the given type is Json.NET related , or not. /// @@ -119,12 +126,7 @@ public static bool IsJObjectType(this Type type) return false; } - if (type == typeof(JObject)) - { - return true; - } - - if (type == typeof(JToken)) + if (jObjects.Any(p => p == type)) { return true; } @@ -657,82 +659,31 @@ public static bool HasInterface(this Type type, string interfaceName) private static bool IsArrayType(this Type type) { - if (type.BaseType == typeof(Array)) - { - return true; - } - - if (type.IsGenericTypeOf(typeof(List<>))) - { - return true; - } - - if (type.IsGenericTypeOf(typeof(IList<>))) - { - return true; - } - - if (type.IsGenericTypeOf(typeof(ICollection<>))) - { - return true; - } - - if (type.IsGenericTypeOf(typeof(IEnumerable<>))) - { - return true; - } - - if (type.IsGenericTypeOf(typeof(IReadOnlyList<>))) - { - return true; - } - - if (type.IsGenericTypeOf(typeof(IReadOnlyCollection<>))) - { - return true; - } - - if (type.IsGenericTypeOf(typeof(HashSet<>))) - { - return true; - } - - if (type.IsGenericTypeOf(typeof(ISet<>))) - { - return true; - } - - return false; + var isArrayType = type.Name.Equals("String", StringComparison.InvariantCultureIgnoreCase) == false && + type.GetInterfaces() + .Where(p => p.IsInterface) + .Where(p => p.Name.Equals("IEnumerable", StringComparison.InvariantCultureIgnoreCase) == true) + .Any() && + type.IsJObjectType() == false && + type.IsDictionaryType() == false; + + return isArrayType; } - private static bool IsDictionaryType(this Type type) + private static HashSet dictionaries = new HashSet { - if (!type.IsGenericType) - { - return false; - } + "Dictionary`2", + "IDictionary`2", + "IReadOnlyDictionary`2", + "KeyValuePair`2", + }; - if (type.Name.Equals("Dictionary`2", StringComparison.CurrentCultureIgnoreCase)) - { - return true; - } - - if (type.Name.Equals("IDictionary`2", StringComparison.CurrentCultureIgnoreCase)) - { - return true; - } - - if (type.Name.Equals("IReadOnlyDictionary`2", StringComparison.CurrentCultureIgnoreCase)) - { - return true; - } - - if (type.Name.Equals("KeyValuePair`2", StringComparison.CurrentCultureIgnoreCase)) - { - return true; - } + private static bool IsDictionaryType(this Type type) + { + var isDictionaryType = type.IsGenericType && + dictionaries.Any(p => type.Name.Equals(p, StringComparison.InvariantCultureIgnoreCase) == true); - return false; + return isDictionaryType; } private static bool IsNullableType(this Type type, out Type underlyingType) diff --git a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests/Extensions/TypeExtensionsTests.cs b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests/Extensions/TypeExtensionsTests.cs index 60f967af..3863b499 100644 --- a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests/Extensions/TypeExtensionsTests.cs +++ b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests/Extensions/TypeExtensionsTests.cs @@ -18,25 +18,57 @@ namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Extensions [TestClass] public class TypeExtensionsTests { - [TestMethod] - public void Given_IList_Should_Return_True() => - typeof(IList).IsOpenApiArray().Should().BeTrue(); - - [TestMethod] - public void Given_List_Should_Return_True() => - typeof(List).IsOpenApiArray().Should().BeTrue(); + [DataTestMethod] + [DataRow(typeof(string), false)] + [DataRow(typeof(int), false)] + [DataRow(typeof(double), false)] + [DataRow(typeof(bool), false)] + [DataRow(typeof(Array), true)] + [DataRow(typeof(string[]), true)] + [DataRow(typeof(List), true)] + [DataRow(typeof(IList), true)] + [DataRow(typeof(ICollection), true)] + [DataRow(typeof(IEnumerable), true)] + [DataRow(typeof(IReadOnlyList), true)] + [DataRow(typeof(IReadOnlyCollection), true)] + [DataRow(typeof(HashSet), true)] + [DataRow(typeof(ISet), true)] + [DataRow(typeof(Dictionary), false)] + [DataRow(typeof(IDictionary), false)] + [DataRow(typeof(IReadOnlyDictionary), false)] + [DataRow(typeof(KeyValuePair), false)] + public void Given_ArrayTypes_When_IsOpenApiArray_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = TypeExtensions.IsOpenApiArray(type); - [TestMethod] - public void Given_Array_Method_Should_Return_True() => - typeof(string[]).IsOpenApiArray().Should().BeTrue(); + result.Should().Be(expected); + } - [TestMethod] - public void Given_Object_That_Extends_List_Should_Return_False() => - typeof(JObject).IsOpenApiArray().Should().BeFalse(); + [DataTestMethod] + [DataRow(typeof(string), false)] + [DataRow(typeof(int), false)] + [DataRow(typeof(double), false)] + [DataRow(typeof(bool), false)] + [DataRow(typeof(Array), false)] + [DataRow(typeof(string[]), false)] + [DataRow(typeof(List), false)] + [DataRow(typeof(IList), false)] + [DataRow(typeof(ICollection), false)] + [DataRow(typeof(IEnumerable), false)] + [DataRow(typeof(IReadOnlyList), false)] + [DataRow(typeof(IReadOnlyCollection), false)] + [DataRow(typeof(HashSet), false)] + [DataRow(typeof(ISet), false)] + [DataRow(typeof(Dictionary), true)] + [DataRow(typeof(IDictionary), true)] + [DataRow(typeof(IReadOnlyDictionary), true)] + [DataRow(typeof(KeyValuePair), true)] + public void Given_DictionaryTypes_When_IsOpenApiDictionary_Invoked_Then_It_Should_Return_Result(Type type, bool expected) + { + var result = TypeExtensions.IsOpenApiDictionary(type); - [TestMethod] - public void Given_String_Method_Should_Return_False() => - typeof(string).IsOpenApiArray().Should().BeFalse(); + result.Should().Be(expected); + } [TestMethod] public void Given_DefaultNamingStrategy_When_GetOpenApiTypeName_Invoked_Then_It_Should_Return_Result()