hedgehog-1.5: Release with confidence.

Safe Haskell | None
Language | Haskell2010

Hedgehog.Internal.State

Contents

- Variables
- Environment
- Commands
- Actions

Synopsis

- newtype Var a (v :: Type -> Type) = Var (v a)
- concrete :: Var a Concrete -> a
- opaque :: Var (Opaque a) Concrete -> a
- newtype Concrete a where
  - Concrete :: forall a. a -> Concrete a
- data Symbolic a where
  - Symbolic :: forall a. Typeable a => Name -> Symbolic a
- newtype Name = Name Int
- newtype Environment = Environment {
  - unEnvironment :: Map Name Dynamic
  }
- data EnvironmentError
  - = EnvironmentValueNotFound !Name
  - | EnvironmentTypeError !TypeRep !TypeRep
- emptyEnvironment :: Environment
- insertConcrete :: Symbolic a -> Concrete a -> Environment -> Environment
- reifyDynamic :: Typeable a => Dynamic -> Either EnvironmentError (Concrete a)
- reifyEnvironment :: Environment -> forall a. Symbolic a -> Either EnvironmentError (Concrete a)
- reify :: TraversableB t => Environment -> t Symbolic -> Either EnvironmentError (t Concrete)
- data Command (gen :: Type -> Type) (m :: Type -> Type) (state :: (Type -> Type) -> Type) = (TraversableB input, Show (input Symbolic), Show output, Typeable output) => Command {
  - commandGen :: state Symbolic -> Maybe (gen (input Symbolic))
  - commandExecute :: input Concrete -> m output
  - commandCallbacks :: [Callback input output state]
  }
- data Callback (input :: (Type -> Type) -> Type) output (state :: (Type -> Type) -> Type)
  - = Require (state Symbolic -> input Symbolic -> Bool)
  - | Update (forall (v :: Type -> Type). Ord1 v => state v -> input v -> Var output v -> state v)
  - | Ensure (state Concrete -> state Concrete -> input Concrete -> output -> Test ())
- commandGenOK :: forall (gen :: Type -> Type) (m :: Type -> Type) state. Command gen m state -> state Symbolic -> Bool
- data Action (m :: Type -> Type) (state :: (Type -> Type) -> Type) = (TraversableB input, Show (input Symbolic), Show output) => Action {
  - actionInput :: input Symbolic
  - actionOutput :: Symbolic output
  - actionExecute :: input Concrete -> m output
  - actionRequire :: state Symbolic -> input Symbolic -> Bool
  - actionUpdate :: forall (v :: Type -> Type). Ord1 v => state v -> input v -> Var output v -> state v
  - actionEnsure :: state Concrete -> state Concrete -> input Concrete -> output -> Test ()
  }
- newtype Sequential (m :: Type -> Type) (state :: (Type -> Type) -> Type) = Sequential {
  - sequentialActions :: [Action m state]
  }
- data Parallel (m :: Type -> Type) (state :: (Type -> Type) -> Type) = Parallel {
  - parallelPrefix :: [Action m state]
  - parallelBranch1 :: [Action m state]
  - parallelBranch2 :: [Action m state]
  }
- takeVariables :: TraversableB t => t Symbolic -> Map Name TypeRep
- variablesOK :: TraversableB t => t Symbolic -> Map Name TypeRep -> Bool
- dropInvalid :: forall (m :: Type -> Type) (state :: (Type -> Type) -> Type). [Action m state] -> State (Context state) [Action m state]
- action :: forall (gen :: Type -> Type) (m :: Type -> Type) (state :: (Type -> Type) -> Type). (MonadGen gen, MonadTest m) => [Command gen m state] -> GenT (StateT (Context state) (GenBase gen)) (Action m state)
- sequential :: forall gen (m :: Type -> Type) state. (MonadGen gen, MonadTest m) => Range Int -> (forall (v :: Type -> Type). state v) -> [Command gen m state] -> gen (Sequential m state)
- parallel :: forall gen (m :: Type -> Type) state. (MonadGen gen, MonadTest m) => Range Int -> Range Int -> (forall (v :: Type -> Type). state v) -> [Command gen m state] -> gen (Parallel m state)
- executeSequential :: (MonadTest m, MonadCatch m, HasCallStack) => (forall (v :: Type -> Type). state v) -> Sequential m state -> m ()
- executeParallel :: (MonadTest m, MonadCatch m, MonadBaseControl IO m, HasCallStack) => (forall (v :: Type -> Type). state v) -> Parallel m state -> m ()

