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.Around

Synopsis

Documentation

before :: IO c -> TestDefM a c e -> TestDefM a () e Source #

Run a custom action before every spec item, to set up an inner resource c.

before_ :: IO () -> TestDefM a c e -> TestDefM a c e Source #

Run a custom action before every spec item without setting up any inner resources.

after :: (c -> IO ()) -> TestDefM a c e -> TestDefM a c e Source #

Run a custom action after every spec item, using the inner resource c.

after_ :: IO () -> TestDefM a c e -> TestDefM a c e Source #

Run a custom action after every spec item without using any inner resources.

around :: ((c -> IO ()) -> IO ()) -> TestDefM a c e -> TestDefM a () e Source #

Run a custom action before and/or after every spec item, to provide access to an inner resource c.

See the FOOTGUN note in the docs for around_.

around_ :: (IO () -> IO ()) -> TestDefM a c e -> TestDefM a c e Source #

Run a custom action before and/or after every spec item without accessing any inner resources.

It is important that the wrapper function that you provide runs the action that it gets _exactly once_.

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 ()
   around_ 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 aroundAll_.

The same thing will go wrong if you run the given action more than once like this:

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

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.

aroundWith :: forall a c d r. ((c -> IO ()) -> d -> IO ()) -> TestDefM a c r -> TestDefM a d r Source #

Run a custom action before and/or after every spec item, to provide access to an inner resource c while using the inner resource d.

See the FOOTGUN note in the docs for around_.

aroundWith' :: forall a c d r (u :: [Type]). HContains u a => ((a -> c -> IO ()) -> a -> d -> IO ()) -> TestDefM u c r -> TestDefM u d r Source #

Run a custom action before and/or after every spec item, to provide access to an inner resource c while using the inner resource d and any outer resource available.