Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions MSTest.slnf
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"src\\Package\\MSTest.Sdk\\MSTest.Sdk.csproj",
"src\\Package\\MSTest\\MSTest.csproj",
"src\\TestFramework\\TestFramework.Extensions\\TestFramework.Extensions.csproj",
"src\\TestFramework\\TestFramework.SourceGeneration\\TestFramework.SourceGeneration.csproj",
"src\\TestFramework\\TestFramework\\TestFramework.csproj",
"test\\IntegrationTests\\MSTest.Acceptance.IntegrationTests\\MSTest.Acceptance.IntegrationTests.csproj",
"test\\IntegrationTests\\MSTest.IntegrationTests\\MSTest.IntegrationTests.csproj",
Expand Down
1 change: 1 addition & 0 deletions NonWindowsTests.slnf
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"src\\Platform\\Microsoft.Testing.Platform.MSBuild\\Microsoft.Testing.Platform.MSBuild.csproj",
"src\\Platform\\Microsoft.Testing.Platform\\Microsoft.Testing.Platform.csproj",
"src\\TestFramework\\TestFramework.Extensions\\TestFramework.Extensions.csproj",
"src\\TestFramework\\TestFramework.SourceGeneration\\TestFramework.SourceGeneration.csproj",
"src\\TestFramework\\TestFramework\\TestFramework.csproj",
"test\\IntegrationTests\\MSTest.Acceptance.IntegrationTests\\MSTest.Acceptance.IntegrationTests.csproj",
"test\\IntegrationTests\\Microsoft.Testing.Platform.Acceptance.IntegrationTests\\Microsoft.Testing.Platform.Acceptance.IntegrationTests.csproj",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
{
IncrementalValuesProvider<HandlerInfo> handlers = context.SyntaxProvider.ForAttributeWithMetadataName(
MarkerAttributeMetadataName,
predicate: static (node, _) => node is StructDeclarationSyntax,
predicate: static (node, _) => node is StructDeclarationSyntax { Parent: ClassDeclarationSyntax or StructDeclarationSyntax },
transform: static (ctx, _) => GetHandlerInfo(ctx));

context.RegisterSourceOutput(handlers, static (spc, handler) => Emit(spc, handler));
Expand All @@ -36,17 +36,8 @@ private static HandlerInfo GetHandlerInfo(GeneratorAttributeSyntaxContext contex
{
var structSymbol = (INamedTypeSymbol)context.TargetSymbol;

bool nullableLiteralParameter = false;
foreach (AttributeData attribute in context.Attributes)
{
foreach (KeyValuePair<string, TypedConstant> namedArgument in attribute.NamedArguments)
{
if (namedArgument.Key == "NullableLiteralParameter" && namedArgument.Value.Value is true)
{
nullableLiteralParameter = true;
}
}
}
bool nullableLiteralParameter = context.Attributes.Any(attribute => attribute.NamedArguments.Any(namedArgument =>
namedArgument.Key == "NullableLiteralParameter" && namedArgument.Value.Value is true));

INamedTypeSymbol containingType = structSymbol.ContainingType;
Comment thread
Evangelink marked this conversation as resolved.
string typeParameters = string.Empty;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,24 @@ public static void Contains([NotNull] ICollection? collection, object? element,
}
}

Assert.ReportAssertFailed("CollectionAssert.Contains", Assert.BuildUserMessage(message));
ReportContainsFailed(collection, element, Assert.BuildUserMessage(message));
}

[DoesNotReturn]
private static void ReportContainsFailed(ICollection collection, object? element, string? userMessage)
{
string expectedText = AssertionValueRenderer.RenderValue(element);
string collectionText = AssertionValueRenderer.RenderValue(collection);
EvidenceBlock evidence = EvidenceBlock.Create()
.AddLine("expected:", expectedText)
.AddLine("collection:", collectionText);

StructuredAssertionMessage structured = new(FrameworkMessages.ContainsItemFailedSummary);
structured.WithUserMessage(userMessage);
structured.WithEvidence(evidence);
structured.WithExpectedAndActual(expectedText, null);

Assert.ReportAssertFailed(structured);
}

/// <summary>
Expand Down Expand Up @@ -111,11 +128,28 @@ public static void DoesNotContain([NotNull] ICollection? collection, object? ele
{
if (object.Equals(current, element))
{
Assert.ReportAssertFailed("CollectionAssert.DoesNotContain", Assert.BuildUserMessage(message));
ReportDoesNotContainFailed(collection, element, Assert.BuildUserMessage(message));
}
}
}

[DoesNotReturn]
private static void ReportDoesNotContainFailed(ICollection collection, object? element, string? userMessage)
{
string notExpectedText = AssertionValueRenderer.RenderValue(element);
string collectionText = AssertionValueRenderer.RenderValue(collection);
EvidenceBlock evidence = EvidenceBlock.Create()
.AddLine("unexpected:", notExpectedText)
.AddLine("collection:", collectionText);

StructuredAssertionMessage structured = new(FrameworkMessages.DoesNotContainItemFailedSummary);
structured.WithUserMessage(userMessage);
structured.WithEvidence(evidence);
structured.WithExpectedAndActual(notExpectedText, null);

Assert.ReportAssertFailed(structured);
}

/// <summary>
/// Tests whether all items in the specified collection are non-null and throws
/// an exception if any element is null.
Expand Down Expand Up @@ -152,11 +186,26 @@ public static void AllItemsAreNotNull([NotNull] ICollection? collection, string?
{
if (current == null)
{
Assert.ReportAssertFailed("CollectionAssert.AllItemsAreNotNull", Assert.BuildUserMessage(message));
ReportAllItemsAreNotNullFailed(collection, Assert.BuildUserMessage(message));
}
}
}

[DoesNotReturn]
private static void ReportAllItemsAreNotNullFailed(ICollection collection, string? userMessage)
{
string collectionText = AssertionValueRenderer.RenderValue(collection);
EvidenceBlock evidence = EvidenceBlock.Create()
.AddLine("collection:", collectionText);

StructuredAssertionMessage structured = new(FrameworkMessages.AreAllNotNullFailedSummary);
structured.WithUserMessage(userMessage);
structured.WithEvidence(evidence);
structured.WithExpectedAndActual(expectedText: null, actualText: collectionText);

Assert.ReportAssertFailed(structured);
}

/// <summary>
/// Tests whether all items in the specified collection are unique or not and
/// throws if any two elements in the collection are equal.
Expand Down Expand Up @@ -193,8 +242,6 @@ public static void AllItemsAreUnique([NotNull] ICollection? collection, string?

Assert.CheckParameterNotNull(collection, "CollectionAssert.AllItemsAreUnique", "collection");

message = Assert.ReplaceNulls(message);

bool foundNull = false;
HashSet<object> table = [];
foreach (object? current in collection)
Expand All @@ -208,32 +255,35 @@ public static void AllItemsAreUnique([NotNull] ICollection? collection, string?
else
{
// Found a second occurrence of null.
string userMessage = Assert.BuildUserMessage(message);
string finalMessage = string.Format(
CultureInfo.CurrentCulture,
FrameworkMessages.AllItemsAreUniqueFailMsg,
userMessage,
FrameworkMessages.Common_NullInMessages);

Assert.ReportAssertFailed("CollectionAssert.AllItemsAreUnique", finalMessage);
ReportAllItemsAreUniqueFailed(collection, duplicate: null, Assert.BuildUserMessage(message));
}
}
else
{
if (!table.Add(current))
{
string userMessage = Assert.BuildUserMessage(message);
string finalMessage = string.Format(
CultureInfo.CurrentCulture,
FrameworkMessages.AllItemsAreUniqueFailMsg,
userMessage,
Assert.ReplaceNulls(current));

Assert.ReportAssertFailed("CollectionAssert.AllItemsAreUnique", finalMessage);
ReportAllItemsAreUniqueFailed(collection, current, Assert.BuildUserMessage(message));
}
}
}
}