# Variables

newtype Var a (v :: Type -> Type) Source #

Variables are the potential or actual result of executing an action. They are parameterised by either `Symbolic` or `Concrete` depending on the phase of the test.

`Symbolic` variables are the potential results of actions. These are used when generating the sequence of actions to execute. They allow actions which occur later in the sequence to make use of the result of an action which came earlier in the sequence.

`Concrete` variables are the actual results of actions. These are used during test execution. They provide access to the actual runtime value of a variable.

The state update `Callback` for a command needs to be polymorphic in the type of variable because it is used in both the generation and the execution phase.

The order of arguments makes `Var` `FunctorB` and `TraversableB`, which is how `Symbolic` values are turned into `Concrete` ones.

Constructors

Var (v a) |

#### Instances

Instances details

FunctorB (Var a :: (Type -> Type) -> Type) Source # |
Instance details Defined in Hedgehog.Internal.State Methods bmap :: (forall a0. f a0 -> g a0) -> Var a f -> Var a g Source #
TraversableB (Var a :: (Type -> Type) -> Type) Source # |
Instance details Defined in Hedgehog.Internal.State Methods btraverse :: Applicative e => (forall a0. f a0 -> e (g a0)) -> Var a f -> e (Var a g) Source #
(Show a, Show1 v) => Show (Var a v) Source # |
Instance details Defined in Hedgehog.Internal.State Methods showsPrec :: Int -> Var a v -> ShowS Source # show :: Var a v -> String Source # showList :: [Var a v] -> ShowS Source #
(Eq a, Eq1 v) => Eq (Var a v) Source # |
Instance details Defined in Hedgehog.Internal.State Methods (==) :: Var a v -> Var a v -> Bool Source # (/=) :: Var a v -> Var a v -> Bool Source #
(Ord a, Ord1 v) => Ord (Var a v) Source # |
Instance details Defined in Hedgehog.Internal.State Methods compare :: Var a v -> Var a v -> Ordering Source # (<) :: Var a v -> Var a v -> Bool Source # (<=) :: Var a v -> Var a v -> Bool Source # (>) :: Var a v -> Var a v -> Bool Source # (>=) :: Var a v -> Var a v -> Bool Source # max :: Var a v -> Var a v -> Var a v Source # min :: Var a v -> Var a v -> Var a v Source #

concrete :: Var a Concrete -> a Source #

Take the value from a concrete variable.

opaque :: Var (Opaque a) Concrete -> a Source #

Take the value from an opaque concrete variable.

newtype Concrete a where Source #

Concrete values: At test-execution time, `Symbolic` values from generation are replaced with `Concrete` values from performing actions. This type gives us something of the same kind as `Symbolic` to pass as a type argument to `Var`.

Constructors

Concrete :: forall a. a -> Concrete a |

#### Instances

Instances details

Eq1 Concrete Source # |
Instance details Defined in Hedgehog.Internal.State Methods liftEq :: (a -> b -> Bool) -> Concrete a -> Concrete b -> Bool Source #
Ord1 Concrete Source # |
Instance details Defined in Hedgehog.Internal.State Methods liftCompare :: (a -> b -> Ordering) -> Concrete a -> Concrete b -> Ordering Source #
Show1 Concrete Source # |
Instance details Defined in Hedgehog.Internal.State Methods liftShowsPrec :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> Concrete a -> ShowS Source # liftShowList :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> [Concrete a] -> ShowS Source #
Functor Concrete Source # |
Instance details Defined in Hedgehog.Internal.State Methods fmap :: (a -> b) -> Concrete a -> Concrete b Source # (<$) :: a -> Concrete b -> Concrete a Source #
Foldable Concrete Source # |

