Skip to content

Deduplicate command-line provider boilerplate via CommandLineOptionsProviderBase#8712

Open
Copilot wants to merge 6 commits into
mainfrom
copilot/duplicate-code-optimization
Open

Deduplicate command-line provider boilerplate via CommandLineOptionsProviderBase#8712
Copilot wants to merge 6 commits into
mainfrom
copilot/duplicate-code-optimization

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 31, 2026

Multiple ICommandLineOptionsProvider implementations were repeating the same extension metadata and default validation/enablement boilerplate despite an existing shared base type. This change consolidates those providers on CommandLineOptionsProviderBase and adds a base constructor path for extension-delegated metadata.

  • Problem addressed

    • Removes repeated Uid/Version/DisplayName/Description/default validation boilerplate across Platform and extension command-line providers.
    • Aligns providers on a single default behavior surface to reduce drift risk as command-line provider contracts evolve.
  • Base abstraction updates

    • Added overload to CommandLineOptionsProviderBase:
      • CommandLineOptionsProviderBase(IExtension extension, IReadOnlyCollection<CommandLineOption> commandLineOptions)
    • Enables providers that delegate metadata to an injected extension to use the same base path as static-metadata providers.
  • Provider migrations

    • Switched direct implementations to inherit from CommandLineOptionsProviderBase:
      • VSTestBridge: TestCaseFilter*, TestRunParameters*, RunSettings*
      • Extensions: Retry, Azure DevOps report, HTML report, TRX report
      • Platform: PlatformCommandLineProvider, MaxFailedTests*, TreeNodeFilter*, TerminalTestReporter*
    • Removed duplicated base-equivalent members from migrated providers.
    • Kept provider-specific validation logic intact (moved/retained as overrides where applicable).
  • Unit test coverage

    • Extended CommandLineOptionsProviderBase tests for:
      • metadata propagation through the new IExtension constructor overload
      • null extension guard behavior
protected CommandLineOptionsProviderBase(
    IExtension extension,
    IReadOnlyCollection<CommandLineOption> commandLineOptions)
    : this(
        (extension ?? throw new ArgumentNullException(nameof(extension))).Uid,
        extension.Version,
        extension.DisplayName,
        extension.Description,
        commandLineOptions)
{
}

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot May 31, 2026 06:16
Copilot AI changed the title [WIP] Refactor ICommandLineOptionsProvider implementations to reduce duplicate code Deduplicate command-line provider boilerplate via CommandLineOptionsProviderBase May 31, 2026
Copilot AI requested a review from Evangelink May 31, 2026 06:17
@Evangelink Evangelink marked this pull request as ready for review May 31, 2026 06:31
Copilot AI review requested due to automatic review settings May 31, 2026 06:31
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 consolidates repeated command-line provider boilerplate by moving migrated providers onto CommandLineOptionsProviderBase and adding an overload that initializes provider metadata from an IExtension.

Changes:

  • Adds an IExtension-backed constructor overload to CommandLineOptionsProviderBase.
  • Migrates Platform, VSTestBridge, Retry, Azure DevOps, HTML, TRX, and terminal command-line providers to inherit from the shared base.
  • Adds unit tests for extension metadata propagation and null extension validation.
