Apply structured assertion messages (RFC 012) to Assert.MatchesRegex / DoesNotMatchRegex#8259
Conversation
…/ DoesNotMatchRegex Migrates Assert.MatchesRegex / Assert.DoesNotMatchRegex to the structured assertion message format defined in RFC 012, following the patterns used by the previously migrated string predicate assertions. The evidence block carries the expected/unexpected pattern (rendered as a string literal so it copy-pastes cleanly) and the actual string. Removes the now-unused BuildUserMessageForPatternExpressionAndValueExpression helper from Assert.cs because the call-site is now reconstructed via FormatCallSiteExpression. StringAssert.Matches / DoesNotMatch are unaffected and continue to use FrameworkMessages.IsMatchFail / IsNotMatchFail. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Rolls forward the RFC 012 “Structured Assertion Messages” migration by converting Assert.MatchesRegex and Assert.DoesNotMatchRegex to the structured, multi-line failure format and wiring new localized summary resources.
Changes:
- Migrated
Assert.MatchesRegex/Assert.DoesNotMatchRegexfailure paths toStructuredAssertionMessage+EvidenceBlock+ call-site rendering. - Added new
FrameworkMessages.*FailedSummaryresource entries and regenerated corresponding XLF entries. - Removed the now-unused
BuildUserMessageForPatternExpressionAndValueExpressionhelper fromAssert.cs.
Show a summary per file
| File | Description |
|---|---|
| src/TestFramework/TestFramework/Assertions/Assert.Matches.cs | Converts regex assertions to structured assertion messages with evidence blocks and call-site formatting. |
| src/TestFramework/TestFramework/Assertions/Assert.cs | Removes unused user-message builder helper now that call-sites are formatted via FormatCallSiteExpression. |
| src/TestFramework/TestFramework/Resources/FrameworkMessages.resx | Adds MatchesRegexFailedSummary and DoesNotMatchRegexFailedSummary resource strings. |
| src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.cs.xlf | Adds new trans-units for the two new summary resource keys. |
| src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.de.xlf | Adds new trans-units for the two new summary resource keys. |
| src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.es.xlf | Adds new trans-units for the two new summary resource keys. |
| src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.fr.xlf | Adds new trans-units for the two new summary resource keys. |
| src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.it.xlf | Adds new trans-units for the two new summary resource keys. |
| src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ja.xlf | Adds new trans-units for the two new summary resource keys. |
| src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ko.xlf | Adds new trans-units for the two new summary resource keys. |
| src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pl.xlf | Adds new trans-units for the two new summary resource keys. |
| src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pt-BR.xlf | Adds new trans-units for the two new summary resource keys. |
| src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ru.xlf | Adds new trans-units for the two new summary resource keys. |
| src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.tr.xlf | Adds new trans-units for the two new summary resource keys. |
| src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hans.xlf | Adds new trans-units for the two new summary resource keys. |
| src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hant.xlf | Adds new trans-units for the two new summary resource keys. |
Copilot's findings
- Files reviewed: 16/16 changed files
- Comments generated: 2
Evangelink
left a comment
There was a problem hiding this comment.
Review Summary — PR #8259: Structured assertion messages for Assert.MatchesRegex / DoesNotMatchRegex
This PR continues the RFC 012 rollout in a clean, consistent manner. The implementation faithfully mirrors the pattern established by prior migrations (#8170, #8187, #8210, #8214, #8258).
| Dimension | Result | Severity |
|---|---|---|
| Algorithmic Correctness | ✅ LGTM | — |
| Threading & Concurrency | ✅ N/A (no shared state) | — |
| Security | ✅ N/A | — |
| Public API & Binary Compatibility | ✅ LGTM | — |
| Performance & Allocations | ✅ LGTM | — |
| Cross-TFM Compatibility | ✅ LGTM | — |
| Resource & IDisposable | ✅ N/A | — |
| Localization & Resources | ✅ LGTM — XLF files regenerated via the UpdateXlf automated build target |
— |
| Test Completeness | MODERATE | |
| Code Structure | ✅ LGTM | — |
| Naming & Conventions | ✅ LGTM | — |
| Documentation Accuracy | ✅ LGTM | — |
| Scope & PR Discipline | ✅ LGTM | — |
Notable design consistency
WithExpectedAndActual(patternText, actualText) is called in ReportAssertDoesNotMatchRegexFailed, storing the (unwanted) pattern as AssertFailedException.ExpectedText. This is consistent with how other DoesNot* methods (e.g. DoesNotContain, DoesNotStartWith) handle the same property in this codebase — the evidence block labels ("unexpected pattern:" / "actual:") provide the human-readable semantics.
Single finding
Test coverage gap (MODERATE): No unit tests were added for the new structured failure message paths. See the inline comment on line 163 of Assert.Matches.cs for details and recommendations.
Generated by Expert Code Review (on open) for issue #8259 · ● 14.5M
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
@copilot resolve the merge conflicts in this pull request |
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
Resolved. I merged |
|
@copilot resolve the merge conflicts in this pull request |
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
Resolved. I merged the latest |
These string-predicate helpers (substring, prefix, suffix) are no longer referenced after the structured assertion message refactors landed on main, and IDE0051 is enforced as an error on Linux/macOS. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Copilot's findings
Comments suppressed due to low confidence (1)
src/TestFramework/TestFramework/Assertions/Assert.Matches.cs:149
- Same issue as above: [DoesNotReturn] is not accurate because ReportAssertFailed(StructuredAssertionMessage) returns in AssertScope mode. Please remove the attribute (or ensure the method truly does not return).
[DoesNotReturn]
private static void ReportAssertDoesNotMatchRegexFailed(Regex pattern, string value, string? userMessage, string patternExpression, string valueExpression)
{
- Files reviewed: 17/17 changed files
- Comments generated: 2
Continues the rollout of RFC 012 — Structured Assertion Messages by migrating
Assert.MatchesRegex/Assert.DoesNotMatchRegexto the structured-message format. Follows the pattern established by previously migrated assertions (#8170, #8187, #8210, #8214) and the in-flight #8258 (StartsWith/EndsWith).Output format
Assert.MatchesRegex(new Regex(""^foo""), ""hello""):Assert.DoesNotMatchRegex(new Regex(""world""), ""hello world"", ""value should not match""):Notes
MatchesRegexFailedSummary/DoesNotMatchRegexFailedSummaryresource entries (XLF files regenerated viaUpdateXlf).BuildUserMessageForPatternExpressionAndValueExpressionhelper fromAssert.csbecause the call-site is now reconstructed byFormatCallSiteExpression.StringAssert.Matches/StringAssert.DoesNotMatchare intentionally unchanged and continue to useFrameworkMessages.IsMatchFail/IsNotMatchFail.Validation
dotnet build src/TestFramework/TestFramework/TestFramework.csproj -c Debug— clean.dotnet test test/UnitTests/TestFramework.UnitTests/TestFramework.UnitTests.csproj -c Debug— 3535/3535 passed.Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com