{-# LANGUAGE DataKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeOperators #-}
module Test.Syd.Def.SetupFunc where
import Control.Exception
import Control.Monad.IO.Class
import Test.Syd.Def.Around
import Test.Syd.Def.AroundAll
import Test.Syd.Def.TestDefM
import Test.Syd.HList
newtype SetupFunc resource = SetupFunc
{ SetupFunc resource -> forall r. (resource -> IO r) -> IO r
unSetupFunc :: forall r. (resource -> IO r) -> IO r
}
instance Functor SetupFunc where
fmap :: (a -> b) -> SetupFunc a -> SetupFunc b
fmap a -> b
f (SetupFunc forall r. (a -> IO r) -> IO r
provideA) = (forall r. (b -> IO r) -> IO r) -> SetupFunc b
forall resource.
(forall r. (resource -> IO r) -> IO r) -> SetupFunc resource
SetupFunc ((forall r. (b -> IO r) -> IO r) -> SetupFunc b)
-> (forall r. (b -> IO r) -> IO r) -> SetupFunc b
forall a b. (a -> b) -> a -> b
$ \b -> IO r
takeB ->
let takeA :: a -> IO r
takeA = \a
a -> b -> IO r
takeB (b -> IO r) -> b -> IO r
forall a b. (a -> b) -> a -> b
$ a -> b
f a
a
in (a -> IO r) -> IO r
forall r. (a -> IO r) -> IO r
provideA a -> IO r
takeA
instance Applicative SetupFunc where
pure :: a -> SetupFunc a
pure a
a = (forall r. (a -> IO r) -> IO r) -> SetupFunc a
forall resource.
(forall r. (resource -> IO r) -> IO r) -> SetupFunc resource
SetupFunc ((forall r. (a -> IO r) -> IO r) -> SetupFunc a)
-> (forall r. (a -> IO r) -> IO r) -> SetupFunc a
forall a b. (a -> b) -> a -> b
$ \a -> IO r
aFunc -> a -> IO r
aFunc a
a
(SetupFunc forall r. ((a -> b) -> IO r) -> IO r
provideF) <*> :: SetupFunc (a -> b) -> SetupFunc a -> SetupFunc b
<*> (SetupFunc forall r. (a -> IO r) -> IO r
provideA) = (forall r. (b -> IO r) -> IO r) -> SetupFunc b
forall resource.
(forall r. (resource -> IO r) -> IO r) -> SetupFunc resource
SetupFunc ((forall r. (b -> IO r) -> IO r) -> SetupFunc b)
-> (forall r. (b -> IO r) -> IO r) -> SetupFunc b
forall a b. (a -> b) -> a -> b
$ \b -> IO r
takeB ->
((a -> b) -> IO r) -> IO r
forall r. ((a -> b) -> IO r) -> IO r
provideF
( \a -> b
f ->
(a -> IO r) -> IO r
forall r. (a -> IO r) -> IO r
provideA
( \a
a ->
b -> IO r
takeB (a -> b
f a
a)
)
)
instance Monad SetupFunc where
(SetupFunc forall r. (a -> IO r) -> IO r
provideA) >>= :: SetupFunc a -> (a -> SetupFunc b) -> SetupFunc b
>>= a -> SetupFunc b
m = (forall r. (b -> IO r) -> IO r) -> SetupFunc b
forall resource.
(forall r. (resource -> IO r) -> IO r) -> SetupFunc resource
SetupFunc ((forall r. (b -> IO r) -> IO r) -> SetupFunc b)
-> (forall r. (b -> IO r) -> IO r) -> SetupFunc b
forall a b. (a -> b) -> a -> b
$ \b -> IO r
takeB ->
(a -> IO r) -> IO r
forall r. (a -> IO r) -> IO r
provideA
( \a
a ->
let (SetupFunc forall r. (b -> IO r) -> IO r
provideB) = a -> SetupFunc b
m a
a
in (b -> IO r) -> IO r
forall r. (b -> IO r) -> IO r
provideB (\b
b -> b -> IO r
takeB b
b)
)
instance MonadIO SetupFunc where
liftIO :: IO a -> SetupFunc a
liftIO IO a
ioFunc = (forall r. (a -> IO r) -> IO r) -> SetupFunc a
forall resource.
(forall r. (resource -> IO r) -> IO r) -> SetupFunc resource
SetupFunc ((forall r. (a -> IO r) -> IO r) -> SetupFunc a)
-> (forall r. (a -> IO r) -> IO r) -> SetupFunc a
forall a b. (a -> b) -> a -> b
$ \a -> IO r
takeA -> do
IO a
ioFunc IO a -> (a -> IO r) -> IO r
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= a -> IO r
takeA
bracketSetupFunc :: IO resource -> (resource -> IO r) -> SetupFunc resource
bracketSetupFunc :: IO resource -> (resource -> IO r) -> SetupFunc resource
bracketSetupFunc IO resource
acquire resource -> IO r
release = (forall r. (resource -> IO r) -> IO r) -> SetupFunc resource
forall resource.
(forall r. (resource -> IO r) -> IO r) -> SetupFunc resource
SetupFunc ((forall r. (resource -> IO r) -> IO r) -> SetupFunc resource)
-> (forall r. (resource -> IO r) -> IO r) -> SetupFunc resource
forall a b. (a -> b) -> a -> b
$ \resource -> IO r
func -> IO resource -> (resource -> IO r) -> (resource -> IO r) -> IO r
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket IO resource
acquire resource -> IO r
release resource -> IO r
func
setupAround ::
SetupFunc inner ->
TestDefM outers inner result ->
TestDefM outers () result
setupAround :: SetupFunc inner
-> TestDefM outers inner result -> TestDefM outers () result
setupAround SetupFunc inner
setupFunc = (() -> SetupFunc inner)
-> TestDefM outers inner result -> TestDefM outers () result
forall oldInner newInner (outers :: [*]) result.
(oldInner -> SetupFunc newInner)
-> TestDefM outers newInner result
-> TestDefM outers oldInner result
setupAroundWith ((() -> SetupFunc inner)
-> TestDefM outers inner result -> TestDefM outers () result)
-> (() -> SetupFunc inner)
-> TestDefM outers inner result
-> TestDefM outers () result
forall a b. (a -> b) -> a -> b
$ \() -> SetupFunc inner
setupFunc
setupAroundWith ::
(oldInner -> SetupFunc newInner) ->
TestDefM outers newInner result ->
TestDefM outers oldInner result
setupAroundWith :: (oldInner -> SetupFunc newInner)
-> TestDefM outers newInner result
-> TestDefM outers oldInner result
setupAroundWith oldInner -> SetupFunc newInner
takeOldInner = ((newInner -> IO ()) -> oldInner -> IO ())
-> TestDefM outers newInner result
-> TestDefM outers oldInner result
forall newInner oldInner (outers :: [*]) result.
((newInner -> IO ()) -> oldInner -> IO ())
-> TestDefM outers newInner result
-> TestDefM outers oldInner result
aroundWith (((newInner -> IO ()) -> oldInner -> IO ())
-> TestDefM outers newInner result
-> TestDefM outers oldInner result)
-> ((newInner -> IO ()) -> oldInner -> IO ())
-> TestDefM outers newInner result
-> TestDefM outers oldInner result
forall a b. (a -> b) -> a -> b
$ \newInner -> IO ()
takeNewInner oldInner
oldInner ->
let SetupFunc forall r. (newInner -> IO r) -> IO r
provideNewInner = oldInner -> SetupFunc newInner
takeOldInner oldInner
oldInner
in (newInner -> IO ()) -> IO ()
forall r. (newInner -> IO r) -> IO r
provideNewInner ((newInner -> IO ()) -> IO ()) -> (newInner -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \newInner
newInner -> newInner -> IO ()
takeNewInner newInner
newInner
setupAroundWith' ::
HContains outers outer =>
(outer -> oldInner -> SetupFunc newInner) ->
TestDefM outers newInner result ->
TestDefM outers oldInner result
setupAroundWith' :: (outer -> oldInner -> SetupFunc newInner)
-> TestDefM outers newInner result
-> TestDefM outers oldInner result
setupAroundWith' outer -> oldInner -> SetupFunc newInner
f = ((outer -> newInner -> IO ()) -> outer -> oldInner -> IO ())
-> TestDefM outers newInner result
-> TestDefM outers oldInner result
forall newInner oldInner outer result (outers :: [*]).
HContains outers outer =>
((outer -> newInner -> IO ()) -> outer -> oldInner -> IO ())
-> TestDefM outers newInner result
-> TestDefM outers oldInner result
aroundWith' (((outer -> newInner -> IO ()) -> outer -> oldInner -> IO ())
-> TestDefM outers newInner result
-> TestDefM outers oldInner result)
-> ((outer -> newInner -> IO ()) -> outer -> oldInner -> IO ())
-> TestDefM outers newInner result
-> TestDefM outers oldInner result
forall a b. (a -> b) -> a -> b
$ \outer -> newInner -> IO ()
takeBoth outer
outer oldInner
oldInner ->
let SetupFunc forall r. (newInner -> IO r) -> IO r
provideNewInner = outer -> oldInner -> SetupFunc newInner
f outer
outer oldInner
oldInner
in (newInner -> IO ()) -> IO ()
forall r. (newInner -> IO r) -> IO r
provideNewInner ((newInner -> IO ()) -> IO ()) -> (newInner -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \newInner
newInner -> outer -> newInner -> IO ()
takeBoth outer
outer newInner
newInner
setupAroundAll ::
SetupFunc outer ->
TestDefM (outer : outers) inner result ->
TestDefM outers inner result
setupAroundAll :: SetupFunc outer
-> TestDefM (outer : outers) inner result
-> TestDefM outers inner result
setupAroundAll SetupFunc outer
sf = ((outer -> IO ()) -> IO ())
-> TestDefM (outer : outers) inner result
-> TestDefM outers inner result
forall outer (otherOuters :: [*]) inner result.
((outer -> IO ()) -> IO ())
-> TestDefM (outer : otherOuters) inner result
-> TestDefM otherOuters inner result
aroundAll (((outer -> IO ()) -> IO ())
-> TestDefM (outer : outers) inner result
-> TestDefM outers inner result)
-> ((outer -> IO ()) -> IO ())
-> TestDefM (outer : outers) inner result
-> TestDefM outers inner result
forall a b. (a -> b) -> a -> b
$ \outer -> IO ()
func -> SetupFunc outer -> (outer -> IO ()) -> IO ()
forall resource.
SetupFunc resource -> forall r. (resource -> IO r) -> IO r
unSetupFunc SetupFunc outer
sf outer -> IO ()
func
setupAroundAllWith ::
(oldOuter -> SetupFunc newOuter) ->
TestDefM (newOuter ': oldOuter ': outers) inner result ->
TestDefM (oldOuter ': outers) inner result
setupAroundAllWith :: (oldOuter -> SetupFunc newOuter)
-> TestDefM (newOuter : oldOuter : outers) inner result
-> TestDefM (oldOuter : outers) inner result
setupAroundAllWith oldOuter -> SetupFunc newOuter
sf = ((newOuter -> IO ()) -> oldOuter -> IO ())
-> TestDefM (newOuter : oldOuter : outers) inner result
-> TestDefM (oldOuter : outers) inner result
forall newOuter oldOuter (otherOuters :: [*]) inner result.
((newOuter -> IO ()) -> oldOuter -> IO ())
-> TestDefM (newOuter : oldOuter : otherOuters) inner result
-> TestDefM (oldOuter : otherOuters) inner result
aroundAllWith (((newOuter -> IO ()) -> oldOuter -> IO ())
-> TestDefM (newOuter : oldOuter : outers) inner result
-> TestDefM (oldOuter : outers) inner result)
-> ((newOuter -> IO ()) -> oldOuter -> IO ())
-> TestDefM (newOuter : oldOuter : outers) inner result
-> TestDefM (oldOuter : outers) inner result
forall a b. (a -> b) -> a -> b
$ \newOuter -> IO ()
takeNewOuter oldOuter
oldOuter ->
let SetupFunc forall r. (newOuter -> IO r) -> IO r
provideNewOuter = oldOuter -> SetupFunc newOuter
sf oldOuter
oldOuter
in (newOuter -> IO ()) -> IO ()
forall r. (newOuter -> IO r) -> IO r
provideNewOuter ((newOuter -> IO ()) -> IO ()) -> (newOuter -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \newOuter
newOuter -> newOuter -> IO ()
takeNewOuter newOuter
newOuter