[DoesNotReturn]
private static void ReportAllItemsAreUniqueFailed(ICollection collection, object? duplicate, string? userMessage)
{
string duplicateText = AssertionValueRenderer.RenderValue(duplicate);
string collectionText = AssertionValueRenderer.RenderValue(collection);
EvidenceBlock evidence = EvidenceBlock.Create()
.AddLine("duplicate:", duplicateText)
.AddLine("collection:", collectionText);

StructuredAssertionMessage structured = new(FrameworkMessages.AreAllDistinctFailedSummary);
structured.WithUserMessage(userMessage);
structured.WithEvidence(evidence);
structured.WithExpectedAndActual(expectedText: null, actualText: collectionText);

Assert.ReportAssertFailed(structured);
}

#endregion
}
108 changes: 93 additions & 15 deletions src/TestFramework/TestFramework/Assertions/StringAssert.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,28 @@ public static void Contains([NotNull] string? value, [NotNull] string? substring
Assert.CheckParameterNotNull(substring, "StringAssert.Contains", "substring");
if (value.IndexOf(substring, comparisonType) < 0)
{
string userMessage = Assert.BuildUserMessage(message);
string finalMessage = string.Format(CultureInfo.CurrentCulture, FrameworkMessages.ContainsFail, value, substring, userMessage);
Assert.ReportAssertFailed("StringAssert.Contains", finalMessage);
ReportContainsFailed(value, substring, comparisonType, Assert.BuildUserMessage(message));
}
}

