Packages

Makina is a DSL for writing PBT models for stateful systems.

Current section

Files

Jump to
makina priv docs state.md
Raw

priv/docs/state.md

Provides a set of macros to define the state of a Makina model.
The state of a Makina model is formed by a set of attributes. These attributes are stored inside a
map with the name of the attributes as keys.
## Basic state definition
A basic state declaration is shown below:
# 1) Create a module that will store the state
defmodule Model do
# 2) Use Makina.State to configure the module and import the necessary macros
use Makina.State
# 3) Write the state definition, type declarations are optional but recommended.
defstate value: 0 :: integer()
end
Each attribute in the state definition should contain different names. Multiple state definitions
are allowed.
## Functions
After macro expansion the module will contain the functions:
- Each attribute will generate a function `attribute_`name`/0` which contains the initial value of
that attribute. In this example this is just the function `attribute_value/0`.
- `initial_state/0` that returns the initial state of the model. In this example the map `%{value:
0}`.
- `validate_state/1` that receives a state and throws an error if it doesn't contain any of the
attributes in the state definition.
## Types
After macro expansion the module will contain the types:
- `symbolic_state/0` represents the state of the model during test generation.
- `dynamic_state/0` represents the state of the model during test execution.
- `state/0` represents the state at any point of the execution.
- `state_update/0` represents the modifications allowed to the state.
## Extending the state
Makina states can be extended in new models.
defmodule Extends do
use Makina.State, extends: Model
defstate attr_2: 1 :: integer()
end
The resulting state will contain the union of the state attributes defined in `Model` and
`Extends`. Notice that definitions in `Model` can be overriden:
defmodule Extends2 do
use Makina.State, extends: Model
defstate value: super() + 1
end
When an attribute is overriden its type definition is not required and the original initial state
can be accessed using `super/0`.