Skip to content

test(coverage): guard the v8-ignore hints in src/ so each ignored arm keeps the unit test it names - #601

Merged
jeefy merged 3 commits into
mainfrom
quality/test-coverage-ignore-hint-guard
Oct 29, 2026
Merged

jeefy merged 3 commits into
mainfrom
quality/test-coverage-ignore-hint-guard

Conversation

@hivecommons-hive

Copy link
Copy Markdown
Contributor

Test Improvement

Adds __tests__/coverageIgnoreHints.test.ts, a static guard over the 25 /* v8 ignore */ hints in src/ (7 ignore next arms, 6 start/stop test-only hook blocks, 11 files at main @ 9acb046). Each arm-level hint says <name>.test.ts drives it, but @vitest/coverage-v8 honours the hint in the unit run as well as the bundle run (same provider, no option to disable source hints), so neither floor can see the named test disappear: with configBlunderbussDelay.test.ts and configSweep.test.ts excluded, npm run test:coverage still passes every threshold and reports config.ts at 100 % lines with neither 619 nor 679 listed. Details and the reproduction in #600.

The guard asserts, for every hint:

rule catches
a -- reason follows the hint (a bare stop is exempt; its reason is on the start) an unexplained ignore
an ignore next names <name>.test.ts drives it, the file exists under __tests__/, and it imports the hinted module (from '../../src/utils/config') the cited test being deleted, renamed, or moved off the module
src/labels/lgtm.ts:68, whose hint names no test, is recorded in a one-entry table (__tests__/label/lgtm.test.ts:796 drives it through handleIssueComment; the comment text ships into dist/index.js, so naming it in the hint means repacking); the table is itself checked a stale table entry once the hint is updated, or the driver file vanishing
every start has a stop in the same file, says test-only hook, and each export function between them is called by some test a hook kept ignored after its last caller is gone

No src/, dist/, config or docs file is touched.

Files / cluster claimed — one new file, __tests__/coverageIgnoreHints.test.ts (reads src/**/*.ts and __tests__/**/*.ts; imports only root from __tests__/utils/workflowYaml.ts). Disjoint from every held PR: #591/#593/#597 (plugin, dispatcher and label unit tests), #595 (__tests__/setup.ts, config type guards), #596 (bundle scenario + e2e floor), #598 (__tests__/testUtils.ts, fixture ordering), #599 (tsconfig.test.json, existing-test type fixes). docs/contributing.md is deliberately left alone because four of those PRs edit it; the file's header comment carries the rationale.

Testing

  • npx vitest run __tests__/coverageIgnoreHints.test.ts — 39 passed
  • fault injection, each restored afterwards: configBlunderbussDelay.test.ts moved away → config.ts:619 names the unit test that drives the ignored arm fails; an uncited /* v8 ignore next -- probe */ appended to sleep.ts → sleep.ts:13 names the unit test … fails; resetLabelCache renamed → labeling.ts:91 is a test-only hook, exported and called from a test fails; lgtm.test.ts drives it added to lgtm.ts:68 without dropping the table entry → records out-of-hint drivers only for hints that still exist and still name no test fails
  • npx vitest run — 192 files, 2512 passed, 75 skipped
  • npx eslint __tests__/coverageIgnoreHints.test.ts — clean; tsc --noEmit --strict on the file — clean

Related Issue

Closes #600


Filed by quality agent (hold-gated mode). Human review required.

— hive: agent=quality backend=copilot model=claude-fable-5.1 copilot=1.0.88

… keeps the unit test it names

Every `/* v8 ignore */` hint hides its arm from both coverage runs: the
bundle run it was written for and the unit run, which uses the same
provider and has no option to disable source hints. The unit floor
therefore cannot notice when the test a hint names is deleted or stops
reaching the arm — config.ts still reports 100 % lines with
configBlunderbussDelay.test.ts and configSweep.test.ts removed.

__tests__/coverageIgnoreHints.test.ts pins what can be checked
statically: every hint states a reason; every `ignore next` names a
`<name>.test.ts` that exists and imports the hinted module (lgtm.ts:68,
whose driver reaches the arm through the dispatcher, is recorded in a
checked one-entry table); every `start`/`stop` block is a test-only
hook whose exported functions some test still calls.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: quality <280983584+hivecommons-hive[bot]@users.noreply.github.com>
@hivecommons-hive
hivecommons-hive Bot requested a review from jpmcb as a code owner October 27, 2026 21:25
@hivecommons-hive hivecommons-hive Bot added the hold Indicates that a PR should not merge because someone has issued a /hold command. label Oct 27, 2026
@hivecommons-hive

Copy link
Copy Markdown
Contributor Author

Important

Held for human review by the hive's ACMM level gate.

This PR was opened by the "quality" agent while Hive policy required a human checkpoint for that agent. Agent PRs are held at ACMM L3–L5; an outreach PR that targets a repository this hive does not manage is held at every level because it publishes project-facing communication into someone else's project.

Hive will keep the hold label until a human removes it. Operators can make a deliberate one-off release during an ACMM level change with release_level_holds=true, but level changes never release this hold automatically.

@hivecommons-hive hivecommons-hive Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Read the tree at bc1b372, re-ran the suite, and fault-injected the guard. This looks correct to me.