[DoesNotReturn]
private static void ReportContainsFailed(string value, string substring, StringComparison comparisonType, string? userMessage)
{
string expectedText = AssertionValueRenderer.RenderValue(substring);
string actualText = AssertionValueRenderer.RenderValue(value);
EvidenceBlock evidence = EvidenceBlock.Create()
.AddLine("expected substring:", expectedText)
.AddLine("actual:", actualText)
.AddLine("comparison:", comparisonType.ToString());

StructuredAssertionMessage structured = new(FrameworkMessages.ContainsSubstringFailedSummary);
structured.WithUserMessage(userMessage);
structured.WithEvidence(evidence);
structured.WithExpectedAndActual(expectedText, actualText);

Assert.ReportAssertFailed(structured);
}

/// <summary>
/// Tests whether the specified string begins with the specified substring
/// and throws an exception if the test string does not start with the
Expand Down Expand Up @@ -259,12 +275,28 @@ public static void StartsWith([NotNull] string? value, [NotNull] string? substri
Assert.CheckParameterNotNull(substring, "StringAssert.StartsWith", "substring");
if (!value.StartsWith(substring, comparisonType))
{
string userMessage = Assert.BuildUserMessage(message);
string finalMessage = string.Format(CultureInfo.CurrentCulture, FrameworkMessages.StartsWithFail, value, substring, userMessage);
Assert.ReportAssertFailed("StringAssert.StartsWith", finalMessage);
ReportStartsWithFailed(value, substring, comparisonType, Assert.BuildUserMessage(message));
}
}

[DoesNotReturn]
private static void ReportStartsWithFailed(string value, string substring, StringComparison comparisonType, string? userMessage)
{
string expectedText = AssertionValueRenderer.RenderValue(substring);
string actualText = AssertionValueRenderer.RenderValue(value);
EvidenceBlock evidence = EvidenceBlock.Create()
.AddLine("expected prefix:", expectedText)
.AddLine("actual:", actualText)
.AddLine("comparison:", comparisonType.ToString());

StructuredAssertionMessage structured = new(FrameworkMessages.StartsWithFailedSummary);
structured.WithUserMessage(userMessage);
structured.WithEvidence(evidence);
structured.WithExpectedAndActual(expectedText, actualText);

Assert.ReportAssertFailed(structured);
}

/// <summary>
/// Tests whether the specified string ends with the specified substring
/// and throws an exception if the test string does not end with the
Expand Down Expand Up @@ -358,12 +390,28 @@ public static void EndsWith([NotNull] string? value, [NotNull] string? substring
Assert.CheckParameterNotNull(substring, "StringAssert.EndsWith", "substring");
if (!value.EndsWith(substring, comparisonType))
{
string userMessage = Assert.BuildUserMessage(message);
string finalMessage = string.Format(CultureInfo.CurrentCulture, FrameworkMessages.EndsWithFail, value, substring, userMessage);
Assert.ReportAssertFailed("StringAssert.EndsWith", finalMessage);
ReportEndsWithFailed(value, substring, comparisonType, Assert.BuildUserMessage(message));
}
}

[DoesNotReturn]
private static void ReportEndsWithFailed(string value, string substring, StringComparison comparisonType, string? userMessage)
{
string expectedText = AssertionValueRenderer.RenderValue(substring);
string actualText = AssertionValueRenderer.RenderValue(value);
EvidenceBlock evidence = EvidenceBlock.Create()
.AddLine("expected suffix:", expectedText)
.AddLine("actual:", actualText)
.AddLine("comparison:", comparisonType.ToString());

StructuredAssertionMessage structured = new(FrameworkMessages.EndsWithFailedSummary);
structured.WithUserMessage(userMessage);
structured.WithEvidence(evidence);
structured.WithExpectedAndActual(expectedText, actualText);

Assert.ReportAssertFailed(structured);
}

#endregion Substrings

#region Regular Expressions
Expand Down Expand Up @@ -415,12 +463,27 @@ public static void Matches([NotNull] string? value, [NotNull] Regex? pattern, st

if (!pattern.IsMatch(value))
{
string userMessage = Assert.BuildUserMessage(message);
string finalMessage = string.Format(CultureInfo.CurrentCulture, FrameworkMessages.IsMatchFail, value, pattern, userMessage);
Assert.ReportAssertFailed("StringAssert.Matches", finalMessage);
ReportMatchesFailed(value, pattern, Assert.BuildUserMessage(message));
}
}

