diff --git a/src/Platform/Microsoft.Testing.Extensions.TrxReport.Abstractions/TrxReportProperties.cs b/src/Platform/Microsoft.Testing.Extensions.TrxReport.Abstractions/TrxReportProperties.cs index 09a55f0650..e4d92e116c 100644 --- a/src/Platform/Microsoft.Testing.Extensions.TrxReport.Abstractions/TrxReportProperties.cs +++ b/src/Platform/Microsoft.Testing.Extensions.TrxReport.Abstractions/TrxReportProperties.cs @@ -17,6 +17,26 @@ public sealed record StandardOutputTrxMessage(string? Message) : TrxMessage(Mess public sealed record DebugOrTraceTrxMessage(string? Message) : TrxMessage(Message); -public sealed record TrxMessagesProperty(TrxMessage[] Messages) : IProperty; - -public sealed record TrxCategoriesProperty(string[] Categories) : IProperty; +public sealed record TrxMessagesProperty(TrxMessage[] Messages) : IProperty +{ + [SuppressMessage("CodeQuality", "IDE0051:Remove unused private members", Justification = "https://github.com/dotnet/roslyn/issues/52421")] + private bool PrintMembers(StringBuilder builder) + { + builder.Append("Messages = ["); + builder.Append(string.Join(", ", Messages.Select(x => x.ToString()))); + builder.Append(']'); + return true; + } +} + +public sealed record TrxCategoriesProperty(string[] Categories) : IProperty +{ + [SuppressMessage("CodeQuality", "IDE0051:Remove unused private members", Justification = "https://github.com/dotnet/roslyn/issues/52421")] + private bool PrintMembers(StringBuilder builder) + { + builder.Append("Categories = ["); + builder.Append(string.Join(", ", Categories)); + builder.Append(']'); + return true; + } +} diff --git a/src/Platform/Microsoft.Testing.Platform/Messages/TestNodeProperties.cs b/src/Platform/Microsoft.Testing.Platform/Messages/TestNodeProperties.cs index 83afea914a..64c6bcab3d 100644 --- a/src/Platform/Microsoft.Testing.Platform/Messages/TestNodeProperties.cs +++ b/src/Platform/Microsoft.Testing.Platform/Messages/TestNodeProperties.cs @@ -262,6 +262,17 @@ public TimingProperty(TimingInfo globalTiming, StepTimingInfo[] stepTimings) /// Gets the steps timing info. /// public StepTimingInfo[] StepTimings { get; } + + [SuppressMessage("CodeQuality", "IDE0051:Remove unused private members", Justification = "https://github.com/dotnet/roslyn/issues/52421")] + private bool PrintMembers(StringBuilder builder) + { + builder.Append("GlobalTiming = "); + builder.Append(GlobalTiming); + builder.Append(", StepTimings = ["); + builder.Append(string.Join(", ", StepTimings.Select(x => x.ToString()))); + builder.Append(']'); + return true; + } } /// @@ -301,7 +312,26 @@ public sealed record TestFileLocationProperty(string FilePath, LinePositionSpan /// Method name. /// Parameter type full name. /// Return type full name. -public sealed record TestMethodIdentifierProperty(string AssemblyFullName, string Namespace, string TypeName, string MethodName, string[] ParameterTypeFullNames, string ReturnTypeFullName) : IProperty; +public sealed record TestMethodIdentifierProperty(string AssemblyFullName, string Namespace, string TypeName, string MethodName, string[] ParameterTypeFullNames, string ReturnTypeFullName) : IProperty +{ + [SuppressMessage("CodeQuality", "IDE0051:Remove unused private members", Justification = "https://github.com/dotnet/roslyn/issues/52421")] + private bool PrintMembers(StringBuilder builder) + { + builder.Append("AssemblyFullName = "); + builder.Append(AssemblyFullName); + builder.Append(", Namespace = "); + builder.Append(Namespace); + builder.Append(", TypeName = "); + builder.Append(TypeName); + builder.Append(", MethodName = "); + builder.Append(MethodName); + builder.Append(", ParameterTypeFullNames = ["); + builder.Append(string.Join(", ", ParameterTypeFullNames)); + builder.Append("], ReturnTypeFullName = "); + builder.Append(ReturnTypeFullName); + return true; + } +} /// /// Initializes a new instance of the class. @@ -338,6 +368,30 @@ public record StandardErrorProperty(string StandardError) : IProperty; internal sealed record SerializableKeyValuePairStringProperty(string Key, string Value) : KeyValuePairStringProperty(Key, Value); -internal sealed record SerializableNamedKeyValuePairsStringProperty(string Name, KeyValuePair[] Pairs) : IProperty; +internal sealed record SerializableNamedKeyValuePairsStringProperty(string Name, KeyValuePair[] Pairs) : IProperty +{ + [SuppressMessage("CodeQuality", "IDE0051:Remove unused private members", Justification = "https://github.com/dotnet/roslyn/issues/52421")] + private bool PrintMembers(StringBuilder builder) + { + builder.Append("Name = "); + builder.Append(Name); + builder.Append(", Pairs = ["); + builder.Append(string.Join(", ", Pairs.Select(x => x.ToString()))); + builder.Append(']'); + return true; + } +} -internal sealed record SerializableNamedArrayStringProperty(string Name, string[] Values) : IProperty; +internal sealed record SerializableNamedArrayStringProperty(string Name, string[] Values) : IProperty +{ + [SuppressMessage("CodeQuality", "IDE0051:Remove unused private members", Justification = "https://github.com/dotnet/roslyn/issues/52421")] + private bool PrintMembers(StringBuilder builder) + { + builder.Append("Name = "); + builder.Append(Name); + builder.Append(", Values = ["); + builder.Append(string.Join(", ", Values)); + builder.Append(']'); + return true; + } +} diff --git a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/TrxReportPropertiesTests.cs b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/TrxReportPropertiesTests.cs new file mode 100644 index 0000000000..a24247877c --- /dev/null +++ b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/TrxReportPropertiesTests.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.Testing.Extensions.TrxReport.Abstractions.UnitTests; + +[TestClass] +public sealed class TrxReportPropertiesTests +{ + [TestMethod] + public void TrxMessagesProperty_ToStringIsCorrect() + => Assert.AreEqual( + "TrxMessagesProperty { Messages = [TrxMessage { Message = some message }] }", + new TrxMessagesProperty([new("some message")]).ToString()); + + [TestMethod] + public void TrxCategoriesProperty_ToStringIsCorrect() + => Assert.AreEqual( + "TrxCategoriesProperty { Categories = [some category] }", + new TrxCategoriesProperty(["some category"]).ToString()); +} diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Messages/TestNodePropertiesTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Messages/TestNodePropertiesTests.cs new file mode 100644 index 0000000000..a733a793ec --- /dev/null +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Messages/TestNodePropertiesTests.cs @@ -0,0 +1,222 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.Testing.Platform.Extensions.Messages.UnitTests; + +[TestClass] +public sealed class TestNodePropertiesTests +{ + [TestMethod] + public void KeyValuePairStringProperty_ToStringIsCorrect() + => Assert.AreEqual( + "KeyValuePairStringProperty { Key = key, Value = value }", + new KeyValuePairStringProperty("key", "value").ToString()); + + [TestMethod] + public void DiscoveredTestNodeStateProperty_ToStringIsCorrect() + => Assert.AreEqual( + "DiscoveredTestNodeStateProperty { Explanation = some explanation }", + new DiscoveredTestNodeStateProperty("some explanation").ToString()); + + [TestMethod] + public void DiscoveredTestNodeStateProperty_WhenNoExplanation_ToStringIsCorrect() + => Assert.AreEqual( + "DiscoveredTestNodeStateProperty { Explanation = }", + new DiscoveredTestNodeStateProperty().ToString()); + + [TestMethod] + public void InProgressTestNodeStateProperty_ToStringIsCorrect() + => Assert.AreEqual( + "InProgressTestNodeStateProperty { Explanation = some explanation }", + new InProgressTestNodeStateProperty("some explanation").ToString()); + + [TestMethod] + public void InProgressTestNodeStateProperty_WhenNoExplanation_ToStringIsCorrect() + => Assert.AreEqual( + "InProgressTestNodeStateProperty { Explanation = }", + new InProgressTestNodeStateProperty().ToString()); + + [TestMethod] + public void PassedTestNodeStateProperty_ToStringIsCorrect() + => Assert.AreEqual( + "PassedTestNodeStateProperty { Explanation = some explanation }", + new PassedTestNodeStateProperty("some explanation").ToString()); + + [TestMethod] + public void PassedTestNodeStateProperty_WhenNoExplanation_ToStringIsCorrect() + => Assert.AreEqual( + "PassedTestNodeStateProperty { Explanation = }", + new PassedTestNodeStateProperty().ToString()); + + [TestMethod] + public void SkippedTestNodeStateProperty_ToStringIsCorrect() + => Assert.AreEqual( + "SkippedTestNodeStateProperty { Explanation = some explanation }", + new SkippedTestNodeStateProperty("some explanation").ToString()); + + [TestMethod] + public void SkippedTestNodeStateProperty_WhenNoExplanation_ToStringIsCorrect() + => Assert.AreEqual( + "SkippedTestNodeStateProperty { Explanation = }", + new SkippedTestNodeStateProperty().ToString()); + + [TestMethod] + public void FailedTestNodeStateProperty_ToStringIsCorrect() + => Assert.AreEqual( + "FailedTestNodeStateProperty { Explanation = some explanation, Exception = }", + new FailedTestNodeStateProperty("some explanation").ToString()); + + [TestMethod] + public void FailedTestNodeStateProperty_WhenNoExplanation_ToStringIsCorrect() + => Assert.AreEqual( + "FailedTestNodeStateProperty { Explanation = , Exception = }", + new FailedTestNodeStateProperty().ToString()); + + [TestMethod] + public void FailedTestNodeStateProperty_WhenExceptionAndExplanation_ToStringIsCorrect() + => Assert.AreEqual( + "FailedTestNodeStateProperty { Explanation = some explanation, Exception = System.Exception: some message }", + new FailedTestNodeStateProperty(new Exception("some message"), "some explanation").ToString()); + + [TestMethod] + public void FailedTestNodeStateProperty_WhenExceptionAndNoExplanation_ToStringIsCorrect() + => Assert.AreEqual( + "FailedTestNodeStateProperty { Explanation = some message, Exception = System.Exception: some message }", + new FailedTestNodeStateProperty(new Exception("some message")).ToString()); + + [TestMethod] + public void ErrorTestNodeStateProperty_ToStringIsCorrect() + => Assert.AreEqual( + "ErrorTestNodeStateProperty { Explanation = some explanation, Exception = }", + new ErrorTestNodeStateProperty("some explanation").ToString()); + + [TestMethod] + public void ErrorTestNodeStateProperty_WhenNoExplanation_ToStringIsCorrect() + => Assert.AreEqual( + "ErrorTestNodeStateProperty { Explanation = , Exception = }", + new ErrorTestNodeStateProperty().ToString()); + + [TestMethod] + public void ErrorTestNodeStateProperty_WhenExceptionAndExplanation_ToStringIsCorrect() + => Assert.AreEqual( + "ErrorTestNodeStateProperty { Explanation = some explanation, Exception = System.Exception: some message }", + new ErrorTestNodeStateProperty(new Exception("some message"), "some explanation").ToString()); + + [TestMethod] + public void ErrorTestNodeStateProperty_WhenExceptionAndNoExplanation_ToStringIsCorrect() + => Assert.AreEqual( + "ErrorTestNodeStateProperty { Explanation = some message, Exception = System.Exception: some message }", + new ErrorTestNodeStateProperty(new Exception("some message")).ToString()); + + [TestMethod] + public void TimeoutTestNodeStateProperty_ToStringIsCorrect() + => Assert.AreEqual( + "TimeoutTestNodeStateProperty { Explanation = some explanation, Exception = , Timeout = }", + new TimeoutTestNodeStateProperty("some explanation").ToString()); + + [TestMethod] + public void TimeoutTestNodeStateProperty_WhenNoExplanation_ToStringIsCorrect() + => Assert.AreEqual( + "TimeoutTestNodeStateProperty { Explanation = , Exception = , Timeout = }", + new TimeoutTestNodeStateProperty().ToString()); + + [TestMethod] + public void TimeoutTestNodeStateProperty_WhenExceptionAndExplanation_ToStringIsCorrect() + => Assert.AreEqual( + "TimeoutTestNodeStateProperty { Explanation = some explanation, Exception = System.Exception: some message, Timeout = }", + new TimeoutTestNodeStateProperty(new Exception("some message"), "some explanation").ToString()); + + [TestMethod] + public void TimeoutTestNodeStateProperty_WhenExceptionAndNoExplanation_ToStringIsCorrect() + => Assert.AreEqual( + "TimeoutTestNodeStateProperty { Explanation = some message, Exception = System.Exception: some message, Timeout = }", + new TimeoutTestNodeStateProperty(new Exception("some message")).ToString()); + + [TestMethod] + public void CancelledTestNodeStateProperty_ToStringIsCorrect() + => Assert.AreEqual( + "CancelledTestNodeStateProperty { Explanation = some explanation, Exception = }", + new CancelledTestNodeStateProperty("some explanation").ToString()); + + [TestMethod] + public void CancelledTestNodeStateProperty_WhenNoExplanation_ToStringIsCorrect() + => Assert.AreEqual( + "CancelledTestNodeStateProperty { Explanation = , Exception = }", + new CancelledTestNodeStateProperty().ToString()); + + [TestMethod] + public void CancelledTestNodeStateProperty_WhenExceptionAndExplanation_ToStringIsCorrect() + => Assert.AreEqual( + "CancelledTestNodeStateProperty { Explanation = some explanation, Exception = System.Exception: some message }", + new CancelledTestNodeStateProperty(new Exception("some message"), "some explanation").ToString()); + + [TestMethod] + public void CancelledTestNodeStateProperty_WhenExceptionAndNoExplanation_ToStringIsCorrect() + => Assert.AreEqual( + "CancelledTestNodeStateProperty { Explanation = some message, Exception = System.Exception: some message }", + new CancelledTestNodeStateProperty(new Exception("some message")).ToString()); + + [TestMethod] + public void TimingProperty_ToStringIsCorrect() + { + CultureInfo originalCulture = CultureInfo.CurrentCulture; + try + { + CultureInfo.CurrentCulture = CultureInfo.InvariantCulture; + DateTimeOffset startTime = new(2021, 9, 1, 0, 0, 0, default); + DateTimeOffset endTime = new(2021, 9, 1, 1, 2, 3, default); + TimeSpan duration = endTime - startTime; + Assert.AreEqual( + "TimingProperty { GlobalTiming = TimingInfo { StartTime = 09/01/2021 00:00:00 +00:00, EndTime = 09/01/2021 01:02:03 +00:00, Duration = 01:02:03 }, StepTimings = [] }", + new TimingProperty(new(startTime, endTime, duration)).ToString()); + } + finally + { + CultureInfo.CurrentCulture = originalCulture; + } + } + + [TestMethod] + public void TimingProperty_WithStepTimings_ToStringIsCorrect() + { + CultureInfo originalCulture = CultureInfo.CurrentCulture; + try + { + CultureInfo.CurrentCulture = CultureInfo.InvariantCulture; + DateTimeOffset startTime = new(2021, 9, 1, 0, 0, 0, default); + DateTimeOffset endTime = new(2021, 9, 1, 1, 2, 3, default); + TimeSpan duration = endTime - startTime; + Assert.AreEqual( + "TimingProperty { GlobalTiming = TimingInfo { StartTime = 09/01/2021 00:00:00 +00:00, EndTime = 09/01/2021 01:02:03 +00:00, Duration = 01:02:03 }, StepTimings = [StepTimingInfo { Id = run, Description = some description, Timing = TimingInfo { StartTime = 09/01/2021 00:00:00 +00:00, EndTime = 09/01/2021 01:02:03 +00:00, Duration = 01:02:03 } }] }", + new TimingProperty(new(startTime, endTime, duration), [new("run", "some description", new(startTime, endTime, duration))]).ToString()); + } + finally + { + CultureInfo.CurrentCulture = originalCulture; + } + } + + [TestMethod] + public void TestFileLocationProperty_ToStringIsCorrect() + => Assert.AreEqual( + "TestFileLocationProperty { FilePath = some path, LineSpan = LinePositionSpan { Start = LinePosition { Line = 42, Column = 1 }, End = LinePosition { Line = 43, Column = 10 } } }", + new TestFileLocationProperty("some path", new(new(42, 1), new(43, 10))).ToString()); + + [TestMethod] + public void TestMethodIdentifierProperty_ToStringIsCorrect() + => Assert.AreEqual( + "TestMethodIdentifierProperty { AssemblyFullName = assembly, Namespace = namespace, TypeName = type, MethodName = method, ParameterTypeFullNames = [string], ReturnTypeFullName = bool }", + new TestMethodIdentifierProperty("assembly", "namespace", "type", "method", ["string"], "bool").ToString()); + + [TestMethod] + public void SerializableNamedKeyValuePairsStringProperty_ToStringIsCorrect() + => Assert.AreEqual( + "SerializableNamedKeyValuePairsStringProperty { Name = some name, Pairs = [[key, value]] }", + new SerializableNamedKeyValuePairsStringProperty("some name", [new("key", "value")]).ToString()); + + [TestMethod] + public void SerializableNamedArrayStringProperty_ToStringIsCorrect() + => Assert.AreEqual( + "SerializableNamedArrayStringProperty { Name = some name, Values = [value] }", + new SerializableNamedArrayStringProperty("some name", ["value"]).ToString()); +}