Skip to content

[duplicate-code] Duplicate banner display logic and SKIP_BANNER constant across output device classes #9170

Description

@Evangelink

🔍 Duplicate Code Detected: Banner Display Logic in Output Devices

Analysis of commit 6d6e32d

Assignee: @copilot

Summary

Both TerminalOutputDevice and SimplifiedConsoleOutputDeviceBase independently define the same private TESTINGPLATFORM_CONSOLEOUTPUTDEVICE_SKIP_BANNER constant and implement nearly identical DisplayBannerAsync logic, including the same StringBuilder-based platform information banner construction.

Duplication Details

Pattern: Duplicate TESTINGPLATFORM_CONSOLEOUTPUTDEVICE_SKIP_BANNER constant and DisplayBannerAsync logic

  • Severity: Medium
  • Occurrences: 2 independent implementations
  • Locations:
    • src/Platform/Microsoft.Testing.Platform/OutputDevice/SimplifiedConsoleOutputDeviceBase.cs (lines 25, 44, 77, 120–168)
    • src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs (lines 28, 65, 109, 347–417)
  • Code Sample — identical constant in both files:
// Declared independently in BOTH files:
private const string TESTINGPLATFORM_CONSOLEOUTPUTDEVICE_SKIP_BANNER =
    nameof(TESTINGPLATFORM_CONSOLEOUTPUTDEVICE_SKIP_BANNER);
  • Code Sample — near-identical banner construction in both DisplayBannerAsync implementations:
// Same logic duplicated in both files:
StringBuilder stringBuilder = new();
stringBuilder.Append(_platformInformation.Name);

if (_platformInformation.Version is { } version)
{
    stringBuilder.Append(CultureInfo.InvariantCulture, $" v{version}");
    if (_platformInformation.CommitHash is { } commitHash)
    {
        stringBuilder.Append(CultureInfo.InvariantCulture, $"+{commitHash[..10]}");
    }
}

if (_platformInformation.BuildDate is { } buildDate)
{
    stringBuilder.Append(CultureInfo.InvariantCulture, $" (UTC {buildDate.UtcDateTime:d})");
}

if (_runtimeFeature.IsDynamicCodeSupported)
{
    stringBuilder.Append(" [");
    stringBuilder.Append(_longArchitecture);
    stringBuilder.Append(" - ");
    stringBuilder.Append(_runtimeFramework);
    stringBuilder.Append(']');
}

Additionally, the _bannerDisplayed bool field and the env-var set/read pattern appear identically in both files.

Impact Analysis

  • Maintainability: Any change to the banner format (e.g., adding new platform metadata fields) must be applied in two places. The SimplifiedConsoleOutputDeviceBase is used for browser/WASI output and TerminalOutputDevice for standard console, so both paths must be kept in sync manually.
  • Bug Risk: A fix to banner formatting (spacing, field ordering, encoding) would silently miss one of the two implementations. The skip-banner env variable name could also diverge if changed in only one place.
  • Code Bloat: ~30 lines of identical banner-building logic duplicated.

Refactoring Recommendations

  1. Extract shared banner constant to a shared location

    • Move TESTINGPLATFORM_CONSOLEOUTPUTDEVICE_SKIP_BANNER to a static class (e.g., OutputDeviceConstants) or a shared base class
    • Both files can reference the single definition
    • Target location: src/Platform/Microsoft.Testing.Platform/OutputDevice/
  2. Extract banner text construction to a shared static helper

    • Create a static BuildBannerText(IPlatformInformation, IRuntimeFeature, string? longArchitecture, string? runtimeFramework) helper method
    • Both SimplifiedConsoleOutputDeviceBase.DisplayBannerAsync and TerminalOutputDevice.DisplayBannerAsync call this helper
    • Target location: A new OutputDeviceBannerHelper.cs or an extension method class in the same namespace

Implementation Checklist

  • Review duplication findings
  • Extract TESTINGPLATFORM_CONSOLEOUTPUTDEVICE_SKIP_BANNER to a shared constant
  • Extract platform info banner StringBuilder logic to a shared static helper
  • Update both DisplayBannerAsync implementations to use the shared helper
  • Verify existing output device tests still pass
  • Verify no functionality broken

Analysis Metadata

  • Analyzed Files: 2
  • Detection Method: Semantic code analysis — identical constant declaration and near-identical method body
  • Commit: 6d6e32d
  • Analysis Date: 2026-06-16

🤖 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 Duplicate Code Detector workflow. · 951.6 AIC · ⌖ 25.8 AIC · [◷]( · )

Add this agentic workflows to your repo

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/duplicate-code-detector.md@main
  • expires on Jun 18, 2026, 6:17 AM UTC

Metadata

Metadata

Labels

type/automationCreated or maintained by an agentic workflow.type/tech-debtCode health, refactoring, simplification.

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions