Copyright  (c) 20152018 Michael Walker 

License  MIT 
Maintainer  Michael Walker <mike@barrucadu.co.uk> 
Stability  stable 
Portability  FlexibleContexts, FlexibleInstances, GADTs, LambdaCase, TypeSynonymInstances 
Safe Haskell  None 
Language  Haskell2010 
This module allows using Deja Fu predicates with Tasty to test the behaviour of concurrent systems.
Synopsis
 testAuto :: (Eq a, Show a) => ConcIO a > TestTree
 testDejafu :: Show b => TestName > ProPredicate a b > ConcIO a > TestTree
 testDejafus :: Show b => [(TestName, ProPredicate a b)] > ConcIO a > TestTree
 testAutoWay :: (Eq a, Show a) => Way > MemType > ConcIO a > TestTree
 testDejafuWay :: Show b => Way > MemType > TestName > ProPredicate a b > ConcIO a > TestTree
 testDejafusWay :: Show b => Way > MemType > [(TestName, ProPredicate a b)] > ConcIO a > TestTree
 testAutoWithSettings :: (Eq a, Show a) => Settings IO a > ConcIO a > TestTree
 testDejafuWithSettings :: Show b => Settings IO a > TestName > ProPredicate a b > ConcIO a > TestTree
 testDejafusWithSettings :: Show b => Settings IO a > [(TestName, ProPredicate a b)] > ConcIO a > TestTree
 data Condition
 type Predicate a = ProPredicate a a
 data ProPredicate a b = ProPredicate {}
 module Test.DejaFu.Settings
 testProperty :: (Testable p, Listable (X p), Eq (X p), Show (X p), Show (O p)) => TestName > p > TestTree
 testPropertyFor :: (Testable p, Listable (X p), Eq (X p), Show (X p), Show (O p)) => Int > Int > TestName > p > TestTree
 data Sig s o x = Sig {
 initialise :: x > ConcIO s
 observe :: s > x > ConcIO o
 interfere :: s > x > ConcIO ()
 expression :: s > ConcIO ()
 data RefinementProperty o x
 class Testable a where
 class Listable a where
 expectFailure :: RefinementProperty o x > RefinementProperty o x
 refines :: Ord o => Sig s1 o x > Sig s2 o x > RefinementProperty o x
 (=>=) :: Ord o => Sig s1 o x > Sig s2 o x > RefinementProperty o x
 strictlyRefines :: Ord o => Sig s1 o x > Sig s2 o x > RefinementProperty o x
 (>) :: Ord o => Sig s1 o x > Sig s2 o x > RefinementProperty o x
 equivalentTo :: Ord o => Sig s1 o x > Sig s2 o x > RefinementProperty o x
 (===) :: Ord o => Sig s1 o x > Sig s2 o x > RefinementProperty o x
 testDejafuDiscard :: Show b => (Either Condition a > Maybe Discard) > Way > MemType > String > ProPredicate a b > ConcIO a > TestTree
 testDejafusDiscard :: Show b => (Either Condition a > Maybe Discard) > Way > MemType > [(TestName, ProPredicate a b)] > ConcIO a > TestTree
Unit testing
This is supported by an IsTest
instance for ConcIO
. This
instance tries all executions, reporting as failures the cases
which return a Just
string.
instance IsTest (ConcIO (Maybe String))
instance IsOption Bounds
instance IsOption MemType
Unit testing
Automatically test a computation. In particular, look for deadlocks, uncaught exceptions, and multiple return values.
Since: 1.0.0.0
:: Show b  
=> TestName  The name of the test. 
> ProPredicate a b  The predicate to check. 
> ConcIO a  The computation to test. 
> TestTree 
Check that a predicate holds.
Since: 1.0.0.0
:: Show b  
=> [(TestName, ProPredicate a b)]  The list of predicates (with names) to check. 
> ConcIO a  The computation to test. 
> TestTree 
Variant of testDejafu
which takes a collection of predicates to
test. This will share work between the predicates, rather than
running the concurrent computation many times for each predicate.
Since: 1.0.0.0
:: (Eq a, Show a)  
=> Way  How to execute the concurrent program. 
> MemType  The memory model to use for nonsynchronised 
> ConcIO a  The computation to test. 
> TestTree 
Variant of testAuto
which tests a computation under a given
execution way and memory model.
Since: 1.0.0.0
:: Show b  
=> Way  How to execute the concurrent program. 
> MemType  The memory model to use for nonsynchronised 
> TestName  The name of the test. 
> ProPredicate a b  The predicate to check. 
> ConcIO a  The computation to test. 
> TestTree 
Variant of testDejafu
which takes a way to execute the program
and a memory model.
Since: 1.0.0.0
:: Show b  
=> Way  How to execute the concurrent program. 
> MemType  The memory model to use for nonsynchronised 
> [(TestName, ProPredicate a b)]  The list of predicates (with names) to check. 
> ConcIO a  The computation to test. 
> TestTree 
Variant of testDejafus
which takes a way to execute the program
and a memory model.
Since: 1.0.0.0
Variant of testAuto
which takes a settings record.
Since: 1.1.0.0
testDejafuWithSettings Source #
:: Show b  
=> Settings IO a  The settings record 
> TestName  The name of the test. 
> ProPredicate a b  The predicate to check. 
> ConcIO a  The computation to test. 
> TestTree 
Variant of testDejafu
which takes a settings record.
Since: 1.1.0.0
testDejafusWithSettings Source #
:: Show b  
=> Settings IO a  The SCT settings. 
> [(TestName, ProPredicate a b)]  The list of predicates (with names) to check. 
> ConcIO a  The computation to test. 
> TestTree 
Variant of testDejafus
which takes a settings record.
Since: 1.1.0.0
Reexports
An indication of how a concurrent computation terminated, if it didn't produce a value.
The Eq
, Ord
, and NFData
instances compare/evaluate the
exception with show
in the UncaughtException
case.
Since: dejafu1.12.0.0
Instances
Eq Condition  
Ord Condition  
Defined in Test.DejaFu.Types  
Show Condition  
Generic Condition  
NFData Condition  
Defined in Test.DejaFu.Types  
type Rep Condition  
Defined in Test.DejaFu.Types type Rep Condition = D1 (MetaData "Condition" "Test.DejaFu.Types" "dejafu1.12.0.0DIjpmnM3gUIFghrMy7zMb1" False) ((C1 (MetaCons "Abort" PrefixI False) (U1 :: Type > Type) :+: C1 (MetaCons "Deadlock" PrefixI False) (U1 :: Type > Type)) :+: (C1 (MetaCons "STMDeadlock" PrefixI False) (U1 :: Type > Type) :+: C1 (MetaCons "UncaughtException" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 SomeException)))) 
type Predicate a = ProPredicate a a #
A Predicate
is a function which collapses a list of results
into a Result
, possibly discarding some on the way.
Predicate
cannot be a functor as the type parameter is used both
co and contravariantly.
Since: dejafu1.0.0.0
data ProPredicate a b #
A ProPredicate
is a function which collapses a list of results
into a Result
, possibly discarding some on the way.
Since: dejafu1.0.0.0
Instances
Profunctor ProPredicate  
Defined in Test.DejaFu dimap :: (a > b) > (c > d) > ProPredicate b c > ProPredicate a d # lmap :: (a > b) > ProPredicate b c > ProPredicate a c # rmap :: (b > c) > ProPredicate a b > ProPredicate a c # (#.) :: Coercible c b => q b c > ProPredicate a b > ProPredicate a c # (.#) :: Coercible b a => ProPredicate b c > q a b > ProPredicate a c #  
Functor (ProPredicate x)  
Defined in Test.DejaFu fmap :: (a > b) > ProPredicate x a > ProPredicate x b # (<$) :: a > ProPredicate x b > ProPredicate x a # 
module Test.DejaFu.Settings
Refinement property testing
:: (Testable p, Listable (X p), Eq (X p), Show (X p), Show (O p))  
=> TestName  The name of the test. 
> p  The property to check. 
> TestTree 
Check a refinement property with a variety of seed values and variable assignments.
Since: 0.6.0.0
:: (Testable p, Listable (X p), Eq (X p), Show (X p), Show (O p))  
=> Int  The number of seed values to try. 
> Int  The number of variable assignments per seed value to try. 
> TestName  The name of the test. 
> p  The property to check. 
> TestTree 
Like testProperty
, but takes a number of cases to check.
The maximum number of cases tried by testPropertyFor n m
will be
n * m
.
Since: 0.7.1.0
Reexports
A concurrent function and some information about how to execute it and observe its effect.
s
is the state type (MVar ConcIO a
in the example)o
is the observation type (Maybe a
in the example)x
is the seed type (Maybe a
in the example)
Since: dejafu0.7.0.0
Sig  

