Package-level declarations

Types

Link copied to clipboard

What one caller may do with the aggregate of an AccessPolicySpec.

Link copied to clipboard

The aggregate an access policy is checked on, and the callers it is checked for (accessPolicySpec).

Link copied to clipboard
Link copied to clipboard

An event a command committed, with its stream's envelope: the aggregate aggregateId of tenantId at version, the commandId and requestId of the command that committed it, the request facts (headers) it carried, the operator it was sent in the name of (none for an anonymous caller) and its commitTime in epoch milliseconds, the time of the specification's clock. body is the event itself.

Link copied to clipboard
class Expectations<S : Any> @InternalWowApi constructor(model: AggregateModel<S>, codec: EventCodec, result: Result<CommandOutcome>, version: Int, stateAt: (Int) -> S, forker: (String, AggregateModel<S>?, AggregateSpec<S>.() -> Unit) -> Unit)

The checks of a command's outcome, or of the exception its decide function threw (expectError). version is the aggregate's version after the command and stateAt reads its committed state at a version: expectState reads the state the aggregate is in after a command that committed nothing.

Link copied to clipboard

A failure in a AggregateSpec.fork, which names the fork and, for a failing check of a command, the step and the command: In fork "paid", whenCommand(ShipOrder) (command-4): Expected ….

Link copied to clipboard

An aggregate a processor reads, as ProcessorSpec.givenAggregate gave it: its model replays its history, one commit per event, to the state and version it is at. ProcessorSpec.whenEvent hands over its next commit, and the aggregate is then at it: the next one comes after it, and ProcessorSpec.whenRedelivered and ProcessorSpec.whenDeliveredLate hand it again. A fork of the specification advances a copy of its own, which ProcessorSpec.whenEvent still finds by the aggregate's ref.

Link copied to clipboard

The checks of one handling by a ProcessorSpec: the handlers that were called (handled), the commands they derived (commands), among them the schedules they set or cancelled (schedules), or what one of them threw (expectError). The steps that follow a saga's handling go on from its checks: the rejection (whenRejected) or the receipt (whenCommitted) of a command it derived, in place or in a fork.

Link copied to clipboard

Calls the handlers of one processor of kind as the runtime would, one commit or receipt at a time.

Link copied to clipboard

The job instances of a scheduleSpec and the handlers of their jobs.

Link copied to clipboard

The ids the test DSL gives domain code, the same on every run: the n-th global id is id-n, the n-th id of an aggregate type is <aggregate>-n (order-1, order-2), each counted from 1.

Link copied to clipboard
annotation class WowTestDsl

The scopes of the test DSL: within a block, only the members of its own receiver are in reach without naming it, so an expectation block never calls the specification around it by accident. What a follow-up step needs is a member of the expectations themselves (ProcessorExpectations.whenRejected, ProcessorExpectations.fork).

Properties

Link copied to clipboard

The id of the aggregate AggregateSpec.givenReservation gives a key to by default.

Link copied to clipboard

Where the time of an aggregateSpec starts by default.

Link copied to clipboard

The tenant a specification's aggregates are in by default, the default tenant of a caller (Caller.DEFAULT_TENANT): that of aggregateSpec, ScheduleSpec's instances and ProcessorSpec.givenAggregate.

Functions

Link copied to clipboard
fun <S : Any> accessPolicySpec(model: AggregateModel<S>, policy: AccessPolicy<S>, block: AccessPolicySpec<S>.() -> Unit)

Checks the access policy of model's aggregates: given an aggregate (its events, or its state), whether a caller may read it and change it, as the kernel and the queries decide (the access attributes the state derives, the built-in owner and space its scope's).

Link copied to clipboard
fun <S : Any> aggregateSpec(model: AggregateModel<S>, id: String = "aggregate-1", caller: Caller? = null, tenantId: String = caller?.tenantId ?: DEFAULT_TENANT, start: Instant = DEFAULT_START, block: AggregateSpec<S>.() -> Unit)

Specifies an aggregate's behaviour as given events, a command and the expected outcome, against the real kernel and an in-memory log:

Link copied to clipboard
fun <S : Any> aggregateSpecTests(model: AggregateModel<S>, id: String = "aggregate-1", caller: Caller? = null, tenantId: String = caller?.tenantId ?: DEFAULT_TENANT, start: Instant = DEFAULT_START, block: AggregateSpec<S>.() -> Unit): Stream<DynamicNode>

The specification aggregateSpec runs, as a tree of tests for a JUnit @TestFactory: each AggregateSpec.whenCommand, AggregateSpec.advanceTime and AggregateSpec.expectNothingDue is a test of its own, and each AggregateSpec.fork a container of the tests it runs, named by the fork. A failing check fails its own test only: the specification goes on, so the other steps and forks still run and report on their own.

Link copied to clipboard
fun commandTypeOf(command: Command<*>): String

The full type name of command as its receipts carry it, <context>.<aggregate>.<name>: the name is its class's @Name, or its simple name.

Link copied to clipboard
fun committedReceipt(command: Command<*>, executionId: ExecutionId, version: Int = 1, aggregateId: String = command.ref.id, duplicate: Boolean = false, commandType: String = commandTypeOf(command)): CommandReceipt.Committed<Any>

The success receipt of command, committed on the aggregate aggregateId at version (duplicate when its target had already committed the request), as the runtime hands it to the @OnCommitted handler of the saga whose execution executionId derived the command: for ProcessorSpec.whenCommitted.

