= test-fixtures

== purpose

Shared test fixture library providing reusable mock implementations, factory functions, and test doubles for all Correx testing modules. Reduces duplication and ensures consistent test setup across the project.

== responsibilities

* Provide factory functions for constructing `NewEvent`, `StoredEvent`, and domain events with minimal boilerplate
* Provide mock inference provider (`MockInferenceProvider`) with configurable behavior (fixed response, delay, forced failure)
* Provide mock tokenizer (`MockTokenizer`) with deterministic character-based token counting
* Provide test tool implementations (`EchoTool`, `FailingTool`, `RejectedTool`) at different tier levels
* Provide mock event replayers and session repositories for kernel tests
* Provide workflow graph fixtures (`simpleGraph`, `threeStageGraph`)
* Provide approval fixtures (approval request factory, cycle policy validator)
* Provide cycle detection fixtures
* Provide context compression fixtures (no-op compressor, simple builder)
* Provide inference fixtures (fixed router, failing router, context pack, generation config)

== non-responsibilities

* Does not contain any test assertions or test cases (except `MockToolsTest` which validates the tools themselves)
* Does not provide mocks for infrastructure adapters (SQLite, HTTP, etc.)
* Does not provide full in-memory event store replacement

== key types

=== EventFixtures
* **kind**: object
* **purpose**: Factory methods `newEvent()` and `stored()` that produce `NewEvent` and `StoredEvent` instances with sensible defaults. Reduces boilerplate in event-sourcing tests.

=== MockInferenceProvider
* **kind**: class
* **purpose**: Configurable fake `InferenceProvider`. Three mutually exclusive modes: `fixedResponse` (returns immediately), `artificialDelayMs` (suspends before responding), `forcedFailure` (throws). Tracks `inferCallCount`.

=== MockTokenizer
* **kind**: class
* **purpose**: Character-based `Tokenizer` approximation: 1 token ≈ 4 characters. Deterministic and not model-accurate. Suitable for contract and budget tests.

=== EchoTool / FailingTool / RejectedTool
* **kind**: classes implementing `Tool`
* **purpose**: Test tools at tiers T0, T2, and T4 respectively. `EchoTool` validates successfully, `FailingTool` fails validation, `RejectedTool` validates but is configured for rejection.

=== MockEventReplayer / MockSessionRepository
* **kind**: classes
* **purpose**: Test doubles for kernel module dependencies. Return pre-configured or default states by session ID.

=== InferenceFixtures
* **kind**: object
* **purpose**: Factory methods for `InferenceProvider`, `InferenceRouter`, `InferenceRequest`, `InferenceResponse`, `ContextPack`, `GenerationConfig`.

=== ApprovalFixtures
* **kind**: top-level functions
* **purpose**: `request()` factory for `DomainApprovalRequest`; `cyclePolicyMissingValidator()` for validation pipeline tests.

=== WorkflowFixtures
* **kind**: object
* **purpose**: `simpleGraph()` factory creating a two-stage A->B workflow graph.

=== TransitionFixtures
* **kind**: object
* **purpose**: `alwaysTrueEvaluator()`, `simpleResolver()`, `threeStageGraph()` for transition resolution tests.

=== CycleFixtures
* **kind**: object
* **purpose**: `simpleCycle()` for cycle detection tests.

=== ContextFixtures
* **kind**: object
* **purpose**: `simpleCompressor()` (no-op) and `simpleBuilder()` for context builder tests.

== event flow

Not applicable — this module provides construction helpers, not event processing.

== integration points

* `:core:events` — `EventPayload`, `NewEvent`, `StoredEvent`, `EventMetadata`
* `:core:inference` — `InferenceProvider`, `InferenceRouter`, `InferenceRequest`, `InferenceResponse`, `Tokenizer`
* `:core:tools` — `Tool` interface, `Tier`
* `:core:approvals` — `DomainApprovalRequest`, domain approval types
* `:core:transitions` — `WorkflowGraph`, `TransitionResolver`, `TransitionConditionEvaluator`
* `:core:context` — `ContextPack`, `ContextCompressor`, `DefaultContextPackBuilder`
* `:core:sessions` — `SessionState`, `EventReplayer`
* `:core:kernel` — `OrchestrationState`
* `:core:validation` — `Validator`, validation model types

== invariants

* `MockTokenizer.tokenize("")` returns empty list; `countTokens("")` returns 0
* `MockTokenizer` uses 4-char chunking — `countTokens("abcd")` = 1, `countTokens("abcde")` = 2
* `EventFixtures.stored()` defaults to `sessionSequence = sequence` (1:1 mapping)
* `MockInferenceProvider.inferCallCount` increments atomically per call

== PlantUML diagram

[plantuml, test-fixtures, "png"]
----
include::../../diagrams/test-fixtures.puml[]
----




== known issues

* `MockTokenizer` is not model-accurate — tests using it for token budgets may pass with the mock but fail with a real tokenizer
* `EventFixtures.stored()` sets `sessionSequence = sequence` by default, which may not match production behavior where sequences diverge after resets or gaps

== open questions

* Should `MockInferenceProvider` support streaming response simulation?
* Should the fixtures include an in-memory event store implementation for tests?
