PropertyDamage.IEx (PropertyDamage v0.2.0)

View Source

Interactive helpers for exploring and debugging PropertyDamage models in IEx.

These functions help you understand, test, and debug your models interactively.

Quick Start

iex> import PropertyDamage.IEx
iex> explain(MyModel)
iex> dry_run(MyModel, commands: 5)
iex> debug_command(%CreateUser{name: "test"}, MyAdapter)

Available Functions

Summary

Functions

Check which commands have valid preconditions in a given state.

Execute a single command against an adapter with detailed output.

Generate a command sequence without executing it.

Display detailed information about a model.

Show the projection state after applying a list of events.

Functions

check_preconditions(state, model)

@spec check_preconditions(map(), module()) :: :ok

Check which commands have valid preconditions in a given state.

Useful for debugging why certain commands aren't being generated.

Examples

iex> state = %{accounts: %{}}  # Empty state
iex> PropertyDamage.IEx.check_preconditions(state, MyModel)

PRECONDITION CHECK

  Command                     Precondition  Reason

  CreateAccount                VALID       -
  Credit                       INVALID     No accounts exist
  Debit                        INVALID     No accounts exist
  GetBalance                   INVALID     No accounts exist

debug_command(command, adapter, opts \\ [])

@spec debug_command(struct(), module(), keyword()) :: :ok | {:error, term()}

Execute a single command against an adapter with detailed output.

Shows the command, request/response details, and resulting events. Useful for testing individual commands before running full sequences.

Options

  • :adapter_opts - Options passed to adapter.setup/1 (default: [])
  • :refs - Map of ref atoms to resolved values (default: %{})

Examples

iex> PropertyDamage.IEx.debug_command(
...>   %CreateAccount{currency: "USD"},
...>   MyAdapter
...> )


                     COMMAND EXECUTION


COMMAND

CreateAccount
  currency: "USD"

EXECUTION

Status: OK
Time: 15ms

RESULT EVENT

AccountCreated
  account_id: "acc_abc123"
  currency: "USD"
  balance: 0

iex> PropertyDamage.IEx.debug_command(
...>   %Credit{account_ref: :ref0, amount: 500},
...>   MyAdapter,
...>   refs: %{ref0: "acc_abc123"}
...> )

dry_run(model, opts \\ [])

@spec dry_run(
  module(),
  keyword()
) :: :ok

Generate a command sequence without executing it.

Useful for seeing what commands would be generated given the model's configuration.

Options

  • :commands - Number of commands to generate (default: 10)
  • :seed - Random seed for reproducibility
  • :branching - Enable branching sequences (default: false)
  • :verbose - Show detailed command fields (default: false)

Examples

iex> PropertyDamage.IEx.dry_run(MyModel, commands: 5)

Generated sequence (5 commands):

[0] CreateAccount{currency: "USD"}
[1] Credit{account_ref: :ref0, amount: 500}
[2] CreateAuthorization{account_ref: :ref0, amount: 200}
[3] Debit{account_ref: :ref0, amount: 100}
[4] GetBalance{account_ref: :ref0}

Seed: 12345 (use this to reproduce)

iex> PropertyDamage.IEx.dry_run(MyModel, seed: 12345)
# Same sequence as above

explain(model)

@spec explain(module()) :: :ok

Display detailed information about a model.

Shows commands (with weights), projections, optional callbacks, and helpful hints about the model's configuration.

Examples

iex> PropertyDamage.IEx.explain(ToyBankTest.Model)


                      ToyBankTest.Model


COMMANDS (6 total)

  Weight  Command                     Semantics

     5    CreateAccount               sync
     3    Credit                      sync
     3    Debit                       sync
     2    CreateAuthorization         probe
     2    CreateCapture               sync
     1    CloseAccount                sync
...

inspect_state(events, projection)

@spec inspect_state([struct()], module()) :: :ok

Show the projection state after applying a list of events.

Useful for understanding how events affect model state.

Examples

iex> events = [
...>   %AccountCreated{account_id: "acc_1", currency: "USD"},
...>   %Credited{account_id: "acc_1", amount: 500}
...> ]
iex> PropertyDamage.IEx.inspect_state(events, MyProjection)

STATE AFTER 2 EVENTS

%{
  accounts: %{
    "acc_1" => %{currency: "USD", balance: 500}
  }
}