Link copied to clipboard
fun committedResult(command: Command<*>, version: Int = 1, aggregateId: String = if (command.ref.isAssigned) command.ref.id else "${command.ref.type.name}-1", duplicate: Boolean = false): CommandResult

The result a target answers a synchronous call of command with when it committed it: at its COMMITTED hop, on the aggregate aggregateId (the command's, or <aggregate>-1 for a creation that left its id to the target), at version, duplicate when the target had already committed the request.

Link copied to clipboard
fun failedResult(command: Command<*>, code: String, message: String = code): CommandResult

The result a target answers a synchronous call of command with when it failed for a technical reason code, such as a store it could not reach.

Link copied to clipboard
fun projectionSpec(handlers: List<ProcessorBinding<*>>, block: ProcessorSpec.() -> Unit)

Specifies a projection's behaviour: given a commit (a StateEvent, built with stateEvent), what its handlers write. handlers are the projection's, from the function the compiler generated for it (<processor>Handlers), with a fake of the port it writes to, which the expectations then read:

Link copied to clipboard
fun projectionSpecTests(handlers: List<ProcessorBinding<*>>, block: ProcessorSpec.() -> Unit): Stream<DynamicNode>

The specification projectionSpec runs, as a tree of tests for a JUnit @TestFactory, as sagaSpecTests.

Link copied to clipboard
fun publishedEvent(name: String, body: Any = emptyMap<String, Any>(), revision: Int = 1): PublishedEvent

An event of a stream another context publishes that the handler has no api class of at its revision, as it receives it: its full name (<context>.<aggregate>.<event>), revision and body as JSON text, an empty object by default.

Link copied to clipboard
fun reactorSpec(handlers: List<ProcessorBinding<*>>, block: ProcessorSpec.() -> Unit)

Specifies a reactor's behaviour as projectionSpec does a projection's: given a commit, its side effects.

Link copied to clipboard
fun reactorSpecTests(handlers: List<ProcessorBinding<*>>, block: ProcessorSpec.() -> Unit): Stream<DynamicNode>

The specification reactorSpec runs, as a tree of tests for a JUnit @TestFactory, as sagaSpecTests.

Link copied to clipboard
fun rejectedReceipt(command: Command<*>, executionId: ExecutionId, code: String, message: String = code, commandType: String = commandTypeOf(command)): CommandReceipt.Rejected<Any>

The rejection of command with code and message, as the runtime hands it to the @OnRejected handler of the saga whose execution executionId derived the command: for ProcessorSpec.whenRejected.

Link copied to clipboard
fun rejectedResult(command: Command<*>, code: String, message: String = code): CommandResult

The result a target answers a synchronous call of command with when it refused it with code.

Link copied to clipboard
fun sagaSpec(handlers: List<ProcessorBinding<*>>, block: ProcessorSpec.() -> Unit)

Specifies a saga's behaviour: given a commit of a stream, its own context's or one it reads from another context (a StateEvent, built with stateEvent), or the rejection or the commit of a command it derived, the commands it derives and the commands it schedules. handlers are the handlers of the saga under test, from the function the compiler generated for it (<processor>Handlers, orderSagaHandlers for OrderSaga), which constructs that saga only, with its own services:

Link copied to clipboard
fun sagaSpecTests(handlers: List<ProcessorBinding<*>>, block: ProcessorSpec.() -> Unit): Stream<DynamicNode>

The specification sagaSpec runs, as a tree of tests for a JUnit @TestFactory: each ProcessorSpec.whenEvent, ProcessorSpec.whenRejected and ProcessorSpec.whenCommitted is a test of its own, and each ProcessorSpec.fork a container named by it; a failing check fails its own test only, as aggregateSpecTests does:

Link copied to clipboard
fun scheduleSpec(handlers: List<ProcessorBinding<*>>, start: Instant = DEFAULT_START, partitions: Int = 1, block: ScheduleSpec.() -> Unit)

Specifies a saga's @OnSchedule handlers against the real job aggregate: enable an instance of a job, move the time on, and check the ticks the handlers got and the commands they derived. handlers are the saga's, from the function the compiler generated for it (<processor>Handlers), which names the bounded context their jobs run in; its log has partitions partitions (for a SHARDED job's instances). Their calls are answered (ScheduleSpec.answerCalls) and their reads served (ScheduleSpec.givenQueries) as a saga specification's are, and a failing handling is retried or parked by its job's @Retry.

Link copied to clipboard
fun scheduleSpecTests(handlers: List<ProcessorBinding<*>>, start: Instant = DEFAULT_START, partitions: Int = 1, block: ScheduleSpec.() -> Unit): Stream<DynamicNode>

The specification scheduleSpec runs, as a tree of tests for a JUnit @TestFactory: each ScheduleSpec.advanceTime that checks what the handlers did, and each ScheduleSpec.whenTick, is a test of its own, as sagaSpecTests does.

Link copied to clipboard
fun <S> stateEvent(ref: AggregateRef, state: S, vararg events: Any, version: Int = 1, commandType: String = ".Command", commandId: String = "command-", requestId: String = "request-", commitTime: Long = DEFAULT_START.toEpochMilli(), scope: Scope = Scope.NONE, causation: Causation? = null, headers: Map<String, String> = emptyMap(), operator: Operator? = null): StateEvent<S>

The commit of events at version of ref, leaving it in state, as a processor's handler receives it: the events of its own context as their classes, those of a stream it reads from another context as the classes of that context's api, or publishedEvents for those it has no class of at their revision. The command's ids default to command-<version> and request-<version>, and the commit time to DEFAULT_START.