Skip to content

[file-diet] Refactor Assert.StringDifference.cs (733 lines) into smaller focused files #10181

Description

@github-actions

Overview

The file src/TestFramework/TestFramework/Assertions/Assert.StringDifference.cs has grown to 733 lines, making it harder to navigate and maintain. This task involves refactoring it into smaller, more focused files.

Current State

  • File: src/TestFramework/TestFramework/Assertions/Assert.StringDifference.cs
  • Size: 733 lines
  • Language: C#
Structural Analysis

The file is a partial class Assert containing:

  • Two entry-point helpers: FindFirstStringDifference and AddStringComparisonEvidence
  • A large rendering pipeline (~15 private static methods): CreateStringDifferenceDiagnostic, RenderMismatchFragment, CreatePreview, GetPreviewLength, RenderMismatch, CreateTokenWindow, EnumerateStringTokens, AppendEscapedToken, CreateCodePointDiagnostic, FormatCodePoints, and several Unicode helpers
  • Six nested private types: StringDifference (struct), StringDifferenceDiagnostic (class), StringTokenWindow (class), StringToken (struct), StringPreview (struct), ScalarInfo (struct)

The file has two distinct concerns: (1) the tokenizer/diff engine and its supporting data types, and (2) the rendering/formatting of those differences into diagnostic messages.

Refactoring Strategy

Proposed File Splits

Based on the file's structure, split it into the following files (all remain inside the Assert partial class pattern or as nested-type extractions):

  1. Assert.StringDifference.cs (trimmed)

    • Contents: FindFirstStringDifference, AddStringComparisonEvidence, CreateStringDifferenceDiagnostic, and the StringDifference / StringDifferenceDiagnostic nested types
    • Responsibility: Entry points — bridge between the public Assert API and the diff engine
  2. Assert.StringDifference.Tokenizer.cs

    • Contents: EnumerateStringTokens, CreateStringToken, ShouldMergeTextElements, IsCombiningCharacter, IsEmojiModifier, IsEmojiTag, IsVariationSelector, IsRegionalIndicator, GetScalar, GetPreviousScalar, and the StringToken / ScalarInfo nested types
    • Responsibility: Unicode-aware string tokenization
  3. Assert.StringDifference.Rendering.cs

    • Contents: GetRenderedStringLengthUpToBudget, GetShortPrefixLength, RenderMismatchFragment, CreatePreview, GetPreviewLength, IsBeforeContextOmitted, IsAfterContextOmitted, RenderMismatch, CreateTokenWindow, GetEscapedCharacterLength, AppendEscapedToken, IsUnpairedSurrogate, CreateCodePointDiagnostic, NeedsCodePointDiagnostic, FormatCodePoints, and the StringTokenWindow / StringPreview nested types
    • Responsibility: Formatting diff results into human-readable diagnostic strings

Implementation Guidelines

  1. Preserve Behavior: All existing functionality must work identically after the split
  2. Maintain Public API: These are all private helpers — no public API changes required
  3. Keep partial class pattern: Each new file should be public sealed partial class Assert in the same namespace
  4. Test After Each Split: Run ./build.sh -test (or .\build.cmd -test on Windows) after each incremental change
  5. One File at a Time: Split one module at a time to make review easier

Acceptance Criteria

  • Original file is split into focused modules as described above
  • Each new file is under 300 lines
  • All tests pass after refactoring (./build.sh -test)
  • No breaking changes to public API
  • File naming follows the existing Assert.*.cs partial-class convention

Priority: Medium
Effort: Small
Expected Impact: Improved code navigability, easier code review, reduced merge conflicts when multiple features touch string-diff diagnostics simultaneously

🤖 Automated content by GitHub Copilot. Generated by the Daily File Diet workflow. · sonnet46 32.5 AIC · ⌖ 5.7 AIC · ⊞ 8K · [◷]( · )

  • expires on Jul 25, 2026, 7:17 PM UTC

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions