# Testing For this library the types _are_ the feature, so a runtime-only test loop would verify the wrong thing. The commands are in [CONTRIBUTING.md](../CONTRIBUTING.md); this file records why the loop is shaped the way it is. ## Type-driven development The rules — the loop and the pairing rule — are in [CONTRIBUTING.md § Testing discipline (type-driven)](../CONTRIBUTING.md#testing-discipline-type-driven). What follows is why and what was rejected. #### Decision (2026-09) The compile-time expectation is written before the runtime assertion, and both before the implementation. #### Why - A runtime-only test can pass while the type is wrong, so a type-level library would ship a broken feature its tests bless. - The type error is a more precise spec than a failing assertion, because it states the exact expected type before the logic exists. #### Rejected - Runtime-first (classic red/green): it verifies the value, not the contract, and the contract is the product. - Testing the type only: it would not catch handler wiring, `exhaustive()` throwing, or the `otherwise` fallback (see `src/index.test.ts`). The runner is `node --test --strip-types "src/**/*.test.ts"` and the tiers are in [CONTRIBUTING.md § Development commands](../CONTRIBUTING.md#development-commands). `c8` uses V8 coverage, so the `--strip-types` source is instrumented without a build step, and the runner relies on the `.ts` import-extension convention (see [tooling.md](./tooling.md#source-imports-use-ts-extensions)). ## Known issues - The type-aware linter misidentifies `expectTypeOf()` as a floating promise, so `src/index.test.ts` carries a file-level `oxlint-disable typescript/no-floating-promises` with an explanatory comment. It is a known false positive, not a rule worth disabling project-wide (see [tooling.md § oxlint-disable directives live next to the code](./tooling.md#oxlint-disable-directives-live-next-to-the-code)).