Skip to content

Testing

OpenCodeHub has three test surfaces. Each runs at a different cadence and covers a different level of the stack. This page is the map.

Every TypeScript package has its own test script that runs the Node.js test runner against compiled output:

Terminal window
pnpm -r test

Conventions:

  • Test files live alongside source as *.test.ts.
  • tsc compiles them into dist/**/*.test.js.
  • Each package’s test script is node --test './dist/**/*.test.js' (or close — check packages/<pkg>/package.json for the exact form).
  • No Jest, no Vitest. The stdlib test runner keeps the dev dependency surface small and Apache-2.0 clean.

mise run test runs the full matrix after a build. The pre-push lefthook hook runs the same command, so you usually catch failures before CI does.

Any time you touch code under packages/*/src/. Fixtures live in packages/<pkg>/test/fixtures/. The parseFixture helper in packages/ingestion (see Adding a language provider) is the standard tool for ingestion-side assertions.

scripts/smoke-mcp.sh boots the stdio MCP server, sends initialize + tools/list, and asserts that the advertised tool count matches EXPECTED_TOOLS. Run it directly or via:

Terminal window
mise run smoke:mcp

The expected tool count is 29 (packages/mcp/src/server.ts). If your fork drifts from that number, set EXPECTED_TOOLS=<n> to match.

Acceptance gates — v1.0 Definition of Done

Section titled “Acceptance gates — v1.0 Definition of Done”

scripts/acceptance.sh runs the v1 Definition-of-Done gates. Mandatory gates fail the run; soft gates log timings or skip when a dependency binary is missing and do not change the exit code.

Terminal window
mise run acceptance
GateWhat it checksSoft?
1pnpm install --frozen-lockfileno
2pnpm -r buildno
3pnpm -r testno
4banned-strings sweepno
5license allowlistno
6determinism — double-run graphHash identicalno
7incremental reindex timings (5-run p95, logged only)soft
8MCP stdio boot + tools/listno
9MCP server end-to-end harness — minimum case-pass floorno
10embeddings determinism (skipped if model weights absent)soft
11100-file fixture incremental timing (5-run p95, logged only)soft
12scanner smoke — codehub scan --scanners semgrep emits SARIFno
13SARIF Zod-schema validationno
14license-audit smoke via the MCP toolno
15verdict smoke on a 2-commit fixtureno

Run acceptance before opening a PR that touches the analyze pipeline, storage, the MCP server, or anything else called out in Dev loop / When to run acceptance.

The SCIP indexer regression tests run via .github/workflows/gym.yml on every PR that touches packages/scip-ingest, packages/ingestion, or the frozen corpus. Pinned indexer versions live in the same workflow file (ADR 0006). A drift in any indexer’s output against the frozen baseline fails the PR.

Every failure — a lint warning, a flaky eval, a soft acceptance gate that turned hard because a binary became available — is a blocker until it is fixed or explicitly waived. See the tenets block.

  • scripts/acceptance.sh — the v1 Definition-of-Done runner.
  • scripts/smoke-mcp.sh — MCP boot smoke.
  • .github/workflows/{ci,gym}.yml — CI workflows.