Verified against the repository, not just the diff:

  • The 25 hints the guard walks are real: grep -rn "v8 ignore" src/ at this head returns exactly the 7 ignore next arms and 6 start/stop blocks the PR body claims (e.g. src/utils/config.ts:619, src/utils/auth.ts:18, src/plugins/tide.ts:235).
  • src/labels/lgtm.ts:68 indeed names no test, and the recorded driver is real: __tests__/label/lgtm.test.ts:796 ("a binding refused with a non-Error value fails the command with its string form") reaches the arm through handleIssueComment.
  • root imported from __tests__/utils/workflowYaml.ts:7 resolves to the repo root as the file assumes.
  • npx vitest run __tests__/coverageIgnoreHints.test.ts → 39 passed. Fault injection: moving __tests__/utils/configBlunderbussDelay.test.ts away makes exactly one case fail — src/utils/config.ts:619 names the unit test that drives the ignored arm — and restoring it goes green again. The guard is not vacuous (exist where this guard expects them pins that too).
  • hookNames (line 85) only matches export function/export async function; a hook written as export const would yield an empty list and fail loudly via the no exported function between start and stop assertion — conservative, not a hole.

Scope matches Closes #600 — the issue's recommendation section describes this file almost verbatim, including the deliberate limitation (static guard only; no stripped-hints coverage run), which the issue records as an accepted decision. One new test file, nothing else touched, disjoint from the other held PRs as claimed.

Minor observation, not a defect: importsModule (line 77) requires a single-quoted relative specifier; an alias or double-quoted import of a hinted module would false-fail the guard. That is the repo's idiom today and the failure mode is loud, so fine as is.

I cannot approve (human signature), but a maintainer can take this on the strength of the checks above.

— hive: agent=reviewer backend=copilot model=claude-fable-5 copilot=1.0.88

@hivecommons-hive

Copy link
Copy Markdown
Contributor Author

/kind cleanup


🐝 Hive Agent: quality | Instance: hosted-available-lke648397-260827-5q9t | SHA: 9acb046

— hive: agent=quality backend=copilot model=claude-fable-5.1 copilot=1.0.88

@github-actions github-actions Bot added kind/cleanup Categorizes issue or PR as related to cleaning up code, process, or technical debt. and removed needs-kind labels Oct 27, 2026
hivecommons-hive Bot and others added 2 commits October 28, 2026 22:31
The six reset*() hooks the block rule was written for are gone; the one
start/stop block left (src/platform/index.ts:18) ignores the adapter-only
PlatformScope, which the action never reaches from dist/index.js but
runState.test.ts exercises. The rule now asks of every block what it asked
of the hooks — each export inside is named by some test — without requiring
the 'test-only hook' wording. lgtm.ts's recorded driver moves to line 65.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: quality <280983584+hivecommons-hive[bot]@users.noreply.github.com>
@hivecommons-hive

Copy link
Copy Markdown
Contributor Author

Merged origin/main and adjusted the guard for #607 (RunState refactor), which would otherwise have turned this PR red on merge: 3 of 29 cases failed against main (lgtm.ts hint moved 68→65; the only remaining v8 ignore start block, src/platform/index.ts:18, ignores the adapter-only PlatformScope, not a test-only hook, and the six reset*() hooks the block rule was written for no longer exist). The block rule now requires every export inside an ignored block to be named by some test, without the test-only hook wording; fault-injecting a rename of installPlatformScope's only test reference fails it as before. 29/29 pass; hold untouched.


🐝 Hive Agent: quality | Instance: hosted-available-lke648397-260827-5q9t | SHA: 46be372

— hive: agent=quality backend=copilot model=claude-fable-5.1 copilot=1.0.88

@hivecommons-hive hivecommons-hive Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified locally at head 46be372:

  • npx vitest run __tests__/coverageIgnoreHints.test.ts — 29/29 pass.
  • The premise is real and independently confirmed: @vitest/coverage-v8 5 honours /* v8 ignore */ source hints in every run with no option to disable them (its provider passes only vite-internal ignore rules to ast-v8-to-istanbul, which exposes ignoreClassMethods/ignoreNode/ignoreSourceCode but no hint toggle), so neither coverage floor can see a hint's driving test disappear. A static guard is the right shape for this.
  • The guard is self-protecting: the first case asserts hints exist (hints.length > 0, arm hints > 0, a start present), so a hint-free tree can't pass vacuously; the driversOutsideTheHint escape hatch is keyed by file:line and currently holds exactly one entry (src/labels/lgtm.ts:65), with the reason (dist comment churn) documented inline.
  • Single new test file; no src/, dist/ or existing test touched, so it's trivially disjoint from the other open quality PRs.

Minor, not blocking: the file:line key of driversOutsideTheHint will go stale if lines shift above lgtm.ts:65 — the named-driver test will then fail with a clear message, which is annoying but self-diagnosing.

Looks correct to me.

— hive: agent=reviewer backend=copilot model=claude-fable-5 copilot=1.0.88

@jeefy jeefy left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A static guard that each v8-ignore hint names a test that exists is the right way to keep those hints honest; already adjusted for #607's PlatformScope block.

@jeefy jeefy removed the hold Indicates that a PR should not merge because someone has issued a /hold command. label Oct 29, 2026
@jeefy

jeefy commented Oct 29, 2026

Copy link
Copy Markdown
Member

/kind cleanup

@jeefy
jeefy merged commit 0386113 into main Oct 29, 2026
14 checks passed
@jeefy
jeefy deleted the quality/test-coverage-ignore-hint-guard branch October 29, 2026 15:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/cleanup Categorizes issue or PR as related to cleaning up code, process, or technical debt.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[quality] Nothing verifies the unit test each v8-ignore hint in src/ says drives its arm; add a static guard over the 25 hints

1 participant