Skip to content

Commit 1ae81a1

Browse files
nganclaude
andcommitted
Document coders, FK verification, and PK sequence reset in reference
Reflects v0.15.0 (Coder concept + register API) and v0.16.0 (FK verification gate, batched + per-table sequence reset) in the canonical in-repo reference. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 1b77b3a commit 1ae81a1

1 file changed

Lines changed: 57 additions & 1 deletion

File tree

docs/reference.md

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ Canonical API, configuration, and contract reference.
77
- **Definition**: `FixtureKit.define { ... }` returns a `FixtureKit::Definition`.
88
- **Fixture**: wraps an identifier and a definition; handles cache save/mount.
99
- **Cache**: persists and replays SQL for touched models.
10+
- **Coder**: decides what gets cached during generate and how to replay it on mount. `FixtureKit::ActiveRecordCoder` is registered by default; additional coders can be registered to capture state outside ActiveRecord.
1011
- **Repository**: exposes records via methods, loaded lazily and memoized per test.
11-
- **Runner**: owns configuration, registry, startup state, and adapter instance.
12+
- **Runner**: owns configuration, registry, startup state, and adapter and coder instances.
1213

1314
## Framework Entrypoints
1415

@@ -176,6 +177,61 @@ Default values:
176177
`config.callbacks`
177178
- Returns callback registry (`FixtureKit::Callbacks`).
178179

180+
`config.coders`
181+
- Returns the registered coder classes as a `Set`.
182+
- Default: `Set.new([FixtureKit::ActiveRecordCoder])`.
183+
184+
`config.register(coder_class)`
185+
- Adds a coder class to the registered set. Coder instances are created lazily once per runner and reused across fixtures.
186+
187+
## Coder Contract
188+
189+
Subclass `FixtureKit::Coder` and implement:
190+
191+
`#generate(parent_data: nil, &block)`
192+
- Called once when fixture cache is being built.
193+
- Set up observation, then call the block to evaluate the user's fixture definition (and any inner coders).
194+
- Return data to be cached for this coder. Will be passed to `#encode` before serialization.
195+
- `parent_data` is the cached data from the same coder on the parent fixture when `extends:` is used; `nil` otherwise.
196+
197+
`#mount(data)`
198+
- Called once per test mount with the data this coder produced. Re-create the state on the test database.
199+
200+
`#encode(data)`
201+
- Convert the in-memory representation produced by `#generate` to a JSON-serializable form. Default: identity.
202+
203+
`#decode(data)`
204+
- Inverse of `#encode`. Default: identity.
205+
206+
Coder registration:
207+
208+
```ruby
209+
FixtureKit.configure do |config|
210+
config.register(MyCoder)
211+
end
212+
```
213+
214+
Chain semantics:
215+
- Coders form a chain; outer coders wrap inner coders' generate blocks.
216+
- The innermost block is the user's `FixtureKit.define` body.
217+
- Order is determined by registration; `ActiveRecordCoder` is registered first by default.
218+
219+
## Foreign Key Verification
220+
221+
When `ActiveRecord.verify_foreign_keys_for_fixtures` is `true` (Rails default since 8.0 `load_defaults`), `FixtureKit::ActiveRecordCoder#mount` calls `connection.check_all_foreign_keys_valid!` after replaying cached statements. A violation raises `FixtureKit::Error` with a stale-cache hint.
222+
223+
- PostgreSQL and SQLite implement the check.
224+
- MySQL inherits the abstract no-op.
225+
226+
## Primary Key Sequence Reset
227+
228+
After replaying cached INSERTs, `FixtureKit::ActiveRecordCoder#mount` resets the primary key sequence for each touched table:
229+
- Rails 8.2+: `connection.reset_column_sequences!(tables)` in one batched call per connection.
230+
- Rails 8.0/8.1: per-table `connection.reset_pk_sequence!(table)`.
231+
- Adapters that expose neither (MySQL, SQLite): skipped — their PK generators advance from explicit-id INSERTs.
232+
233+
This prevents `PG::UniqueViolation` when fixtures are mounted onto a database whose sequence is at its initial value (e.g., parallel test workers with their own DB copies).
234+
179235
## Adapter Contract
180236

181237
Subclass `FixtureKit::Adapter` and implement:

0 commit comments

Comments
 (0)