diff --git a/src/TestFramework/TestFramework/Assertions/Assert.AreEqual.cs b/src/TestFramework/TestFramework/Assertions/Assert.AreEqual.cs index 5cd7fe9939..0b08c2a036 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.AreEqual.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.AreEqual.cs @@ -48,8 +48,7 @@ internal void ComputeAssertion(string expectedExpression, string actualExpressio { if (_builder is not null) { - _builder.Insert(0, string.Format(CultureInfo.CurrentCulture, FrameworkMessages.CallerArgumentExpressionTwoParametersMessage, "expected", expectedExpression, "actual", actualExpression) + " "); - ThrowAssertAreEqualFailed(_expected, _actual, _builder.ToString()); + ThrowAssertAreEqualFailed(_expected, _actual, _builder.ToString(), expectedExpression, actualExpression); } } @@ -115,8 +114,7 @@ internal void ComputeAssertion(string notExpectedExpression, string actualExpres { if (_builder is not null) { - _builder.Insert(0, string.Format(CultureInfo.CurrentCulture, FrameworkMessages.CallerArgumentExpressionTwoParametersMessage, "notExpected", notExpectedExpression, "actual", actualExpression) + " "); - ThrowAssertAreNotEqualFailed(_notExpected, _actual, _builder.ToString()); + ThrowAssertAreNotEqualFailed(_notExpected, _actual, _builder.ToString(), notExpectedExpression, actualExpression); } } @@ -159,7 +157,7 @@ internal void ComputeAssertion(string notExpectedExpression, string actualExpres public readonly struct AssertNonGenericAreEqualInterpolatedStringHandler { private readonly StringBuilder? _builder; - private readonly Action? _failAction; + private readonly Action? _failAction; public AssertNonGenericAreEqualInterpolatedStringHandler(int literalLength, int formattedCount, float expected, float actual, float delta, out bool shouldAppend) { @@ -167,7 +165,7 @@ public AssertNonGenericAreEqualInterpolatedStringHandler(int literalLength, int if (shouldAppend) { _builder = new StringBuilder(literalLength + formattedCount); - _failAction = userMessage => ThrowAssertAreEqualFailed(expected, actual, delta, userMessage); + _failAction = (userMessage, expectedExpr, actualExpr) => ThrowAssertAreEqualFailed(expected, actual, delta, userMessage, expectedExpr, actualExpr); } } @@ -177,7 +175,7 @@ public AssertNonGenericAreEqualInterpolatedStringHandler(int literalLength, int if (shouldAppend) { _builder = new StringBuilder(literalLength + formattedCount); - _failAction = userMessage => ThrowAssertAreEqualFailed(expected, actual, delta, userMessage); + _failAction = (userMessage, expectedExpr, actualExpr) => ThrowAssertAreEqualFailed(expected, actual, delta, userMessage, expectedExpr, actualExpr); } } @@ -187,7 +185,7 @@ public AssertNonGenericAreEqualInterpolatedStringHandler(int literalLength, int if (shouldAppend) { _builder = new StringBuilder(literalLength + formattedCount); - _failAction = userMessage => ThrowAssertAreEqualFailed(expected, actual, delta, userMessage); + _failAction = (userMessage, expectedExpr, actualExpr) => ThrowAssertAreEqualFailed(expected, actual, delta, userMessage, expectedExpr, actualExpr); } } @@ -197,7 +195,7 @@ public AssertNonGenericAreEqualInterpolatedStringHandler(int literalLength, int if (shouldAppend) { _builder = new StringBuilder(literalLength + formattedCount); - _failAction = userMessage => ThrowAssertAreEqualFailed(expected, actual, delta, userMessage); + _failAction = (userMessage, expectedExpr, actualExpr) => ThrowAssertAreEqualFailed(expected, actual, delta, userMessage, expectedExpr, actualExpr); } } @@ -213,18 +211,12 @@ public AssertNonGenericAreEqualInterpolatedStringHandler(int literalLength, int if (shouldAppend) { _builder = new StringBuilder(literalLength + formattedCount); - _failAction = userMessage => ThrowAssertAreEqualFailed(expected, actual, ignoreCase, culture, userMessage); + _failAction = (userMessage, expectedExpr, actualExpr) => ThrowAssertAreEqualFailed(expected, actual, ignoreCase, culture, userMessage, expectedExpr, actualExpr); } } internal void ComputeAssertion(string expectedExpression, string actualExpression) - { - if (_failAction is not null) - { - _builder!.Insert(0, string.Format(CultureInfo.CurrentCulture, FrameworkMessages.CallerArgumentExpressionTwoParametersMessage, "expected", expectedExpression, "actual", actualExpression) + " "); - _failAction.Invoke(_builder!.ToString()); - } - } + => _failAction?.Invoke(_builder!.ToString(), expectedExpression, actualExpression); public void AppendLiteral(string value) => _builder!.Append(value); @@ -265,7 +257,7 @@ internal void ComputeAssertion(string expectedExpression, string actualExpressio public readonly struct AssertNonGenericAreNotEqualInterpolatedStringHandler { private readonly StringBuilder? _builder; - private readonly Action? _failAction; + private readonly Action? _failAction; public AssertNonGenericAreNotEqualInterpolatedStringHandler(int literalLength, int formattedCount, float notExpected, float actual, float delta, out bool shouldAppend) { @@ -273,7 +265,7 @@ public AssertNonGenericAreNotEqualInterpolatedStringHandler(int literalLength, i if (shouldAppend) { _builder = new StringBuilder(literalLength + formattedCount); - _failAction = userMessage => ThrowAssertAreNotEqualFailed(notExpected, actual, delta, userMessage); + _failAction = (userMessage, notExpectedExpr, actualExpr) => ThrowAssertAreNotEqualFailed(notExpected, actual, delta, userMessage, notExpectedExpr, actualExpr); } } @@ -283,7 +275,7 @@ public AssertNonGenericAreNotEqualInterpolatedStringHandler(int literalLength, i if (shouldAppend) { _builder = new StringBuilder(literalLength + formattedCount); - _failAction = userMessage => ThrowAssertAreNotEqualFailed(notExpected, actual, delta, userMessage); + _failAction = (userMessage, notExpectedExpr, actualExpr) => ThrowAssertAreNotEqualFailed(notExpected, actual, delta, userMessage, notExpectedExpr, actualExpr); } } @@ -293,7 +285,7 @@ public AssertNonGenericAreNotEqualInterpolatedStringHandler(int literalLength, i if (shouldAppend) { _builder = new StringBuilder(literalLength + formattedCount); - _failAction = userMessage => ThrowAssertAreNotEqualFailed(notExpected, actual, delta, userMessage); + _failAction = (userMessage, notExpectedExpr, actualExpr) => ThrowAssertAreNotEqualFailed(notExpected, actual, delta, userMessage, notExpectedExpr, actualExpr); } } @@ -303,7 +295,7 @@ public AssertNonGenericAreNotEqualInterpolatedStringHandler(int literalLength, i if (shouldAppend) { _builder = new StringBuilder(literalLength + formattedCount); - _failAction = userMessage => ThrowAssertAreNotEqualFailed(notExpected, actual, delta, userMessage); + _failAction = (userMessage, notExpectedExpr, actualExpr) => ThrowAssertAreNotEqualFailed(notExpected, actual, delta, userMessage, notExpectedExpr, actualExpr); } } @@ -319,18 +311,12 @@ public AssertNonGenericAreNotEqualInterpolatedStringHandler(int literalLength, i if (shouldAppend) { _builder = new StringBuilder(literalLength + formattedCount); - _failAction = userMessage => ThrowAssertAreNotEqualFailed(notExpected, actual, userMessage); + _failAction = (userMessage, notExpectedExpr, actualExpr) => ThrowAssertAreNotEqualFailed(notExpected, actual, userMessage, notExpectedExpr, actualExpr); } } internal void ComputeAssertion(string notExpectedExpression, string actualExpression) - { - if (_failAction is not null) - { - _builder!.Insert(0, string.Format(CultureInfo.CurrentCulture, FrameworkMessages.CallerArgumentExpressionTwoParametersMessage, "notExpected", notExpectedExpression, "actual", actualExpression) + " "); - _failAction.Invoke(_builder!.ToString()); - } - } + => _failAction?.Invoke(_builder!.ToString(), notExpectedExpression, actualExpression); public void AppendLiteral(string value) => _builder!.Append(value); @@ -488,8 +474,7 @@ public static void AreEqual(T? expected, T? actual, IEqualityComparer comp return; } - string userMessage = BuildUserMessageForExpectedExpressionAndActualExpression(message, expectedExpression, actualExpression); - ThrowAssertAreEqualFailed(expected, actual, userMessage); + ThrowAssertAreEqualFailed(expected, actual, message, expectedExpression, actualExpression); } private static bool AreEqualFailing(T? expected, T? actual, IEqualityComparer? comparer) @@ -547,24 +532,14 @@ private static bool AreEqualFailing(long expected, long actual, long delta) private static string FormatStringComparisonMessage(string? expected, string? actual, string userMessage) { // Handle null cases - if (expected is null && actual is null) - { - return string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.AreEqualFailMsg, - userMessage, - ReplaceNulls(expected), - ReplaceNulls(actual)); - } - if (expected is null || actual is null) { - return string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.AreEqualFailMsg, - userMessage, - ReplaceNulls(expected), - ReplaceNulls(actual)); + string message = userMessage; + message += FormatAlignedParameters( + (nameof(expected), FormatValue(expected)), + (nameof(actual), FormatValue(actual))); + + return message; } // Find the first difference @@ -609,98 +584,88 @@ private static string FormatStringDifferenceMessage(string expected, string actu string actualPreview = tuple.Item2; int caretPosition = tuple.Item3; - // Get localized prefixes - string expectedPrefix = FrameworkMessages.AreEqualStringDiffExpectedPrefix; - string actualPrefix = FrameworkMessages.AreEqualStringDiffActualPrefix; + // Fixed prefixes - expressions are now shown on the first line + string expectedPrefix = " expected: "; + string actualPrefix = " actual: "; - // Calculate the maximum prefix length to align the caret properly - int maxPrefixLength = Math.Max(expectedPrefix.Length, actualPrefix.Length); - - // Pad shorter prefix to match the longer one for proper alignment - string paddedExpectedPrefix = expectedPrefix.PadRight(maxPrefixLength); - string paddedActualPrefix = actualPrefix.PadRight(maxPrefixLength); + int maxPrefixLength = expectedPrefix.Length; // " expected: " is always the longest // Build the formatted lines with proper alignment - string expectedLine = paddedExpectedPrefix + $"\"{expectedPreview}\""; - string actualLine = paddedActualPrefix + $"\"{actualPreview}\""; + string expectedLine = expectedPrefix + $"\"{expectedPreview}\""; + string actualLine = actualPrefix + $"\"{actualPreview}\""; // The caret should align under the difference in the string content - // For localized prefixes with different lengths, we need to account for the longer prefix - // to ensure proper alignment. But the caret position is relative to the string content. int adjustedCaretPosition = maxPrefixLength + 1 + caretPosition; // +1 for the opening quote - // Format user message properly - add leading space if not empty, otherwise no extra formatting - string formattedUserMessage = string.IsNullOrEmpty(userMessage) ? string.Empty : $" {userMessage}"; - - return string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.AreEqualStringDiffFailMsg, - lengthInfo, - formattedUserMessage, - expectedLine, - actualLine, - new string('-', adjustedCaretPosition) + "^"); + string formattedUserMessage = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage; + + return formattedUserMessage + Environment.NewLine + lengthInfo + Environment.NewLine + expectedLine + Environment.NewLine + actualLine + Environment.NewLine + " " + new string('-', adjustedCaretPosition - 2) + "^"; } [DoesNotReturn] - private static void ThrowAssertAreEqualFailed(object? expected, object? actual, string userMessage) + private static void ThrowAssertAreEqualFailed(object? expected, object? actual, string? userMessage, string expectedExpression, string actualExpression) { - string finalMessage = actual != null && expected != null && !actual.GetType().Equals(expected.GetType()) - ? string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.AreEqualDifferentTypesFailMsg, - userMessage, - ReplaceNulls(expected), - expected.GetType().FullName, - ReplaceNulls(actual), - actual.GetType().FullName) - : expected is string expectedString && actual is string actualString - ? FormatStringComparisonMessage(expectedString, actualString, userMessage) - : string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.AreEqualFailMsg, - userMessage, - ReplaceNulls(expected), - ReplaceNulls(actual)); - ThrowAssertFailed("Assert.AreEqual", finalMessage); + string callSite = FormatCallSite("Assert.AreEqual", (nameof(expected), expectedExpression), (nameof(actual), actualExpression)); + string message = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; + + if (actual is not null && expected is not null && !actual.GetType().Equals(expected.GetType())) + { + message += Environment.NewLine + FrameworkMessages.AreEqualFailNew; + message += FormatAlignedParameters( + (nameof(expected), $"{FormatValue(expected)} ({expected.GetType().FullName})"), + (nameof(actual), $"{FormatValue(actual)} ({actual.GetType().FullName})")); + } + else if (expected is string expectedString && actual is string actualString) + { + message = FormatStringComparisonMessage(expectedString, actualString, message); + ThrowAssertFailed(callSite, message); + return; + } + else + { + message += Environment.NewLine + FrameworkMessages.AreEqualFailNew; + message += FormatAlignedParameters( + (nameof(expected), FormatValue(expected)), + (nameof(actual), FormatValue(actual))); + } + + ThrowAssertFailed(callSite, message); } [DoesNotReturn] - private static void ThrowAssertAreEqualFailed(T expected, T actual, T delta, string userMessage) + private static void ThrowAssertAreEqualFailed(T expected, T actual, T delta, string? userMessage, string expectedExpression, string actualExpression) where T : struct, IConvertible { - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.AreEqualDeltaFailMsg, - userMessage, - expected.ToString(CultureInfo.CurrentCulture.NumberFormat), - actual.ToString(CultureInfo.CurrentCulture.NumberFormat), - delta.ToString(CultureInfo.CurrentCulture.NumberFormat)); - ThrowAssertFailed("Assert.AreEqual", finalMessage); + string callSite = FormatCallSite("Assert.AreEqual", (nameof(expected), expectedExpression), (nameof(actual), actualExpression)); + string message = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; + message += Environment.NewLine + string.Format(CultureInfo.CurrentCulture, FrameworkMessages.AreEqualDeltaNoGreaterThanFailMsg, delta.ToString(CultureInfo.CurrentCulture.NumberFormat)); + message += FormatAlignedParameters( + (nameof(expected), FormatValue(expected)), + (nameof(actual), FormatValue(actual))); + ThrowAssertFailed(callSite, message); } [DoesNotReturn] - private static void ThrowAssertAreEqualFailed(string? expected, string? actual, bool ignoreCase, CultureInfo culture, string userMessage) + private static void ThrowAssertAreEqualFailed(string? expected, string? actual, bool ignoreCase, CultureInfo culture, string? userMessage, string expectedExpression, string actualExpression) { - string finalMessage; + string callSite = FormatCallSite("Assert.AreEqual", (nameof(expected), expectedExpression), (nameof(actual), actualExpression)); + string message = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; // If the user requested to match case, and the difference between expected/actual is casing only, then we use a different message. if (!ignoreCase && CompareInternal(expected, actual, ignoreCase: true, culture) == 0) { - finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.AreEqualCaseFailMsg, - userMessage, - ReplaceNulls(expected), - ReplaceNulls(actual)); + message += Environment.NewLine + FrameworkMessages.AreEqualCaseDiffersMsg; + message += FormatAlignedParameters( + (nameof(expected), FormatValue(expected)), + (nameof(actual), FormatValue(actual))); } else { // Use enhanced string comparison for string-specific failures - finalMessage = FormatStringComparisonMessage(expected, actual, userMessage); + message = FormatStringComparisonMessage(expected, actual, message); } - ThrowAssertFailed("Assert.AreEqual", finalMessage); + ThrowAssertFailed(callSite, message); } /// @@ -791,8 +756,7 @@ public static void AreNotEqual(T? notExpected, T? actual, IEqualityComparer @@ -837,8 +801,7 @@ public static void AreEqual(float expected, float actual, float delta, string? m { if (AreEqualFailing(expected, actual, delta)) { - string userMessage = BuildUserMessageForExpectedExpressionAndActualExpression(message, expectedExpression, actualExpression); - ThrowAssertAreEqualFailed(expected, actual, delta, userMessage); + ThrowAssertAreEqualFailed(expected, actual, delta, message, expectedExpression, actualExpression); } } @@ -884,8 +847,7 @@ public static void AreNotEqual(float notExpected, float actual, float delta, str { if (AreNotEqualFailing(notExpected, actual, delta)) { - string userMessage = BuildUserMessageForNotExpectedExpressionAndActualExpression(message, notExpectedExpression, actualExpression); - ThrowAssertAreNotEqualFailed(notExpected, actual, delta, userMessage); + ThrowAssertAreNotEqualFailed(notExpected, actual, delta, message, notExpectedExpression, actualExpression); } } @@ -952,8 +914,7 @@ public static void AreEqual(decimal expected, decimal actual, decimal delta, str { if (AreEqualFailing(expected, actual, delta)) { - string userMessage = BuildUserMessageForExpectedExpressionAndActualExpression(message, expectedExpression, actualExpression); - ThrowAssertAreEqualFailed(expected, actual, delta, userMessage); + ThrowAssertAreEqualFailed(expected, actual, delta, message, expectedExpression, actualExpression); } } @@ -999,8 +960,7 @@ public static void AreNotEqual(decimal notExpected, decimal actual, decimal delt { if (AreNotEqualFailing(notExpected, actual, delta)) { - string userMessage = BuildUserMessageForNotExpectedExpressionAndActualExpression(message, notExpectedExpression, actualExpression); - ThrowAssertAreNotEqualFailed(notExpected, actual, delta, userMessage); + ThrowAssertAreNotEqualFailed(notExpected, actual, delta, message, notExpectedExpression, actualExpression); } } @@ -1049,8 +1009,7 @@ public static void AreEqual(long expected, long actual, long delta, string? mess { if (AreEqualFailing(expected, actual, delta)) { - string userMessage = BuildUserMessageForExpectedExpressionAndActualExpression(message, expectedExpression, actualExpression); - ThrowAssertAreEqualFailed(expected, actual, delta, userMessage); + ThrowAssertAreEqualFailed(expected, actual, delta, message, expectedExpression, actualExpression); } } @@ -1096,8 +1055,7 @@ public static void AreNotEqual(long notExpected, long actual, long delta, string { if (AreNotEqualFailing(notExpected, actual, delta)) { - string userMessage = BuildUserMessageForNotExpectedExpressionAndActualExpression(message, notExpectedExpression, actualExpression); - ThrowAssertAreNotEqualFailed(notExpected, actual, delta, userMessage); + ThrowAssertAreNotEqualFailed(notExpected, actual, delta, message, notExpectedExpression, actualExpression); } } @@ -1145,8 +1103,7 @@ public static void AreEqual(double expected, double actual, double delta, string { if (AreEqualFailing(expected, actual, delta)) { - string userMessage = BuildUserMessageForExpectedExpressionAndActualExpression(message, expectedExpression, actualExpression); - ThrowAssertAreEqualFailed(expected, actual, delta, userMessage); + ThrowAssertAreEqualFailed(expected, actual, delta, message, expectedExpression, actualExpression); } } @@ -1192,8 +1149,7 @@ public static void AreNotEqual(double notExpected, double actual, double delta, { if (AreNotEqualFailing(notExpected, actual, delta)) { - string userMessage = BuildUserMessageForNotExpectedExpressionAndActualExpression(message, notExpectedExpression, actualExpression); - ThrowAssertAreNotEqualFailed(notExpected, actual, delta, userMessage); + ThrowAssertAreNotEqualFailed(notExpected, actual, delta, message, notExpectedExpression, actualExpression); } } @@ -1219,17 +1175,16 @@ private static bool AreNotEqualFailing(double notExpected, double actual, double } [DoesNotReturn] - private static void ThrowAssertAreNotEqualFailed(T notExpected, T actual, T delta, string userMessage) + private static void ThrowAssertAreNotEqualFailed(T notExpected, T actual, T delta, string? userMessage, string notExpectedExpression, string actualExpression) where T : struct, IConvertible { - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.AreNotEqualDeltaFailMsg, - userMessage, - notExpected.ToString(CultureInfo.CurrentCulture.NumberFormat), - actual.ToString(CultureInfo.CurrentCulture.NumberFormat), - delta.ToString(CultureInfo.CurrentCulture.NumberFormat)); - ThrowAssertFailed("Assert.AreNotEqual", finalMessage); + string callSite = FormatCallSite("Assert.AreNotEqual", (nameof(notExpected), notExpectedExpression), (nameof(actual), actualExpression)); + string message = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; + message += Environment.NewLine + string.Format(CultureInfo.CurrentCulture, FrameworkMessages.AreNotEqualDeltaGreaterThanFailMsg, delta.ToString(CultureInfo.CurrentCulture.NumberFormat)); + message += FormatAlignedParameters( + (nameof(notExpected), FormatValue(notExpected)), + (nameof(actual), FormatValue(actual))); + ThrowAssertFailed(callSite, message); } /// @@ -1322,8 +1277,7 @@ public static void AreEqual(string? expected, string? actual, bool ignoreCase, C return; } - string userMessage = BuildUserMessageForExpectedExpressionAndActualExpression(message, expectedExpression, actualExpression); - ThrowAssertAreEqualFailed(expected, actual, ignoreCase, culture, userMessage); + ThrowAssertAreEqualFailed(expected, actual, ignoreCase, culture, message, expectedExpression, actualExpression); } /// @@ -1418,8 +1372,7 @@ public static void AreNotEqual(string? notExpected, string? actual, bool ignoreC return; } - string userMessage = BuildUserMessageForNotExpectedExpressionAndActualExpression(message, notExpectedExpression, actualExpression); - ThrowAssertAreNotEqualFailed(notExpected, actual, userMessage); + ThrowAssertAreNotEqualFailed(notExpected, actual, message, notExpectedExpression, actualExpression); } private static bool AreNotEqualFailing(string? notExpected, string? actual, bool ignoreCase, CultureInfo culture) @@ -1429,15 +1382,15 @@ private static bool AreNotEqualFailing(T? notExpected, T? actual, IEqualityCo => (comparer ?? EqualityComparer.Default).Equals(notExpected!, actual!); [DoesNotReturn] - private static void ThrowAssertAreNotEqualFailed(object? notExpected, object? actual, string userMessage) + private static void ThrowAssertAreNotEqualFailed(object? notExpected, object? actual, string? userMessage, string notExpectedExpression, string actualExpression) { - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.AreNotEqualFailMsg, - userMessage, - ReplaceNulls(notExpected), - ReplaceNulls(actual)); - ThrowAssertFailed("Assert.AreNotEqual", finalMessage); + string callSite = FormatCallSite("Assert.AreNotEqual", (nameof(notExpected), notExpectedExpression), (nameof(actual), actualExpression)); + string message = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; + message += Environment.NewLine + FrameworkMessages.AreNotEqualFailNew; + message += FormatAlignedParameters( + (nameof(notExpected), FormatValue(notExpected)), + (nameof(actual), FormatValue(actual))); + ThrowAssertFailed(callSite, message); } } diff --git a/src/TestFramework/TestFramework/Assertions/Assert.AreSame.cs b/src/TestFramework/TestFramework/Assertions/Assert.AreSame.cs index 93be91c7fd..b85e4b1dbf 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.AreSame.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.AreSame.cs @@ -38,8 +38,7 @@ internal void ComputeAssertion(string expectedExpression, string actualExpressio { if (_builder is not null) { - _builder.Insert(0, string.Format(CultureInfo.CurrentCulture, FrameworkMessages.CallerArgumentExpressionTwoParametersMessage, "expected", expectedExpression, "actual", actualExpression) + " "); - ThrowAssertAreSameFailed(_expected, _actual, _builder.ToString()); + ThrowAssertAreSameFailed(_expected, _actual, _builder.ToString(), expectedExpression, actualExpression); } } @@ -80,9 +79,13 @@ internal void ComputeAssertion(string expectedExpression, string actualExpressio public readonly struct AssertAreNotSameInterpolatedStringHandler { private readonly StringBuilder? _builder; + private readonly TArgument? _notExpected; + private readonly TArgument? _actual; public AssertAreNotSameInterpolatedStringHandler(int literalLength, int formattedCount, TArgument? notExpected, TArgument? actual, out bool shouldAppend) { + _notExpected = notExpected; + _actual = actual; shouldAppend = IsAreNotSameFailing(notExpected, actual); if (shouldAppend) { @@ -94,8 +97,7 @@ internal void ComputeAssertion(string notExpectedExpression, string actualExpres { if (_builder is not null) { - _builder.Insert(0, string.Format(CultureInfo.CurrentCulture, FrameworkMessages.CallerArgumentExpressionTwoParametersMessage, "notExpected", notExpectedExpression, "actual", actualExpression) + " "); - ThrowAssertAreNotSameFailed(_builder.ToString()); + ThrowAssertAreNotSameFailed(_notExpected, _actual, _builder.ToString(), notExpectedExpression, actualExpression); } } @@ -177,26 +179,45 @@ public static void AreSame(T? expected, T? actual, string? message = "", [Cal return; } - string userMessage = BuildUserMessageForExpectedExpressionAndActualExpression(message, expectedExpression, actualExpression); - ThrowAssertAreSameFailed(expected, actual, userMessage); + ThrowAssertAreSameFailed(expected, actual, message, expectedExpression, actualExpression); } private static bool IsAreSameFailing(T? expected, T? actual) => !object.ReferenceEquals(expected, actual); [DoesNotReturn] - private static void ThrowAssertAreSameFailed(T? expected, T? actual, string userMessage) + private static void ThrowAssertAreSameFailed(T? expected, T? actual, string? userMessage, string expectedExpression, string actualExpression) { - string finalMessage = userMessage; + string callSite = FormatCallSite("Assert.AreSame", (nameof(expected), expectedExpression), (nameof(actual), actualExpression)); + string message = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; + + // When both values have the same string representation, include hash codes + // to help the user understand they are different object instances. + string expectedFormatted = FormatValue(expected); + string actualFormatted = FormatValue(actual); + bool sameToString = expected is not null && actual is not null && expectedFormatted == actualFormatted; + string expectedValue = sameToString + ? expectedFormatted + $" (Hash={RuntimeHelpers.GetHashCode(expected!)})" + : expectedFormatted; + string actualValue = sameToString + ? actualFormatted + $" (Hash={RuntimeHelpers.GetHashCode(actual!)})" + : actualFormatted; + + // If value types, add diagnostic hint before parameter details if (expected is ValueType && actual is ValueType) { - finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.AreSameGivenValues, - userMessage); + message += Environment.NewLine + string.Format(CultureInfo.CurrentCulture, FrameworkMessages.AreSameGivenValues, string.Empty).TrimEnd(); + } + else + { + message += Environment.NewLine + FrameworkMessages.AreSameFailNew; } - ThrowAssertFailed("Assert.AreSame", finalMessage); + message += FormatAlignedParameters( + (nameof(expected), expectedValue), + (nameof(actual), actualValue)); + + ThrowAssertFailed(callSite, message); } /// @@ -240,7 +261,7 @@ public static void AreNotSame(T? notExpected, T? actual, string? message = "" { if (IsAreNotSameFailing(notExpected, actual)) { - ThrowAssertAreNotSameFailed(BuildUserMessageForNotExpectedExpressionAndActualExpression(message, notExpectedExpression, actualExpression)); + ThrowAssertAreNotSameFailed(notExpected, actual, message, notExpectedExpression, actualExpression); } } @@ -248,6 +269,14 @@ private static bool IsAreNotSameFailing(T? notExpected, T? actual) => object.ReferenceEquals(notExpected, actual); [DoesNotReturn] - private static void ThrowAssertAreNotSameFailed(string userMessage) - => ThrowAssertFailed("Assert.AreNotSame", userMessage); + private static void ThrowAssertAreNotSameFailed(T? notExpected, T? actual, string? userMessage, string notExpectedExpression, string actualExpression) + { + string callSite = FormatCallSite("Assert.AreNotSame", (nameof(notExpected), notExpectedExpression), (nameof(actual), actualExpression)); + string message = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; + message += Environment.NewLine + FrameworkMessages.AreNotSameFailNew; + message += FormatAlignedParameters( + (nameof(notExpected), FormatValue(notExpected)), + (nameof(actual), FormatValue(actual))); + ThrowAssertFailed(callSite, message); + } } diff --git a/src/TestFramework/TestFramework/Assertions/Assert.Contains.cs b/src/TestFramework/TestFramework/Assertions/Assert.Contains.cs index 819452d1f4..a1debff78a 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.Contains.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.Contains.cs @@ -39,8 +39,7 @@ internal TItem ComputeAssertion(string collectionExpression) { if (_builder is not null) { - _builder.Insert(0, string.Format(CultureInfo.CurrentCulture, FrameworkMessages.CallerArgumentExpressionSingleParameterMessage, "collection", collectionExpression) + " "); - ThrowAssertContainsSingleFailed(_actualCount, _builder.ToString()); + ThrowAssertContainsSingleFailed(_actualCount, _builder.ToString(), collectionExpression); } return _item!; @@ -164,13 +163,11 @@ public static T ContainsSingle(Func predicate, IEnumerable collec if (string.IsNullOrEmpty(predicateExpression)) { - string userMessage = BuildUserMessageForCollectionExpression(message, collectionExpression); - ThrowAssertContainsSingleFailed(actualCount, userMessage); + ThrowAssertContainsSingleFailed(actualCount, message, collectionExpression); } else { - string userMessage = BuildUserMessageForPredicateExpressionAndCollectionExpression(message, predicateExpression, collectionExpression); - ThrowAssertSingleMatchFailed(actualCount, userMessage); + ThrowAssertSingleMatchFailed(actualCount, message, predicateExpression, collectionExpression); } // Unreachable code but compiler cannot work it out @@ -225,13 +222,11 @@ public static T ContainsSingle(Func predicate, IEnumerable collec if (string.IsNullOrEmpty(predicateExpression)) { - string userMessage = BuildUserMessageForCollectionExpression(message, collectionExpression); - ThrowAssertContainsSingleFailed(matchCount, userMessage); + ThrowAssertContainsSingleFailed(matchCount, message, collectionExpression); } else { - string userMessage = BuildUserMessageForPredicateExpressionAndCollectionExpression(message, predicateExpression, collectionExpression); - ThrowAssertSingleMatchFailed(matchCount, userMessage); + ThrowAssertSingleMatchFailed(matchCount, message, predicateExpression, collectionExpression); } return default; @@ -260,8 +255,7 @@ public static void Contains(T expected, IEnumerable collection, string? me { if (!collection.Contains(expected)) { - string userMessage = BuildUserMessageForExpectedExpressionAndCollectionExpression(message, expectedExpression, collectionExpression); - ThrowAssertContainsItemFailed(userMessage); + ThrowAssertContainsItemFailed(message, expectedExpression, collectionExpression, collection); } } @@ -291,8 +285,7 @@ public static void Contains(object? expected, IEnumerable collection, string? me } } - string userMessage = BuildUserMessageForExpectedExpressionAndCollectionExpression(message, expectedExpression, collectionExpression); - ThrowAssertContainsItemFailed(userMessage); + ThrowAssertContainsItemFailed(message, expectedExpression, collectionExpression, collection); } /// @@ -315,8 +308,7 @@ public static void Contains(T expected, IEnumerable collection, IEqualityC { if (!collection.Contains(expected, comparer)) { - string userMessage = BuildUserMessageForExpectedExpressionAndCollectionExpression(message, expectedExpression, collectionExpression); - ThrowAssertContainsItemFailed(userMessage); + ThrowAssertContainsItemFailed(message, expectedExpression, collectionExpression, collection); } } @@ -348,8 +340,7 @@ public static void Contains(object? expected, IEnumerable collection, IEqualityC } } - string userMessage = BuildUserMessageForExpectedExpressionAndCollectionExpression(message, expectedExpression, collectionExpression); - ThrowAssertContainsItemFailed(userMessage); + ThrowAssertContainsItemFailed(message, expectedExpression, collectionExpression, collection); } /// @@ -371,8 +362,7 @@ public static void Contains(Func predicate, IEnumerable collectio { if (!collection.Any(predicate)) { - string userMessage = BuildUserMessageForPredicateExpressionAndCollectionExpression(message, predicateExpression, collectionExpression); - ThrowAssertContainsPredicateFailed(userMessage); + ThrowAssertContainsPredicateFailed(message, predicateExpression, collectionExpression, collection); } } @@ -403,8 +393,7 @@ public static void Contains(Func predicate, IEnumerable collectio } } - string userMessage = BuildUserMessageForPredicateExpressionAndCollectionExpression(message, predicateExpression, collectionExpression); - ThrowAssertContainsPredicateFailed(userMessage); + ThrowAssertContainsPredicateFailed(message, predicateExpression, collectionExpression, collection); } /// @@ -476,9 +465,7 @@ public static void Contains(string substring, string value, StringComparison com if (!value.Contains(substring, comparisonType)) { - string userMessage = BuildUserMessageForSubstringExpressionAndValueExpression(message, substringExpression, valueExpression); - string finalMessage = string.Format(CultureInfo.CurrentCulture, FrameworkMessages.ContainsFail, value, substring, userMessage); - ThrowAssertFailed("Assert.Contains", finalMessage); + ThrowAssertStringContainsFailed(value, substring, message, substringExpression, valueExpression); } } @@ -505,8 +492,7 @@ public static void DoesNotContain(T notExpected, IEnumerable collection, s { if (collection.Contains(notExpected)) { - string userMessage = BuildUserMessageForNotExpectedExpressionAndCollectionExpression(message, notExpectedExpression, collectionExpression); - ThrowAssertDoesNotContainItemFailed(userMessage); + ThrowAssertDoesNotContainItemFailed(message, notExpectedExpression, collectionExpression, collection); } } @@ -532,8 +518,7 @@ public static void DoesNotContain(object? notExpected, IEnumerable collection, s { if (object.Equals(notExpected, item)) { - string userMessage = BuildUserMessageForNotExpectedExpressionAndCollectionExpression(message, notExpectedExpression, collectionExpression); - ThrowAssertDoesNotContainItemFailed(userMessage); + ThrowAssertDoesNotContainItemFailed(message, notExpectedExpression, collectionExpression, collection); } } } @@ -558,8 +543,7 @@ public static void DoesNotContain(T notExpected, IEnumerable collection, I { if (collection.Contains(notExpected, comparer)) { - string userMessage = BuildUserMessageForNotExpectedExpressionAndCollectionExpression(message, notExpectedExpression, collectionExpression); - ThrowAssertDoesNotContainItemFailed(userMessage); + ThrowAssertDoesNotContainItemFailed(message, notExpectedExpression, collectionExpression, collection); } } @@ -587,8 +571,7 @@ public static void DoesNotContain(object? notExpected, IEnumerable collection, I { if (comparer.Equals(item, notExpected)) { - string userMessage = BuildUserMessageForNotExpectedExpressionAndCollectionExpression(message, notExpectedExpression, collectionExpression); - ThrowAssertDoesNotContainItemFailed(userMessage); + ThrowAssertDoesNotContainItemFailed(message, notExpectedExpression, collectionExpression, collection); } } } @@ -612,8 +595,7 @@ public static void DoesNotContain(Func predicate, IEnumerable col { if (collection.Any(predicate)) { - string userMessage = BuildUserMessageForPredicateExpressionAndCollectionExpression(message, predicateExpression, collectionExpression); - ThrowAssertDoesNotContainPredicateFailed(userMessage); + ThrowAssertDoesNotContainPredicateFailed(message, predicateExpression, collectionExpression, collection); } } @@ -640,8 +622,7 @@ public static void DoesNotContain(Func predicate, IEnumerable col { if (predicate(item)) { - string userMessage = BuildUserMessageForPredicateExpressionAndCollectionExpression(message, predicateExpression, collectionExpression); - ThrowAssertDoesNotContainPredicateFailed(userMessage); + ThrowAssertDoesNotContainPredicateFailed(message, predicateExpression, collectionExpression, collection); } } } @@ -715,9 +696,7 @@ public static void DoesNotContain(string substring, string value, StringComparis if (value.Contains(substring, comparisonType)) { - string userMessage = BuildUserMessageForSubstringExpressionAndValueExpression(message, substringExpression, valueExpression); - string finalMessage = string.Format(CultureInfo.CurrentCulture, FrameworkMessages.DoesNotContainFail, value, substring, userMessage); - ThrowAssertFailed("Assert.DoesNotContain", finalMessage); + ThrowAssertStringDoesNotContainFailed(value, substring, message, substringExpression, valueExpression); } } @@ -756,73 +735,120 @@ public static void IsInRange(T minValue, T maxValue, T value, string? message if (value.CompareTo(minValue) < 0 || value.CompareTo(maxValue) > 0) { - string userMessage = BuildUserMessageForMinValueExpressionAndMaxValueExpressionAndValueExpression(message, minValueExpression, maxValueExpression, valueExpression); - string finalMessage = string.Format(CultureInfo.CurrentCulture, FrameworkMessages.IsInRangeFail, value, minValue, maxValue, userMessage); - ThrowAssertFailed("IsInRange", finalMessage); + ThrowAssertIsInRangeFailed(value, minValue, maxValue, message, minValueExpression, maxValueExpression, valueExpression); } } #endregion // IsInRange [DoesNotReturn] - private static void ThrowAssertSingleMatchFailed(int actualCount, string userMessage) + private static void ThrowAssertSingleMatchFailed(int actualCount, string? userMessage, string predicateExpression, string collectionExpression) { - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.ContainsSingleMatchFailMsg, - userMessage, - actualCount); - ThrowAssertFailed("Assert.ContainsSingle", finalMessage); + string callSite = FormatCallSite("Assert.ContainsSingle", ("predicate", predicateExpression), ("collection", collectionExpression)); + string message = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; + message += Environment.NewLine + string.Format(CultureInfo.CurrentCulture, FrameworkMessages.ContainsSingleMatchFailNew, actualCount); + ThrowAssertFailed(callSite, message); } [DoesNotReturn] - private static void ThrowAssertContainsSingleFailed(int actualCount, string userMessage) + private static void ThrowAssertContainsSingleFailed(int actualCount, string? userMessage, string collectionExpression) { - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.ContainsSingleFailMsg, - userMessage, - actualCount); - ThrowAssertFailed("Assert.ContainsSingle", finalMessage); + string callSite = FormatCallSite("Assert.ContainsSingle", ("collection", collectionExpression)); + string message = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; + message += Environment.NewLine + string.Format(CultureInfo.CurrentCulture, FrameworkMessages.ContainsSingleFailNew, actualCount); + ThrowAssertFailed(callSite, message); } [DoesNotReturn] - private static void ThrowAssertContainsItemFailed(string userMessage) + private static void ThrowAssertContainsItemFailed(string? userMessage, string expectedExpression, string collectionExpression, IEnumerable? collectionValue = null) { - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.ContainsItemFailMsg, - userMessage); - ThrowAssertFailed("Assert.Contains", finalMessage); + string callSite = FormatCallSite("Assert.Contains", ("expected", expectedExpression), ("collection", collectionExpression)); + string message = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; + message += Environment.NewLine + FrameworkMessages.ContainsItemFailNew; + if (collectionValue is not null) + { + message += FormatCollectionParameter(collectionExpression, collectionValue); + } + + ThrowAssertFailed(callSite, message); + } + + [DoesNotReturn] + private static void ThrowAssertContainsPredicateFailed(string? userMessage, string predicateExpression, string collectionExpression, IEnumerable? collectionValue = null) + { + string callSite = FormatCallSite("Assert.Contains", ("predicate", predicateExpression), ("collection", collectionExpression)); + string message = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; + message += Environment.NewLine + FrameworkMessages.ContainsPredicateFailNew; + if (collectionValue is not null) + { + message += FormatCollectionParameter(collectionExpression, collectionValue); + } + + ThrowAssertFailed(callSite, message); + } + + [DoesNotReturn] + private static void ThrowAssertDoesNotContainItemFailed(string? userMessage, string notExpectedExpression, string collectionExpression, IEnumerable? collectionValue = null) + { + string callSite = FormatCallSite("Assert.DoesNotContain", ("notExpected", notExpectedExpression), ("collection", collectionExpression)); + string message = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; + message += Environment.NewLine + FrameworkMessages.DoesNotContainItemFailNew; + if (collectionValue is not null) + { + message += FormatCollectionParameter(collectionExpression, collectionValue); + } + + ThrowAssertFailed(callSite, message); + } + + [DoesNotReturn] + private static void ThrowAssertDoesNotContainPredicateFailed(string? userMessage, string predicateExpression, string collectionExpression, IEnumerable? collectionValue = null) + { + string callSite = FormatCallSite("Assert.DoesNotContain", ("predicate", predicateExpression), ("collection", collectionExpression)); + string message = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; + message += Environment.NewLine + FrameworkMessages.DoesNotContainPredicateFailNew; + if (collectionValue is not null) + { + message += FormatCollectionParameter(collectionExpression, collectionValue); + } + + ThrowAssertFailed(callSite, message); } [DoesNotReturn] - private static void ThrowAssertContainsPredicateFailed(string userMessage) + private static void ThrowAssertStringContainsFailed(string value, string substring, string? userMessage, string substringExpression, string valueExpression) { - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.ContainsPredicateFailMsg, - userMessage); - ThrowAssertFailed("Assert.Contains", finalMessage); + string callSite = FormatCallSite("Assert.Contains", (nameof(substring), substringExpression), (nameof(value), valueExpression)); + string message = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; + message += Environment.NewLine + FrameworkMessages.ContainsStringFailNew; + message += FormatAlignedParameters( + (nameof(substring), FormatValue(substring)), + (nameof(value), FormatValue(value))); + ThrowAssertFailed(callSite, message); } [DoesNotReturn] - private static void ThrowAssertDoesNotContainItemFailed(string userMessage) + private static void ThrowAssertStringDoesNotContainFailed(string value, string substring, string? userMessage, string substringExpression, string valueExpression) { - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.DoesNotContainItemFailMsg, - userMessage); - ThrowAssertFailed("Assert.DoesNotContain", finalMessage); + string callSite = FormatCallSite("Assert.DoesNotContain", (nameof(substring), substringExpression), (nameof(value), valueExpression)); + string message = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; + message += Environment.NewLine + FrameworkMessages.DoesNotContainStringFailNew; + message += FormatAlignedParameters( + (nameof(substring), FormatValue(substring)), + (nameof(value), FormatValue(value))); + ThrowAssertFailed(callSite, message); } [DoesNotReturn] - private static void ThrowAssertDoesNotContainPredicateFailed(string userMessage) + private static void ThrowAssertIsInRangeFailed(T value, T minValue, T maxValue, string? userMessage, string minValueExpression, string maxValueExpression, string valueExpression) { - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.DoesNotContainPredicateFailMsg, - userMessage); - ThrowAssertFailed("Assert.DoesNotContain", finalMessage); + string callSite = FormatCallSite("Assert.IsInRange", (nameof(value), valueExpression)); + string message = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; + message += Environment.NewLine + FrameworkMessages.IsInRangeFailNew; + message += FormatAlignedParameters( + (nameof(minValue), FormatValue(minValue)), + (nameof(maxValue), FormatValue(maxValue)), + (nameof(value), FormatValue(value))); + ThrowAssertFailed(callSite, message); } } diff --git a/src/TestFramework/TestFramework/Assertions/Assert.Count.cs b/src/TestFramework/TestFramework/Assertions/Assert.Count.cs index 555d341686..04b1cd5c32 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.Count.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.Count.cs @@ -20,6 +20,7 @@ public readonly struct AssertCountInterpolatedStringHandler private readonly StringBuilder? _builder; private readonly int _expectedCount; private readonly int _actualCount; + private readonly IEnumerable? _collection; public AssertCountInterpolatedStringHandler(int literalLength, int formattedCount, int count, IEnumerable collection, out bool shouldAppend) { @@ -29,6 +30,7 @@ public AssertCountInterpolatedStringHandler(int literalLength, int formattedCoun if (shouldAppend) { _builder = new StringBuilder(literalLength + formattedCount); + _collection = collection; } } @@ -40,6 +42,7 @@ public AssertCountInterpolatedStringHandler(int literalLength, int formattedCoun if (shouldAppend) { _builder = new StringBuilder(literalLength + formattedCount); + _collection = collection; } } @@ -47,8 +50,7 @@ internal void ComputeAssertion(string assertionName, string collectionExpression { if (_builder is not null) { - _builder.Insert(0, string.Format(CultureInfo.CurrentCulture, FrameworkMessages.CallerArgumentExpressionSingleParameterMessage, "collection", collectionExpression) + " "); - ThrowAssertCountFailed(assertionName, _expectedCount, _actualCount, _builder.ToString()); + ThrowAssertCountFailed(assertionName, _expectedCount, _actualCount, _collection!, _builder.ToString(), collectionExpression); } } @@ -115,8 +117,7 @@ internal void ComputeAssertion(string collectionExpression) { if (_builder is not null) { - _builder.Insert(0, string.Format(CultureInfo.CurrentCulture, FrameworkMessages.CallerArgumentExpressionSingleParameterMessage, "collection", collectionExpression) + " "); - ThrowAssertIsNotEmptyFailed(_builder.ToString()); + ThrowAssertIsNotEmptyFailed(_builder.ToString(), collectionExpression); } } @@ -202,8 +203,7 @@ public static void IsNotEmpty(IEnumerable collection, string? message = "" return; } - string userMessage = BuildUserMessageForCollectionExpression(message, collectionExpression); - ThrowAssertIsNotEmptyFailed(userMessage); + ThrowAssertIsNotEmptyFailed(message, collectionExpression); } /// @@ -222,8 +222,7 @@ public static void IsNotEmpty(IEnumerable collection, string? message = "", [Cal return; } - string userMessage = BuildUserMessageForCollectionExpression(message, collectionExpression); - ThrowAssertIsNotEmptyFailed(userMessage); + ThrowAssertIsNotEmptyFailed(message, collectionExpression); } #endregion // IsNotEmpty @@ -326,32 +325,30 @@ private static void HasCount(string assertionName, int expected, IEnumerable< return; } - string userMessage = BuildUserMessageForCollectionExpression(message, collectionExpression); - ThrowAssertCountFailed(assertionName, expected, actualCount, userMessage); + ThrowAssertCountFailed(assertionName, expected, actualCount, collection, message, collectionExpression); } private static void HasCount(string assertionName, int expected, IEnumerable collection, string? message, string collectionExpression) => HasCount(assertionName, expected, collection.Cast(), message, collectionExpression); [DoesNotReturn] - private static void ThrowAssertCountFailed(string assertionName, int expectedCount, int actualCount, string userMessage) + private static void ThrowAssertCountFailed(string assertionName, int expectedCount, int actualCount, IEnumerable collection, string? userMessage, string collectionExpression) { - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.HasCountFailMsg, - userMessage, - expectedCount, - actualCount); - ThrowAssertFailed($"Assert.{assertionName}", finalMessage); + string callSite = FormatCallSite($"Assert.{assertionName}", ("collection", collectionExpression)); + string msg = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; + msg += Environment.NewLine + FrameworkMessages.HasCountFailNew; + msg += FormatCollectionParameter(collectionExpression, collection); + msg += $"{Environment.NewLine} expectedCount: {expectedCount}"; + msg += $"{Environment.NewLine} actualCount: {actualCount}"; + ThrowAssertFailed(callSite, msg); } [DoesNotReturn] - private static void ThrowAssertIsNotEmptyFailed(string userMessage) + private static void ThrowAssertIsNotEmptyFailed(string? userMessage, string collectionExpression) { - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.IsNotEmptyFailMsg, - userMessage); - ThrowAssertFailed("Assert.IsNotEmpty", finalMessage); + string callSite = FormatCallSite("Assert.IsNotEmpty", ("collection", collectionExpression)); + string msg = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; + msg += Environment.NewLine + FrameworkMessages.IsNotEmptyFailNew; + ThrowAssertFailed(callSite, msg); } } diff --git a/src/TestFramework/TestFramework/Assertions/Assert.EndsWith.cs b/src/TestFramework/TestFramework/Assertions/Assert.EndsWith.cs index 772c1d1e48..1b1bc6ef7f 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.EndsWith.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.EndsWith.cs @@ -76,9 +76,13 @@ public static void EndsWith([NotNull] string? expectedSuffix, [NotNull] string? CheckParameterNotNull(expectedSuffix, "Assert.EndsWith", "expectedSuffix"); if (!value.EndsWith(expectedSuffix, comparisonType)) { - string userMessage = BuildUserMessageForExpectedSuffixExpressionAndValueExpression(message, expectedSuffixExpression, valueExpression); - string finalMessage = string.Format(CultureInfo.CurrentCulture, FrameworkMessages.EndsWithFail, value, expectedSuffix, userMessage); - ThrowAssertFailed("Assert.EndsWith", finalMessage); + string callSite = FormatCallSite("Assert.EndsWith", (nameof(expectedSuffix), expectedSuffixExpression), (nameof(value), valueExpression)); + string msg = string.IsNullOrEmpty(message) ? string.Empty : message!; + msg += Environment.NewLine + FrameworkMessages.EndsWithFailNew; + msg += FormatAlignedParameters( + (nameof(expectedSuffix), FormatValue(expectedSuffix)), + (nameof(value), FormatValue(value))); + ThrowAssertFailed(callSite, msg); } } @@ -150,9 +154,13 @@ public static void DoesNotEndWith([NotNull] string? notExpectedSuffix, [NotNull] CheckParameterNotNull(notExpectedSuffix, "Assert.DoesNotEndWith", "notExpectedSuffix"); if (value.EndsWith(notExpectedSuffix, comparisonType)) { - string userMessage = BuildUserMessageForNotExpectedSuffixExpressionAndValueExpression(message, notExpectedSuffixExpression, valueExpression); - string finalMessage = string.Format(CultureInfo.CurrentCulture, FrameworkMessages.DoesNotEndWithFail, value, notExpectedSuffix, userMessage); - ThrowAssertFailed("Assert.DoesNotEndWith", finalMessage); + string callSite = FormatCallSite("Assert.DoesNotEndWith", (nameof(notExpectedSuffix), notExpectedSuffixExpression), (nameof(value), valueExpression)); + string msg = string.IsNullOrEmpty(message) ? string.Empty : message!; + msg += Environment.NewLine + FrameworkMessages.DoesNotEndWithFailNew; + msg += FormatAlignedParameters( + (nameof(notExpectedSuffix), FormatValue(notExpectedSuffix)), + (nameof(value), FormatValue(value))); + ThrowAssertFailed(callSite, msg); } } } diff --git a/src/TestFramework/TestFramework/Assertions/Assert.IComparable.cs b/src/TestFramework/TestFramework/Assertions/Assert.IComparable.cs index a953f5cd33..5767ee98a4 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.IComparable.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.IComparable.cs @@ -49,8 +49,7 @@ public static void IsGreaterThan(T lowerBound, T value, string? message = "", return; } - string userMessage = BuildUserMessageForLowerBoundExpressionAndValueExpression(message, lowerBoundExpression, valueExpression); - ThrowAssertIsGreaterThanFailed(lowerBound, value, userMessage); + ThrowAssertIsGreaterThanFailed(lowerBound, value, message, lowerBoundExpression, valueExpression); } #endregion // IsGreaterThan @@ -94,8 +93,7 @@ public static void IsGreaterThanOrEqualTo(T lowerBound, T value, string? mess return; } - string userMessage = BuildUserMessageForLowerBoundExpressionAndValueExpression(message, lowerBoundExpression, valueExpression); - ThrowAssertIsGreaterThanOrEqualToFailed(lowerBound, value, userMessage); + ThrowAssertIsGreaterThanOrEqualToFailed(lowerBound, value, message, lowerBoundExpression, valueExpression); } #endregion // IsGreaterThanOrEqualTo @@ -139,8 +137,7 @@ public static void IsLessThan(T upperBound, T value, string? message = "", [C return; } - string userMessage = BuildUserMessageForUpperBoundExpressionAndValueExpression(message, upperBoundExpression, valueExpression); - ThrowAssertIsLessThanFailed(upperBound, value, userMessage); + ThrowAssertIsLessThanFailed(upperBound, value, message, upperBoundExpression, valueExpression); } #endregion // IsLessThan @@ -184,8 +181,7 @@ public static void IsLessThanOrEqualTo(T upperBound, T value, string? message return; } - string userMessage = BuildUserMessageForUpperBoundExpressionAndValueExpression(message, upperBoundExpression, valueExpression); - ThrowAssertIsLessThanOrEqualToFailed(upperBound, value, userMessage); + ThrowAssertIsLessThanOrEqualToFailed(upperBound, value, message, upperBoundExpression, valueExpression); } #endregion // IsLessThanOrEqualTo @@ -221,15 +217,13 @@ public static void IsPositive(T value, string? message = "", [CallerArgumentE // Handle special case for floating point NaN values if (value is float.NaN) { - string userMessage = BuildUserMessageForValueExpression(message, valueExpression); - ThrowAssertIsPositiveFailed(value, userMessage); + ThrowAssertIsPositiveFailed(value, message, valueExpression); return; } if (value is double.NaN) { - string userMessage = BuildUserMessageForValueExpression(message, valueExpression); - ThrowAssertIsPositiveFailed(value, userMessage); + ThrowAssertIsPositiveFailed(value, message, valueExpression); return; } @@ -238,8 +232,7 @@ public static void IsPositive(T value, string? message = "", [CallerArgumentE return; } - string userMessage2 = BuildUserMessageForValueExpression(message, valueExpression); - ThrowAssertIsPositiveFailed(value, userMessage2); + ThrowAssertIsPositiveFailed(value, message, valueExpression); } #endregion // IsPositive @@ -275,15 +268,13 @@ public static void IsNegative(T value, string? message = "", [CallerArgumentE // Handle special case for floating point NaN values if (value is float.NaN) { - string userMessage = BuildUserMessageForValueExpression(message, valueExpression); - ThrowAssertIsNegativeFailed(value, userMessage); + ThrowAssertIsNegativeFailed(value, message, valueExpression); return; } if (value is double.NaN) { - string userMessage = BuildUserMessageForValueExpression(message, valueExpression); - ThrowAssertIsNegativeFailed(value, userMessage); + ThrowAssertIsNegativeFailed(value, message, valueExpression); return; } @@ -292,79 +283,76 @@ public static void IsNegative(T value, string? message = "", [CallerArgumentE return; } - string userMessage2 = BuildUserMessageForValueExpression(message, valueExpression); - ThrowAssertIsNegativeFailed(value, userMessage2); + ThrowAssertIsNegativeFailed(value, message, valueExpression); } #endregion // IsNegative [DoesNotReturn] - private static void ThrowAssertIsGreaterThanFailed(T lowerBound, T value, string userMessage) + private static void ThrowAssertIsGreaterThanFailed(T lowerBound, T value, string? userMessage, string lowerBoundExpression, string valueExpression) { - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.IsGreaterThanFailMsg, - userMessage, - ReplaceNulls(lowerBound), - ReplaceNulls(value)); - ThrowAssertFailed("Assert.IsGreaterThan", finalMessage); + string callSite = FormatCallSite("Assert.IsGreaterThan", (nameof(lowerBound), lowerBoundExpression), (nameof(value), valueExpression)); + string msg = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; + msg += Environment.NewLine + FrameworkMessages.IsGreaterThanFailNew; + msg += FormatAlignedParameters( + (nameof(lowerBound), FormatValue(lowerBound)), + (nameof(value), FormatValue(value))); + ThrowAssertFailed(callSite, msg); } [DoesNotReturn] - private static void ThrowAssertIsGreaterThanOrEqualToFailed(T lowerBound, T value, string userMessage) + private static void ThrowAssertIsGreaterThanOrEqualToFailed(T lowerBound, T value, string? userMessage, string lowerBoundExpression, string valueExpression) { - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.IsGreaterThanOrEqualToFailMsg, - userMessage, - ReplaceNulls(lowerBound), - ReplaceNulls(value)); - ThrowAssertFailed("Assert.IsGreaterThanOrEqualTo", finalMessage); + string callSite = FormatCallSite("Assert.IsGreaterThanOrEqualTo", (nameof(lowerBound), lowerBoundExpression), (nameof(value), valueExpression)); + string msg = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; + msg += Environment.NewLine + FrameworkMessages.IsGreaterThanOrEqualToFailNew; + msg += FormatAlignedParameters( + (nameof(lowerBound), FormatValue(lowerBound)), + (nameof(value), FormatValue(value))); + ThrowAssertFailed(callSite, msg); } [DoesNotReturn] - private static void ThrowAssertIsLessThanFailed(T upperBound, T value, string userMessage) + private static void ThrowAssertIsLessThanFailed(T upperBound, T value, string? userMessage, string upperBoundExpression, string valueExpression) { - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.IsLessThanFailMsg, - userMessage, - ReplaceNulls(upperBound), - ReplaceNulls(value)); - ThrowAssertFailed("Assert.IsLessThan", finalMessage); + string callSite = FormatCallSite("Assert.IsLessThan", (nameof(upperBound), upperBoundExpression), (nameof(value), valueExpression)); + string msg = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; + msg += Environment.NewLine + FrameworkMessages.IsLessThanFailNew; + msg += FormatAlignedParameters( + (nameof(upperBound), FormatValue(upperBound)), + (nameof(value), FormatValue(value))); + ThrowAssertFailed(callSite, msg); } [DoesNotReturn] - private static void ThrowAssertIsLessThanOrEqualToFailed(T upperBound, T value, string userMessage) + private static void ThrowAssertIsLessThanOrEqualToFailed(T upperBound, T value, string? userMessage, string upperBoundExpression, string valueExpression) { - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.IsLessThanOrEqualToFailMsg, - userMessage, - ReplaceNulls(upperBound), - ReplaceNulls(value)); - ThrowAssertFailed("Assert.IsLessThanOrEqualTo", finalMessage); + string callSite = FormatCallSite("Assert.IsLessThanOrEqualTo", (nameof(upperBound), upperBoundExpression), (nameof(value), valueExpression)); + string msg = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; + msg += Environment.NewLine + FrameworkMessages.IsLessThanOrEqualToFailNew; + msg += FormatAlignedParameters( + (nameof(upperBound), FormatValue(upperBound)), + (nameof(value), FormatValue(value))); + ThrowAssertFailed(callSite, msg); } [DoesNotReturn] - private static void ThrowAssertIsPositiveFailed(T value, string userMessage) + private static void ThrowAssertIsPositiveFailed(T value, string? userMessage, string valueExpression) { - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.IsPositiveFailMsg, - userMessage, - ReplaceNulls(value)); - ThrowAssertFailed("Assert.IsPositive", finalMessage); + string callSite = FormatCallSite("Assert.IsPositive", (nameof(value), valueExpression)); + string msg = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; + msg += Environment.NewLine + FrameworkMessages.IsPositiveFailNew; + msg += Environment.NewLine + FormatParameter(nameof(value), valueExpression, value); + ThrowAssertFailed(callSite, msg); } [DoesNotReturn] - private static void ThrowAssertIsNegativeFailed(T value, string userMessage) + private static void ThrowAssertIsNegativeFailed(T value, string? userMessage, string valueExpression) { - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.IsNegativeFailMsg, - userMessage, - ReplaceNulls(value)); - ThrowAssertFailed("Assert.IsNegative", finalMessage); + string callSite = FormatCallSite("Assert.IsNegative", (nameof(value), valueExpression)); + string msg = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; + msg += Environment.NewLine + FrameworkMessages.IsNegativeFailNew; + msg += Environment.NewLine + FormatParameter(nameof(value), valueExpression, value); + ThrowAssertFailed(callSite, msg); } } diff --git a/src/TestFramework/TestFramework/Assertions/Assert.IsExactInstanceOfType.cs b/src/TestFramework/TestFramework/Assertions/Assert.IsExactInstanceOfType.cs index 144f17cdbe..904d24f39b 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.IsExactInstanceOfType.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.IsExactInstanceOfType.cs @@ -38,8 +38,7 @@ internal void ComputeAssertion(string valueExpression) { if (_builder is not null) { - _builder.Insert(0, string.Format(CultureInfo.CurrentCulture, FrameworkMessages.CallerArgumentExpressionSingleParameterMessage, "value", valueExpression) + " "); - ThrowAssertIsExactInstanceOfTypeFailed(_value, _expectedType, _builder.ToString()); + ThrowAssertIsExactInstanceOfTypeFailed(_value, _expectedType, _builder.ToString(), valueExpression); } } @@ -50,16 +49,11 @@ internal void ComputeAssertion(string valueExpression) #if NETCOREAPP3_1_OR_GREATER public void AppendFormatted(ReadOnlySpan value) => _builder!.Append(value); -#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads +#pragma warning disable RS0027 public void AppendFormatted(ReadOnlySpan value, int alignment = 0, string? format = null) => AppendFormatted(value.ToString(), alignment, format); -#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads +#pragma warning restore RS0027 #endif - // NOTE: All the overloads involving format and/or alignment are not super efficient. - // This code path is only for when an assert is failing, so that's not the common scenario - // and should be okay if not very optimized. - // A more efficient implementation that can be used for .NET 6 and later is to delegate the work to - // the BCL's StringBuilder.AppendInterpolatedStringHandler public void AppendFormatted(T value, string? format) => _builder!.AppendFormat(null, $"{{0:{format}}}", value); public void AppendFormatted(T value, int alignment) => _builder!.AppendFormat(null, $"{{0,{alignment}}}", value); @@ -68,13 +62,13 @@ internal void ComputeAssertion(string valueExpression) public void AppendFormatted(string? value) => _builder!.Append(value); -#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters -#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads +#pragma warning disable RS0026 +#pragma warning disable RS0027 public void AppendFormatted(string? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); public void AppendFormatted(object? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); -#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters -#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads +#pragma warning restore RS0026 +#pragma warning restore RS0027 } [InterpolatedStringHandler] @@ -98,8 +92,7 @@ internal void ComputeAssertion(string valueExpression) { if (_builder is not null) { - _builder.Insert(0, string.Format(CultureInfo.CurrentCulture, FrameworkMessages.CallerArgumentExpressionSingleParameterMessage, "value", valueExpression) + " "); - ThrowAssertIsExactInstanceOfTypeFailed(_value, typeof(TArg), _builder.ToString()); + ThrowAssertIsExactInstanceOfTypeFailed(_value, typeof(TArg), _builder.ToString(), valueExpression); } } @@ -160,8 +153,7 @@ internal void ComputeAssertion(string valueExpression) { if (_builder is not null) { - _builder.Insert(0, string.Format(CultureInfo.CurrentCulture, FrameworkMessages.CallerArgumentExpressionSingleParameterMessage, "value", valueExpression) + " "); - ThrowAssertIsNotExactInstanceOfTypeFailed(_value, _wrongType, _builder.ToString()); + ThrowAssertIsNotExactInstanceOfTypeFailed(_value, _wrongType, _builder.ToString(), valueExpression); } } @@ -220,8 +212,7 @@ internal void ComputeAssertion(string valueExpression) { if (_builder is not null) { - _builder.Insert(0, string.Format(CultureInfo.CurrentCulture, FrameworkMessages.CallerArgumentExpressionSingleParameterMessage, "value", valueExpression) + " "); - ThrowAssertIsNotExactInstanceOfTypeFailed(_value, typeof(TArg), _builder.ToString()); + ThrowAssertIsNotExactInstanceOfTypeFailed(_value, typeof(TArg), _builder.ToString(), valueExpression); } } @@ -291,7 +282,7 @@ public static void IsExactInstanceOfType([NotNull] object? value, [NotNull] Type { if (IsExactInstanceOfTypeFailing(value, expectedType)) { - ThrowAssertIsExactInstanceOfTypeFailed(value, expectedType, BuildUserMessageForValueExpression(message, valueExpression)); + ThrowAssertIsExactInstanceOfTypeFailed(value, expectedType, message, valueExpression); } } @@ -329,20 +320,23 @@ private static bool IsExactInstanceOfTypeFailing([NotNullWhen(false)] object? va => expectedType is null || value is null || value.GetType() != expectedType; [DoesNotReturn] - private static void ThrowAssertIsExactInstanceOfTypeFailed(object? value, Type? expectedType, string userMessage) + private static void ThrowAssertIsExactInstanceOfTypeFailed(object? value, Type? expectedType, string? userMessage, string valueExpression) { - string finalMessage = userMessage; + string callSite = FormatCallSite("Assert.IsExactInstanceOfType", (nameof(value), valueExpression)); + string message = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; + if (expectedType is not null && value is not null) + { + message += Environment.NewLine + FrameworkMessages.IsExactInstanceOfTypeFailNew; + } + + message += Environment.NewLine + FormatParameter(nameof(value), valueExpression, value); if (expectedType is not null && value is not null) { - finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.IsExactInstanceOfFailMsg, - userMessage, - expectedType.ToString(), - value.GetType().ToString()); + message += Environment.NewLine + $" expectedType: {expectedType}" + + Environment.NewLine + $" actualType: {value.GetType()}"; } - ThrowAssertFailed("Assert.IsExactInstanceOfType", finalMessage); + ThrowAssertFailed(callSite, message); } /// @@ -373,7 +367,7 @@ public static void IsNotExactInstanceOfType(object? value, [NotNull] Type? wrong { if (IsNotExactInstanceOfTypeFailing(value, wrongType)) { - ThrowAssertIsNotExactInstanceOfTypeFailed(value, wrongType, BuildUserMessageForValueExpression(message, valueExpression)); + ThrowAssertIsNotExactInstanceOfTypeFailed(value, wrongType, message, valueExpression); } } @@ -405,19 +399,22 @@ private static bool IsNotExactInstanceOfTypeFailing(object? value, [NotNullWhen( (value is not null && value.GetType() == wrongType); [DoesNotReturn] - private static void ThrowAssertIsNotExactInstanceOfTypeFailed(object? value, Type? wrongType, string userMessage) + private static void ThrowAssertIsNotExactInstanceOfTypeFailed(object? value, Type? wrongType, string? userMessage, string valueExpression) { - string finalMessage = userMessage; + string callSite = FormatCallSite("Assert.IsNotExactInstanceOfType", (nameof(value), valueExpression)); + string message = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; + if (wrongType is not null) + { + message += Environment.NewLine + FrameworkMessages.IsNotExactInstanceOfTypeFailNew; + } + + message += Environment.NewLine + FormatParameter(nameof(value), valueExpression, value); if (wrongType is not null) { - finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.IsNotExactInstanceOfFailMsg, - userMessage, - wrongType.ToString(), - value!.GetType().ToString()); + message += Environment.NewLine + $" wrongType: {wrongType}" + + Environment.NewLine + $" actualType: {value!.GetType()}"; } - ThrowAssertFailed("Assert.IsNotExactInstanceOfType", finalMessage); + ThrowAssertFailed(callSite, message); } } diff --git a/src/TestFramework/TestFramework/Assertions/Assert.IsInstanceOfType.cs b/src/TestFramework/TestFramework/Assertions/Assert.IsInstanceOfType.cs index bdd68f1607..d8bd8117bd 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.IsInstanceOfType.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.IsInstanceOfType.cs @@ -38,8 +38,7 @@ internal void ComputeAssertion(string valueExpression) { if (_builder is not null) { - _builder.Insert(0, string.Format(CultureInfo.CurrentCulture, FrameworkMessages.CallerArgumentExpressionSingleParameterMessage, "value", valueExpression) + " "); - ThrowAssertIsInstanceOfTypeFailed(_value, _expectedType, _builder.ToString()); + ThrowAssertIsInstanceOfTypeFailed(_value, _expectedType, _builder.ToString(), valueExpression); } } @@ -98,8 +97,7 @@ internal void ComputeAssertion(string valueExpression) { if (_builder is not null) { - _builder.Insert(0, string.Format(CultureInfo.CurrentCulture, FrameworkMessages.CallerArgumentExpressionSingleParameterMessage, "value", valueExpression) + " "); - ThrowAssertIsInstanceOfTypeFailed(_value, typeof(TArg), _builder.ToString()); + ThrowAssertIsInstanceOfTypeFailed(_value, typeof(TArg), _builder.ToString(), valueExpression); } } @@ -160,8 +158,7 @@ internal void ComputeAssertion(string valueExpression) { if (_builder is not null) { - _builder.Insert(0, string.Format(CultureInfo.CurrentCulture, FrameworkMessages.CallerArgumentExpressionSingleParameterMessage, "value", valueExpression) + " "); - ThrowAssertIsNotInstanceOfTypeFailed(_value, _wrongType, _builder.ToString()); + ThrowAssertIsNotInstanceOfTypeFailed(_value, _wrongType, _builder.ToString(), valueExpression); } } @@ -220,8 +217,7 @@ internal void ComputeAssertion(string valueExpression) { if (_builder is not null) { - _builder.Insert(0, string.Format(CultureInfo.CurrentCulture, FrameworkMessages.CallerArgumentExpressionSingleParameterMessage, "value", valueExpression) + " "); - ThrowAssertIsNotInstanceOfTypeFailed(_value, typeof(TArg), _builder.ToString()); + ThrowAssertIsNotInstanceOfTypeFailed(_value, typeof(TArg), _builder.ToString(), valueExpression); } } @@ -292,7 +288,7 @@ public static void IsInstanceOfType([NotNull] object? value, [NotNull] Type? exp { if (IsInstanceOfTypeFailing(value, expectedType)) { - ThrowAssertIsInstanceOfTypeFailed(value, expectedType, BuildUserMessageForValueExpression(message, valueExpression)); + ThrowAssertIsInstanceOfTypeFailed(value, expectedType, message, valueExpression); } } @@ -331,20 +327,23 @@ private static bool IsInstanceOfTypeFailing([NotNullWhen(false)] object? value, => expectedType == null || value == null || !expectedType.IsInstanceOfType(value); [DoesNotReturn] - private static void ThrowAssertIsInstanceOfTypeFailed(object? value, Type? expectedType, string userMessage) + private static void ThrowAssertIsInstanceOfTypeFailed(object? value, Type? expectedType, string? userMessage, string valueExpression) { - string finalMessage = userMessage; + string callSite = FormatCallSite("Assert.IsInstanceOfType", (nameof(value), valueExpression)); + string message = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; if (expectedType is not null && value is not null) { - finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.IsInstanceOfFailMsg, - userMessage, - expectedType.ToString(), - value.GetType().ToString()); + message += Environment.NewLine + FrameworkMessages.IsInstanceOfTypeFailNew; } - ThrowAssertFailed("Assert.IsInstanceOfType", finalMessage); + message += Environment.NewLine + FormatParameter(nameof(value), valueExpression, value); + if (expectedType is not null && value is not null) + { + message += Environment.NewLine + $" expectedType: {expectedType}" + + Environment.NewLine + $" actualType: {value.GetType()}"; + } + + ThrowAssertFailed(callSite, message); } /// @@ -376,7 +375,7 @@ public static void IsNotInstanceOfType(object? value, [NotNull] Type? wrongType, { if (IsNotInstanceOfTypeFailing(value, wrongType)) { - ThrowAssertIsNotInstanceOfTypeFailed(value, wrongType, BuildUserMessageForValueExpression(message, valueExpression)); + ThrowAssertIsNotInstanceOfTypeFailed(value, wrongType, message, valueExpression); } } @@ -409,19 +408,22 @@ private static bool IsNotInstanceOfTypeFailing(object? value, [NotNullWhen(false (value is not null && wrongType.IsInstanceOfType(value)); [DoesNotReturn] - private static void ThrowAssertIsNotInstanceOfTypeFailed(object? value, Type? wrongType, string userMessage) + private static void ThrowAssertIsNotInstanceOfTypeFailed(object? value, Type? wrongType, string? userMessage, string valueExpression) { - string finalMessage = userMessage; + string callSite = FormatCallSite("Assert.IsNotInstanceOfType", (nameof(value), valueExpression)); + string message = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; + if (wrongType is not null) + { + message += Environment.NewLine + FrameworkMessages.IsNotInstanceOfTypeFailNew; + } + + message += Environment.NewLine + FormatParameter(nameof(value), valueExpression, value); if (wrongType is not null) { - finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.IsNotInstanceOfFailMsg, - userMessage, - wrongType.ToString(), - value!.GetType().ToString()); + message += Environment.NewLine + $" wrongType: {wrongType}" + + Environment.NewLine + $" actualType: {value!.GetType()}"; } - ThrowAssertFailed("Assert.IsNotInstanceOfType", finalMessage); + ThrowAssertFailed(callSite, message); } } diff --git a/src/TestFramework/TestFramework/Assertions/Assert.IsNull.cs b/src/TestFramework/TestFramework/Assertions/Assert.IsNull.cs index fd6db5b3d4..4b447ea7de 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.IsNull.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.IsNull.cs @@ -22,9 +22,11 @@ public sealed partial class Assert public readonly struct AssertIsNullInterpolatedStringHandler { private readonly StringBuilder? _builder; + private readonly object? _value; public AssertIsNullInterpolatedStringHandler(int literalLength, int formattedCount, object? value, out bool shouldAppend) { + _value = value; shouldAppend = IsNullFailing(value); if (shouldAppend) { @@ -36,8 +38,7 @@ internal void ComputeAssertion(string valueExpression) { if (_builder is not null) { - _builder.Insert(0, string.Format(CultureInfo.CurrentCulture, FrameworkMessages.CallerArgumentExpressionSingleParameterMessage, "value", valueExpression) + " "); - ThrowAssertIsNullFailed(_builder.ToString()); + ThrowAssertIsNullFailed(_value, _builder.ToString(), valueExpression); } } @@ -90,8 +91,7 @@ internal void ComputeAssertion(string valueExpression) { if (_builder is not null) { - _builder.Insert(0, string.Format(CultureInfo.CurrentCulture, FrameworkMessages.CallerArgumentExpressionSingleParameterMessage, "value", valueExpression) + " "); - ThrowAssertIsNotNullFailed(_builder.ToString()); + ThrowAssertIsNotNullFailed(_builder.ToString(), valueExpression); } } @@ -152,14 +152,21 @@ public static void IsNull(object? value, string? message = "", [CallerArgumentEx { if (IsNullFailing(value)) { - ThrowAssertIsNullFailed(BuildUserMessageForValueExpression(message, valueExpression)); + ThrowAssertIsNullFailed(value, message, valueExpression); } } private static bool IsNullFailing(object? value) => value is not null; - private static void ThrowAssertIsNullFailed(string? message) - => ThrowAssertFailed("Assert.IsNull", message); + [DoesNotReturn] + private static void ThrowAssertIsNullFailed(object? value, string? userMessage, string valueExpression) + { + string callSite = FormatCallSite("Assert.IsNull", (nameof(value), valueExpression)); + string message = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; + message += Environment.NewLine + FrameworkMessages.IsNullFailNew; + message += Environment.NewLine + FormatParameter(nameof(value), valueExpression, value); + ThrowAssertFailed(callSite, message); + } /// #pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 @@ -191,13 +198,19 @@ public static void IsNotNull([NotNull] object? value, string? message = "", [Cal { if (IsNotNullFailing(value)) { - ThrowAssertIsNotNullFailed(BuildUserMessageForValueExpression(message, valueExpression)); + ThrowAssertIsNotNullFailed(message, valueExpression); } } private static bool IsNotNullFailing([NotNullWhen(false)] object? value) => value is null; [DoesNotReturn] - private static void ThrowAssertIsNotNullFailed(string? message) - => ThrowAssertFailed("Assert.IsNotNull", message); + private static void ThrowAssertIsNotNullFailed(string? userMessage, string valueExpression) + { + string callSite = FormatCallSite("Assert.IsNotNull", ("value", valueExpression)); + string message = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; + message += Environment.NewLine + FrameworkMessages.IsNotNullFailNew; + message += Environment.NewLine + FormatParameter("value", valueExpression, null); + ThrowAssertFailed(callSite, message); + } } diff --git a/src/TestFramework/TestFramework/Assertions/Assert.IsTrue.cs b/src/TestFramework/TestFramework/Assertions/Assert.IsTrue.cs index 1c31f3add1..1ea772f961 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.IsTrue.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.IsTrue.cs @@ -22,9 +22,11 @@ public sealed partial class Assert public readonly struct AssertIsTrueInterpolatedStringHandler { private readonly StringBuilder? _builder; + private readonly bool? _condition; public AssertIsTrueInterpolatedStringHandler(int literalLength, int formattedCount, bool? condition, out bool shouldAppend) { + _condition = condition; shouldAppend = IsTrueFailing(condition); if (shouldAppend) { @@ -36,8 +38,7 @@ internal void ComputeAssertion(string conditionExpression) { if (_builder is not null) { - _builder.Insert(0, string.Format(CultureInfo.CurrentCulture, FrameworkMessages.CallerArgumentExpressionSingleParameterMessage, "condition", conditionExpression) + " "); - ThrowAssertIsTrueFailed(_builder.ToString()); + ThrowAssertIsTrueFailed(_condition, _builder.ToString(), conditionExpression); } } @@ -74,9 +75,11 @@ internal void ComputeAssertion(string conditionExpression) public readonly struct AssertIsFalseInterpolatedStringHandler { private readonly StringBuilder? _builder; + private readonly bool? _condition; public AssertIsFalseInterpolatedStringHandler(int literalLength, int formattedCount, bool? condition, out bool shouldAppend) { + _condition = condition; shouldAppend = IsFalseFailing(condition); if (shouldAppend) { @@ -88,8 +91,7 @@ internal void ComputeAssertion(string conditionExpression) { if (_builder is not null) { - _builder.Insert(0, string.Format(CultureInfo.CurrentCulture, FrameworkMessages.CallerArgumentExpressionSingleParameterMessage, "condition", conditionExpression) + " "); - ThrowAssertIsFalseFailed(_builder.ToString()); + ThrowAssertIsFalseFailed(_condition, _builder.ToString(), conditionExpression); } } @@ -150,15 +152,22 @@ public static void IsTrue([DoesNotReturnIf(false)] bool? condition, string? mess { if (IsTrueFailing(condition)) { - ThrowAssertIsTrueFailed(BuildUserMessageForConditionExpression(message, conditionExpression)); + ThrowAssertIsTrueFailed(condition, message, conditionExpression); } } private static bool IsTrueFailing(bool? condition) => condition is false or null; - private static void ThrowAssertIsTrueFailed(string? message) - => ThrowAssertFailed("Assert.IsTrue", message); + [DoesNotReturn] + private static void ThrowAssertIsTrueFailed(bool? condition, string? userMessage, string conditionExpression) + { + string callSite = FormatCallSite("Assert.IsTrue", (nameof(condition), conditionExpression)); + string message = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; + message += Environment.NewLine + FrameworkMessages.IsTrueFailNew; + message += Environment.NewLine + FormatParameter(nameof(condition), conditionExpression, condition); + ThrowAssertFailed(callSite, message); + } /// #pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 @@ -188,7 +197,7 @@ public static void IsFalse([DoesNotReturnIf(true)] bool? condition, string? mess { if (IsFalseFailing(condition)) { - ThrowAssertIsFalseFailed(BuildUserMessageForConditionExpression(message, conditionExpression)); + ThrowAssertIsFalseFailed(condition, message, conditionExpression); } } @@ -196,6 +205,12 @@ private static bool IsFalseFailing(bool? condition) => condition is true or null; [DoesNotReturn] - private static void ThrowAssertIsFalseFailed(string userMessage) - => ThrowAssertFailed("Assert.IsFalse", userMessage); + private static void ThrowAssertIsFalseFailed(bool? condition, string? userMessage, string conditionExpression) + { + string callSite = FormatCallSite("Assert.IsFalse", (nameof(condition), conditionExpression)); + string message = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage!; + message += Environment.NewLine + FrameworkMessages.IsFalseFailNew; + message += Environment.NewLine + FormatParameter(nameof(condition), conditionExpression, condition); + ThrowAssertFailed(callSite, message); + } } diff --git a/src/TestFramework/TestFramework/Assertions/Assert.Matches.cs b/src/TestFramework/TestFramework/Assertions/Assert.Matches.cs index b204970b6d..ce2f23fe09 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.Matches.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.Matches.cs @@ -44,9 +44,13 @@ public static void MatchesRegex([NotNull] Regex? pattern, [NotNull] string? valu if (!pattern.IsMatch(value)) { - string userMessage = BuildUserMessageForPatternExpressionAndValueExpression(message, patternExpression, valueExpression); - string finalMessage = string.Format(CultureInfo.CurrentCulture, FrameworkMessages.IsMatchFail, value, pattern, userMessage); - ThrowAssertFailed("Assert.MatchesRegex", finalMessage); + string callSite = FormatCallSite("Assert.MatchesRegex", (nameof(pattern), patternExpression), (nameof(value), valueExpression)); + string msg = string.IsNullOrEmpty(message) ? string.Empty : message!; + msg += Environment.NewLine + FrameworkMessages.MatchesRegexFailNew; + msg += FormatAlignedParameters( + (nameof(pattern), FormatValue(pattern)), + (nameof(value), FormatValue(value))); + ThrowAssertFailed(callSite, msg); } } @@ -120,9 +124,13 @@ public static void DoesNotMatchRegex([NotNull] Regex? pattern, [NotNull] string? if (pattern.IsMatch(value)) { - string userMessage = BuildUserMessageForPatternExpressionAndValueExpression(message, patternExpression, valueExpression); - string finalMessage = string.Format(CultureInfo.CurrentCulture, FrameworkMessages.IsNotMatchFail, value, pattern, userMessage); - ThrowAssertFailed("Assert.DoesNotMatchRegex", finalMessage); + string callSite = FormatCallSite("Assert.DoesNotMatchRegex", (nameof(pattern), patternExpression), (nameof(value), valueExpression)); + string msg = string.IsNullOrEmpty(message) ? string.Empty : message!; + msg += Environment.NewLine + FrameworkMessages.DoesNotMatchRegexFailNew; + msg += FormatAlignedParameters( + (nameof(pattern), FormatValue(pattern)), + (nameof(value), FormatValue(value))); + ThrowAssertFailed(callSite, msg); } } diff --git a/src/TestFramework/TestFramework/Assertions/Assert.StartsWith.cs b/src/TestFramework/TestFramework/Assertions/Assert.StartsWith.cs index 6f5c728535..47f94e657e 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.StartsWith.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.StartsWith.cs @@ -76,9 +76,13 @@ public static void StartsWith([NotNull] string? expectedPrefix, [NotNull] string CheckParameterNotNull(expectedPrefix, "Assert.StartsWith", "expectedPrefix"); if (!value.StartsWith(expectedPrefix, comparisonType)) { - string userMessage = BuildUserMessageForExpectedPrefixExpressionAndValueExpression(message, expectedPrefixExpression, valueExpression); - string finalMessage = string.Format(CultureInfo.CurrentCulture, FrameworkMessages.StartsWithFail, value, expectedPrefix, userMessage); - ThrowAssertFailed("Assert.StartsWith", finalMessage); + string callSite = FormatCallSite("Assert.StartsWith", (nameof(expectedPrefix), expectedPrefixExpression), (nameof(value), valueExpression)); + string msg = string.IsNullOrEmpty(message) ? string.Empty : message!; + msg += Environment.NewLine + FrameworkMessages.StartsWithFailNew; + msg += FormatAlignedParameters( + (nameof(expectedPrefix), FormatValue(expectedPrefix)), + (nameof(value), FormatValue(value))); + ThrowAssertFailed(callSite, msg); } } @@ -148,9 +152,13 @@ public static void DoesNotStartWith([NotNull] string? notExpectedPrefix, [NotNul CheckParameterNotNull(notExpectedPrefix, "Assert.DoesNotStartWith", "notExpectedPrefix"); if (value.StartsWith(notExpectedPrefix, comparisonType)) { - string userMessage = BuildUserMessageForNotExpectedPrefixExpressionAndValueExpression(message, notExpectedPrefixExpression, valueExpression); - string finalMessage = string.Format(CultureInfo.CurrentCulture, FrameworkMessages.DoesNotStartWithFail, value, notExpectedPrefix, userMessage); - ThrowAssertFailed("Assert.DoesNotStartWith", finalMessage); + string callSite = FormatCallSite("Assert.DoesNotStartWith", (nameof(notExpectedPrefix), notExpectedPrefixExpression), (nameof(value), valueExpression)); + string msg = string.IsNullOrEmpty(message) ? string.Empty : message!; + msg += Environment.NewLine + FrameworkMessages.DoesNotStartWithFailNew; + msg += FormatAlignedParameters( + (nameof(notExpectedPrefix), FormatValue(notExpectedPrefix)), + (nameof(value), FormatValue(value))); + ThrowAssertFailed(callSite, msg); } } } diff --git a/src/TestFramework/TestFramework/Assertions/Assert.ThrowsException.cs b/src/TestFramework/TestFramework/Assertions/Assert.ThrowsException.cs index b5478a28a6..108330d4df 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.ThrowsException.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.ThrowsException.cs @@ -42,8 +42,7 @@ internal TException ComputeAssertion(string actionExpression) { if (_state.FailAction is not null) { - _builder!.Insert(0, string.Format(CultureInfo.CurrentCulture, FrameworkMessages.CallerArgumentExpressionSingleParameterMessage, "action", actionExpression) + " "); - _state.FailAction(_builder!.ToString()); + _state.FailAction(_builder!.ToString(), actionExpression); } else { @@ -113,8 +112,7 @@ internal TException ComputeAssertion(string actionExpression) { if (_state.FailAction is not null) { - _builder!.Insert(0, string.Format(CultureInfo.CurrentCulture, FrameworkMessages.CallerArgumentExpressionSingleParameterMessage, "action", actionExpression) + " "); - _state.FailAction(_builder!.ToString()); + _state.FailAction(_builder!.ToString(), actionExpression); } else { @@ -327,7 +325,7 @@ private static TException ThrowsException(Action action, bool isStri ThrowsExceptionState state = IsThrowsFailing(action, isStrictType, assertMethodName); if (state.FailAction is not null) { - state.FailAction(BuildUserMessageForActionExpression(message, actionExpression)); + state.FailAction(message ?? string.Empty, actionExpression); } else { @@ -347,7 +345,7 @@ private static TException ThrowsException(Action action, bool isStri ThrowsExceptionState state = IsThrowsFailing(action, isStrictType, assertMethodName); if (state.FailAction is not null) { - state.FailAction(BuildUserMessageForActionExpression(messageBuilder(state.ExceptionThrown), actionExpression)); + state.FailAction(messageBuilder(state.ExceptionThrown), actionExpression); } else { @@ -483,7 +481,7 @@ private static async Task ThrowsExceptionAsync(Func(action, isStrictType, assertMethodName).ConfigureAwait(false); if (state.FailAction is not null) { - state.FailAction(BuildUserMessageForActionExpression(message, actionExpression)); + state.FailAction(message ?? string.Empty, actionExpression); } else { @@ -503,7 +501,7 @@ private static async Task ThrowsExceptionAsync(Func(action, isStrictType, assertMethodName).ConfigureAwait(false); if (state.FailAction is not null) { - state.FailAction(BuildUserMessageForActionExpression(messageBuilder(state.ExceptionThrown), actionExpression)); + state.FailAction(messageBuilder(state.ExceptionThrown), actionExpression); } else { @@ -530,27 +528,25 @@ private static async Task IsThrowsAsyncFailingAsync + (userMessage, actionExpr) => { - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.WrongExceptionThrown, - userMessage, - typeof(TException), - ex.GetType()); - ThrowAssertFailed("Assert." + assertMethodName, finalMessage); + string msg = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage; + msg += Environment.NewLine + FrameworkMessages.WrongExceptionThrownNew; + msg += FormatExpressionParameter(nameof(action), actionExpr); + msg += Environment.NewLine + $" expectedExceptionType: {typeof(TException)}"; + msg += Environment.NewLine + $" actualExceptionType: {ex.GetType()}"; + ThrowAssertFailed("Assert." + assertMethodName, msg); }, ex); } return ThrowsExceptionState.CreateFailingState( - failAction: userMessage => + failAction: (userMessage, actionExpr) => { - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.NoExceptionThrown, - userMessage, - typeof(TException)); - ThrowAssertFailed("Assert." + assertMethodName, finalMessage); + string msg = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage; + msg += Environment.NewLine + FrameworkMessages.NoExceptionThrownNew; + msg += FormatExpressionParameter(nameof(action), actionExpr); + msg += Environment.NewLine + $" expectedExceptionType: {typeof(TException)}"; + ThrowAssertFailed("Assert." + assertMethodName, msg); }, null); } @@ -570,27 +566,25 @@ private static ThrowsExceptionState IsThrowsFailing(Action action, b return isExceptionOfType ? ThrowsExceptionState.CreateNotFailingState(ex) : ThrowsExceptionState.CreateFailingState( - userMessage => + (userMessage, actionExpr) => { - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.WrongExceptionThrown, - userMessage, - typeof(TException), - ex.GetType()); - ThrowAssertFailed("Assert." + assertMethodName, finalMessage); + string msg = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage; + msg += Environment.NewLine + FrameworkMessages.WrongExceptionThrownNew; + msg += FormatExpressionParameter(nameof(action), actionExpr); + msg += Environment.NewLine + $" expectedExceptionType: {typeof(TException)}"; + msg += Environment.NewLine + $" actualExceptionType: {ex.GetType()}"; + ThrowAssertFailed("Assert." + assertMethodName, msg); }, ex); } return ThrowsExceptionState.CreateFailingState( - failAction: userMessage => + failAction: (userMessage, actionExpr) => { - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.NoExceptionThrown, - userMessage, - typeof(TException)); - ThrowAssertFailed("Assert." + assertMethodName, finalMessage); + string msg = string.IsNullOrEmpty(userMessage) ? string.Empty : userMessage; + msg += Environment.NewLine + FrameworkMessages.NoExceptionThrownNew; + msg += FormatExpressionParameter(nameof(action), actionExpr); + msg += Environment.NewLine + $" expectedExceptionType: {typeof(TException)}"; + ThrowAssertFailed("Assert." + assertMethodName, msg); }, null); } @@ -598,9 +592,9 @@ private readonly struct ThrowsExceptionState { public Exception? ExceptionThrown { get; } - public Action? FailAction { get; } + public Action? FailAction { get; } - private ThrowsExceptionState(Exception? exceptionThrown, Action? failAction) + private ThrowsExceptionState(Exception? exceptionThrown, Action? failAction) { // If the assert is failing, failAction should be non-null, and exceptionWhenNotFailing may or may not be null. // If the assert is not failing, exceptionWhenNotFailing should be non-null, and failAction should be null. @@ -608,7 +602,7 @@ private ThrowsExceptionState(Exception? exceptionThrown, Action? failAct FailAction = failAction; } - public static ThrowsExceptionState CreateFailingState(Action failAction, Exception? exceptionThrown) + public static ThrowsExceptionState CreateFailingState(Action failAction, Exception? exceptionThrown) => new(exceptionThrown, failAction); public static ThrowsExceptionState CreateNotFailingState(Exception exception) diff --git a/src/TestFramework/TestFramework/Assertions/Assert.cs b/src/TestFramework/TestFramework/Assertions/Assert.cs index 4a832186af..7988a6a684 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.cs @@ -50,8 +50,18 @@ internal static void ThrowAssertFailed(string assertionName, string? message) } } - throw new AssertFailedException( - string.Format(CultureInfo.CurrentCulture, FrameworkMessages.AssertionFailed, assertionName, message)); + string formattedMessage = string.Format(CultureInfo.CurrentCulture, FrameworkMessages.AssertionFailed, assertionName, message); + + // When there's no user message (message starts with newline for parameter details), + // the format produces a trailing space before the newline ("failed. \\r\\n"). + // Remove it to avoid trailing whitespace on the first line while preserving localization. + if (message is not null && message.StartsWith(Environment.NewLine, StringComparison.Ordinal)) + { + string prefix = string.Format(CultureInfo.CurrentCulture, FrameworkMessages.AssertionFailed, assertionName, string.Empty); + formattedMessage = prefix.TrimEnd() + message; + } + + throw new AssertFailedException(formattedMessage); } private static bool ShouldLaunchDebugger() @@ -74,125 +84,375 @@ private static bool ShouldLaunchDebugger() internal static string BuildUserMessage(string? format) => format ?? string.Empty; - private static string BuildUserMessageForSingleExpression(string? format, string callerArgExpression, string parameterName) + /// + /// Checks the parameter for valid conditions. + /// + /// + /// The parameter. + /// + /// + /// The assertion Name. + /// + /// + /// parameter name. + /// + internal static void CheckParameterNotNull([NotNull] object? param, string assertionName, string parameterName) + { + if (param is null) + { + string finalMessage = string.Format(CultureInfo.CurrentCulture, FrameworkMessages.NullParameterToAssert, parameterName); + ThrowAssertFailed(assertionName, finalMessage); + } + } + + internal static string ReplaceNulls(object? input) + => input?.ToString() ?? string.Empty; + + internal static string FormatValue(T? value, int maxLength = 256) { - string userMessage = BuildUserMessage(format); - if (string.IsNullOrEmpty(callerArgExpression)) + if (value is null) { - return userMessage; + return "(null)"; } - string callerArgMessagePart = string.Format(CultureInfo.InvariantCulture, FrameworkMessages.CallerArgumentExpressionSingleParameterMessage, parameterName, callerArgExpression); - return string.IsNullOrEmpty(userMessage) - ? callerArgMessagePart - : $"{callerArgMessagePart} {userMessage}"; + if (value is string s) + { + return EscapeNewlines(Truncate($"\"{s}\"", maxLength)); + } + + // For collections, show a preview with element values + if (value is IEnumerable enumerable) + { + return FormatCollectionPreview(enumerable); + } + + // Always use the runtime type for non-null values so that interface/base-class + // typed parameters still resolve the actual overridden ToString(). + Type type = value.GetType(); + + if (type.IsPrimitive || value is decimal or DateTime or DateTimeOffset + or TimeSpan or Guid or Enum) + { + return EscapeNewlines(Truncate(value.ToString() ?? string.Empty, maxLength)); + } + + MethodInfo? toStringMethod = type.GetMethod(nameof(ToString), BindingFlags.Public | BindingFlags.Instance, null, Type.EmptyTypes, null); + if (toStringMethod is not null + && toStringMethod.DeclaringType != typeof(object) + && toStringMethod.DeclaringType != typeof(ValueType)) + { + try + { + return EscapeNewlines(Truncate(value.ToString() ?? string.Empty, maxLength)); + } + catch (Exception) + { + // Fall through to type name display if ToString throws + } + } + + // No useful ToString - just return the type name + string typeName = type.FullName ?? type.Name; + return $"<{typeName}>"; } - private static string BuildUserMessageForTwoExpressions(string? format, string callerArgExpression1, string parameterName1, string callerArgExpression2, string parameterName2) + internal static string TruncateExpression(string expression, int maxLength = 100) + => expression.Length <= maxLength + ? expression +#if NETCOREAPP3_1_OR_GREATER + : string.Concat(expression.AsSpan(0, maxLength), "..."); +#else + : expression.Substring(0, maxLength) + "..."; +#endif + + private static string Truncate(string value, int maxLength) + => value.Length <= maxLength + ? value +#if NETCOREAPP3_1_OR_GREATER + : string.Concat(value.AsSpan(0, maxLength), "... ", (value.Length - maxLength).ToString(CultureInfo.InvariantCulture), " more"); +#else + : value.Substring(0, maxLength) + $"... {value.Length - maxLength} more"; +#endif + + private static string EscapeNewlines(string value) + => value.Contains('\n') || value.Contains('\r') + ? value.Replace("\r\n", "\\r\\n").Replace("\n", "\\n").Replace("\r", "\\r") + : value; + + private static bool IsExpressionRedundant(string expression, string formattedValue) { - string userMessage = BuildUserMessage(format); - if (string.IsNullOrEmpty(callerArgExpression1) || string.IsNullOrEmpty(callerArgExpression2)) + if (string.IsNullOrEmpty(expression)) + { + return true; + } + + // Exact match: expression "5" == formattedValue "5" + if (expression == formattedValue) { - return userMessage; + return true; } - string callerArgMessagePart = string.Format(CultureInfo.InvariantCulture, FrameworkMessages.CallerArgumentExpressionTwoParametersMessage, parameterName1, callerArgExpression1, parameterName2, callerArgExpression2); - return string.IsNullOrEmpty(userMessage) - ? callerArgMessagePart - : $"{callerArgMessagePart} {userMessage}"; + // Null literal: expression "null" vs formattedValue "(null)" + if (expression is "null" && formattedValue is "(null)") + { + return true; + } + + // Boolean/true/false: expression "true" vs formattedValue "True" + if (string.Equals(expression, formattedValue, StringComparison.OrdinalIgnoreCase)) + { + return true; + } + + // Numeric literal in different notation (e.g., "100E-2" vs "1") + if (double.TryParse(expression, NumberStyles.Any, CultureInfo.InvariantCulture, out double exprNum) + && double.TryParse(formattedValue, NumberStyles.Any, CultureInfo.InvariantCulture, out double fmtNum) + && exprNum == fmtNum) + { + return true; + } + + // C# string literal expression: @"\d+" or "\d+" vs formattedValue \d+ + // Strip the string literal syntax and compare the inner content + string? innerContent = TryExtractStringLiteralContent(expression); + return innerContent is not null && innerContent == formattedValue; } - private static string BuildUserMessageForThreeExpressions(string? format, string callerArgExpression1, string parameterName1, string callerArgExpression2, string parameterName2, string callerArgExpression3, string parameterName3) + /// + /// Tries to extract the string content from a C# string literal expression. + /// Returns the inner string value for @"..." and "..." literals, or null if not a string literal. + /// + private static string? TryExtractStringLiteralContent(string expression) { - string userMessage = BuildUserMessage(format); - if (string.IsNullOrEmpty(callerArgExpression1) || string.IsNullOrEmpty(callerArgExpression2) || string.IsNullOrEmpty(callerArgExpression3)) + // Verbatim string: @"content" + if (expression.Length >= 3 && expression[0] == '@' && expression[1] == '"' && expression[expression.Length - 1] == '"') + { + return expression.Substring(2, expression.Length - 3).Replace("\"\"", "\""); + } + + // Regular string: "content" + if (expression.Length >= 2 && expression[0] == '"' && expression[expression.Length - 1] == '"') { - return userMessage; + return expression.Substring(1, expression.Length - 2); } - string callerArgMessagePart = string.Format(CultureInfo.InvariantCulture, FrameworkMessages.CallerArgumentExpressionThreeParametersMessage, parameterName1, callerArgExpression1, parameterName2, callerArgExpression2, parameterName3, callerArgExpression3); - return string.IsNullOrEmpty(userMessage) - ? callerArgMessagePart - : $"{callerArgMessagePart} {userMessage}"; + // Not a string literal + return null; } - private static string BuildUserMessageForConditionExpression(string? format, string conditionExpression) - => BuildUserMessageForSingleExpression(format, conditionExpression, "condition"); + /// + /// Checks if the expression is a typed numeric literal (e.g., 1.0f, 1.1d, 0.001m, 2L) + /// or a well-known numeric constant (float.NaN, double.NaN) that is a more informative + /// representation than the plain ToString() value. + /// + private static bool IsExpressionMoreSpecificNumericLiteral(string expression, string formattedValue) + { + if (string.IsNullOrEmpty(expression) || expression.Length < 2) + { + return false; + } - private static string BuildUserMessageForValueExpression(string? format, string valueExpression) - => BuildUserMessageForSingleExpression(format, valueExpression, "value"); + // Well-known numeric constants: float.NaN, double.NaN, float.PositiveInfinity, etc. + if (expression.StartsWith("float.", StringComparison.Ordinal) || expression.StartsWith("double.", StringComparison.Ordinal)) + { + return true; + } - private static string BuildUserMessageForActionExpression(string? format, string actionExpression) - => BuildUserMessageForSingleExpression(format, actionExpression, "action"); + // Check if expression ends with a numeric type suffix + char lastChar = expression[expression.Length - 1]; + if (lastChar is not ('f' or 'F' or 'd' or 'D' or 'm' or 'M' or 'L' or 'l' or 'u' or 'U')) + { + return false; + } - private static string BuildUserMessageForCollectionExpression(string? format, string collectionExpression) - => BuildUserMessageForSingleExpression(format, collectionExpression, "collection"); + // The formatted value should be the numeric part without the suffix + // e.g., expression "1.0d" -> formattedValue "1" or "1.0" + string numericPart = expression.Substring(0, expression.Length - 1); - private static string BuildUserMessageForSubstringExpressionAndValueExpression(string? format, string substringExpression, string valueExpression) - => BuildUserMessageForTwoExpressions(format, substringExpression, "substring", valueExpression, "value"); + // Handle UL/ul suffix (two chars) + if (numericPart.Length > 0 && numericPart[numericPart.Length - 1] is 'u' or 'U' or 'l' or 'L') + { + numericPart = numericPart.Substring(0, numericPart.Length - 1); + } - private static string BuildUserMessageForExpectedSuffixExpressionAndValueExpression(string? format, string expectedSuffixExpression, string valueExpression) - => BuildUserMessageForTwoExpressions(format, expectedSuffixExpression, "expectedSuffix", valueExpression, "value"); + // Check if removing the suffix gives the formatted value, or if they represent the same number + return numericPart == formattedValue + || (double.TryParse(numericPart, NumberStyles.Any, CultureInfo.InvariantCulture, out double exprNum) + && double.TryParse(formattedValue, NumberStyles.Any, CultureInfo.InvariantCulture, out double valNum) + && exprNum == valNum); + } - private static string BuildUserMessageForNotExpectedSuffixExpressionAndValueExpression(string? format, string notExpectedSuffixExpression, string valueExpression) - => BuildUserMessageForTwoExpressions(format, notExpectedSuffixExpression, "notExpectedSuffix", valueExpression, "value"); + internal static string FormatParameter(string paramName, string expression, T? value) + { + string formattedValue = FormatValue(value); - private static string BuildUserMessageForExpectedPrefixExpressionAndValueExpression(string? format, string expectedPrefixExpression, string valueExpression) - => BuildUserMessageForTwoExpressions(format, expectedPrefixExpression, "expectedPrefix", valueExpression, "value"); + return $" {paramName}: {formattedValue}"; + } - private static string BuildUserMessageForNotExpectedPrefixExpressionAndValueExpression(string? format, string notExpectedPrefixExpression, string valueExpression) - => BuildUserMessageForTwoExpressions(format, notExpectedPrefixExpression, "notExpectedPrefix", valueExpression, "value"); + /// + /// Formats a parameter line showing only the expression (no value). + /// Used for parameters like predicates and actions where the + /// runtime value's ToString() is not useful. + /// Returns empty string if the expression is empty or matches the parameter name. + /// + internal static string FormatExpressionParameter(string paramName, string expression) + => string.IsNullOrEmpty(expression) || expression == paramName + ? string.Empty + : Environment.NewLine + $" {paramName}: {TruncateExpression(expression)}"; - private static string BuildUserMessageForPatternExpressionAndValueExpression(string? format, string patternExpression, string valueExpression) - => BuildUserMessageForTwoExpressions(format, patternExpression, "pattern", valueExpression, "value"); + /// + /// Formats a collection parameter line showing a preview of the collection elements. + /// + internal static string FormatCollectionParameter(string expression, IEnumerable collection) + { + string preview = FormatCollectionPreview(collection); - private static string BuildUserMessageForLowerBoundExpressionAndValueExpression(string? format, string lowerBoundExpression, string valueExpression) - => BuildUserMessageForTwoExpressions(format, lowerBoundExpression, "lowerBound", valueExpression, "value"); + return $"{Environment.NewLine} collection: {preview}"; + } - private static string BuildUserMessageForUpperBoundExpressionAndValueExpression(string? format, string upperBoundExpression, string valueExpression) - => BuildUserMessageForTwoExpressions(format, upperBoundExpression, "upperBound", valueExpression, "value"); + /// + /// Formats a preview string for a collection, showing element values up to characters. + /// + /// Performance: We avoid enumerating the entire collection when the display is truncated. + /// For ICollection, we read .Count directly (O(1)) to get the total without full enumeration. + /// For non-ICollection enumerables (e.g. LINQ queries, infinite sequences), we stop + /// enumeration as soon as the display budget is exhausted and report "N+ elements" since + /// the true count is unknown. This prevents hangs on lazy/infinite sequences and avoids + /// O(n) enumeration cost when only a prefix is displayed. + /// + /// + private static string FormatCollectionPreview(IEnumerable collection, int maxLength = 256) + { + // Perf: get count from ICollection (O(1)) to avoid full enumeration just for the count. + int? knownCount = collection is ICollection c ? c.Count : null; + + var elements = new List(); + int enumeratedCount = 0; + int currentLength = 0; + bool truncated = false; + + // Perf: wrap in try-catch so that faulting enumerators (e.g. collection modified during + // iteration, or user-defined iterators that throw) don't bubble up from assertion formatting. + try + { + foreach (object? item in collection) + { + enumeratedCount++; + + string formatted = item is IEnumerable innerCollection and not string + ? FormatCollectionPreview(innerCollection, maxLength: 50) + : FormatValue(item, maxLength: 50); + + // Account for ", " separator between elements + int addedLength = elements.Count > 0 + ? formatted.Length + 2 + : formatted.Length; + + if (currentLength + addedLength > maxLength && elements.Count > 0) + { + truncated = true; - private static string BuildUserMessageForExpectedExpressionAndCollectionExpression(string? format, string expectedExpression, string collectionExpression) - => BuildUserMessageForTwoExpressions(format, expectedExpression, "expected", collectionExpression, "collection"); + // Perf: stop enumeration immediately once the display budget is exceeded. + // Without this break, we'd continue iterating potentially millions of + // elements (or hang on infinite sequences) just to compute totalCount. + break; + } - private static string BuildUserMessageForNotExpectedExpressionAndCollectionExpression(string? format, string notExpectedExpression, string collectionExpression) - => BuildUserMessageForTwoExpressions(format, notExpectedExpression, "notExpected", collectionExpression, "collection"); + elements.Add(formatted); + currentLength += addedLength; + } + } + catch (Exception) + { + // If enumeration fails, report what we've collected so far + truncated = elements.Count > 0; + } + + int totalCount = knownCount ?? enumeratedCount; + int displayedCount = elements.Count; + + string elementList = string.Join(", ", elements); + if (truncated) + { + int remaining = totalCount - displayedCount; + string remainingText = knownCount is null + ? $"{remaining}+" + : $"{remaining}"; + elementList += $", ... {remainingText} more"; + } - private static string BuildUserMessageForPredicateExpressionAndCollectionExpression(string? format, string predicateExpression, string collectionExpression) - => BuildUserMessageForTwoExpressions(format, predicateExpression, "predicate", collectionExpression, "collection"); + string countText = truncated + ? string.Empty + : $" ({totalCount} {(totalCount == 1 ? "item" : "items")})"; - private static string BuildUserMessageForExpectedExpressionAndActualExpression(string? format, string expectedExpression, string actualExpression) - => BuildUserMessageForTwoExpressions(format, expectedExpression, "expected", actualExpression, "actual"); + return $"[{elementList}]{countText}"; + } - private static string BuildUserMessageForNotExpectedExpressionAndActualExpression(string? format, string notExpectedExpression, string actualExpression) - => BuildUserMessageForTwoExpressions(format, notExpectedExpression, "notExpected", actualExpression, "actual"); + internal static string FormatParameterWithValue(string paramName, string expression, string formattedValue) + => $" {paramName}: {formattedValue}"; - private static string BuildUserMessageForMinValueExpressionAndMaxValueExpressionAndValueExpression(string? format, string minValueExpression, string maxValueExpression, string valueExpression) - => BuildUserMessageForThreeExpressions(format, minValueExpression, "minValue", maxValueExpression, "maxValue", valueExpression, "value"); + /// + /// Formats a parameter line, checking expression redundancy against a base value + /// while displaying a different (enriched) display value. + /// + internal static string FormatParameterWithExpressionCheck(string paramName, string expression, string baseValue, string displayValue) + => $" {paramName}: {displayValue}"; /// - /// Checks the parameter for valid conditions. + /// Builds the "Assert.Method(expr1, expr2)" call site string for the first line. + /// Only the primary/semantic parameters are included (not message, culture, delta, etc.). /// - /// - /// The parameter. - /// - /// - /// The assertion Name. - /// - /// - /// parameter name. - /// - internal static void CheckParameterNotNull([NotNull] object? param, string assertionName, string parameterName) + internal static string FormatCallSite(string methodName, params (string ParamName, string Expression)[] args) { - if (param == null) + var sb = new StringBuilder(methodName); + sb.Append('('); + for (int i = 0; i < args.Length; i++) { - string finalMessage = string.Format(CultureInfo.CurrentCulture, FrameworkMessages.NullParameterToAssert, parameterName); - ThrowAssertFailed(assertionName, finalMessage); + if (i > 0) + { + sb.Append(", "); + } + + string expression = args[i].Expression; + string paramName = args[i].ParamName; + sb.Append(string.IsNullOrEmpty(expression) || expression == paramName + ? paramName + : TruncateExpression(expression, 50)); } + + sb.Append(')'); + + return sb.ToString(); } - internal static string ReplaceNulls(object? input) - => input?.ToString() ?? string.Empty; + /// + /// Formats multiple parameter lines with aligned values. + /// All labels are padded so that values start at the same column. + /// + internal static string FormatAlignedParameters(params (string Label, string Value)[] parameters) + { + int maxLabelLength = 0; + foreach ((string label, string _) in parameters) + { + if (label.Length > maxLabelLength) + { + maxLabelLength = label.Length; + } + } + + var sb = new StringBuilder(); + foreach ((string label, string value) in parameters) + { + sb.Append(Environment.NewLine); + sb.Append(" "); + sb.Append(label); + sb.Append(':'); + sb.Append(new string(' ', maxLabelLength - label.Length + 1)); + sb.Append(value); + } + + return sb.ToString(); + } private static int CompareInternal(string? expected, string? actual, bool ignoreCase, CultureInfo culture) #pragma warning disable CA1309 // Use ordinal string comparison diff --git a/src/TestFramework/TestFramework/Resources/FrameworkMessages.resx b/src/TestFramework/TestFramework/Resources/FrameworkMessages.resx index 537b9331a7..021e98fcef 100644 --- a/src/TestFramework/TestFramework/Resources/FrameworkMessages.resx +++ b/src/TestFramework/TestFramework/Resources/FrameworkMessages.resx @@ -126,42 +126,12 @@ Duplicate item found:<{1}>. {0} - - Expected:<{1}>. Actual:<{2}>. {0} - - - Expected a difference no greater than <{3}> between expected value <{1}> and actual value <{2}>. {0} - - - Expected:<{1}>. Case is different for actual value:<{2}>. {0} - - - Expected:<{1} ({2})>. Actual:<{3} ({4})>. {0} - - - {0}{1} -{2} -{3} -{4} - - - Expected: - - - But was: - String lengths are both {0} but differ at index {1}. Expected string length {0} but was {1}. - - Expected any value except:<{1}>. Actual:<{2}>. {0} - - - Expected a difference greater than <{3}> between expected value <{1}> and actual value <{2}>. {0} - Do not pass value types to AreSame(). Values converted to Object will never be the same. Consider using AreEqual(). {0} @@ -183,9 +153,6 @@ String '{0}' does not contain string '{1}'. {2}. - - Value '{0}' is not within the expected range [{1}..{2}]. {3} - The number of elements in the collections do not match. Expected:<{1}>. Actual:<{2}>.{0} @@ -203,21 +170,9 @@ Actual: {2} {0} failed. {1} - - {0} Expected type:<{1}>. Actual type:<{2}>. - String '{0}' does not match pattern '{1}'. {2} - - Wrong Type:<{1}>. Actual type:<{2}>. {0} - - - {0} Expected exact type:<{1}>. Actual type:<{2}>. - - - Wrong exact Type:<{1}>. Actual type:<{2}>. {0} - String '{0}' matches pattern '{1}'. {2} @@ -256,12 +211,6 @@ Actual: {2} (Failed to get the message for an exception of type {0} due to an exception.) - - Expected exception type:<{1}> but no exception was thrown. {0} - - - Expected exception type:<{1}>. Actual exception type:<{2}>. {0} - {0} ({1}) @@ -289,54 +238,9 @@ Actual: {2} The dynamic data source '{0}' in type '{1}' should exist and be a property, a method, or a field. - - Expected collection of size {1}. Actual: {2}. {0} - - - Expected exactly one item to match the predicate but found {1} item(s). {0} - - - Expected collection to contain exactly one element but found {1} element(s). {0} - - - Expected collection to contain the specified item. {0} - - - Expected at least one item to match the predicate. {0} - - - Expected collection to not contain the specified item. {0} - - - Expected no items to match the predicate. {0} - - - Expected collection to contain any item but it is empty. {0} - Invalid GitHub ticket URL - - String '{0}' does contain string '{1}'. {2}. - - - Actual value <{2}> is not greater than expected value <{1}>. {0} - - - Actual value <{2}> is not greater than or equal to expected value <{1}>. {0} - - - Actual value <{2}> is not less than expected value <{1}>. {0} - - - Actual value <{2}> is not less than or equal to expected value <{1}>. {0} - - - Expected value <{1}> to be positive. {0} - - - Expected value <{1}> to be negative. {0} - String '{0}' ends with string '{1}'. {2} @@ -364,10 +268,6 @@ Actual: {2} The property 'TestContext.{0}' is related to current test is not available during assembly or class fixtures. - - '{0}' expression: '{1}'. - Example: "'value' expression: 'new object()'", where 'value' is the parameter name of an assertion method, and 'new object()' is the expression the user passed to the assert method. - Assert.That({0}) failed. {0} is the user code expression @@ -379,18 +279,130 @@ Actual: {2} Details: - - '{0}' expression: '{1}', '{2}' expression: '{3}'. - Example: "'minValue' expression: 'userCode1', 'maxValue' expression: 'userCode2', 'value' expression: 'userCode3'", where 'minValue', 'maxValue', and 'value' are the parameter names of an assertion method, and 'userCode's are the expressions the user passed to the assert method. - - - '{0}' expression: '{1}', '{2}' expression: '{3}', '{4}' expression: '{5}'. - Example: "'substring' expression: 'userCode1', 'value' expression: 'userCode2'", where 'substring' and 'value' are the parameter names of an assertion method, and 'userCode's are the expressions the user passed to the assert method. - Element(s) <{0}> is/are not present in the collection. The maximum value must be greater than or equal to the minimum value. + + Expected a difference no greater than <{0}>. + + + Expected a difference greater than <{0}>. + + + Case differs. + + + String does not start with expected prefix. + + + String starts with unexpected prefix. + + + String does not end with expected suffix. + + + String ends with unexpected suffix. + + + String does not match expected pattern. + + + String matches pattern but should not. + + + Expected collection to contain the specified item. + + + Expected at least one item to match the predicate. + + + Expected collection to not contain the specified item. + + + Expected no items to match the predicate. + + + String does not contain the expected substring. + + + String contains the unexpected substring. + + + Expected exactly one item to match the predicate but found {0} item(s). + + + Expected collection to contain exactly one item but found {0} item(s). + + + Expected collection to have the specified number of items. + + + Expected collection to contain any item but it is empty. + + + Value is not within the expected range. + + + Wrong exception type was thrown. + + + No exception was thrown. + + + Expected values to be equal. + + + Expected values to differ. + + + Expected references to be the same. + + + Expected references to be different. + + + Expected condition to be true. + + + Expected condition to be false. + + + Expected value to be null. + + + Expected a non-null value. + + + Expected value to be of the specified type. + + + Value should not be of the specified type. + + + Expected value to be exactly of the specified type. + + + Value should not be exactly of the specified type. + + + Expected value to be greater than the specified bound. + + + Expected value to be greater than or equal to the specified bound. + + + Expected value to be less than the specified bound. + + + Expected value to be less than or equal to the specified bound. + + + Expected a positive value. + + + Expected a negative value. + \ No newline at end of file diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.cs.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.cs.xlf index 02a8e5a3bc..3a55011531 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.cs.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.cs.xlf @@ -17,46 +17,20 @@ Byla nalezena duplicitní položka:<{1}>. {0} - - Expected:<{1}>. Actual:<{2}>. {0} - Očekáváno:<{1}>. Aktuálně:<{2}>. {0} - - - - Expected a difference no greater than <{3}> between expected value <{1}> and actual value <{2}>. {0} - Očekáván rozdíl, který není větší jak <{3}> mezi očekávanou hodnotou <{1}> a aktuální hodnotou <{2}>. {0} - - - - Expected:<{1}>. Case is different for actual value:<{2}>. {0} - Očekáváno:<{1}>. Případ je rozdílný pro aktuální hodnotu:<{2}>. {0} - - - - Expected:<{1} ({2})>. Actual:<{3} ({4})>. {0} - Očekáváno:<{1} ({2})>. Aktuálně:<{3} ({4})>. {0} - - - - {0}{1} -{2} -{3} -{4} - {0}{1} -{2} -{3} -{4} + + Case differs. + Case differs. - - Expected: - Očekáváno: - + + Expected a difference no greater than <{0}>. + Expected a difference no greater than <{0}>. + - - But was: - Ale bylo: - + + Expected values to be equal. + Expected values to be equal. + String lengths are both {0} but differ at index {1}. @@ -68,15 +42,25 @@ Očekávaná délka řetězce je {0}, ale byla {1}. - - Expected any value except:<{1}>. Actual:<{2}>. {0} - Nebyla očekávána žádná hodnota kromě:<{1}>. Aktuálně:<{2}>. {0} - + + Expected a difference greater than <{0}>. + Expected a difference greater than <{0}>. + - - Expected a difference greater than <{3}> between expected value <{1}> and actual value <{2}>. {0} - Očekáván rozdíl, který je větší jak <{3}> mezi očekávanou hodnotou <{1}> a aktuální hodnotou <{2}>. {0} - + + Expected values to differ. + Expected values to differ. + + + + Expected references to be different. + Expected references to be different. + + + + Expected references to be the same. + Expected references to be the same. + Do not pass value types to AreSame(). Values converted to Object will never be the same. Consider using AreEqual(). {0} @@ -118,21 +102,6 @@ Obě kolekce obsahují stejné elementy. {0} - - '{0}' expression: '{1}'. - Výraz „{0}“: {1}. - Example: "'value' expression: 'new object()'", where 'value' is the parameter name of an assertion method, and 'new object()' is the expression the user passed to the assert method. - - - '{0}' expression: '{1}', '{2}' expression: '{3}', '{4}' expression: '{5}'. - Výraz „{0}“: {1}, výraz „{2}“: {3}, výraz „{4}“: {5}. - Example: "'substring' expression: 'userCode1', 'value' expression: 'userCode2'", where 'substring' and 'value' are the parameter names of an assertion method, and 'userCode's are the expressions the user passed to the assert method. - - - '{0}' expression: '{1}', '{2}' expression: '{3}'. - Výraz „{0}“: {1}, výraz „{2}“: {3}. - Example: "'minValue' expression: 'userCode1', 'maxValue' expression: 'userCode2', 'value' expression: 'userCode3'", where 'minValue', 'maxValue', and 'value' are the parameter names of an assertion method, and 'userCode's are the expressions the user passed to the assert method. - {0}. {1} {0}. {1} @@ -143,39 +112,44 @@ Řetězec '{0}' neobsahuje řetězec '{1}'. {2}. - - Expected collection to contain the specified item. {0} - Očekávala se kolekce, která bude obsahovat zadanou položku. {0} + + Expected collection to contain the specified item. + Expected collection to contain the specified item. + + + + Expected at least one item to match the predicate. + Expected at least one item to match the predicate. - - Expected at least one item to match the predicate. {0} - Očekávala se alespoň jedna položka odpovídající predikátu. {0} + + Expected collection to contain exactly one item but found {0} item(s). + Expected collection to contain exactly one item but found {0} item(s). - - Expected collection to contain exactly one element but found {1} element(s). {0} - Očekávalo se, že kolekce bude obsahovat přesně jeden prvek, ale našlo se tolik elementů: {1}. {0} + + Expected exactly one item to match the predicate but found {0} item(s). + Expected exactly one item to match the predicate but found {0} item(s). - - Expected exactly one item to match the predicate but found {1} item(s). {0} - Očekávala se přesně jedna položka odpovídající predikátu, ale našlo se tolik položek: {1}. {0} + + String does not contain the expected substring. + String does not contain the expected substring. - - String '{0}' does contain string '{1}'. {2}. - Řetězec {0} obsahuje řetězec {1}. {2}. + + Expected collection to not contain the specified item. + Expected collection to not contain the specified item. - - Expected collection to not contain the specified item. {0} - Očekávalo se, že kolekce nebude obsahovat zadanou položku. {0} + + Expected no items to match the predicate. + Expected no items to match the predicate. - - Expected no items to match the predicate. {0} - Očekávaly se žádné položky, které by odpovídaly predikátu. {0} + + String contains the unexpected substring. + String contains the unexpected substring. @@ -183,11 +157,26 @@ Řetězec „{0}“ končí řetězcem „{1}“. {2} + + String ends with unexpected suffix. + String ends with unexpected suffix. + + + + String matches pattern but should not. + String matches pattern but should not. + + String '{0}' starts with string '{1}'. {2} Řetězec „{0}“ začíná řetězcem „{1}“. {2} + + String starts with unexpected prefix. + String starts with unexpected prefix. + + Dynamic data field '{0}' should be static. Dynamické datové pole {0} by mělo být statické. @@ -237,9 +226,14 @@ Skutečnost: {2} {0} selhalo. {1} - - Expected collection of size {1}. Actual: {2}. {0} - Očekávala se kolekce {1} velikosti. Skutečnost: {2} {0} + + String does not end with expected suffix. + String does not end with expected suffix. + + + + Expected collection to have the specified number of items. + Expected collection to have the specified number of items. @@ -252,9 +246,29 @@ Skutečnost: {2} Neplatná adresa URL lístku GitHubu - - Value '{0}' is not within the expected range [{1}..{2}]. {3} - Hodnota {0} není v očekávaném rozsahu [{1}..{2}]. {3} + + Expected value to be exactly of the specified type. + Expected value to be exactly of the specified type. + + + + Expected condition to be false. + Expected condition to be false. + + + + Expected value to be greater than the specified bound. + Expected value to be greater than the specified bound. + + + + Expected value to be greater than or equal to the specified bound. + Expected value to be greater than or equal to the specified bound. + + + + Value is not within the expected range. + Value is not within the expected range. @@ -262,41 +276,81 @@ Skutečnost: {2} Maximální hodnota musí být větší nebo rovna minimální hodnotě. - - {0} Expected type:<{1}>. Actual type:<{2}>. - {0} Očekávaný typ:<{1}>. Aktuální typ:<{2}>. - + + Expected value to be of the specified type. + Expected value to be of the specified type. + + + + Expected value to be less than the specified bound. + Expected value to be less than the specified bound. + + + + Expected value to be less than or equal to the specified bound. + Expected value to be less than or equal to the specified bound. + String '{0}' does not match pattern '{1}'. {2} Řetězec „{0}“ neodpovídá vzoru „{1}“. {2} - - Expected collection to contain any item but it is empty. {0} - Očekávalo se, že kolekce bude obsahovat libovolnou položku, ale je prázdná. {0} + + Expected a negative value. + Expected a negative value. - - Wrong Type:<{1}>. Actual type:<{2}>. {0} - Špatný typ:<{1}>. Aktuální typ:<{2}>. {0} - + + Expected collection to contain any item but it is empty. + Expected collection to contain any item but it is empty. + - - {0} Expected exact type:<{1}>. Actual type:<{2}>. - {0} Očekávaný přesný typ:<{1}>. Skutečný typ:<{2}>. - + + Value should not be exactly of the specified type. + Value should not be exactly of the specified type. + - - Wrong exact Type:<{1}>. Actual type:<{2}>. {0} - Nesprávný přesný typ:<{1}>. Skutečný typ:<{2}>. {0} - + + Value should not be of the specified type. + Value should not be of the specified type. + String '{0}' matches pattern '{1}'. {2} Řetězec „{0}“ odpovídá vzoru „{1}“. {2} + + Expected a non-null value. + Expected a non-null value. + + + + Expected value to be null. + Expected value to be null. + + + + Expected a positive value. + Expected a positive value. + + + + Expected condition to be true. + Expected condition to be true. + + + + String does not match expected pattern. + String does not match expected pattern. + + + + No exception was thrown. + No exception was thrown. + + The member specified ({0}) could not be found. You might need to regenerate your private accessor, @@ -358,21 +412,16 @@ Skutečnost: {2} (objekt) + + String does not start with expected prefix. + String does not start with expected prefix. + + (Failed to get the message for an exception of type {0} due to an exception.) (Z důvodu výjimky se nepodařilo získat zprávu o výjimce typu {0}.) - - Expected exception type:<{1}> but no exception was thrown. {0} - Byl očekáván typ výjimky: <{1}>, ale nebyla vyvolána žádná výjimka. {0} - - - - Expected exception type:<{1}>. Actual exception type:<{2}>. {0} - Očekávaný typ výjimky: <{1}> Skutečný typ výjimky: <{2}>. {0} - - {0} ({1}) {0} ({1}) @@ -398,36 +447,6 @@ Skutečnost: {2} Vlastnost nebo metoda {0} ve třídě {1} vrací prázdné IEnumerable<object[]>. - - Actual value <{2}> is not greater than expected value <{1}>. {0} - Skutečná hodnota <{2}> není větší než očekávaná hodnota <{1}>. {0} - - - - Actual value <{2}> is not greater than or equal to expected value <{1}>. {0} - Skutečná hodnota <{2}> není větší nebo rovna očekávané hodnotě <{1}>. {0} - - - - Actual value <{2}> is not less than expected value <{1}>. {0} - Skutečná hodnota <{2}> není menší než očekávaná hodnota <{1}>. {0} - - - - Actual value <{2}> is not less than or equal to expected value <{1}>. {0} - Skutečná hodnota <{2}> není menší nebo rovna očekávané hodnotě <{1}>. {0} - - - - Expected value <{1}> to be positive. {0} - Očekávaná hodnota <{1}> má být kladná. {0} - - - - Expected value <{1}> to be negative. {0} - Očekávaná hodnota <{1}> má být záporná. {0} - - Assert.Equals should not be used for Assertions. Please use Assert.AreEqual & overloads instead. Assert.Equals by neměla být pro kontrolní výrazy používána. Použijte prosím místo toho Assert.AreEqual a její přetížení. @@ -458,6 +477,11 @@ Skutečnost: {2} CollectionAssert.ReferenceEquals se nemá používat pro kontrolní výrazy. Místo toho použijte metody CollectionAssert nebo Assert.AreSame & overloads. + + Wrong exception type was thrown. + Wrong exception type was thrown. + + \ No newline at end of file diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.de.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.de.xlf index b240c09df6..9140235903 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.de.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.de.xlf @@ -17,46 +17,20 @@ Doppeltes Element gefunden: <{1}>. {0} - - Expected:<{1}>. Actual:<{2}>. {0} - Erwartet:<{1}>. Tatsächlich:<{2}>. {0} - - - - Expected a difference no greater than <{3}> between expected value <{1}> and actual value <{2}>. {0} - Es wurde eine Differenz nicht größer als <{3}> zwischen dem erwarteten Wert <{1}> und dem tatsächlichen Wert <{2}> erwartet. {0} - - - - Expected:<{1}>. Case is different for actual value:<{2}>. {0} - Erwartet:<{1}>. Die Großschreibung des tatsächlichen Werts weicht davon ab:<{2}>. {0} - - - - Expected:<{1} ({2})>. Actual:<{3} ({4})>. {0} - Erwartet:<{1} ({2})>. Tatsächlich:<{3} ({4})>. {0} - - - - {0}{1} -{2} -{3} -{4} - {0}{1} -{2} -{3} -{4} + + Case differs. + Case differs. - - Expected: - Erwartet: - + + Expected a difference no greater than <{0}>. + Expected a difference no greater than <{0}>. + - - But was: - War aber: - + + Expected values to be equal. + Expected values to be equal. + String lengths are both {0} but differ at index {1}. @@ -68,15 +42,25 @@ Die erwartete Länge der Zeichenfolge ist {0}, war aber {1}. - - Expected any value except:<{1}>. Actual:<{2}>. {0} - Es wurde ein beliebiger Wert erwartet außer:<{1}>. Tatsächlich:<{2}>. {0} - + + Expected a difference greater than <{0}>. + Expected a difference greater than <{0}>. + - - Expected a difference greater than <{3}> between expected value <{1}> and actual value <{2}>. {0} - Es wurde eine Differenz größer als <{3}> zwischen dem erwarteten Wert <{1}> und dem tatsächlichen Wert <{2}> erwartet. {0} - + + Expected values to differ. + Expected values to differ. + + + + Expected references to be different. + Expected references to be different. + + + + Expected references to be the same. + Expected references to be the same. + Do not pass value types to AreSame(). Values converted to Object will never be the same. Consider using AreEqual(). {0} @@ -118,21 +102,6 @@ Beide Sammlungen enthalten dieselben Elemente. {0} - - '{0}' expression: '{1}'. - „{0}“ Ausdruck: „{1}“. - Example: "'value' expression: 'new object()'", where 'value' is the parameter name of an assertion method, and 'new object()' is the expression the user passed to the assert method. - - - '{0}' expression: '{1}', '{2}' expression: '{3}', '{4}' expression: '{5}'. - „{0}“ Ausdruck: „{1}“, „{2}“ Ausdruck: „{3}“, „{4}“ Ausdruck: „{5}“. - Example: "'substring' expression: 'userCode1', 'value' expression: 'userCode2'", where 'substring' and 'value' are the parameter names of an assertion method, and 'userCode's are the expressions the user passed to the assert method. - - - '{0}' expression: '{1}', '{2}' expression: '{3}'. - „{0}“ Ausdruck: „{1}“, „{2}“ Ausdruck: „{3}“. - Example: "'minValue' expression: 'userCode1', 'maxValue' expression: 'userCode2', 'value' expression: 'userCode3'", where 'minValue', 'maxValue', and 'value' are the parameter names of an assertion method, and 'userCode's are the expressions the user passed to the assert method. - {0}. {1} {0}. {1} @@ -143,39 +112,44 @@ Die Zeichenfolge "{0}" enthält nicht die Zeichenfolge "{1}". {2}. - - Expected collection to contain the specified item. {0} - Es wurde erwartet, dass die Sammlung das angegebene Element enthält. {0} + + Expected collection to contain the specified item. + Expected collection to contain the specified item. + + + + Expected at least one item to match the predicate. + Expected at least one item to match the predicate. - - Expected at least one item to match the predicate. {0} - Es wurde erwartet, dass mindestens ein Element mit dem Prädikat übereinstimmt. {0} + + Expected collection to contain exactly one item but found {0} item(s). + Expected collection to contain exactly one item but found {0} item(s). - - Expected collection to contain exactly one element but found {1} element(s). {0} - Es wurde erwartet, dass die Sammlung genau ein Element enthält, es wurden jedoch {1} gefunden. {0} + + Expected exactly one item to match the predicate but found {0} item(s). + Expected exactly one item to match the predicate but found {0} item(s). - - Expected exactly one item to match the predicate but found {1} item(s). {0} - Es wurde erwartet, dass genau ein Element mit dem Prädikat übereinstimmt, es wurden jedoch {1} Element(e) gefunden. {0} + + String does not contain the expected substring. + String does not contain the expected substring. - - String '{0}' does contain string '{1}'. {2}. - Die Zeichenfolge „{0}“ enthält die Zeichenfolge „{1}“. {2}. + + Expected collection to not contain the specified item. + Expected collection to not contain the specified item. - - Expected collection to not contain the specified item. {0} - Es wurde erwartet, dass die Sammlung das angegebene Element nicht enthält. {0} + + Expected no items to match the predicate. + Expected no items to match the predicate. - - Expected no items to match the predicate. {0} - Es wurden erwartet, dass keine Elemente mit dem Prädikat übereinstimmen. {0} + + String contains the unexpected substring. + String contains the unexpected substring. @@ -183,11 +157,26 @@ Die Zeichenfolge „{0}“ endet mit der Zeichenfolge „{1}“. {2} + + String ends with unexpected suffix. + String ends with unexpected suffix. + + + + String matches pattern but should not. + String matches pattern but should not. + + String '{0}' starts with string '{1}'. {2} Die Zeichenfolge „{0}“ beginnt mit der Zeichenfolge „{1}“. {2} + + String starts with unexpected prefix. + String starts with unexpected prefix. + + Dynamic data field '{0}' should be static. Das dynamische Datenfeld „{0}“ sollte statisch sein. @@ -237,9 +226,14 @@ Tatsächlich: {2} Fehler bei "{0}". {1} - - Expected collection of size {1}. Actual: {2}. {0} - Es wurde eine Sammlung mit einer Größe {1} erwartet. Tatsächlich: {2}. {0} + + String does not end with expected suffix. + String does not end with expected suffix. + + + + Expected collection to have the specified number of items. + Expected collection to have the specified number of items. @@ -252,9 +246,29 @@ Tatsächlich: {2} Ungültige GitHub-Ticket-URL. - - Value '{0}' is not within the expected range [{1}..{2}]. {3} - Der Wert „{0}“ liegt nicht im erwarteten Bereich [{1}..{2}]. {3} + + Expected value to be exactly of the specified type. + Expected value to be exactly of the specified type. + + + + Expected condition to be false. + Expected condition to be false. + + + + Expected value to be greater than the specified bound. + Expected value to be greater than the specified bound. + + + + Expected value to be greater than or equal to the specified bound. + Expected value to be greater than or equal to the specified bound. + + + + Value is not within the expected range. + Value is not within the expected range. @@ -262,41 +276,81 @@ Tatsächlich: {2} Der Höchstwert muss größer oder gleich dem Mindestwert sein. - - {0} Expected type:<{1}>. Actual type:<{2}>. - {0}Erwarteter Typ:<{1}>. Tatsächlicher Typ:<{2}>. - + + Expected value to be of the specified type. + Expected value to be of the specified type. + + + + Expected value to be less than the specified bound. + Expected value to be less than the specified bound. + + + + Expected value to be less than or equal to the specified bound. + Expected value to be less than or equal to the specified bound. + String '{0}' does not match pattern '{1}'. {2} Die Zeichenfolge „{0}“ stimmt nicht mit dem Muster „{1}“ überein. {2} - - Expected collection to contain any item but it is empty. {0} - Es wurde erwartet, dass die Sammlung ein beliebiges Element enthält, aber leer ist. {0} + + Expected a negative value. + Expected a negative value. - - Wrong Type:<{1}>. Actual type:<{2}>. {0} - Falscher Typ:<{1}>. Tatsächlicher Typ:<{2}>. {0} - + + Expected collection to contain any item but it is empty. + Expected collection to contain any item but it is empty. + - - {0} Expected exact type:<{1}>. Actual type:<{2}>. - {0} Erwarteter genauer Typ:<{1}>. Tatsächlicher Typ:<{2}>. - + + Value should not be exactly of the specified type. + Value should not be exactly of the specified type. + - - Wrong exact Type:<{1}>. Actual type:<{2}>. {0} - Falscher genauer Typ:<{1}>. Tatsächlicher Typ:<{2}>. {0} - + + Value should not be of the specified type. + Value should not be of the specified type. + String '{0}' matches pattern '{1}'. {2} Die Zeichenfolge „{0}“ stimmt mit dem Muster „{1}“ überein. {2} + + Expected a non-null value. + Expected a non-null value. + + + + Expected value to be null. + Expected value to be null. + + + + Expected a positive value. + Expected a positive value. + + + + Expected condition to be true. + Expected condition to be true. + + + + String does not match expected pattern. + String does not match expected pattern. + + + + No exception was thrown. + No exception was thrown. + + The member specified ({0}) could not be found. You might need to regenerate your private accessor, @@ -358,21 +412,16 @@ Tatsächlich: {2} (Objekt) + + String does not start with expected prefix. + String does not start with expected prefix. + + (Failed to get the message for an exception of type {0} due to an exception.) (Fehler beim Abrufen der Meldung für eine Ausnahme vom Typ "{0}" aufgrund einer Ausnahme.) - - Expected exception type:<{1}> but no exception was thrown. {0} - Erwarteter Ausnahmetyp:<{1}>, aber es wurde keine Ausnahme ausgelöst. {0} - - - - Expected exception type:<{1}>. Actual exception type:<{2}>. {0} - Erwarteter Ausnahmetyp:<{1}>. Tatsächlicher Ausnahmetyp:<{2}>. {0} - - {0} ({1}) {0} ({1}) @@ -398,36 +447,6 @@ Tatsächlich: {2} Eigenschaft oder Methode "{0}" in "{1}" gibt leeres IEnumerable<object[]> zurück. - - Actual value <{2}> is not greater than expected value <{1}>. {0} - Der tatsächliche Wert <{2}> ist nicht größer als der erwartete Wert <{1}>. {0} - - - - Actual value <{2}> is not greater than or equal to expected value <{1}>. {0} - Der tatsächliche Wert <{2}> ist nicht größer oder gleich dem erwarteten Wert <{1}>. {0} - - - - Actual value <{2}> is not less than expected value <{1}>. {0} - Der tatsächliche Wert <{2}> ist nicht kleiner als der erwartete Wert <{1}>. {0} - - - - Actual value <{2}> is not less than or equal to expected value <{1}>. {0} - Der tatsächliche Wert <{2}> ist nicht kleiner oder gleich dem erwarteten Wert <{1}>. {0} - - - - Expected value <{1}> to be positive. {0} - Es wurde erwartet, dass der Wert <{1}> positiv ist. {0} - - - - Expected value <{1}> to be negative. {0} - Es wurde erwartet, dass der Wert <{1}> negativ ist. {0} - - Assert.Equals should not be used for Assertions. Please use Assert.AreEqual & overloads instead. Assert.Equals sollte nicht für Assertions verwendet werden. Verwenden Sie stattdessen Assert.AreEqual und Überladungen. @@ -458,6 +477,11 @@ Tatsächlich: {2} CollectionAssert.ReferenceEquals darf nicht für Assertions verwendet werden. Verwenden Sie stattdessen CollectionAssert-Methoden oder Assert.AreSame und Überladungen. + + Wrong exception type was thrown. + Wrong exception type was thrown. + + \ No newline at end of file diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.es.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.es.xlf index 427b030537..6416d88204 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.es.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.es.xlf @@ -17,46 +17,20 @@ Se encontró un elemento duplicado:<{1}>. {0} - - Expected:<{1}>. Actual:<{2}>. {0} - Se esperaba <{1}>, pero es <{2}>. {0} - - - - Expected a difference no greater than <{3}> between expected value <{1}> and actual value <{2}>. {0} - Se esperaba una diferencia no superior a <{3}> entre el valor esperado <{1}> y el valor actual <{2}>. {0} - - - - Expected:<{1}>. Case is different for actual value:<{2}>. {0} - Se esperaba:<{1}>. La caja es diferente para el valor actual:<{2}>. {0} - - - - Expected:<{1} ({2})>. Actual:<{3} ({4})>. {0} - Se esperaba:<{1} ({2})>, pero es:<{3} ({4})>. {0} - - - - {0}{1} -{2} -{3} -{4} - {0}{1} -{2} -{3} -{4} + + Case differs. + Case differs. - - Expected: - Se esperaba: - + + Expected a difference no greater than <{0}>. + Expected a difference no greater than <{0}>. + - - But was: - Pero fue: - + + Expected values to be equal. + Expected values to be equal. + String lengths are both {0} but differ at index {1}. @@ -68,15 +42,25 @@ Se esperaba una longitud de cadena {0} pero fue {1}. - - Expected any value except:<{1}>. Actual:<{2}>. {0} - Se esperaba cualquier valor excepto <{1}>, pero es <{2}>. {0} - + + Expected a difference greater than <{0}>. + Expected a difference greater than <{0}>. + - - Expected a difference greater than <{3}> between expected value <{1}> and actual value <{2}>. {0} - Se esperaba una diferencia mayor que <{3}> entre el valor esperado <{1}> y el valor actual <{2}>. {0} - + + Expected values to differ. + Expected values to differ. + + + + Expected references to be different. + Expected references to be different. + + + + Expected references to be the same. + Expected references to be the same. + Do not pass value types to AreSame(). Values converted to Object will never be the same. Consider using AreEqual(). {0} @@ -118,21 +102,6 @@ Ambas colecciones tienen los mismos elementos. {0} - - '{0}' expression: '{1}'. - Expresión "{0}": "{1}". - Example: "'value' expression: 'new object()'", where 'value' is the parameter name of an assertion method, and 'new object()' is the expression the user passed to the assert method. - - - '{0}' expression: '{1}', '{2}' expression: '{3}', '{4}' expression: '{5}'. - Expresión "{0}": "{1}", expresión "{2}": "{3}", expresión "{4}": "{5}". - Example: "'substring' expression: 'userCode1', 'value' expression: 'userCode2'", where 'substring' and 'value' are the parameter names of an assertion method, and 'userCode's are the expressions the user passed to the assert method. - - - '{0}' expression: '{1}', '{2}' expression: '{3}'. - Expresión "{0}": "{1}", expresión "{2}": "{3}". - Example: "'minValue' expression: 'userCode1', 'maxValue' expression: 'userCode2', 'value' expression: 'userCode3'", where 'minValue', 'maxValue', and 'value' are the parameter names of an assertion method, and 'userCode's are the expressions the user passed to the assert method. - {0}. {1} {0}. {1} @@ -143,39 +112,44 @@ La cadena '{0}' no contiene la cadena '{1}'. {2}. - - Expected collection to contain the specified item. {0} - Se esperaba que la colección contuviera el elemento especificado. {0} + + Expected collection to contain the specified item. + Expected collection to contain the specified item. + + + + Expected at least one item to match the predicate. + Expected at least one item to match the predicate. - - Expected at least one item to match the predicate. {0} - Se esperaba al menos un elemento para que coincida con el predicado. {0} + + Expected collection to contain exactly one item but found {0} item(s). + Expected collection to contain exactly one item but found {0} item(s). - - Expected collection to contain exactly one element but found {1} element(s). {0} - Se esperaba que la colección contuviera exactamente un elemento, pero se encontraron {1} elementos. {0} + + Expected exactly one item to match the predicate but found {0} item(s). + Expected exactly one item to match the predicate but found {0} item(s). - - Expected exactly one item to match the predicate but found {1} item(s). {0} - Se esperaba exactamente un elemento para que coincida con el predicado, pero se encontraron {1} elementos. {0} + + String does not contain the expected substring. + String does not contain the expected substring. - - String '{0}' does contain string '{1}'. {2}. - La cadena '{0}' contiene la cadena '{1}'. {2}. + + Expected collection to not contain the specified item. + Expected collection to not contain the specified item. - - Expected collection to not contain the specified item. {0} - Se esperaba que la colección no contenga el elemento especificado. {0} + + Expected no items to match the predicate. + Expected no items to match the predicate. - - Expected no items to match the predicate. {0} - No se esperaba que ningún elemento coincidía con el predicado. {0} + + String contains the unexpected substring. + String contains the unexpected substring. @@ -183,11 +157,26 @@ La cadena "{0}" termina con la cadena "{1}". {2} + + String ends with unexpected suffix. + String ends with unexpected suffix. + + + + String matches pattern but should not. + String matches pattern but should not. + + String '{0}' starts with string '{1}'. {2} La cadena "{0}" comienza con la cadena "{1}". {2} + + String starts with unexpected prefix. + String starts with unexpected prefix. + + Dynamic data field '{0}' should be static. El campo de datos dinámico '{0}' debe ser estático. @@ -237,9 +226,14 @@ Real: {2} Error de {0}. {1} - - Expected collection of size {1}. Actual: {2}. {0} - Se esperaba una colección de tamaño {1}. Real: {2}. {0} + + String does not end with expected suffix. + String does not end with expected suffix. + + + + Expected collection to have the specified number of items. + Expected collection to have the specified number of items. @@ -252,9 +246,29 @@ Real: {2} Dirección URL de vale de GitHub no válida - - Value '{0}' is not within the expected range [{1}..{2}]. {3} - El valor "{0}" no está dentro del rango esperado [{1}..{2}]. {3} + + Expected value to be exactly of the specified type. + Expected value to be exactly of the specified type. + + + + Expected condition to be false. + Expected condition to be false. + + + + Expected value to be greater than the specified bound. + Expected value to be greater than the specified bound. + + + + Expected value to be greater than or equal to the specified bound. + Expected value to be greater than or equal to the specified bound. + + + + Value is not within the expected range. + Value is not within the expected range. @@ -262,41 +276,81 @@ Real: {2} El valor máximo debe ser igual o mayor que el valor mínimo. - - {0} Expected type:<{1}>. Actual type:<{2}>. - {0} Tipo esperado:<{1}>. Tipo real:<{2}>. - + + Expected value to be of the specified type. + Expected value to be of the specified type. + + + + Expected value to be less than the specified bound. + Expected value to be less than the specified bound. + + + + Expected value to be less than or equal to the specified bound. + Expected value to be less than or equal to the specified bound. + String '{0}' does not match pattern '{1}'. {2} La cadena "{0}" no coincide con el patrón "{1}". {2} - - Expected collection to contain any item but it is empty. {0} - Se esperaba que la colección contenga cualquier elemento, pero está vacía. {0} + + Expected a negative value. + Expected a negative value. - - Wrong Type:<{1}>. Actual type:<{2}>. {0} - Tipo incorrecto:<{1}>. Tipo actual:<{2}>. {0} - + + Expected collection to contain any item but it is empty. + Expected collection to contain any item but it is empty. + - - {0} Expected exact type:<{1}>. Actual type:<{2}>. - {0} Tipo exacto esperado: <{1}>. Tipo real:<{2}>. - + + Value should not be exactly of the specified type. + Value should not be exactly of the specified type. + - - Wrong exact Type:<{1}>. Actual type:<{2}>. {0} - Tipo exacto incorrecto: <{1}>. Tipo actual:<{2}>. {0} - + + Value should not be of the specified type. + Value should not be of the specified type. + String '{0}' matches pattern '{1}'. {2} La cadena "{0}" coincide con el patrón "{1}". {2} + + Expected a non-null value. + Expected a non-null value. + + + + Expected value to be null. + Expected value to be null. + + + + Expected a positive value. + Expected a positive value. + + + + Expected condition to be true. + Expected condition to be true. + + + + String does not match expected pattern. + String does not match expected pattern. + + + + No exception was thrown. + No exception was thrown. + + The member specified ({0}) could not be found. You might need to regenerate your private accessor, @@ -358,21 +412,16 @@ Real: {2} (objeto) + + String does not start with expected prefix. + String does not start with expected prefix. + + (Failed to get the message for an exception of type {0} due to an exception.) (No se pudo obtener el mensaje para una excepción del tipo {0} debido a una excepción.) - - Expected exception type:<{1}> but no exception was thrown. {0} - Tipo de excepción esperada:<{1}> pero no se lanzó ninguna excepción. {0} - - - - Expected exception type:<{1}>. Actual exception type:<{2}>. {0} - Tipo de excepción esperada:<{1}>. Tipo de excepción actual: <{2}>. {0} - - {0} ({1}) {0} ({1}) @@ -398,36 +447,6 @@ Real: {2} La propiedad o el método {0} en {1} devuelve un elemento IEnumerable<object[]> vacío. - - Actual value <{2}> is not greater than expected value <{1}>. {0} - El valor real <{2}> no es mayor que el valor esperado <{1}>. {0} - - - - Actual value <{2}> is not greater than or equal to expected value <{1}>. {0} - El valor real <{2}> no es mayor o igual que el valor esperado <{1}>. {0} - - - - Actual value <{2}> is not less than expected value <{1}>. {0} - El valor real <{2}> no es menor que el valor esperado <{1}>. {0} - - - - Actual value <{2}> is not less than or equal to expected value <{1}>. {0} - El valor real <{2}> no es menor o igual que el valor esperado <{1}>. {0} - - - - Expected value <{1}> to be positive. {0} - Se esperaba que el valor <{1}> ser positivo. {0} - - - - Expected value <{1}> to be negative. {0} - Se esperaba que el valor <{1}> ser negativo. {0} - - Assert.Equals should not be used for Assertions. Please use Assert.AreEqual & overloads instead. No se debe usar Assert.Equals para aserciones. Use Assert.AreEqual y Overloads en su lugar. @@ -458,6 +477,11 @@ Real: {2} CollectionAssert.ReferenceEquals no se debe usar para las aserciones. Use los métodos CollectionAssert o las sobrecargas Assert.AreSame & en su lugar. + + Wrong exception type was thrown. + Wrong exception type was thrown. + + \ No newline at end of file diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.fr.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.fr.xlf index 0e46d1985a..dd1f2d262e 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.fr.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.fr.xlf @@ -17,46 +17,20 @@ Un élément dupliqué a été trouvé : <{1}>. {0} - - Expected:<{1}>. Actual:<{2}>. {0} - Attendu : <{1}>, Réel : <{2}>. {0} - - - - Expected a difference no greater than <{3}> between expected value <{1}> and actual value <{2}>. {0} - Différence attendue non supérieure à <{3}> comprise entre la valeur attendue <{1}> et la valeur réelle <{2}>. {0} - - - - Expected:<{1}>. Case is different for actual value:<{2}>. {0} - Attendu :<{1}>. La casse est différente pour la valeur réelle :<{2}>. {0} - - - - Expected:<{1} ({2})>. Actual:<{3} ({4})>. {0} - Attendu : <{1} ({2})>, Réel : <{3} ({4})>. {0} - - - - {0}{1} -{2} -{3} -{4} - {0}{1} -{2} -{3} -{4} + + Case differs. + Case differs. - - Expected: - Attendu : - + + Expected a difference no greater than <{0}>. + Expected a difference no greater than <{0}>. + - - But was: - Mais c'était : - + + Expected values to be equal. + Expected values to be equal. + String lengths are both {0} but differ at index {1}. @@ -68,15 +42,25 @@ La longueur de chaîne attendue {0} mais était {1}. - - Expected any value except:<{1}>. Actual:<{2}>. {0} - Toute valeur attendue sauf :<{1}>. Réel :<{2}>. {0} - + + Expected a difference greater than <{0}>. + Expected a difference greater than <{0}>. + - - Expected a difference greater than <{3}> between expected value <{1}> and actual value <{2}>. {0} - Différence attendue supérieure à <{3}> comprise entre la valeur attendue <{1}> et la valeur réelle <{2}>. {0} - + + Expected values to differ. + Expected values to differ. + + + + Expected references to be different. + Expected references to be different. + + + + Expected references to be the same. + Expected references to be the same. + Do not pass value types to AreSame(). Values converted to Object will never be the same. Consider using AreEqual(). {0} @@ -118,21 +102,6 @@ Les deux collections contiennent les mêmes éléments. {0} - - '{0}' expression: '{1}'. - « {0} » expression : « {1} ». - Example: "'value' expression: 'new object()'", where 'value' is the parameter name of an assertion method, and 'new object()' is the expression the user passed to the assert method. - - - '{0}' expression: '{1}', '{2}' expression: '{3}', '{4}' expression: '{5}'. - expression « {0} », « {1} », expression « {2} », « {3} », expression « {4} », « {5} ». - Example: "'substring' expression: 'userCode1', 'value' expression: 'userCode2'", where 'substring' and 'value' are the parameter names of an assertion method, and 'userCode's are the expressions the user passed to the assert method. - - - '{0}' expression: '{1}', '{2}' expression: '{3}'. - expression « {0} » : « {1} », expression « {2} » : « {3} ». - Example: "'minValue' expression: 'userCode1', 'maxValue' expression: 'userCode2', 'value' expression: 'userCode3'", where 'minValue', 'maxValue', and 'value' are the parameter names of an assertion method, and 'userCode's are the expressions the user passed to the assert method. - {0}. {1} {0}. {1} @@ -143,39 +112,44 @@ La chaîne '{0}' ne contient pas la chaîne '{1}'. {2}. - - Expected collection to contain the specified item. {0} - Collection attendue pour contenir l’élément spécifié. {0} + + Expected collection to contain the specified item. + Expected collection to contain the specified item. + + + + Expected at least one item to match the predicate. + Expected at least one item to match the predicate. - - Expected at least one item to match the predicate. {0} - Au moins un élément doit correspondre au prédicat. {0} + + Expected collection to contain exactly one item but found {0} item(s). + Expected collection to contain exactly one item but found {0} item(s). - - Expected collection to contain exactly one element but found {1} element(s). {0} - Collection attendue pour contenir exactement un élément mais {1} élément(s) trouvé(s). {0} + + Expected exactly one item to match the predicate but found {0} item(s). + Expected exactly one item to match the predicate but found {0} item(s). - - Expected exactly one item to match the predicate but found {1} item(s). {0} - Un seul élément était attendu pour correspondre au prédicat, mais {1} élément(s) trouvé(s). {0} + + String does not contain the expected substring. + String does not contain the expected substring. - - String '{0}' does contain string '{1}'. {2}. - La chaîne « {0} » contient la chaîne « {1} ». {2}. + + Expected collection to not contain the specified item. + Expected collection to not contain the specified item. - - Expected collection to not contain the specified item. {0} - Collection attendue pour ne pas contenir l’élément spécifié. {0} + + Expected no items to match the predicate. + Expected no items to match the predicate. - - Expected no items to match the predicate. {0} - Aucun élément ne doit correspondre au prédicat. {0} + + String contains the unexpected substring. + String contains the unexpected substring. @@ -183,11 +157,26 @@ La chaîne '{0}' se termine par la chaîne '{1}'. {2} + + String ends with unexpected suffix. + String ends with unexpected suffix. + + + + String matches pattern but should not. + String matches pattern but should not. + + String '{0}' starts with string '{1}'. {2} La chaîne '{0}' commence par la chaîne '{1}'. {2} + + String starts with unexpected prefix. + String starts with unexpected prefix. + + Dynamic data field '{0}' should be static. Le champ de données dynamiques « {0} » doit être statique. @@ -237,9 +226,14 @@ Réel : {2} Échec de {0}. {1} - - Expected collection of size {1}. Actual: {2}. {0} - Collection de tailles attendue {1}. Réel : {2}. {0} + + String does not end with expected suffix. + String does not end with expected suffix. + + + + Expected collection to have the specified number of items. + Expected collection to have the specified number of items. @@ -252,9 +246,29 @@ Réel : {2} URL de ticket GitHub non valide - - Value '{0}' is not within the expected range [{1}..{2}]. {3} - La valeur « {0} » n'est pas dans la plage attendue [{1}..{2}]. {3} + + Expected value to be exactly of the specified type. + Expected value to be exactly of the specified type. + + + + Expected condition to be false. + Expected condition to be false. + + + + Expected value to be greater than the specified bound. + Expected value to be greater than the specified bound. + + + + Expected value to be greater than or equal to the specified bound. + Expected value to be greater than or equal to the specified bound. + + + + Value is not within the expected range. + Value is not within the expected range. @@ -262,41 +276,81 @@ Réel : {2} La valeur maximale doit être supérieure ou égale à la valeur minimale. - - {0} Expected type:<{1}>. Actual type:<{2}>. - {0}Type attendu :<{1}>. Type réel :<{2}>. - + + Expected value to be of the specified type. + Expected value to be of the specified type. + + + + Expected value to be less than the specified bound. + Expected value to be less than the specified bound. + + + + Expected value to be less than or equal to the specified bound. + Expected value to be less than or equal to the specified bound. + String '{0}' does not match pattern '{1}'. {2} La chaîne '{0}' ne correspond pas au modèle '{1}'. {2} - - Expected collection to contain any item but it is empty. {0} - La collection doit contenir n’importe quel élément, mais elle est vide. {0} + + Expected a negative value. + Expected a negative value. - - Wrong Type:<{1}>. Actual type:<{2}>. {0} - Type incorrect : <{1}>, Type réel : <{2}>. {0} - + + Expected collection to contain any item but it is empty. + Expected collection to contain any item but it is empty. + - - {0} Expected exact type:<{1}>. Actual type:<{2}>. - {0} Type exact attendu :<{1}>. Type réel :<{2}>. - + + Value should not be exactly of the specified type. + Value should not be exactly of the specified type. + - - Wrong exact Type:<{1}>. Actual type:<{2}>. {0} - Type exact incorrect :<{1}>. Type réel :<{2}>. {0} - + + Value should not be of the specified type. + Value should not be of the specified type. + String '{0}' matches pattern '{1}'. {2} La chaîne '{0}' correspond au modèle '{1}'. {2} + + Expected a non-null value. + Expected a non-null value. + + + + Expected value to be null. + Expected value to be null. + + + + Expected a positive value. + Expected a positive value. + + + + Expected condition to be true. + Expected condition to be true. + + + + String does not match expected pattern. + String does not match expected pattern. + + + + No exception was thrown. + No exception was thrown. + + The member specified ({0}) could not be found. You might need to regenerate your private accessor, @@ -358,21 +412,16 @@ Réel : {2} (objet) + + String does not start with expected prefix. + String does not start with expected prefix. + + (Failed to get the message for an exception of type {0} due to an exception.) (Échec de la réception du message pour une exception de type {0} en raison d'une exception.) - - Expected exception type:<{1}> but no exception was thrown. {0} - Type d’exception attendu :<{1}> mais aucune exception n’a été levée. {0} - - - - Expected exception type:<{1}>. Actual exception type:<{2}>. {0} - Type d’exception attendu :<{1}>. Type d’exception réel :<{2}>. {0} - - {0} ({1}) {0} ({1}) @@ -398,36 +447,6 @@ Réel : {2} La propriété ou la méthode {0} sur {1} retourne un IEnumerable<object[]> vide. - - Actual value <{2}> is not greater than expected value <{1}>. {0} - La valeur réelle <{2}> n’est pas supérieure à la valeur attendue <{1}>. {0} - - - - Actual value <{2}> is not greater than or equal to expected value <{1}>. {0} - La valeur réelle <{2}> n’est pas supérieure ou égale à la valeur attendue <{1}>. {0} - - - - Actual value <{2}> is not less than expected value <{1}>. {0} - La valeur réelle <{2}> n’est pas inférieure à la valeur attendue <{1}>. {0} - - - - Actual value <{2}> is not less than or equal to expected value <{1}>. {0} - La valeur réelle <{2}> n’est pas inférieure ou égale à la valeur attendue <{1}>. {0} - - - - Expected value <{1}> to be positive. {0} - La valeur attendue <{1}> doit être positive. {0} - - - - Expected value <{1}> to be negative. {0} - La valeur attendue <{1}> doit être négative. {0} - - Assert.Equals should not be used for Assertions. Please use Assert.AreEqual & overloads instead. Assert.Equals ne doit pas être utilisé pour les assertions. Utilisez Assert.AreEqual & overloads à la place. @@ -458,6 +477,11 @@ Réel : {2} CollectionAssert.ReferenceEquals ne doit pas être utilisé pour les assertions. Utilisez plutôt les méthodes CollectionAssert ou Assert.AreSame & overloads. + + Wrong exception type was thrown. + Wrong exception type was thrown. + + \ No newline at end of file diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.it.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.it.xlf index bfdc4c7ee6..68900310c3 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.it.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.it.xlf @@ -17,46 +17,20 @@ Rilevato elemento duplicato:<{1}>. {0} - - Expected:<{1}>. Actual:<{2}>. {0} - Previsto:<{1}>. Effettivo:<{2}>. {0} - - - - Expected a difference no greater than <{3}> between expected value <{1}> and actual value <{2}>. {0} - Prevista una differenza non maggiore di <{3}> tra il valore previsto <{1}> e il valore effettivo <{2}>. {0} - - - - Expected:<{1}>. Case is different for actual value:<{2}>. {0} - Previsto:<{1}>. La combinazione di maiuscole e minuscole è diversa per il valore effettivo:<{2}>. {0} - - - - Expected:<{1} ({2})>. Actual:<{3} ({4})>. {0} - Previsto:<{1} ({2})>. Effettivo:<{3} ({4})>. {0} - - - - {0}{1} -{2} -{3} -{4} - {0}{1} -{2} -{3} -{4} + + Case differs. + Case differs. - - Expected: - Previsto: - + + Expected a difference no greater than <{0}>. + Expected a difference no greater than <{0}>. + - - But was: - Ma era: - + + Expected values to be equal. + Expected values to be equal. + String lengths are both {0} but differ at index {1}. @@ -68,15 +42,25 @@ La lunghezza della stringa prevista è {0} ma era {1}. - - Expected any value except:<{1}>. Actual:<{2}>. {0} - Previsto qualsiasi valore tranne:<{1}>. Effettivo:<{2}>. {0} - + + Expected a difference greater than <{0}>. + Expected a difference greater than <{0}>. + - - Expected a difference greater than <{3}> between expected value <{1}> and actual value <{2}>. {0} - Prevista una differenza maggiore di <{3}> tra il valore previsto <{1}> e il valore effettivo <{2}>. {0} - + + Expected values to differ. + Expected values to differ. + + + + Expected references to be different. + Expected references to be different. + + + + Expected references to be the same. + Expected references to be the same. + Do not pass value types to AreSame(). Values converted to Object will never be the same. Consider using AreEqual(). {0} @@ -118,21 +102,6 @@ Le raccolte contengono entrambe gli stessi elementi. {0} - - '{0}' expression: '{1}'. - Espressione '{0}': '{1}'. - Example: "'value' expression: 'new object()'", where 'value' is the parameter name of an assertion method, and 'new object()' is the expression the user passed to the assert method. - - - '{0}' expression: '{1}', '{2}' expression: '{3}', '{4}' expression: '{5}'. - Espressione '{0}': '{1}', espressione '{2}': '{3}', espressione '{4}': '{5}'. - Example: "'substring' expression: 'userCode1', 'value' expression: 'userCode2'", where 'substring' and 'value' are the parameter names of an assertion method, and 'userCode's are the expressions the user passed to the assert method. - - - '{0}' expression: '{1}', '{2}' expression: '{3}'. - Espressione '{0}': '{1}', espressione '{2}': '{3}'. - Example: "'minValue' expression: 'userCode1', 'maxValue' expression: 'userCode2', 'value' expression: 'userCode3'", where 'minValue', 'maxValue', and 'value' are the parameter names of an assertion method, and 'userCode's are the expressions the user passed to the assert method. - {0}. {1} {0}. {1} @@ -143,39 +112,44 @@ La stringa '{0}' non contiene la stringa '{1}'. {2}. - - Expected collection to contain the specified item. {0} - La raccolta dovrebbe contenere l'elemento specificato. {0} + + Expected collection to contain the specified item. + Expected collection to contain the specified item. + + + + Expected at least one item to match the predicate. + Expected at least one item to match the predicate. - - Expected at least one item to match the predicate. {0} - Almeno un elemento dovrebbe corrispondere al predicato. {0} + + Expected collection to contain exactly one item but found {0} item(s). + Expected collection to contain exactly one item but found {0} item(s). - - Expected collection to contain exactly one element but found {1} element(s). {0} - La raccolta dovrebbe contenere un unico elemento, ma ne sono stati trovati {1}. {0} + + Expected exactly one item to match the predicate but found {0} item(s). + Expected exactly one item to match the predicate but found {0} item(s). - - Expected exactly one item to match the predicate but found {1} item(s). {0} - Un unico elemento dovrebbe corrispondere al predicato, ma ne sono stati trovati {1}. {0} + + String does not contain the expected substring. + String does not contain the expected substring. - - String '{0}' does contain string '{1}'. {2}. - La stringa '{0}' contiene la stringa '{1}'. {2}. + + Expected collection to not contain the specified item. + Expected collection to not contain the specified item. - - Expected collection to not contain the specified item. {0} - La raccolta non dovrebbe contenere l'elemento specificato. {0} + + Expected no items to match the predicate. + Expected no items to match the predicate. - - Expected no items to match the predicate. {0} - Nessun elemento dovrebbe corrispondere al predicato. {0} + + String contains the unexpected substring. + String contains the unexpected substring. @@ -183,11 +157,26 @@ La stringa '{0}' termina con la stringa '{1}'. {2} + + String ends with unexpected suffix. + String ends with unexpected suffix. + + + + String matches pattern but should not. + String matches pattern but should not. + + String '{0}' starts with string '{1}'. {2} La stringa '{0}' inizia con la stringa '{1}'. {2} + + String starts with unexpected prefix. + String starts with unexpected prefix. + + Dynamic data field '{0}' should be static. Il campo dati dinamico '{0}' deve essere statico. @@ -237,9 +226,14 @@ Effettivo: {2} {0} non riuscita. {1} - - Expected collection of size {1}. Actual: {2}. {0} - Prevista raccolta di dimensioni {1}. Effettivo: {2}. {0} + + String does not end with expected suffix. + String does not end with expected suffix. + + + + Expected collection to have the specified number of items. + Expected collection to have the specified number of items. @@ -252,9 +246,29 @@ Effettivo: {2} L'URL del ticket GitHub non è valido - - Value '{0}' is not within the expected range [{1}..{2}]. {3} - Il valore '{0}' non è compreso nell'intervallo previsto [{1}, {2}]. {3} + + Expected value to be exactly of the specified type. + Expected value to be exactly of the specified type. + + + + Expected condition to be false. + Expected condition to be false. + + + + Expected value to be greater than the specified bound. + Expected value to be greater than the specified bound. + + + + Expected value to be greater than or equal to the specified bound. + Expected value to be greater than or equal to the specified bound. + + + + Value is not within the expected range. + Value is not within the expected range. @@ -262,41 +276,81 @@ Effettivo: {2} Il valore massimo deve essere maggiore o uguale al valore minimo. - - {0} Expected type:<{1}>. Actual type:<{2}>. - {0} Tipo previsto:<{1}>. Tipo effettivo:<{2}>. - + + Expected value to be of the specified type. + Expected value to be of the specified type. + + + + Expected value to be less than the specified bound. + Expected value to be less than the specified bound. + + + + Expected value to be less than or equal to the specified bound. + Expected value to be less than or equal to the specified bound. + String '{0}' does not match pattern '{1}'. {2} La stringa '{0}' non corrisponde al criterio '{1}'. {2} - - Expected collection to contain any item but it is empty. {0} - È previsto che la raccolta contenga qualsiasi elemento, ma è vuota. {0} + + Expected a negative value. + Expected a negative value. - - Wrong Type:<{1}>. Actual type:<{2}>. {0} - Tipo errato:<{1}>. Tipo effettivo:<{2}>. {0} - + + Expected collection to contain any item but it is empty. + Expected collection to contain any item but it is empty. + - - {0} Expected exact type:<{1}>. Actual type:<{2}>. - {0} Tipo esatto previsto:<{1}>. Tipo effettivo:<{2}>. - + + Value should not be exactly of the specified type. + Value should not be exactly of the specified type. + - - Wrong exact Type:<{1}>. Actual type:<{2}>. {0} - Tipo esatto errato:<{1}>. Tipo effettivo:<{2}>. {0} - + + Value should not be of the specified type. + Value should not be of the specified type. + String '{0}' matches pattern '{1}'. {2} La stringa '{0}' corrisponde al criterio '{1}'. {2} + + Expected a non-null value. + Expected a non-null value. + + + + Expected value to be null. + Expected value to be null. + + + + Expected a positive value. + Expected a positive value. + + + + Expected condition to be true. + Expected condition to be true. + + + + String does not match expected pattern. + String does not match expected pattern. + + + + No exception was thrown. + No exception was thrown. + + The member specified ({0}) could not be found. You might need to regenerate your private accessor, @@ -358,21 +412,16 @@ Effettivo: {2} (oggetto) + + String does not start with expected prefix. + String does not start with expected prefix. + + (Failed to get the message for an exception of type {0} due to an exception.) Non è stato possibile ottenere il messaggio per un'eccezione di tipo {0} a causa di un'eccezione. - - Expected exception type:<{1}> but no exception was thrown. {0} - È previsto il tipo di eccezione: <{1}> ma non è stata generata alcuna eccezione. {0} - - - - Expected exception type:<{1}>. Actual exception type:<{2}>. {0} - Tipo di eccezione previsto:<{1}>. Tipo di eccezione effettivo: <{2}>. {0} - - {0} ({1}) {0} ({1}) @@ -398,36 +447,6 @@ Effettivo: {2} La proprietà o il metodo {0} nella classe {1} restituisce un elemento IEnumerable<object[]> vuoto. - - Actual value <{2}> is not greater than expected value <{1}>. {0} - Il valore effettivo <{2}> non è maggiore del valore previsto <{1}>. {0} - - - - Actual value <{2}> is not greater than or equal to expected value <{1}>. {0} - Il valore effettivo <{2}> non è maggiore o uguale al valore previsto <{1}>. {0} - - - - Actual value <{2}> is not less than expected value <{1}>. {0} - Il valore effettivo <{2}> non è minore del valore previsto <{1}>. {0} - - - - Actual value <{2}> is not less than or equal to expected value <{1}>. {0} - Il valore effettivo <{2}> non è minore o uguale al valore previsto <{1}>. {0} - - - - Expected value <{1}> to be positive. {0} - Il valore <{1}{0}> dovrebbe essere positivo. - - - - Expected value <{1}> to be negative. {0} - Il valore <{1}{0}> dovrebbe essere negativo. - - Assert.Equals should not be used for Assertions. Please use Assert.AreEqual & overloads instead. Non è possibile usare Assert.Equals per le asserzioni. Usare Assert.AreEqual e gli overload. @@ -458,6 +477,11 @@ Effettivo: {2} Non è possibile usare CollectionAssert.ReferenceEquals per le asserzioni. In alternativa, usare i metodi CollectionAssert o Assert.AreSame e gli overload. + + Wrong exception type was thrown. + Wrong exception type was thrown. + + \ No newline at end of file diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ja.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ja.xlf index bdced96434..d88c519410 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ja.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ja.xlf @@ -17,46 +17,20 @@ 重複する項目が見つかりました:<{1}>。{0} - - Expected:<{1}>. Actual:<{2}>. {0} - <{1}> が必要ですが、<{2}> が指定されました。{0} - - - - Expected a difference no greater than <{3}> between expected value <{1}> and actual value <{2}>. {0} - 指定する値 <{1}> と実際の値 <{2}> との間には <{3}> 以内の差が必要です。{0} - - - - Expected:<{1}>. Case is different for actual value:<{2}>. {0} - <{1}> が必要です。実際の値: <{2}> では大文字と小文字が異なります。{0} - - - - Expected:<{1} ({2})>. Actual:<{3} ({4})>. {0} - <{1} ({2})> が必要ですが、<{3} ({4})> が指定されました。{0} - - - - {0}{1} -{2} -{3} -{4} - {0}{1} -{2} -{3} -{4} + + Case differs. + Case differs. - - Expected: - 期待値: - + + Expected a difference no greater than <{0}>. + Expected a difference no greater than <{0}>. + - - But was: - しかし、次でした: - + + Expected values to be equal. + Expected values to be equal. + String lengths are both {0} but differ at index {1}. @@ -68,15 +42,25 @@ 期待される文字列の長さは {0} ですが、実際は {1} でした。 - - Expected any value except:<{1}>. Actual:<{2}>. {0} - <{1}> 以外の任意の値が必要ですが、<{2}> が指定されています。{0} - + + Expected a difference greater than <{0}>. + Expected a difference greater than <{0}>. + - - Expected a difference greater than <{3}> between expected value <{1}> and actual value <{2}>. {0} - 指定する値 <{1}> と実際の値 <{2}> との間には、<{3}> を超える差が必要です。{0} - + + Expected values to differ. + Expected values to differ. + + + + Expected references to be different. + Expected references to be different. + + + + Expected references to be the same. + Expected references to be the same. + Do not pass value types to AreSame(). Values converted to Object will never be the same. Consider using AreEqual(). {0} @@ -118,21 +102,6 @@ 両方のコレクションが同じ要素を含んでいます。{0} - - '{0}' expression: '{1}'. - '{0}' 式: '{1}'。 - Example: "'value' expression: 'new object()'", where 'value' is the parameter name of an assertion method, and 'new object()' is the expression the user passed to the assert method. - - - '{0}' expression: '{1}', '{2}' expression: '{3}', '{4}' expression: '{5}'. - '{0}' 式: '{1}'、'{2}' 式: '{3}'、'{4}' 式: '{5}'。 - Example: "'substring' expression: 'userCode1', 'value' expression: 'userCode2'", where 'substring' and 'value' are the parameter names of an assertion method, and 'userCode's are the expressions the user passed to the assert method. - - - '{0}' expression: '{1}', '{2}' expression: '{3}'. - '{0}' 式: '{1}'、'{2}' 式: '{3}'。 - Example: "'minValue' expression: 'userCode1', 'maxValue' expression: 'userCode2', 'value' expression: 'userCode3'", where 'minValue', 'maxValue', and 'value' are the parameter names of an assertion method, and 'userCode's are the expressions the user passed to the assert method. - {0}. {1} {0}。{1} @@ -143,39 +112,44 @@ 文字列 '{0}' は文字列 '{1}' を含んでいません。{2}。 - - Expected collection to contain the specified item. {0} - 指定された項目を含むコレクションが必要です。{0} + + Expected collection to contain the specified item. + Expected collection to contain the specified item. + + + + Expected at least one item to match the predicate. + Expected at least one item to match the predicate. - - Expected at least one item to match the predicate. {0} - 述語と一致する項目が少なくとも 1 つ必要です。{0} + + Expected collection to contain exactly one item but found {0} item(s). + Expected collection to contain exactly one item but found {0} item(s). - - Expected collection to contain exactly one element but found {1} element(s). {0} - コレクションには 1 つの要素だけを含める必要がありますが、{1} 要素が見つかりました。{0} + + Expected exactly one item to match the predicate but found {0} item(s). + Expected exactly one item to match the predicate but found {0} item(s). - - Expected exactly one item to match the predicate but found {1} item(s). {0} - 述語と一致する項目が 1 つだけ必要ですが、{1} 項目が見つかりました。{0} + + String does not contain the expected substring. + String does not contain the expected substring. - - String '{0}' does contain string '{1}'. {2}. - 文字列 '{0}' は文字列 '{1}' を含んでいます。{2}。 + + Expected collection to not contain the specified item. + Expected collection to not contain the specified item. - - Expected collection to not contain the specified item. {0} - 指定された項目を含まないコレクションが必要です。{0} + + Expected no items to match the predicate. + Expected no items to match the predicate. - - Expected no items to match the predicate. {0} - 述語に一致する項目が必要ありません。{0} + + String contains the unexpected substring. + String contains the unexpected substring. @@ -183,11 +157,26 @@ 文字列 '{0}' の末尾は文字列 '{1}' です。{2} + + String ends with unexpected suffix. + String ends with unexpected suffix. + + + + String matches pattern but should not. + String matches pattern but should not. + + String '{0}' starts with string '{1}'. {2} 文字列 '{0}' は文字列 '{1}' で始まります。 {2} + + String starts with unexpected prefix. + String starts with unexpected prefix. + + Dynamic data field '{0}' should be static. 動的データ フィールド '{0}' は静的である必要があります。 @@ -237,9 +226,14 @@ Actual: {2} {0} に失敗しました。{1} - - Expected collection of size {1}. Actual: {2}. {0} - サイズ {1} のコレクションが必要です。実際: {2}。{0} + + String does not end with expected suffix. + String does not end with expected suffix. + + + + Expected collection to have the specified number of items. + Expected collection to have the specified number of items. @@ -252,9 +246,29 @@ Actual: {2} GitHub チケット URL が無効です - - Value '{0}' is not within the expected range [{1}..{2}]. {3} - 値 '{0}' は予期される範囲 [{1}..{2}] 内にありません。{3} + + Expected value to be exactly of the specified type. + Expected value to be exactly of the specified type. + + + + Expected condition to be false. + Expected condition to be false. + + + + Expected value to be greater than the specified bound. + Expected value to be greater than the specified bound. + + + + Expected value to be greater than or equal to the specified bound. + Expected value to be greater than or equal to the specified bound. + + + + Value is not within the expected range. + Value is not within the expected range. @@ -262,41 +276,81 @@ Actual: {2} 最大値は、最小値以上である必要があります。 - - {0} Expected type:<{1}>. Actual type:<{2}>. - {0} には型 <{1}> が必要ですが、型 <{2}> が指定されました。 - + + Expected value to be of the specified type. + Expected value to be of the specified type. + + + + Expected value to be less than the specified bound. + Expected value to be less than the specified bound. + + + + Expected value to be less than or equal to the specified bound. + Expected value to be less than or equal to the specified bound. + String '{0}' does not match pattern '{1}'. {2} 文字列 '{0}' はパターン '{1}' と一致しません。{2} - - Expected collection to contain any item but it is empty. {0} - コレクションには項目が含まれている必要がありますが、空です。{0} + + Expected a negative value. + Expected a negative value. - - Wrong Type:<{1}>. Actual type:<{2}>. {0} - 正しくない型は <{1}> であり、実際の型は <{2}> です。{0} - + + Expected collection to contain any item but it is empty. + Expected collection to contain any item but it is empty. + - - {0} Expected exact type:<{1}>. Actual type:<{2}>. - {0} 正確な型が必要です: <{1}>。実際の型: <{2}>。 - + + Value should not be exactly of the specified type. + Value should not be exactly of the specified type. + - - Wrong exact Type:<{1}>. Actual type:<{2}>. {0} - 間違った正確な型: <{1}>。実際の型: {2}。{0} - + + Value should not be of the specified type. + Value should not be of the specified type. + String '{0}' matches pattern '{1}'. {2} 文字列 '{0}' はパターン '{1}' と一致します。{2} + + Expected a non-null value. + Expected a non-null value. + + + + Expected value to be null. + Expected value to be null. + + + + Expected a positive value. + Expected a positive value. + + + + Expected condition to be true. + Expected condition to be true. + + + + String does not match expected pattern. + String does not match expected pattern. + + + + No exception was thrown. + No exception was thrown. + + The member specified ({0}) could not be found. You might need to regenerate your private accessor, @@ -358,21 +412,16 @@ Actual: {2} (オブジェクト) + + String does not start with expected prefix. + String does not start with expected prefix. + + (Failed to get the message for an exception of type {0} due to an exception.) (例外が発生したため、型 {0} の例外のメッセージを取得できませんでした。) - - Expected exception type:<{1}> but no exception was thrown. {0} - 例外の種類: <{1}> が予期されますが、例外はスローされませんでした。{0} - - - - Expected exception type:<{1}>. Actual exception type:<{2}>. {0} - 予期される例外の種類: <{1}>。実際の例外の種類: <{2}>。{0} - - {0} ({1}) {0} ({1}) @@ -398,36 +447,6 @@ Actual: {2} {1} 上のプロパティまたはメソッド {0} は空の IEnumerable<object[]> を返します。 - - Actual value <{2}> is not greater than expected value <{1}>. {0} - 実際の値 <{2}> は、予期された値 <{1}> より大きくありません。{0} - - - - Actual value <{2}> is not greater than or equal to expected value <{1}>. {0} - 実際の値 <{2}> は、予期された値 <{1}> 以上ではありません。{0} - - - - Actual value <{2}> is not less than expected value <{1}>. {0} - 実際の値 <{2}> は、予期された値 <{1}> より小さくありません。{0} - - - - Actual value <{2}> is not less than or equal to expected value <{1}>. {0} - 実際の値 <{2}> は、予期された値 <{1}> 以下ではありません。{0} - - - - Expected value <{1}> to be positive. {0} - 正の値 <{1}> が必要です。{0} - - - - Expected value <{1}> to be negative. {0} - 負の値 <{1}> が必要です。{0} - - Assert.Equals should not be used for Assertions. Please use Assert.AreEqual & overloads instead. アサーションには Assert.Equals を使用せずに、Assert.AreEqual とオーバーロードを使用してください。(& ) @@ -458,6 +477,11 @@ Actual: {2} アサーションには CollectionAssert.ReferenceEquals を使用しないでください。代わりに CollectionAssert メソッドまたは Assert.AreSame およびオーバーロードを使用してください。 + + Wrong exception type was thrown. + Wrong exception type was thrown. + + \ No newline at end of file diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ko.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ko.xlf index 6d9292a56e..a1df05f673 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ko.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ko.xlf @@ -17,46 +17,20 @@ 중복된 항목이 있습니다. <{1}>. {0} - - Expected:<{1}>. Actual:<{2}>. {0} - 예상 값: <{1}>. 실제 값: <{2}>. {0} - - - - Expected a difference no greater than <{3}> between expected value <{1}> and actual value <{2}>. {0} - 예상 값 <{1}>과(와) 실제 값 <{2}>의 차이가 <{3}>보다 크지 않아야 합니다. {0} - - - - Expected:<{1}>. Case is different for actual value:<{2}>. {0} - 예상 값: <{1}>. 대/소문자가 다른 실제 값: <{2}>. {0} - - - - Expected:<{1} ({2})>. Actual:<{3} ({4})>. {0} - 예상 값: <{1} ({2})>. 실제 값: <{3} ({4})>. {0} - - - - {0}{1} -{2} -{3} -{4} - {0}{1} -{2} -{3} -{4} + + Case differs. + Case differs. - - Expected: - 예상: - + + Expected a difference no greater than <{0}>. + Expected a difference no greater than <{0}>. + - - But was: - 그러나 다음과 같습니다. - + + Expected values to be equal. + Expected values to be equal. + String lengths are both {0} but differ at index {1}. @@ -68,15 +42,25 @@ 문자열 길이 {0}(을)를 예상했지만 {1}입니다. - - Expected any value except:<{1}>. Actual:<{2}>. {0} - 예상 값: <{1}>을(를) 제외한 모든 값. 실제 값: <{2}>. {0} - + + Expected a difference greater than <{0}>. + Expected a difference greater than <{0}>. + - - Expected a difference greater than <{3}> between expected value <{1}> and actual value <{2}>. {0} - 예상 값 <{1}>과(와) 실제 값 <{2}>의 차이가 <{3}>보다 커야 합니다. {0} - + + Expected values to differ. + Expected values to differ. + + + + Expected references to be different. + Expected references to be different. + + + + Expected references to be the same. + Expected references to be the same. + Do not pass value types to AreSame(). Values converted to Object will never be the same. Consider using AreEqual(). {0} @@ -118,21 +102,6 @@ 두 컬렉션에 같은 요소가 포함되어 있습니다. {0} - - '{0}' expression: '{1}'. - '{0}' 식: '{1}'. - Example: "'value' expression: 'new object()'", where 'value' is the parameter name of an assertion method, and 'new object()' is the expression the user passed to the assert method. - - - '{0}' expression: '{1}', '{2}' expression: '{3}', '{4}' expression: '{5}'. - ' {0}' 식: '{1}', '{2}' 식: '{3}', '{4}' 식: '{5}'. - Example: "'substring' expression: 'userCode1', 'value' expression: 'userCode2'", where 'substring' and 'value' are the parameter names of an assertion method, and 'userCode's are the expressions the user passed to the assert method. - - - '{0}' expression: '{1}', '{2}' expression: '{3}'. - '{0}' 식: '{1}', '{2}' 식: '{3}'. - Example: "'minValue' expression: 'userCode1', 'maxValue' expression: 'userCode2', 'value' expression: 'userCode3'", where 'minValue', 'maxValue', and 'value' are the parameter names of an assertion method, and 'userCode's are the expressions the user passed to the assert method. - {0}. {1} {0}. {1} @@ -143,39 +112,44 @@ '{0}' 문자열이 '{1}' 문자열을 포함하지 않습니다. {2} - - Expected collection to contain the specified item. {0} - 지정한 항목을 포함할 컬렉션이 필요합니다. {0} + + Expected collection to contain the specified item. + Expected collection to contain the specified item. + + + + Expected at least one item to match the predicate. + Expected at least one item to match the predicate. - - Expected at least one item to match the predicate. {0} - 조건자와 일치하는 항목이 하나 이상 필요합니다. {0} + + Expected collection to contain exactly one item but found {0} item(s). + Expected collection to contain exactly one item but found {0} item(s). - - Expected collection to contain exactly one element but found {1} element(s). {0} - 정확히 하나의 요소를 포함할 컬렉션이 필요하지만 {1}개 요소가 발견되었습니다. {0} + + Expected exactly one item to match the predicate but found {0} item(s). + Expected exactly one item to match the predicate but found {0} item(s). - - Expected exactly one item to match the predicate but found {1} item(s). {0} - 조건자에 일치하는 항목이 하나만 필요하지만 {1}개 항목이 발견되었습니다. {0} + + String does not contain the expected substring. + String does not contain the expected substring. - - String '{0}' does contain string '{1}'. {2}. - '{0}' 문자열에 '{1}' 문자열이 포함되어 있습니다. {2}. + + Expected collection to not contain the specified item. + Expected collection to not contain the specified item. - - Expected collection to not contain the specified item. {0} - 지정한 항목을 포함하지 않을 컬렉션이 필요합니다. {0} + + Expected no items to match the predicate. + Expected no items to match the predicate. - - Expected no items to match the predicate. {0} - 조건자와 일치하는 항목이 필요하지 않습니다. {0} + + String contains the unexpected substring. + String contains the unexpected substring. @@ -183,11 +157,26 @@ 문자열 '{0}'은 문자열 '{1}'(으)로 끝납니다. {2} + + String ends with unexpected suffix. + String ends with unexpected suffix. + + + + String matches pattern but should not. + String matches pattern but should not. + + String '{0}' starts with string '{1}'. {2} 문자열 '{0}'은 문자열 '{1}'(으)로 시작합니다. {2} + + String starts with unexpected prefix. + String starts with unexpected prefix. + + Dynamic data field '{0}' should be static. 동적 데이터 필드 '{0}'은(는) 정적이어야 합니다. @@ -237,9 +226,14 @@ Actual: {2} {0}이(가) 실패했습니다. {1} - - Expected collection of size {1}. Actual: {2}. {0} - {1} 크기 컬렉션이 필요합니다. 실제: {2}. {0} + + String does not end with expected suffix. + String does not end with expected suffix. + + + + Expected collection to have the specified number of items. + Expected collection to have the specified number of items. @@ -252,9 +246,29 @@ Actual: {2} 잘못된 GitHub 티켓 URL - - Value '{0}' is not within the expected range [{1}..{2}]. {3} - '{0}' 값이 예상 범위 [{1}..{2}] 내에 있지 않습니다. {3} + + Expected value to be exactly of the specified type. + Expected value to be exactly of the specified type. + + + + Expected condition to be false. + Expected condition to be false. + + + + Expected value to be greater than the specified bound. + Expected value to be greater than the specified bound. + + + + Expected value to be greater than or equal to the specified bound. + Expected value to be greater than or equal to the specified bound. + + + + Value is not within the expected range. + Value is not within the expected range. @@ -262,41 +276,81 @@ Actual: {2} 최댓값은 최솟값보다 크거나 같아야 합니다. - - {0} Expected type:<{1}>. Actual type:<{2}>. - {0} 예상 형식: <{1}>, 실제 형식: <{2}>. - + + Expected value to be of the specified type. + Expected value to be of the specified type. + + + + Expected value to be less than the specified bound. + Expected value to be less than the specified bound. + + + + Expected value to be less than or equal to the specified bound. + Expected value to be less than or equal to the specified bound. + String '{0}' does not match pattern '{1}'. {2} '{0}' 문자열이 '{1}' 패턴과 일치하지 않습니다. {2} - - Expected collection to contain any item but it is empty. {0} - 항목을 포함할 컬렉션이 필요한데 비어 있습니다. {0} + + Expected a negative value. + Expected a negative value. - - Wrong Type:<{1}>. Actual type:<{2}>. {0} - 잘못된 형식: <{1}>, 실제 형식: <{2}>. {0} - + + Expected collection to contain any item but it is empty. + Expected collection to contain any item but it is empty. + - - {0} Expected exact type:<{1}>. Actual type:<{2}>. - {0} 예상되는 정확한 형식:<{1}>. 실제 형식: <{2}>. - + + Value should not be exactly of the specified type. + Value should not be exactly of the specified type. + - - Wrong exact Type:<{1}>. Actual type:<{2}>. {0} - 잘못된 정확한 형식:<{1}>. 실제 형식: <{2}>. {0} - + + Value should not be of the specified type. + Value should not be of the specified type. + String '{0}' matches pattern '{1}'. {2} '{0}' 문자열이 '{1}' 패턴과 일치합니다. {2} + + Expected a non-null value. + Expected a non-null value. + + + + Expected value to be null. + Expected value to be null. + + + + Expected a positive value. + Expected a positive value. + + + + Expected condition to be true. + Expected condition to be true. + + + + String does not match expected pattern. + String does not match expected pattern. + + + + No exception was thrown. + No exception was thrown. + + The member specified ({0}) could not be found. You might need to regenerate your private accessor, @@ -358,21 +412,16 @@ Actual: {2} (개체) + + String does not start with expected prefix. + String does not start with expected prefix. + + (Failed to get the message for an exception of type {0} due to an exception.) (예외로 인해 {0} 형식의 예외에 대한 메시지를 가져오지 못했습니다.) - - Expected exception type:<{1}> but no exception was thrown. {0} - 예상 예외 형식:<{1}> 하지만 예외가 발생하지 않음. {0} - - - - Expected exception type:<{1}>. Actual exception type:<{2}>. {0} - 예상 예외 형식:<{1}>. 실제 예상 형식:<{2}>. {0} - - {0} ({1}) {0}({1}) @@ -398,36 +447,6 @@ Actual: {2} {1}의 속성 또는 메서드 {0}이(가) 빈 IEnumerable<object[]>를 반환합니다. - - Actual value <{2}> is not greater than expected value <{1}>. {0} - 실제 값 <{2}>은(는)는 예상 값 <{1}>보다 크지 않습니다. {0} - - - - Actual value <{2}> is not greater than or equal to expected value <{1}>. {0} - 실제 값 <{2}>은(는)는 예상 값 <{1}>보다 크거나 같지 않습니다. {0} - - - - Actual value <{2}> is not less than expected value <{1}>. {0} - 실제 값 <{2}>은(는)는 예상 값 <{1}>보다 작지 않습니다. {0} - - - - Actual value <{2}> is not less than or equal to expected value <{1}>. {0} - 실제 값 <{2}>은(는)는 예상 값 <{1}>보다 작거나 같지 않습니다. {0} - - - - Expected value <{1}> to be positive. {0} - 예상 값 <{1}>은(는) 양수일 것으로 예상합니다. {0} - - - - Expected value <{1}> to be negative. {0} - 예상 값 <{1}>은(는) 음수일 것으로 예상합니다. {0} - - Assert.Equals should not be used for Assertions. Please use Assert.AreEqual & overloads instead. 어설션에 Assert.Equals를 사용할 수 없습니다. 대신 Assert.AreEqual 및 오버로드를 사용하세요. @@ -458,6 +477,11 @@ Actual: {2} CollectionAssert.ReferenceEquals는 Assertions에 사용할 수 없습니다. 대신 CollectionAssert 메서드 또는 Assert.AreSame 및 오버로드를 사용하세요. + + Wrong exception type was thrown. + Wrong exception type was thrown. + + \ No newline at end of file diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pl.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pl.xlf index c50ff5897a..510bf94e6a 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pl.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pl.xlf @@ -17,46 +17,20 @@ Znaleziono duplikat:<{1}>. {0} - - Expected:<{1}>. Actual:<{2}>. {0} - Oczekiwana:<{1}>. Rzeczywista:<{2}>. {0} - - - - Expected a difference no greater than <{3}> between expected value <{1}> and actual value <{2}>. {0} - Oczekiwano różnicy nie większej niż <{3}> pomiędzy oczekiwaną wartością <{1}> a rzeczywistą wartością <{2}>. {0} - - - - Expected:<{1}>. Case is different for actual value:<{2}>. {0} - Oczekiwano:<{1}>. Przypadek różni się od rzeczywistej wartości:<{2}>. {0} - - - - Expected:<{1} ({2})>. Actual:<{3} ({4})>. {0} - Oczekiwana:<{1} ({2})>. Rzeczywista:<{3} ({4})>. {0} - - - - {0}{1} -{2} -{3} -{4} - {0}{1} -{2} -{3} -{4} + + Case differs. + Case differs. - - Expected: - Oczekiwane: - + + Expected a difference no greater than <{0}>. + Expected a difference no greater than <{0}>. + - - But was: - Ale było: - + + Expected values to be equal. + Expected values to be equal. + String lengths are both {0} but differ at index {1}. @@ -68,15 +42,25 @@ Oczekiwano ciągu o długości {0}, ale miał wartość {1}. - - Expected any value except:<{1}>. Actual:<{2}>. {0} - Oczekiwano dowolnej wartości za wyjątkiem:<{1}>. Rzeczywista:<{2}>. {0} - + + Expected a difference greater than <{0}>. + Expected a difference greater than <{0}>. + - - Expected a difference greater than <{3}> between expected value <{1}> and actual value <{2}>. {0} - Oczekiwano różnicy większej niż <{3}> pomiędzy oczekiwaną wartością <{1}> a rzeczywistą wartością <{2}>. {0} - + + Expected values to differ. + Expected values to differ. + + + + Expected references to be different. + Expected references to be different. + + + + Expected references to be the same. + Expected references to be the same. + Do not pass value types to AreSame(). Values converted to Object will never be the same. Consider using AreEqual(). {0} @@ -118,21 +102,6 @@ Obie kolekcje zawierają te same elementy. {0} - - '{0}' expression: '{1}'. - Wyrażenie „{0}”: „{1}”. - Example: "'value' expression: 'new object()'", where 'value' is the parameter name of an assertion method, and 'new object()' is the expression the user passed to the assert method. - - - '{0}' expression: '{1}', '{2}' expression: '{3}', '{4}' expression: '{5}'. - Wyrażenie „{0}”: „{1}”, wyrażenie „{2}”: „{3}”, wyrażenie „{4}”: „{5}”. - Example: "'substring' expression: 'userCode1', 'value' expression: 'userCode2'", where 'substring' and 'value' are the parameter names of an assertion method, and 'userCode's are the expressions the user passed to the assert method. - - - '{0}' expression: '{1}', '{2}' expression: '{3}'. - Wyrażenie „{0}”: „{1}”, wyrażenie „{2}”: „{3}”. - Example: "'minValue' expression: 'userCode1', 'maxValue' expression: 'userCode2', 'value' expression: 'userCode3'", where 'minValue', 'maxValue', and 'value' are the parameter names of an assertion method, and 'userCode's are the expressions the user passed to the assert method. - {0}. {1} {0}. {1} @@ -143,39 +112,44 @@ Ciąg „{0}” nie zawiera ciągu „{1}”. {2}. - - Expected collection to contain the specified item. {0} - Oczekiwano, że kolekcja będzie zawierać określony element. {0} + + Expected collection to contain the specified item. + Expected collection to contain the specified item. + + + + Expected at least one item to match the predicate. + Expected at least one item to match the predicate. - - Expected at least one item to match the predicate. {0} - Oczekiwano co najmniej jednego elementu zgodnego z predykatem. {0} + + Expected collection to contain exactly one item but found {0} item(s). + Expected collection to contain exactly one item but found {0} item(s). - - Expected collection to contain exactly one element but found {1} element(s). {0} - Oczekiwano, że kolekcja będzie zawierać dokładnie jeden element, ale znaleziono {1} elementów. {0} + + Expected exactly one item to match the predicate but found {0} item(s). + Expected exactly one item to match the predicate but found {0} item(s). - - Expected exactly one item to match the predicate but found {1} item(s). {0} - Oczekiwano dokładnie jednego elementu zgodnego z predykatem, ale znaleziono {1} elementów. {0} + + String does not contain the expected substring. + String does not contain the expected substring. - - String '{0}' does contain string '{1}'. {2}. - Ciąg „{0}” zawiera ciąg „{1}”. {2}. + + Expected collection to not contain the specified item. + Expected collection to not contain the specified item. - - Expected collection to not contain the specified item. {0} - Oczekiwano, że kolekcja nie będzie zawierać określonego elementu. {0} + + Expected no items to match the predicate. + Expected no items to match the predicate. - - Expected no items to match the predicate. {0} - Nie oczekiwano elementów zgodnych z predykatem. {0} + + String contains the unexpected substring. + String contains the unexpected substring. @@ -183,11 +157,26 @@ Ciąg „{0}” kończy się ciągiem „{1}”. {2} + + String ends with unexpected suffix. + String ends with unexpected suffix. + + + + String matches pattern but should not. + String matches pattern but should not. + + String '{0}' starts with string '{1}'. {2} Ciąg „{0}” rozpoczyna się od ciągu „{1}”. {2} + + String starts with unexpected prefix. + String starts with unexpected prefix. + + Dynamic data field '{0}' should be static. Dynamiczne pole danych „{0}” powinno być statyczne. @@ -237,9 +226,14 @@ Rzeczywiste: {2} {0} — niepowodzenie. {1} - - Expected collection of size {1}. Actual: {2}. {0} - Oczekiwano kolekcji rozmiaru {1}. Wartość rzeczywista: {2}. {0} + + String does not end with expected suffix. + String does not end with expected suffix. + + + + Expected collection to have the specified number of items. + Expected collection to have the specified number of items. @@ -252,9 +246,29 @@ Rzeczywiste: {2} Nieprawidłowy adres URL biletu usługi GitHub - - Value '{0}' is not within the expected range [{1}..{2}]. {3} - Wartość „{0}” nie mieści się w oczekiwanym zakresie [{1}..{2}]. {3} + + Expected value to be exactly of the specified type. + Expected value to be exactly of the specified type. + + + + Expected condition to be false. + Expected condition to be false. + + + + Expected value to be greater than the specified bound. + Expected value to be greater than the specified bound. + + + + Expected value to be greater than or equal to the specified bound. + Expected value to be greater than or equal to the specified bound. + + + + Value is not within the expected range. + Value is not within the expected range. @@ -262,41 +276,81 @@ Rzeczywiste: {2} Wartość maksymalna musi być większa niż wartość minimalna lub jej równa. - - {0} Expected type:<{1}>. Actual type:<{2}>. - {0} Oczekiwany typ:<{1}>. Rzeczywisty typ:<{2}>. - + + Expected value to be of the specified type. + Expected value to be of the specified type. + + + + Expected value to be less than the specified bound. + Expected value to be less than the specified bound. + + + + Expected value to be less than or equal to the specified bound. + Expected value to be less than or equal to the specified bound. + String '{0}' does not match pattern '{1}'. {2} Ciąg „{0}” nie jest zgodny ze wzorcem „{1}”. {2} - - Expected collection to contain any item but it is empty. {0} - Oczekiwano, że kolekcja będzie zawierać dowolny element, ale jest pusta. {0} + + Expected a negative value. + Expected a negative value. - - Wrong Type:<{1}>. Actual type:<{2}>. {0} - Zły typ:<{1}>. Rzeczywisty typ:<{2}>. {0} - + + Expected collection to contain any item but it is empty. + Expected collection to contain any item but it is empty. + - - {0} Expected exact type:<{1}>. Actual type:<{2}>. - {0} Oczekiwano dokładnego typu:<{1}>. Rzeczywisty typ:<{2}>. - + + Value should not be exactly of the specified type. + Value should not be exactly of the specified type. + - - Wrong exact Type:<{1}>. Actual type:<{2}>. {0} - Nieprawidłowy dokładny typ:<{1}>. Rzeczywisty typ:<{2}>. {0} - + + Value should not be of the specified type. + Value should not be of the specified type. + String '{0}' matches pattern '{1}'. {2} Ciąg „{0}” jest zgodny ze wzorcem „{1}”. {2} + + Expected a non-null value. + Expected a non-null value. + + + + Expected value to be null. + Expected value to be null. + + + + Expected a positive value. + Expected a positive value. + + + + Expected condition to be true. + Expected condition to be true. + + + + String does not match expected pattern. + String does not match expected pattern. + + + + No exception was thrown. + No exception was thrown. + + The member specified ({0}) could not be found. You might need to regenerate your private accessor, @@ -358,21 +412,16 @@ Rzeczywiste: {2} (obiekt) + + String does not start with expected prefix. + String does not start with expected prefix. + + (Failed to get the message for an exception of type {0} due to an exception.) (Nie można pobrać komunikatu dotyczącego wyjątku typu {0} z powodu wyjątku). - - Expected exception type:<{1}> but no exception was thrown. {0} - Oczekiwano typu wyjątku:<{1}>, ale nie zgłoszono wyjątku. {0} - - - - Expected exception type:<{1}>. Actual exception type:<{2}>. {0} - Oczekiwano typu wyjątku:<{1}>. Rzeczywisty typ wyjątku:<{2}>. {0} - - {0} ({1}) {0} ({1}) @@ -398,36 +447,6 @@ Rzeczywiste: {2} Właściwość lub metoda {0} w elemencie {1} zwraca pusty interfejs IEnumerable<object[]>. - - Actual value <{2}> is not greater than expected value <{1}>. {0} - Wartość rzeczywista <{2}> nie jest większa niż oczekiwana wartość <{1}>. {0} - - - - Actual value <{2}> is not greater than or equal to expected value <{1}>. {0} - Wartość rzeczywista <{2}> nie jest większa lub równa oczekiwanej wartości <{1}>. {0} - - - - Actual value <{2}> is not less than expected value <{1}>. {0} - Wartość rzeczywista <{2}> nie jest mniejsza niż oczekiwana wartość <{1}>. {0} - - - - Actual value <{2}> is not less than or equal to expected value <{1}>. {0} - Wartość rzeczywista <{2}> nie jest mniejsza lub równa oczekiwanej wartości <{1}>. {0} - - - - Expected value <{1}> to be positive. {0} - Oczekiwana wartość <{1}> powinna być dodatnia. {0} - - - - Expected value <{1}> to be negative. {0} - Oczekiwana wartość <{1}> powinna być negatywna. {0} - - Assert.Equals should not be used for Assertions. Please use Assert.AreEqual & overloads instead. Assert.Equals nie powinno być używane do potwierdzania. Zamiast tego użyj Assert.AreEqual i przeciążeń. @@ -458,6 +477,11 @@ Rzeczywiste: {2} Element Assert.ReferenceEquals nie powinien być używany dla asercji. Zamiast tego użyj metod CollectionAssert lub Assert.AreSame oraz ich przeciążeń. + + Wrong exception type was thrown. + Wrong exception type was thrown. + + \ No newline at end of file diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pt-BR.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pt-BR.xlf index faf04cc886..08f42d5be8 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pt-BR.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pt-BR.xlf @@ -17,46 +17,20 @@ Item duplicado encontrado:<{1}>. {0} - - Expected:<{1}>. Actual:<{2}>. {0} - Esperado:<{1}>. Real:<{2}>. {0} - - - - Expected a difference no greater than <{3}> between expected value <{1}> and actual value <{2}>. {0} - Esperada uma diferença não maior que <{3}> entre o valor esperado <{1}> e o valor real <{2}>. {0} - - - - Expected:<{1}>. Case is different for actual value:<{2}>. {0} - Esperado:<{1}>. Capitalização é diferente para o valor real:<{2}>. {0} - - - - Expected:<{1} ({2})>. Actual:<{3} ({4})>. {0} - Esperado:<{1} ({2})>. Real:<{3} ({4})>. {0} - - - - {0}{1} -{2} -{3} -{4} - {0}{1} -{2} -{3} -{4} + + Case differs. + Case differs. - - Expected: - Esperado: - + + Expected a difference no greater than <{0}>. + Expected a difference no greater than <{0}>. + - - But was: - Mas foi: - + + Expected values to be equal. + Expected values to be equal. + String lengths are both {0} but differ at index {1}. @@ -68,15 +42,25 @@ Comprimento esperado da cadeia de caracteres {0}, mas foi {1}. - - Expected any value except:<{1}>. Actual:<{2}>. {0} - Esperado qualquer valor exceto:<{1}>. Real:<{2}>. {0} - + + Expected a difference greater than <{0}>. + Expected a difference greater than <{0}>. + - - Expected a difference greater than <{3}> between expected value <{1}> and actual value <{2}>. {0} - Esperada uma diferença maior que <{3}> entre o valor esperado <{1}> e o valor real <{2}>. {0} - + + Expected values to differ. + Expected values to differ. + + + + Expected references to be different. + Expected references to be different. + + + + Expected references to be the same. + Expected references to be the same. + Do not pass value types to AreSame(). Values converted to Object will never be the same. Consider using AreEqual(). {0} @@ -118,21 +102,6 @@ Ambas as coleções contêm os mesmos elementos. {0} - - '{0}' expression: '{1}'. - Expressão "{0}": "{1}". - Example: "'value' expression: 'new object()'", where 'value' is the parameter name of an assertion method, and 'new object()' is the expression the user passed to the assert method. - - - '{0}' expression: '{1}', '{2}' expression: '{3}', '{4}' expression: '{5}'. - Expressão "{0}": "{1}", "{2}" expressão: "{3}", "{4}" expressão: "{5}". - Example: "'substring' expression: 'userCode1', 'value' expression: 'userCode2'", where 'substring' and 'value' are the parameter names of an assertion method, and 'userCode's are the expressions the user passed to the assert method. - - - '{0}' expression: '{1}', '{2}' expression: '{3}'. - Expressão "{0}": "{1}", "{2}" expressão: "{3}". - Example: "'minValue' expression: 'userCode1', 'maxValue' expression: 'userCode2', 'value' expression: 'userCode3'", where 'minValue', 'maxValue', and 'value' are the parameter names of an assertion method, and 'userCode's are the expressions the user passed to the assert method. - {0}. {1} {0}. {1} @@ -143,39 +112,44 @@ A cadeia de caracteres '{0}' não contém a cadeia de caracteres '{1}'. {2}. - - Expected collection to contain the specified item. {0} - A coleção esperada contém o item especificado. {0} + + Expected collection to contain the specified item. + Expected collection to contain the specified item. + + + + Expected at least one item to match the predicate. + Expected at least one item to match the predicate. - - Expected at least one item to match the predicate. {0} - Esperava-se que pelo menos um item correspondesse ao predicado. {0} + + Expected collection to contain exactly one item but found {0} item(s). + Expected collection to contain exactly one item but found {0} item(s). - - Expected collection to contain exactly one element but found {1} element(s). {0} - A coleção esperada contém exatamente um elemento, mas encontrou {1} elementos. {0} + + Expected exactly one item to match the predicate but found {0} item(s). + Expected exactly one item to match the predicate but found {0} item(s). - - Expected exactly one item to match the predicate but found {1} item(s). {0} - Esperava-se exatamente um item para corresponder ao predicado, mas encontrou {1} itens. {0} + + String does not contain the expected substring. + String does not contain the expected substring. - - String '{0}' does contain string '{1}'. {2}. - A cadeia de caracteres "{0}" contém a cadeia de caracteres "{1}". {2}. + + Expected collection to not contain the specified item. + Expected collection to not contain the specified item. - - Expected collection to not contain the specified item. {0} - A coleção esperada não contém o item especificado. {0} + + Expected no items to match the predicate. + Expected no items to match the predicate. - - Expected no items to match the predicate. {0} - Não era esperado nenhum item que corresponda ao predicado. {0} + + String contains the unexpected substring. + String contains the unexpected substring. @@ -183,11 +157,26 @@ A cadeia de caracteres “{0}” termina com cadeia de caracteres “{1}”. {2} + + String ends with unexpected suffix. + String ends with unexpected suffix. + + + + String matches pattern but should not. + String matches pattern but should not. + + String '{0}' starts with string '{1}'. {2} A cadeia de caracteres “{0}” começa com a cadeia de caracteres “{1}”. {2} + + String starts with unexpected prefix. + String starts with unexpected prefix. + + Dynamic data field '{0}' should be static. O campo de dados dinâmicos '{0}' deve ser estático. @@ -237,9 +226,14 @@ Real: {2} {0} falhou. {1} - - Expected collection of size {1}. Actual: {2}. {0} - Coleção esperada de tamanho {1}. Real: {2}. {0} + + String does not end with expected suffix. + String does not end with expected suffix. + + + + Expected collection to have the specified number of items. + Expected collection to have the specified number of items. @@ -252,9 +246,29 @@ Real: {2} URL de tíquete do GitHub inválida - - Value '{0}' is not within the expected range [{1}..{2}]. {3} - O valor '{0}' não está dentro do intervalo esperado [{1}.. {2}]. {3} + + Expected value to be exactly of the specified type. + Expected value to be exactly of the specified type. + + + + Expected condition to be false. + Expected condition to be false. + + + + Expected value to be greater than the specified bound. + Expected value to be greater than the specified bound. + + + + Expected value to be greater than or equal to the specified bound. + Expected value to be greater than or equal to the specified bound. + + + + Value is not within the expected range. + Value is not within the expected range. @@ -262,41 +276,81 @@ Real: {2} O valor máximo deve ser maior ou igual ao valor mínimo. - - {0} Expected type:<{1}>. Actual type:<{2}>. - {0} Tipo esperado:<{1}>. Tipo real:<{2}>. - + + Expected value to be of the specified type. + Expected value to be of the specified type. + + + + Expected value to be less than the specified bound. + Expected value to be less than the specified bound. + + + + Expected value to be less than or equal to the specified bound. + Expected value to be less than or equal to the specified bound. + String '{0}' does not match pattern '{1}'. {2} A cadeia de caracteres “{0}” não corresponde ao padrão “{1}”. {2} - - Expected collection to contain any item but it is empty. {0} - A coleção esperada conter qualquer item, mas ela está vazia. {0} + + Expected a negative value. + Expected a negative value. - - Wrong Type:<{1}>. Actual type:<{2}>. {0} - Tipo errado:<{1}>. Tipo real:<{2}>. {0} - + + Expected collection to contain any item but it is empty. + Expected collection to contain any item but it is empty. + - - {0} Expected exact type:<{1}>. Actual type:<{2}>. - {0} Tipo exato esperado:<{1}>. Tipo real:<{2}>. - + + Value should not be exactly of the specified type. + Value should not be exactly of the specified type. + - - Wrong exact Type:<{1}>. Actual type:<{2}>. {0} - Tipo exato errado:<{1}>. Tipo real:<{2}>. {0} - + + Value should not be of the specified type. + Value should not be of the specified type. + String '{0}' matches pattern '{1}'. {2} A cadeia de caracteres “{0}” corresponde ao padrão “{1}”. {2} + + Expected a non-null value. + Expected a non-null value. + + + + Expected value to be null. + Expected value to be null. + + + + Expected a positive value. + Expected a positive value. + + + + Expected condition to be true. + Expected condition to be true. + + + + String does not match expected pattern. + String does not match expected pattern. + + + + No exception was thrown. + No exception was thrown. + + The member specified ({0}) could not be found. You might need to regenerate your private accessor, @@ -358,21 +412,16 @@ Real: {2} (objeto) + + String does not start with expected prefix. + String does not start with expected prefix. + + (Failed to get the message for an exception of type {0} due to an exception.) (Falha ao obter a mensagem para uma exceção do tipo {0} devido a uma exceção.) - - Expected exception type:<{1}> but no exception was thrown. {0} - Tipo de exceção esperado:<{1}> mas nenhuma exceção foi lançada. {0} - - - - Expected exception type:<{1}>. Actual exception type:<{2}>. {0} - Tipo de exceção esperado:<{1}>. Tipo de exceção real:<{2}>. {0} - - {0} ({1}) {0} ({1}) @@ -398,36 +447,6 @@ Real: {2} A propriedade ou o método {0} em {1} retorna um IEnumerable<object[]> vazio. - - Actual value <{2}> is not greater than expected value <{1}>. {0} - O valor <{2}> real não é maior que o valor esperado <{1}>. {0} - - - - Actual value <{2}> is not greater than or equal to expected value <{1}>. {0} - O valor <{2}> real não é maior ou igual ao valor esperado <{1}>. {0} - - - - Actual value <{2}> is not less than expected value <{1}>. {0} - O valor <{2}> real não é menor que o valor esperado <{1}>. {0} - - - - Actual value <{2}> is not less than or equal to expected value <{1}>. {0} - O valor <{2}> real não é menor ou igual ao valor esperado <{1}>. {0} - - - - Expected value <{1}> to be positive. {0} - O valor <{1}> esperado deve ser positivo. {0} - - - - Expected value <{1}> to be negative. {0} - O valor <{1}> esperado deve ser negativo. {0} - - Assert.Equals should not be used for Assertions. Please use Assert.AreEqual & overloads instead. Assert.Equals não deveria ser usado para Declarações. Use Assert.AreEqual e sobrecargas em seu lugar. @@ -458,6 +477,11 @@ Real: {2} CollectionAssert.ReferenceEquals não deve ser usado com as Declarações. Em vez disso, use os métodos CollectionAssert ou Assert.AreSame e as sobrecargas. + + Wrong exception type was thrown. + Wrong exception type was thrown. + + \ No newline at end of file diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ru.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ru.xlf index e39af70016..4a565ec9cb 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ru.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ru.xlf @@ -17,46 +17,20 @@ Обнаружен совпадающий элемент: <{1}>. {0} - - Expected:<{1}>. Actual:<{2}>. {0} - Ожидается: <{1}>. Фактически: <{2}>. {0} - - - - Expected a difference no greater than <{3}> between expected value <{1}> and actual value <{2}>. {0} - Между ожидаемым значением <{1}> и фактическим значением <{2}> требуется разница не более чем <{3}>. {0} - - - - Expected:<{1}>. Case is different for actual value:<{2}>. {0} - Ожидается: <{1}>. Отличается на фактическое значение: <{2}>. {0} - - - - Expected:<{1} ({2})>. Actual:<{3} ({4})>. {0} - Ожидается: <{1} ({2})>. Фактически: <{3} ({4})>. {0} - - - - {0}{1} -{2} -{3} -{4} - {0}{1} -{2} -{3} -{4} + + Case differs. + Case differs. - - Expected: - Ожидалось: - + + Expected a difference no greater than <{0}>. + Expected a difference no greater than <{0}>. + - - But was: - Было: - + + Expected values to be equal. + Expected values to be equal. + String lengths are both {0} but differ at index {1}. @@ -68,15 +42,25 @@ Ожидалась длина строки: {0}, фактическая длина строки: {1}. - - Expected any value except:<{1}>. Actual:<{2}>. {0} - Ожидается любое значение, кроме: <{1}>. Фактически: <{2}>. {0} - + + Expected a difference greater than <{0}>. + Expected a difference greater than <{0}>. + - - Expected a difference greater than <{3}> between expected value <{1}> and actual value <{2}>. {0} - Между ожидаемым значением <{1}> и фактическим значением <{2}> требуется разница более чем <{3}>. {0} - + + Expected values to differ. + Expected values to differ. + + + + Expected references to be different. + Expected references to be different. + + + + Expected references to be the same. + Expected references to be the same. + Do not pass value types to AreSame(). Values converted to Object will never be the same. Consider using AreEqual(). {0} @@ -118,21 +102,6 @@ Обе коллекции содержат одинаковые элементы. {0} - - '{0}' expression: '{1}'. - Выражение "{0}": "{1}". - Example: "'value' expression: 'new object()'", where 'value' is the parameter name of an assertion method, and 'new object()' is the expression the user passed to the assert method. - - - '{0}' expression: '{1}', '{2}' expression: '{3}', '{4}' expression: '{5}'. - Выражение "{0}": "{1}", выражение "{2}": "{3}", выражение "{4}": "{5}". - Example: "'substring' expression: 'userCode1', 'value' expression: 'userCode2'", where 'substring' and 'value' are the parameter names of an assertion method, and 'userCode's are the expressions the user passed to the assert method. - - - '{0}' expression: '{1}', '{2}' expression: '{3}'. - Выражение "{0}": "{1}", выражение "{2}": "{3}". - Example: "'minValue' expression: 'userCode1', 'maxValue' expression: 'userCode2', 'value' expression: 'userCode3'", where 'minValue', 'maxValue', and 'value' are the parameter names of an assertion method, and 'userCode's are the expressions the user passed to the assert method. - {0}. {1} {0}. {1} @@ -143,39 +112,44 @@ Строка "{0}" не содержит строку "{1}". {2}. - - Expected collection to contain the specified item. {0} - Ожидалось, что коллекция будет содержать указанный элемент. {0} + + Expected collection to contain the specified item. + Expected collection to contain the specified item. - - Expected at least one item to match the predicate. {0} - Ожидался по крайней мере один элемент, соответствующий предикату. {0} + + Expected at least one item to match the predicate. + Expected at least one item to match the predicate. - - Expected collection to contain exactly one element but found {1} element(s). {0} - Ожидалось, что коллекция будет содержать ровно один элемент, но найдено элементов: {1}. {0} + + Expected collection to contain exactly one item but found {0} item(s). + Expected collection to contain exactly one item but found {0} item(s). - - Expected exactly one item to match the predicate but found {1} item(s). {0} - Ожидался ровно один элемент, соответствующий предикату, но найдено элементов: {1}. {0} + + Expected exactly one item to match the predicate but found {0} item(s). + Expected exactly one item to match the predicate but found {0} item(s). - - String '{0}' does contain string '{1}'. {2}. - Строка "{0}" не содержит строку "{1}". {2}. + + String does not contain the expected substring. + String does not contain the expected substring. + + + + Expected collection to not contain the specified item. + Expected collection to not contain the specified item. - - Expected collection to not contain the specified item. {0} - Ожидалось, что коллекция не будет содержать указанный элемент. {0} + + Expected no items to match the predicate. + Expected no items to match the predicate. - - Expected no items to match the predicate. {0} - Ожидалось, что ни один элемент не будет соответствовать предикату. {0} + + String contains the unexpected substring. + String contains the unexpected substring. @@ -183,11 +157,26 @@ Строка "{0}" заканчивается строкой "{1}". {2} + + String ends with unexpected suffix. + String ends with unexpected suffix. + + + + String matches pattern but should not. + String matches pattern but should not. + + String '{0}' starts with string '{1}'. {2} Строка "{0}" начинается со строки "{1}". {2} + + String starts with unexpected prefix. + String starts with unexpected prefix. + + Dynamic data field '{0}' should be static. Поле динамических данных "{0}" должно быть статическим. @@ -237,9 +226,14 @@ Actual: {2} Сбой {0}. {1} - - Expected collection of size {1}. Actual: {2}. {0} - Ожидается коллекция размеров {1}. Фактически: {2}. {0} + + String does not end with expected suffix. + String does not end with expected suffix. + + + + Expected collection to have the specified number of items. + Expected collection to have the specified number of items. @@ -252,9 +246,29 @@ Actual: {2} Недопустимый URL-адрес билета GitHub - - Value '{0}' is not within the expected range [{1}..{2}]. {3} - Значение "{0}" не находится в пределах ожидаемого диапазона [{1}..{2}]. {3} + + Expected value to be exactly of the specified type. + Expected value to be exactly of the specified type. + + + + Expected condition to be false. + Expected condition to be false. + + + + Expected value to be greater than the specified bound. + Expected value to be greater than the specified bound. + + + + Expected value to be greater than or equal to the specified bound. + Expected value to be greater than or equal to the specified bound. + + + + Value is not within the expected range. + Value is not within the expected range. @@ -262,41 +276,81 @@ Actual: {2} Максимальное значение должно быть больше минимального значения или равно ему. - - {0} Expected type:<{1}>. Actual type:<{2}>. - {0}Ожидается тип: <{1}>. Фактический тип: <{2}>. - + + Expected value to be of the specified type. + Expected value to be of the specified type. + + + + Expected value to be less than the specified bound. + Expected value to be less than the specified bound. + + + + Expected value to be less than or equal to the specified bound. + Expected value to be less than or equal to the specified bound. + String '{0}' does not match pattern '{1}'. {2} Строка "{0}" не соответствует шаблону "{1}". {2} - - Expected collection to contain any item but it is empty. {0} - Ожидается, что коллекция будет содержать любой элемент, но она пуста. {0} + + Expected a negative value. + Expected a negative value. - - Wrong Type:<{1}>. Actual type:<{2}>. {0} - Неверный тип: <{1}>. Фактический тип: <{2}>. {0} - + + Expected collection to contain any item but it is empty. + Expected collection to contain any item but it is empty. + - - {0} Expected exact type:<{1}>. Actual type:<{2}>. - {0} Ожидается точный тип: <{1}>. Фактический тип: <{2}>. - + + Value should not be exactly of the specified type. + Value should not be exactly of the specified type. + - - Wrong exact Type:<{1}>. Actual type:<{2}>. {0} - Неверный точный тип: <{1}>. Фактический тип: <{2}>. {0} - + + Value should not be of the specified type. + Value should not be of the specified type. + String '{0}' matches pattern '{1}'. {2} Строка "{0}" соответствует шаблону "{1}". {2} + + Expected a non-null value. + Expected a non-null value. + + + + Expected value to be null. + Expected value to be null. + + + + Expected a positive value. + Expected a positive value. + + + + Expected condition to be true. + Expected condition to be true. + + + + String does not match expected pattern. + String does not match expected pattern. + + + + No exception was thrown. + No exception was thrown. + + The member specified ({0}) could not be found. You might need to regenerate your private accessor, @@ -358,21 +412,16 @@ Actual: {2} (объект) + + String does not start with expected prefix. + String does not start with expected prefix. + + (Failed to get the message for an exception of type {0} due to an exception.) (Не удалось получить сообщение для исключения с типом {0} в связи с возникновением исключения.) - - Expected exception type:<{1}> but no exception was thrown. {0} - Ожидаемый тип исключения:<{1}> но исключение не создано. {0} - - - - Expected exception type:<{1}>. Actual exception type:<{2}>. {0} - Ожидаемый тип исключения:<{1}>. Фактический тип исключения:<{2}>. {0} - - {0} ({1}) {0} ({1}) @@ -398,36 +447,6 @@ Actual: {2} Свойство или метод {0} класса {1} возвращает пустой IEnumerable<object[]>. - - Actual value <{2}> is not greater than expected value <{1}>. {0} - Действительное значение <{2}> не больше ожидаемого значения <{1}>. {0} - - - - Actual value <{2}> is not greater than or equal to expected value <{1}>. {0} - Действительное значение <{2}> не больше или не равно ожидаемому значению <{1}>. {0} - - - - Actual value <{2}> is not less than expected value <{1}>. {0} - Действительное значение <{2}> не меньше ожидаемого значения <{1}>. {0} - - - - Actual value <{2}> is not less than or equal to expected value <{1}>. {0} - Действительное значение <{2}> не меньше или не равно ожидаемому значению <{1}>. {0} - - - - Expected value <{1}> to be positive. {0} - Ожидалось, что значение <{1}> будет положительным. {0} - - - - Expected value <{1}> to be negative. {0} - Ожидалось, что значение <{1}> будет отрицательным. {0} - - Assert.Equals should not be used for Assertions. Please use Assert.AreEqual & overloads instead. Нельзя использовать Assert.Equals для Assertions. Вместо этого используйте Assert.AreEqual и перегрузки. @@ -458,6 +477,11 @@ Actual: {2} Нельзя использовать CollectionAssert.ReferenceEquals для Assertions. Вместо этого используйте методы CollectionAssert или Assert.AreSame и перегрузки. + + Wrong exception type was thrown. + Wrong exception type was thrown. + + \ No newline at end of file diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.tr.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.tr.xlf index 3a24012694..46ad51880f 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.tr.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.tr.xlf @@ -17,46 +17,20 @@ Yinelenen öğe bulundu:<{1}>. {0} - - Expected:<{1}>. Actual:<{2}>. {0} - Beklenen:<{1}>. Gerçek:<{2}>. {0} - - - - Expected a difference no greater than <{3}> between expected value <{1}> and actual value <{2}>. {0} - Beklenen değer <{1}> ile gerçek değer <{2}> arasında, şundan büyük olmayan fark bekleniyor: <{3}>. {0} - - - - Expected:<{1}>. Case is different for actual value:<{2}>. {0} - Beklenen:<{1}>. Durum, gerçek değer için farklı:<{2}>. {0} - - - - Expected:<{1} ({2})>. Actual:<{3} ({4})>. {0} - Beklenen:<{1} ({2})>. Gerçek:<{3} ({4})>. {0} - - - - {0}{1} -{2} -{3} -{4} - {0}{1} -{2} -{3} -{4} + + Case differs. + Case differs. - - Expected: - Beklenen: - + + Expected a difference no greater than <{0}>. + Expected a difference no greater than <{0}>. + - - But was: - Ancak: - + + Expected values to be equal. + Expected values to be equal. + String lengths are both {0} but differ at index {1}. @@ -68,15 +42,25 @@ Beklenen dize uzunluğu {0} idi, ancak dize uzunluğu {1} oldu. - - Expected any value except:<{1}>. Actual:<{2}>. {0} - Şunun dışında bir değer bekleniyor:<{1}>. Gerçek:<{2}>. {0} - + + Expected a difference greater than <{0}>. + Expected a difference greater than <{0}>. + - - Expected a difference greater than <{3}> between expected value <{1}> and actual value <{2}>. {0} - Beklenen değer <{1}> ile gerçek değer <{2}> arasında, şundan büyük olan fark bekleniyor: <{3}>. {0} - + + Expected values to differ. + Expected values to differ. + + + + Expected references to be different. + Expected references to be different. + + + + Expected references to be the same. + Expected references to be the same. + Do not pass value types to AreSame(). Values converted to Object will never be the same. Consider using AreEqual(). {0} @@ -118,21 +102,6 @@ Her iki koleksiyon da aynı öğeleri içeriyor. {0} - - '{0}' expression: '{1}'. - '{0}' ifadesi: '{1}'. - Example: "'value' expression: 'new object()'", where 'value' is the parameter name of an assertion method, and 'new object()' is the expression the user passed to the assert method. - - - '{0}' expression: '{1}', '{2}' expression: '{3}', '{4}' expression: '{5}'. - '{0}' ifadesi: '{1}', '{2}' ifadesi: '{3}', '{4}' ifadesi: '{5}'. - Example: "'substring' expression: 'userCode1', 'value' expression: 'userCode2'", where 'substring' and 'value' are the parameter names of an assertion method, and 'userCode's are the expressions the user passed to the assert method. - - - '{0}' expression: '{1}', '{2}' expression: '{3}'. - '{0}' ifadesi: '{1}', '{2}' ifadesi: '{3}'. - Example: "'minValue' expression: 'userCode1', 'maxValue' expression: 'userCode2', 'value' expression: 'userCode3'", where 'minValue', 'maxValue', and 'value' are the parameter names of an assertion method, and 'userCode's are the expressions the user passed to the assert method. - {0}. {1} {0}. {1} @@ -143,39 +112,44 @@ '{0}' dizesi, '{1}' dizesini içermiyor. {2}. - - Expected collection to contain the specified item. {0} - Koleksiyonun belirtilen öğeyi içermesi bekleniyordu. {0} + + Expected collection to contain the specified item. + Expected collection to contain the specified item. - - Expected at least one item to match the predicate. {0} - En az bir öğenin koşulla eşleşmesi bekleniyordu. {0} + + Expected at least one item to match the predicate. + Expected at least one item to match the predicate. - - Expected collection to contain exactly one element but found {1} element(s). {0} - Beklenen koleksiyonun tam olarak bir öğe içermesi beklenirken, {1} öğe bulundu. {0} + + Expected collection to contain exactly one item but found {0} item(s). + Expected collection to contain exactly one item but found {0} item(s). - - Expected exactly one item to match the predicate but found {1} item(s). {0} - Özellikle bir öğenin koşulla eşleşmesi beklenirken {1} öğe bulundu. {0} + + Expected exactly one item to match the predicate but found {0} item(s). + Expected exactly one item to match the predicate but found {0} item(s). - - String '{0}' does contain string '{1}'. {2}. - '{0}' dizesi, '{1}' dizesini içermiyor. {2}. + + String does not contain the expected substring. + String does not contain the expected substring. + + + + Expected collection to not contain the specified item. + Expected collection to not contain the specified item. - - Expected collection to not contain the specified item. {0} - Koleksiyonun belirtilen öğeyi içermemesi bekleniyordu. {0} + + Expected no items to match the predicate. + Expected no items to match the predicate. - - Expected no items to match the predicate. {0} - Hiçbir öğenin koşulla eşleşmesi beklenmiyordu. {0} + + String contains the unexpected substring. + String contains the unexpected substring. @@ -183,11 +157,26 @@ '{0}' dizesi '{1}' dizesi ile bitiyor. {2} + + String ends with unexpected suffix. + String ends with unexpected suffix. + + + + String matches pattern but should not. + String matches pattern but should not. + + String '{0}' starts with string '{1}'. {2} '{0}' dizesi '{1}' dizesi ile başlıyor. {2} + + String starts with unexpected prefix. + String starts with unexpected prefix. + + Dynamic data field '{0}' should be static. Dinamik veri alanı ‘{0}’ statik olmalıdır. @@ -237,9 +226,14 @@ Gerçekte olan: {2} {0} başarısız. {1} - - Expected collection of size {1}. Actual: {2}. {0} - Beklenen boyut {1}. Gerçek: {2}. {0} + + String does not end with expected suffix. + String does not end with expected suffix. + + + + Expected collection to have the specified number of items. + Expected collection to have the specified number of items. @@ -252,9 +246,29 @@ Gerçekte olan: {2} Geçersiz GitHub anahtar URL'si - - Value '{0}' is not within the expected range [{1}..{2}]. {3} - Değer '{0}' beklenen aralık [{1}..{2}] içinde değil. {3} + + Expected value to be exactly of the specified type. + Expected value to be exactly of the specified type. + + + + Expected condition to be false. + Expected condition to be false. + + + + Expected value to be greater than the specified bound. + Expected value to be greater than the specified bound. + + + + Expected value to be greater than or equal to the specified bound. + Expected value to be greater than or equal to the specified bound. + + + + Value is not within the expected range. + Value is not within the expected range. @@ -262,41 +276,81 @@ Gerçekte olan: {2} En büyük değer en küçük değerden büyük veya buna eşit olmalıdır. - - {0} Expected type:<{1}>. Actual type:<{2}>. - {0} Beklenen tür:<{1}>. Gerçek tür:<{2}>. - + + Expected value to be of the specified type. + Expected value to be of the specified type. + + + + Expected value to be less than the specified bound. + Expected value to be less than the specified bound. + + + + Expected value to be less than or equal to the specified bound. + Expected value to be less than or equal to the specified bound. + String '{0}' does not match pattern '{1}'. {2} '{0}' dizesi, '{1}' deseni ile eşleşmiyor. {2} - - Expected collection to contain any item but it is empty. {0} - Koleksiyonun herhangi bir öğe içermesi bekleniyordu ancak boş. {0} + + Expected a negative value. + Expected a negative value. - - Wrong Type:<{1}>. Actual type:<{2}>. {0} - Yanlış Tür:<{1}>. Gerçek tür:<{2}>. {0} - + + Expected collection to contain any item but it is empty. + Expected collection to contain any item but it is empty. + - - {0} Expected exact type:<{1}>. Actual type:<{2}>. - {0} Beklenen tam tür:<{1}>. Gerçek tür:<{2}>. - + + Value should not be exactly of the specified type. + Value should not be exactly of the specified type. + - - Wrong exact Type:<{1}>. Actual type:<{2}>. {0} - Yanlış tam tür:<{1}>. Gerçek tür:<{2}>. {0} - + + Value should not be of the specified type. + Value should not be of the specified type. + String '{0}' matches pattern '{1}'. {2} '{0}' dizesi, '{1}' deseni ile eşleşiyor. {2} + + Expected a non-null value. + Expected a non-null value. + + + + Expected value to be null. + Expected value to be null. + + + + Expected a positive value. + Expected a positive value. + + + + Expected condition to be true. + Expected condition to be true. + + + + String does not match expected pattern. + String does not match expected pattern. + + + + No exception was thrown. + No exception was thrown. + + The member specified ({0}) could not be found. You might need to regenerate your private accessor, @@ -358,21 +412,16 @@ Gerçekte olan: {2} (nesne) + + String does not start with expected prefix. + String does not start with expected prefix. + + (Failed to get the message for an exception of type {0} due to an exception.) (Bir özel durum nedeniyle, {0} türündeki özel durum iletisi alınamadı.) - - Expected exception type:<{1}> but no exception was thrown. {0} - Beklenen özel durum türü:<{1}> ancak hiçbir özel durum oluşmadı. {0} - - - - Expected exception type:<{1}>. Actual exception type:<{2}>. {0} - Beklenen özel durum türü:<{1}>. Gerçek özel durum türü:<{2}>. {0} - - {0} ({1}) {0} ({1}) @@ -398,36 +447,6 @@ Gerçekte olan: {2} {1} üzerindeki {0} özelliği veya metodu boş IEnumerable<object[]> döndürür. - - Actual value <{2}> is not greater than expected value <{1}>. {0} - Geçerli <{2}> değeri, beklenen <{1}> değerinden daha büyük değil. {0} - - - - Actual value <{2}> is not greater than or equal to expected value <{1}>. {0} - Geçerli <{2}> değeri, beklenen <{1}> değerinden büyük veya bu değere eşit değil. {0} - - - - Actual value <{2}> is not less than expected value <{1}>. {0} - Geçerli <{2}> değeri, beklenen <{1}> değerinden daha küçük değil. {0} - - - - Actual value <{2}> is not less than or equal to expected value <{1}>. {0} - Geçerli <{2}> değeri, beklenen <{1}> değerinden küçük veya bu değere eşit değil. {0} - - - - Expected value <{1}> to be positive. {0} - Beklenen <{1}> değeri pozitif olmalıdır. {0} - - - - Expected value <{1}> to be negative. {0} - Beklenen <{1}> değeri negatif olmalıdır. {0} - - Assert.Equals should not be used for Assertions. Please use Assert.AreEqual & overloads instead. Assert.Equals, Onaylama için kullanılmamalı. Lütfen yerine Assert.AreEqual & aşırı yüklemeleri kullanın. @@ -458,6 +477,11 @@ Gerçekte olan: {2} CollectionAssert.ReferenceEquals, Onaylama için kullanılmamalı. Lütfen bunun yerine CollectionAssert yöntemlerini veya Assert.AreSame & aşırı yüklemelerini kullanın. + + Wrong exception type was thrown. + Wrong exception type was thrown. + + \ No newline at end of file diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hans.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hans.xlf index 94100054a3..ec618b8862 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hans.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hans.xlf @@ -17,46 +17,20 @@ 找到了重复项: <{1}>。{0} - - Expected:<{1}>. Actual:<{2}>. {0} - 应为: <{1}>,实际为: <{2}>。{0} - - - - Expected a difference no greater than <{3}> between expected value <{1}> and actual value <{2}>. {0} - 预期值 <{1}> 和实际值 <{2}> 之间的差不应大于 <{3}>。{0} - - - - Expected:<{1}>. Case is different for actual value:<{2}>. {0} - 应为: <{1}>。实际值的大小写有所不同: <{2}>。{0} - - - - Expected:<{1} ({2})>. Actual:<{3} ({4})>. {0} - 应为: <{1} ({2})>,实际为: <{3} ({4})>。{0} - - - - {0}{1} -{2} -{3} -{4} - {0}{1} -{2} -{3} -{4} + + Case differs. + Case differs. - - Expected: - 应为: - + + Expected a difference no greater than <{0}>. + Expected a difference no greater than <{0}>. + - - But was: - 但却是: - + + Expected values to be equal. + Expected values to be equal. + String lengths are both {0} but differ at index {1}. @@ -68,15 +42,25 @@ 字符串长度应为 {0},但为 {1}。 - - Expected any value except:<{1}>. Actual:<{2}>. {0} - 应为: <{1}> 以外的任意值,实际为: <{2}>。{0} - + + Expected a difference greater than <{0}>. + Expected a difference greater than <{0}>. + - - Expected a difference greater than <{3}> between expected value <{1}> and actual value <{2}>. {0} - 预期值 <{1}> 和实际值 <{2}> 之间的差应大于 <{3}>。{0} - + + Expected values to differ. + Expected values to differ. + + + + Expected references to be different. + Expected references to be different. + + + + Expected references to be the same. + Expected references to be the same. + Do not pass value types to AreSame(). Values converted to Object will never be the same. Consider using AreEqual(). {0} @@ -118,21 +102,6 @@ 这两个集合包含相同的元素。{0} - - '{0}' expression: '{1}'. - ‘{0}’表达式:‘{1}’。 - Example: "'value' expression: 'new object()'", where 'value' is the parameter name of an assertion method, and 'new object()' is the expression the user passed to the assert method. - - - '{0}' expression: '{1}', '{2}' expression: '{3}', '{4}' expression: '{5}'. - ‘{0}’表达式:‘{1}’,‘{2}’表达式:‘{3}’,‘{4}’表达式:‘{5}’。 - Example: "'substring' expression: 'userCode1', 'value' expression: 'userCode2'", where 'substring' and 'value' are the parameter names of an assertion method, and 'userCode's are the expressions the user passed to the assert method. - - - '{0}' expression: '{1}', '{2}' expression: '{3}'. - ‘{0}’表达式:‘{1}’,‘{2}’表达式:‘{3}’。 - Example: "'minValue' expression: 'userCode1', 'maxValue' expression: 'userCode2', 'value' expression: 'userCode3'", where 'minValue', 'maxValue', and 'value' are the parameter names of an assertion method, and 'userCode's are the expressions the user passed to the assert method. - {0}. {1} {0}。{1} @@ -143,39 +112,44 @@ 字符串“{0}”不包含字符串“{1}”。{2}。 - - Expected collection to contain the specified item. {0} - 预期集合包含指定项。{0} + + Expected collection to contain the specified item. + Expected collection to contain the specified item. + + + + Expected at least one item to match the predicate. + Expected at least one item to match the predicate. - - Expected at least one item to match the predicate. {0} - 应至少有一项与谓词匹配。{0} + + Expected collection to contain exactly one item but found {0} item(s). + Expected collection to contain exactly one item but found {0} item(s). - - Expected collection to contain exactly one element but found {1} element(s). {0} - 预期集合仅包含一个元素,但找到 {1} 个元素。{0} + + Expected exactly one item to match the predicate but found {0} item(s). + Expected exactly one item to match the predicate but found {0} item(s). - - Expected exactly one item to match the predicate but found {1} item(s). {0} - 应恰好只有一项与谓词匹配,但找到 {1} 项。{0} + + String does not contain the expected substring. + String does not contain the expected substring. - - String '{0}' does contain string '{1}'. {2}. - 字符串“{0}”确实包含字符串“{1}”。{2} + + Expected collection to not contain the specified item. + Expected collection to not contain the specified item. - - Expected collection to not contain the specified item. {0} - 预期集合不包含指定项。{0} + + Expected no items to match the predicate. + Expected no items to match the predicate. - - Expected no items to match the predicate. {0} - 预期没有与谓词匹配的项。{0} + + String contains the unexpected substring. + String contains the unexpected substring. @@ -183,11 +157,26 @@ 字符串 '{0}' 以字符串 '{1}'结尾。{2} + + String ends with unexpected suffix. + String ends with unexpected suffix. + + + + String matches pattern but should not. + String matches pattern but should not. + + String '{0}' starts with string '{1}'. {2} 字符串 '{0}' 以字符串 '{1}' 开头。{2} + + String starts with unexpected prefix. + String starts with unexpected prefix. + + Dynamic data field '{0}' should be static. 动态数据字段“{0}”应该是静态的。 @@ -237,9 +226,14 @@ Actual: {2} {0} 失败。{1} - - Expected collection of size {1}. Actual: {2}. {0} - 大小 {1} 的预期集合。实际: {2}。{0} + + String does not end with expected suffix. + String does not end with expected suffix. + + + + Expected collection to have the specified number of items. + Expected collection to have the specified number of items. @@ -252,9 +246,29 @@ Actual: {2} GitHub 票证 URL 无效 - - Value '{0}' is not within the expected range [{1}..{2}]. {3} - 值 "{0}" 不在预期范围 [{1}..{2}] 内。{3} + + Expected value to be exactly of the specified type. + Expected value to be exactly of the specified type. + + + + Expected condition to be false. + Expected condition to be false. + + + + Expected value to be greater than the specified bound. + Expected value to be greater than the specified bound. + + + + Expected value to be greater than or equal to the specified bound. + Expected value to be greater than or equal to the specified bound. + + + + Value is not within the expected range. + Value is not within the expected range. @@ -262,41 +276,81 @@ Actual: {2} 最大值必须大于或等于最小值。 - - {0} Expected type:<{1}>. Actual type:<{2}>. - {0} 类型应为: <{1}>。类型实为: <{2}>。 - + + Expected value to be of the specified type. + Expected value to be of the specified type. + + + + Expected value to be less than the specified bound. + Expected value to be less than the specified bound. + + + + Expected value to be less than or equal to the specified bound. + Expected value to be less than or equal to the specified bound. + String '{0}' does not match pattern '{1}'. {2} 字符串 '{0}' 与模式 '{1}' 不匹配。{2} - - Expected collection to contain any item but it is empty. {0} - 集合应包含任何项,但它为空。{0} + + Expected a negative value. + Expected a negative value. - - Wrong Type:<{1}>. Actual type:<{2}>. {0} - 错误类型为: <{1}>,实际类型为: <{2}>。{0} - + + Expected collection to contain any item but it is empty. + Expected collection to contain any item but it is empty. + - - {0} Expected exact type:<{1}>. Actual type:<{2}>. - {0} 预期的确切类型: <{1}>。实际类型: <{2}>。 - + + Value should not be exactly of the specified type. + Value should not be exactly of the specified type. + - - Wrong exact Type:<{1}>. Actual type:<{2}>. {0} - 错误的确切类型: <{1}>。实际类型: <{2}>。{0} - + + Value should not be of the specified type. + Value should not be of the specified type. + String '{0}' matches pattern '{1}'. {2} 字符串 '{0}' 与模式 '{1}' 匹配。{2} + + Expected a non-null value. + Expected a non-null value. + + + + Expected value to be null. + Expected value to be null. + + + + Expected a positive value. + Expected a positive value. + + + + Expected condition to be true. + Expected condition to be true. + + + + String does not match expected pattern. + String does not match expected pattern. + + + + No exception was thrown. + No exception was thrown. + + The member specified ({0}) could not be found. You might need to regenerate your private accessor, @@ -358,21 +412,16 @@ Actual: {2} (对象) + + String does not start with expected prefix. + String does not start with expected prefix. + + (Failed to get the message for an exception of type {0} due to an exception.) (因异常而未能获取类型为 {0} 的异常的消息。) - - Expected exception type:<{1}> but no exception was thrown. {0} - 预期异常类型:<{1}>,但未引发异常。{0} - - - - Expected exception type:<{1}>. Actual exception type:<{2}>. {0} - 预期异常类型:<{1}>。实际异常类型:<{2}>。{0} - - {0} ({1}) {0} ({1}) @@ -398,36 +447,6 @@ Actual: {2} {1} 上的属性或方法 {0} 返回空 IEnumerable<object[]>。 - - Actual value <{2}> is not greater than expected value <{1}>. {0} - 实际值 <{2}> 不大于预期值 <{1}>。{0} - - - - Actual value <{2}> is not greater than or equal to expected value <{1}>. {0} - 实际值 <{2}> 不大于或等于预期值 <{1}>。{0} - - - - Actual value <{2}> is not less than expected value <{1}>. {0} - 实际值 <{2}> 不小于预期值 <{1}>。{0} - - - - Actual value <{2}> is not less than or equal to expected value <{1}>. {0} - 实际值 <{2}> 不小于或等于预期值 <{1}>。{0} - - - - Expected value <{1}> to be positive. {0} - 预期值 <{1}> 为正值。{0} - - - - Expected value <{1}> to be negative. {0} - 预期值 <{1}> 为负值。{0} - - Assert.Equals should not be used for Assertions. Please use Assert.AreEqual & overloads instead. Assert.Equals 不应用于断言。请改用 Assert.AreEqual 和重载。 @@ -458,6 +477,11 @@ Actual: {2} CollectionAssert.ReferenceEquals 不应用于断言。请改用 CollectionAssert 方法或 Assert.AreSame 和重载。 + + Wrong exception type was thrown. + Wrong exception type was thrown. + + \ No newline at end of file diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hant.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hant.xlf index 3d758f945a..328ecf7d3a 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hant.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hant.xlf @@ -17,46 +17,20 @@ 找到重複的項目: <{1}>。{0} - - Expected:<{1}>. Actual:<{2}>. {0} - 預期: <{1}>。實際: <{2}>。{0} - - - - Expected a difference no greater than <{3}> between expected value <{1}> and actual value <{2}>. {0} - 預期值 <{1}> 和實際值 <{2}> 之間的預期差異沒有大於 <{3}>。{0} - - - - Expected:<{1}>. Case is different for actual value:<{2}>. {0} - 預期: <{1}>。大小寫與下列實際值不同: <{2}>。{0} - - - - Expected:<{1} ({2})>. Actual:<{3} ({4})>. {0} - 預期: <{1} ({2})>。實際: <{3} ({4})>。{0} - - - - {0}{1} -{2} -{3} -{4} - {0}{1} -{2} -{3} -{4} + + Case differs. + Case differs. - - Expected: - 預期為: - + + Expected a difference no greater than <{0}>. + Expected a difference no greater than <{0}>. + - - But was: - 但為: - + + Expected values to be equal. + Expected values to be equal. + String lengths are both {0} but differ at index {1}. @@ -68,15 +42,25 @@ 預期的字串長度為 {0},但為 {1}。 - - Expected any value except:<{1}>. Actual:<{2}>. {0} - 預期任何值 (<{1}> 除外)。實際: <{2}>。{0} - + + Expected a difference greater than <{0}>. + Expected a difference greater than <{0}>. + - - Expected a difference greater than <{3}> between expected value <{1}> and actual value <{2}>. {0} - 預期值 <{1}> 和實際值 <{2}> 之間的預期差異大於 <{3}>。{0} - + + Expected values to differ. + Expected values to differ. + + + + Expected references to be different. + Expected references to be different. + + + + Expected references to be the same. + Expected references to be the same. + Do not pass value types to AreSame(). Values converted to Object will never be the same. Consider using AreEqual(). {0} @@ -118,21 +102,6 @@ 兩個集合含有相同的項目。{0} - - '{0}' expression: '{1}'. - '{0}' 運算式: '{1}'。 - Example: "'value' expression: 'new object()'", where 'value' is the parameter name of an assertion method, and 'new object()' is the expression the user passed to the assert method. - - - '{0}' expression: '{1}', '{2}' expression: '{3}', '{4}' expression: '{5}'. - '{0}' 運算式: '{1}','{2}' 運算式: '{3}','{4}' 運算式: '{5}'。 - Example: "'substring' expression: 'userCode1', 'value' expression: 'userCode2'", where 'substring' and 'value' are the parameter names of an assertion method, and 'userCode's are the expressions the user passed to the assert method. - - - '{0}' expression: '{1}', '{2}' expression: '{3}'. - '{0}' 運算式: '{1}','{2}' 運算式: '{3}'。 - Example: "'minValue' expression: 'userCode1', 'maxValue' expression: 'userCode2', 'value' expression: 'userCode3'", where 'minValue', 'maxValue', and 'value' are the parameter names of an assertion method, and 'userCode's are the expressions the user passed to the assert method. - {0}. {1} {0}。{1} @@ -143,39 +112,44 @@ 字串 '{0}' 未包含字串 '{1}'。{2}。 - - Expected collection to contain the specified item. {0} - 預期集合包含指定的項目。{0} + + Expected collection to contain the specified item. + Expected collection to contain the specified item. + + + + Expected at least one item to match the predicate. + Expected at least one item to match the predicate. - - Expected at least one item to match the predicate. {0} - 必須至少有一個項目符合述詞。{0} + + Expected collection to contain exactly one item but found {0} item(s). + Expected collection to contain exactly one item but found {0} item(s). - - Expected collection to contain exactly one element but found {1} element(s). {0} - 預期集合應僅包含一個元素,但發現 {1} 個元素。{0} + + Expected exactly one item to match the predicate but found {0} item(s). + Expected exactly one item to match the predicate but found {0} item(s). - - Expected exactly one item to match the predicate but found {1} item(s). {0} - 預期只有一個項目符合述詞,但找到 {1} 個項目。{0} + + String does not contain the expected substring. + String does not contain the expected substring. - - String '{0}' does contain string '{1}'. {2}. - 字串 '{0}' 有包含字串 '{1}'。{2}。 + + Expected collection to not contain the specified item. + Expected collection to not contain the specified item. - - Expected collection to not contain the specified item. {0} - 預期集合不包含指定的項目。{0} + + Expected no items to match the predicate. + Expected no items to match the predicate. - - Expected no items to match the predicate. {0} - 預期沒有任何項目符合述詞。{0} + + String contains the unexpected substring. + String contains the unexpected substring. @@ -183,11 +157,26 @@ 字串 '{0}' 以字串 '{1}' 結尾。{2} + + String ends with unexpected suffix. + String ends with unexpected suffix. + + + + String matches pattern but should not. + String matches pattern but should not. + + String '{0}' starts with string '{1}'. {2} 字串 '{0}' 以字串 '{1}' 開頭。{2} + + String starts with unexpected prefix. + String starts with unexpected prefix. + + Dynamic data field '{0}' should be static. 動態資料欄位 '{0}' 應該為靜態。 @@ -237,9 +226,14 @@ Actual: {2} {0} 失敗。 {1} - - Expected collection of size {1}. Actual: {2}. {0} - 預期的大小集合 {1}。實際: {2}。{0} + + String does not end with expected suffix. + String does not end with expected suffix. + + + + Expected collection to have the specified number of items. + Expected collection to have the specified number of items. @@ -252,9 +246,29 @@ Actual: {2} 無效的 GitHub 票證 URL - - Value '{0}' is not within the expected range [{1}..{2}]. {3} - 值 '{0}' 不在預期的範圍 [{1}, {2}] 內。{3} + + Expected value to be exactly of the specified type. + Expected value to be exactly of the specified type. + + + + Expected condition to be false. + Expected condition to be false. + + + + Expected value to be greater than the specified bound. + Expected value to be greater than the specified bound. + + + + Expected value to be greater than or equal to the specified bound. + Expected value to be greater than or equal to the specified bound. + + + + Value is not within the expected range. + Value is not within the expected range. @@ -262,41 +276,81 @@ Actual: {2} 最大值必須大於或等於最小值。 - - {0} Expected type:<{1}>. Actual type:<{2}>. - {0} 預期的類型: <{1}>,實際的類型: <{2}>。 - + + Expected value to be of the specified type. + Expected value to be of the specified type. + + + + Expected value to be less than the specified bound. + Expected value to be less than the specified bound. + + + + Expected value to be less than or equal to the specified bound. + Expected value to be less than or equal to the specified bound. + String '{0}' does not match pattern '{1}'. {2} 字串 '{0}' 與模式 '{1}' 不符。{2} - - Expected collection to contain any item but it is empty. {0} - 預期集合包含任何專案,但卻是空的。{0} + + Expected a negative value. + Expected a negative value. - - Wrong Type:<{1}>. Actual type:<{2}>. {0} - 錯誤的類型: <{1}>。實際的類型: <{2}>。{0} - + + Expected collection to contain any item but it is empty. + Expected collection to contain any item but it is empty. + - - {0} Expected exact type:<{1}>. Actual type:<{2}>. - {0} 預期的精確類型:<{1}>。實際的類型: <{2}>。 - + + Value should not be exactly of the specified type. + Value should not be exactly of the specified type. + - - Wrong exact Type:<{1}>. Actual type:<{2}>. {0} - 錯誤的精確類型:<{1}>。實際的類型: <{2}>。 {0} - + + Value should not be of the specified type. + Value should not be of the specified type. + String '{0}' matches pattern '{1}'. {2} 字串 '{0}' 與模式 '{1}' 相符。{2} + + Expected a non-null value. + Expected a non-null value. + + + + Expected value to be null. + Expected value to be null. + + + + Expected a positive value. + Expected a positive value. + + + + Expected condition to be true. + Expected condition to be true. + + + + String does not match expected pattern. + String does not match expected pattern. + + + + No exception was thrown. + No exception was thrown. + + The member specified ({0}) could not be found. You might need to regenerate your private accessor, @@ -358,21 +412,16 @@ Actual: {2} (物件) + + String does not start with expected prefix. + String does not start with expected prefix. + + (Failed to get the message for an exception of type {0} due to an exception.) (因為發生例外狀況,所以無法取得類型 {0} 之例外狀況的訊息。) - - Expected exception type:<{1}> but no exception was thrown. {0} - 預期的例外狀況類型:<{1}>,但未擲回任何例外狀況。{0} - - - - Expected exception type:<{1}>. Actual exception type:<{2}>. {0} - 預期的例外狀況類型:<{1}>。實際的例外狀況類型:<{2}>。{0} - - {0} ({1}) {0} ({1}) @@ -398,36 +447,6 @@ Actual: {2} {1} 上的屬性或方法 {0} 傳回空的 IEnumerable<object[]>。 - - Actual value <{2}> is not greater than expected value <{1}>. {0} - 實際值 <{2}> 不大於預期值 <{1}>。{0} - - - - Actual value <{2}> is not greater than or equal to expected value <{1}>. {0} - 實際值 <{2}> 不大於或等於預期值 <{1}>。{0} - - - - Actual value <{2}> is not less than expected value <{1}>. {0} - 實際值 <{2}> 不小於預期值 <{1}>。{0} - - - - Actual value <{2}> is not less than or equal to expected value <{1}>. {0} - 實際值 <{2}> 不小於或等於預期值 <{1}>。{0} - - - - Expected value <{1}> to be positive. {0} - 預期值 <{1}> 為正數。{0} - - - - Expected value <{1}> to be negative. {0} - 預期值 <{1}> 為負數。{0} - - Assert.Equals should not be used for Assertions. Please use Assert.AreEqual & overloads instead. Assert.Equals 不應使用於判斷提示。請改用 Assert.AreEqual 及多載。 @@ -458,6 +477,11 @@ Actual: {2} CollectionAssert.ReferenceEquals 不應使用於判斷提示。請改用 CollectionAssert 方法或 Assert.AreSame 及其多載。 + + Wrong exception type was thrown. + Wrong exception type was thrown. + + \ No newline at end of file diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/OutputTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/OutputTests.cs index 0a2f3d678e..4f260239db 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/OutputTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/OutputTests.cs @@ -17,7 +17,12 @@ public async Task DetailedOutputIsAsExpected(string tfm) TestHostResult testHostResult = await testHost.ExecuteAsync("--output detailed", cancellationToken: TestContext.CancellationToken); // Assert - testHostResult.AssertOutputContains("Assert.AreEqual failed. Expected:<1>. Actual:<2>."); + testHostResult.AssertOutputContains(""" + Assert.AreEqual failed. + Expected values to be equal. + expected: 1 + actual: 2 + """); testHostResult.AssertOutputContains(""" Standard output Console message diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TrxReportTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TrxReportTests.cs index 2943f72d25..87f16e337b 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TrxReportTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TrxReportTests.cs @@ -33,7 +33,15 @@ public async Task TrxReport_WhenTestFails_ContainsExceptionInfoInOutput(string t // Verify that exception message is present Assert.Contains(@"", trxContent, trxContent); - Assert.Contains("Assert.AreEqual failed. Expected:<1>. Actual:<2>.", trxContent, trxContent); + Assert.Contains( + """ + Assert.AreEqual failed. + Expected values to be equal. + expected: 1 + actual: 2 + """, + trxContent, + trxContent); // Verify that stack trace is present Assert.Contains(@"", trxContent, trxContent); diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.AreEqualTests.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.AreEqualTests.cs index 1ba1daaad9..db39b8f0f9 100644 --- a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.AreEqualTests.cs +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.AreEqualTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using AwesomeAssertions; @@ -19,7 +19,12 @@ public void AreNotEqualShouldFailWhenNotEqualTypeWithMessage() { Action action = () => Assert.AreNotEqual(1, 1, "A Message"); action.Should().Throw() - .And.Message.Should().Contain("A Message"); + .WithMessage(""" + Assert.AreNotEqual(1, 1) failed. A Message + Expected values to differ. + notExpected: 1 + actual: 1 + """); } public void AreNotEqualShouldFailWhenNotEqualString() @@ -32,7 +37,12 @@ public void AreNotEqualShouldFailWhenNotEqualStringWithMessage() { Action action = () => Assert.AreNotEqual("A", "A", "A Message"); action.Should().Throw() - .And.Message.Should().Contain("A Message"); + .WithMessage(""" + Assert.AreNotEqual("A", "A") failed. A Message + Expected values to differ. + notExpected: "A" + actual: "A" + """); } [SuppressMessage("Globalization", "CA1304:Specify CultureInfo", Justification = "Testing the API without the culture")] @@ -52,7 +62,12 @@ public void AreNotEqualShouldFailWhenNotEqualIntWithMessage() { Action action = () => Assert.AreNotEqual(1, 1, "A Message"); action.Should().Throw() - .And.Message.Should().Contain("A Message"); + .WithMessage(""" + Assert.AreNotEqual(1, 1) failed. A Message + Expected values to differ. + notExpected: 1 + actual: 1 + """); } public void AreNotEqualShouldFailWhenNotEqualLong() @@ -65,7 +80,12 @@ public void AreNotEqualShouldFailWhenNotEqualLongWithMessage() { Action action = () => Assert.AreNotEqual(1L, 1L, "A Message"); action.Should().Throw() - .And.Message.Should().Contain("A Message"); + .WithMessage(""" + Assert.AreNotEqual(1L, 1L) failed. A Message + Expected values to differ. + notExpected: 1 + actual: 1 + """); } public void AreNotEqualShouldFailWhenNotEqualLongWithDelta() @@ -84,7 +104,12 @@ public void AreNotEqualShouldFailWhenNotEqualDecimalWithMessage() { Action action = () => Assert.AreNotEqual(0.1M, 0.1M, "A Message"); action.Should().Throw() - .And.Message.Should().Contain("A Message"); + .WithMessage(""" + Assert.AreNotEqual(0.1M, 0.1M) failed. A Message + Expected values to differ. + notExpected: 0.1 + actual: 0.1 + """); } public void AreNotEqualShouldFailWhenNotEqualDecimalWithDelta() @@ -103,7 +128,12 @@ public void AreNotEqualShouldFailWhenNotEqualDoubleWithMessage() { Action action = () => Assert.AreNotEqual(0.1, 0.1, "A Message"); action.Should().Throw() - .And.Message.Should().Contain("A Message"); + .WithMessage(""" + Assert.AreNotEqual(0.1, 0.1) failed. A Message + Expected values to differ. + notExpected: 0.1 + actual: 0.1 + """); } public void AreNotEqualShouldFailWhenNotEqualDoubleWithDelta() @@ -122,7 +152,12 @@ public void AreNotEqualShouldFailWhenFloatDoubleWithMessage() { Action action = () => Assert.AreNotEqual(100E-2, 100E-2, "A Message"); action.Should().Throw() - .And.Message.Should().Contain("A Message"); + .WithMessage(""" + Assert.AreNotEqual(100E-2, 100E-2) failed. A Message + Expected values to differ. + notExpected: 1 + actual: 1 + """); } public void AreNotEqualShouldFailWhenNotEqualFloatWithDelta() @@ -141,7 +176,12 @@ public void AreEqualShouldFailWhenNotEqualTypeWithMessage() { Action action = () => Assert.AreEqual(null, "string", "A Message"); action.Should().Throw() - .And.Message.Should().Contain("A Message"); + .WithMessage(""" + Assert.AreEqual(null, "string") failed. A Message + Expected values to be equal. + expected: (null) + actual: "string" + """); } public void AreEqual_WithTurkishCultureAndIgnoreCase_Throws() @@ -174,7 +214,12 @@ public void AreEqual_WithEnglishCultureAndDoesNotIgnoreCase_Throws() // Won't ignore case. Action action = () => Assert.AreEqual(expected, actual, false, englishCulture); action.Should().Throw() - .WithMessage("Assert.AreEqual failed. Expected:. Case is different for actual value:. 'expected' expression: 'expected', 'actual' expression: 'actual'."); + .WithMessage("""" + Assert.AreEqual(expected, actual) failed. + Case differs. + expected: "i" + actual: "I" + """"); } public void AreEqual_WithTurkishCultureAndDoesNotIgnoreCase_Throws() @@ -191,8 +236,7 @@ public void AreEqual_WithTurkishCultureAndDoesNotIgnoreCase_Throws() public void AreEqualShouldFailWhenNotEqualStringWithMessage() { Action action = () => Assert.AreEqual("A", "a", "A Message"); - action.Should().Throw() - .And.Message.Should().Contain("A Message"); + action.Should().Throw().And.Message.Should().Contain("A Message"); } [SuppressMessage("Globalization", "CA1304:Specify CultureInfo", Justification = "Testing the API without the culture")] @@ -212,7 +256,12 @@ public void AreEqualShouldFailWhenNotEqualIntWithMessage() { Action action = () => Assert.AreEqual(1, 2, "A Message"); action.Should().Throw() - .And.Message.Should().Contain("A Message"); + .WithMessage(""" + Assert.AreEqual(1, 2) failed. A Message + Expected values to be equal. + expected: 1 + actual: 2 + """); } public void AreEqualShouldFailWhenNotEqualLong() @@ -225,7 +274,12 @@ public void AreEqualShouldFailWhenNotEqualLongWithMessage() { Action action = () => Assert.AreEqual(1L, 2L, "A Message"); action.Should().Throw() - .And.Message.Should().Contain("A Message"); + .WithMessage(""" + Assert.AreEqual(1L, 2L) failed. A Message + Expected values to be equal. + expected: 1 + actual: 2 + """); } public void AreEqualShouldFailWhenNotEqualLongWithDelta() @@ -244,7 +298,12 @@ public void AreEqualShouldFailWhenNotEqualDoubleWithMessage() { Action action = () => Assert.AreEqual(0.1, 0.2, "A Message"); action.Should().Throw() - .And.Message.Should().Contain("A Message"); + .WithMessage(""" + Assert.AreEqual(0.1, 0.2) failed. A Message + Expected values to be equal. + expected: 0.1 + actual: 0.2 + """); } public void AreEqualShouldFailWhenNotEqualDoubleWithDelta() @@ -264,7 +323,12 @@ public void AreEqualShouldFailWhenNotEqualDecimalWithMessage() { Action action = () => Assert.AreEqual(0.1M, 0.2M, "A Message"); action.Should().Throw() - .And.Message.Should().Contain("A Message"); + .WithMessage(""" + Assert.AreEqual(0.1M, 0.2M) failed. A Message + Expected values to be equal. + expected: 0.1 + actual: 0.2 + """); } public void AreEqualShouldFailWhenNotEqualDecimalWithDelta() @@ -283,7 +347,12 @@ public void AreEqualShouldFailWhenFloatDoubleWithMessage() { Action action = () => Assert.AreEqual(100E-2, 200E-2, "A Message"); action.Should().Throw() - .And.Message.Should().Contain("A Message"); + .WithMessage(""" + Assert.AreEqual(100E-2, 200E-2) failed. A Message + Expected values to be equal. + expected: 1 + actual: 2 + """); } public void AreEqualShouldFailWhenNotEqualFloatWithDelta() @@ -302,7 +371,12 @@ public void AreEqualTwoObjectsDifferentTypeShouldFail() { Action action = () => Assert.AreEqual(new object(), 1); action.Should().Throw() - .And.Message.Should().Contain("Assert.AreEqual failed. Expected:. Actual:<1 (System.Int32)>."); + .WithMessage(""" + Assert.AreEqual(new object(), 1) failed. + Expected values to be equal. + expected: (System.Object) + actual: 1 (System.Int32) + """); } public void AreEqualWithTypeOverridingEqualsShouldWork() @@ -373,7 +447,12 @@ public async Task GenericAreEqual_InterpolatedString_DifferentValues_ShouldFail( DateTime dateTime = DateTime.Now; Func action = async () => Assert.AreEqual(0, 1, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}"); (await action.Should().ThrowAsync()) - .WithMessage($"Assert.AreEqual failed. Expected:<0>. Actual:<1>. 'expected' expression: '0', 'actual' expression: '1'. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + .WithMessage(""" + Assert.AreEqual(0, 1) failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString()* + Expected values to be equal. + expected: 0 + actual: 1 + """); o.WasToStringCalled.Should().BeTrue(); } @@ -390,7 +469,12 @@ public async Task GenericAreNotEqual_InterpolatedString_SameValues_ShouldFail() DateTime dateTime = DateTime.Now; Func action = async () => Assert.AreNotEqual(0, 0, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}"); (await action.Should().ThrowAsync()) - .WithMessage($"Assert.AreNotEqual failed. Expected any value except:<0>. Actual:<0>. 'notExpected' expression: '0', 'actual' expression: '0'. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + .WithMessage(""" + Assert.AreNotEqual(0, 0) failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString()* + Expected values to differ. + notExpected: 0 + actual: 0 + """); o.WasToStringCalled.Should().BeTrue(); } @@ -407,7 +491,12 @@ public async Task FloatAreEqual_InterpolatedString_DifferentValues_ShouldFail() DateTime dateTime = DateTime.Now; Func action = async () => Assert.AreEqual(1.0f, 1.1f, 0.001f, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}"); (await action.Should().ThrowAsync()) - .WithMessage($"Assert.AreEqual failed. Expected a difference no greater than <0.001> between expected value <1> and actual value <1.1>. 'expected' expression: '1.0f', 'actual' expression: '1.1f'. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + .WithMessage(""" + Assert.AreEqual(1.0f, 1.1f) failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString()* + Expected a difference no greater than <0.001>. + expected: 1 + actual: 1.1 + """); o.WasToStringCalled.Should().BeTrue(); } @@ -424,7 +513,12 @@ public async Task FloatAreNotEqual_InterpolatedString_SameValues_ShouldFail() DateTime dateTime = DateTime.Now; Func action = async () => Assert.AreNotEqual(1.0f, 1.1f, 0.2f, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}"); (await action.Should().ThrowAsync()) - .WithMessage($"Assert.AreNotEqual failed. Expected a difference greater than <0.2> between expected value <1> and actual value <1.1>. 'notExpected' expression: '1.0f', 'actual' expression: '1.1f'. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + .WithMessage(""" + Assert.AreNotEqual(1.0f, 1.1f) failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString()* + Expected a difference greater than <0.2>. + notExpected: 1 + actual: 1.1 + """); o.WasToStringCalled.Should().BeTrue(); } @@ -441,7 +535,12 @@ public async Task DecimalAreEqual_InterpolatedString_DifferentValues_ShouldFail( DateTime dateTime = DateTime.Now; Func action = async () => Assert.AreEqual(1.0m, 1.1m, 0.001m, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}"); (await action.Should().ThrowAsync()) - .WithMessage($"Assert.AreEqual failed. Expected a difference no greater than <0.001> between expected value <1.0> and actual value <1.1>. 'expected' expression: '1.0m', 'actual' expression: '1.1m'. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + .WithMessage(""" + Assert.AreEqual(1.0m, 1.1m) failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString()* + Expected a difference no greater than <0.001>. + expected: 1.0 + actual: 1.1 + """); o.WasToStringCalled.Should().BeTrue(); } @@ -458,7 +557,12 @@ public async Task DecimalAreNotEqual_InterpolatedString_SameValues_ShouldFail() DateTime dateTime = DateTime.Now; Func action = async () => Assert.AreNotEqual(1.0m, 1.1m, 0.2m, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}"); (await action.Should().ThrowAsync()) - .WithMessage($"Assert.AreNotEqual failed. Expected a difference greater than <0.2> between expected value <1.0> and actual value <1.1>. 'notExpected' expression: '1.0m', 'actual' expression: '1.1m'. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + .WithMessage(""" + Assert.AreNotEqual(1.0m, 1.1m) failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString()* + Expected a difference greater than <0.2>. + notExpected: 1.0 + actual: 1.1 + """); o.WasToStringCalled.Should().BeTrue(); } @@ -475,7 +579,12 @@ public async Task LongAreEqual_InterpolatedString_DifferentValues_ShouldFail() DateTime dateTime = DateTime.Now; Func action = async () => Assert.AreEqual(1L, 2L, 0L, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}"); (await action.Should().ThrowAsync()) - .WithMessage($"Assert.AreEqual failed. Expected a difference no greater than <0> between expected value <1> and actual value <2>. 'expected' expression: '1L', 'actual' expression: '2L'. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + .WithMessage(""" + Assert.AreEqual(1L, 2L) failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString()* + Expected a difference no greater than <0>. + expected: 1 + actual: 2 + """); o.WasToStringCalled.Should().BeTrue(); } @@ -492,7 +601,12 @@ public async Task LongAreNotEqual_InterpolatedString_SameValues_ShouldFail() DateTime dateTime = DateTime.Now; Func action = async () => Assert.AreNotEqual(1L, 2L, 1L, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}"); (await action.Should().ThrowAsync()) - .WithMessage($"Assert.AreNotEqual failed. Expected a difference greater than <1> between expected value <1> and actual value <2>. 'notExpected' expression: '1L', 'actual' expression: '2L'. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + .WithMessage(""" + Assert.AreNotEqual(1L, 2L) failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString()* + Expected a difference greater than <1>. + notExpected: 1 + actual: 2 + """); o.WasToStringCalled.Should().BeTrue(); } @@ -509,7 +623,12 @@ public async Task DoubleAreEqual_InterpolatedString_DifferentValues_ShouldFail() DateTime dateTime = DateTime.Now; Func action = async () => Assert.AreEqual(1.0d, 1.1d, 0.001d, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}"); (await action.Should().ThrowAsync()) - .WithMessage($"Assert.AreEqual failed. Expected a difference no greater than <0.001> between expected value <1> and actual value <1.1>. 'expected' expression: '1.0d', 'actual' expression: '1.1d'. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + .WithMessage(""" + Assert.AreEqual(1.0d, 1.1d) failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString()* + Expected a difference no greater than <0.001>. + expected: 1 + actual: 1.1 + """); o.WasToStringCalled.Should().BeTrue(); } @@ -526,7 +645,12 @@ public async Task DoubleAreNotEqual_InterpolatedString_SameValues_ShouldFail() DateTime dateTime = DateTime.Now; Func action = async () => Assert.AreNotEqual(1.0d, 1.1d, 0.2d, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}"); (await action.Should().ThrowAsync()) - .WithMessage($"Assert.AreNotEqual failed. Expected a difference greater than <0.2> between expected value <1> and actual value <1.1>. 'notExpected' expression: '1.0d', 'actual' expression: '1.1d'. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + .WithMessage(""" + Assert.AreNotEqual(1.0d, 1.1d) failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString()* + Expected a difference greater than <0.2>. + notExpected: 1 + actual: 1.1 + """); o.WasToStringCalled.Should().BeTrue(); } @@ -698,13 +822,23 @@ Specified argument was out of the range of valid values. public void FloatAreEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualDifferenceGreaterThanDeltaPositive_DeltaIsNumeric_ShouldFail() { Action action = () => Assert.AreEqual(5.0f, 2.0f, 2.0f); // difference is 3. Delta is 2 - action.Should().Throw().WithMessage("Assert.AreEqual failed. Expected a difference no greater than <2> between expected value <5> and actual value <2>. 'expected' expression: '5.0f', 'actual' expression: '2.0f'."); + action.Should().Throw().WithMessage("""" + Assert.AreEqual(5.0f, 2.0f) failed. + Expected a difference no greater than <2>. + expected: 5 + actual: 2 + """"); } public void FloatAreEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualDifferenceGreaterThanDeltaNegative_DeltaIsNumeric_ShouldFail() { Action action = () => Assert.AreEqual(2.0f, 5.0f, 2.0f); // difference is -3. Delta is 2 - action.Should().Throw().WithMessage("Assert.AreEqual failed. Expected a difference no greater than <2> between expected value <2> and actual value <5>. 'expected' expression: '2.0f', 'actual' expression: '5.0f'."); + action.Should().Throw().WithMessage("""" + Assert.AreEqual(2.0f, 5.0f) failed. + Expected a difference no greater than <2>. + expected: 2 + actual: 5 + """"); } public void FloatAreEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualDifferenceLessThanDeltaPositive_DeltaIsNumeric_ShouldPass() @@ -716,13 +850,23 @@ public void FloatAreEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualDif public void FloatAreEqual_ExpectedIsNumeric_ActualIsNaN_DeltaIsNumeric_ShouldFail() { Action action = () => Assert.AreEqual(5.0f, float.NaN, 2.0f); - action.Should().Throw().WithMessage("Assert.AreEqual failed. Expected a difference no greater than <2> between expected value <5> and actual value . 'expected' expression: '5.0f', 'actual' expression: 'float.NaN'."); + action.Should().Throw().WithMessage("""" + Assert.AreEqual(5.0f, float.NaN) failed. + Expected a difference no greater than <2>. + expected: 5 + actual: NaN + """"); } public void FloatAreEqual_ExpectedIsNaN_ActualIsNumeric_DeltaIsNumeric_ShouldFail() { Action action = () => Assert.AreEqual(float.NaN, 5.0f, 2.0f); - action.Should().Throw().WithMessage("Assert.AreEqual failed. Expected a difference no greater than <2> between expected value and actual value <5>. 'expected' expression: 'float.NaN', 'actual' expression: '5.0f'."); + action.Should().Throw().WithMessage("""" + Assert.AreEqual(float.NaN, 5.0f) failed. + Expected a difference no greater than <2>. + expected: NaN + actual: 5 + """"); } public void FloatAreEqual_ExpectedIsNaN_ActualIsNaN_DeltaIsNumeric_ShouldPass() @@ -910,13 +1054,23 @@ public void FloatAreNotEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActual public void FloatAreNotEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualDifferenceLessThanDeltaPositive_DeltaIsNumeric_ShouldFail() { Action action = () => Assert.AreNotEqual(5.0f, 4.0f, 2.0f); // difference is 1. Delta is 2 - action.Should().Throw().WithMessage("Assert.AreNotEqual failed. Expected a difference greater than <2> between expected value <5> and actual value <4>. 'notExpected' expression: '5.0f', 'actual' expression: '4.0f'."); + action.Should().Throw().WithMessage("""" + Assert.AreNotEqual(5.0f, 4.0f) failed. + Expected a difference greater than <2>. + notExpected: 5 + actual: 4 + """"); } public void FloatAreNotEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualDifferenceLessThanDeltaNegative_DeltaIsNumeric_ShouldFail() { Action action = () => Assert.AreNotEqual(4.0f, 5.0f, 2.0f); // difference is -1. Delta is 2 - action.Should().Throw().WithMessage("Assert.AreNotEqual failed. Expected a difference greater than <2> between expected value <4> and actual value <5>. 'notExpected' expression: '4.0f', 'actual' expression: '5.0f'."); + action.Should().Throw().WithMessage("""" + Assert.AreNotEqual(4.0f, 5.0f) failed. + Expected a difference greater than <2>. + notExpected: 4 + actual: 5 + """"); } public void FloatAreNotEqual_ExpectedIsNumeric_ActualIsNaN_DeltaIsNumeric_ShouldPass() => Assert.AreNotEqual(5.0f, float.NaN, 2.0f); @@ -927,7 +1081,12 @@ public void FloatAreNotEqual_ExpectedIsNaN_ActualIsNumeric_DeltaIsNumeric_Should public void FloatAreNotEqual_ExpectedIsNaN_ActualIsNaN_DeltaIsNumeric_ShouldFail() { Action action = () => Assert.AreNotEqual(float.NaN, float.NaN, 2.0f); - action.Should().Throw().WithMessage("Assert.AreNotEqual failed. Expected a difference greater than <2> between expected value and actual value . 'notExpected' expression: 'float.NaN', 'actual' expression: 'float.NaN'."); + action.Should().Throw().WithMessage("""" + Assert.AreNotEqual(float.NaN, float.NaN) failed. + Expected a difference greater than <2>. + notExpected: NaN + actual: NaN + """"); } public void DoubleAreEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualNotEquals_DeltaIsNaN_ShouldFail() @@ -1111,14 +1270,24 @@ public void DoubleAreEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualDi { Action action = () => Assert.AreEqual(5.0d, 2.0d, 2.0d); // difference is 3. Delta is 2 action.Should().Throw() - .WithMessage("Assert.AreEqual failed. Expected a difference no greater than <2> between expected value <5> and actual value <2>. 'expected' expression: '5.0d', 'actual' expression: '2.0d'."); + .WithMessage("""" + Assert.AreEqual(5.0d, 2.0d) failed. + Expected a difference no greater than <2>. + expected: 5 + actual: 2 + """"); } public void DoubleAreEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualDifferenceGreaterThanDeltaNegative_DeltaIsNumeric_ShouldFail() { Action action = () => Assert.AreEqual(2.0d, 5.0d, 2.0d); // difference is -3. Delta is 2 action.Should().Throw() - .WithMessage("Assert.AreEqual failed. Expected a difference no greater than <2> between expected value <2> and actual value <5>. 'expected' expression: '2.0d', 'actual' expression: '5.0d'."); + .WithMessage("""" + Assert.AreEqual(2.0d, 5.0d) failed. + Expected a difference no greater than <2>. + expected: 2 + actual: 5 + """"); } public void DoubleAreEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualDifferenceLessThanDeltaPositive_DeltaIsNumeric_ShouldPass() @@ -1131,14 +1300,24 @@ public void DoubleAreEqual_ExpectedIsNumeric_ActualIsNaN_DeltaIsNumeric_ShouldFa { Action action = () => Assert.AreEqual(5.0d, double.NaN, 2.0d); action.Should().Throw() - .WithMessage("Assert.AreEqual failed. Expected a difference no greater than <2> between expected value <5> and actual value . 'expected' expression: '5.0d', 'actual' expression: 'double.NaN'."); + .WithMessage("""" + Assert.AreEqual(5.0d, double.NaN) failed. + Expected a difference no greater than <2>. + expected: 5 + actual: NaN + """"); } public void DoubleAreEqual_ExpectedIsNaN_ActualIsNumeric_DeltaIsNumeric_ShouldFail() { Action action = () => Assert.AreEqual(double.NaN, 5.0d, 2.0d); action.Should().Throw() - .WithMessage("Assert.AreEqual failed. Expected a difference no greater than <2> between expected value and actual value <5>. 'expected' expression: 'double.NaN', 'actual' expression: '5.0d'."); + .WithMessage("""" + Assert.AreEqual(double.NaN, 5.0d) failed. + Expected a difference no greater than <2>. + expected: NaN + actual: 5 + """"); } public void DoubleAreEqual_ExpectedIsNaN_ActualIsNaN_DeltaIsNumeric_ShouldPass() @@ -1334,14 +1513,24 @@ public void DoubleAreNotEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActua { Action action = () => Assert.AreNotEqual(5.0d, 4.0d, 2.0d); // difference is 1. Delta is 2 action.Should().Throw() - .WithMessage("Assert.AreNotEqual failed. Expected a difference greater than <2> between expected value <5> and actual value <4>. 'notExpected' expression: '5.0d', 'actual' expression: '4.0d'."); + .WithMessage("""" + Assert.AreNotEqual(5.0d, 4.0d) failed. + Expected a difference greater than <2>. + notExpected: 5 + actual: 4 + """"); } public void DoubleAreNotEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualDifferenceLessThanDeltaNegative_DeltaIsNumeric_ShouldFail() { Action action = () => Assert.AreNotEqual(4.0d, 5.0d, 2.0d); // difference is -1. Delta is 2 action.Should().Throw() - .WithMessage("Assert.AreNotEqual failed. Expected a difference greater than <2> between expected value <4> and actual value <5>. 'notExpected' expression: '4.0d', 'actual' expression: '5.0d'."); + .WithMessage("""" + Assert.AreNotEqual(4.0d, 5.0d) failed. + Expected a difference greater than <2>. + notExpected: 4 + actual: 5 + """"); } public void DoubleAreNotEqual_ExpectedIsNumeric_ActualIsNaN_DeltaIsNumeric_ShouldPass() => Assert.AreNotEqual(5.0d, double.NaN, 2.0d); @@ -1353,7 +1542,12 @@ public void DoubleAreNotEqual_ExpectedIsNaN_ActualIsNaN_DeltaIsNumeric_ShouldFai { Action action = () => Assert.AreNotEqual(double.NaN, double.NaN, 2.0d); action.Should().Throw() - .WithMessage("Assert.AreNotEqual failed. Expected a difference greater than <2> between expected value and actual value . 'notExpected' expression: 'double.NaN', 'actual' expression: 'double.NaN'."); + .WithMessage("""" + Assert.AreNotEqual(double.NaN, double.NaN) failed. + Expected a difference greater than <2>. + notExpected: NaN + actual: NaN + """"); } private class TypeOverridesEquals @@ -1412,10 +1606,11 @@ public void AreEqualStringDifferenceAtBeginning() Action action = () => Assert.AreEqual("baaa", "aaaa"); action.Should().Throw() .WithMessage(""" - Assert.AreEqual failed. String lengths are both 4 but differ at index 0. 'expected' expression: '"baaa"', 'actual' expression: '"aaaa"'. - Expected: "baaa" - But was: "aaaa" - -----------^ + Assert.AreEqual("baaa", "aaaa") failed. + String lengths are both 4 but differ at index 0. + expected: "baaa" + actual: "aaaa" + -----------^ """); } @@ -1424,10 +1619,11 @@ public void AreEqualStringDifferenceAtEnd() Action action = () => Assert.AreEqual("aaaa", "aaab"); action.Should().Throw() .WithMessage(""" - Assert.AreEqual failed. String lengths are both 4 but differ at index 3. 'expected' expression: '"aaaa"', 'actual' expression: '"aaab"'. - Expected: "aaaa" - But was: "aaab" - --------------^ + Assert.AreEqual("aaaa", "aaab") failed. + String lengths are both 4 but differ at index 3. + expected: "aaaa" + actual: "aaab" + --------------^ """); } @@ -1436,10 +1632,11 @@ public void AreEqualStringWithSpecialCharactersShouldEscape() Action action = () => Assert.AreEqual("aa\ta", "aa a"); action.Should().Throw() .WithMessage(""" - Assert.AreEqual failed. String lengths are both 4 but differ at index 2. 'expected' expression: '"aa\ta"', 'actual' expression: '"aa a"'. - Expected: "aa␉a" - But was: "aa a" - -------------^ + Assert.AreEqual("aa\ta", "aa a") failed. + String lengths are both 4 but differ at index 2. + expected: "aa␉a" + actual: "aa a" + -------------^ """); } @@ -1451,10 +1648,11 @@ public void AreEqualLongStringsShouldTruncateAndShowContext() Action action = () => Assert.AreEqual(expected, actual); action.Should().Throw() .WithMessage(""" - Assert.AreEqual failed. String lengths are both 201 but differ at index 100. 'expected' expression: 'expected', 'actual' expression: 'actual'. - Expected: "...aaaaaaaaaaaaaaaaaabcccccccccccccccc..." - But was: "...aaaaaaaaaaaaaaaaaadcccccccccccccccc..." - --------------------------------^ + Assert.AreEqual(expected, actual) failed. + String lengths are both 201 but differ at index 100. + expected: "...aaaaaaaaaaaaaaaaaabcccccccccccccccc..." + actual: "...aaaaaaaaaaaaaaaaaadcccccccccccccccc..." + --------------------------------^ """); } @@ -1463,10 +1661,11 @@ public void AreEqualStringWithCultureShouldUseEnhancedMessage() Action action = () => Assert.AreEqual("aaaa", "aaab", false, CultureInfo.InvariantCulture); action.Should().Throw() .WithMessage(""" - Assert.AreEqual failed. String lengths are both 4 but differ at index 3. 'expected' expression: '"aaaa"', 'actual' expression: '"aaab"'. - Expected: "aaaa" - But was: "aaab" - --------------^ + Assert.AreEqual("aaaa", "aaab") failed. + String lengths are both 4 but differ at index 3. + expected: "aaaa" + actual: "aaab" + --------------^ """); } @@ -1475,10 +1674,11 @@ public void AreEqualStringWithDifferentLength() Action action = () => Assert.AreEqual("aaaa", "aaa"); action.Should().Throw() .WithMessage(""" - Assert.AreEqual failed. Expected string length 4 but was 3. 'expected' expression: '"aaaa"', 'actual' expression: '"aaa"'. - Expected: "aaaa" - But was: "aaa" - --------------^ + Assert.AreEqual("aaaa", "aaa") failed. + Expected string length 4 but was 3. + expected: "aaaa" + actual: "aaa" + --------------^ """); } @@ -1487,10 +1687,11 @@ public void AreEqualShorterExpectedString() Action action = () => Assert.AreEqual("aaa", "aaab"); action.Should().Throw() .WithMessage(""" - Assert.AreEqual failed. Expected string length 3 but was 4. 'expected' expression: '"aaa"', 'actual' expression: '"aaab"'. - Expected: "aaa" - But was: "aaab" - --------------^ + Assert.AreEqual("aaa", "aaab") failed. + Expected string length 3 but was 4. + expected: "aaa" + actual: "aaab" + --------------^ """); } @@ -1499,22 +1700,24 @@ public void AreEqualStringWithUserMessage() Action action = () => Assert.AreEqual("aaaa", "aaab", "My custom message"); action.Should().Throw() .WithMessage(""" - Assert.AreEqual failed. String lengths are both 4 but differ at index 3. 'expected' expression: '"aaaa"', 'actual' expression: '"aaab"'. My custom message - Expected: "aaaa" - But was: "aaab" - --------------^ + Assert.AreEqual("aaaa", "aaab") failed. My custom message + String lengths are both 4 but differ at index 3. + expected: "aaaa" + actual: "aaab" + --------------^ """); } public void AreEqualStringWithEmojis() { - Action action = () => Assert.AreEqual("🥰", "aaab"); + Action action = () => Assert.AreEqual("??", "aaab"); action.Should().Throw() .WithMessage(""" - Assert.AreEqual failed. Expected string length 2 but was 4. 'expected' expression: '"🥰"', 'actual' expression: '"aaab"'. - Expected: "🥰" - But was: "aaab" - -----------^ + Assert.AreEqual("??", "aaab") failed. + Expected string length 2 but was 4. + expected: "??" + actual: "aaab" + -----------^ """); } @@ -1722,4 +1925,94 @@ private void StringPreviewsAreEqual(string expected, string actual) """); } } + + #region Truncation and newline escaping + + public void AreEqual_WithLongExpression_ShouldTruncateExpression() + { + object aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ = 1; + + Action action = () => Assert.AreEqual(aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ, 2); + action.Should().Throw() + .WithMessage(""" + Assert.AreEqual(aVeryLongVariableNameThatExceedsOneHundredCharacte..., 2) failed. + Expected values to be equal. + expected: 1 + actual: 2 + """); + } + + public void AreEqual_WithLongToStringValue_ShouldTruncateValue() + { + var expected = new ObjectWithLongToString(); + var actual = new ObjectWithLongToString(); + + Action action = () => Assert.AreEqual(expected, actual); + action.Should().Throw() + .WithMessage($""" + Assert.AreEqual(expected, actual) failed. + Expected values to be equal. + expected: {new string('L', 256)}... 44 more + actual: {new string('L', 256)}... 44 more + """); + } + + public void AreEqual_WithNewlineInToString_ShouldEscapeNewlines() + { + var expected = new ObjectWithNewlineToString(); + var actual = new ObjectWithNewlineToString(); + + Action action = () => Assert.AreEqual(expected, actual); + action.Should().Throw() + .WithMessage(""" + Assert.AreEqual(expected, actual) failed. + Expected values to be equal. + expected: line1\r\nline2\nline3 + actual: line1\r\nline2\nline3 + """); + } + + public void AreNotEqual_WithLongExpression_ShouldTruncateExpression() + { + object aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ = 1; + + Action action = () => Assert.AreNotEqual(aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ, 1); + action.Should().Throw() + .WithMessage(""" + Assert.AreNotEqual(aVeryLongVariableNameThatExceedsOneHundredCharacte..., 1) failed. + Expected values to differ. + notExpected: 1 + actual: 1 + """); + } + + public void AreNotEqual_WithLongToStringValue_ShouldTruncateValue() + { + var obj = new ObjectWithLongToString(); + + Action action = () => Assert.AreNotEqual(obj, obj); + action.Should().Throw() + .WithMessage($""" + Assert.AreNotEqual(obj, obj) failed. + Expected values to differ. + notExpected: {new string('L', 256)}... 44 more + actual: {new string('L', 256)}... 44 more + """); + } + + public void AreNotEqual_WithNewlineInToString_ShouldEscapeNewlines() + { + var obj = new ObjectWithNewlineToString(); + + Action action = () => Assert.AreNotEqual(obj, obj); + action.Should().Throw() + .WithMessage(""" + Assert.AreNotEqual(obj, obj) failed. + Expected values to differ. + notExpected: line1\r\nline2\nline3 + actual: line1\r\nline2\nline3 + """); + } + + #endregion } diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.AreSame.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.AreSame.cs index bd97809016..773564ded3 100644 --- a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.AreSame.cs +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.AreSame.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using AwesomeAssertions; @@ -16,7 +16,12 @@ public void AreSame_PassSameObject_ShouldPass() public void AreSame_PassDifferentObject_ShouldFail() { Action action = () => Assert.AreSame(new object(), new object()); - action.Should().Throw().WithMessage("Assert.AreSame failed. 'expected' expression: 'new object()', 'actual' expression: 'new object()'."); + action.Should().Throw().WithMessage(""" + Assert.AreSame(new object(), new object()) failed. + Expected references to be the same. + expected: (Hash=*) + actual: (Hash=*) + """); } public void AreSame_StringMessage_PassSameObject_ShouldPass() @@ -28,7 +33,12 @@ public void AreSame_StringMessage_PassSameObject_ShouldPass() public void AreSame_StringMessage_PassDifferentObject_ShouldFail() { Action action = () => Assert.AreSame(new object(), new object(), "User-provided message"); - action.Should().Throw().WithMessage("Assert.AreSame failed. 'expected' expression: 'new object()', 'actual' expression: 'new object()'. User-provided message"); + action.Should().Throw().WithMessage(""" + Assert.AreSame(new object(), new object()) failed. User-provided message + Expected references to be the same. + expected: (Hash=*) + actual: (Hash=*) + """); } public void AreSame_InterpolatedString_PassSameObject_ShouldPass() @@ -43,7 +53,12 @@ public async Task AreSame_InterpolatedString_PassDifferentObject_ShouldFail() DummyClassTrackingToStringCalls o = new(); DateTime dateTime = DateTime.Now; Func action = async () => Assert.AreSame(new object(), new object(), $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}"); - (await action.Should().ThrowAsync()).WithMessage($"Assert.AreSame failed. 'expected' expression: 'new object()', 'actual' expression: 'new object()'. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + (await action.Should().ThrowAsync()).WithMessage(""" + Assert.AreSame(new object(), new object()) failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString()* + Expected references to be the same. + expected: (Hash=*) + actual: (Hash=*) + """); o.WasToStringCalled.Should().BeTrue(); } @@ -53,26 +68,46 @@ public void AreNotSame_PassDifferentObject_ShouldPass() public void AreSame_BothAreValueTypes_ShouldFailWithSpecializedMessage() { Action action = () => Assert.AreSame(1, 1); - action.Should().Throw().WithMessage("Assert.AreSame failed. Do not pass value types to AreSame(). Values converted to Object will never be the same. Consider using AreEqual(). 'expected' expression: '1', 'actual' expression: '1'."); + action.Should().Throw().WithMessage(""" + Assert.AreSame(1, 1) failed. + Do not pass value types to AreSame(). Values converted to Object will never be the same. Consider using AreEqual(). + expected: 1 (Hash=*) + actual: 1 (Hash=*) + """); } public void AreSame_StringMessage_BothAreValueTypes_ShouldFailWithSpecializedMessage() { Action action = () => Assert.AreSame(1, 1, "User-provided message"); - action.Should().Throw().WithMessage("Assert.AreSame failed. Do not pass value types to AreSame(). Values converted to Object will never be the same. Consider using AreEqual(). 'expected' expression: '1', 'actual' expression: '1'. User-provided message"); + action.Should().Throw().WithMessage(""" + Assert.AreSame(1, 1) failed. User-provided message + Do not pass value types to AreSame(). Values converted to Object will never be the same. Consider using AreEqual(). + expected: 1 (Hash=*) + actual: 1 (Hash=*) + """); } public void AreSame_InterpolatedString_BothAreValueTypes_ShouldFailWithSpecializedMessage() { Action action = () => Assert.AreSame(1, 1, $"User-provided message {new object().GetType()}"); - action.Should().Throw().WithMessage("Assert.AreSame failed. Do not pass value types to AreSame(). Values converted to Object will never be the same. Consider using AreEqual(). 'expected' expression: '1', 'actual' expression: '1'. User-provided message System.Object"); + action.Should().Throw().WithMessage(""" + Assert.AreSame(1, 1) failed. User-provided message System.Object + Do not pass value types to AreSame(). Values converted to Object will never be the same. Consider using AreEqual(). + expected: 1 (Hash=*) + actual: 1 (Hash=*) + """); } public void AreNotSame_PassSameObject_ShouldFail() { object o = new(); Action action = () => Assert.AreNotSame(o, o); - action.Should().Throw().WithMessage("Assert.AreNotSame failed. 'notExpected' expression: 'o', 'actual' expression: 'o'."); + action.Should().Throw().WithMessage(""" + Assert.AreNotSame(o, o) failed. + Expected references to be different. + notExpected: + actual: + """); } public void AreNotSame_StringMessage_PassDifferentObject_ShouldPass() @@ -82,7 +117,12 @@ public void AreNotSame_StringMessage_PassSameObject_ShouldFail() { object o = new(); Action action = () => Assert.AreNotSame(o, o, "User-provided message"); - action.Should().Throw().WithMessage("Assert.AreNotSame failed. 'notExpected' expression: 'o', 'actual' expression: 'o'. User-provided message"); + action.Should().Throw().WithMessage(""" + Assert.AreNotSame(o, o) failed. User-provided message + Expected references to be different. + notExpected: + actual: + """); } public void AreNotSame_InterpolatedString_PassDifferentObject_ShouldPass() @@ -97,7 +137,96 @@ public async Task AreNotSame_InterpolatedString_PassSameObject_ShouldFail() DummyClassTrackingToStringCalls o = new(); DateTime dateTime = DateTime.Now; Func action = async () => Assert.AreNotSame(o, o, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}"); - (await action.Should().ThrowAsync()).WithMessage($"Assert.AreNotSame failed. 'notExpected' expression: 'o', 'actual' expression: 'o'. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + (await action.Should().ThrowAsync()).WithMessage(""" + Assert.AreNotSame(o, o) failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString()* + Expected references to be different. + notExpected: DummyClassTrackingToStringCalls + actual: DummyClassTrackingToStringCalls + """); o.WasToStringCalled.Should().BeTrue(); } + + #region AreSame/AreNotSame truncation and newline escaping + + public void AreSame_WithLongExpression_ShouldTruncateExpression() + { + object aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ = new object(); + + Action action = () => Assert.AreSame(aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ, new object()); + action.Should().Throw() + .WithMessage(""" + Assert.AreSame(aVeryLongVariableNameThatExceedsOneHundredCharacte..., new object()) failed. + Expected references to be the same. + expected: (Hash=*) + actual: (Hash=*) + """); + } + + public void AreSame_WithLongToStringValue_ShouldTruncateValue() + { + Action action = () => Assert.AreSame(new ObjectWithLongToString(), new ObjectWithLongToString()); + action.Should().Throw() + .WithMessage($""" + Assert.AreSame(new ObjectWithLongToString(), new ObjectWithLongToString()) failed. + Expected references to be the same. + expected: {new string('L', 256)}... 44 more (Hash=*) + actual: {new string('L', 256)}... 44 more (Hash=*) + """); + } + + public void AreSame_WithNewlineInToString_ShouldEscapeNewlines() + { + Action action = () => Assert.AreSame(new ObjectWithNewlineToString(), new ObjectWithNewlineToString()); + action.Should().Throw() + .WithMessage(""" + Assert.AreSame(new ObjectWithNewlineToString(), new ObjectWithNewlineToString()) failed. + Expected references to be the same. + expected: line1\r\nline2\nline3 (Hash=*) + actual: line1\r\nline2\nline3 (Hash=*) + """); + } + + public void AreNotSame_WithLongExpression_ShouldTruncateExpression() + { + object aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ = new object(); + + Action action = () => Assert.AreNotSame(aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ, aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ); + action.Should().Throw() + .WithMessage(""" + Assert.AreNotSame(aVeryLongVariableNameThatExceedsOneHundredCharacte..., aVeryLongVariableNameThatExceedsOneHundredCharacte...) failed. + Expected references to be different. + notExpected: + actual: + """); + } + + public void AreNotSame_WithLongToStringValue_ShouldTruncateValue() + { + var obj = new ObjectWithLongToString(); + + Action action = () => Assert.AreNotSame(obj, obj); + action.Should().Throw() + .WithMessage($""" + Assert.AreNotSame(obj, obj) failed. + Expected references to be different. + notExpected: {new string('L', 256)}... 44 more + actual: {new string('L', 256)}... 44 more + """); + } + + public void AreNotSame_WithNewlineInToString_ShouldEscapeNewlines() + { + var obj = new ObjectWithNewlineToString(); + + Action action = () => Assert.AreNotSame(obj, obj); + action.Should().Throw() + .WithMessage(""" + Assert.AreNotSame(obj, obj) failed. + Expected references to be different. + notExpected: line1\r\nline2\nline3 + actual: line1\r\nline2\nline3 + """); + } + + #endregion } diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.Contains.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.Contains.cs index 74d12c523a..70871e5fd5 100644 --- a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.Contains.cs +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.Contains.cs @@ -338,7 +338,10 @@ public void ContainsSingle_InterpolatedHandler_WithMultipleElements_ThrowsExcept Action action = () => Assert.ContainsSingle(collection, ref handler); // Assert - action.Should().Throw().WithMessage("Assert.ContainsSingle failed. Expected collection to contain exactly one element but found 3 element(s). 'collection' expression: 'collection'. "); + action.Should().Throw().WithMessage(""" + Assert.ContainsSingle(collection) failed. + Expected collection to contain exactly one item but found 3 item(s). + """); } /// @@ -368,7 +371,10 @@ public void ContainsSingle_InNonGenericCollection_NoMessage_WithEmptyCollection_ Action action = () => Assert.ContainsSingle(collection); // Assert - action.Should().Throw().WithMessage("Assert.ContainsSingle failed. Expected collection to contain exactly one element but found 0 element(s). 'collection' expression: 'collection'."); + action.Should().Throw().WithMessage(""" + Assert.ContainsSingle(collection) failed. + Expected collection to contain exactly one item but found 0 item(s). + """); } /// @@ -383,7 +389,10 @@ public void ContainsSingle_InNonGenericCollection_AssertCustomMessage_WithEmptyC Action action = () => Assert.ContainsSingle(collection, "my custom message"); // Assert - action.Should().Throw().WithMessage("Assert.ContainsSingle failed. Expected collection to contain exactly one element but found 0 element(s). 'collection' expression: 'collection'. my custom message"); + action.Should().Throw().WithMessage(""" + Assert.ContainsSingle(collection) failed. my custom message + Expected collection to contain exactly one item but found 0 item(s). + """); } #endregion @@ -417,7 +426,10 @@ public void Contains_ValueExpected_ItemDoesNotExist_ThrowsException() Action action = () => Assert.Contains(20, collection, "Item 20 not found"); // Assert - action.Should().Throw().WithMessage("Assert.Contains failed. Expected collection to contain the specified item. 'expected' expression: '20', 'collection' expression: 'collection'. Item 20 not found"); + action.Should().Throw().WithMessage(""" + Assert.Contains(20, collection) failed. Item 20 not found + Expected collection to contain the specified item.* + """); } /// @@ -433,7 +445,10 @@ public void Contains_InNonGenericCollection_ValueExpected_ItemDoesNotExist_Throw Action action = () => Assert.Contains(expected, collection, $"Item {expected} not found"); // Assert - action.Should().Throw().WithMessage($"*Item {expected} not found*"); + action.Should().Throw().WithMessage(""" + Assert.Contains(expected, collection) failed. Item 20 not found + Expected collection to contain the specified item.* + """); } /// @@ -479,7 +494,10 @@ public void Contains_InNonGenericCollection_NullableValueExpected_ItemDoesNotExi Action action = () => Assert.Contains(expected, collection, $"Item {expected} not found"); // Assert - action.Should().Throw().WithMessage($"*Item {expected} not found*"); + action.Should().Throw().WithMessage(""" + Assert.Contains(expected, collection) failed. Item not found + Expected collection to contain the specified item.* + """); } /// @@ -528,7 +546,10 @@ public void Contains_WithComparer_ItemDoesNotExist_ThrowsException() Action action = () => Assert.Contains("cherry", collection, comparer, "Missing cherry"); // Assert - action.Should().Throw().WithMessage("Assert.Contains failed. Expected collection to contain the specified item. 'expected' expression: '\"cherry\"', 'collection' expression: 'collection'. Missing cherry"); + action.Should().Throw().WithMessage(""" + Assert.Contains("cherry", collection) failed. Missing cherry + Expected collection to contain the specified item.* + """); } /// @@ -574,7 +595,10 @@ public void Contains_Predicate_NoItemMatches_ThrowsException() Action action = () => Assert.Contains(IsEven, collection, "No even number found"); // Assert - action.Should().Throw().WithMessage("Assert.Contains failed. Expected at least one item to match the predicate. 'predicate' expression: 'IsEven', 'collection' expression: 'collection'. No even number found"); + action.Should().Throw().WithMessage(""" + Assert.Contains(IsEven, collection) failed. No even number found + Expected at least one item to match the predicate.* + """); } /// @@ -590,7 +614,10 @@ public void Contains_InNonGenericCollection_Predicate_NoItemMatches_ThrowsExcept Action action = () => Assert.Contains(IsEven, collection, "No even number found"); // Assert - action.Should().Throw().WithMessage("Assert.Contains failed. Expected at least one item to match the predicate. 'predicate' expression: 'IsEven', 'collection' expression: 'collection'. No even number found"); + action.Should().Throw().WithMessage(""" + Assert.Contains(IsEven, collection) failed. No even number found + Expected at least one item to match the predicate.* + """); } /// @@ -623,7 +650,12 @@ public void Contains_StringVersion_SubstringNotPresent_ThrowsException() Action action = () => Assert.Contains(substring, value, StringComparison.Ordinal, "Missing substring"); // Assert - action.Should().Throw().WithMessage("Assert.Contains failed. String 'The quick brown fox' does not contain string 'lazy'. 'substring' expression: 'substring', 'value' expression: 'value'. Missing substring."); + action.Should().Throw().WithMessage(""" + Assert.Contains(substring, value) failed. Missing substring + String does not contain the expected substring. + substring: "lazy" + value: "The quick brown fox" + """); } public void Contains_HashSetWithCustomComparer_ItemExists_DoesNotThrow() @@ -699,7 +731,10 @@ public void Contains_InNonGenericCollection_WithComparer_ItemDoesNotExist_Throws Action action = () => Assert.Contains("banana", collection, comparer); // Assert - action.Should().Throw().WithMessage("Assert.Contains failed. Expected collection to contain the specified item. 'expected' expression: '\"banana\"', 'collection' expression: 'collection'."); + action.Should().Throw().WithMessage(""" + Assert.Contains("banana", collection) failed. + Expected collection to contain the specified item.* + """); } /// @@ -834,7 +869,12 @@ public void Contains_String_EmptyValue_WithNonEmptySubstring_ThrowsException() Action action = () => Assert.Contains(substring, value); // Assert - action.Should().Throw().WithMessage("Assert.Contains failed. String '' does not contain string 'test'. 'substring' expression: 'substring', 'value' expression: 'value'.."); + action.Should().Throw().WithMessage(""" + Assert.Contains(substring, value) failed. + String does not contain the expected substring. + substring: "test" + value: "" + """); } /// @@ -937,7 +977,10 @@ public void DoesNotContain_ValueExpected_ItemPresent_ThrowsException() Action action = () => Assert.DoesNotContain(10, collection, "Item 10 should not be found"); // Assert - action.Should().Throw().WithMessage("Assert.DoesNotContain failed. Expected collection to not contain the specified item. 'notExpected' expression: '10', 'collection' expression: 'collection'. Item 10 should not be found"); + action.Should().Throw().WithMessage(""" + Assert.DoesNotContain(10, collection) failed. Item 10 should not be found + Expected collection to not contain the specified item.* + """); } /// @@ -965,10 +1008,14 @@ public void DoesNotContain_InNonGenericCollection_ValueExpected_ItemPresent_Thro var collection = new ArrayList { 5, 10, 15, "a" }; // Act - Action action = () => Assert.DoesNotContain(10, collection, "Assert.DoesNotContain failed. Expected collection to not contain the specified item. Item {0} should not be found"); + Action action = () => Assert.DoesNotContain(10, collection, "Item 10 should not be found"); // Assert - action.Should().Throw().WithMessage("Assert.DoesNotContain failed. Expected collection to not contain the specified item. 'notExpected' expression: '10', 'collection' expression: 'collection'. Assert.DoesNotContain failed. Expected collection to not contain the specified item. Item {0} should not be found"); + action.Should().Throw().WithMessage(""" + Assert.DoesNotContain(10, collection) failed. Item 10 should not be found + Expected collection to not contain the specified item. + collection: [5, 10, 15, "a"] (4 items) + """); } /// @@ -1017,7 +1064,10 @@ public void DoesNotContain_WithComparer_ItemPresent_ThrowsException() Action action = () => Assert.DoesNotContain("APPLE", collection, comparer, "Unexpected \"APPLE\""); // Assert - action.Should().Throw().WithMessage("Assert.DoesNotContain failed. Expected collection to not contain the specified item. 'notExpected' expression: '\"APPLE\"', 'collection' expression: 'collection'. Unexpected \"APPLE\""); + action.Should().Throw().WithMessage(""" + Assert.DoesNotContain("APPLE", collection) failed. Unexpected "APPLE" + Expected collection to not contain the specified item.* + """); } /// @@ -1034,7 +1084,10 @@ public void DoesNotContain_InNonGenericCollection_WithComparer_ItemPresent_Throw Action action = () => Assert.DoesNotContain("APPLE", collection, comparer, "APPLE"); // Assert - action.Should().Throw().WithMessage("Assert.DoesNotContain failed. Expected collection to not contain the specified item. 'notExpected' expression: '\"APPLE\"', 'collection' expression: 'collection'. APPLE"); + action.Should().Throw().WithMessage(""" + Assert.DoesNotContain("APPLE", collection) failed. APPLE + Expected collection to not contain the specified item.* + """); } /// @@ -1080,7 +1133,10 @@ public void DoesNotContain_Predicate_AtLeastOneItemMatches_ThrowsException() Action action = () => Assert.DoesNotContain(IsEven, collection, "An even number exists"); // Assert - action.Should().Throw().WithMessage("Assert.DoesNotContain failed. Expected no items to match the predicate. 'predicate' expression: 'IsEven', 'collection' expression: 'collection'. An even number exists"); + action.Should().Throw().WithMessage(""" + Assert.DoesNotContain(IsEven, collection) failed. An even number exists + Expected no items to match the predicate.* + """); } /// @@ -1096,7 +1152,10 @@ public void DoesNotContain_InNonGenericCollection_Predicate_AtLeastOneItemMatche Action action = () => Assert.DoesNotContain(IsEven, collection, "An even number exists"); // Assert - action.Should().Throw().WithMessage("Assert.DoesNotContain failed. Expected no items to match the predicate. 'predicate' expression: 'IsEven', 'collection' expression: 'collection'. An even number exists"); + action.Should().Throw().WithMessage(""" + Assert.DoesNotContain(IsEven, collection) failed. An even number exists + Expected no items to match the predicate.* + """); } /// @@ -1129,7 +1188,12 @@ public void DoesNotContain_StringVersion_SubstringPresent_ThrowsException() Action action = () => Assert.DoesNotContain(substring, value, StringComparison.Ordinal, "Unexpected substring"); // Assert - action.Should().Throw().WithMessage("Assert.DoesNotContain failed. String 'The quick brown fox' does contain string 'brown'. 'substring' expression: 'substring', 'value' expression: 'value'. Unexpected substring."); + action.Should().Throw().WithMessage(""" + Assert.DoesNotContain(substring, value) failed. Unexpected substring + String contains the unexpected substring. + substring: "brown" + value: "The quick brown fox" + """); } /// @@ -1164,7 +1228,12 @@ public void DoesNotContain_StringWithComparisonAndMessage_SubstringPresent_Throw Action action = () => Assert.DoesNotContain(substring, value, StringComparison.OrdinalIgnoreCase, "Found unexpected substring"); // Assert - action.Should().Throw().WithMessage("Assert.DoesNotContain failed. String 'The quick brown fox' does contain string 'BROWN'. 'substring' expression: 'substring', 'value' expression: 'value'. Found unexpected substring."); + action.Should().Throw().WithMessage(""" + Assert.DoesNotContain(substring, value) failed. Found unexpected substring + String contains the unexpected substring. + substring: "BROWN" + value: "The quick brown fox" + """); } /// @@ -1197,7 +1266,12 @@ public void DoesNotContain_StringSimpleOverload_SubstringPresent_ThrowsException Action action = () => Assert.DoesNotContain(substring, value); // Assert - action.Should().Throw().WithMessage("Assert.DoesNotContain failed. String 'The quick brown fox' does contain string 'brown'. 'substring' expression: 'substring', 'value' expression: 'value'.."); + action.Should().Throw().WithMessage(""" + Assert.DoesNotContain(substring, value) failed. + String contains the unexpected substring. + substring: "brown" + value: "The quick brown fox" + """); } /// @@ -1230,7 +1304,12 @@ public void DoesNotContain_StringWithMessageOnly_SubstringPresent_ThrowsExceptio Action action = () => Assert.DoesNotContain(substring, value, "Found unexpected substring"); // Assert - action.Should().Throw().WithMessage("Assert.DoesNotContain failed. String 'The quick brown fox' does contain string 'brown'. 'substring' expression: 'substring', 'value' expression: 'value'. Found unexpected substring."); + action.Should().Throw().WithMessage(""" + Assert.DoesNotContain(substring, value) failed. Found unexpected substring + String contains the unexpected substring. + substring: "brown" + value: "The quick brown fox" + """); } /// @@ -1473,7 +1552,10 @@ public void ContainsSinglePredicate_NoItemMatches_ThrowsException() // Assert action.Should().Throw() - .WithMessage("Assert.ContainsSingle failed. Expected exactly one item to match the predicate but found 0 item(s). 'predicate' expression: 'x => x % 2 == 0', 'collection' expression: 'collection'."); + .WithMessage(""" + Assert.ContainsSingle(x => x % 2 == 0, collection) failed. + Expected exactly one item to match the predicate but found 0 item(s). + """); } /// @@ -1490,7 +1572,10 @@ public void ContainsSinglePredicate_InNonGenericCollection_NoItemMatches_ThrowsE // Assert action.Should().Throw() - .WithMessage("Assert.ContainsSingle failed. Expected exactly one item to match the predicate but found 0 item(s). 'predicate' expression: 'x => x is int i && i % 2 == 0', 'collection' expression: 'collection'."); + .WithMessage(""" + Assert.ContainsSingle(x => x is int i && i % 2 == 0, collection) failed. + Expected exactly one item to match the predicate but found 0 item(s). + """); } /// @@ -1507,7 +1592,10 @@ public void ContainsSinglePredicate_MultipleItemsMatch_ThrowsException() // Assert action.Should().Throw() - .WithMessage("Assert.ContainsSingle failed. Expected exactly one item to match the predicate but found 4 item(s). 'predicate' expression: 'x => x % 2 == 0', 'collection' expression: 'collection'."); + .WithMessage(""" + Assert.ContainsSingle(x => x % 2 == 0, collection) failed. + Expected exactly one item to match the predicate but found 4 item(s). + """); } /// @@ -1524,7 +1612,10 @@ public void ContainsSinglePredicate_InNonGenericCollection_MultipleItemsMatch_Th // Assert action.Should().Throw() - .WithMessage("Assert.ContainsSingle failed. Expected exactly one item to match the predicate but found 2 item(s). 'predicate' expression: 'x => x is int i && i % 2 == 0', 'collection' expression: 'collection'."); + .WithMessage(""" + Assert.ContainsSingle(x => x is int i && i % 2 == 0, collection) failed. + Expected exactly one item to match the predicate but found 2 item(s). + """); } /// @@ -1541,7 +1632,10 @@ public void ContainsSinglePredicate_WithMessage_NoItemMatches_ThrowsException() // Assert action.Should().Throw() - .WithMessage("Assert.ContainsSingle failed. Expected exactly one item to match the predicate but found 0 item(s). 'predicate' expression: 'x => x % 2 == 0', 'collection' expression: 'collection'. No even numbers found in collection with 3 items"); + .WithMessage(""" + Assert.ContainsSingle(x => x % 2 == 0, collection) failed. No even numbers found in collection with 3 items + Expected exactly one item to match the predicate but found 0 item(s). + """); } /// @@ -1558,7 +1652,10 @@ public void ContainsSinglePredicate_InNonGenericCollection_WithMessage_NoItemMat // Assert action.Should().Throw() - .WithMessage("Assert.ContainsSingle failed. Expected exactly one item to match the predicate but found 0 item(s). 'predicate' expression: 'x => x is int i && i % 2 == 0', 'collection' expression: 'collection'. No even numbers found in collection with 3 items"); + .WithMessage(""" + Assert.ContainsSingle(x => x is int i && i % 2 == 0, collection) failed. No even numbers found in collection with 3 items + Expected exactly one item to match the predicate but found 0 item(s). + """); } /// @@ -1575,7 +1672,10 @@ public void ContainsSinglePredicate_WithMessage_MultipleItemsMatch_ThrowsExcepti // Assert action.Should().Throw() - .WithMessage("Assert.ContainsSingle failed. Expected exactly one item to match the predicate but found 3 item(s). 'predicate' expression: 'x => x % 2 == 0', 'collection' expression: 'collection'. Too many even numbers found: 3"); + .WithMessage(""" + Assert.ContainsSingle(x => x % 2 == 0, collection) failed. Too many even numbers found: 3 + Expected exactly one item to match the predicate but found 3 item(s). + """); } /// @@ -1592,7 +1692,10 @@ public void ContainsSinglePredicate_InNonGenericCollection_WithMessage_MultipleI // Assert action.Should().Throw() - .WithMessage("Assert.ContainsSingle failed. Expected exactly one item to match the predicate but found 2 item(s). 'predicate' expression: 'x => x is int i && i % 2 == 0', 'collection' expression: 'collection'. Too many even numbers found: 2"); + .WithMessage(""" + Assert.ContainsSingle(x => x is int i && i % 2 == 0, collection) failed. Too many even numbers found: 2 + Expected exactly one item to match the predicate but found 2 item(s). + """); } /// @@ -1684,7 +1787,11 @@ public void Contains_ItemNotFound_ShowsSpecificErrorMessage() // Assert action.Should().Throw() - .WithMessage("Assert.Contains failed. Expected collection to contain the specified item. 'expected' expression: '5', 'collection' expression: 'collection'."); + .WithMessage(""" + Assert.Contains(5, collection) failed. + Expected collection to contain the specified item.* + collection: [1, 2, 3] (3 items) + """); } /// @@ -1700,7 +1807,11 @@ public void Contains_InNonGenericCollection_ItemNotFound_ShowsSpecificErrorMessa // Assert action.Should().Throw() - .WithMessage("Assert.Contains failed. Expected collection to contain the specified item. 'expected' expression: '5', 'collection' expression: 'collection'."); + .WithMessage(""" + Assert.Contains(5, collection) failed. + Expected collection to contain the specified item.* + collection: [1, 2, 3] (3 items) + """); } /// @@ -1716,7 +1827,11 @@ public void Contains_PredicateNotMatched_ShowsSpecificErrorMessage() // Assert action.Should().Throw() - .WithMessage("Assert.Contains failed. Expected at least one item to match the predicate. 'predicate' expression: 'x => x % 2 == 0', 'collection' expression: 'collection'."); + .WithMessage(""" + Assert.Contains(x => x % 2 == 0, collection) failed. + Expected at least one item to match the predicate.* + collection: [1, 3, 5] (3 items) + """); } /// @@ -1732,7 +1847,11 @@ public void DoesNotContain_ItemFound_ShowsSpecificErrorMessage() // Assert action.Should().Throw() - .WithMessage("Assert.DoesNotContain failed. Expected collection to not contain the specified item. 'notExpected' expression: '2', 'collection' expression: 'collection'."); + .WithMessage(""" + Assert.DoesNotContain(2, collection) failed. + Expected collection to not contain the specified item.* + collection: [1, 2, 3] (3 items) + """); } /// @@ -1748,7 +1867,11 @@ public void DoesNotContain_PredicateMatched_ShowsSpecificErrorMessage() // Assert action.Should().Throw() - .WithMessage("Assert.DoesNotContain failed. Expected no items to match the predicate. 'predicate' expression: 'x => x % 2 == 0', 'collection' expression: 'collection'."); + .WithMessage(""" + Assert.DoesNotContain(x => x % 2 == 0, collection) failed. + Expected no items to match the predicate.* + collection: [1, 2, 3] (3 items) + """); } public void DoesNotContains_HashSetWithCustomComparer_ItemDoesNotExist_DoesNotThrow() @@ -1792,4 +1915,88 @@ private AlwaysFalseEqualityComparer() } #endregion + + #region Contains/DoesNotContain string truncation and newline escaping + + public void Contains_String_WithLongExpression_ShouldTruncateExpression() + { + string aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ = "hello"; + + Action action = () => Assert.Contains("world", aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ); + action.Should().Throw() + .WithMessage(""" + Assert.Contains("world", aVeryLongVariableNameThatExceedsOneHundredCharacte...) failed. + String does not contain the expected substring. + substring: "world" + value: "hello" + """); + } + + public void Contains_String_WithLongValue_ShouldTruncateValue() + { + string longValue = new string('x', 300); + + Action action = () => Assert.Contains("world", longValue); + action.Should().Throw() + .WithMessage($""" + Assert.Contains("world", longValue) failed. + String does not contain the expected substring. + substring: "world" + value: "{new string('x', 255)}... 46 more + """); + } + + public void Contains_String_WithNewlineInValue_ShouldEscapeNewlines() + { + Action action = () => Assert.Contains("world", "hello\r\nfoo"); + action.Should().Throw() + .WithMessage(""" + Assert.Contains("world", "hello\r\nfoo") failed. + String does not contain the expected substring. + substring: "world" + value: "hello\r\nfoo" + """); + } + + public void DoesNotContain_String_WithLongExpression_ShouldTruncateExpression() + { + string aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ = "hello world"; + + Action action = () => Assert.DoesNotContain("hello", aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ); + action.Should().Throw() + .WithMessage(""" + Assert.DoesNotContain("hello", aVeryLongVariableNameThatExceedsOneHundredCharacte...) failed. + String contains the unexpected substring. + substring: "hello" + value: "hello world" + """); + } + + public void DoesNotContain_String_WithLongValue_ShouldTruncateValue() + { + string longValue = "hello" + new string('x', 300); + + Action action = () => Assert.DoesNotContain("hello", longValue); + action.Should().Throw() + .WithMessage($""" + Assert.DoesNotContain("hello", longValue) failed. + String contains the unexpected substring. + substring: "hello" + value: "hello{new string('x', 250)}... 51 more + """); + } + + public void DoesNotContain_String_WithNewlineInValue_ShouldEscapeNewlines() + { + Action action = () => Assert.DoesNotContain("hello", "hello\r\nworld"); + action.Should().Throw() + .WithMessage(""" + Assert.DoesNotContain("hello", "hello\r\nworld") failed. + String contains the unexpected substring. + substring: "hello" + value: "hello\r\nworld" + """); + } + + #endregion } diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.EndsWith.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.EndsWith.cs new file mode 100644 index 0000000000..537ec66b74 --- /dev/null +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.EndsWith.cs @@ -0,0 +1,139 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using AwesomeAssertions; + +namespace Microsoft.VisualStudio.TestPlatform.TestFramework.UnitTests; + +public partial class AssertTests +{ + #region EndsWith + + public void EndsWith_WhenValueEndsWithSuffix_ShouldPass() + => Assert.EndsWith("world", "hello world"); + + public void EndsWith_WhenValueDoesNotEndWithSuffix_ShouldFail() + { + Action action = () => Assert.EndsWith("hello", "world"); + action.Should().Throw() + .WithMessage(""" + Assert.EndsWith("hello", "world") failed. + String does not end with expected suffix. + expectedSuffix: "hello" + value: "world" + """); + } + + public void EndsWith_WithMessage_WhenValueDoesNotEndWithSuffix_ShouldFail() + { + Action action = () => Assert.EndsWith("hello", "world", "User message"); + action.Should().Throw() + .WithMessage(""" + Assert.EndsWith("hello", "world") failed. User message + String does not end with expected suffix. + expectedSuffix: "hello" + value: "world" + """); + } + + public void DoesNotEndWith_WhenValueDoesNotEndWithSuffix_ShouldPass() + => Assert.DoesNotEndWith("hello", "world"); + + public void DoesNotEndWith_WhenValueEndsWithSuffix_ShouldFail() + { + Action action = () => Assert.DoesNotEndWith("world", "hello world"); + action.Should().Throw() + .WithMessage(""" + Assert.DoesNotEndWith("world", "hello world") failed. + String ends with unexpected suffix. + notExpectedSuffix: "world" + value: "hello world" + """); + } + + #endregion + + #region EndsWith/DoesNotEndWith truncation and newline escaping + + public void EndsWith_WithLongExpression_ShouldTruncateExpression() + { + string aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ = "hello world"; + + Action action = () => Assert.EndsWith("hello", aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ); + action.Should().Throw() + .WithMessage(""" + Assert.EndsWith("hello", aVeryLongVariableNameThatExceedsOneHundredCharacte...) failed. + String does not end with expected suffix. + expectedSuffix: "hello" + value: "hello world" + """); + } + + public void EndsWith_WithLongValue_ShouldTruncateValue() + { + string longValue = new string('x', 300); + + Action action = () => Assert.EndsWith("world", longValue); + action.Should().Throw() + .WithMessage($""" + Assert.EndsWith("world", longValue) failed. + String does not end with expected suffix. + expectedSuffix: "world" + value: "{new string('x', 255)}... 46 more + """); + } + + public void EndsWith_WithNewlineInValue_ShouldEscapeNewlines() + { + Action action = () => Assert.EndsWith("world", "hello\r\nfoo"); + action.Should().Throw() + .WithMessage(""" + Assert.EndsWith("world", "hello\r\nfoo") failed. + String does not end with expected suffix. + expectedSuffix: "world" + value: "hello\r\nfoo" + """); + } + + public void DoesNotEndWith_WithLongExpression_ShouldTruncateExpression() + { + string aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ = "hello world"; + + Action action = () => Assert.DoesNotEndWith("world", aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ); + action.Should().Throw() + .WithMessage(""" + Assert.DoesNotEndWith("world", aVeryLongVariableNameThatExceedsOneHundredCharacte...) failed. + String ends with unexpected suffix. + notExpectedSuffix: "world" + value: "hello world" + """); + } + + public void DoesNotEndWith_WithLongValue_ShouldTruncateValue() + { + string longValue = new string('x', 300) + "world"; + + Action action = () => Assert.DoesNotEndWith("world", longValue); + action.Should().Throw() + .WithMessage($""" + Assert.DoesNotEndWith("world", longValue) failed. + String ends with unexpected suffix. + notExpectedSuffix: "world" + value: "{new string('x', 255)}... 51 more + """); + } + + public void DoesNotEndWith_WithNewlineInValue_ShouldEscapeNewlines() + { + Action action = () => Assert.DoesNotEndWith("world", "hello\r\nworld"); + action.Should().Throw() + .WithMessage(""" + Assert.DoesNotEndWith("world", "hello\r\nworld") failed. + String ends with unexpected suffix. + notExpectedSuffix: "world" + value: "hello\r\nworld" + """); + } + + #endregion +} diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IComparableTests.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IComparableTests.cs index a574b23c53..d8d25a1e32 100644 --- a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IComparableTests.cs +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IComparableTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using AwesomeAssertions; @@ -42,7 +42,12 @@ public void IsGreaterThanShouldThrowWithMessage() // Assert action.Should().Throw() - .WithMessage("Assert.IsGreaterThan failed. Actual value <5> is not greater than expected value <10>. 'lowerBound' expression: '10', 'value' expression: '5'. A Message"); + .WithMessage(""" + Assert.IsGreaterThan(10, 5) failed. A Message + Expected value to be greater than the specified bound. + lowerBound: 10 + value: 5 + """); } public void IsGreaterThanShouldWorkWithDoubles() => @@ -86,7 +91,12 @@ public void IsGreaterThanOrEqualToShouldThrowWithMessage() // Assert action.Should().Throw() - .WithMessage("Assert.IsGreaterThanOrEqualTo failed. Actual value <5> is not greater than or equal to expected value <10>. 'lowerBound' expression: '10', 'value' expression: '5'. A Message"); + .WithMessage(""" + Assert.IsGreaterThanOrEqualTo(10, 5) failed. A Message + Expected value to be greater than or equal to the specified bound. + lowerBound: 10 + value: 5 + """); } public void IsGreaterThanOrEqualToShouldWorkWithDoubles() => @@ -130,7 +140,12 @@ public void IsLessThanShouldThrowWithMessage() // Assert action.Should().Throw() - .WithMessage("Assert.IsLessThan failed. Actual value <10> is not less than expected value <5>. 'upperBound' expression: '5', 'value' expression: '10'. A Message"); + .WithMessage(""" + Assert.IsLessThan(5, 10) failed. A Message + Expected value to be less than the specified bound. + upperBound: 5 + value: 10 + """); } public void IsLessThanShouldWorkWithDoubles() => @@ -174,7 +189,12 @@ public void IsLessThanOrEqualToShouldThrowWithMessage() // Assert action.Should().Throw() - .WithMessage("Assert.IsLessThanOrEqualTo failed. Actual value <10> is not less than or equal to expected value <5>. 'upperBound' expression: '5', 'value' expression: '10'. A Message"); + .WithMessage(""" + Assert.IsLessThanOrEqualTo(5, 10) failed. A Message + Expected value to be less than or equal to the specified bound. + upperBound: 5 + value: 10 + """); } public void IsLessThanOrEqualToShouldWorkWithDoubles() => @@ -233,7 +253,11 @@ public void IsPositiveShouldThrowWithMessage() // Assert action.Should().Throw() - .WithMessage("Assert.IsPositive failed. Expected value <-5> to be positive. 'value' expression: '-5'. A Message"); + .WithMessage(""" + Assert.IsPositive(-5) failed. A Message + Expected a positive value. + value: -5 + """); } public void IsPositiveShouldWorkWithDoubles() => @@ -298,7 +322,11 @@ public void IsNegativeShouldThrowWithMessage() // Assert action.Should().Throw() - .WithMessage("Assert.IsNegative failed. Expected value <5> to be negative. 'value' expression: '5'. A Message"); + .WithMessage(""" + Assert.IsNegative(5) failed. A Message + Expected a negative value. + value: 5 + """); } public void IsNegativeShouldWorkWithDoubles() => @@ -314,4 +342,232 @@ public void IsNegativeShouldThrowForZeroDouble() } #endregion + + #region IComparable truncation and newline escaping + + public void IsGreaterThan_WithLongExpression_ShouldTruncateExpression() + { + int aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ = 10; + + Action action = () => Assert.IsGreaterThan(aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ, 5); + action.Should().Throw() + .WithMessage(""" + Assert.IsGreaterThan(aVeryLongVariableNameThatExceedsOneHundredCharacte..., 5) failed. + Expected value to be greater than the specified bound. + lowerBound: 10 + value: 5 + """); + } + + public void IsGreaterThan_WithLongToStringValue_ShouldTruncateValue() + { + var lowerBound = new ComparableWithLongToString(10); + var value = new ComparableWithLongToString(5); + + Action action = () => Assert.IsGreaterThan(lowerBound, value); + action.Should().Throw() + .WithMessage($""" + Assert.IsGreaterThan(lowerBound, value) failed. + Expected value to be greater than the specified bound. + lowerBound: {new string('V', 256)}... 44 more + value: {new string('V', 256)}... 44 more + """); + } + + public void IsGreaterThan_WithNewlineInToString_ShouldEscapeNewlines() + { + var lowerBound = new ComparableWithNewlineToString(10); + var value = new ComparableWithNewlineToString(5); + + Action action = () => Assert.IsGreaterThan(lowerBound, value); + action.Should().Throw() + .WithMessage(""" + Assert.IsGreaterThan(lowerBound, value) failed. + Expected value to be greater than the specified bound. + lowerBound: line1\r\nline2 + value: line1\r\nline2 + """); + } + + public void IsGreaterThanOrEqualTo_WithLongExpression_ShouldTruncateExpression() + { + int aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ = 10; + + Action action = () => Assert.IsGreaterThanOrEqualTo(aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ, 5); + action.Should().Throw() + .WithMessage(""" + Assert.IsGreaterThanOrEqualTo(aVeryLongVariableNameThatExceedsOneHundredCharacte..., 5) failed. + Expected value to be greater than or equal to the specified bound. + lowerBound: 10 + value: 5 + """); + } + + public void IsGreaterThanOrEqualTo_WithLongToStringValue_ShouldTruncateValue() + { + var lowerBound = new ComparableWithLongToString(10); + var value = new ComparableWithLongToString(5); + + Action action = () => Assert.IsGreaterThanOrEqualTo(lowerBound, value); + action.Should().Throw() + .WithMessage($""" + Assert.IsGreaterThanOrEqualTo(lowerBound, value) failed. + Expected value to be greater than or equal to the specified bound. + lowerBound: {new string('V', 256)}... 44 more + value: {new string('V', 256)}... 44 more + """); + } + + public void IsGreaterThanOrEqualTo_WithNewlineInToString_ShouldEscapeNewlines() + { + var lowerBound = new ComparableWithNewlineToString(10); + var value = new ComparableWithNewlineToString(5); + + Action action = () => Assert.IsGreaterThanOrEqualTo(lowerBound, value); + action.Should().Throw() + .WithMessage(""" + Assert.IsGreaterThanOrEqualTo(lowerBound, value) failed. + Expected value to be greater than or equal to the specified bound. + lowerBound: line1\r\nline2 + value: line1\r\nline2 + """); + } + + public void IsLessThan_WithLongExpression_ShouldTruncateExpression() + { + int aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ = 5; + + Action action = () => Assert.IsLessThan(aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ, 10); + action.Should().Throw() + .WithMessage(""" + Assert.IsLessThan(aVeryLongVariableNameThatExceedsOneHundredCharacte..., 10) failed. + Expected value to be less than the specified bound. + upperBound: 5 + value: 10 + """); + } + + public void IsLessThan_WithLongToStringValue_ShouldTruncateValue() + { + var upperBound = new ComparableWithLongToString(5); + var value = new ComparableWithLongToString(10); + + Action action = () => Assert.IsLessThan(upperBound, value); + action.Should().Throw() + .WithMessage($""" + Assert.IsLessThan(upperBound, value) failed. + Expected value to be less than the specified bound. + upperBound: {new string('V', 256)}... 44 more + value: {new string('V', 256)}... 44 more + """); + } + + public void IsLessThan_WithNewlineInToString_ShouldEscapeNewlines() + { + var upperBound = new ComparableWithNewlineToString(5); + var value = new ComparableWithNewlineToString(10); + + Action action = () => Assert.IsLessThan(upperBound, value); + action.Should().Throw() + .WithMessage(""" + Assert.IsLessThan(upperBound, value) failed. + Expected value to be less than the specified bound. + upperBound: line1\r\nline2 + value: line1\r\nline2 + """); + } + + public void IsLessThanOrEqualTo_WithLongExpression_ShouldTruncateExpression() + { + int aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ = 5; + + Action action = () => Assert.IsLessThanOrEqualTo(aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ, 10); + action.Should().Throw() + .WithMessage(""" + Assert.IsLessThanOrEqualTo(aVeryLongVariableNameThatExceedsOneHundredCharacte..., 10) failed. + Expected value to be less than or equal to the specified bound. + upperBound: 5 + value: 10 + """); + } + + public void IsLessThanOrEqualTo_WithLongToStringValue_ShouldTruncateValue() + { + var upperBound = new ComparableWithLongToString(5); + var value = new ComparableWithLongToString(10); + + Action action = () => Assert.IsLessThanOrEqualTo(upperBound, value); + action.Should().Throw() + .WithMessage($""" + Assert.IsLessThanOrEqualTo(upperBound, value) failed. + Expected value to be less than or equal to the specified bound. + upperBound: {new string('V', 256)}... 44 more + value: {new string('V', 256)}... 44 more + """); + } + + public void IsLessThanOrEqualTo_WithNewlineInToString_ShouldEscapeNewlines() + { + var upperBound = new ComparableWithNewlineToString(5); + var value = new ComparableWithNewlineToString(10); + + Action action = () => Assert.IsLessThanOrEqualTo(upperBound, value); + action.Should().Throw() + .WithMessage(""" + Assert.IsLessThanOrEqualTo(upperBound, value) failed. + Expected value to be less than or equal to the specified bound. + upperBound: line1\r\nline2 + value: line1\r\nline2 + """); + } + + public void IsPositive_WithLongExpression_ShouldTruncateExpression() + { + int aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ = -5; + + Action action = () => Assert.IsPositive(aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ); + action.Should().Throw() + .WithMessage(""" + Assert.IsPositive(aVeryLongVariableNameThatExceedsOneHundredCharacte...) failed. + Expected a positive value. + value: -5 + """); + } + + public void IsNegative_WithLongExpression_ShouldTruncateExpression() + { + int aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ = 5; + + Action action = () => Assert.IsNegative(aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ); + action.Should().Throw() + .WithMessage(""" + Assert.IsNegative(aVeryLongVariableNameThatExceedsOneHundredCharacte...) failed. + Expected a negative value. + value: 5 + """); + } + + #endregion + + private sealed class ComparableWithLongToString : IComparable + { + private readonly int _value; + + public ComparableWithLongToString(int value) => _value = value; + + public int CompareTo(ComparableWithLongToString? other) => _value.CompareTo(other?._value ?? 0); + + public override string ToString() => new string('V', 300); + } + + private sealed class ComparableWithNewlineToString : IComparable + { + private readonly int _value; + + public ComparableWithNewlineToString(int value) => _value = value; + + public int CompareTo(ComparableWithNewlineToString? other) => _value.CompareTo(other?._value ?? 0); + + public override string ToString() => "line1\r\nline2"; + } } diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.InconclusiveTests.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.InconclusiveTests.cs index d0b8d8fcc7..68819704e1 100644 --- a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.InconclusiveTests.cs +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.InconclusiveTests.cs @@ -12,6 +12,6 @@ public void InconclusiveDoesNotThrowWhenMessageContainsInvalidStringFormatCompos { Action action = () => Assert.Inconclusive("{"); action.Should().Throw() - .And.Message.Should().Contain("Assert.Inconclusive failed. {"); + .WithMessage("Assert.Inconclusive failed. {"); } } diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsExactInstanceOfTypeTests.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsExactInstanceOfTypeTests.cs index af72c579fa..94676ed0cd 100644 --- a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsExactInstanceOfTypeTests.cs +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsExactInstanceOfTypeTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using AwesomeAssertions; @@ -12,21 +12,33 @@ public void ExactInstanceOfTypeShouldFailWhenValueIsNull() { Action action = () => Assert.IsExactInstanceOfType(null, typeof(AssertTests)); action.Should().Throw() - .WithMessage("Assert.IsExactInstanceOfType failed. 'value' expression: 'null'."); + .WithMessage(""" +Assert.IsExactInstanceOfType(null) failed. + value: (null) +"""); } public void ExactInstanceOfTypeShouldFailWhenTypeIsNull() { Action action = () => Assert.IsExactInstanceOfType(5, null); action.Should().Throw() - .WithMessage("Assert.IsExactInstanceOfType failed. 'value' expression: '5'."); + .WithMessage(""" +Assert.IsExactInstanceOfType(5) failed. + value: 5 +"""); } public void ExactInstanceOfTypeShouldFailWhenTypeIsMismatched() { Action action = () => Assert.IsExactInstanceOfType(5, typeof(string)); action.Should().Throw() - .WithMessage("Assert.IsExactInstanceOfType failed. 'value' expression: '5'. Expected exact type:. Actual type:."); + .WithMessage(""" +Assert.IsExactInstanceOfType(5) failed. +Expected value to be exactly of the specified type. + value: 5 + expectedType: System.String + actualType: System.Int32 +"""); } public void ExactInstanceOfTypeShouldPassOnSameInstance() => Assert.IsExactInstanceOfType(5, typeof(int)); @@ -35,7 +47,13 @@ public void ExactInstanceOfTypeShouldFailOnHigherInstance() { Action action = () => Assert.IsExactInstanceOfType(5, typeof(object)); action.Should().Throw() - .WithMessage("Assert.IsExactInstanceOfType failed. 'value' expression: '5'. Expected exact type:. Actual type:."); + .WithMessage(""" +Assert.IsExactInstanceOfType(5) failed. +Expected value to be exactly of the specified type. + value: 5 + expectedType: System.Object + actualType: System.Int32 +"""); } public void ExactInstanceOfTypeShouldFailOnDerivedType() @@ -43,7 +61,13 @@ public void ExactInstanceOfTypeShouldFailOnDerivedType() object x = new MemoryStream(); Action action = () => Assert.IsExactInstanceOfType(x, typeof(Stream)); action.Should().Throw() - .WithMessage("Assert.IsExactInstanceOfType failed. 'value' expression: 'x'. Expected exact type:. Actual type:."); + .WithMessage(""" +Assert.IsExactInstanceOfType(x) failed. +Expected value to be exactly of the specified type. + value: + expectedType: System.IO.Stream + actualType: System.IO.MemoryStream +"""); } public void ExactInstanceOfTypeShouldPassOnExactType() @@ -56,21 +80,33 @@ public void ExactInstanceOfType_WithStringMessage_ShouldFailWhenValueIsNull() { Action action = () => Assert.IsExactInstanceOfType(null, typeof(AssertTests), "User-provided message"); action.Should().Throw() - .WithMessage("Assert.IsExactInstanceOfType failed. 'value' expression: 'null'. User-provided message"); + .WithMessage(""" +Assert.IsExactInstanceOfType(null) failed. User-provided message + value: (null) +"""); } public void ExactInstanceOfType_WithStringMessage_ShouldFailWhenTypeIsNull() { Action action = () => Assert.IsExactInstanceOfType(5, null, "User-provided message"); action.Should().Throw() - .WithMessage("Assert.IsExactInstanceOfType failed. 'value' expression: '5'. User-provided message"); + .WithMessage(""" +Assert.IsExactInstanceOfType(5) failed. User-provided message + value: 5 +"""); } public void ExactInstanceOfType_WithStringMessage_ShouldFailWhenTypeIsMismatched() { Action action = () => Assert.IsExactInstanceOfType(5, typeof(string), "User-provided message"); action.Should().Throw() - .WithMessage("Assert.IsExactInstanceOfType failed. 'value' expression: '5'. User-provided message Expected exact type:. Actual type:."); + .WithMessage(""" +Assert.IsExactInstanceOfType(5) failed. User-provided message +Expected value to be exactly of the specified type. + value: 5 + expectedType: System.String + actualType: System.Int32 +"""); } public void ExactInstanceOfType_WithStringMessage_ShouldPassWhenTypeIsCorrect() @@ -82,7 +118,10 @@ public async Task ExactInstanceOfType_WithInterpolatedString_ShouldFailWhenValue DateTime dateTime = DateTime.Now; Func action = async () => Assert.IsExactInstanceOfType(null, typeof(AssertTests), $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}"); (await action.Should().ThrowAsync()) - .WithMessage($"Assert.IsExactInstanceOfType failed. 'value' expression: 'null'. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + .WithMessage(""" + Assert.IsExactInstanceOfType(null) failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString()* + value: (null) + """); o.WasToStringCalled.Should().BeTrue(); } @@ -91,7 +130,10 @@ public void ExactInstanceOfType_WithInterpolatedString_ShouldFailWhenTypeIsNull( DummyClassTrackingToStringCalls o = new(); Action action = () => Assert.IsExactInstanceOfType(5, null, $"User-provided message {o}"); action.Should().Throw() - .WithMessage("Assert.IsExactInstanceOfType failed. 'value' expression: '5'. User-provided message DummyClassTrackingToStringCalls"); + .WithMessage(""" +Assert.IsExactInstanceOfType(5) failed. User-provided message DummyClassTrackingToStringCalls + value: 5 +"""); o.WasToStringCalled.Should().BeTrue(); } @@ -100,7 +142,13 @@ public void ExactInstanceOfType_WithInterpolatedString_ShouldFailWhenTypeIsMisma DummyClassTrackingToStringCalls o = new(); Action action = () => Assert.IsExactInstanceOfType(5, typeof(string), $"User-provided message {o}"); action.Should().Throw() - .WithMessage("Assert.IsExactInstanceOfType failed. 'value' expression: '5'. User-provided message DummyClassTrackingToStringCalls Expected exact type:. Actual type:."); + .WithMessage(""" +Assert.IsExactInstanceOfType(5) failed. User-provided message DummyClassTrackingToStringCalls +Expected value to be exactly of the specified type. + value: 5 + expectedType: System.String + actualType: System.Int32 +"""); o.WasToStringCalled.Should().BeTrue(); } @@ -134,21 +182,36 @@ public void ExactInstanceNotOfTypeShouldFailOnExactType() object x = new MemoryStream(); Action action = () => Assert.IsNotExactInstanceOfType(x, typeof(MemoryStream)); action.Should().Throw() - .WithMessage("Assert.IsNotExactInstanceOfType failed. Wrong exact Type:. Actual type:. 'value' expression: 'x'."); + .WithMessage(""" +Assert.IsNotExactInstanceOfType(x) failed. +Value should not be exactly of the specified type. + value: + wrongType: System.IO.MemoryStream + actualType: System.IO.MemoryStream +"""); } public void IsExactInstanceOfTypeUsingGenericType_WhenValueIsNull_Fails() { Action action = () => Assert.IsExactInstanceOfType(null); action.Should().Throw() - .WithMessage("Assert.IsExactInstanceOfType failed. 'value' expression: 'null'."); + .WithMessage(""" +Assert.IsExactInstanceOfType(null) failed. + value: (null) +"""); } public void IsExactInstanceOfTypeUsingGenericType_WhenTypeMismatch_Fails() { Action action = () => Assert.IsExactInstanceOfType(5); action.Should().Throw() - .WithMessage("Assert.IsExactInstanceOfType failed. 'value' expression: '5'. Expected exact type:. Actual type:."); + .WithMessage(""" +Assert.IsExactInstanceOfType(5) failed. +Expected value to be exactly of the specified type. + value: 5 + expectedType: System.String + actualType: System.Int32 +"""); } public void IsExactInstanceOfTypeUsingGenericType_WhenDerivedType_Fails() @@ -156,7 +219,13 @@ public void IsExactInstanceOfTypeUsingGenericType_WhenDerivedType_Fails() object x = new MemoryStream(); Action action = () => Assert.IsExactInstanceOfType(x); action.Should().Throw() - .WithMessage("Assert.IsExactInstanceOfType failed. 'value' expression: 'x'. Expected exact type:. Actual type:."); + .WithMessage(""" +Assert.IsExactInstanceOfType(x) failed. +Expected value to be exactly of the specified type. + value: + expectedType: System.IO.Stream + actualType: System.IO.MemoryStream +"""); } public void IsExactInstanceOfTypeUsingGenericType_OnSameInstance_DoesNotThrow() => Assert.IsExactInstanceOfType(5); @@ -178,7 +247,13 @@ public void IsExactInstanceOfTypeUsingGenericType_OnHigherInstance_Fails() { Action action = () => Assert.IsExactInstanceOfType(5); action.Should().Throw() - .WithMessage("Assert.IsExactInstanceOfType failed. 'value' expression: '5'. Expected exact type:. Actual type:."); + .WithMessage(""" +Assert.IsExactInstanceOfType(5) failed. +Expected value to be exactly of the specified type. + value: 5 + expectedType: System.Object + actualType: System.Int32 +"""); } public void IsExactInstanceOfTypeUsingGenericTypeWithReturn_OnExactType_DoesNotThrow() @@ -205,7 +280,13 @@ public void IsNotExactInstanceOfTypeUsingGenericType_OnExactType_Fails() object x = new MemoryStream(); Action action = () => Assert.IsNotExactInstanceOfType(x); action.Should().Throw() - .WithMessage("Assert.IsNotExactInstanceOfType failed. Wrong exact Type:. Actual type:. 'value' expression: 'x'."); + .WithMessage(""" +Assert.IsNotExactInstanceOfType(x) failed. +Value should not be exactly of the specified type. + value: + wrongType: System.IO.MemoryStream + actualType: System.IO.MemoryStream +"""); } public void IsExactInstanceOfType_WhenNonNullNullableValue_LearnNonNull() @@ -277,4 +358,98 @@ public void IsNotExactInstanceOfType_WhenNonNullNullableTypeAndMessage_LearnNonN Assert.IsNotExactInstanceOfType(new object(), intType, "my message"); _ = intType.ToString(); // no warning about possible null } + + #region IsExactInstanceOfType/IsNotExactInstanceOfType truncation and newline escaping + + public void IsExactInstanceOfType_WithLongExpression_ShouldTruncateExpression() + { + object aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ = "hello"; + + Action action = () => Assert.IsExactInstanceOfType(aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ, typeof(int)); + action.Should().Throw() + .WithMessage(""" + Assert.IsExactInstanceOfType(aVeryLongVariableNameThatExceedsOneHundredCharacte...) failed. + Expected value to be exactly of the specified type. + value: "hello" + expectedType: System.Int32 + actualType: System.String + """); + } + + public void IsExactInstanceOfType_WithLongToStringValue_ShouldTruncateValue() + { + var obj = new ObjectWithLongToString(); + + Action action = () => Assert.IsExactInstanceOfType(obj, typeof(int)); + action.Should().Throw() + .WithMessage($""" + Assert.IsExactInstanceOfType(obj) failed. + Expected value to be exactly of the specified type. + value: {new string('L', 256)}... 44 more + expectedType: System.Int32 + actualType: Microsoft.VisualStudio.TestPlatform.TestFramework.UnitTests.ObjectWithLongToString + """); + } + + public void IsExactInstanceOfType_WithNewlineInToString_ShouldEscapeNewlines() + { + var obj = new ObjectWithNewlineToString(); + + Action action = () => Assert.IsExactInstanceOfType(obj, typeof(int)); + action.Should().Throw() + .WithMessage(""" + Assert.IsExactInstanceOfType(obj) failed. + Expected value to be exactly of the specified type. + value: line1\r\nline2\nline3 + expectedType: System.Int32 + actualType: Microsoft.VisualStudio.TestPlatform.TestFramework.UnitTests.ObjectWithNewlineToString + """); + } + + public void IsNotExactInstanceOfType_WithLongExpression_ShouldTruncateExpression() + { + string aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ = "hello"; + + Action action = () => Assert.IsNotExactInstanceOfType(aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ, typeof(string)); + action.Should().Throw() + .WithMessage(""" + Assert.IsNotExactInstanceOfType(aVeryLongVariableNameThatExceedsOneHundredCharacte...) failed. + Value should not be exactly of the specified type. + value: "hello" + wrongType: System.String + actualType: System.String + """); + } + + public void IsNotExactInstanceOfType_WithLongToStringValue_ShouldTruncateValue() + { + var obj = new ObjectWithLongToString(); + + Action action = () => Assert.IsNotExactInstanceOfType(obj, typeof(ObjectWithLongToString)); + action.Should().Throw() + .WithMessage($""" + Assert.IsNotExactInstanceOfType(obj) failed. + Value should not be exactly of the specified type. + value: {new string('L', 256)}... 44 more + wrongType: Microsoft.VisualStudio.TestPlatform.TestFramework.UnitTests.ObjectWithLongToString + actualType: Microsoft.VisualStudio.TestPlatform.TestFramework.UnitTests.ObjectWithLongToString + """); + } + + public void IsNotExactInstanceOfType_WithNewlineInToString_ShouldEscapeNewlines() + { + var obj = new ObjectWithNewlineToString(); + + Action action = () => Assert.IsNotExactInstanceOfType(obj, typeof(ObjectWithNewlineToString)); + action.Should().Throw() + .WithMessage(""" + Assert.IsNotExactInstanceOfType(obj) failed. + Value should not be exactly of the specified type. + value: line1\r\nline2\nline3 + wrongType: Microsoft.VisualStudio.TestPlatform.TestFramework.UnitTests.ObjectWithNewlineToString + actualType: Microsoft.VisualStudio.TestPlatform.TestFramework.UnitTests.ObjectWithNewlineToString + """); + } + + #endregion } diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsInRange.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsInRange.cs index b9a6646e91..b511a61536 100644 --- a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsInRange.cs +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsInRange.cs @@ -57,7 +57,13 @@ public void IsInRange_WithValueBelowRange_ThrowsAssertFailedException() // Act & Assert Action action = () => Assert.IsInRange(minValue, maxValue, value); action.Should().Throw() - .And.Message.Should().Contain("Value '3' is not within the expected range [5..10]"); + .WithMessage(""" + Assert.IsInRange(value) failed. + Value is not within the expected range. + minValue: 5 + maxValue: 10 + value: 3 + """); } public void IsInRange_WithValueAboveRange_ThrowsAssertFailedException() @@ -70,7 +76,13 @@ public void IsInRange_WithValueAboveRange_ThrowsAssertFailedException() // Act & Assert Action action = () => Assert.IsInRange(minValue, maxValue, value); action.Should().Throw() - .And.Message.Should().Contain("Value '8' is not within the expected range [1..5]"); + .WithMessage(""" + Assert.IsInRange(value) failed. + Value is not within the expected range. + minValue: 1 + maxValue: 5 + value: 8 + """); } public void IsInRange_WithCustomMessage_IncludesCustomMessage() @@ -86,8 +98,13 @@ public void IsInRange_WithCustomMessage_IncludesCustomMessage() // Assert action.Should().ThrowExactly() - .And.Message.Should().Contain("Value '10' is not within the expected range [1..5]") - .And.Contain(customMessage); + .WithMessage(""" + Assert.IsInRange(value) failed. Custom error message + Value is not within the expected range. + minValue: 1 + maxValue: 5 + value: 10 + """); } public void IsInRange_WithDoubleValues_WorksCorrectly() @@ -102,7 +119,13 @@ public void IsInRange_WithDoubleValues_WorksCorrectly() Assert.IsInRange(minValue, maxValue, valueInRange); Action action = () => Assert.IsInRange(minValue, maxValue, valueOutOfRange); action.Should().Throw() - .And.Message.Should().Contain("Value '6' is not within the expected range [1.5..5.5]"); + .WithMessage(""" + Assert.IsInRange(valueOutOfRange) failed. + Value is not within the expected range. + minValue: 1.5 + maxValue: 5.5 + value: 6 + """); } public void IsInRange_WithDateTimeValues_WorksCorrectly() @@ -119,7 +142,7 @@ public void IsInRange_WithDateTimeValues_WorksCorrectly() // Assert action.Should().ThrowExactly() - .And.Message.Should().Contain("is not within the expected range"); + .WithMessage("Assert.IsInRange(valueOutOfRange) failed.*Value is not within the expected range*"); } public void IsInRange_WithCharValues_WorksCorrectly() @@ -136,7 +159,7 @@ public void IsInRange_WithCharValues_WorksCorrectly() // Assert action.Should().ThrowExactly() - .And.Message.Should().Contain("Value 'a' is not within the expected range [A..Z]"); + .WithMessage("Assert.IsInRange(valueOutOfRange) failed.*Value is not within the expected range*"); } public void IsInRange_WithNullMessage_DoesNotThrow() @@ -195,7 +218,13 @@ public void IsInRange_WithAllNegativeValuesBelowRange_ThrowsAssertFailedExceptio // Assert action.Should().ThrowExactly() - .And.Message.Should().Contain("Value '-12' is not within the expected range [-10..-5]"); + .WithMessage(""" + Assert.IsInRange(value) failed. + Value is not within the expected range. + minValue: -10 + maxValue: -5 + value: -12 + """); } public void IsInRange_WithAllNegativeValuesAboveRange_ThrowsAssertFailedException() @@ -210,7 +239,13 @@ public void IsInRange_WithAllNegativeValuesAboveRange_ThrowsAssertFailedExceptio // Assert action.Should().ThrowExactly() - .And.Message.Should().Contain("Value '-3' is not within the expected range [-10..-5]"); + .WithMessage(""" + Assert.IsInRange(value) failed. + Value is not within the expected range. + minValue: -10 + maxValue: -5 + value: -3 + """); } public void IsInRange_WithRangeSpanningNegativeToPositive_ValueInRange_DoesNotThrow() @@ -258,7 +293,13 @@ public void IsInRange_WithRangeSpanningNegativeToPositive_ValueBelowRange_Throws // Assert action.Should().ThrowExactly() - .And.Message.Should().Contain("Value '-7' is not within the expected range [-5..5]"); + .WithMessage(""" + Assert.IsInRange(value) failed. + Value is not within the expected range. + minValue: -5 + maxValue: 5 + value: -7 + """); } public void IsInRange_WithRangeSpanningNegativeToPositive_ValueAboveRange_ThrowsAssertFailedException() @@ -273,7 +314,13 @@ public void IsInRange_WithRangeSpanningNegativeToPositive_ValueAboveRange_Throws // Assert action.Should().ThrowExactly() - .And.Message.Should().Contain("Value '7' is not within the expected range [-5..5]"); + .WithMessage(""" + Assert.IsInRange(value) failed. + Value is not within the expected range. + minValue: -5 + maxValue: 5 + value: 7 + """); } public void IsInRange_WithNegativeDoubleValues_WorksCorrectly() @@ -299,7 +346,7 @@ public void IsInRange_WithMaxValueLessThanMinValue_ThrowsArgumentOutOfRangeExcep // Assert action.Should().ThrowExactly() - .And.Message.Should().Contain("The maximum value must be greater than or equal to the minimum value"); + .WithMessage("The maximum value must be greater than or equal to the minimum value. (Parameter 'maxValue')"); } public void IsInRange_WithMaxValueEqualToMinValue_Int_ShouldPassIfValueIsEqual() @@ -322,7 +369,13 @@ public void IsInRange_WithMaxValueEqualToMinValue_Int_ShouldFailIfValueIsSmaller Action action = () => Assert.IsInRange(minValue, maxValue, value); action.Should().ThrowExactly() - .And.Message.Should().Contain("Value '4' is not within the expected range [5..5]"); + .WithMessage(""" + Assert.IsInRange(value) failed. + Value is not within the expected range. + minValue: 5 + maxValue: 5 + value: 4 + """); } public void IsInRange_WithMaxValueEqualToMinValue_Int_ShouldFailIfValueIsLarger() @@ -334,7 +387,13 @@ public void IsInRange_WithMaxValueEqualToMinValue_Int_ShouldFailIfValueIsLarger( Action action = () => Assert.IsInRange(minValue, maxValue, value); action.Should().ThrowExactly() - .And.Message.Should().Contain("Value '6' is not within the expected range [5..5]"); + .WithMessage(""" + Assert.IsInRange(value) failed. + Value is not within the expected range. + minValue: 5 + maxValue: 5 + value: 6 + """); } public void IsInRange_WithMaxValueEqualToMinValue_Float_ShouldPassIfValueIsEqual() @@ -357,7 +416,13 @@ public void IsInRange_WithMaxValueEqualToMinValue_Float_ShouldFailIfValueIsSmall Action action = () => Assert.IsInRange(minValue, maxValue, value); action.Should().ThrowExactly() - .And.Message.Should().Contain("Value '4' is not within the expected range [5..5]"); + .WithMessage(""" + Assert.IsInRange(value) failed. + Value is not within the expected range. + minValue: 5 + maxValue: 5 + value: 4 + """); } public void IsInRange_WithMaxValueEqualToMinValue_Float_ShouldFailIfValueIsLarger() @@ -369,8 +434,89 @@ public void IsInRange_WithMaxValueEqualToMinValue_Float_ShouldFailIfValueIsLarge Action action = () => Assert.IsInRange(minValue, maxValue, value); action.Should().ThrowExactly() - .And.Message.Should().Contain("Value '6' is not within the expected range [5..5]"); + .WithMessage(""" + Assert.IsInRange(value) failed. + Value is not within the expected range. + minValue: 5 + maxValue: 5 + value: 6 + """); } #endregion // IsInRange Tests + + #region IsInRange truncation and newline escaping + + public void IsInRange_WithLongExpression_ShouldTruncateExpression() + { + int aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ = 20; + + Action action = () => Assert.IsInRange(1, 10, aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ); + action.Should().Throw() + .WithMessage(""" + Assert.IsInRange(aVeryLongVariableNameThatExceedsOneHundredCharacte...) failed. + Value is not within the expected range. + minValue: 1 + maxValue: 10 + value: 20 + """); + } + + public void IsInRange_WithLongToStringValue_ShouldTruncateValue() + { + var min = new IsInRangeComparableWithLongToString(1); + var max = new IsInRangeComparableWithLongToString(10); + var value = new IsInRangeComparableWithLongToString(20); + + Action action = () => Assert.IsInRange(min, max, value); + action.Should().Throw() + .WithMessage($""" + Assert.IsInRange(value) failed. + Value is not within the expected range. + minValue: {new string('R', 256)}... 44 more + maxValue: {new string('R', 256)}... 44 more + value: {new string('R', 256)}... 44 more + """); + } + + public void IsInRange_WithNewlineInToString_ShouldEscapeNewlines() + { + var min = new IsInRangeComparableWithNewlineToString(1); + var max = new IsInRangeComparableWithNewlineToString(10); + var value = new IsInRangeComparableWithNewlineToString(20); + + Action action = () => Assert.IsInRange(min, max, value); + action.Should().Throw() + .WithMessage(""" + Assert.IsInRange(value) failed. + Value is not within the expected range. + minValue: line1\r\nline2 + maxValue: line1\r\nline2 + value: line1\r\nline2 + """); + } + + #endregion + + private readonly struct IsInRangeComparableWithLongToString : IComparable + { + private readonly int _value; + + public IsInRangeComparableWithLongToString(int value) => _value = value; + + public int CompareTo(IsInRangeComparableWithLongToString other) => _value.CompareTo(other._value); + + public override string ToString() => new string('R', 300); + } + + private readonly struct IsInRangeComparableWithNewlineToString : IComparable + { + private readonly int _value; + + public IsInRangeComparableWithNewlineToString(int value) => _value = value; + + public int CompareTo(IsInRangeComparableWithNewlineToString other) => _value.CompareTo(other._value); + + public override string ToString() => "line1\r\nline2"; + } } diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsInstanceOfTypeTests.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsInstanceOfTypeTests.cs index 6e5e917ed7..0dda1f3dc0 100644 --- a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsInstanceOfTypeTests.cs +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsInstanceOfTypeTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using AwesomeAssertions; @@ -12,21 +12,33 @@ public void InstanceOfTypeShouldFailWhenValueIsNull() { Action action = () => Assert.IsInstanceOfType(null, typeof(AssertTests)); action.Should().Throw() - .WithMessage("Assert.IsInstanceOfType failed. 'value' expression: 'null'."); + .WithMessage(""" + Assert.IsInstanceOfType(null) failed. + value: (null) + """); } public void InstanceOfTypeShouldFailWhenTypeIsNull() { Action action = () => Assert.IsInstanceOfType(5, null); action.Should().Throw() - .WithMessage("Assert.IsInstanceOfType failed. 'value' expression: '5'."); + .WithMessage(""" + Assert.IsInstanceOfType(5) failed. + value: 5 + """); } public void InstanceOfTypeShouldFailWhenTypeIsMismatched() { Action action = () => Assert.IsInstanceOfType(5, typeof(string)); action.Should().Throw() - .WithMessage("Assert.IsInstanceOfType failed. 'value' expression: '5'. Expected type:. Actual type:."); + .WithMessage(""" + Assert.IsInstanceOfType(5) failed. + Expected value to be of the specified type. + value: 5 + expectedType: System.String + actualType: System.Int32 + """); } public void InstanceOfTypeShouldPassOnSameInstance() => Assert.IsInstanceOfType(5, typeof(int)); @@ -37,21 +49,33 @@ public void InstanceOfType_WithStringMessage_ShouldFailWhenValueIsNull() { Action action = () => Assert.IsInstanceOfType(null, typeof(AssertTests), "User-provided message"); action.Should().Throw() - .WithMessage("Assert.IsInstanceOfType failed. 'value' expression: 'null'. User-provided message"); + .WithMessage(""" + Assert.IsInstanceOfType(null) failed. User-provided message + value: (null) + """); } public void InstanceOfType_WithStringMessage_ShouldFailWhenTypeIsNull() { Action action = () => Assert.IsInstanceOfType(5, null, "User-provided message"); action.Should().Throw() - .WithMessage("Assert.IsInstanceOfType failed. 'value' expression: '5'. User-provided message"); + .WithMessage(""" + Assert.IsInstanceOfType(5) failed. User-provided message + value: 5 + """); } public void InstanceOfType_WithStringMessage_ShouldFailWhenTypeIsMismatched() { Action action = () => Assert.IsInstanceOfType(5, typeof(string), "User-provided message"); action.Should().Throw() - .WithMessage("Assert.IsInstanceOfType failed. 'value' expression: '5'. User-provided message Expected type:. Actual type:."); + .WithMessage(""" + Assert.IsInstanceOfType(5) failed. User-provided message + Expected value to be of the specified type. + value: 5 + expectedType: System.String + actualType: System.Int32 + """); } public void InstanceOfType_WithStringMessage_ShouldPassWhenTypeIsCorrect() @@ -63,7 +87,10 @@ public async Task InstanceOfType_WithInterpolatedString_ShouldFailWhenValueIsNul DateTime dateTime = DateTime.Now; Func action = async () => Assert.IsInstanceOfType(null, typeof(AssertTests), $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}"); (await action.Should().ThrowAsync()) - .WithMessage($"Assert.IsInstanceOfType failed. 'value' expression: 'null'. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + .WithMessage(""" + Assert.IsInstanceOfType(null) failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString()* + value: (null) + """); o.WasToStringCalled.Should().BeTrue(); } @@ -72,7 +99,10 @@ public void InstanceOfType_WithInterpolatedString_ShouldFailWhenTypeIsNull() DummyClassTrackingToStringCalls o = new(); Action action = () => Assert.IsInstanceOfType(5, null, $"User-provided message {o}"); action.Should().Throw() - .WithMessage("Assert.IsInstanceOfType failed. 'value' expression: '5'. User-provided message DummyClassTrackingToStringCalls"); + .WithMessage(""" + Assert.IsInstanceOfType(5) failed. User-provided message DummyClassTrackingToStringCalls + value: 5 + """); o.WasToStringCalled.Should().BeTrue(); } @@ -81,7 +111,13 @@ public void InstanceOfType_WithInterpolatedString_ShouldFailWhenTypeIsMismatched DummyClassTrackingToStringCalls o = new(); Action action = () => Assert.IsInstanceOfType(5, typeof(string), $"User-provided message {o}"); action.Should().Throw() - .WithMessage("Assert.IsInstanceOfType failed. 'value' expression: '5'. User-provided message DummyClassTrackingToStringCalls Expected type:. Actual type:."); + .WithMessage(""" + Assert.IsInstanceOfType(5) failed. User-provided message DummyClassTrackingToStringCalls + Expected value to be of the specified type. + value: 5 + expectedType: System.String + actualType: System.Int32 + """); o.WasToStringCalled.Should().BeTrue(); } @@ -108,14 +144,23 @@ public void IsInstanceOfTypeUsingGenericType_WhenValueIsNull_Fails() { Action action = () => Assert.IsInstanceOfType(null); action.Should().Throw() - .WithMessage("Assert.IsInstanceOfType failed. 'value' expression: 'null'."); + .WithMessage(""" + Assert.IsInstanceOfType(null) failed. + value: (null) + """); } public void IsInstanceOfTypeUsingGenericType_WhenTypeMismatch_Fails() { Action action = () => Assert.IsInstanceOfType(5); action.Should().Throw() - .WithMessage("Assert.IsInstanceOfType failed. 'value' expression: '5'. Expected type:. Actual type:."); + .WithMessage(""" + Assert.IsInstanceOfType(5) failed. + Expected value to be of the specified type. + value: 5 + expectedType: System.String + actualType: System.Int32 + """); } public void IsInstanceOfTypeUsingGenericTypeWithOutParameter_WhenValueIsNull_Fails() @@ -229,4 +274,98 @@ public void IsNotInstanceOfType_WhenNonNullNullableTypeAndMessage_LearnNonNull() private Type? GetObjType() => typeof(object); private Type? GetIntType() => typeof(int); + + #region IsInstanceOfType/IsNotInstanceOfType truncation and newline escaping + + public void IsInstanceOfType_WithLongExpression_ShouldTruncateExpression() + { + object aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ = "hello"; + + Action action = () => Assert.IsInstanceOfType(aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ, typeof(int)); + action.Should().Throw() + .WithMessage(""" + Assert.IsInstanceOfType(aVeryLongVariableNameThatExceedsOneHundredCharacte...) failed. + Expected value to be of the specified type. + value: "hello" + expectedType: System.Int32 + actualType: System.String + """); + } + + public void IsInstanceOfType_WithLongToStringValue_ShouldTruncateValue() + { + var obj = new ObjectWithLongToString(); + + Action action = () => Assert.IsInstanceOfType(obj, typeof(int)); + action.Should().Throw() + .WithMessage($""" + Assert.IsInstanceOfType(obj) failed. + Expected value to be of the specified type. + value: {new string('L', 256)}... 44 more + expectedType: System.Int32 + actualType: Microsoft.VisualStudio.TestPlatform.TestFramework.UnitTests.ObjectWithLongToString + """); + } + + public void IsInstanceOfType_WithNewlineInToString_ShouldEscapeNewlines() + { + var obj = new ObjectWithNewlineToString(); + + Action action = () => Assert.IsInstanceOfType(obj, typeof(int)); + action.Should().Throw() + .WithMessage(""" + Assert.IsInstanceOfType(obj) failed. + Expected value to be of the specified type. + value: line1\r\nline2\nline3 + expectedType: System.Int32 + actualType: Microsoft.VisualStudio.TestPlatform.TestFramework.UnitTests.ObjectWithNewlineToString + """); + } + + public void IsNotInstanceOfType_WithLongExpression_ShouldTruncateExpression() + { + string aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ = "hello"; + + Action action = () => Assert.IsNotInstanceOfType(aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ, typeof(string)); + action.Should().Throw() + .WithMessage(""" + Assert.IsNotInstanceOfType(aVeryLongVariableNameThatExceedsOneHundredCharacte...) failed. + Value should not be of the specified type. + value: "hello" + wrongType: System.String + actualType: System.String + """); + } + + public void IsNotInstanceOfType_WithLongToStringValue_ShouldTruncateValue() + { + var obj = new ObjectWithLongToString(); + + Action action = () => Assert.IsNotInstanceOfType(obj, typeof(ObjectWithLongToString)); + action.Should().Throw() + .WithMessage($""" + Assert.IsNotInstanceOfType(obj) failed. + Value should not be of the specified type. + value: {new string('L', 256)}... 44 more + wrongType: Microsoft.VisualStudio.TestPlatform.TestFramework.UnitTests.ObjectWithLongToString + actualType: Microsoft.VisualStudio.TestPlatform.TestFramework.UnitTests.ObjectWithLongToString + """); + } + + public void IsNotInstanceOfType_WithNewlineInToString_ShouldEscapeNewlines() + { + var obj = new ObjectWithNewlineToString(); + + Action action = () => Assert.IsNotInstanceOfType(obj, typeof(ObjectWithNewlineToString)); + action.Should().Throw() + .WithMessage(""" + Assert.IsNotInstanceOfType(obj) failed. + Value should not be of the specified type. + value: line1\r\nline2\nline3 + wrongType: Microsoft.VisualStudio.TestPlatform.TestFramework.UnitTests.ObjectWithNewlineToString + actualType: Microsoft.VisualStudio.TestPlatform.TestFramework.UnitTests.ObjectWithNewlineToString + """); + } + + #endregion } diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsNull.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsNull.cs index bd365d680a..93e8d4509c 100644 --- a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsNull.cs +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsNull.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using AwesomeAssertions; @@ -16,7 +16,11 @@ public void IsNull_PassNonNull_ShouldFail() { Action action = () => Assert.IsNull(new object()); action.Should().Throw() - .WithMessage("Assert.IsNull failed. 'value' expression: 'new object()'."); + .WithMessage(""" + Assert.IsNull(new object()) failed. + Expected value to be null. + value: + """); } public void IsNull_StringMessage_PassNull_ShouldPass() @@ -26,7 +30,11 @@ public void IsNull_StringMessage_PassNonNull_ShouldFail() { Action action = () => Assert.IsNull(new object(), "User-provided message"); action.Should().Throw() - .WithMessage("Assert.IsNull failed. 'value' expression: 'new object()'. User-provided message"); + .WithMessage(""" + Assert.IsNull(new object()) failed. User-provided message + Expected value to be null. + value: + """); } public void IsNull_InterpolatedString_PassNull_ShouldPass() @@ -42,7 +50,11 @@ public async Task IsNull_InterpolatedString_PassNonNull_ShouldFail() DateTime dateTime = DateTime.Now; Func action = async () => Assert.IsNull(new object(), $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}"); (await action.Should().ThrowAsync()) - .WithMessage($"Assert.IsNull failed. 'value' expression: 'new object()'. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + .WithMessage(""" + Assert.IsNull(new object()) failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString()* + Expected value to be null. + value: + """); o.WasToStringCalled.Should().BeTrue(); } @@ -73,14 +85,22 @@ public void IsNotNull_PassNull_ShouldFail() { Action action = () => Assert.IsNotNull(null); action.Should().Throw() - .WithMessage("Assert.IsNotNull failed. 'value' expression: 'null'."); + .WithMessage(""" + Assert.IsNotNull(null) failed. + Expected a non-null value. + value: (null) + """); } public void IsNotNull_StringMessage_PassNonNull_ShouldFail() { Action action = () => Assert.IsNotNull(null, "User-provided message"); action.Should().Throw() - .WithMessage("Assert.IsNotNull failed. 'value' expression: 'null'. User-provided message"); + .WithMessage(""" + Assert.IsNotNull(null) failed. User-provided message + Expected a non-null value. + value: (null) + """); } public async Task IsNotNull_InterpolatedString_PassNonNull_ShouldFail() @@ -89,7 +109,11 @@ public async Task IsNotNull_InterpolatedString_PassNonNull_ShouldFail() DateTime dateTime = DateTime.Now; Func action = async () => Assert.IsNotNull(null, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}"); (await action.Should().ThrowAsync()) - .WithMessage($"Assert.IsNotNull failed. 'value' expression: 'null'. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + .WithMessage(""" + Assert.IsNotNull(null) failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString()* + Expected a non-null value. + value: (null) + """); o.WasToStringCalled.Should().BeTrue(); } } diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsTrueTests.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsTrueTests.cs index a09c1416ef..980974a46a 100644 --- a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsTrueTests.cs +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsTrueTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using AwesomeAssertions; @@ -12,7 +12,11 @@ public void IsFalseNullableBooleanShouldFailWithNull() bool? nullBool = null; Action action = () => Assert.IsFalse(nullBool); action.Should().Throw() - .WithMessage("Assert.IsFalse failed. 'condition' expression: 'nullBool'."); + .WithMessage(""" + Assert.IsFalse(nullBool) failed. + Expected condition to be false. + condition: (null) + """); } public void IsFalseNullableBooleanShouldFailWithTrue() @@ -20,7 +24,11 @@ public void IsFalseNullableBooleanShouldFailWithTrue() bool? nullBool = true; Action action = () => Assert.IsFalse(nullBool); action.Should().Throw() - .WithMessage("Assert.IsFalse failed. 'condition' expression: 'nullBool'."); + .WithMessage(""" + Assert.IsFalse(nullBool) failed. + Expected condition to be false. + condition: True + """); } public void IsFalseNullableBooleanShouldNotFailWithFalse() @@ -33,7 +41,11 @@ public void IsFalseBooleanShouldFailWithTrue() { Action action = () => Assert.IsFalse(true); action.Should().Throw() - .WithMessage("Assert.IsFalse failed. 'condition' expression: 'true'."); + .WithMessage(""" + Assert.IsFalse(true) failed. + Expected condition to be false. + condition: True + """); } public void IsFalseBooleanShouldNotFailWithFalse() @@ -44,7 +56,11 @@ public void IsFalseNullableBooleanStringMessageShouldFailWithNull() bool? nullBool = null; Action action = () => Assert.IsFalse(nullBool, "User-provided message"); action.Should().Throw() - .WithMessage("Assert.IsFalse failed. 'condition' expression: 'nullBool'. User-provided message"); + .WithMessage(""" + Assert.IsFalse(nullBool) failed. User-provided message + Expected condition to be false. + condition: (null) + """); } public void IsFalseNullableBooleanStringMessageShouldFailWithTrue() @@ -52,7 +68,11 @@ public void IsFalseNullableBooleanStringMessageShouldFailWithTrue() bool? nullBool = true; Action action = () => Assert.IsFalse(nullBool, "User-provided message"); action.Should().Throw() - .WithMessage("Assert.IsFalse failed. 'condition' expression: 'nullBool'. User-provided message"); + .WithMessage(""" + Assert.IsFalse(nullBool) failed. User-provided message + Expected condition to be false. + condition: True + """); } public void IsFalseNullableBooleanStringMessageShouldNotFailWithFalse() @@ -65,7 +85,11 @@ public void IsFalseBooleanStringMessageShouldFailWithTrue() { Action action = () => Assert.IsFalse(true, "User-provided message"); action.Should().Throw() - .WithMessage("Assert.IsFalse failed. 'condition' expression: 'true'. User-provided message"); + .WithMessage(""" + Assert.IsFalse(true) failed. User-provided message + Expected condition to be false. + condition: True + """); } public void IsFalseBooleanStringMessageShouldNotFailWithFalse() @@ -78,7 +102,11 @@ public async Task IsFalseNullableBooleanInterpolatedStringMessageShouldFailWithN DateTime dateTime = DateTime.Now; Func action = async () => Assert.IsFalse(nullBool, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}"); (await action.Should().ThrowAsync()) - .WithMessage($"Assert.IsFalse failed. 'condition' expression: 'nullBool'. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + .WithMessage(""" + Assert.IsFalse(nullBool) failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString()* + Expected condition to be false. + condition: (null) + """); } public async Task IsFalseNullableBooleanInterpolatedStringMessageShouldFailWithTrue() @@ -88,7 +116,11 @@ public async Task IsFalseNullableBooleanInterpolatedStringMessageShouldFailWithT DateTime dateTime = DateTime.Now; Func action = async () => Assert.IsFalse(nullBool, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}"); (await action.Should().ThrowAsync()) - .WithMessage($"Assert.IsFalse failed. 'condition' expression: 'nullBool'. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + .WithMessage(""" + Assert.IsFalse(nullBool) failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString()* + Expected condition to be false. + condition: True + """); } public void IsFalseNullableBooleanInterpolatedStringMessageShouldNotFailWithFalse() @@ -103,7 +135,11 @@ public async Task IsFalseBooleanInterpolatedStringMessageShouldFailWithTrue() DateTime dateTime = DateTime.Now; Func action = async () => Assert.IsFalse(true, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}"); (await action.Should().ThrowAsync()) - .WithMessage($"Assert.IsFalse failed. 'condition' expression: 'true'. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + .WithMessage(""" + Assert.IsFalse(true) failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString()* + Expected condition to be false. + condition: True + """); } public void IsFalseBooleanInterpolatedStringMessageShouldNotFailWithFalse() @@ -114,7 +150,11 @@ public void IsTrueNullableBooleanShouldFailWithNull() bool? nullBool = null; Action action = () => Assert.IsTrue(nullBool); action.Should().Throw() - .WithMessage("Assert.IsTrue failed. 'condition' expression: 'nullBool'."); + .WithMessage(""" + Assert.IsTrue(nullBool) failed. + Expected condition to be true. + condition: (null) + """); } public void IsTrueNullableBooleanShouldFailWithFalse() @@ -122,7 +162,11 @@ public void IsTrueNullableBooleanShouldFailWithFalse() bool? nullBool = false; Action action = () => Assert.IsTrue(nullBool); action.Should().Throw() - .WithMessage("Assert.IsTrue failed. 'condition' expression: 'nullBool'."); + .WithMessage(""" + Assert.IsTrue(nullBool) failed. + Expected condition to be true. + condition: False + """); } public void IsTrueNullableBooleanShouldNotFailWithTrue() @@ -135,7 +179,11 @@ public void IsTrueBooleanShouldFailWithFalse() { Action action = () => Assert.IsTrue(false); action.Should().Throw() - .WithMessage("Assert.IsTrue failed. 'condition' expression: 'false'."); + .WithMessage(""" + Assert.IsTrue(false) failed. + Expected condition to be true. + condition: False + """); } public void IsTrueBooleanShouldNotFailWithTrue() @@ -146,7 +194,11 @@ public void IsTrueNullableBooleanStringMessageShouldFailWithNull() bool? nullBool = null; Action action = () => Assert.IsTrue(nullBool, "User-provided message"); action.Should().Throw() - .WithMessage("Assert.IsTrue failed. 'condition' expression: 'nullBool'. User-provided message"); + .WithMessage(""" + Assert.IsTrue(nullBool) failed. User-provided message + Expected condition to be true. + condition: (null) + """); } public void IsTrueNullableBooleanStringMessageShouldFailWithFalse() @@ -154,7 +206,11 @@ public void IsTrueNullableBooleanStringMessageShouldFailWithFalse() bool? nullBool = false; Action action = () => Assert.IsTrue(nullBool, "User-provided message"); action.Should().Throw() - .WithMessage("Assert.IsTrue failed. 'condition' expression: 'nullBool'. User-provided message"); + .WithMessage(""" + Assert.IsTrue(nullBool) failed. User-provided message + Expected condition to be true. + condition: False + """); } public void IsTrueNullableBooleanStringMessageShouldNotFailWithTrue() @@ -167,7 +223,11 @@ public void IsTrueBooleanStringMessageShouldFailWithFalse() { Action action = () => Assert.IsTrue(false, "User-provided message"); action.Should().Throw() - .WithMessage("Assert.IsTrue failed. 'condition' expression: 'false'. User-provided message"); + .WithMessage(""" + Assert.IsTrue(false) failed. User-provided message + Expected condition to be true. + condition: False + """); } public void IsTrueBooleanStringMessageShouldNotFailWithTrue() @@ -180,7 +240,11 @@ public async Task IsTrueNullableBooleanInterpolatedStringMessageShouldFailWithNu DateTime dateTime = DateTime.Now; Func action = async () => Assert.IsTrue(nullBool, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}"); (await action.Should().ThrowAsync()) - .WithMessage($"Assert.IsTrue failed. 'condition' expression: 'nullBool'. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + .WithMessage(""" + Assert.IsTrue(nullBool) failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString()* + Expected condition to be true. + condition: (null) + """); } public async Task IsTrueNullableBooleanInterpolatedStringMessageShouldFailWithFalse() @@ -190,7 +254,11 @@ public async Task IsTrueNullableBooleanInterpolatedStringMessageShouldFailWithFa DateTime dateTime = DateTime.Now; Func action = async () => Assert.IsTrue(nullBool, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}"); (await action.Should().ThrowAsync()) - .WithMessage($"Assert.IsTrue failed. 'condition' expression: 'nullBool'. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + .WithMessage(""" + Assert.IsTrue(nullBool) failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString()* + Expected condition to be true. + condition: False + """); } public void IsTrueNullableBooleanInterpolatedStringMessageShouldNotFailWithTrue() @@ -205,9 +273,43 @@ public async Task IsTrueBooleanInterpolatedStringMessageShouldFailWithFalse() DateTime dateTime = DateTime.Now; Func action = async () => Assert.IsTrue(false, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}"); (await action.Should().ThrowAsync()) - .WithMessage($"Assert.IsTrue failed. 'condition' expression: 'false'. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + .WithMessage(""" + Assert.IsTrue(false) failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString()* + Expected condition to be true. + condition: False + """); } public void IsTrueBooleanInterpolatedStringMessageShouldNotFailWithTrue() => Assert.IsTrue(true, $"User-provided message. Input: {true}"); + + #region IsTrue/IsFalse truncation + + public void IsTrue_WithLongExpression_ShouldTruncateExpression() + { + bool aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ = false; + + Action action = () => Assert.IsTrue(aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ); + action.Should().Throw() + .WithMessage(""" + Assert.IsTrue(aVeryLongVariableNameThatExceedsOneHundredCharacte...) failed. + Expected condition to be true. + condition: False + """); + } + + public void IsFalse_WithLongExpression_ShouldTruncateExpression() + { + bool aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ = true; + + Action action = () => Assert.IsFalse(aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ); + action.Should().Throw() + .WithMessage(""" + Assert.IsFalse(aVeryLongVariableNameThatExceedsOneHundredCharacte...) failed. + Expected condition to be false. + condition: True + """); + } + + #endregion } diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.Items.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.Items.cs index 98a5160f29..c81a7375a9 100644 --- a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.Items.cs +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.Items.cs @@ -25,7 +25,13 @@ public void Count_WhenCountIsNotSame_ShouldFail() var collection = new List { 1 }; Action action = () => Assert.HasCount(3, collection); action.Should().Throw() - .WithMessage("Assert.HasCount failed. Expected collection of size 3. Actual: 1. 'collection' expression: 'collection'."); + .WithMessage(""" + Assert.HasCount(collection) failed. + Expected collection to have the specified number of items. + collection: [1] (1 item) + expectedCount: 3 + actualCount: 1 + """); } public async Task Count_InterpolatedString_WhenCountIsNotSame_ShouldFail() @@ -34,7 +40,13 @@ public async Task Count_InterpolatedString_WhenCountIsNotSame_ShouldFail() DateTime dateTime = DateTime.Now; Func action = async () => Assert.HasCount(1, Array.Empty(), $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}"); (await action.Should().ThrowAsync()) - .WithMessage($"Assert.HasCount failed. Expected collection of size 1. Actual: 0. 'collection' expression: 'Array.Empty()'. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + .WithMessage(""" + Assert.HasCount(Array.Empty()) failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString()* + Expected collection to have the specified number of items. + collection: [] (0 items) + expectedCount: 1 + actualCount: 0 + """); o.WasToStringCalled.Should().BeTrue(); } @@ -53,7 +65,13 @@ public void NotAny_WhenNotEmpty_ShouldFail() var collection = new List { 1 }; Action action = () => Assert.IsEmpty(collection); action.Should().Throw() - .WithMessage("Assert.IsEmpty failed. Expected collection of size 0. Actual: 1. 'collection' expression: 'collection'."); + .WithMessage(""" + Assert.IsEmpty(collection) failed. + Expected collection to have the specified number of items. + collection: [1] (1 item) + expectedCount: 0 + actualCount: 1 + """); } public async Task NotAny_InterpolatedString_WhenNotEmpty_ShouldFail() @@ -63,7 +81,13 @@ public async Task NotAny_InterpolatedString_WhenNotEmpty_ShouldFail() DateTime dateTime = DateTime.Now; Func action = async () => Assert.IsEmpty(collection, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}"); (await action.Should().ThrowAsync()) - .WithMessage($"Assert.IsEmpty failed. Expected collection of size 0. Actual: 1. 'collection' expression: 'collection'. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + .WithMessage(""" + Assert.IsEmpty(collection) failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString()* + Expected collection to have the specified number of items. + collection: [1] (1 item) + expectedCount: 0 + actualCount: 1 + """); o.WasToStringCalled.Should().BeTrue(); } @@ -86,14 +110,20 @@ public void Single_WhenNoItems_ShouldFail() { Action action = () => Assert.ContainsSingle(Array.Empty()); action.Should().Throw() - .WithMessage("Assert.ContainsSingle failed. Expected collection to contain exactly one element but found 0 element(s). 'collection' expression: 'Array.Empty()'."); + .WithMessage(""" + Assert.ContainsSingle(Array.Empty()) failed. + Expected collection to contain exactly one item but found 0 item(s). + """); } public void Single_WhenMultipleItems_ShouldFail() { Action action = () => Assert.ContainsSingle([1, 2, 3]); action.Should().Throw() - .WithMessage("Assert.ContainsSingle failed. Expected collection to contain exactly one element but found 3 element(s). 'collection' expression: '[1, 2, 3]'."); + .WithMessage(""" + Assert.ContainsSingle([1, 2, 3]) failed. + Expected collection to contain exactly one item but found 3 item(s). + """); } public async Task Single_InterpolatedString_WhenNoItem_ShouldFail() @@ -102,7 +132,10 @@ public async Task Single_InterpolatedString_WhenNoItem_ShouldFail() DateTime dateTime = DateTime.Now; Func action = async () => Assert.ContainsSingle(Array.Empty(), $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}"); (await action.Should().ThrowAsync()) - .WithMessage($"Assert.ContainsSingle failed. Expected collection to contain exactly one element but found 0 element(s). 'collection' expression: 'Array.Empty()'. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + .WithMessage(""" + Assert.ContainsSingle(Array.Empty()) failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString()* + Expected collection to contain exactly one item but found 0 item(s). + """); o.WasToStringCalled.Should().BeTrue(); } @@ -112,7 +145,10 @@ public async Task Single_InterpolatedString_WhenMultipleItems_ShouldFail() DateTime dateTime = DateTime.Now; Func action = async () => Assert.ContainsSingle([1, 2, 3], $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}"); (await action.Should().ThrowAsync()) - .WithMessage($"Assert.ContainsSingle failed. Expected collection to contain exactly one element but found 3 element(s). 'collection' expression: '[1, 2, 3]'. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + .WithMessage(""" + Assert.ContainsSingle([1, 2, 3]) failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString()* + Expected collection to contain exactly one item but found 3 item(s). + """); o.WasToStringCalled.Should().BeTrue(); } @@ -137,7 +173,10 @@ public void SinglePredicate_WhenNoItemMatches_ShouldFail() var collection = new List { 1, 3, 5 }; Action action = () => Assert.ContainsSingle(x => x % 2 == 0, collection); action.Should().Throw() - .WithMessage("Assert.ContainsSingle failed. Expected exactly one item to match the predicate but found 0 item(s). 'predicate' expression: 'x => x % 2 == 0', 'collection' expression: 'collection'."); + .WithMessage(""" + Assert.ContainsSingle(x => x % 2 == 0, collection) failed. + Expected exactly one item to match the predicate but found 0 item(s). + """); } public void SinglePredicate_WhenMultipleItemsMatch_ShouldFail() @@ -145,7 +184,10 @@ public void SinglePredicate_WhenMultipleItemsMatch_ShouldFail() var collection = new List { 2, 4, 6 }; Action action = () => Assert.ContainsSingle(x => x % 2 == 0, collection); action.Should().Throw() - .WithMessage("Assert.ContainsSingle failed. Expected exactly one item to match the predicate but found 3 item(s). 'predicate' expression: 'x => x % 2 == 0', 'collection' expression: 'collection'."); + .WithMessage(""" + Assert.ContainsSingle(x => x % 2 == 0, collection) failed. + Expected exactly one item to match the predicate but found 3 item(s). + """); } public void SinglePredicate_Message_WhenNoItemMatches_ShouldFail() @@ -153,7 +195,10 @@ public void SinglePredicate_Message_WhenNoItemMatches_ShouldFail() var collection = new List { 1, 3, 5 }; Action action = () => Assert.ContainsSingle(x => x % 2 == 0, collection, "No even numbers found: test"); action.Should().Throw() - .WithMessage("Assert.ContainsSingle failed. Expected exactly one item to match the predicate but found 0 item(s). 'predicate' expression: 'x => x % 2 == 0', 'collection' expression: 'collection'. No even numbers found: test"); + .WithMessage(""" + Assert.ContainsSingle(x => x % 2 == 0, collection) failed. No even numbers found: test + Expected exactly one item to match the predicate but found 0 item(s). + """); } public void SinglePredicate_Message_WhenMultipleItemsMatch_ShouldFail() @@ -161,7 +206,10 @@ public void SinglePredicate_Message_WhenMultipleItemsMatch_ShouldFail() var collection = new List { 2, 4, 6 }; Action action = () => Assert.ContainsSingle(x => x % 2 == 0, collection, "Too many even numbers: test"); action.Should().Throw() - .WithMessage("Assert.ContainsSingle failed. Expected exactly one item to match the predicate but found 3 item(s). 'predicate' expression: 'x => x % 2 == 0', 'collection' expression: 'collection'. Too many even numbers: test"); + .WithMessage(""" + Assert.ContainsSingle(x => x % 2 == 0, collection) failed. Too many even numbers: test + Expected exactly one item to match the predicate but found 3 item(s). + """); } public void Any_WhenOneItem_ShouldPass() @@ -194,7 +242,10 @@ public void Any_WhenNoItem_ShouldFail() { Action action = () => Assert.IsNotEmpty(Array.Empty()); action.Should().Throw() - .WithMessage("Assert.IsNotEmpty failed. Expected collection to contain any item but it is empty. 'collection' expression: 'Array.Empty()'."); + .WithMessage(""" + Assert.IsNotEmpty(Array.Empty()) failed. + Expected collection to contain any item but it is empty. + """); } public async Task Any_InterpolatedString_WhenNoItem_ShouldFail() @@ -203,7 +254,10 @@ public async Task Any_InterpolatedString_WhenNoItem_ShouldFail() DateTime dateTime = DateTime.Now; Func action = async () => Assert.IsNotEmpty(Array.Empty(), $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}"); (await action.Should().ThrowAsync()) - .WithMessage($"Assert.IsNotEmpty failed. Expected collection to contain any item but it is empty. 'collection' expression: 'Array.Empty()'. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + .WithMessage(""" + Assert.IsNotEmpty(Array.Empty()) failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString()* + Expected collection to contain any item but it is empty. + """); o.WasToStringCalled.Should().BeTrue(); } } diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.MatchesRegex.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.MatchesRegex.cs new file mode 100644 index 0000000000..209e3d5c45 --- /dev/null +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.MatchesRegex.cs @@ -0,0 +1,127 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using AwesomeAssertions; + +namespace Microsoft.VisualStudio.TestPlatform.TestFramework.UnitTests; + +public partial class AssertTests +{ + #region MatchesRegex + + public void MatchesRegex_WhenValueMatchesPattern_ShouldPass() + => Assert.MatchesRegex(@"\d+", "abc123"); + + public void MatchesRegex_WhenValueDoesNotMatchPattern_ShouldFail() + { + Action action = () => Assert.MatchesRegex(@"\d+", "abc"); + action.Should().Throw() + .WithMessage(""" + Assert.MatchesRegex(@"\d+", "abc") failed. + String does not match expected pattern. + pattern: \d+ + value: "abc" + """); + } + + public void DoesNotMatchRegex_WhenValueDoesNotMatchPattern_ShouldPass() + => Assert.DoesNotMatchRegex(@"\d+", "abc"); + + public void DoesNotMatchRegex_WhenValueMatchesPattern_ShouldFail() + { + Action action = () => Assert.DoesNotMatchRegex(@"\d+", "abc123"); + action.Should().Throw() + .WithMessage(""" + Assert.DoesNotMatchRegex(@"\d+", "abc123") failed. + String matches pattern but should not. + pattern: \d+ + value: "abc123" + """); + } + + #endregion + + #region MatchesRegex/DoesNotMatchRegex truncation and newline escaping + + public void MatchesRegex_WithLongExpression_ShouldTruncateExpression() + { + string aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ = "hello"; + + Action action = () => Assert.MatchesRegex(@"\d+", aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ); + action.Should().Throw() + .WithMessage(""" + Assert.MatchesRegex(@"\d+", aVeryLongVariableNameThatExceedsOneHundredCharacte...) failed. + String does not match expected pattern. + pattern: \d+ + value: "hello" + """); + } + + public void MatchesRegex_WithLongValue_ShouldTruncateValue() + { + string longValue = new string('x', 300); + + Action action = () => Assert.MatchesRegex(@"\d+", longValue); + action.Should().Throw() + .WithMessage($""" + Assert.MatchesRegex(@"\d+", longValue) failed. + String does not match expected pattern. + pattern: \d+ + value: "{new string('x', 255)}... 46 more + """); + } + + public void MatchesRegex_WithNewlineInValue_ShouldEscapeNewlines() + { + Action action = () => Assert.MatchesRegex(@"^\d+$", "hello\r\nworld"); + action.Should().Throw() + .WithMessage(""" + Assert.MatchesRegex(@"^\d+$", "hello\r\nworld") failed. + String does not match expected pattern. + pattern: ^\d+$ + value: "hello\r\nworld" + """); + } + + public void DoesNotMatchRegex_WithLongExpression_ShouldTruncateExpression() + { + string aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ = "abc123"; + + Action action = () => Assert.DoesNotMatchRegex(@"\d+", aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ); + action.Should().Throw() + .WithMessage(""" + Assert.DoesNotMatchRegex(@"\d+", aVeryLongVariableNameThatExceedsOneHundredCharacte...) failed. + String matches pattern but should not. + pattern: \d+ + value: "abc123" + """); + } + + public void DoesNotMatchRegex_WithLongValue_ShouldTruncateValue() + { + string longValue = new string('1', 300); + + Action action = () => Assert.DoesNotMatchRegex(@"\d+", longValue); + action.Should().Throw() + .WithMessage($""" + Assert.DoesNotMatchRegex(@"\d+", longValue) failed. + String matches pattern but should not. + pattern: \d+ + value: "{new string('1', 255)}... 46 more + """); + } + + public void DoesNotMatchRegex_WithNewlineInValue_ShouldEscapeNewlines() + { + Action action = () => Assert.DoesNotMatchRegex(@"hello", "hello\r\nworld"); + action.Should().Throw() + .WithMessage(""" + Assert.DoesNotMatchRegex(@"hello", "hello\r\nworld") failed. + String matches pattern but should not. + pattern: hello + value: "hello\r\nworld" + """); + } + + #endregion +} diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.StartsWith.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.StartsWith.cs new file mode 100644 index 0000000000..537d61df61 --- /dev/null +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.StartsWith.cs @@ -0,0 +1,139 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using AwesomeAssertions; + +namespace Microsoft.VisualStudio.TestPlatform.TestFramework.UnitTests; + +public partial class AssertTests +{ + #region StartsWith + + public void StartsWith_WhenValueStartsWithPrefix_ShouldPass() + => Assert.StartsWith("hello", "hello world"); + + public void StartsWith_WhenValueDoesNotStartWithPrefix_ShouldFail() + { + Action action = () => Assert.StartsWith("world", "hello"); + action.Should().Throw() + .WithMessage(""" + Assert.StartsWith("world", "hello") failed. + String does not start with expected prefix. + expectedPrefix: "world" + value: "hello" + """); + } + + public void StartsWith_WithMessage_WhenValueDoesNotStartWithPrefix_ShouldFail() + { + Action action = () => Assert.StartsWith("world", "hello", "User message"); + action.Should().Throw() + .WithMessage(""" + Assert.StartsWith("world", "hello") failed. User message + String does not start with expected prefix. + expectedPrefix: "world" + value: "hello" + """); + } + + public void DoesNotStartWith_WhenValueDoesNotStartWithPrefix_ShouldPass() + => Assert.DoesNotStartWith("world", "hello"); + + public void DoesNotStartWith_WhenValueStartsWithPrefix_ShouldFail() + { + Action action = () => Assert.DoesNotStartWith("hello", "hello world"); + action.Should().Throw() + .WithMessage(""" + Assert.DoesNotStartWith("hello", "hello world") failed. + String starts with unexpected prefix. + notExpectedPrefix: "hello" + value: "hello world" + """); + } + + #endregion + + #region StartsWith/DoesNotStartWith truncation and newline escaping + + public void StartsWith_WithLongExpression_ShouldTruncateExpression() + { + string aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ = "hello world"; + + Action action = () => Assert.StartsWith("world", aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ); + action.Should().Throw() + .WithMessage(""" + Assert.StartsWith("world", aVeryLongVariableNameThatExceedsOneHundredCharacte...) failed. + String does not start with expected prefix. + expectedPrefix: "world" + value: "hello world" + """); + } + + public void StartsWith_WithLongValue_ShouldTruncateValue() + { + string longValue = new string('x', 300); + + Action action = () => Assert.StartsWith("world", longValue); + action.Should().Throw() + .WithMessage($""" + Assert.StartsWith("world", longValue) failed. + String does not start with expected prefix. + expectedPrefix: "world" + value: "{new string('x', 255)}... 46 more + """); + } + + public void StartsWith_WithNewlineInValue_ShouldEscapeNewlines() + { + Action action = () => Assert.StartsWith("world", "hello\r\nworld"); + action.Should().Throw() + .WithMessage(""" + Assert.StartsWith("world", "hello\r\nworld") failed. + String does not start with expected prefix. + expectedPrefix: "world" + value: "hello\r\nworld" + """); + } + + public void DoesNotStartWith_WithLongExpression_ShouldTruncateExpression() + { + string aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ = "hello world"; + + Action action = () => Assert.DoesNotStartWith("hello", aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ); + action.Should().Throw() + .WithMessage(""" + Assert.DoesNotStartWith("hello", aVeryLongVariableNameThatExceedsOneHundredCharacte...) failed. + String starts with unexpected prefix. + notExpectedPrefix: "hello" + value: "hello world" + """); + } + + public void DoesNotStartWith_WithLongValue_ShouldTruncateValue() + { + string longValue = "hello" + new string('x', 300); + + Action action = () => Assert.DoesNotStartWith("hello", longValue); + action.Should().Throw() + .WithMessage($""" + Assert.DoesNotStartWith("hello", longValue) failed. + String starts with unexpected prefix. + notExpectedPrefix: "hello" + value: "hello{new string('x', 250)}... 51 more + """); + } + + public void DoesNotStartWith_WithNewlineInValue_ShouldEscapeNewlines() + { + Action action = () => Assert.DoesNotStartWith("hello", "hello\r\nworld"); + action.Should().Throw() + .WithMessage(""" + Assert.DoesNotStartWith("hello", "hello\r\nworld") failed. + String starts with unexpected prefix. + notExpectedPrefix: "hello" + value: "hello\r\nworld" + """); + } + + #endregion +} diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.ThrowsExceptionTests.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.ThrowsExceptionTests.cs index c41eba3302..9790e5c3ca 100644 --- a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.ThrowsExceptionTests.cs +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.ThrowsExceptionTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using AwesomeAssertions; @@ -70,7 +70,13 @@ public void ThrowsAsync_WhenExceptionIsNotExpectedType_ShouldThrow() Action action = t.Wait; action.Should().Throw() .WithInnerException() - .WithMessage("Assert.ThrowsAsync failed. Expected exception type:. Actual exception type:. 'action' expression: '() => throw new Exception()'."); + .WithMessage(""" + Assert.ThrowsAsync failed. + Wrong exception type was thrown. + action: () => throw new Exception() + expectedExceptionType: System.ArgumentException + actualExceptionType: System.Exception + """); } public void ThrowsExactlyAsync_WhenExceptionIsDerivedFromExpectedType_ShouldThrow() @@ -79,7 +85,13 @@ public void ThrowsExactlyAsync_WhenExceptionIsDerivedFromExpectedType_ShouldThro Action action = t.Wait; action.Should().Throw() .WithInnerException() - .WithMessage("Assert.ThrowsExactlyAsync failed. Expected exception type:. Actual exception type:. 'action' expression: '() => throw new ArgumentNullException()'."); + .WithMessage(""" + Assert.ThrowsExactlyAsync failed. + Wrong exception type was thrown. + action: () => throw new ArgumentNullException() + expectedExceptionType: System.ArgumentException + actualExceptionType: System.ArgumentNullException + """); } public void Throws_WithMessageBuilder_Passes() @@ -105,7 +117,12 @@ public void Throws_WithMessageBuilder_FailsBecauseNoException() return "message constructed via builder."; }); action.Should().Throw() - .WithMessage("Assert.Throws failed. Expected exception type: but no exception was thrown. 'action' expression: '() => { }'. message constructed via builder."); + .WithMessage(""" + Assert.Throws failed. message constructed via builder. + No exception was thrown. + action: () => { } + expectedExceptionType: System.ArgumentNullException + """); wasBuilderCalled.Should().BeTrue(); exceptionPassedToBuilder.Should().BeNull(); @@ -122,7 +139,13 @@ public void Throws_WithMessageBuilder_FailsBecauseTypeMismatch() return "message constructed via builder."; }); action.Should().Throw() - .WithMessage("Assert.Throws failed. Expected exception type:. Actual exception type:. 'action' expression: '() => throw new ArgumentOutOfRangeException(\"MyParamNameHere\")'. message constructed via builder."); + .WithMessage(""" + Assert.Throws failed. message constructed via builder. + Wrong exception type was thrown. + action: () => throw new ArgumentOutOfRangeException("MyParamNameHere") + expectedExceptionType: System.ArgumentNullException + actualExceptionType: System.ArgumentOutOfRangeException + """); wasBuilderCalled.Should().BeTrue(); exceptionPassedToBuilder.Should().BeOfType(); @@ -152,7 +175,12 @@ public void ThrowsExactly_WithMessageBuilder_FailsBecauseNoException() return "message constructed via builder."; }); action.Should().Throw() - .WithMessage("Assert.ThrowsExactly failed. Expected exception type: but no exception was thrown. 'action' expression: '() => { }'. message constructed via builder."); + .WithMessage(""" + Assert.ThrowsExactly failed. message constructed via builder. + No exception was thrown. + action: () => { } + expectedExceptionType: System.ArgumentNullException + """); wasBuilderCalled.Should().BeTrue(); exceptionPassedToBuilder.Should().BeNull(); @@ -169,7 +197,13 @@ public void ThrowsExactly_WithMessageBuilder_FailsBecauseTypeMismatch() return "message constructed via builder."; }); action.Should().Throw() - .WithMessage("Assert.ThrowsExactly failed. Expected exception type:. Actual exception type:. 'action' expression: '() => throw new ArgumentOutOfRangeException(\"MyParamNameHere\")'. message constructed via builder."); + .WithMessage(""" + Assert.ThrowsExactly failed. message constructed via builder. + Wrong exception type was thrown. + action: () => throw new ArgumentOutOfRangeException("MyParamNameHere") + expectedExceptionType: System.ArgumentNullException + actualExceptionType: System.ArgumentOutOfRangeException + """); wasBuilderCalled.Should().BeTrue(); exceptionPassedToBuilder.Should().BeOfType(); @@ -199,7 +233,12 @@ public async Task ThrowsAsync_WithMessageBuilder_FailsBecauseNoException() return "message constructed via builder."; }); (await action.Should().ThrowAsync()) - .WithMessage("Assert.ThrowsAsync failed. Expected exception type: but no exception was thrown. 'action' expression: '() => Task.CompletedTask'. message constructed via builder."); + .WithMessage(""" + Assert.ThrowsAsync failed. message constructed via builder. + No exception was thrown. + action: () => Task.CompletedTask + expectedExceptionType: System.ArgumentNullException + """); wasBuilderCalled.Should().BeTrue(); exceptionPassedToBuilder.Should().BeNull(); @@ -216,7 +255,13 @@ public async Task ThrowsAsync_WithMessageBuilder_FailsBecauseTypeMismatch() return "message constructed via builder."; }); (await action.Should().ThrowAsync()) - .WithMessage("Assert.ThrowsAsync failed. Expected exception type:. Actual exception type:. 'action' expression: '() => Task.FromException(new ArgumentOutOfRangeException(\"MyParamNameHere\"))'. message constructed via builder."); + .WithMessage(""" + Assert.ThrowsAsync failed. message constructed via builder. + Wrong exception type was thrown. + action: () => Task.FromException(new ArgumentOutOfRangeException("MyParamNameHere")) + expectedExceptionType: System.ArgumentNullException + actualExceptionType: System.ArgumentOutOfRangeException + """); wasBuilderCalled.Should().BeTrue(); exceptionPassedToBuilder.Should().BeOfType(); @@ -246,7 +291,12 @@ public async Task ThrowsExactlyAsync_WithMessageBuilder_FailsBecauseNoException( return "message constructed via builder."; }); (await action.Should().ThrowAsync()) - .WithMessage("Assert.ThrowsExactlyAsync failed. Expected exception type: but no exception was thrown. 'action' expression: '() => Task.CompletedTask'. message constructed via builder."); + .WithMessage(""" + Assert.ThrowsExactlyAsync failed. message constructed via builder. + No exception was thrown. + action: () => Task.CompletedTask + expectedExceptionType: System.ArgumentNullException + """); wasBuilderCalled.Should().BeTrue(); exceptionPassedToBuilder.Should().BeNull(); @@ -263,7 +313,13 @@ public async Task ThrowsExactlyAsync_WithMessageBuilder_FailsBecauseTypeMismatch return "message constructed via builder."; }); (await action.Should().ThrowAsync()) - .WithMessage("Assert.ThrowsExactlyAsync failed. Expected exception type:. Actual exception type:. 'action' expression: '() => Task.FromException(new ArgumentOutOfRangeException(\"MyParamNameHere\"))'. message constructed via builder."); + .WithMessage(""" + Assert.ThrowsExactlyAsync failed. message constructed via builder. + Wrong exception type was thrown. + action: () => Task.FromException(new ArgumentOutOfRangeException("MyParamNameHere")) + expectedExceptionType: System.ArgumentNullException + actualExceptionType: System.ArgumentOutOfRangeException + """); wasBuilderCalled.Should().BeTrue(); exceptionPassedToBuilder.Should().BeOfType(); diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.cs index 21dbd8e1ac..e0c18c595e 100644 --- a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.cs +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.cs @@ -65,4 +65,226 @@ private sealed class DummyIFormattable : IFormattable public string ToString(string? format, IFormatProvider? formatProvider) => "DummyIFormattable.ToString()"; } + + #region FormatValue truncation + + public void FormatValue_WhenStringExceedsMaxLength_ShouldTruncateWithEllipsis() + { + // FormatValue truncation applies to non-string-diff contexts like IsNull + // 300 'x' chars -> quoted as "xxx..." (302 chars total) -> truncated at 256 chars with ellipsis + string longValue = new('x', 300); + // Truncate takes first 256 chars of quoted string: opening quote + 255 x's, then appends "... 46 more" + string expectedValue = "\"" + new string('x', 255) + "... 46 more"; + + Action action = () => Assert.IsNull(longValue); + action.Should().Throw() + .WithMessage($""" + Assert.IsNull(*) failed. + Expected value to be null. + value: {expectedValue} + """); + } + + public void FormatValue_WhenStringIsWithinMaxLength_ShouldNotTruncate() + { + string value = new('x', 50); + string expectedFullValue = "\"" + new string('x', 50) + "\""; + + Action action = () => Assert.IsNull(value); + action.Should().Throw() + .WithMessage($""" + Assert.IsNull(*) failed. + Expected value to be null. + value: {expectedFullValue} + """); + } + + public void FormatValue_WhenCustomToStringExceedsMaxLength_ShouldTruncate() + { + // Custom ToString returns 300 chars ? truncated at 256 + var obj = new ObjectWithLongToString(); + string expectedValue = new string('L', 256) + "... 44 more"; + + Action action = () => Assert.IsNull(obj); + action.Should().Throw() + .WithMessage($""" + Assert.IsNull(*) failed. + Expected value to be null. + value: {expectedValue} + """); + } + + public void TruncateExpression_WhenExpressionExceeds100Chars_ShouldShowEllipsis() + { + // Variable name is 113 chars ? exceeds 100 char limit ? truncated with "..." + string aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ = null!; + + Action action = () => Assert.IsNotNull(aVeryLongVariableNameThatExceedsOneHundredCharactersInLengthToTestTruncationBehaviorOfExpressionDisplayXYZ); + action.Should().Throw() + .WithMessage(""" + Assert.IsNotNull(*) failed. + Expected a non-null value. + value: (null) + """); + } + + #endregion + + #region FormatValue newline escaping + + public void FormatValue_WhenValueContainsNewlines_ShouldEscapeThem() + { + var obj = new ObjectWithNewlineToString(); + + Action action = () => Assert.IsNull(obj); + action.Should().Throw() + .WithMessage(""" + Assert.IsNull(*) failed. + Expected value to be null. + value: line1\r\nline2\nline3 + """); + } + + public void FormatValue_WhenStringContainsNewlines_ShouldEscapeThem() + { + string value = "hello\nworld"; + + Action action = () => Assert.IsNull(value); + action.Should().Throw() + .WithMessage(""" + Assert.IsNull(*) failed. + Expected value to be null. + value: "hello\nworld" + """); + } + + #endregion + + #region FormatValue collection preview + + public void FormatValue_WhenValueIsCollection_ShouldShowPreview() + { + var collection = new List { 1, 2, 3 }; + + Action action = () => Assert.IsNull(collection); + action.Should().Throw() + .WithMessage(""" + Assert.IsNull(*) failed. + Expected value to be null. + value: [1, 2, 3] (3 items) + """); + } + + public void FormatCollectionPreview_WhenTotalStringLengthExceeds256_ShouldTruncate() + { + // Each element is a 30-char string -> FormatValue wraps in quotes -> "aaa...aaa" = 32 chars + // With ", " separator: first = 32, subsequent = 34 each + // 32 + 6*34 = 236 <= 256, 32 + 7*34 = 270 > 256 + // So 7 elements should display, then "...", with total count 20 + var collection = new List(); + for (int i = 0; i < 20; i++) + { + collection.Add(new string((char)('a' + (i % 26)), 30)); + } + + Action action = () => Assert.Contains("not-there", collection); + action.Should().Throw() + .WithMessage($""" + Assert.Contains(*) failed. + Expected collection to contain the specified item. + collection: ["{new string('a', 30)}", "{new string('b', 30)}", "{new string('c', 30)}", "{new string('d', 30)}", "{new string('e', 30)}", "{new string('f', 30)}", "{new string('g', 30)}", ... 13 more] + """); + } + + public void FormatCollectionPreview_WhenElementToStringExceeds50_ShouldTruncateElement() + { + // Element has 80-char string ? FormatValue(maxLength:50) ? "zzz..." (82 chars quoted) ? truncated at 50 + var collection = new List { new string('z', 80), "short" }; + string expectedFirstElement = "\"" + new string('z', 49) + "... 32 more"; + + Action action = () => Assert.Contains("not-there", collection); + action.Should().Throw() + .WithMessage($""" + Assert.Contains(*) failed. + Expected collection to contain the specified item. + collection*[{expectedFirstElement}, "short"] (2 items) + """); + } + + public void FormatCollectionPreview_WhenCollectionContainsNestedCollections_ShouldShowNestedPreview() + { + var inner1 = new List { 1, 2 }; + var inner2 = new List { 3, 4 }; + var outer = new List> { inner1, inner2 }; + + Action action = () => Assert.IsNull(outer); + action.Should().Throw() + .WithMessage(""" + Assert.IsNull(*) failed. + Expected value to be null. + value: [[1, 2] (2 items), [3, 4] (2 items)] (2 items) + """); + } + + public void FormatCollectionPreview_WhenNestedCollectionIsLarge_ShouldTruncateInnerAt50() + { + // Inner collection has many elements -> inner preview string budget is 50 chars + // Elements 0-9 are 1 char each: "0" takes 1, subsequent take 3 (digit + ", ") + // 1 + 9*3 = 28 chars for 0-9. Then 10-99 are 2 char digits + 2 sep = 4 each + // 28 + 4n = 50 -> n = 5.5 -> 5 more (10-14). 28 + 5*4 = 48, next would be 52 > 50 + // So inner preview shows: 0-14 (15 elements), then "..." + var inner = new List(); + for (int i = 0; i < 50; i++) + { + inner.Add(i); + } + + var outer = new List> { inner }; + + Action action = () => Assert.IsNull(outer); + action.Should().Throw() + .WithMessage(""" + Assert.IsNull(*) failed. + Expected value to be null. + value: [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, ... 35 more]] (1 item) + """); + } + + public void FormatCollectionPreview_WhenElementContainsNewlines_ShouldEscapeThem() + { + var collection = new List { "line1\nline2", "ok" }; + + Action action = () => Assert.Contains("not-there", collection); + action.Should().Throw() + .WithMessage(""" + Assert.Contains(*) failed. + Expected collection to contain the specified item. + collection*["line1\nline2", "ok"] (2 items) + """); + } + + public void FormatCollectionPreview_WhenSingleElement_ShouldShowSingularForm() + { + var collection = new List { 42 }; + + Action action = () => Assert.Contains(99, collection); + action.Should().Throw() + .WithMessage(""" + Assert.Contains(*) failed. + Expected collection to contain the specified item. + collection: [42] (1 item) + """); + } + + #endregion +} + +internal sealed class ObjectWithNewlineToString +{ + public override string ToString() => "line1\r\nline2\nline3"; +} + +internal sealed class ObjectWithLongToString +{ + public override string ToString() => new string('L', 300); }