Initial Commit
This commit is contained in:
62
openspec/archive/2026-04-19-enterprise-testing/proposal.md
Normal file
62
openspec/archive/2026-04-19-enterprise-testing/proposal.md
Normal file
@@ -0,0 +1,62 @@
|
||||
## Why
|
||||
|
||||
`@suaveplan/testing` is the shared test infrastructure every other `@suaveplan/*` package imports from. As Layer 0 in the genesis dependency graph (zero `@suaveplan/*` workspace deps — rule #9 of `openspec/project.md`), every package downstream depends on it. Enterprise-quality testing unblocks enterprise quality everywhere else.
|
||||
|
||||
The enterprise specification at `/mnt/s/web/suaveplan/enterprise/testing.md` sets the bar; this change translates that spec into genesis form, **preserving the full public surface** established in the archived `2026-04-08-testing-libraries` change (RequestBuilder, ResponseBuilder, FakeClock, Factory, FixtureManager, MemoryStore, helpers, dual-runner conditional exports, `createTestConfig` — full inventory in `design.md`) while upgrading internals to enterprise grade.
|
||||
|
||||
This is the first implementation change on the `genesis` branch. There is no prior genesis code to audit — the "current state" is empty. Design intent comes from the enterprise doc; surface intent comes from the existing implementation on `main` at `/mnt/s/web/suaveplan/packages/universal/testing/src/`.
|
||||
|
||||
## What Changes
|
||||
|
||||
All requirements from `enterprise/testing.md` §3 are carried forward, with **four explicit substitutions** forced by genesis rule #9 (testing packages may not depend on any `@suaveplan/*` workspace package). Each substitution is called out inline below.
|
||||
|
||||
### Carried forward verbatim
|
||||
|
||||
- **Universal purity** — zero browser/Node/React deps in `src/`. Runs in Bun, Node, and modern browsers. Enforced by a tree-shake test that inspects the built bundle.
|
||||
- **Zod schemas** for all public function inputs and outputs, exported from sibling `*.schemas.ts` files alongside each implementation file. Zod is an **external catalog dep** (`catalog:forms`), not routed through `@suaveplan/schema-registry`.
|
||||
- **Property-based tests (fast-check)** for pure functions (clock arithmetic, builder composition, factory deterministic output given fixed RNG, memory-store TTL math, semver-ish helpers).
|
||||
- **Deterministic behaviour** — no `Math.random()` / `Date.now()` / `performance.now()` at module scope. Every function that reads time or randomness accepts an optional `{ clock?, rng?, signal? }` options parameter. Zero-config defaults preserved.
|
||||
- **Backpressure & cancellation** — `AbortSignal` on every iterative / async helper (`waitFor`, `FixtureManager.setupAll/teardownAll`, `Factory.build` in batch mode, `MemoryStore` eviction sweeps), checked at bounded intervals (≤ 256 items or ≤ 1 KB).
|
||||
- **Idempotency & retry primitives** wired for any helper with network-ish retry semantics (e.g. `waitFor` polling).
|
||||
- **Feature flags** — any risky new behaviour gated behind an options flag with safe defaults.
|
||||
- **Structured errors** with stable codes of the form `TESTING.<DOMAIN>.<REASON>` (e.g. `TESTING.CLOCK.MAX_TIMERS_EXCEEDED`, `TESTING.FIXTURES.SETUP_FAILED`). Every thrown error carries `{ code, cause?, context? }`.
|
||||
- **Benchmarks** via `mitata` (external catalog dep) under `src/__benchmarks__/<domain>.bench.ts`, baseline in `benchmarks/baselines.json`, CI gate at 10% regression floor.
|
||||
- **Plugin / extension interface** — `FixtureManager` accepts plugins implementing `beforeEach/afterEach/onError` hooks; `Factory` accepts `traits` that downstream packages can contribute without forking.
|
||||
- **Observability surface** — counters, histograms, spans for every public entrypoint. Gated: no-op when no OTEL SDK is registered; live when one is. Useful for diagnosing flaky test environments in CI without touching test source.
|
||||
- **Security** — input validation at the boundary via Zod, no prototype-pollution vectors in `MemoryStore`, dependency audit clean.
|
||||
- **Migration story** — N/A; genesis starts fresh at version `0.1.0`.
|
||||
- **Example / story** — `examples/` directory with runnable usage of each public entrypoint.
|
||||
|
||||
### Substitutions (enterprise-doc → genesis form)
|
||||
|
||||
| Enterprise doc requires | Genesis substitution | Why |
|
||||
|---|---|---|
|
||||
| Errors extend `@suaveplan/error` | Local `TestingError extends Error` with the same `{ code, cause, context }` shape, stable `TESTING.<DOMAIN>.<REASON>` codes | Rule #9 — can't take `@suaveplan/*` deps. Shape-compatible so a future `@suaveplan/error` adapter can bridge without API change. |
|
||||
| OTEL via `@suaveplan/opentelemetry` | `@opentelemetry/api` (external, ~2 KB, no transitive Node deps). Spans/counters/histograms created via the standard API, no-op without a registered SDK | Rule #9. `@opentelemetry/api` is the canonical public API spec; the internal package will wrap this at a later layer. |
|
||||
| Schemas via `@suaveplan/schema-registry` | `zod` direct (catalog:forms). Schemas exported from `*.schemas.ts` under stable names (e.g. `BuilderSchemas.request.input`) so a future `schema-registry` adapter can enumerate them | Rule #9. |
|
||||
| Clock via `@suaveplan/datetime` | Local `Clock` interface in `src/context/context.ts`: `{ now(): number; hrtime(): bigint }`. `defaultClock` reads `Date.now()` / `performance.now()` directly. `FakeClock` implements the same interface. | Rule #9. |
|
||||
| i18n via `@suaveplan/i18n` or hard-coded message keys | English-only `message` fields. `code` is the machine contract; `message` is developer-facing. Matches the utils D10 precedent. | Rule #9. Test helpers emit messages to developers in logs, not to end users. |
|
||||
|
||||
### Public surface preserved
|
||||
|
||||
Every export enumerated in `design.md` §Surface Inventory is retained unchanged in shape. Internals are rewritten; signatures gain the optional `{ clock?, rng?, signal? }` options parameter where appropriate (purely additive — zero-config callers are unaffected).
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `testing`: shared test infrastructure for the genesis monorepo — test primitives (vitest + bun-test conditional export), mock API, request/response builders, FakeClock, Factory, FixtureManager, MemoryStore, async helpers, vitest config factory, polyfills. Layer 0 leaf.
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
(none — genesis has no prior spec)
|
||||
|
||||
## Impact
|
||||
|
||||
- **Affected code:** `/mnt/s/web/genesis/packages/universal/testing/**` (fresh implementation).
|
||||
- **Affected consumers:** none on genesis yet; every subsequent genesis package depends on this one.
|
||||
- **Version:** `0.1.0` (genesis baseline; no bump until graduation cut).
|
||||
- **Catalogs added / extended in root `package.json`:** `zod` to `catalogs.forms`, `@opentelemetry/api` to a new `catalogs.observability`, `fast-check` and `mitata` to `catalogs.testing`.
|
||||
- **Root `package.json` `devDependencies` addition:** `@types/bun` already present; tooling catalogs unchanged.
|
||||
- **New capability spec:** `openspec/specs/testing/spec.md` (created on archive).
|
||||
- **Pre-publish gate:** full turbo `lint typecheck test` on `@suaveplan/testing` + istanbul coverage ≥ 95% before `bun scripts/publish.ts --package @suaveplan/testing`.
|
||||
Reference in New Issue
Block a user