[DoesNotReturn]
private static void ReportMatchesFailed(string value, Regex pattern, string? userMessage)
{
string patternText = AssertionValueRenderer.RenderValue(pattern.ToString());
string actualText = AssertionValueRenderer.RenderValue(value);
EvidenceBlock evidence = EvidenceBlock.Create()
.AddLine("expected pattern:", patternText)
.AddLine("actual:", actualText);

StructuredAssertionMessage structured = new(FrameworkMessages.MatchesRegexFailedSummary);
structured.WithUserMessage(userMessage);
structured.WithEvidence(evidence);
structured.WithExpectedAndActual(patternText, actualText);

Assert.ReportAssertFailed(structured);
}

/// <summary>
/// Tests whether the specified string does not match a regular expression
/// and throws an exception if the string matches the expression.
Expand Down Expand Up @@ -468,12 +531,27 @@ public static void DoesNotMatch([NotNull] string? value, [NotNull] Regex? patter

if (pattern.IsMatch(value))
{
string userMessage = Assert.BuildUserMessage(message);
string finalMessage = string.Format(CultureInfo.CurrentCulture, FrameworkMessages.IsNotMatchFail, value, pattern, userMessage);
Assert.ReportAssertFailed("StringAssert.DoesNotMatch", finalMessage);
ReportDoesNotMatchFailed(value, pattern, Assert.BuildUserMessage(message));
}
}

[DoesNotReturn]
private static void ReportDoesNotMatchFailed(string value, Regex pattern, string? userMessage)
{
string patternText = AssertionValueRenderer.RenderValue(pattern.ToString());
string actualText = AssertionValueRenderer.RenderValue(value);
EvidenceBlock evidence = EvidenceBlock.Create()
.AddLine("unexpected pattern:", patternText)
.AddLine("actual:", actualText);

StructuredAssertionMessage structured = new(FrameworkMessages.DoesNotMatchRegexFailedSummary);
structured.WithUserMessage(userMessage);
structured.WithEvidence(evidence);
structured.WithExpectedAndActual(patternText, actualText);

Assert.ReportAssertFailed(structured);
}

#endregion Regular Expressions

#region DoNotUse
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,51 @@ public void CollectionAssertAllItemsAreUniqueMessageNullabilityPostConditions()
_ = collection.Count; // no warning
}

public void CollectionAssertContainsPopulatesStructuredExpectedWithoutActual()
{
ICollection collection = new[] { "a", "b" };
Action action = () => CollectionAssert.Contains(collection, "c");
AssertFailedException ex = action.Should().Throw<AssertFailedException>().Which;
ex.Message.Should().Contain("Expected collection to contain the specified element.");
ex.ExpectedText.Should().Be("\"c\"");
ex.Data["assert.expected"].Should().Be("\"c\"");
ex.ActualText.Should().BeNull();
ex.Data.Contains("assert.actual").Should().BeFalse();
}

public void CollectionAssertDoesNotContainPopulatesStructuredExpectedWithoutActual()
{
ICollection collection = new[] { "a", "b" };
Action action = () => CollectionAssert.DoesNotContain(collection, "a");
AssertFailedException ex = action.Should().Throw<AssertFailedException>().Which;
ex.Message.Should().Contain("Expected collection to not contain the specified element.");
ex.ExpectedText.Should().Be("\"a\"");
ex.Data["assert.expected"].Should().Be("\"a\"");
ex.ActualText.Should().BeNull();
ex.Data.Contains("assert.actual").Should().BeFalse();
}

public void CollectionAssertAllItemsAreNotNullPopulatesStructuredActual()
{
ICollection collection = new[] { "a", null };
Action action = () => CollectionAssert.AllItemsAreNotNull(collection);
AssertFailedException ex = action.Should().Throw<AssertFailedException>().Which;
ex.Message.Should().Contain("Expected all items in collection to be non-null.");
ex.ActualText.Should().NotBeNull();
ex.Data["assert.actual"].Should().NotBeNull();
}

public void CollectionAssertAllItemsAreUniquePopulatesStructuredActual()
{
ICollection collection = new[] { "a", "a" };
Action action = () => CollectionAssert.AllItemsAreUnique(collection);
AssertFailedException ex = action.Should().Throw<AssertFailedException>().Which;
ex.Message.Should().Contain("Expected all items in collection to be distinct.");
ex.Message.Should().Contain("duplicate:");
ex.ActualText.Should().NotBeNull();
ex.Data["assert.actual"].Should().NotBeNull();
}

public void CollectionAssertIsSubsetOfNullabilityPostConditions()
{
ICollection? collection = GetCollection();
Expand Down
Loading
Loading