-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for nested/pointer/byref types for Type.ToTypeString() #3468
Changes from all commits
b6c7859
e8f98f2
15f90f3
7c090e7
9e045fa
e74eb65
2f4a887
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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,148 @@ 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))] | ||
[DataRow("void", typeof(void))] | ||
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<float>", typeof(Span<float>))] | ||
[DataRow("System.Memory<char>", typeof(Memory<char>))] | ||
[DataRow("System.Collections.Generic.IEnumerable<int>", typeof(IEnumerable<int>))] | ||
[DataRow("System.Collections.Generic.Dictionary<int, System.Collections.Generic.List<float>>", typeof(Dictionary<int, List<float>>))] | ||
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<float>", typeof(Span<float>).ToTypeString()); | ||
Assert.AreEqual("System.Memory<char>", typeof(Memory<char>).ToTypeString()); | ||
Assert.AreEqual("System.Collections.Generic.IEnumerable<int>", typeof(IEnumerable<int>).ToTypeString()); | ||
Assert.AreEqual(typeof(Dictionary<int, List<float>>).ToTypeString(), "System.Collections.Generic.Dictionary<int, System.Collections.Generic.List<float>>"); | ||
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<int?>", typeof(Animal.Rabbit<int?>))] | ||
[DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Rabbit<string>", typeof(Animal.Rabbit<string>))] | ||
[DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Rabbit<int>.Foo", typeof(Animal.Rabbit<int>.Foo))] | ||
[DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Rabbit<(string, int)?>.Foo", typeof(Animal.Rabbit<(string, int)?>.Foo))] | ||
[DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Rabbit<int>.Foo<string>", typeof(Animal.Rabbit<int>.Foo<string>))] | ||
[DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Rabbit<int>.Foo<int[]>", typeof(Animal.Rabbit<int>.Foo<int[]>))] | ||
[DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Rabbit<string[]>.Foo<object>", typeof(Animal.Rabbit<string[]>.Foo<object>))] | ||
[DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Rabbit<(string, int)?>.Foo<(int, int?)>", typeof(Animal.Rabbit<(string, int)?>.Foo<(int, int?)>))] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No 🦙? 😒 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. jk There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Too late! e74eb65 🙈 |
||
[DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Llama<float, System.DateTime>", typeof(Animal.Llama<float, DateTime>))] | ||
[DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Llama<string, (int?, object)>", typeof(Animal.Llama<string, (int?, object)>))] | ||
[DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Llama<string, (int?, object)?>.Foo", typeof(Animal.Llama<string, (int?, object)?>.Foo))] | ||
[DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Llama<float, System.DateTime>.Foo", typeof(Animal.Llama<float, DateTime>.Foo))] | ||
[DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Llama<string, (int?, object)?>.Foo<string>", typeof(Animal.Llama<string, (int?, object)?>.Foo<string>))] | ||
[DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Llama<float, System.DateTime>.Foo<(float?, int)?>", typeof(Animal.Llama<float, DateTime>.Foo<(float?, int)?>))] | ||
[DataRow("UnitTests.Extensions.Test_TypeExtensions.Vehicle<double>", typeof(Vehicle<double>))] | ||
[DataRow("UnitTests.Extensions.Test_TypeExtensions.Vehicle<int?>[]", typeof(Vehicle<int?>[]))] | ||
[DataRow("System.Collections.Generic.List<UnitTests.Extensions.Test_TypeExtensions.Vehicle<int>>", typeof(List<Vehicle<int>>))] | ||
[DataRow("System.Collections.Generic.List<UnitTests.Extensions.Test_TypeExtensions.Animal.Rabbit<int?>>", typeof(List<Animal.Rabbit<int?>>))] | ||
[DataRow("System.Collections.Generic.List<UnitTests.Extensions.Test_TypeExtensions.Animal.Llama<float, System.DateTime[]>>", typeof(List<Animal.Llama<float, DateTime[]>>))] | ||
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<int>*", typeof(Foo<int>*))] | ||
[DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Cat**", typeof(Animal.Cat**))] | ||
[DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Cat<int>*", typeof(Animal.Cat<int>*))] | ||
[DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Cat<float>.Bar**", typeof(Animal.Cat<float>.Bar**))] | ||
[DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Cat<double>.Bar<int>***", typeof(Animal.Cat<double>.Bar<int>***))] | ||
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<int>&", typeof(Foo<int>))] | ||
[DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Cat&", typeof(Animal.Cat))] | ||
[DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Cat<int>&", typeof(Animal.Cat<int>))] | ||
[DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Cat<float>.Bar&", typeof(Animal.Cat<float>.Bar))] | ||
[DataRow("UnitTests.Extensions.Test_TypeExtensions.Animal.Cat<double>.Bar<int>&", typeof(Animal.Cat<double>.Bar<int>))] | ||
public void Test_TypeExtensions_RefTypes(string name, Type type) | ||
{ | ||
Assert.AreEqual(name, type.MakeByRefType().ToTypeString()); | ||
} | ||
|
||
private class Animal | ||
{ | ||
public struct Cat | ||
{ | ||
} | ||
|
||
public struct Cat<T1> | ||
{ | ||
public struct Bar | ||
{ | ||
} | ||
|
||
public struct Bar<T2> | ||
{ | ||
} | ||
} | ||
|
||
public class Dog | ||
{ | ||
} | ||
|
||
public class Rabbit<T> | ||
{ | ||
public class Foo | ||
{ | ||
} | ||
|
||
public class Foo<T2> | ||
{ | ||
} | ||
} | ||
|
||
public class Llama<T1, T2> | ||
{ | ||
public class Foo | ||
{ | ||
} | ||
|
||
public class Foo<T3> | ||
{ | ||
} | ||
} | ||
} | ||
|
||
private class Vehicle<T> | ||
{ | ||
} | ||
} | ||
|
||
internal struct Foo<T> | ||
{ | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the output here significantly different or just better formatted here? i.e. if someone with 6.1 upgrades, will the result be different in the cases where things worked?
(Just want to check if we should mark this as a breaking change even though the API surface itself didn't change.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The output should be the same for types that were properly supported already 😊
In that line I'm explicitly adding the namespace just because with this change we're now using the name of each type directly instead of the fullname (so that we can manually traverse each type in case of nested types), so we need to add the namespace at the start ourselves to match the previous output with the fully qualified name.
As for changes between this PR and the previous version, here's some examples.
I'm only displaying cases with actual differences, such as nested types or pointer/ref types:
In general, some cases just look nicer (eg.
.
instead of+
for a simple nested type, orvoid
instead ofSystem.Void
), while others are now actually correct, whereas currently they are either missing bits (eg. nested types getting lost in the process) and/or displayed with wrong type arguments (they're basically all combined together).