Skip to main content

Testing and Quality

We use multiple layers of checks so that both human and AI changes stay safe and consistent. Nothing is merged without passing these gates.

Unit tests (Vitest)

  • Where: *.spec.ts next to source under src/.
  • Run: pnpm test (or pnpm test:watch).
  • Conventions: Colocated tests; use *.factory.ts for model fixtures; no inline DB object construction. Rules enforce this so the assistant doesn’t skip tests or invent ad-hoc data.

E2E tests (Vitest)

  • Where: e2e/ with a separate Vitest config.
  • Run: pnpm run e2e (or pnpm e2e:watch).
  • Purpose: End-to-end flows (e.g. API + DB + AdminJS) to catch integration breakage. Pre-commit and CI run these.

Contract tests

  • Where: Contract specs and harness in e2e/ (e.g. adminjs-mongoose contract).
  • Run: pnpm test:contracts; coverage check via pnpm check:contracts-coverage.
  • Purpose: Ensure adapters and integrations satisfy defined contracts so refactors don’t silently break assumptions.

Lint (ESLint)

  • Run: pnpm lint.
  • Purpose: Enforces import boundaries (ports/adapters/types), style, and project-specific rules. Runs in lint-staged and CI.

Typecheck (TypeScript)

  • Run: pnpm typecheck.
  • Purpose: Ensures the codebase compiles with strict typing. Runs in pre-commit and CI.

Cycle detection

  • Run: pnpm check:cycles.
  • Purpose: Ensures no circular dependencies under src/. Run before pushing; CI can run it as well.

Semgrep

  • Run: pnpm semgrep (scan) or pnpm semgrep:ci (fail on findings).
  • Purpose: Security and bug-pattern scanning. Pre-commit requires Semgrep; CI uses semgrep:ci so the main branch stays clean.

Pre-commit (Husky)

The pre-commit hook runs in parallel where possible:

  1. Lint-staged — Format and lint on staged files.
  2. Typecheck — Full project typecheck.
  3. Test — Unit tests.
  4. Contract coverage — Verify dependency contract tests.
  5. Semgrep — Security scan.
  6. E2E — End-to-end tests.

If any step fails, the commit is blocked. We do not use --no-verify to skip; see the git-commit-safety rule. This keeps every commit on a branch in a state that CI can reproduce.

Order of operations

Recommended local order before pushing: pnpm typecheckpnpm lintpnpm testpnpm run e2epnpm check:cycles. The same checks (plus docs build) run in CI so the branch is merge-ready when green.