Initial Commit
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
# OpenSpec Change: testing-spec-conformance
|
||||
|
||||
- **Change ID**: testing-spec-conformance
|
||||
- **Package**: `@suaveplan/testing`
|
||||
- **Status**: PROPOSED
|
||||
- **Date**: 2026-04-26
|
||||
|
||||
## Summary
|
||||
|
||||
Close five drift items uncovered by `bun scripts/openspec-conformance.ts @suaveplan/testing`:
|
||||
|
||||
1. `**Verified by:**` lines on every requirement in `openspec/specs/testing/spec.md` (15 reqs, all owned by this package).
|
||||
2. Thread a `<TBody = unknown>` generic through `RequestBuilder`, `ResponseBuilder`, `TestRequest`, `TestResponse`, and the corresponding `*BuilderState` types so consumers can pin the body type at the call site instead of the public d.ts leaking five `: unknown` positions.
|
||||
3. Add a `tests/spec-conformance.spec-conformance.test.ts` pinning the new generic threading via `expectTypeOf`, the dual-runner / sideEffects / subpath-export package-shape assertions, the schemas-leaf-isolation check, and the module-scope determinism scan (`Math.random` / `Date.now` / `performance.now` allow-list).
|
||||
4. Replace the wall-clock fallback in `measureTime` and `withObservability` with the existing injectable `Clock` substrate (`defaultClock` by default, `FakeClock` when injected). Removes the last two non-deterministic call sites in `src/` outside the allow list.
|
||||
5. Tighten `scripts/openspec-conformance.ts`: stop matching change folders by token-substring on the folder name (which over-matched 226 reqs across `enterprise-testing-dom`, `enterprise-testing-e2e`, `enterprise-ab-testing`, `enterprise-network-testing`, etc.). Match only via `**Package**: @suaveplan/<pkg>` in `proposal.md` frontmatter, and only pull active-change `specs/<cap>/spec.md` deltas from changes whose proposal explicitly names this package.
|
||||
|
||||
After this change, `bun scripts/openspec-conformance.ts @suaveplan/testing` exits 0.
|
||||
|
||||
## Current state
|
||||
|
||||
`@suaveplan/testing` is structurally solid (Layer 0, zero `@suaveplan/*` workspace deps, 295 passing tests, structured `TestingError` hierarchy with stable `TESTING.<DOMAIN>.<REASON>` codes, dual-runner subpath exports, `sideEffects: false`, fast-check property tests, mitata bench harness). Conformance gaps are documentary plus two real drift items:
|
||||
|
||||
- 35/35 requirements lacked `**Verified by:**` lines (down from 226 once the conformance script's over-matching was fixed).
|
||||
- 5 public d.ts positions resolved to `: unknown` (`request-builder.types.d.ts`, `response-builder.types.d.ts`, `http.types.d.ts` x2, `fixture-manager-internals.d.ts`).
|
||||
- 2 wall-clock fallback sites (`measureTime`, `withObservability`) bypassed the `Clock` substrate documented by the spec's "Module-scope non-determinism absent" scenario.
|
||||
- The conformance script over-matched on folder-name tokens, pulling in unrelated `testing-*` change folders.
|
||||
|
||||
## What changes
|
||||
|
||||
1. Add `**Verified by:**` lines under every `### Requirement:` block in `openspec/specs/testing/spec.md`. Citations name real `it(...)` test titles in `src/**/*.test.ts` and `tests/*.test.ts`.
|
||||
2. Thread `<TBody = unknown>` through `RequestBuilder`, `ResponseBuilder`, `RequestBuilderState`, `ResponseBuilderState`, `TestRequest`, and `TestResponse`. Default generic preserves the existing `unknown` surface for zero-config callers.
|
||||
3. Add `tests/spec-conformance.spec-conformance.test.ts`:
|
||||
- `expectTypeOf` assertions over `RequestBuilder<UserPayload>` / `ResponseBuilder<UserPayload>` so the generic threading regresses loudly.
|
||||
- `package.json` shape: `sideEffects === false`, every public surface has a subpath export.
|
||||
- Module-scope determinism: scan `src/` for `Math.random(` / `Date.now(` / `performance.now(` outside the allow list (`context`, `fake-clock`, `memory-store`).
|
||||
- Schema-bundle isolation: `*.schemas.ts` files do not import their sibling implementation file.
|
||||
4. `measureTime(fn, { clock })` and `withObservability({ ..., clock })` now route every wall-clock read through `defaultClock` (default) or a caller-supplied `Clock`. Behaviour identical for zero-config callers.
|
||||
5. `scripts/openspec-conformance.ts` swaps the folder-name token regex for a frontmatter check and only pulls active-change `specs/<cap>/spec.md` deltas from changes explicitly tagged `**Package**: @suaveplan/<pkg>`.
|
||||
|
||||
## Impact
|
||||
|
||||
- **Public API**: additive — `RequestBuilder`, `ResponseBuilder`, `TestRequest`, `TestResponse` gain an optional `<TBody>` generic with `unknown` default. `measureTime` and `withObservability` gain an optional `clock` option.
|
||||
- **Tests**: 7 new `it` blocks under `tests/spec-conformance.spec-conformance.test.ts`. Existing 295 tests unchanged.
|
||||
- **Spec**: 15 `**Verified by:**` lines folded into `openspec/specs/testing/spec.md`. Two stale `packages/universal/testing/` path references corrected to `packages/dev/testing/`.
|
||||
- **Tooling**: `scripts/openspec-conformance.ts` matching tightened. Affects every package's audit but downward-only (fewer false-positive folders).
|
||||
Reference in New Issue
Block a user