Instance details

Defined in Hedgehog.Internal.State

Methods

fold :: Monoid m => Concrete m -> m Source #

foldMap :: Monoid m => (a -> m) -> Concrete a -> m Source #

foldMap' :: Monoid m => (a -> m) -> Concrete a -> m Source #

foldr :: (a -> b -> b) -> b -> Concrete a -> b Source #

foldr' :: (a -> b -> b) -> b -> Concrete a -> b Source #

foldl :: (b -> a -> b) -> b -> Concrete a -> b Source #

foldl' :: (b -> a -> b) -> b -> Concrete a -> b Source #

foldr1 :: (a -> a -> a) -> Concrete a -> a Source #

foldl1 :: (a -> a -> a) -> Concrete a -> a Source #

toList :: Concrete a -> [a] Source #

null :: Concrete a -> Bool Source #

length :: Concrete a -> Int Source #

elem :: Eq a => a -> Concrete a -> Bool Source #

maximum :: Ord a => Concrete a -> a Source #

minimum :: Ord a => Concrete a -> a Source #

sum :: Num a => Concrete a -> a Source #

product :: Num a => Concrete a -> a Source #

Traversable Concrete Source # |
Instance details Defined in Hedgehog.Internal.State Methods traverse :: Applicative f => (a -> f b) -> Concrete a -> f (Concrete b) Source # sequenceA :: Applicative f => Concrete (f a) -> f (Concrete a) Source # mapM :: Monad m => (a -> m b) -> Concrete a -> m (Concrete b) Source # sequence :: Monad m => Concrete (m a) -> m (Concrete a) Source #
Show a => Show (Concrete a) Source # |
Instance details Defined in Hedgehog.Internal.State Methods showsPrec :: Int -> Concrete a -> ShowS Source # show :: Concrete a -> String Source # showList :: [Concrete a] -> ShowS Source #
Eq a => Eq (Concrete a) Source # |
Instance details Defined in Hedgehog.Internal.State Methods (==) :: Concrete a -> Concrete a -> Bool Source # (/=) :: Concrete a -> Concrete a -> Bool Source #
Ord a => Ord (Concrete a) Source # |

Instance details

Defined in Hedgehog.Internal.State

Methods

compare :: Concrete a -> Concrete a -> Ordering Source #

(<) :: Concrete a -> Concrete a -> Bool Source #

(<=) :: Concrete a -> Concrete a -> Bool Source #

(>) :: Concrete a -> Concrete a -> Bool Source #

(>=) :: Concrete a -> Concrete a -> Bool Source #

max :: Concrete a -> Concrete a -> Concrete a Source #

min :: Concrete a -> Concrete a -> Concrete a Source #

data Symbolic a where Source #

Symbolic values: Because hedgehog generates actions in a separate phase before execution, you will sometimes need to refer to the result of a previous action in a generator without knowing the value of the result (e.g., to get the ID of a previously-created user).

Symbolic variables provide a token to stand in for the actual variables at generation time (and in `Require`/`Update` callbacks). At execution time, real values are available, so your execute actions work on `Concrete` variables.

See also: `Command`, `Var`

Constructors

Symbolic :: forall a. Typeable a => Name -> Symbolic a |

#### Instances

Instances details

