Skip to content

feat(checks): let OrphanExport report exports imported only by tests (CD-320) - #208

Merged
TAJD merged 1 commit into
mainfrom
fix/cd-320
Aug 10, 2026
Merged

feat(checks): let OrphanExport report exports imported only by tests (CD-320)#208
TAJD merged 1 commit into
mainfrom
fix/cd-320

Conversation

@TAJD

@TAJD TAJD commented Aug 9, 2026

Copy link
Copy Markdown
Owner

Closes CD-320. Read the correction below before the diff — the ticket's premise was wrong, and the finding that replaces it is filed as CD-325.

The ticket said

Design.OrphanExport drops test-file import edges, so an export a test imports is reported as "never imported in the project". Evidence: all 33 findings on poker-puzzle at 0.4.2 are symbols that tests import.

What is actually true

cofferdam counts a test-file import like any other. Minimal reproduction:

apps/worker/src/lib/account-capabilities.ts   export function entitlementFor(x: number): number { … }
apps/worker/test/account-capabilities.test.ts import { entitlementFor } from '../src/lib/account-capabilities'

cofferdam check . --no-cache at 0.4.2 → clean. Multi-line and type-mixed specifier lists behave the same. Add a one-line .cofferdamignore containing **/*.test.ts and the orphan finding appears.

That is what happened on poker-puzzle: its .cofferdamignore excludes **/*.test.ts and **/*.test.tsx, so the test files contributed no edges. An ignore rule silently changes the answers other files get, and Design.OrphanExport states that answer as a fact about the whole project. Filed as CD-325; not fixed here.

What this PR does ship

The capability the ticket asked for was genuinely missing, so it is kept:

  • test_imports_count, a bool defaulting to true — the pre-existing behaviour, now named and switchable.
  • FileConsumption tallies consumption twice per file: any counts every importer, non_test counts only importers that miss test_file_patterns. Classification reuses the existing pattern list rather than inventing a second definition of "test file".
  • Under test_imports_count = false, an export consumed solely by tests reports "imported only by test files" — distinct from the genuine "never imported" case, which still reports in both modes.
  • The namespace-import shortcut (a namespace import claims every named export) moves into is_consumed so both tallies get it identically, replacing the old continue special case.

Before this, "exported solely for tests" — a real smell — could not be seen at all.

Tests

Six cases: same-directory .test.ts and __tests__/ conventions, each in both modes; a normal-file importer (never flagged either way); no importer at all (flagged "never imported" both ways). Also fixes the pre-existing opts_default() helper in design/mod.rs for the new field.

Verification

cargo build --workspace, cargo test --workspace (1382 passed, 8 ignored), cargo clippy --workspace --all-targets -- -D warnings, cargo fmt --all -- --check — all green. cofferdam gen-docs re-run and committed.

🤖 Generated with Claude Code

https://claude.ai/code/session_019afugU2bTYCtXn6Vy9dn1v

…(CD-320)

Consumption is now tallied twice per file — every importer, and only
importers that don't match `test_file_patterns`. A new
`test_imports_count` option (default true, the pre-existing behaviour)
picks which tally decides orphan status. Under the strict reading an
export consumed solely by tests reports "imported only by test files",
distinct from the genuine "never imported" case.

The ticket's premise — that cofferdam drops test-file import edges — is
wrong; it counts them like any other. The poker-puzzle findings that
motivated it came from that repo's `.cofferdamignore` excluding
`**/*.test.ts`, refiled as CD-325. The capability was missing all the
same.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019afugU2bTYCtXn6Vy9dn1v
@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown

Criterion benchmark comparison (PR head vs base branch)

�[1m�[92m   Compiling�[0m cofferdam-checks v0.4.2 (/home/runner/work/cofferdam/cofferdam/crates/cofferdam-checks)
�[1m�[92m   Compiling�[0m cofferdam-engine v0.4.2 (/home/runner/work/cofferdam/cofferdam/crates/cofferdam-engine)
�[1m�[92m    Finished�[0m `bench` profile [optimized] target(s) in 49.34s
�[1m�[92m     Running�[0m benches/engine_bench.rs (target/release/deps/engine_bench-e0ce420cbfc0fb1d)
Gnuplot not found, using plotters backend
Benchmarking full_run_no_cache
Benchmarking full_run_no_cache: Warming up for 3.0000 s
Benchmarking full_run_no_cache: Collecting 20 samples in estimated 7.1123 s (420 iterations)
Benchmarking full_run_no_cache: Analyzing
full_run_no_cache       time:   [16.532 ms 16.679 ms 16.909 ms]
                        change: [+0.6774% +1.9444% +3.5728%] (p = 0.01 < 0.05)
                        Change within noise threshold.
Found 2 outliers among 20 measurements (10.00%)
  2 (10.00%) high severe

Benchmarking single_file_edit_incremental
Benchmarking single_file_edit_incremental: Warming up for 3.0000 s

Warning: Unable to complete 20 samples in 5.0s. You may wish to increase target time to 9.6s, enable flat sampling, or reduce sample count to 10.
Benchmarking single_file_edit_incremental: Collecting 20 samples in estimated 9.5992 s (210 iterations)
Benchmarking single_file_edit_incremental: Analyzing
single_file_edit_incremental
                        time:   [7.3557 ms 7.4005 ms 7.4598 ms]
                        change: [-3.4150% -2.4237% -1.4780%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 5 outliers among 20 measurements (25.00%)
  2 (10.00%) low mild
  2 (10.00%) high mild
  1 (5.00%) high severe


@TAJD
TAJD merged commit ae1a61e into main Aug 10, 2026
18 checks passed
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.

1 participant