4 | import public Evince.Synchronized
10 | mapTree : ((a -> m (TestResult ())) -> b -> m (TestResult ())) -> SpecTree m a -> SpecTree m b
11 | mapTree f (It label loc test) = It label loc (f test)
12 | mapTree f (Describe label children) = Describe label (mapTrees f children)
13 | mapTree f (Focused t) = Focused (mapTree f t)
14 | mapTree f (WithCleanup cleanup children) = WithCleanup cleanup (mapTrees f children)
15 | mapTree f (Pending label reason) = Pending label reason
17 | mapTrees : ((a -> m (TestResult ())) -> b -> m (TestResult ())) -> List (SpecTree m a) -> List (SpecTree m b)
19 | mapTrees f (t :: ts) = mapTree f t :: mapTrees f ts
23 | before : Monad m => m () -> Spec m a () -> Spec m a ()
25 | let trees = mapTrees (\test, res => setup >> test res) (getSpecTrees body)
26 | in MkSpec (Lin <>< trees) ()
30 | after : Monad m => m () -> Spec m a () -> Spec m a ()
31 | after teardown body =
32 | let trees = mapTrees (\test, res => do r <- test res;
teardown;
pure r) (getSpecTrees body)
33 | in MkSpec (Lin <>< trees) ()
39 | around : (m (TestResult ()) -> m (TestResult ())) -> Spec m a () -> Spec m a ()
40 | around wrapper body =
41 | let trees = mapTrees (\test, res => wrapper (test res)) (getSpecTrees body)
42 | in MkSpec (Lin <>< trees) ()
47 | beforeAll : {m : Type -> Type} -> (Synchronized m, HasIO m) => m () -> Spec m a () -> Spec m a ()
48 | beforeAll setup body =
49 | let ref = unsafePerformIO (newIORef False)
50 | lock = unsafePerformIO newLock
51 | wrappedSetup = lock.withLock $
do
52 | done <- liftIO (readIORef ref)
53 | unless done $
do setup;
liftIO (writeIORef ref True)
54 | trees = mapTrees (\test, res => wrappedSetup >> test res) (getSpecTrees body)
55 | in MkSpec (Lin <>< trees) ()
59 | afterAll : m () -> Spec m a () -> Spec m a ()
60 | afterAll cleanup body =
61 | MkSpec [< WithCleanup cleanup (getSpecTrees body)] ()
66 | beforeWith : Monad m => (outer -> m inner) -> Spec m inner () -> Spec m outer ()
68 | let trees = mapTrees (\test, o => f o >>= test) (getSpecTrees body)
69 | in MkSpec (Lin <>< trees) ()
75 | aroundWith : ((inner -> m (TestResult ())) -> outer -> m (TestResult ())) -> Spec m inner () -> Spec m outer ()
77 | let trees = mapTrees f (getSpecTrees body)
78 | in MkSpec (Lin <>< trees) ()
82 | afterWith : Monad m => (a -> m ()) -> Spec m a () -> Spec m a ()
83 | afterWith teardown body =
84 | let trees = mapTrees (\test, res => do r <- test res;
teardown res;
pure r) (getSpecTrees body)
85 | in MkSpec (Lin <>< trees) ()
90 | beforeAllWith : {m : Type -> Type} -> (Synchronized m, HasIO m) => (outer -> m inner) -> Spec m inner () -> Spec m outer ()
91 | beforeAllWith f body =
92 | let ref = unsafePerformIO (newIORef (the (Maybe inner) Nothing))
93 | lock = unsafePerformIO newLock
94 | cachedF = \o => lock.withLock $
do
95 | cached <- liftIO (readIORef ref)
97 | Just val => pure val
98 | Nothing => do val <- f o;
liftIO (writeIORef ref (Just val));
pure val
99 | trees = mapTrees (\test, o => cachedF o >>= test) (getSpecTrees body)
100 | in MkSpec (Lin <>< trees) ()
104 | provide : Monad m => m a -> Spec m a () -> Spec m () ()
105 | provide setup = beforeWith (\() => setup)