@rivus/agent-kit/testing/effect
aggregateRepositoryConformance: the conformance cases every aggregate repository passes — anywhere, with effect
Functions
aggregateRepositoryConformance()
function aggregateRepositoryConformance<Id, S extends object>(fixtures: AggregateRepositoryFixtures<Id, S>): AggregateRepositoryCase[];The checks every aggregate repository implementation must pass, independent of a test runner. Generic cases run for every implementation; the reopen case runs for a persistent one and the unknown-schema case for a storage that carries a schema version.
Type Parameters
Id
Id
S
S extends object
Parameters
fixtures
AggregateRepositoryFixtures<Id, S>
Returns
Interfaces
AggregateRepository
The part of an aggregate repository's calling convention that every aggregate shares: load reads the stored
snapshot or undefined, and save writes atomically only over the revision it is shown, failing with a
RevisionConflict-tagged error instead of writing when the stored revision differs. Aggregate-specific
operations, such as Lease's fence or Ledger's pre-image blobs, are outside this suite.
Type Parameters
Id
Id
S
S extends object
Methods
load()
load(id: Id): Effect<S | undefined, unknown>;Parameters
id
Id
Returns
Effect<S | undefined, unknown>
save()
save(
id: Id,
snapshot: S,
expectedRevision: number | undefined
): Effect<void, unknown>;Parameters
id
Id
snapshot
S
expectedRevision
number | undefined
Returns
Effect<void, unknown>
AggregateRepositoryCase
One named case; wire it into the test runner, for example for (const c of cases) it.live(c.name, () => c.run).
Properties
name
readonly name: string;run
readonly run: Effect<void, Error>;AggregateRepositoryFixtures
Type Parameters
Id
Id
S
S extends object
Properties
id
readonly id: Id;The id every case stores under.
open
readonly open: <A>(steps: readonly ((session: AggregateRepositorySession<Id, S>) => Effect<A, unknown>)[]) => Effect<readonly A[], unknown>;Runs steps against one fresh storage location: the first step's repository creates it, and each later step
opens the same location again after the previous repository has closed, as the next process would. A step whose
repository cannot open the location fails the whole call; the unknown-schema case reads that as the refusal.
Type Parameters
A
A
Parameters
steps
readonly ((session: AggregateRepositorySession<Id, S>) => Effect<A, unknown>)[]
Returns
Effect<readonly A[], unknown>
persistent
readonly persistent: boolean;Whether the storage outlives the repository; the suite then also runs the reopen case.
refusesUnknownSchemaVersion
readonly refusesUnknownSchemaVersion: boolean;Whether the storage carries a schema version that the repository refuses when it does not know it, so that the
sessions carry writeUnknownSchemaVersion; the suite then also runs the unknown-schema case. A storage without
a schema version, such as a process-local map, declares false.
sample
readonly sample: (revision: number) => S;The snapshot stored for revision; the suite stores successive samples under increasing revisions.
Parameters
revision
number
Returns
S
AggregateRepositorySession
One open repository over a storage location, with what the conformance cases reach for besides it.
Type Parameters
Id
Id
S
S extends object
Properties
repository
readonly repository: AggregateRepository<Id, S>;writeUnknownSchemaVersion?
readonly writeUnknownSchemaVersion?: () => Effect<void, unknown>;Bypassing the repository, replaces what the storage holds for the fixtures' id with a record of an unknown
schema version, as a newer version would leave it. Present only when the fixtures declare
refusesUnknownSchemaVersion.
Returns
Effect<void, unknown>