Eq1 Symbolic Source # |
Instance details Defined in Hedgehog.Internal.State Methods liftEq :: (a -> b -> Bool) -> Symbolic a -> Symbolic b -> Bool Source #
Ord1 Symbolic Source # |
Instance details Defined in Hedgehog.Internal.State Methods liftCompare :: (a -> b -> Ordering) -> Symbolic a -> Symbolic b -> Ordering Source #
Show1 Symbolic Source # |
Instance details Defined in Hedgehog.Internal.State Methods liftShowsPrec :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> Symbolic a -> ShowS Source # liftShowList :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> [Symbolic a] -> ShowS Source #
Show (Symbolic a) Source # |
Instance details Defined in Hedgehog.Internal.State Methods showsPrec :: Int -> Symbolic a -> ShowS Source # show :: Symbolic a -> String Source # showList :: [Symbolic a] -> ShowS Source #
Eq (Symbolic a) Source # |
Instance details Defined in Hedgehog.Internal.State Methods (==) :: Symbolic a -> Symbolic a -> Bool Source # (/=) :: Symbolic a -> Symbolic a -> Bool Source #
Ord (Symbolic a) Source # |

Instance details

Defined in Hedgehog.Internal.State

Methods

compare :: Symbolic a -> Symbolic a -> Ordering Source #

(<) :: Symbolic a -> Symbolic a -> Bool Source #

(<=) :: Symbolic a -> Symbolic a -> Bool Source #

(>) :: Symbolic a -> Symbolic a -> Bool Source #

(>=) :: Symbolic a -> Symbolic a -> Bool Source #

max :: Symbolic a -> Symbolic a -> Symbolic a Source #

min :: Symbolic a -> Symbolic a -> Symbolic a Source #

newtype Name Source #

Symbolic variable names.

Constructors

Name Int |

#### Instances

Instances details

Num Name Source # |
Instance details Defined in Hedgehog.Internal.State Methods (+) :: Name -> Name -> Name Source # (-) :: Name -> Name -> Name Source # (*) :: Name -> Name -> Name Source # negate :: Name -> Name Source # abs :: Name -> Name Source # signum :: Name -> Name Source # fromInteger :: Integer -> Name Source #
Show Name Source # |
Instance details Defined in Hedgehog.Internal.State Methods showsPrec :: Int -> Name -> ShowS Source # show :: Name -> String Source # showList :: [Name] -> ShowS Source #
Eq Name Source # |
Instance details Defined in Hedgehog.Internal.State Methods (==) :: Name -> Name -> Bool Source # (/=) :: Name -> Name -> Bool Source #
Ord Name Source # |
Instance details Defined in Hedgehog.Internal.State Methods compare :: Name -> Name -> Ordering Source # (<) :: Name -> Name -> Bool Source # (<=) :: Name -> Name -> Bool Source # (>) :: Name -> Name -> Bool Source # (>=) :: Name -> Name -> Bool Source # max :: Name -> Name -> Name Source # min :: Name -> Name -> Name Source #

# Environment

newtype Environment Source #

A mapping of symbolic values to concrete values.

Constructors

Environment |

Fields

- unEnvironment :: Map Name Dynamic

#### Instances

Instances details

Show Environment Source # |
Instance details Defined in Hedgehog.Internal.State Methods showsPrec :: Int -> Environment -> ShowS Source # show :: Environment -> String Source # showList :: [Environment] -> ShowS Source #

data EnvironmentError Source #

Environment errors.

Constructors

EnvironmentValueNotFound !Name |
EnvironmentTypeError !TypeRep !TypeRep |

#### Instances

Instances details

Show EnvironmentError Source # |
Instance details Defined in Hedgehog.Internal.State Methods showsPrec :: Int -> EnvironmentError -> ShowS Source # show :: EnvironmentError -> String Source # showList :: [EnvironmentError] -> ShowS Source #
Eq EnvironmentError Source # |
Instance details Defined in Hedgehog.Internal.State Methods (==) :: EnvironmentError -> EnvironmentError -> Bool Source # (/=) :: EnvironmentError -> EnvironmentError -> Bool Source #
Ord EnvironmentError Source # |

