src/lib/utils/exec.ts sits at 0% functions / 3.95% lines — the worst-covered file in the project by a wide margin.
It is not a peripheral helper. It is the shared subprocess layer that src/lib/analyzers/audit.ts, src/lib/analyzers/deps.ts, src/lib/scorers/risk.ts, and src/lib/github/dependabot.ts all route through. Every package-manager invocation upkeep makes goes through this file.
Why it is untested
Two reasons, and neither is fixed by adding more of the tests we already have:
- The paths that reach it in anger are the CLI integration tests, and those run the CLI via
Bun.spawn. Coverage instrumentation does not follow into a child process, so those runs contribute nothing to the measurement.
- The unit tests that cover the analyzers mock
exec away, which is correct for testing an analyzer's logic but means the wrapper itself is never exercised.
So the fix is direct unit tests against exec.ts — not more integration tests. This was split out of #26 for exactly that reason: it lets the coverage threshold there be set against honest current numbers rather than aspirational ones.
Worth covering
- non-zero exit codes and how failures are surfaced to callers
- stdout/stderr capture, including interleaving and large output
- timeout behaviour, if the wrapper implements one
- command-not-found (a missing package manager binary)
- argument handling and any quoting/escaping
Acceptance
src/lib/utils/exec.tssits at 0% functions / 3.95% lines — the worst-covered file in the project by a wide margin.It is not a peripheral helper. It is the shared subprocess layer that
src/lib/analyzers/audit.ts,src/lib/analyzers/deps.ts,src/lib/scorers/risk.ts, andsrc/lib/github/dependabot.tsall route through. Every package-manager invocation upkeep makes goes through this file.Why it is untested
Two reasons, and neither is fixed by adding more of the tests we already have:
Bun.spawn. Coverage instrumentation does not follow into a child process, so those runs contribute nothing to the measurement.execaway, which is correct for testing an analyzer's logic but means the wrapper itself is never exercised.So the fix is direct unit tests against
exec.ts— not more integration tests. This was split out of #26 for exactly that reason: it lets the coverage threshold there be set against honest current numbers rather than aspirational ones.Worth covering
Acceptance
src/lib/utils/exec.ts, exercising the error paths and not only the happy onebunfig.tomlthresholds added in feat: local install recipe, CI coverage gate, and unskip integration tests #26 raised to reflect the new floorjust checkpasses