Skip to content

Migrate string AreEqual overloads to RFC 012 messages#8331

Merged
Evangelink merged 1 commit into
mainfrom
dev/amauryleve/rfc012-string-areequal
May 19, 2026
Merged

Migrate string AreEqual overloads to RFC 012 messages#8331
Evangelink merged 1 commit into
mainfrom
dev/amauryleve/rfc012-string-areequal

Conversation

@Evangelink
Copy link
Copy Markdown
Member

Summary

  • migrate the string-specific Assert.AreEqual / Assert.AreNotEqual failure paths to RFC 012 structured assertion messages
  • share string diff-summary formatting with the generic Assert.AreEqual path and update string interpolated handlers
  • refresh string assertion tests and regenerated XLF resources for the new messages

Validation

  • dotnet build src\TestFramework\TestFramework\TestFramework.csproj -c Release --nologo -v:minimal
  • dotnet msbuild test\UnitTests\TestFramework.UnitTests\TestFramework.UnitTests.csproj /restore /t:Build /p:Configuration=Release /p:TargetFramework=net9.0 /m:1 /v:m /nologo
  • artifacts\bin\TestFramework.UnitTests\Release\net9.0\Microsoft.VisualStudio.TestPlatform.TestFramework.UnitTests.exe --no-progress --output Normal --treenode-filter "/*/*/AssertTests/*AreEqual*"
  • artifacts\bin\TestFramework.UnitTests\Release\net9.0\Microsoft.VisualStudio.TestPlatform.TestFramework.UnitTests.exe --no-progress --output Normal --treenode-filter "/*/*/AssertTests/*AreNotEqual*"

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 18, 2026 19:08
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR migrates the string-specific Assert.AreEqual / Assert.AreNotEqual failure paths in the MSTest framework to RFC 012 structured assertion messages, aligning string diff summary behavior with the generic Assert.AreEqual path and updating unit tests and localized resources accordingly.

Changes:

  • Updated Assert.AreEqual(string) / Assert.AreNotEqual(string) to emit RFC 012 structured messages (summary + evidence + call-site expression), including culture/ignore-case evidence when applicable.
  • Centralized string diff-summary formatting via shared helpers (and removed the older string preview helper logic).
  • Refreshed string assertion unit tests and updated FrameworkMessages.resx plus corresponding XLF resources.
Show a summary per file
File Description
test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.AreEqualTests.cs Updates assertions to match new structured string messages; adds coverage for ignore-case+culture diff behavior and AreNotEqual structured output.
src/TestFramework/TestFramework/Assertions/Assert.AreEqual.String.cs Implements structured message reporting for string AreEqual/AreNotEqual, including comparison-aware diff index computation and evidence formatting.
src/TestFramework/TestFramework/Assertions/Assert.AreEqual.InterpolatedStringHandlers.cs Updates interpolated string handlers to route through the new structured-message failure paths for string overloads and to pass caller argument expressions.
src/TestFramework/TestFramework/Assertions/Assert.AreEqual.cs Reuses the new diff-summary formatting for the generic AreEqual string path and removes the older formatted string-diff message implementation.
src/TestFramework/TestFramework/Resources/FrameworkMessages.resx Updates string diff summary templates and adds new structured-message summary resources for string-specific paths.
src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.*.xlf Regenerates localized resources for the updated/new messages.

Copilot's findings

  • Files reviewed: 18/18 changed files
  • Comments generated: 1

Copy link
Copy Markdown
Member Author

@Evangelink Evangelink left a comment

Choose a reason for hiding this comment

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

Review Summary — PR #8331: Migrate string AreEqual overloads to RFC 012 messages

# Dimension Verdict
1 Algorithmic Correctness ⚠️ 2 MODERATE
5 Performance & Allocations ⚠️ 2 MODERATE
9 Localization & Resources ✅ LGTM
11 Assertion Quality ⚠️ 1 MODERATE
13 Test Completeness & Coverage ⚠️ 1 MODERATE

✅ 16/21 dimensions clean.

Findings

  • Performance — ToString() in culture-aware FindFirstStringDifferenceexpected[i].ToString() allocates a heap string per character comparison; use string.Compare(expected, i, actual, j, 1, ignoreCase, culture) instead (no allocations).

  • Performance — Substring in TryAdvanceMatchingWindow — up to 8 Substring allocations per mismatching position; replace with the index+count overload of string.Compare.

  • Correctness — Surrogate pairsexpected[i].ToString() on a lone surrogate (half of an emoji/supplementary char) produces an ill-formed string; the reported diff index can point into the middle of a surrogate pair rather than its start. Consider snapping the returned index back with char.IsHighSurrogate.

  • Correctness — Hardcoded "1 location(s)" — Both AreEqualStringDiffLengthBothMsg and AreEqualStringDiffLengthDifferentMsg say "differ at 1 location(s)" regardless of how many positions actually differ. The code only computes the first difference index; the count is always 1 or could be many. Consider removing the count claim or computing it, e.g. "Strings have the same length ({0}). First difference at index {1}.".

  • Test CompletenessAreEqualStringSpecificWithNullExpectedUsesStructuredMessage covers (null, "string", false) but not the symmetric ("string", null, false) path. A null actual through the string-specific overload is untested for the new RFC 012 format.

  • Assertion QualityAreEqual_WithTurkishCultureAndDoesNotIgnoreCase_Throws asserts only .Should().Throw<Exception>() with no message verification. For an RFC 012 migration PR this leaves the new structured output for the Turkish-culture path entirely unchecked.

Notes

  • XLF files appear correctly auto-generated (states new/needs-review-translation), not hand-edited ✅
  • PublicAPI.Unshipped.txt is not affected because the modified constructors pre-existed in both handler structs ✅
  • No threading, IPC, security, or cross-TFM concerns identified ✅

Generated by Expert Code Review (on open) for issue #8331 · ● 34.6M

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants