Skip to content

Commit

Permalink
Fix to get underlying type of nullable, list and dictionary object #113
Browse files Browse the repository at this point in the history
  • Loading branch information
justinyoo committed Aug 31, 2020
1 parent a69952d commit 60145a1
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System.Collections.Generic;

using Newtonsoft.Json;

namespace Aliencube.AzureFunctions.FunctionApp.Models
Expand All @@ -8,5 +10,7 @@ public class DummySubResponseModel

[JsonProperty("CapitalisedJsonRequiredValue", Required = Required.Always)]
public string JsonRequiredValue { get; set; }

public Dictionary<string, List<int>> NestedDictionaryValue { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,43 @@ public static bool IsGenericTypeOf(this Type t1, Type t2)
return t1.IsGenericType && t1.GetGenericTypeDefinition() == t2;
}

/// <summary>
/// Gets the underlying type of the given generic type.
/// </summary>
/// <param name="type">Type to check to get its underlying type.</param>
/// <returns>Returns the underlying type.</returns>
public static Type GetUnderlyingType(this Type type)
{
var underlyingType = default(Type);
if (type.IsOpenApiNullable(out var nullableUnderlyingType))
{
underlyingType = nullableUnderlyingType;
}

if (type.IsOpenApiArray())
{
underlyingType = type.GetElementType() ?? type.GetGenericArguments()[0];
}

if (type.IsOpenApiDictionary())
{
underlyingType = type.GetGenericArguments()[1];
}

if (underlyingType.IsNullOrDefault())
{
return underlyingType;
}

if (underlyingType.IsGenericType)
{
var underlyingTypeOfUnderlyingType = underlyingType.GetUnderlyingType();
underlyingType = underlyingTypeOfUnderlyingType;
}

return underlyingType;
}

/// <summary>
/// Gets the Open API description from the given <see cref="Type"/>.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public override void Visit(IAcceptor acceptor, KeyValuePair<string, Type> type,
}

// Gets the schema for the underlying type.
var underlyingType = type.Value.GetGenericArguments()[1];
var underlyingType = type.Value.GetUnderlyingType();
var types = new Dictionary<string, Type>()
{
{ underlyingType.GetOpenApiTypeName(namingStrategy), underlyingType }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public override void Visit(IAcceptor acceptor, KeyValuePair<string, Type> type,
}

// Gets the schema for the underlying type.
var underlyingType = type.Value.GetElementType() ?? type.Value.GetGenericArguments()[0];
var underlyingType = type.Value.GetUnderlyingType();
var types = new Dictionary<string, Type>()
{
{ underlyingType.GetOpenApiTypeName(namingStrategy), underlyingType }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ public override void Visit(IAcceptor acceptor, KeyValuePair<string, Type> type,
}

// Gets the schema for the underlying type.
type.Value.IsOpenApiNullable(out var underlyingType);

var underlyingType = type.Value.GetUnderlyingType();
var types = new Dictionary<string, Type>()
{
{ type.Key, underlyingType }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;

using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Extensions;
using Aliencube.AzureFunctions.Extensions.OpenApi.Core.Tests.Fakes;

using FluentAssertions;

Expand Down Expand Up @@ -57,5 +59,71 @@ public void Given_CamelCaseNamingStrategy_When_GetOpenApiTypeName_Invoked_Then_I

result.Should().Be("int32");
}

[DataTestMethod]
[DataRow(typeof(int))]
[DataRow(typeof(string))]
[DataRow(typeof(FakeModel))]
public void Given_NonGenericType_When_GetUnderlyingType_Invoked_Then_It_Should_Return_Null(Type type)
{
var result = TypeExtensions.GetUnderlyingType(type);

result.Should().BeNull();
}

[DataTestMethod]
[DataRow(typeof(int?), typeof(int))]
[DataRow(typeof(bool?), typeof(bool))]
[DataRow(typeof(DateTime?), typeof(DateTime))]
public void Given_NullableType_When_GetUnderlyingType_Invoked_Then_It_Should_Return_Result(Type type, Type expected)
{
var result = TypeExtensions.GetUnderlyingType(type);

result.Should().Be(expected);
}

[DataTestMethod]
[DataRow(typeof(List<int>), typeof(int))]
[DataRow(typeof(List<bool>), typeof(bool))]
[DataRow(typeof(List<FakeModel>), typeof(FakeModel))]
public void Given_ListType_When_GetUnderlyingType_Invoked_Then_It_Should_Return_Result(Type type, Type expected)
{
var result = TypeExtensions.GetUnderlyingType(type);

result.Should().Be(expected);
}

[DataTestMethod]
[DataRow(typeof(List<int?>), typeof(int))]
[DataRow(typeof(List<bool?>), typeof(bool))]
[DataRow(typeof(List<DateTime?>), typeof(DateTime))]
public void Given_NullableListType_When_GetUnderlyingType_Invoked_Then_It_Should_Return_Result(Type type, Type expected)
{
var result = TypeExtensions.GetUnderlyingType(type);

result.Should().Be(expected);
}

[DataTestMethod]
[DataRow(typeof(Dictionary<string, int>), typeof(int))]
[DataRow(typeof(Dictionary<string, bool>), typeof(bool))]
[DataRow(typeof(Dictionary<string, FakeModel>), typeof(FakeModel))]
public void Given_DictionaryType_When_GetUnderlyingType_Invoked_Then_It_Should_Return_Result(Type type, Type expected)
{
var result = TypeExtensions.GetUnderlyingType(type);

result.Should().Be(expected);
}

[DataTestMethod]
[DataRow(typeof(Dictionary<string, int?>), typeof(int))]
[DataRow(typeof(Dictionary<string, bool?>), typeof(bool))]
[DataRow(typeof(Dictionary<string, DateTime?>), typeof(DateTime))]
public void Given_NullableDictionaryType_When_GetUnderlyingType_Invoked_Then_It_Should_Return_Result(Type type, Type expected)
{
var result = TypeExtensions.GetUnderlyingType(type);

result.Should().Be(expected);
}
}
}

0 comments on commit 60145a1

Please sign in to comment.