Duplicate Code Opportunity
Summary
- Pattern:
src/commands/logs-stats.test.ts (200 lines) and src/commands/logs-summary.test.ts (228 lines) are structurally near-identical. Every test scenario — source discovery, JSON format, error on missing source, explicit source option, multiple sources — is duplicated with only the command name, options type, and default format string changing.
- Locations:
src/commands/logs-stats.test.ts and src/commands/logs-summary.test.ts
- Impact: ~160 duplicated lines across the two files; jscpd flagged 6 independent duplicate clone pairs between them
Evidence
The file headers are identical save for the import line:
// logs-stats.test.ts
import { statsCommand, StatsCommandOptions } from './logs-stats';
// logs-summary.test.ts
import { summaryCommand, SummaryCommandOptions } from './logs-summary';
Both files mock the same four modules (log-discovery, log-aggregator, stats-formatter, logger) and use the same createLogCommandTestHarness() helper. Then every test is repeated:
| Scenario |
logs-stats.test.ts |
logs-summary.test.ts |
| Discover & use most-recent source |
lines 25–58 |
lines 25–58 |
| JSON format output |
lines 56–77 |
lines 81–102 |
| Error on no sources found |
lines 112–125 |
lines 59–72 |
Explicit --source option |
lines 143–158 |
lines 171–186 |
| Multiple sources, picks most recent |
lines 166–187 |
lines 194–215 |
jscpd clone pairs between the two files: lines 5–23, 23–44, 56–77↔81–102, 112–125↔59–72, 143–158↔171–186, 166–187↔194–215.
Suggested Refactoring
Extract a shared parameterised test suite factory into src/commands/test-helpers.test-utils.ts (which already exists):
export function createLogCommandTests<TOptions>(
commandName: string,
runCommand: (opts: TOptions) => Promise<void>,
defaultFormat: string,
makeOptions: (overrides?: Partial<TOptions>) => TOptions,
) {
// ... shared describe block with all common test cases
}
Then each test file becomes:
// logs-stats.test.ts
createLogCommandTests('stats', statsCommand, 'pretty', overrides => ({ format: 'pretty', ...overrides }));
// logs-summary.test.ts
createLogCommandTests('summary', summaryCommand, 'markdown', overrides => ({ format: 'markdown', ...overrides }));
Command-specific edge cases (e.g. markdown output validation unique to summary) stay in their own describe blocks.
Affected Files
src/commands/logs-stats.test.ts — entire file
src/commands/logs-summary.test.ts — entire file
src/commands/test-helpers.test-utils.ts — extend with shared suite factory
Effort Estimate
Low
Detected by Duplicate Code Detector workflow. Run date: 2026-05-05
Generated by Duplicate Code Detector · ● 594.5K · ◷
Duplicate Code Opportunity
Summary
src/commands/logs-stats.test.ts(200 lines) andsrc/commands/logs-summary.test.ts(228 lines) are structurally near-identical. Every test scenario — source discovery, JSON format, error on missing source, explicit source option, multiple sources — is duplicated with only the command name, options type, and default format string changing.src/commands/logs-stats.test.tsandsrc/commands/logs-summary.test.tsEvidence
The file headers are identical save for the import line:
Both files mock the same four modules (
log-discovery,log-aggregator,stats-formatter,logger) and use the samecreateLogCommandTestHarness()helper. Then every test is repeated:--sourceoptionjscpd clone pairs between the two files: lines 5–23, 23–44, 56–77↔81–102, 112–125↔59–72, 143–158↔171–186, 166–187↔194–215.
Suggested Refactoring
Extract a shared parameterised test suite factory into
src/commands/test-helpers.test-utils.ts(which already exists):Then each test file becomes:
Command-specific edge cases (e.g. markdown output validation unique to
summary) stay in their owndescribeblocks.Affected Files
src/commands/logs-stats.test.ts— entire filesrc/commands/logs-summary.test.ts— entire filesrc/commands/test-helpers.test-utils.ts— extend with shared suite factoryEffort Estimate
Low
Detected by Duplicate Code Detector workflow. Run date: 2026-05-05