Instance details

Defined in Hedgehog.Internal.State

Methods

compare :: EnvironmentError -> EnvironmentError -> Ordering Source #

(<) :: EnvironmentError -> EnvironmentError -> Bool Source #

(<=) :: EnvironmentError -> EnvironmentError -> Bool Source #

(>) :: EnvironmentError -> EnvironmentError -> Bool Source #

(>=) :: EnvironmentError -> EnvironmentError -> Bool Source #

max :: EnvironmentError -> EnvironmentError -> EnvironmentError Source #

min :: EnvironmentError -> EnvironmentError -> EnvironmentError Source #

emptyEnvironment :: Environment Source #

Create an empty environment.

insertConcrete :: Symbolic a -> Concrete a -> Environment -> Environment Source #

Insert a symbolic / concrete pairing in to the environment.

reifyDynamic :: Typeable a => Dynamic -> Either EnvironmentError (Concrete a) Source #

Cast a `Dynamic` in to a concrete value.

reifyEnvironment :: Environment -> forall a. Symbolic a -> Either EnvironmentError (Concrete a) Source #

Turns an environment in to a function for looking up a concrete value from a symbolic one.

reify :: TraversableB t => Environment -> t Symbolic -> Either EnvironmentError (t Concrete) Source #

Convert a symbolic structure to a concrete one, using the provided environment.

# Commands

data Command (gen :: Type -> Type) (m :: Type -> Type) (state :: (Type -> Type) -> Type) Source #

The specification for the expected behaviour of an `Action`. These are used to generate sequences of actions to test.

This is the main type you will use when writing state machine tests. `gen` is usually an instance of `MonadGen`, and `m` is usually an instance of `MonadTest`. These constraints appear when you pass your `Command` list to `sequential` or `parallel`.

Constructors

(TraversableB input, Show (input Symbolic), Show output, Typeable output) => Command |

Fields

- commandGen :: state Symbolic -> Maybe (gen (input Symbolic))

  A generator which provides random arguments for a command. If the command cannot be executed in the current state, it should return `Nothing`.

- commandExecute :: input Concrete -> m output

  Executes a command using the arguments generated by `commandGen`.

- commandCallbacks :: [Callback input output state]

  A set of callbacks which provide optional command configuration such as pre-condtions, post-conditions and state updates.

data Callback (input :: (Type -> Type) -> Type) output (state :: (Type -> Type) -> Type) Source #

Optional command configuration.

Constructors

Require (state Symbolic -> input Symbolic -> Bool) | A pre-condition for a command that must be verified before the command can be executed. This is mainly used during shrinking to ensure that it is still OK to run a command despite the fact that some previously executed commands may have been removed from the sequence.
Update (forall (v :: Type -> Type). Ord1 v => state v -> input v -> Var output v -> state v) | Updates the model state, given the input and output of the command. Note that this function is polymorphic in the type of values. This is because it must work over `Symbolic` values when we are generating actions, and `Concrete` values when we are executing them.
Ensure (state Concrete -> state Concrete -> input Concrete -> output -> Test ()) | A post-condition for a command that must be verified for the command to be considered a success. This callback receives the state prior to execution as the first argument, and the state after execution as the second argument.

commandGenOK :: forall (gen :: Type -> Type) (m :: Type -> Type) state. Command gen m state -> state Symbolic -> Bool Source #

Checks that input for a command can be executed in the given state.

# Actions

data Action (m :: Type -> Type) (state :: (Type -> Type) -> Type) Source #

An instantiation of a `Command` which can be executed, and its effect evaluated.

Constructors

(TraversableB input, Show (input Symbolic), Show output) => Action |

Fields

- actionInput :: input Symbolic
- actionOutput :: Symbolic output
- actionExecute :: input Concrete -> m output
- actionRequire :: state Symbolic -> input Symbolic -> Bool
- actionUpdate :: forall (v :: Type -> Type). Ord1 v => state v -> input v -> Var output v -> state v
- actionEnsure :: state Concrete -> state Concrete -> input Concrete -> output -> Test ()

