module Test.StateMachine.Types
(
Untyped(..)
, StateMachine
, stateMachine
, okTransition
, okPostcondition
, okSemantics
, StateMachine'(..)
, Generator
, Shrinker
, Precondition
, Transition
, Transition'
, Postcondition
, Postcondition'
, InitialModel
, Result(..)
, ppResult
, Semantics
, Semantics'
, Runner
, Reason(..)
, module Test.StateMachine.Types.Generics
, module Test.StateMachine.Types.HFunctor
, module Test.StateMachine.Types.References
)
where
import Data.Functor.Classes
(Ord1, Show1)
import Data.Typeable
(Typeable)
import Data.Void
(Void, absurd)
import Test.QuickCheck
(Gen, Property)
import Test.StateMachine.Types.Generics
import Test.StateMachine.Types.HFunctor
import Test.StateMachine.Types.References
data Untyped (act :: (* -> *) -> * -> *) where
Untyped :: (Show resp, Typeable resp) => act Symbolic resp -> Untyped act
type StateMachine model act m = StateMachine' model act m Void
data StateMachine' model act m err = StateMachine
{ generator' :: Generator model act
, shrinker' :: Shrinker act
, precondition' :: Precondition model act
, transition' :: Transition' model act err
, postcondition' :: Postcondition' model act err
, model' :: InitialModel model
, semantics' :: Semantics' act m err
, runner' :: Runner m
}
stateMachine
:: forall m model act
. Functor m
=> Generator model act
-> Shrinker act
-> Precondition model act
-> Transition model act
-> Postcondition model act
-> InitialModel model
-> Semantics act m
-> Runner m
-> StateMachine' model act m Void
stateMachine gen shr precond trans post model sem run =
StateMachine gen shr precond (okTransition trans)
(okPostcondition post) model (okSemantics sem) run
okTransition :: Transition model act -> Transition' model act Void
okTransition transition model act (Success resp) = transition model act resp
okTransition _ _ _ (Fail false) = absurd false
okPostcondition :: Postcondition model act -> Postcondition' model act Void
okPostcondition postcondition model act (Success resp) = postcondition model act resp
okPostcondition _ _ _ (Fail false) = absurd false
okSemantics :: Functor m => Semantics act m -> Semantics' act m Void
okSemantics sem = fmap Success . sem
type Generator model act = model Symbolic -> Gen (Untyped act)
type Shrinker act = forall (v :: * -> *) resp.
act v resp -> [act v resp]
type Precondition model act = forall resp.
model Symbolic -> act Symbolic resp -> Bool
type Transition model act = forall resp v. (Ord1 v, Show1 v) =>
model v -> act v resp -> v resp -> model v
type Transition' model act err = forall resp v. (Ord1 v, Show1 v) =>
model v -> act v resp -> Result err (v resp) -> model v
type Postcondition model act = forall resp.
model Concrete -> act Concrete resp -> resp -> Bool
type Postcondition' model act err = forall resp.
model Concrete -> act Concrete resp -> Result err resp -> Bool
type InitialModel m = forall (v :: * -> *). m v
type Semantics act m = forall resp. act Concrete resp -> m resp
data Result err resp = Success resp | Fail err
deriving Functor
ppResult :: (Show err, Show resp) => Result err resp -> String
ppResult (Success resp) = show resp
ppResult (Fail err) = show err
type Semantics' act m err = forall resp. act Concrete resp -> m (Result err resp)
type Runner m = m Property -> IO Property
data Reason = Ok | PreconditionFailed | PostconditionFailed
deriving (Eq, Show)