sydtest-0.0.0.0: An advanced modern testing framework for Haskell with good defaults and advanced testing features.
Safe HaskellNone
LanguageHaskell2010

Test.Syd.Def.AroundAll

Description

This module defines all the functions you will use to define your test suite.

Synopsis

Documentation

beforeAll :: IO a -> TestDefM (a ': l) c e -> TestDefM l c e Source #

Run a custom action before all spec items in a group, to set up an outer resource a.

beforeAll_ :: IO () -> TestDefM a b e -> TestDefM a b e Source #

Run a custom action before all spec items in a group without setting up any outer resources.

beforeAllWith :: (b -> IO a) -> TestDefM (a ': (b ': l)) c e -> TestDefM (b ': l) c e Source #

Run a custom action before all spec items in a group, to set up an outer resource b by using the outer resource a.

afterAll :: (a -> IO ()) -> TestDefM (a ': l) b e -> TestDefM (a ': l) b e Source #

Run a custom action after all spec items, using the outer resource a.

afterAll' :: (HList l -> IO ()) -> TestDefM l b e -> TestDefM l b e Source #

Run a custom action after all spec items, using all the outer resources.

afterAll_ :: IO () -> TestDefM a b e -> TestDefM a b e Source #

Run a custom action after all spec items without using any outer resources.

aroundAll :: ((a -> IO ()) -> IO ()) -> TestDefM (a ': l) c e -> TestDefM l c e Source #

Run a custom action before and/or after all spec items in group, to provide access to a resource a.

See the FOOTGUN note in the docs for around_.

aroundAll_ :: (IO () -> IO ()) -> TestDefM a b e -> TestDefM a b e Source #

Run a custom action before and/or after all spec items in a group without accessing any resources.

FOOTGUN

Expand

This combinator gives the programmer a lot of power. In fact, it gives the programmer enough power to break the test framework. Indeed, you can provide a wrapper function that just _doesn't_ run the function like this:

spec :: Spec
spec = do
   let don'tDo :: IO () -> IO ()
       don'tDo _ = pure ()
   aroundAll_ don'tDo $ do
     it "should pass" True

During execution, you'll then get an error like this:

thread blocked indefinitely in an MVar operation

The same problem exists when using around_.

Something even more pernicious goes wrong when you run the given action more than once like this:

spec :: Spec
spec = do
   let doTwice :: IO () -> IO ()
       doTwice f = f >> f
   aroundAll_ doTwice $ do
     it "should pass" True

In this case, the test will "just work", but it will be executed twice even if the output reports that it only passed once.

Note: If you're interested in fixing this, talk to me, but only after GHC has gotten impredicative types because that will likely be a requirement.

aroundAllWith :: forall a b c l r. ((a -> IO ()) -> b -> IO ()) -> TestDefM (a ': (b ': l)) c r -> TestDefM (b ': l) c r Source #

Run a custom action before and/or after all spec items in a group to provide access to a resource a while using a resource b

See the FOOTGUN note in the docs for around_.

wrapRWST :: (TestForest a c -> TestTree b d) -> TestDefM a c l -> TestDefM b d l Source #

Declare a node in the spec def forest