#### Instances

Instances details

Show (Action m state) Source # |
Instance details Defined in Hedgehog.Internal.State Methods showsPrec :: Int -> Action m state -> ShowS Source # show :: Action m state -> String Source # showList :: [Action m state] -> ShowS Source #

newtype Sequential (m :: Type -> Type) (state :: (Type -> Type) -> Type) Source #

A sequence of actions to execute.

Constructors

Sequential |

Fields

- sequentialActions :: [Action m state]

  The sequence of actions.

#### Instances

Instances details

Show (Sequential m state) Source # |
Instance details Defined in Hedgehog.Internal.State Methods showsPrec :: Int -> Sequential m state -> ShowS Source # show :: Sequential m state -> String Source # showList :: [Sequential m state] -> ShowS Source #

data Parallel (m :: Type -> Type) (state :: (Type -> Type) -> Type) Source #

A sequential prefix of actions to execute, with two branches to execute in parallel.

Constructors

Parallel |

Fields

- parallelPrefix :: [Action m state]

  The sequential prefix.

- parallelBranch1 :: [Action m state]

  The first branch.

- parallelBranch2 :: [Action m state]

  The second branch.

#### Instances

Instances details

Show (Parallel m state) Source # |
Instance details Defined in Hedgehog.Internal.State Methods showsPrec :: Int -> Parallel m state -> ShowS Source # show :: Parallel m state -> String Source # showList :: [Parallel m state] -> ShowS Source #

takeVariables :: TraversableB t => t Symbolic -> Map Name TypeRep Source #

Collects all the symbolic values in a data structure and produces a set of all the variables they refer to.

variablesOK :: TraversableB t => t Symbolic -> Map Name TypeRep -> Bool Source #

Checks that the symbolic values in the data structure refer only to the variables in the provided set, and that they are of the correct type.

dropInvalid :: forall (m :: Type -> Type) (state :: (Type -> Type) -> Type). [Action m state] -> State (Context state) [Action m state] Source #

Drops invalid actions from the sequence.

action :: forall (gen :: Type -> Type) (m :: Type -> Type) (state :: (Type -> Type) -> Type). (MonadGen gen, MonadTest m) => [Command gen m state] -> GenT (StateT (Context state) (GenBase gen)) (Action m state) Source #

Generates a single action from a set of possible commands.

sequential :: forall gen (m :: Type -> Type) state. (MonadGen gen, MonadTest m) => Range Int -> (forall (v :: Type -> Type). state v) -> [Command gen m state] -> gen (Sequential m state) Source #

Generates a sequence of actions from an initial model state and set of commands.

parallel :: forall gen (m :: Type -> Type) state. (MonadGen gen, MonadTest m) => Range Int -> Range Int -> (forall (v :: Type -> Type). state v) -> [Command gen m state] -> gen (Parallel m state) Source #

Given the initial model state and set of commands, generates prefix actions to be run sequentially, followed by two branches to be run in parallel.

executeSequential :: (MonadTest m, MonadCatch m, HasCallStack) => (forall (v :: Type -> Type). state v) -> Sequential m state -> m () Source #

Executes a list of actions sequentially, verifying that all post-conditions are met and no exceptions are thrown.

To generate a sequence of actions to execute, see the `sequential` combinator in the Hedgehog.Gen module.

executeParallel :: (MonadTest m, MonadCatch m, MonadBaseControl IO m, HasCallStack) => (forall (v :: Type -> Type). state v) -> Parallel m state -> m () Source #

Executes the prefix actions sequentially, then executes the two branches in parallel, verifying that no exceptions are thrown and that there is at least one sequential interleaving where all the post-conditions are met.

To generate parallel actions to execute, see the `parallel` combinator in the Hedgehog.Gen module.