Files
tiny-pattern-ts/development/testing.md
T
tmu 7ea84b66fa ♻️ Drop the last duplicated prose from development/
The GitHub Flow description and the type-first enforcement sentence still
appeared in both CONTRIBUTING.md and development/. development/ now carries only
the context and rationale that is not in CONTRIBUTING.md.
2026-09-15 13:47:01 +00:00

2.1 KiB

Testing

For this library the types are the feature — narrowing, exhaustive() returns, the Matcher<T> contract — so a runtime-only test loop would verify the wrong thing. The contributor-facing commands are in 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). What follows is why the loop is type-driven and what was rejected.

Decision (2026-09)

Test-driven development is type-driven here: 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, and a type-level library would then ship a broken feature that 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 listed in CONTRIBUTING.md § Development commands. c8 uses V8 coverage, so the --strip-types source is instrumented without a build step. The runner relies on the .ts import-extension convention (see tooling.md).

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. This is a known false positive, not a rule we want off project-wide (see tooling.md § oxlint-disable directives live next to the code).