StatefulProperty[S: S, M: M, Cmd: Stringable val]¶
A stateful property test with interleaved command generation and execution.
S is the system under test (ref or val capability). M is the
reference model (ref or val). Cmd is a union of val command
classes, each Stringable.
Each sample creates fresh state via initial_sut() and
initial_model(), draws a step count uniformly from
[1, max_steps()], then for each step calls step to generate and
execute a command, followed by invariant to check model-SUT
agreement. After all steps, final_check runs once. On failure, the
choice sequence is replayed with shrunken candidates.
step() returns StepResult[Cmd]. Return the command
on success, StepReject when the command is invalid for the current
state (the sample is discarded), or StepFail when the system under
test breaks (triggers shrinking).
Factory methods must be deterministic: given the same starting point, they produce equivalent state. They are called once per sample and once per shrink replay. Non-deterministic factories cause the shrinker to accept or reject candidates incorrectly.
All mutable per-sample state belongs in ctx.sut and ctx.model,
not on self. Fields on the implementing class persist between
samples and shrink replays.
Public Functions¶
name¶
The test name.
Returns¶
- String val
params¶
Parameters controlling sample count, seed, shrink budget, and timeout.
Returns¶
- PropertyParams val
max_steps¶
Maximum number of steps per sample. The actual count for each sample is drawn uniformly from [1, max_steps()].
Returns¶
- USize val
initial_sut¶
The initial system under test.
Returns¶
- S^
initial_model¶
The initial model state.
Returns¶
- M^
step¶
Generate and apply a command to ctx.sut and ctx.model.
Return the command on success, StepReject when the command is
invalid for the current state, or StepFail when the system under
test breaks. StepReject discards the sample and retries.
StepFail records the step and triggers shrinking.
fun ref step(
ctx: StatefulContext[S, M] ref,
rnd: Randomness ref,
h: PropertyHelper val)
: StepResult[Cmd]
Parameters¶
- ctx: StatefulContext[S, M] ref
- rnd: Randomness ref
- h: PropertyHelper val
Returns¶
- StepResult[Cmd]
invariant¶
Checked after each step. Return false to fail the property.
The context is box (read-only). Use h.assert_* methods and
chain with and:
fun invariant(ctx: ..., h: PropertyHelper): Bool =>
h.assert_eq[USize](ctx.model.size(), ctx.sut.size()) and
h.assert_true(ctx.sut.size() <= ctx.sut.capacity())
Default returns true (no failure).
Parameters¶
- ctx: StatefulContext[S, M] box
- h: PropertyHelper val
Returns¶
- Bool val
final_check¶
End-of-sequence check after all steps complete. Not called when
step() returns StepFail. The context is box (read-only).
Default returns true (no failure).
Parameters¶
- ctx: StatefulContext[S, M] box
- h: PropertyHelper val
Returns¶
- Bool val