data RefinementProperty o x #
A property which can be given to check
.
Since: dejafu0.7.0.0
Instances
Testable (RefinementProperty o x)  
Defined in Test.DejaFu.Refinement type O (RefinementProperty o x) :: Type # type X (RefinementProperty o x) :: Type # rpropTiers :: RefinementProperty o x > [[([String], RefinementProperty (O (RefinementProperty o x)) (X (RefinementProperty o x)))]]  
type X (RefinementProperty o x)  
Defined in Test.DejaFu.Refinement  
type O (RefinementProperty o x)  
Defined in Test.DejaFu.Refinement 
Things which can be tested.
Since: dejafu0.7.0.0
rpropTiers
The observation value type. This is used to compare the results.
The seed value type. This is used to construct the concurrent states.
Instances
(Listable a, Show a, Testable b) => Testable (a > b)  
Defined in Test.DejaFu.Refinement rpropTiers :: (a > b) > [[([String], RefinementProperty (O (a > b)) (X (a > b)))]]  
Testable (RefinementProperty o x)  
Defined in Test.DejaFu.Refinement type O (RefinementProperty o x) :: Type # type X (RefinementProperty o x) :: Type # rpropTiers :: RefinementProperty o x > [[([String], RefinementProperty (O (RefinementProperty o x)) (X (RefinementProperty o x)))]] 
A type is Listable
when there exists a function that
is able to list (ideally all of) its values.
Ideally, instances should be defined by a tiers
function that
returns a (potentially infinite) list of finite sublists (tiers):
the first sublist contains elements of size 0,
the second sublist contains elements of size 1
and so on.
Size here is defined by the implementor of the typeclass instance.
For algebraic data types, the general form for tiers
is
tiers = cons<N> ConstructorA \/ cons<N> ConstructorB \/ ... \/ cons<N> ConstructorZ
where N
is the number of arguments of each constructor A...Z
.
Here is a datatype with 4 constructors and its listable instance:
data MyType = MyConsA  MyConsB Int  MyConsC Int Char  MyConsD String instance Listable MyType where tiers = cons0 MyConsA \/ cons1 MyConsB \/ cons2 MyConsC \/ cons1 MyConsD
The instance for Hutton's Razor is given by:
data Expr = Val Int  Add Expr Expr instance Listable Expr where tiers = cons1 Val \/ cons2 Add
Instances can be alternatively defined by list
.
In this case, each sublist in tiers
is a singleton list
(each succeeding element of list
has +1 size).
The function deriveListable
from Test.LeanCheck.Derive
can automatically derive instances of this typeclass.
A Listable
instance for functions is also available but is not exported by
default. Import Test.LeanCheck.Function if you need to test higherorder
properties.
Instances
Listable Bool  tiers :: [[Bool]] = [[False,True]] list :: [[Bool]] = [False,True] 
Listable Char  list :: [Char] = ['a', ' ', 'b', 'A', 'c', '\', 'n', 'd', ...] 
Listable Double 
list :: [Double] = [0.0, 1.0, 1.0, Infinity, 0.5, 2.0, ...] 
Listable Float 
list :: [Float] = [ 0.0 , 1.0, 1.0, Infinity , 0.5, 2.0, Infinity, 0.5, 2.0 , 0.33333334, 3.0, 0.33333334, 3.0 , 0.25, 0.6666667, 1.5, 4.0, 0.25, 0.6666667, 1.5, 4.0 , ... ] 
Listable Int  tiers :: [[Int]] = [[0], [1], [1], [2], [2], [3], [3], ...] list :: [Int] = [0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, ...] 
Listable Integer  list :: [Int] = [0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, ...] 
Listable Ordering  list :: [Ordering] = [LT, EQ, GT] 
Listable ()  list :: [()] = [()] tiers :: [[()]] = [[()]] 
Defined in Test.LeanCheck.Core  
Listable a => Listable [a]  tiers :: [[ [Int] ]] = [ [ [] ] , [ [0] ] , [ [0,0], [1] ] , [ [0,0,0], [0,1], [1,0], [1] ] , ... ] list :: [ [Int] ] = [ [], [0], [0,0], [1], [0,0,0], ... ] 
Defined in Test.LeanCheck.Core  
Listable a => Listable (Maybe a)  tiers :: [[Maybe Int]] = [[Nothing], [Just 0], [Just 1], ...] tiers :: [[Maybe Bool]] = [[Nothing], [Just False, Just True]] 
(Listable a, Listable b) => Listable (Either a b)  tiers :: [[Either Bool Bool]] = [[Left False, Right False, Left True, Right True]] tiers :: [[Either Int Int]] = [ [Left 0, Right 0] , [Left 1, Right 1] , [Left (1), Right (1)] , [Left 2, Right 2] , ... ] 
(Listable a, Listable b) => Listable (a, b)  tiers :: [[(Int,Int)]] = [ [(0,0)] , [(0,1),(1,0)] , [(0,1),(1,1),(1,0)] , ...] list :: [(Int,Int)] = [ (0,0), (0,1), (1,0), (0,1), (1,1), ...] 
Defined in Test.LeanCheck.Core  
(Listable a, Listable b, Listable c) => Listable (a, b, c)  list :: [(Int,Int,Int)] = [ (0,0,0), (0,0,1), (0,1,0), ...] 
Defined in Test.LeanCheck.Core  
(Listable a, Listable b, Listable c, Listable d) => Listable (a, b, c, d)  
Defined in Test.LeanCheck.Core  
(Listable a, Listable b, Listable c, Listable d, Listable e) => Listable (a, b, c, d, e)  
Defined in Test.LeanCheck.Core 
expectFailure :: RefinementProperty o x > RefinementProperty o x #
Indicates that the property is supposed to fail.
refines :: Ord o => Sig s1 o x > Sig s2 o x > RefinementProperty o x #
Observational refinement.
True iff the resultset of the left expression is a subset (not necessarily proper) of the resultset of the right expression.
The two signatures can have different state types, this lets you compare the behaviour of different data structures. The observation and seed types must match, however.
Since: dejafu0.7.0.0
(=>=) :: Ord o => Sig s1 o x > Sig s2 o x > RefinementProperty o x #
Infix synonym for refines
.
You might think this should be =<=
, so it looks kind of like a
funny subset operator, with A =<= B
meaning "the resultset of A
is a subset of the resultset of B". Unfortunately you would be
wrong. The operator used in the literature for refinement has the
open end pointing at the LESS general term and the closed end at
the MORE general term. It is read as "is refined by", not
"refines". So for consistency with the literature, the open end
of =>=
points at the less general term, and the closed end at the
more general term, to give the same argument order as refines
.
Since: dejafu0.7.0.0
strictlyRefines :: Ord o => Sig s1 o x > Sig s2 o x > RefinementProperty o x #
Strict observational refinement.
True iff the resultset of the left expression is a proper subset of the resultset of the right expression.
The two signatures can have different state types, this lets you compare the behaviour of different data structures. The observation and seed types must match, however.
Since: dejafu0.7.0.0
(>) :: Ord o => Sig s1 o x > Sig s2 o x > RefinementProperty o x #
Infix synonym for strictlyRefines
Since: dejafu0.7.0.0
equivalentTo :: Ord o => Sig s1 o x > Sig s2 o x > RefinementProperty o x #
Observational equivalence.
True iff the resultset of the left expression is equal to the resultset of the right expression.
The two signatures can have different state types, this lets you compare the behaviour of different data structures. The observation and seed types must match, however.
Since: dejafu0.7.0.0
(===) :: Ord o => Sig s1 o x > Sig s2 o x > RefinementProperty o x #
Infix synonym for equivalentTo
.
Since: dejafu0.7.0.0
Deprecated
:: Show b  
=> (Either Condition a > Maybe Discard)  Selectively discard results. 
> Way  How to execute the concurrent program. 
> MemType  The memory model to use for nonsynchronised 
> String  The name of the test. 
> ProPredicate a b  The predicate to check. 
> ConcIO a  The computation to test. 
> TestTree 
Deprecated: Use testDejafuWithSettings instead
Variant of testDejafuWay
which can selectively discard results.
Since: 1.0.0.0
:: Show b  
=> (Either Condition a > Maybe Discard)  Selectively discard results. 
> Way  How to execute the concurrent program. 
> MemType  The memory model to use for nonsynchronised 
> [(TestName, ProPredicate a b)]  The list of predicates (with names) to check. 
> ConcIO a  The computation to test. 
> TestTree 
Deprecated: Use testDejafusWithSettings instead
Variant of testDejafusWay
which can selectively discard
results, beyond what each predicate already discards.
Since: 1.0.1.0
Orphan instances
IsOption Way Source #  Since: 0.5.0.0 
defaultValue :: Way # parseValue :: String > Maybe Way # optionName :: Tagged Way String # optionHelp :: Tagged Way String # optionCLParser :: Parser Way #  
IsOption MemType Source #  Since: 0.3.0.0 
defaultValue :: MemType # parseValue :: String > Maybe MemType # optionName :: Tagged MemType String #  
IsTest (ConcIO (Maybe String)) Source #  Since: 0.3.0.0 