Skip to content

[Duplicate Code] Signal-handler Jest setup is duplicated across dedicated and branch-coverage tests #6124

Description

@github-actions

Duplicate Code Opportunity

Summary

  • Pattern: The signal-handler test suite and a targeted branch-coverage test independently define the same Promise flush helper, process signal-handler registry, and Jest spies with matching beforeEach/afterEach lifecycle setup.
  • Locations: src/commands/signal-handler.test.ts:7-30 and src/coverage-branch-gaps-3.test.ts:20-42.
  • Impact: 24 duplicated lines; changes to signal registration mocking, spy cleanup, or handler storage must be maintained in two suites. This is an easy test-infrastructure extraction, and the duplicated setup directly exercises process signal and cleanup behavior.

Evidence

src/commands/signal-handler.test.ts:7-30:

type SignalHandlerDependencies = Parameters<typeof registerSignalHandlers>[0];

const flushPromises = (): Promise<void> => new Promise(resolve => setImmediate(resolve));

...

const handlers: Record<string, (...args: unknown[]) => unknown> = {};

beforeEach(() => {
  jest.clearAllMocks();
  processOnSpy = jest.spyOn(process, on).mockImplementation(
    (event: string | symbol, handler: (...args: unknown[]) => void) => {
      handlers[String(event)] = handler;
      return process;
    }
  );
  processExitSpy = jest.spyOn(process, exit).mockImplementation(() => undefined as never);
  consoleErrorSpy = jest.spyOn(console, error).mockImplementation();
});

afterEach(() => {
  processOnSpy.mockRestore();
  processExitSpy.mockRestore();
  consoleErrorSpy.mockRestore();
  delete handlers[SIGINT];
  delete handlers[SIGTERM];
});

src/coverage-branch-gaps-3.test.ts:20-42 repeats the same structure:

const flushPromises = (): Promise<void> => new Promise(resolve => setImmediate(resolve));

...

const handlers: Record<string, (...args: unknown[]) => unknown> = {};

beforeEach(() => {
  jest.clearAllMocks();
  processOnSpy = jest.spyOn(process, on).mockImplementation(
    (event: string | symbol, handler: (...args: unknown[]) => void) => {
      handlers[String(event)] = handler;
      return process;
    }
  );
  processExitSpy = jest.spyOn(process, exit).mockImplementation(() => undefined as never);
  consoleErrorSpy = jest.spyOn(console, error).mockImplementation();
});

afterEach(() => {
  processOnSpy.mockRestore();
  processExitSpy.mockRestore();
  consoleErrorSpy.mockRestore();
  delete handlers[SIGTERM];
});

Suggested Refactoring

Extract a shared signal-handler Jest fixture/helper containing flushPromises, handler capture, process/console spies, and teardown. Import it from both suites, allowing each test to retain only scenario-specific setup and assertions.

A related completed detector issue tracked overlapping signal-handler test cleanup scenarios: #5655. This finding concerns the duplicated cross-file mocking fixture and should be reassessed against that implementation.

Affected Files

  • src/commands/signal-handler.test.ts — lines 7-30
  • src/coverage-branch-gaps-3.test.ts — lines 20-42

Effort Estimate

Low


Detected by Duplicate Code Detector workflow. Run date: 2026-07-12

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

Generated by Duplicate Code Detector · 6.03 AIC · ⊞ 20.1K ·

  • expires on Aug 11, 2026, 6:34 AM UTC

Metadata

Metadata

Assignees

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