Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 43 additions & 30 deletions src/TestFramework/TestFramework/Assertions/Assert.Count.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ internal void ComputeAssertion(string assertionName, string collectionExpression
{
if (_builder is not null)
{
_builder.Insert(0, string.Format(CultureInfo.CurrentCulture, FrameworkMessages.CallerArgumentExpressionSingleParameterMessage, "collection", collectionExpression) + " ");
ReportAssertCountFailed(assertionName, _expectedCount, _actualCount, _builder.ToString());
ReportAssertCountFailed(assertionName, _expectedCount, _actualCount, _builder.ToString(), collectionExpression);
}
}

Expand Down Expand Up @@ -115,8 +114,7 @@ internal void ComputeAssertion(string collectionExpression)
{
if (_builder is not null)
{
_builder.Insert(0, string.Format(CultureInfo.CurrentCulture, FrameworkMessages.CallerArgumentExpressionSingleParameterMessage, "collection", collectionExpression) + " ");
ReportAssertIsNotEmptyFailed(_builder.ToString());
ReportAssertIsNotEmptyFailed(_builder.ToString(), collectionExpression);
}
}

Expand Down Expand Up @@ -207,8 +205,7 @@ public static void IsNotEmpty<T>(IEnumerable<T> collection, string? message = ""
return;
}

string userMessage = BuildUserMessageForCollectionExpression(message, collectionExpression);
ReportAssertIsNotEmptyFailed(userMessage);
ReportAssertIsNotEmptyFailed(message, collectionExpression);
}

/// <summary>
Expand All @@ -229,8 +226,7 @@ public static void IsNotEmpty(IEnumerable collection, string? message = "", [Cal
return;
}

string userMessage = BuildUserMessageForCollectionExpression(message, collectionExpression);
ReportAssertIsNotEmptyFailed(userMessage);
ReportAssertIsNotEmptyFailed(message, collectionExpression);
}
#endregion // IsNotEmpty

Expand All @@ -252,7 +248,7 @@ public static void HasCount<T>(int expected, IEnumerable<T> collection, [Interpo
#pragma warning restore IDE0060 // Remove unused parameter
{
TelemetryCollector.TrackAssertionCall("Assert.HasCount");
message.ComputeAssertion("HasCount", collectionExpression);
message.ComputeAssertion(nameof(HasCount), collectionExpression);
}

/// <summary>
Expand All @@ -267,7 +263,7 @@ public static void HasCount<T>(int expected, IEnumerable<T> collection, [Interpo
/// Users shouldn't pass a value for this parameter.
/// </param>
public static void HasCount<T>(int expected, IEnumerable<T> collection, string? message = "", [CallerArgumentExpression(nameof(collection))] string collectionExpression = "")
=> HasCount("HasCount", expected, collection, message, collectionExpression);
=> HasCount(nameof(HasCount), expected, collection, message, collectionExpression);

/// <summary>
/// Tests whether the collection has the expected count/length.
Expand All @@ -280,7 +276,7 @@ public static void HasCount<T>(int expected, IEnumerable<T> collection, string?
/// Users shouldn't pass a value for this parameter.
/// </param>
public static void HasCount(int expected, IEnumerable collection, string? message = "", [CallerArgumentExpression(nameof(collection))] string collectionExpression = "")
=> HasCount("HasCount", expected, collection, message, collectionExpression);
=> HasCount(nameof(HasCount), expected, collection, message, collectionExpression);

#endregion // HasCount

Expand All @@ -301,7 +297,7 @@ public static void IsEmpty<T>(IEnumerable<T> collection, [InterpolatedStringHand
#pragma warning restore IDE0060 // Remove unused parameter
{
TelemetryCollector.TrackAssertionCall("Assert.IsEmpty");
message.ComputeAssertion("IsEmpty", collectionExpression);
message.ComputeAssertion(nameof(IsEmpty), collectionExpression);
}

/// <summary>
Expand All @@ -315,7 +311,7 @@ public static void IsEmpty<T>(IEnumerable<T> collection, [InterpolatedStringHand
/// Users shouldn't pass a value for this parameter.
/// </param>
public static void IsEmpty<T>(IEnumerable<T> collection, string? message = "", [CallerArgumentExpression(nameof(collection))] string collectionExpression = "")
=> HasCount("IsEmpty", 0, collection, message, collectionExpression);
=> HasCount(nameof(IsEmpty), 0, collection, message, collectionExpression);

/// <summary>
/// Tests that the collection is empty.
Expand All @@ -327,7 +323,7 @@ public static void IsEmpty<T>(IEnumerable<T> collection, string? message = "", [
/// Users shouldn't pass a value for this parameter.
/// </param>
public static void IsEmpty(IEnumerable collection, string? message = "", [CallerArgumentExpression(nameof(collection))] string collectionExpression = "")
=> HasCount("IsEmpty", 0, collection, message, collectionExpression);
=> HasCount(nameof(IsEmpty), 0, collection, message, collectionExpression);

#endregion // IsEmpty

Expand All @@ -343,8 +339,7 @@ private static void HasCount<T>(string assertionName, int expected, IEnumerable<
return;
}

string userMessage = BuildUserMessageForCollectionExpression(message, collectionExpression);
ReportAssertCountFailed(assertionName, expected, actualCount, userMessage);
ReportAssertCountFailed(assertionName, expected, actualCount, message, collectionExpression);
}

private static void HasCount(string assertionName, int expected, IEnumerable collection, string? message, string collectionExpression)
Expand All @@ -359,24 +354,42 @@ private static string GetTrackedAssertionName(string assertionName)
};

[DoesNotReturn]
private static void ReportAssertCountFailed(string assertionName, int expectedCount, int actualCount, string userMessage)
private static void ReportAssertCountFailed(string assertionName, int expectedCount, int actualCount, string? userMessage, string collectionExpression)
{
string finalMessage = string.Format(
CultureInfo.CurrentCulture,
FrameworkMessages.HasCountFailMsg,
userMessage,
expectedCount,
actualCount);
ReportAssertFailed($"Assert.{assertionName}", finalMessage);
bool isEmptyAssertion = string.Equals(assertionName, nameof(IsEmpty), StringComparison.Ordinal);
string summary = isEmptyAssertion
? FrameworkMessages.IsEmptyFailedSummary
: FrameworkMessages.HasCountFailedSummary;

string expectedEvidenceText = expectedCount.ToString(CultureInfo.CurrentCulture);
string expectedCallSiteText = expectedCount.ToString(CultureInfo.InvariantCulture);
string actualText = actualCount.ToString(CultureInfo.CurrentCulture);
EvidenceBlock evidence = EvidenceBlock.Create()
.AddLine("expected count:", expectedEvidenceText)
.AddLine("actual count:", actualText);

StructuredAssertionMessage structured = new(summary);
structured.WithUserMessage(userMessage);
structured.WithEvidence(evidence);
structured.WithExpectedAndActual(expectedEvidenceText, actualText);
structured.WithCallSiteExpression(isEmptyAssertion
? FormatCallSiteExpression($"Assert.{assertionName}", collectionExpression, "<collection>")
: FormatCallSiteExpression($"Assert.{assertionName}", expectedCallSiteText, collectionExpression, "<expected>", "<collection>"));

ReportAssertFailed(structured);
}

[DoesNotReturn]
private static void ReportAssertIsNotEmptyFailed(string userMessage)
private static void ReportAssertIsNotEmptyFailed(string? userMessage, string collectionExpression)
{
string finalMessage = string.Format(
CultureInfo.CurrentCulture,
FrameworkMessages.IsNotEmptyFailMsg,
userMessage);
ReportAssertFailed("Assert.IsNotEmpty", finalMessage);
EvidenceBlock evidence = EvidenceBlock.Create()
.AddLine("actual count:", "0");
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — the evidence value is now formatted via 0.ToString(CultureInfo.CurrentCulture) and reused for the new WithExpectedAndActual(...) call so the evidence respects non-Latin digit cultures, matching the other count-based assertions.


StructuredAssertionMessage structured = new(FrameworkMessages.IsNotEmptyFailedSummary);
structured.WithUserMessage(userMessage);
structured.WithEvidence(evidence);
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — added structured.WithExpectedAndActual("> 0", actualText) so ExpectedText/ActualText (and the assert.expected/assert.actual data entries) are populated for IsNotEmpty failures, matching the other count-based assertions.

structured.WithCallSiteExpression(FormatCallSiteExpression("Assert.IsNotEmpty", collectionExpression, "<collection>"));

ReportAssertFailed(structured);
}
}
17 changes: 0 additions & 17 deletions src/TestFramework/TestFramework/Assertions/Assert.cs
Original file line number Diff line number Diff line change
Expand Up @@ -244,20 +244,6 @@ private static string FormatAssertionFailed(string assertionName, string? messag
internal static string BuildUserMessage(string? format)
=> format ?? string.Empty;

private static string BuildUserMessageForSingleExpression(string? format, string callerArgExpression, string parameterName)
{
string userMessage = BuildUserMessage(format);
if (string.IsNullOrEmpty(callerArgExpression))
{
return userMessage;
}

string callerArgMessagePart = string.Format(CultureInfo.InvariantCulture, FrameworkMessages.CallerArgumentExpressionSingleParameterMessage, parameterName, callerArgExpression);
return string.IsNullOrEmpty(userMessage)
? callerArgMessagePart
: $"{callerArgMessagePart} {userMessage}";
}

private static string BuildUserMessageForTwoExpressions(string? format, string callerArgExpression1, string parameterName1, string callerArgExpression2, string parameterName2)
{
string userMessage = BuildUserMessage(format);
Expand All @@ -272,9 +258,6 @@ private static string BuildUserMessageForTwoExpressions(string? format, string c
: $"{callerArgMessagePart} {userMessage}";
}

private static string BuildUserMessageForCollectionExpression(string? format, string collectionExpression)
=> BuildUserMessageForSingleExpression(format, collectionExpression, "collection");

private static string BuildUserMessageForPatternExpressionAndValueExpression(string? format, string patternExpression, string valueExpression)
=> BuildUserMessageForTwoExpressions(format, patternExpression, "pattern", valueExpression, "value");

Expand Down
15 changes: 9 additions & 6 deletions src/TestFramework/TestFramework/Resources/FrameworkMessages.resx
Original file line number Diff line number Diff line change
Expand Up @@ -298,9 +298,6 @@ Actual: {2}</value>
<data name="DynamicDataSourceShouldExistAndBeValid" xml:space="preserve">
<value>The dynamic data source '{0}' in type '{1}' should exist and be a property, a method, or a field.</value>
</data>
<data name="HasCountFailMsg" xml:space="preserve">
<value>Expected collection of size {1}. Actual: {2}. {0}</value>
</data>
<data name="ContainsSingleMatchFailMsg" xml:space="preserve">
<value>Expected exactly one item to match the predicate but found {1} item(s). {0}</value>
</data>
Expand All @@ -319,9 +316,6 @@ Actual: {2}</value>
<data name="DoesNotContainPredicateFailMsg" xml:space="preserve">
<value>Expected no items to match the predicate. {0}</value>
</data>
<data name="IsNotEmptyFailMsg" xml:space="preserve">
<value>Expected collection to contain any item but it is empty. {0}</value>
</data>
<data name="InvalidGitHubUrl" xml:space="preserve">
<value>Invalid GitHub ticket URL</value>
</data>
Expand Down Expand Up @@ -402,6 +396,15 @@ Actual: {2}</value>
<data name="IsNotNullFailedSummary" xml:space="preserve">
<value>Expected value to not be null.</value>
</data>
<data name="HasCountFailedSummary" xml:space="preserve">
<value>Expected collection to contain a specific number of elements.</value>
</data>
<data name="IsEmptyFailedSummary" xml:space="preserve">
<value>Expected collection to be empty.</value>
</data>
<data name="IsNotEmptyFailedSummary" xml:space="preserve">
<value>Expected collection to not be empty.</value>
</data>
<data name="ContainsSingleFailedSummary" xml:space="preserve">
<value>Expected collection to contain exactly one element.</value>
</data>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,9 +312,9 @@ Skutečnost: {2}</target>
<target state="new">Expected string to end with the specified suffix.</target>
<note />
</trans-unit>
<trans-unit id="HasCountFailMsg">
<source>Expected collection of size {1}. Actual: {2}. {0}</source>
<target state="translated">Očekávala se kolekce {1} velikosti. Skutečnost: {2} {0}</target>
<trans-unit id="HasCountFailedSummary">
<source>Expected collection to contain a specific number of elements.</source>
<target state="new">Expected collection to contain a specific number of elements.</target>
<note />
</trans-unit>
<trans-unit id="InvalidAccessToTestContextProperty">
Expand All @@ -327,6 +327,11 @@ Skutečnost: {2}</target>
<target state="translated">Neplatná adresa URL lístku GitHubu</target>
<note />
</trans-unit>
<trans-unit id="IsEmptyFailedSummary">
<source>Expected collection to be empty.</source>
<target state="new">Expected collection to be empty.</target>
<note />
</trans-unit>
<trans-unit id="IsFalseFailedSummary">
<source>Expected condition to be false.</source>
<target state="translated">Očekávala se podmínka false.</target>
Expand Down Expand Up @@ -382,9 +387,9 @@ Skutečnost: {2}</target>
<target state="new">Expected value to be negative.</target>
<note />
</trans-unit>
<trans-unit id="IsNotEmptyFailMsg">
<source>Expected collection to contain any item but it is empty. {0}</source>
<target state="translated">Očekávalo se, že kolekce bude obsahovat libovolnou položku, ale je prázdná. {0}</target>
<trans-unit id="IsNotEmptyFailedSummary">
<source>Expected collection to not be empty.</source>
<target state="new">Expected collection to not be empty.</target>
<note />
</trans-unit>
<trans-unit id="IsNotInstanceOfFailMsg">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,9 +312,9 @@ Tatsächlich: {2}</target>
<target state="new">Expected string to end with the specified suffix.</target>
<note />
</trans-unit>
<trans-unit id="HasCountFailMsg">
<source>Expected collection of size {1}. Actual: {2}. {0}</source>
<target state="translated">Es wurde eine Sammlung mit einer Größe {1} erwartet. Tatsächlich: {2}. {0}</target>
<trans-unit id="HasCountFailedSummary">
<source>Expected collection to contain a specific number of elements.</source>
<target state="new">Expected collection to contain a specific number of elements.</target>
<note />
</trans-unit>
<trans-unit id="InvalidAccessToTestContextProperty">
Expand All @@ -327,6 +327,11 @@ Tatsächlich: {2}</target>
<target state="translated">Ungültige GitHub-Ticket-URL.</target>
<note />
</trans-unit>
<trans-unit id="IsEmptyFailedSummary">
<source>Expected collection to be empty.</source>
<target state="new">Expected collection to be empty.</target>
<note />
</trans-unit>
<trans-unit id="IsFalseFailedSummary">
<source>Expected condition to be false.</source>
<target state="translated">Es wurde erwartet, dass die Bedingung „falsch“ lautet.</target>
Expand Down Expand Up @@ -382,9 +387,9 @@ Tatsächlich: {2}</target>
<target state="new">Expected value to be negative.</target>
<note />
</trans-unit>
<trans-unit id="IsNotEmptyFailMsg">
<source>Expected collection to contain any item but it is empty. {0}</source>
<target state="translated">Es wurde erwartet, dass die Sammlung ein beliebiges Element enthält, aber leer ist. {0}</target>
<trans-unit id="IsNotEmptyFailedSummary">
<source>Expected collection to not be empty.</source>
<target state="new">Expected collection to not be empty.</target>
<note />
</trans-unit>
<trans-unit id="IsNotInstanceOfFailMsg">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,9 +312,9 @@ Real: {2}</target>
<target state="new">Expected string to end with the specified suffix.</target>
<note />
</trans-unit>
<trans-unit id="HasCountFailMsg">
<source>Expected collection of size {1}. Actual: {2}. {0}</source>
<target state="translated">Se esperaba una colección de tamaño {1}. Real: {2}. {0}</target>
<trans-unit id="HasCountFailedSummary">
<source>Expected collection to contain a specific number of elements.</source>
<target state="new">Expected collection to contain a specific number of elements.</target>
<note />
</trans-unit>
<trans-unit id="InvalidAccessToTestContextProperty">
Expand All @@ -327,6 +327,11 @@ Real: {2}</target>
<target state="translated">Dirección URL de vale de GitHub no válida</target>
<note />
</trans-unit>
<trans-unit id="IsEmptyFailedSummary">
<source>Expected collection to be empty.</source>
<target state="new">Expected collection to be empty.</target>
<note />
</trans-unit>
<trans-unit id="IsFalseFailedSummary">
<source>Expected condition to be false.</source>
<target state="translated">Se esperaba que la condición fuera false.</target>
Expand Down Expand Up @@ -382,9 +387,9 @@ Real: {2}</target>
<target state="new">Expected value to be negative.</target>
<note />
</trans-unit>
<trans-unit id="IsNotEmptyFailMsg">
<source>Expected collection to contain any item but it is empty. {0}</source>
<target state="translated">Se esperaba que la colección contenga cualquier elemento, pero está vacía. {0}</target>
<trans-unit id="IsNotEmptyFailedSummary">
<source>Expected collection to not be empty.</source>
<target state="new">Expected collection to not be empty.</target>
<note />
</trans-unit>
<trans-unit id="IsNotInstanceOfFailMsg">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,9 +312,9 @@ Réel : {2}</target>
<target state="new">Expected string to end with the specified suffix.</target>
<note />
</trans-unit>
<trans-unit id="HasCountFailMsg">
<source>Expected collection of size {1}. Actual: {2}. {0}</source>
<target state="translated">Collection de tailles attendue {1}. Réel : {2}. {0}</target>
<trans-unit id="HasCountFailedSummary">
<source>Expected collection to contain a specific number of elements.</source>
<target state="new">Expected collection to contain a specific number of elements.</target>
<note />
</trans-unit>
<trans-unit id="InvalidAccessToTestContextProperty">
Expand All @@ -327,6 +327,11 @@ Réel : {2}</target>
<target state="translated">URL de ticket GitHub non valide</target>
<note />
</trans-unit>
<trans-unit id="IsEmptyFailedSummary">
<source>Expected collection to be empty.</source>
<target state="new">Expected collection to be empty.</target>
<note />
</trans-unit>
<trans-unit id="IsFalseFailedSummary">
<source>Expected condition to be false.</source>
<target state="translated">La condition attendue doit être false.</target>
Expand Down Expand Up @@ -382,9 +387,9 @@ Réel : {2}</target>
<target state="new">Expected value to be negative.</target>
<note />
</trans-unit>
<trans-unit id="IsNotEmptyFailMsg">
<source>Expected collection to contain any item but it is empty. {0}</source>
<target state="translated">La collection doit contenir n’importe quel élément, mais elle est vide. {0}</target>
<trans-unit id="IsNotEmptyFailedSummary">
<source>Expected collection to not be empty.</source>
<target state="new">Expected collection to not be empty.</target>
<note />
</trans-unit>
<trans-unit id="IsNotInstanceOfFailMsg">
Expand Down
Loading
Loading