Expectations

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.

The event checks (expectEvents, expectEventTypes, expectEvent) read the events the decision committed beside its schedules: the system events wow.ScheduleSet and wow.ScheduleCancelled are checked by expectScheduled and expectScheduleCancelled.

A rejection is a value, not an exception, so a scenario that does not look at it would pass whatever the command did: a rejected command fails the scenario unless expectRejected checks it. A rejection with events commits them as any decision does, so expectRejected composes with the event, version and state checks:

whenCommand(Unlock("0000")) {
expectRejected("wrong-code")
expectEventTypes(AttemptFailed::class)
expectState { failures.assert().isEqualTo(1) }
}

A creation rejected with events fails the scenario, naming the command: its aggregate does not exist, so the events could never be committed.

What the decide function put for the caller (me.ahoo.wow.api.decide.DecideScope.putResult) is checked by expectResult, or read from results.

Constructors

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

Properties

Link copied to clipboard

What the command's decide function threw; null when it returned a decision.

Link copied to clipboard

The kernel's outcome of the command (Committed, Unchanged, Rejected, …), for Wow's own tests; a failure when its decide function threw. A domain's scenario checks it through the expect* functions and results.

Link copied to clipboard

What the command's decide function put for the caller (me.ahoo.wow.api.decide.DecideScope.putResult), by key; a failure when the command committed nothing, since only a committed command answers with results.

Functions

Link copied to clipboard
fun expectAccess(expected: Map<String, Any?>)

The aggregate's access attributes (@Access) are exactly expected after the committed events, or, after a command that committed nothing, in the state the aggregate is in: each declared attribute by name, a single one's value or null, a multiple one's values in any order (AggregateModel.accessOf).

Link copied to clipboard

The command committed the aggregate's deletion, as 9.x's expectStateAggregate { deleted } read it.

Link copied to clipboard
inline fun <reified T : Throwable> expectError(noinline check: T.() -> Unit = {}): T

The command's decide function threw a T (9.x's expectError), which check checks: nothing was written. A rejection is not an error: expectRejected checks it.

fun <T : Throwable> expectError(type: KClass<T>, check: T.() -> Unit = {}): T

The command's decide function threw a type, which check checks.

Link copied to clipboard
inline fun <reified E : Any> expectEvent(noinline check: E.() -> Unit = {}): E

The command committed exactly one event, an E, which check checks.

fun <E : Any> expectEvent(type: KClass<E>, check: E.() -> Unit = {}): E

The command committed exactly one event, of type, which check checks.

Link copied to clipboard
fun expectEventCount(count: Int)

The command committed exactly count events, its schedules' system events aside.

Link copied to clipboard
inline fun <reified E : Any> expectEventEnvelope(noinline check: EventEnvelope<E>.() -> Unit = {}): EventEnvelope<E>

The command committed exactly one event, an E, which check checks with its envelope: the stream's aggregate, version, command and request ids, request facts, operator and commit time beside the event itself (EventEnvelope.body).

fun <E : Any> expectEventEnvelope(type: KClass<E>, check: EventEnvelope<E>.() -> Unit = {}): EventEnvelope<E>

The command committed exactly one event, of type, which check checks with its envelope.

Link copied to clipboard
fun expectEvents(vararg events: Any)

The command committed exactly events, in order; a mismatch lists each difference by its path.

Link copied to clipboard
fun expectEventTypes(vararg types: Class<*>)
fun expectEventTypes(vararg types: KClass<*>)

The command committed events of exactly these types, in order.

Link copied to clipboard

The decide function threw nothing and the command was not rejected.

Link copied to clipboard
fun expectRejected(code: String, check: Rejection.() -> Unit = {})

The command was rejected with code: a full code, or the local name of a code of the aggregate, as its decide function writes it, which the kernel qualifies with the aggregate's type; check checks the rejection, its message say. The events a rejection carried are checked as any committed ones.

Link copied to clipboard
fun expectResult(key: String, value: Any)

The command committed and its decide function put value for the caller under key.

Link copied to clipboard

The command cancelled the schedule key: it committed wow.ScheduleCancelled.

Link copied to clipboard
fun expectScheduled(key: String, command: Any, rule: ScheduleRule? = null, target: AggregateRef? = null)

The command scheduled command under key, for target (the aggregate itself by default), due as rule says when it is given: it committed wow.ScheduleSet.

Link copied to clipboard
fun expectScope(scope: Scope)

The committed stream leaves the aggregate in scope.

Link copied to clipboard
fun expectState(expected: S)

The aggregate's state after the command is expected, field by field as Wow writes it to JSON: a mismatch lists each difference by its path. As expectState of a check, after a command that committed nothing the state is the one the aggregate is in.

fun expectState(check: S.() -> Unit)

Checks the state after the committed events; after a command that committed nothing (it changed nothing, was rejected, or its decide function threw), the state the aggregate is in.

Link copied to clipboard

The command was accepted and changed nothing.

Link copied to clipboard
fun expectVersion(version: Int)

The aggregate is at version after the command: the committed stream's, or the version it was at when the command appended nothing (changed nothing, or was rejected), as 9.x's expectStateAggregate { version } read it.

Link copied to clipboard
fun fork(name: String = "", block: AggregateSpec<S>.() -> Unit)

Runs block on a copy of the aggregate as this command left it, as AggregateSpec.fork does, so that the scenarios after a command branch from its checks, as 9.x's VerifiedStage.fork did:

fun fork(name: String = "", model: AggregateModel<S>, block: AggregateSpec<S>.() -> Unit)

Runs block on a copy of the aggregate as this command left it, as fork does, with model deciding from there on: the same aggregate built with other services (AggregateSpec.fork of a model).