-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Test monadic programs using state machine based models
--
-- See README at
-- https://github.com/advancedtelematic/quickcheck-state-machine#readme
@package quickcheck-state-machine
@version 0.1.0
-- | This module exports a higher-order version of functors, foldable
-- functors, and traversable functors.
module Test.StateMachine.Types.HFunctor
-- | Higher-order functors.
class HFunctor (f :: (* -> *) -> * -> *) where hfmap f = runIdentity . htraverse (Identity . f)
-- | Higher-order version of fmap.
hfmap :: HFunctor f => (forall a. g a -> h a) -> f g b -> f h b
-- | Higher-order version of fmap.
hfmap :: (HFunctor f, HTraversable f) => (forall a. g a -> h a) -> f g b -> f h b
-- | Higher-order version of fmap.
hfmap :: HFunctor f => (forall a. g a -> h a) -> f g b -> f h b
-- | Higher-order foldable functors.
class HFunctor t => HFoldable (t :: (* -> *) -> * -> *) where hfoldMap f = getConst . htraverse (Const . f)
-- | Higher-order version of foldMap.
hfoldMap :: (HFoldable t, Monoid m) => (forall a. v a -> m) -> t v b -> m
-- | Higher-order version of foldMap.
hfoldMap :: (HFoldable t, HTraversable t, Monoid m) => (forall a. v a -> m) -> t v b -> m
-- | Higher-order version of foldMap.
hfoldMap :: (HFoldable t, Monoid m) => (forall a. v a -> m) -> t v b -> m
-- | Higher-order traversable functors.
class (HFunctor t, HFoldable t) => HTraversable (t :: (* -> *) -> * -> *)
-- | Higher-order version of traverse.
htraverse :: (HTraversable t, Applicative f) => (forall a. g a -> f (h a)) -> t g b -> f (t h b)
-- | Higher-order version of traverse.
htraverse :: (HTraversable t, Applicative f) => (forall a. g a -> f (h a)) -> t g b -> f (t h b)
-- | This module contains reference related types. It's taken almost
-- verbatim from the Hedgehog library.
module Test.StateMachine.Types.References
-- | References 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.
data Reference v a
Reference :: (v a) -> Reference v a
-- | Take the value from a concrete variable.
concrete :: Reference Concrete a -> a
-- | Take the value from an opaque concrete variable.
opaque :: Reference Concrete (Opaque a) -> a
-- | Opaque values.
--
-- Useful if you want to put something without a Show instance
-- inside something which you'd like to be able to display.
newtype Opaque a
Opaque :: a -> Opaque a
[unOpaque] :: Opaque a -> a
-- | Symbolic values.
data Symbolic a
[Symbolic] :: Typeable a => Var -> Symbolic a
-- | Concrete values.
newtype Concrete a
[Concrete] :: a -> Concrete a
-- | Symbolic variable names.
newtype Var
Var :: Int -> Var
instance Data.Traversable.Traversable Test.StateMachine.Types.References.Concrete
instance Data.Foldable.Foldable Test.StateMachine.Types.References.Concrete
instance GHC.Base.Functor Test.StateMachine.Types.References.Concrete
instance GHC.Classes.Ord a => GHC.Classes.Ord (Test.StateMachine.Types.References.Concrete a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Test.StateMachine.Types.References.Concrete a)
instance GHC.Read.Read Test.StateMachine.Types.References.Var
instance GHC.Num.Num Test.StateMachine.Types.References.Var
instance GHC.Show.Show Test.StateMachine.Types.References.Var
instance GHC.Classes.Ord Test.StateMachine.Types.References.Var
instance GHC.Classes.Eq Test.StateMachine.Types.References.Var
instance GHC.Classes.Ord a => GHC.Classes.Ord (Test.StateMachine.Types.References.Opaque a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Test.StateMachine.Types.References.Opaque a)
instance GHC.Classes.Eq (Test.StateMachine.Types.References.Symbolic a)
instance GHC.Classes.Ord (Test.StateMachine.Types.References.Symbolic a)
instance (Data.Functor.Classes.Eq1 v, GHC.Classes.Eq a) => GHC.Classes.Eq (Test.StateMachine.Types.References.Reference v a)
instance (Data.Functor.Classes.Ord1 v, GHC.Classes.Ord a) => GHC.Classes.Ord (Test.StateMachine.Types.References.Reference v a)
instance (GHC.Show.Show a, Data.Functor.Classes.Show1 v) => GHC.Show.Show (Test.StateMachine.Types.References.Reference v a)
instance Test.StateMachine.Types.HFunctor.HTraversable Test.StateMachine.Types.References.Reference
instance Test.StateMachine.Types.HFunctor.HFunctor Test.StateMachine.Types.References.Reference
instance Test.StateMachine.Types.HFunctor.HFoldable Test.StateMachine.Types.References.Reference
instance GHC.Show.Show (Test.StateMachine.Types.References.Opaque a)
instance GHC.Show.Show (Test.StateMachine.Types.References.Symbolic a)
instance Data.Functor.Classes.Show1 Test.StateMachine.Types.References.Symbolic
instance Data.Typeable.Internal.Typeable a => GHC.Read.Read (Test.StateMachine.Types.References.Symbolic a)
instance Data.Functor.Classes.Eq1 Test.StateMachine.Types.References.Symbolic
instance Data.Functor.Classes.Ord1 Test.StateMachine.Types.References.Symbolic
instance GHC.Show.Show a => GHC.Show.Show (Test.StateMachine.Types.References.Concrete a)
instance Data.Functor.Classes.Show1 Test.StateMachine.Types.References.Concrete
instance Data.Functor.Classes.Eq1 Test.StateMachine.Types.References.Concrete
instance Data.Functor.Classes.Ord1 Test.StateMachine.Types.References.Concrete
-- | This module contains the main types exposed to the user. The module is
-- perhaps best read indirectly, on a per need basis, via the main module
-- Test.StateMachine.
module Test.StateMachine.Types
-- | An untyped action is an action where the response type is hidden away
-- using an existential type.
--
-- We need to hide the response type when generating actions, because in
-- general the actions we want to generate will have different response
-- types; and thus we can only type the generating function if we hide
-- the response type.
data Untyped (act :: (* -> *) -> * -> *)
[Untyped] :: (Show resp, Typeable resp) => act Symbolic resp -> Untyped act
-- | When generating actions we have access to a model containing symbolic
-- references.
type Generator model act = model Symbolic -> Gen (Untyped act)
-- | Shrinking should preserve the response type of the action.
type Shrinker act = forall (v :: * -> *) resp. act v resp -> [act v resp]
-- | Pre-conditions are checked while generating, at this stage we do not
-- yet have access to concrete references.
type Precondition model act = forall resp. model Symbolic -> act Symbolic resp -> Bool
-- | The transition function must be polymorphic in the type of variables
-- used, as it is used both while generating and executing.
type Transition model act = forall resp v. Ord1 v => model v -> act v resp -> v resp -> model v
-- | When we execute our actions we have access to concrete references.
type Semantics act m = forall resp. act Concrete resp -> m resp
-- | Post-conditions are checked after the actions have been executed and
-- we got a response.
type Postcondition model act = forall resp. model Concrete -> act Concrete resp -> resp -> Property
-- | The initial model is polymorphic in the type of references it uses, so
-- that it can be used both in the pre- and the post-condition check.
type InitialModel m = forall (v :: * -> *). m v
-- | This module exports some QuickCheck utility functions. Some of these
-- should perhaps be upstreamed.
module Test.StateMachine.Internal.Utils
-- | Lifts any to properties.
anyP :: (a -> Property) -> [a] -> Property
-- | Lifts a plain property into a monadic property.
liftProperty :: Monad m => Property -> PropertyM m ()
-- | Write a metaproperty on the output of QuickChecking a property using a
-- boolean predicate on the output.
shrinkPropertyHelper :: Property -> (String -> Bool) -> Property
-- | Same as above, but using a property predicate.
shrinkPropertyHelper' :: Property -> (String -> Property) -> Property
-- | Same above, but for homogeneous pairs.
shrinkPair :: (a -> [a]) -> ((a, a) -> [(a, a)])
-- | Given shrinkers for the components of a pair we can shrink the pair.
shrinkPair' :: (a -> [a]) -> (b -> [b]) -> ((a, b) -> [(a, b)])
-- | This module contains environments that are used to translate between
-- symbolic and concrete references. It's taken verbatim from the
-- Hedgehog library.
module Test.StateMachine.Internal.Types.Environment
-- | A mapping of symbolic values to concrete values.
newtype Environment
Environment :: Map Var Dynamic -> Environment
[unEnvironment] :: Environment -> Map Var Dynamic
-- | Environment errors.
data EnvironmentError
EnvironmentValueNotFound :: !Var -> EnvironmentError
EnvironmentTypeError :: !TypeRep -> !TypeRep -> EnvironmentError
-- | Create an empty environment.
emptyEnvironment :: Environment
-- | Insert a symbolic / concrete pairing in to the environment.
insertConcrete :: Symbolic a -> Concrete a -> Environment -> Environment
-- | Cast a Dynamic in to a concrete value.
reifyDynamic :: forall a. Typeable a => Dynamic -> Either EnvironmentError (Concrete a)
-- | Turns an environment in to a function for looking up a concrete value
-- from a symbolic one.
reifyEnvironment :: Environment -> (forall a. Symbolic a -> Either EnvironmentError (Concrete a))
-- | Convert a symbolic structure to a concrete one, using the provided
-- environment.
reify :: HTraversable t => Environment -> t Symbolic b -> Either EnvironmentError (t Concrete b)
instance GHC.Show.Show Test.StateMachine.Internal.Types.Environment.EnvironmentError
instance GHC.Classes.Ord Test.StateMachine.Internal.Types.Environment.EnvironmentError
instance GHC.Classes.Eq Test.StateMachine.Internal.Types.Environment.EnvironmentError
instance GHC.Show.Show Test.StateMachine.Internal.Types.Environment.Environment
-- | This module exports some types that are used internally by the
-- library.
module Test.StateMachine.Internal.Types
-- | A (sequential) program is an abstract datatype representing a list of
-- actions.
--
-- The idea is that the user shows how to generate, shrink, execute and
-- modelcheck individual actions, and then the below combinators lift
-- those things to whole programs.
newtype Program act
Program :: [Internal act] -> Program act
[unProgram] :: Program act -> [Internal act]
-- | A parallel program is an abstract datatype that represents three
-- sequences of actions; a sequential prefix and two parallel suffixes.
-- Analogous to the sequential case, the user shows how to generate,
-- shrink, execute and modelcheck individual actions, and then the below
-- combinators lift those things to whole parallel programs.
newtype ParallelProgram act
ParallelProgram :: Fork (Program act) -> ParallelProgram act
[unParallelProgram] :: ParallelProgram act -> Fork (Program act)
-- | A process id.
newtype Pid
Pid :: Int -> Pid
-- | Forks are used to represent parallel programs.
data Fork a
Fork :: a -> a -> a -> Fork a
-- | An internal action is an action together with the symbolic variable
-- that will hold its result.
data Internal (act :: (* -> *) -> * -> *)
[Internal] :: (Show resp, Typeable resp) => act Symbolic resp -> Symbolic resp -> Internal act
instance GHC.Show.Show Test.StateMachine.Internal.Types.Pid
instance GHC.Classes.Eq Test.StateMachine.Internal.Types.Pid
instance GHC.Read.Read a => GHC.Read.Read (Test.StateMachine.Internal.Types.Fork a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Test.StateMachine.Internal.Types.Fork a)
instance GHC.Show.Show a => GHC.Show.Show (Test.StateMachine.Internal.Types.Fork a)
instance GHC.Base.Functor Test.StateMachine.Internal.Types.Fork
instance GHC.Classes.Eq a => GHC.Classes.Eq (Test.StateMachine.Internal.Types.Fork a)
instance GHC.Classes.Eq (Test.StateMachine.Internal.Types.Internal act) => GHC.Classes.Eq (Test.StateMachine.Internal.Types.Program act)
instance GHC.Base.Monoid (Test.StateMachine.Internal.Types.Program act)
instance (GHC.Show.Show (Test.StateMachine.Types.Untyped act), Test.StateMachine.Types.HFunctor.HFoldable act) => GHC.Show.Show (Test.StateMachine.Internal.Types.Program act)
instance GHC.Read.Read (Test.StateMachine.Internal.Types.Internal act) => GHC.Read.Read (Test.StateMachine.Internal.Types.Program act)
instance (GHC.Show.Show (Test.StateMachine.Types.Untyped act), Test.StateMachine.Types.HFunctor.HFoldable act) => GHC.Show.Show (Test.StateMachine.Internal.Types.ParallelProgram act)
-- | This module contains functions for visualing a history of a parallel
-- execution.
module Test.StateMachine.Internal.Utils.BoxDrawer
-- | Event invocation or response.
data EventType
Open :: EventType
Close :: EventType
-- | Given a history, and output from processes generate Doc with boxes
exec :: [(EventType, Pid)] -> Fork [String] -> Doc
instance GHC.Show.Show Test.StateMachine.Internal.Utils.BoxDrawer.EventType
-- | This module contains helpers for generating, shrinking, and checking
-- sequential programs.
module Test.StateMachine.Internal.Sequential
-- | Generate programs whose actions all respect their pre-conditions.
generateProgram :: forall model act. Generator model act -> Precondition model act -> Transition model act -> Int -> StateT (model Symbolic) Gen (Program act)
-- | Filter out invalid actions from a program. An action is invalid if
-- either its pre-condition doesn't hold, or it uses references that are
-- not in scope.
filterInvalid :: HFoldable act => Precondition model act -> Transition model act -> Program act -> State (model Symbolic, Set Var) (Program act)
-- | Returns the set of references an action uses.
getUsedVars :: HFoldable act => act Symbolic a -> Set Var
-- | Given a shrinker of typed actions we can lift it to a shrinker of
-- internal actions.
liftShrinkInternal :: Shrinker act -> (Internal act -> [Internal act])
-- | Shrink a program in a pre-condition and scope respecting way.
shrinkProgram :: HFoldable act => Shrinker act -> Precondition model act -> Transition model act -> model Symbolic -> Program act -> [Program act]
-- | For each action in a program, check that if the pre-condition holds
-- for the action, then so does the post-condition.
checkProgram :: Monad m => HFunctor act => Precondition model act -> Transition model act -> Postcondition model act -> model Symbolic -> model Concrete -> Semantics act m -> Program act -> PropertyM (StateT Environment m) ()
-- | This module provides scope-checking for internal actions. This
-- functionality isn't used anywhere in the library, but can be useful
-- for writing metaproperties.
module Test.StateMachine.Internal.ScopeCheck
-- | Scope-check a program, i.e. make sure that no action uses a reference
-- that doesn't exist.
scopeCheck :: forall act. HFoldable act => Program act -> Bool
-- | Same as above, but for parallel programs.
scopeCheckParallel :: HFoldable act => ParallelProgram act -> Bool
-- | This module contains helpers for generating, shrinking, and checking
-- parallel programs.
module Test.StateMachine.Internal.Parallel
-- | Generate a parallel program whose actions all respect their
-- pre-conditions.
generateParallelProgram :: Generator model act -> Precondition model act -> Transition model act -> model Symbolic -> Gen (ParallelProgram act)
-- | Shrink a parallel program in a pre-condition and scope respecting way.
shrinkParallelProgram :: HFoldable act => Shrinker act -> Precondition model act -> Transition model act -> model Symbolic -> (ParallelProgram act -> [ParallelProgram act])
-- | Run a parallel program, by first executing the prefix sequentially and
-- then the suffixes in parallel, and return the history (or trace) of
-- the execution.
executeParallelProgram :: forall act. HTraversable act => Show (Untyped act) => Semantics act IO -> ParallelProgram act -> IO (History act)
-- | Check if a history from a parallel execution can be linearised.
checkParallelProgram :: HFoldable act => Transition model act -> Postcondition model act -> InitialModel model -> ParallelProgram act -> History act -> Property
-- | A history is a trace of invocations and responses from running a
-- parallel program.
newtype History act
History :: History' act -> History act
[unHistory] :: History act -> History' act
-- | This module provides <math>-equality for internal actions. This
-- functionality isn't used anywhere in the library, but can be useful
-- for writing metaproperties.
module Test.StateMachine.Internal.AlphaEquality
-- | Check if two lists of actions are equal modulo
-- <math>-conversion.
alphaEq :: (HFunctor act, Eq (Program act)) => Program act -> Program act -> Bool
-- | Check if two forks of actions are equal modulo
-- <math>-conversion.
alphaEqFork :: (HFunctor act, Eq (Program act)) => Fork (Program act) -> Fork (Program act) -> Bool
-- | The main module for state machine based testing, it contains
-- combinators that help you build sequential and parallel properties.
module Test.StateMachine
-- | A (sequential) program is an abstract datatype representing a list of
-- actions.
--
-- The idea is that the user shows how to generate, shrink, execute and
-- modelcheck individual actions, and then the below combinators lift
-- those things to whole programs.
data Program act
-- | This function is like a forAllShrink for sequential programs.
forAllProgram :: Show (Untyped act) => HFoldable act => Generator model act -> Shrinker act -> Precondition model act -> Transition model act -> InitialModel model -> (Program act -> Property) -> Property
-- | Run a sequential program and check if your model agrees with your
-- semantics.
runAndCheckProgram :: Monad m => HFunctor act => Precondition model act -> Transition model act -> Postcondition model act -> InitialModel model -> Semantics act m -> (m Property -> Property) -> Program act -> Property
-- | Same as above, except with the possibility to setup some resource for
-- the runner to use. The resource could be a database connection for
-- example.
runAndCheckProgram' :: Monad m => HFunctor act => Precondition model act -> Transition model act -> Postcondition model act -> InitialModel model -> Semantics act m -> IO setup -> (setup -> m Property -> Property) -> (setup -> IO ()) -> Program act -> Property
-- | A parallel program is an abstract datatype that represents three
-- sequences of actions; a sequential prefix and two parallel suffixes.
-- Analogous to the sequential case, the user shows how to generate,
-- shrink, execute and modelcheck individual actions, and then the below
-- combinators lift those things to whole parallel programs.
data ParallelProgram act
-- | This function is like a forAllShrink for parallel programs.
forAllParallelProgram :: Show (Untyped act) => HFoldable act => Generator model act -> Shrinker act -> Precondition model act -> Transition model act -> InitialModel model -> (ParallelProgram act -> Property) -> Property
-- | A history is a trace of invocations and responses from running a
-- parallel program.
data History act
-- | Run a parallel program and collect the history of the execution.
runParallelProgram :: Show (Untyped act) => HTraversable act => Semantics act IO -> ParallelProgram act -> (History act -> Property) -> Property
-- | Same as above, but with the possibility of setting up some resource.
runParallelProgram' :: Show (Untyped act) => HTraversable act => IO setup -> (setup -> Semantics act IO) -> (setup -> IO ()) -> ParallelProgram act -> (History act -> Property) -> Property
-- | Check if a history from a parallel execution can be linearised.
checkParallelProgram :: HFoldable act => Transition model act -> Postcondition model act -> InitialModel model -> ParallelProgram act -> History act -> Property