From b6c7859ad6bad7dca8bdda64e783b4bb3e2b56b4 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 8 Sep 2020 14:34:49 +0200 Subject: [PATCH 1/6] Minor code refactoring in unit tests --- .../Extensions/Test_TypeExtensions.cs | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/UnitTests/UnitTests.Shared/Extensions/Test_TypeExtensions.cs b/UnitTests/UnitTests.Shared/Extensions/Test_TypeExtensions.cs index 5acb2392faa..29162c2ae4a 100644 --- a/UnitTests/UnitTests.Shared/Extensions/Test_TypeExtensions.cs +++ b/UnitTests/UnitTests.Shared/Extensions/Test_TypeExtensions.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using Microsoft.Toolkit.Extensions; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -15,32 +14,33 @@ public class Test_TypeExtensions { [TestCategory("TypeExtensions")] [TestMethod] - public void Test_TypeExtensions_BuiltInTypes() + [DataRow("bool", typeof(bool))] + [DataRow("int", typeof(int))] + [DataRow("float", typeof(float))] + [DataRow("double", typeof(double))] + [DataRow("decimal", typeof(decimal))] + [DataRow("object", typeof(object))] + [DataRow("string", typeof(string))] + public void Test_TypeExtensions_BuiltInTypes(string name, Type type) { - Assert.AreEqual("bool", typeof(bool).ToTypeString()); - Assert.AreEqual("int", typeof(int).ToTypeString()); - Assert.AreEqual("float", typeof(float).ToTypeString()); - Assert.AreEqual("double", typeof(double).ToTypeString()); - Assert.AreEqual("decimal", typeof(decimal).ToTypeString()); - Assert.AreEqual("object", typeof(object).ToTypeString()); - Assert.AreEqual("string", typeof(string).ToTypeString()); + Assert.AreEqual(name, type.ToTypeString()); } [TestCategory("TypeExtensions")] [TestMethod] - [SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1009", Justification = "Nullable value tuple type")] - public void Test_TypeExtensions_GenericTypes() + [DataRow("int?", typeof(int?))] + [DataRow("System.DateTime?", typeof(DateTime?))] + [DataRow("(int, float)", typeof((int, float)))] + [DataRow("(double?, string, int)?", typeof((double?, string, int)?))] + [DataRow("int[]", typeof(int[]))] + [DataRow("int[,]", typeof(int[,]))] + [DataRow("System.Span", typeof(Span))] + [DataRow("System.Memory", typeof(Memory))] + [DataRow("System.Collections.Generic.IEnumerable", typeof(IEnumerable))] + [DataRow("System.Collections.Generic.Dictionary>", typeof(Dictionary>))] + public void Test_TypeExtensions_GenericTypes(string name, Type type) { - Assert.AreEqual("int?", typeof(int?).ToTypeString()); - Assert.AreEqual("System.DateTime?", typeof(DateTime?).ToTypeString()); - Assert.AreEqual("(int, float)", typeof((int, float)).ToTypeString()); - Assert.AreEqual("(double?, string, int)?", typeof((double?, string, int)?).ToTypeString()); - Assert.AreEqual("int[]", typeof(int[]).ToTypeString()); - Assert.AreEqual(typeof(int[,]).ToTypeString(), "int[,]"); - Assert.AreEqual("System.Span", typeof(Span).ToTypeString()); - Assert.AreEqual("System.Memory", typeof(Memory).ToTypeString()); - Assert.AreEqual("System.Collections.Generic.IEnumerable", typeof(IEnumerable).ToTypeString()); - Assert.AreEqual(typeof(Dictionary>).ToTypeString(), "System.Collections.Generic.Dictionary>"); + Assert.AreEqual(name, type.ToTypeString()); } } } From e8f98f2df6ca3ebd9a099ccefbd1fa4459250821 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 8 Sep 2020 18:56:24 +0200 Subject: [PATCH 2/6] Added support for nested types --- .../Extensions/TypeExtensions.cs | 122 +++++++++++++----- .../Extensions/Test_TypeExtensions.cs | 81 ++++++++++++ 2 files changed, 169 insertions(+), 34 deletions(-) diff --git a/Microsoft.Toolkit/Extensions/TypeExtensions.cs b/Microsoft.Toolkit/Extensions/TypeExtensions.cs index 3d84b9aed68..0b2ab60b4c5 100644 --- a/Microsoft.Toolkit/Extensions/TypeExtensions.cs +++ b/Microsoft.Toolkit/Extensions/TypeExtensions.cs @@ -56,7 +56,7 @@ public static class TypeExtensions public static string ToTypeString(this Type type) { // Local function to create the formatted string for a given type - static string FormatDisplayString(Type type) + static string FormatDisplayString(Type type, int genericTypeOffset, ReadOnlySpan typeArguments) { // Primitive types use the keyword name if (BuiltInTypesMap.TryGetValue(type, out string? typeName)) @@ -64,62 +64,114 @@ static string FormatDisplayString(Type type) return typeName!; } - // Generic types - if ( -#if NETSTANDARD1_4 - type.GetTypeInfo().IsGenericType && -#else - type.IsGenericType && -#endif - type.FullName is { } fullName && - fullName.Split('`') is { } tokens && - tokens.Length > 0 && - tokens[0] is { } genericName && - genericName.Length > 0) + // Array types are displayed as Foo[] + if (type.IsArray) + { + var elementType = type.GetElementType()!; + var rank = type.GetArrayRank(); + + return $"{FormatDisplayString(elementType, 0, elementType.GetGenericArguments())}[{new string(',', rank - 1)}]"; + } + + // By checking generic types here we are only interested in specific cases, + // ie. nullable value types or value typles. We have a separate path for custom + // generic types, as we can't rely on this API in that case, as it doesn't show + // a difference between nested types that are themselves generic, or nested simple + // types from a generic declaring type. To deal with that, we need to manually track + // the offset within the array of generic arguments for the whole constructed type. + if (type.IsGenericType()) { - var typeArguments = type.GetGenericArguments().Select(FormatDisplayString); + var genericTypeDefinition = type.GetGenericTypeDefinition(); // Nullable types are displayed as T? - var genericType = type.GetGenericTypeDefinition(); - if (genericType == typeof(Nullable<>)) + if (genericTypeDefinition == typeof(Nullable<>)) { - return $"{typeArguments.First()}?"; + var nullableArguments = type.GetGenericArguments(); + + return $"{FormatDisplayString(nullableArguments[0], 0, nullableArguments)}?"; } // ValueTuple types are displayed as (T1, T2) - if (genericType == typeof(ValueTuple<>) || - genericType == typeof(ValueTuple<,>) || - genericType == typeof(ValueTuple<,,>) || - genericType == typeof(ValueTuple<,,,>) || - genericType == typeof(ValueTuple<,,,,>) || - genericType == typeof(ValueTuple<,,,,,>) || - genericType == typeof(ValueTuple<,,,,,,>) || - genericType == typeof(ValueTuple<,,,,,,,>)) + if (genericTypeDefinition == typeof(ValueTuple<>) || + genericTypeDefinition == typeof(ValueTuple<,>) || + genericTypeDefinition == typeof(ValueTuple<,,>) || + genericTypeDefinition == typeof(ValueTuple<,,,>) || + genericTypeDefinition == typeof(ValueTuple<,,,,>) || + genericTypeDefinition == typeof(ValueTuple<,,,,,>) || + genericTypeDefinition == typeof(ValueTuple<,,,,,,>) || + genericTypeDefinition == typeof(ValueTuple<,,,,,,,>)) { - return $"({string.Join(", ", typeArguments)})"; + var formattedTypes = type.GetGenericArguments().Select(t => FormatDisplayString(t, 0, t.GetGenericArguments())); + + return $"({string.Join(", ", formattedTypes)})"; } + } + + string displayName; + + // Generic types + if (type.Name.Contains('`')) + { + // Retrieve the current generic arguments for the current type (leaf or not) + var tokens = type.Name.Split('`'); + var genericArgumentsCount = int.Parse(tokens[1]); + var typeArgumentsOffset = typeArguments.Length - genericTypeOffset - genericArgumentsCount; + var currentTypeArguments = typeArguments.Slice(typeArgumentsOffset, genericArgumentsCount).ToArray(); + var formattedTypes = currentTypeArguments.Select(t => FormatDisplayString(t, 0, t.GetGenericArguments())); // Standard generic types are displayed as Foo - return $"{genericName}<{string.Join(", ", typeArguments)}>"; + displayName = $"{tokens[0]}<{string.Join(", ", formattedTypes)}>"; + + // Track the current offset for the shared generic arguments list + genericTypeOffset += genericArgumentsCount; + } + else + { + // Simple custom types + displayName = type.Name; } - // Array types are displayed as Foo[] - if (type.IsArray) + // If the type is nested, recursively format the hierarchy as well + if (type.IsNested) { - var elementType = type.GetElementType(); - var rank = type.GetArrayRank(); + var openDeclaringType = type.DeclaringType!; + var rootGenericArguments = typeArguments.Slice(0, typeArguments.Length - genericTypeOffset).ToArray(); + + // If the declaring type is generic, we need to reconstruct the closed type + // manually, as the declaring type instance doesn't retain type information. + if (rootGenericArguments.Length > 0) + { + var closedDeclaringType = openDeclaringType.GetGenericTypeDefinition().MakeGenericType(rootGenericArguments); + + return $"{FormatDisplayString(closedDeclaringType, genericTypeOffset, typeArguments)}.{displayName}"; + } - return $"{FormatDisplayString(elementType)}[{new string(',', rank - 1)}]"; + return $"{FormatDisplayString(openDeclaringType, genericTypeOffset, typeArguments)}.{displayName}"; } - return type.ToString(); + return $"{type.Namespace}.{displayName}"; } // Atomically get or build the display string for the current type. // Manually create a static lambda here to enable caching of the generated closure. // This is a workaround for the missing caching for method group conversions, and should // be removed once this issue is resolved: https://github.com/dotnet/roslyn/issues/5835. - return DisplayNames.GetValue(type, t => FormatDisplayString(t)); + return DisplayNames.GetValue(type, t => FormatDisplayString(t, 0, type.GetGenericArguments())); + } + + /// + /// Returns whether or not a given type is generic. + /// + /// The input type. + /// Whether or not the input type is generic. + [Pure] + private static bool IsGenericType(this Type type) + { +#if NETSTANDARD1_4 + return type.GetTypeInfo().IsGenericType; +#else + return type.IsGenericType; +#endif } #if NETSTANDARD1_4 @@ -128,6 +180,7 @@ tokens[0] is { } genericName && /// /// The input type. /// An array of types representing the generic arguments. + [Pure] private static Type[] GetGenericArguments(this Type type) { return type.GetTypeInfo().GenericTypeParameters; @@ -139,6 +192,7 @@ private static Type[] GetGenericArguments(this Type type) /// The input type. /// The type to check against. /// if is an instance of , otherwise. + [Pure] internal static bool IsInstanceOfType(this Type type, object value) { return type.GetTypeInfo().IsAssignableFrom(value.GetType().GetTypeInfo()); diff --git a/UnitTests/UnitTests.Shared/Extensions/Test_TypeExtensions.cs b/UnitTests/UnitTests.Shared/Extensions/Test_TypeExtensions.cs index 29162c2ae4a..4fe7c9d8726 100644 --- a/UnitTests/UnitTests.Shared/Extensions/Test_TypeExtensions.cs +++ b/UnitTests/UnitTests.Shared/Extensions/Test_TypeExtensions.cs @@ -42,5 +42,86 @@ public void Test_TypeExtensions_GenericTypes(string name, Type type) { Assert.AreEqual(name, type.ToTypeString()); } + + [TestCategory("TypeExtensions")] + [TestMethod] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal", typeof(Animal))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Cat", typeof(Animal.Cat))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Dog", typeof(Animal.Dog))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Rabbit", typeof(Animal.Rabbit))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Rabbit", typeof(Animal.Rabbit))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Rabbit.Foo", typeof(Animal.Rabbit.Foo))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Rabbit<(string, int)?>.Foo", typeof(Animal.Rabbit<(string, int)?>.Foo))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Rabbit.Foo", typeof(Animal.Rabbit.Foo))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Rabbit.Foo", typeof(Animal.Rabbit.Foo))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Rabbit.Foo", typeof(Animal.Rabbit.Foo))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Rabbit<(string, int)?>.Foo<(int, int?)>", typeof(Animal.Rabbit<(string, int)?>.Foo<(int, int?)>))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Giraffe", typeof(Animal.Giraffe))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Giraffe", typeof(Animal.Giraffe))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Giraffe.Foo", typeof(Animal.Giraffe.Foo))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Giraffe.Foo", typeof(Animal.Giraffe.Foo))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Giraffe.Foo", typeof(Animal.Giraffe.Foo))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Giraffe.Foo<(float?, int)?>", typeof(Animal.Giraffe.Foo<(float?, int)?>))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Vehicle", typeof(Vehicle))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Vehicle[]", typeof(Vehicle[]))] + [DataRow("System.Collections.Generic.List>", typeof(List>))] + [DataRow("System.Collections.Generic.List>", typeof(List>))] + [DataRow("System.Collections.Generic.List>", typeof(List>))] + public void Test_TypeExtensions_NestedTypes(string name, Type type) + { + Assert.AreEqual(name, type.ToTypeString()); + } + + private class Animal + { + public struct Cat + { + } + + public struct Cat + { + public struct Bar + { + } + + public struct Bar + { + } + } + + public class Dog + { + } + + public class Rabbit + { + public class Foo + { + } + + public class Foo + { + } + } + + public class Giraffe + { + public class Foo + { + } + + public class Foo + { + } + } + } + + private class Vehicle + { + } + } + + internal struct Foo + { } } From 15f90f376f40a932e091fb9597b8303798ec0568 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 8 Sep 2020 18:57:22 +0200 Subject: [PATCH 3/6] Added support for void type --- Microsoft.Toolkit/Extensions/TypeExtensions.cs | 3 ++- UnitTests/UnitTests.Shared/Extensions/Test_TypeExtensions.cs | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Microsoft.Toolkit/Extensions/TypeExtensions.cs b/Microsoft.Toolkit/Extensions/TypeExtensions.cs index 0b2ab60b4c5..51650dcdcf0 100644 --- a/Microsoft.Toolkit/Extensions/TypeExtensions.cs +++ b/Microsoft.Toolkit/Extensions/TypeExtensions.cs @@ -39,7 +39,8 @@ public static class TypeExtensions [typeof(double)] = "double", [typeof(decimal)] = "decimal", [typeof(object)] = "object", - [typeof(string)] = "string" + [typeof(string)] = "string", + [typeof(void)] = "void" }; /// diff --git a/UnitTests/UnitTests.Shared/Extensions/Test_TypeExtensions.cs b/UnitTests/UnitTests.Shared/Extensions/Test_TypeExtensions.cs index 4fe7c9d8726..c4bf0b9354a 100644 --- a/UnitTests/UnitTests.Shared/Extensions/Test_TypeExtensions.cs +++ b/UnitTests/UnitTests.Shared/Extensions/Test_TypeExtensions.cs @@ -21,6 +21,7 @@ public class Test_TypeExtensions [DataRow("decimal", typeof(decimal))] [DataRow("object", typeof(object))] [DataRow("string", typeof(string))] + [DataRow("void", typeof(void))] public void Test_TypeExtensions_BuiltInTypes(string name, Type type) { Assert.AreEqual(name, type.ToTypeString()); From 7c090e735e98d118d8bc75d3a6f21bf54a4beb66 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 8 Sep 2020 19:06:55 +0200 Subject: [PATCH 4/6] Added support for pointer and by-ref types --- .../Extensions/TypeExtensions.cs | 32 +++++++++++++++--- .../Extensions/Test_TypeExtensions.cs | 33 +++++++++++++++++++ 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/Microsoft.Toolkit/Extensions/TypeExtensions.cs b/Microsoft.Toolkit/Extensions/TypeExtensions.cs index 51650dcdcf0..a94e39c5046 100644 --- a/Microsoft.Toolkit/Extensions/TypeExtensions.cs +++ b/Microsoft.Toolkit/Extensions/TypeExtensions.cs @@ -154,10 +154,34 @@ static string FormatDisplayString(Type type, int genericTypeOffset, ReadOnlySpan } // Atomically get or build the display string for the current type. - // Manually create a static lambda here to enable caching of the generated closure. - // This is a workaround for the missing caching for method group conversions, and should - // be removed once this issue is resolved: https://github.com/dotnet/roslyn/issues/5835. - return DisplayNames.GetValue(type, t => FormatDisplayString(t, 0, type.GetGenericArguments())); + return DisplayNames.GetValue(type, t => + { + // By-ref types are displayed as T& + if (t.IsByRef) + { + t = t.GetElementType(); + + return $"{FormatDisplayString(t, 0, type.GetGenericArguments())}&"; + } + + // Pointer types are displayed as T* + if (t.IsPointer) + { + int depth = 0; + + // Calculate the pointer indirection level + while (t.IsPointer) + { + depth++; + t = t.GetElementType(); + } + + return $"{FormatDisplayString(t, 0, type.GetGenericArguments())}{new string('*', depth)}"; + } + + // Standard path for concrete types + return FormatDisplayString(t, 0, type.GetGenericArguments()); + }); } /// diff --git a/UnitTests/UnitTests.Shared/Extensions/Test_TypeExtensions.cs b/UnitTests/UnitTests.Shared/Extensions/Test_TypeExtensions.cs index c4bf0b9354a..486cc1ad4a7 100644 --- a/UnitTests/UnitTests.Shared/Extensions/Test_TypeExtensions.cs +++ b/UnitTests/UnitTests.Shared/Extensions/Test_TypeExtensions.cs @@ -73,6 +73,39 @@ public void Test_TypeExtensions_NestedTypes(string name, Type type) Assert.AreEqual(name, type.ToTypeString()); } +#pragma warning disable SA1015 // Closing generic brackets should be spaced correctly + [TestCategory("TypeExtensions")] + [TestMethod] + [DataRow("void*", typeof(void*))] + [DataRow("int**", typeof(int**))] + [DataRow("byte***", typeof(byte***))] + [DataRow("System.Guid*", typeof(Guid*))] + [DataRow("UnitTests.Extensions.Foo*", typeof(Foo*))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Cat**", typeof(Animal.Cat**))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Cat*", typeof(Animal.Cat*))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Cat.Bar**", typeof(Animal.Cat.Bar**))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Cat.Bar***", typeof(Animal.Cat.Bar***))] + public void Test_TypeExtensions_PointerTypes(string name, Type type) + { + Assert.AreEqual(name, type.ToTypeString()); + } +#pragma warning restore SA1015 + + [TestCategory("TypeExtensions")] + [TestMethod] + [DataRow("int&", typeof(int))] + [DataRow("byte&", typeof(byte))] + [DataRow("System.Guid&", typeof(Guid))] + [DataRow("UnitTests.Extensions.Foo&", typeof(Foo))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Cat&", typeof(Animal.Cat))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Cat&", typeof(Animal.Cat))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Cat.Bar&", typeof(Animal.Cat.Bar))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Cat.Bar&", typeof(Animal.Cat.Bar))] + public void Test_TypeExtensions_RefTypes(string name, Type type) + { + Assert.AreEqual(name, type.MakeByRefType().ToTypeString()); + } + private class Animal { public struct Cat From 9e045fa89826017c45fec7124868a1e01c723ec4 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 8 Sep 2020 19:09:30 +0200 Subject: [PATCH 5/6] Fixed unwanted capture in lambda expression --- Microsoft.Toolkit/Extensions/TypeExtensions.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Microsoft.Toolkit/Extensions/TypeExtensions.cs b/Microsoft.Toolkit/Extensions/TypeExtensions.cs index a94e39c5046..ddbdc934cd4 100644 --- a/Microsoft.Toolkit/Extensions/TypeExtensions.cs +++ b/Microsoft.Toolkit/Extensions/TypeExtensions.cs @@ -159,9 +159,9 @@ static string FormatDisplayString(Type type, int genericTypeOffset, ReadOnlySpan // By-ref types are displayed as T& if (t.IsByRef) { - t = t.GetElementType(); + t = t.GetElementType()!; - return $"{FormatDisplayString(t, 0, type.GetGenericArguments())}&"; + return $"{FormatDisplayString(t, 0, t.GetGenericArguments())}&"; } // Pointer types are displayed as T* @@ -173,14 +173,14 @@ static string FormatDisplayString(Type type, int genericTypeOffset, ReadOnlySpan while (t.IsPointer) { depth++; - t = t.GetElementType(); + t = t.GetElementType()!; } - return $"{FormatDisplayString(t, 0, type.GetGenericArguments())}{new string('*', depth)}"; + return $"{FormatDisplayString(t, 0, t.GetGenericArguments())}{new string('*', depth)}"; } // Standard path for concrete types - return FormatDisplayString(t, 0, type.GetGenericArguments()); + return FormatDisplayString(t, 0, t.GetGenericArguments()); }); } From e74eb65ee2fbe676549307c44fa6ec32c6feec0d Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 9 Sep 2020 00:21:16 +0200 Subject: [PATCH 6/6] Added llamas MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🦙 --- .../Extensions/Test_TypeExtensions.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/UnitTests/UnitTests.Shared/Extensions/Test_TypeExtensions.cs b/UnitTests/UnitTests.Shared/Extensions/Test_TypeExtensions.cs index 486cc1ad4a7..00fa6df6a8a 100644 --- a/UnitTests/UnitTests.Shared/Extensions/Test_TypeExtensions.cs +++ b/UnitTests/UnitTests.Shared/Extensions/Test_TypeExtensions.cs @@ -57,17 +57,17 @@ public void Test_TypeExtensions_GenericTypes(string name, Type type) [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Rabbit.Foo", typeof(Animal.Rabbit.Foo))] [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Rabbit.Foo", typeof(Animal.Rabbit.Foo))] [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Rabbit<(string, int)?>.Foo<(int, int?)>", typeof(Animal.Rabbit<(string, int)?>.Foo<(int, int?)>))] - [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Giraffe", typeof(Animal.Giraffe))] - [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Giraffe", typeof(Animal.Giraffe))] - [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Giraffe.Foo", typeof(Animal.Giraffe.Foo))] - [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Giraffe.Foo", typeof(Animal.Giraffe.Foo))] - [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Giraffe.Foo", typeof(Animal.Giraffe.Foo))] - [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Giraffe.Foo<(float?, int)?>", typeof(Animal.Giraffe.Foo<(float?, int)?>))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Llama", typeof(Animal.Llama))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Llama", typeof(Animal.Llama))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Llama.Foo", typeof(Animal.Llama.Foo))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Llama.Foo", typeof(Animal.Llama.Foo))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Llama.Foo", typeof(Animal.Llama.Foo))] + [DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Llama.Foo<(float?, int)?>", typeof(Animal.Llama.Foo<(float?, int)?>))] [DataRow("UnitTests.Extensions.Test_TypeExtensions.Vehicle", typeof(Vehicle))] [DataRow("UnitTests.Extensions.Test_TypeExtensions.Vehicle[]", typeof(Vehicle[]))] [DataRow("System.Collections.Generic.List>", typeof(List>))] [DataRow("System.Collections.Generic.List>", typeof(List>))] - [DataRow("System.Collections.Generic.List>", typeof(List>))] + [DataRow("System.Collections.Generic.List>", typeof(List>))] public void Test_TypeExtensions_NestedTypes(string name, Type type) { Assert.AreEqual(name, type.ToTypeString()); @@ -138,7 +138,7 @@ public class Foo } } - public class Giraffe + public class Llama { public class Foo {