Skip to content

feat(testing): D-8 honesty lint rules + error-only test-config severity#29

Merged
stevensacks merged 2 commits into
mainfrom
feat/d8-test-honesty-cheap-wins
Jun 25, 2026
Merged

feat(testing): D-8 honesty lint rules + error-only test-config severity#29
stevensacks merged 2 commits into
mainfrom
feat/d8-test-honesty-cheap-wins

Conversation

@stevensacks

@stevensacks stevensacks commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

D-8 test-honesty lint rules + error-only test-config severity

Rebased onto current main (carries the #28 pnpm 11 migration + dep refresh). Ships two test-honesty rules built from stock tooling (no custom plugins) plus a severity cleanup, all in the test-related config blocks.

Rules (all error)

  • vitest/prefer-called-with — a bare toHaveBeenCalled()/toBeCalled() proves a function ran but asserts nothing about arguments or count; require the *With form. Exempts .not. (Stands in for D-8 Rule 3 no-call-through-only; broader than the spec — fires on every bare call, not only sole-assertion ones.)
  • no-restricted-imports in test/story/harness files — consumer tests may not import a server-only (*.server) or internal (**/internals/**) module; reach behavior through the public interface. *.server.test.* is exempt. Static import/export … from only, not dynamic import(). (Stands in for D-8 Rule 4 no-server-import-from-consumer.)
  • playwright/expect-expect promoted warnerror — a Playwright test that asserts nothing is a false green. Custom expect*() helpers still count via assertFunctionPatterns.

Severity: error-only

Per GAIA's "everything is error, never warn" philosophy. A warn under a consumer's --max-warnings=0 is already blocking, so a "non-blocking" warn is a fiction the main consumer never sees. The prior "ship Rule 3 as warn to observe before promoting" rationale is dropped.

GAIA blast radius (dogfooded)

  • Rule 3: 2 trivial sites (Button/tests/index.test.tsx:15, useComponentRect.test.ts:57).
  • Rule 4: 0 — the one *.server import in a test is in a correctly-named *.server.test.ts (exempt).
  • playwright/expect-expect: already enforced as blocking via --max-warnings=0; GAIA passes, so 0 new.

Known gap (tracked separately, not in this PR)

Rule 4 fires under ruleId no-restricted-imports. GAIA's worthiness gate cross-checks D-8 by the frozen gaia-test-honesty/* suffixes and can't attribute a generic no-restricted-imports, so its rule-4 cross-check stays inert (graceful, non-regressive). Reconciliation (retire the two suffixes, or build the custom rules) is a follow-up GAIA-side change.

Verify

pnpm install / typecheck / lint / build all green. Changeset added (minor).

🤖 Generated with Claude Code

stevensacks and others added 2 commits June 25, 2026 13:53
Adds the existing-tool equivalents of SPEC-006 / D-8 Rules 3 and 4 to the
testing flat-config block. Custom Rules 1 and 2 are deliberately shelved.

Rule 3 (no-call-through-only) -> enable vitest/prefer-called-with at `warn`,
the one documented exception to the every-rule-is-error policy (D-8 / R-8:
ships non-blocking until scoping is observed and a human confirms a true
positive). prefer-called-with is broader than spec Rule 3: it fires on every
bare toHaveBeenCalled()/toBeCalled() except the .not form, not only the
sole-assertion shape, so it stands in for Rule 3 rather than matching it.

Rule 4 (no-server-import-from-consumer) -> a sibling no-restricted-imports
config block (core rule, no custom code) forbidding *.server and /internals/
imports from test/story/harness files, with a *.server.test.* filename
exemption via `ignores`. Chosen over import-x/no-restricted-paths because the
rule keys off the import specifier shape plus a per-file exemption, not
directory zones. Static import/export-from only; dynamic import() is out of
scope for this cheap-win form.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Promote every test-config lint severity to error, per GAIA's "everything is
error, never warn" philosophy: a warn under a consumer's --max-warnings=0 is
already blocking, so a "non-blocking" warn is a fiction the main consumer
never sees.

- vitest/prefer-called-with: warn -> error (drop the observe-before-promote
  rationale; it does not hold under --max-warnings=0).
- playwright/expect-expect: warn -> error (a test that asserts nothing is a
  false green; custom expect*() helpers still count via assertFunctionPatterns).

Add the changeset for the D-8 test-honesty rules + this severity change (minor).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@stevensacks stevensacks force-pushed the feat/d8-test-honesty-cheap-wins branch from 2564c5c to e0bb2f9 Compare June 25, 2026 04:57
@stevensacks stevensacks changed the title feat(testing): D-8 honesty cheap-win lint rules (prefer-called-with + no-restricted-imports) feat(testing): D-8 honesty lint rules + error-only test-config severity Jun 25, 2026
@stevensacks stevensacks marked this pull request as ready for review June 25, 2026 04:57
@stevensacks stevensacks enabled auto-merge (squash) June 25, 2026 04:58
@stevensacks stevensacks merged commit e7a2232 into main Jun 25, 2026
1 check passed
@stevensacks stevensacks deleted the feat/d8-test-honesty-cheap-wins branch June 25, 2026 04:58
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