Overview
The file src/Platform/Microsoft.Testing.Extensions.CtrfReport/CtrfReportEngine.cs has grown to 778 lines, making it harder to navigate and maintain. This task involves refactoring it into smaller, more focused files.
Current State
- File:
src/Platform/Microsoft.Testing.Extensions.CtrfReport/CtrfReportEngine.cs
- Size: 778 lines
- Language: C#
Structural Analysis
The file contains a single CtrfReportEngine class with four distinct responsibility groups:
-
Orchestration (lines 1–87): Constructor, GenerateReportAsync, GenerateReportCoreAsync — the top-level entry point that wires the other groups together.
-
File I/O (lines 89–174): WriteWithRetryAsync, SplitCtrfExtension, WriteAsync — collision-safe file writing with a retry loop.
-
File naming (lines 175–421): BuildDefaultFileName, ResolveJsonFileName, GetTargetFrameworkMoniker, GetCtrfOsPlatform, ReplaceInvalidFileNameChars, IsInvalidFileNameChar, IsReservedFileName — composing output paths, sanitizing characters, and avoiding Windows reserved names.
-
JSON serialization (lines 422–778): BuildCtrfJson, WriteTest, WriteRetryAttempt, HasSameKeyEarlier, WriteOutputLines, CollapseAttempts, CollapsedTestResult — the bulk of the file; converts CapturedTestResult[] to a CTRF-compliant JSON byte array.
Refactoring Strategy
Proposed File Splits
Based on the file's structure, split it into the following files (using partial class or companion static helpers to avoid API churn):
-
CtrfReportEngine.cs (keep, trimmed to orchestration only)
- Contents: constructor, fields,
GenerateReportAsync, GenerateReportCoreAsync
- Responsibility: Entry point — coordinates naming, serialisation, and I/O
-
CtrfReportFileWriter.cs (new, extracted as private static helpers or partial class)
- Contents:
WriteWithRetryAsync, SplitCtrfExtension, WriteAsync
- Responsibility: Collision-safe file persistence
-
CtrfReportFileNaming.cs (new)
- Contents:
BuildDefaultFileName, ResolveJsonFileName, GetTargetFrameworkMoniker, GetCtrfOsPlatform, ReplaceInvalidFileNameChars, IsInvalidFileNameChar, IsReservedFileName
- Responsibility: All output-path construction and sanitization rules, including Windows reserved-name detection
-
CtrfJsonSerializer.cs (new)
- Contents:
BuildCtrfJson, WriteTest, WriteRetryAttempt, HasSameKeyEarlier, WriteOutputLines, CollapseAttempts, CollapsedTestResult
- Responsibility: Converting
CapturedTestResult[] to a CTRF-compliant JSON byte array; the largest cohesive concern (~350 lines)
Implementation Guidelines
- Preserve Behavior: All existing functionality must work identically after the split
- Maintain Internal API:
CtrfReportEngine is internal sealed — no public surface change is needed, but the extracted helpers must remain accessible within the assembly (use internal static or partial class)
- Test After Each Split: Run the test suite (
./build.sh -test) after each incremental extraction
- One File at a Time: Extract one group at a time to keep diffs reviewable
- No Namespace Changes: Keep everything in
Microsoft.Testing.Extensions.CtrfReport
Acceptance Criteria
Priority: Medium
Effort: Small — the class is already well-structured; the methods have low coupling and clear groupings
Expected Impact: Improved code navigability, easier testing of individual concerns, reduced merge conflicts when CTRF spec evolves
🤖 Automated content by GitHub Copilot. Posted via a maintainer's GitHub token, so it appears under their account — the account owner did not write or approve this content personally. Generated by the Daily File Diet workflow. · 147.8 AIC · ⌖ 12.8 AIC · [◷]( · ◷)
Overview
The file
src/Platform/Microsoft.Testing.Extensions.CtrfReport/CtrfReportEngine.cshas grown to 778 lines, making it harder to navigate and maintain. This task involves refactoring it into smaller, more focused files.Current State
src/Platform/Microsoft.Testing.Extensions.CtrfReport/CtrfReportEngine.csStructural Analysis
The file contains a single
CtrfReportEngineclass with four distinct responsibility groups:Orchestration (lines 1–87): Constructor,
GenerateReportAsync,GenerateReportCoreAsync— the top-level entry point that wires the other groups together.File I/O (lines 89–174):
WriteWithRetryAsync,SplitCtrfExtension,WriteAsync— collision-safe file writing with a retry loop.File naming (lines 175–421):
BuildDefaultFileName,ResolveJsonFileName,GetTargetFrameworkMoniker,GetCtrfOsPlatform,ReplaceInvalidFileNameChars,IsInvalidFileNameChar,IsReservedFileName— composing output paths, sanitizing characters, and avoiding Windows reserved names.JSON serialization (lines 422–778):
BuildCtrfJson,WriteTest,WriteRetryAttempt,HasSameKeyEarlier,WriteOutputLines,CollapseAttempts,CollapsedTestResult— the bulk of the file; convertsCapturedTestResult[]to a CTRF-compliant JSON byte array.Refactoring Strategy
Proposed File Splits
Based on the file's structure, split it into the following files (using
partial classor companion static helpers to avoid API churn):CtrfReportEngine.cs(keep, trimmed to orchestration only)GenerateReportAsync,GenerateReportCoreAsyncCtrfReportFileWriter.cs(new, extracted asprivate statichelpers orpartial class)WriteWithRetryAsync,SplitCtrfExtension,WriteAsyncCtrfReportFileNaming.cs(new)BuildDefaultFileName,ResolveJsonFileName,GetTargetFrameworkMoniker,GetCtrfOsPlatform,ReplaceInvalidFileNameChars,IsInvalidFileNameChar,IsReservedFileNameCtrfJsonSerializer.cs(new)BuildCtrfJson,WriteTest,WriteRetryAttempt,HasSameKeyEarlier,WriteOutputLines,CollapseAttempts,CollapsedTestResultCapturedTestResult[]to a CTRF-compliant JSON byte array; the largest cohesive concern (~350 lines)Implementation Guidelines
CtrfReportEngineisinternal sealed— no public surface change is needed, but the extracted helpers must remain accessible within the assembly (useinternal staticorpartial class)./build.sh -test) after each incremental extractionMicrosoft.Testing.Extensions.CtrfReportAcceptance Criteria
./build.sh -test)Priority: Medium
Effort: Small — the class is already well-structured; the methods have low coupling and clear groupings
Expected Impact: Improved code navigability, easier testing of individual concerns, reduced merge conflicts when CTRF spec evolves