Show a summary per file
File Description
src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOptionsProviderBase.cs Adds the extension-backed base constructor.
src/Platform/Microsoft.Testing.Platform/CommandLine/PlatformCommandLineProvider.cs Moves platform CLI provider metadata/options to the base class.
src/Platform/Microsoft.Testing.Platform/CommandLine/MaxFailedTestsCommandLineOptionsProvider.cs Uses the new extension-backed base path while keeping validation.
src/Platform/Microsoft.Testing.Platform/CommandLine/TreeNodeFilterCommandLineOptionsProvider.cs Simplifies tree-node filter provider via the base class.
src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporterCommandLineOptionsProvider.cs Moves terminal reporter metadata/options to the base class.
src/Platform/Microsoft.Testing.Extensions.VSTestBridge/CommandLine/TestCaseFilterCommandLineOptionsProvider.cs Uses the base class for VSTest filter option metadata.
src/Platform/Microsoft.Testing.Extensions.VSTestBridge/CommandLine/TestRunParametersCommandLineOptionsProvider.cs Uses the base class while preserving argument validation.
src/Platform/Microsoft.Testing.Extensions.VSTestBridge/CommandLine/RunSettingsCommandLineOptionsProvider.cs Uses the base class while preserving runsettings validation.
src/Platform/Microsoft.Testing.Extensions.Retry/RetryCommandLineOptionsProvider.cs Moves retry provider metadata/options to the base class.
src/Platform/Microsoft.Testing.Extensions.AzureDevOpsReport/AzureDevOpsCommandLineProvider.cs Moves Azure DevOps provider metadata/options to the base class.
src/Platform/Microsoft.Testing.Extensions.HtmlReport/HtmlReportGeneratorCommandLine.cs Moves HTML report provider metadata/options to the base class.
src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxCommandLine.cs Moves TRX report provider metadata/options to the base class.
test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/CommandLineOptionsProviderBaseTests.cs Adds tests for the new extension-backed constructor path.

Copilot's findings

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

Evangelink and others added 2 commits May 31, 2026 08:37
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 31, 2026 06:38
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.

Copilot's findings

  • Files reviewed: 13/13 changed files
  • Comments generated: 4

Addresses PR review comments and CI build failures:
- Add missing 'override' keyword on ValidateCommandLineOptionsAsync in PlatformCommandLineProvider, HtmlReportGeneratorCommandLine, TrxCommandLine, AzureDevOpsCommandLineProvider
- Fix SA1116 by placing first argument on new line in : base(...) / : this(...) constructor initializers across all migrated providers and the base class itself
- Fix SA1508 by removing extra blank line before closing brace in TerminalTestReporterCommandLineOptionsProvider

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 31, 2026 10:24
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.

Copilot's findings

  • Files reviewed: 13/13 changed files
  • Comments generated: 0 new

The original individual providers (e.g. TreeNodeFilterCommandLineOptionsProvider, MaxFailedTestsCommandLineOptionsProvider, RunSettingsCommandLineOptionsProvider) did no validation on Uid/Version and simply assigned extension.Uid / extension.Version directly. The new base class introduced Ensure.NotNullOrWhiteSpace on both, which broke acceptance tests whose test asset (DummyTestFramework) intentionally returns string.Empty for IExtension.Version, DisplayName, and Description.

Relax the validation to null-only (matching how displayName and description are already handled in the same constructor) to preserve pre-refactor behavior. Update unit tests so the whitespace cases now assert no-throw.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink
Copy link
Copy Markdown
Member

Fixed the failing acceptance tests (TestMaxFailedTestsShouldCallStopTestExecutionAsync, WhenCapabilityIsMissingShouldFail) in 22cbf2d.

Root cause: the new CommandLineOptionsProviderBase used Ensure.NotNullOrWhiteSpace on uid and version, but the original per-extension providers (e.g. TreeNodeFilterCommandLineOptionsProvider, MaxFailedTestsCommandLineOptionsProvider, RunSettingsCommandLineOptionsProvider) did no validation and just forwarded extension.Uid / extension.Version. The DummyTestFramework test asset in MaxFailedTestsExtensionTests legitimately returns string.Empty for Version/DisplayName/Description, so the new validation threw ArgumentException at construction time → exit code 57005 instead of 13/5.

Fix: Relaxed the base ctor to null-check only (matching how displayName/description were already handled). The whitespace unit tests were updated to assert no-throw, while the null tests are kept.

Validated locally with the CommandLineOptionsProviderBaseTests (13/13 pass) and a clean Debug build of Microsoft.Testing.Platform. CI should now pick up the acceptance tests.

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.

[duplicate-code] Duplicate Code: ICommandLineOptionsProvider Boilerplate Repeated Across 10+ Implementations

3 participants