4 | import System.Concurrency
10 | mapTree : ((a -> IO (TestResult ())) -> b -> IO (TestResult ())) -> SpecTree a -> SpecTree 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 -> IO (TestResult ())) -> b -> IO (TestResult ())) -> List (SpecTree a) -> List (SpecTree b)
19 | mapTrees f (t :: ts) = mapTree f t :: mapTrees f ts
23 | before : IO () -> Spec a () -> Spec a ()
25 | let trees = mapTrees (\test, res => setup >> test res) (getSpecTrees body)
26 | in MkSpec (Lin <>< trees) ()
30 | after : IO () -> Spec a () -> Spec 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) ()
38 | around : (IO (TestResult ()) -> IO (TestResult ())) -> Spec a () -> Spec a ()
39 | around wrapper body =
40 | let trees = mapTrees (\test, res => wrapper (test res)) (getSpecTrees body)
41 | in MkSpec (Lin <>< trees) ()
46 | beforeAll : IO () -> Spec a () -> Spec a ()
47 | beforeAll setup body =
48 | let ref = unsafePerformIO (newIORef False)
49 | mtx = unsafePerformIO makeMutex
52 | done <- readIORef ref
53 | unless done $
do setup;
writeIORef ref True
55 | trees = mapTrees (\test, res => wrappedSetup >> test res) (getSpecTrees body)
56 | in MkSpec (Lin <>< trees) ()
60 | afterAll : IO () -> Spec a () -> Spec a ()
61 | afterAll cleanup body =
62 | MkSpec [< WithCleanup cleanup (getSpecTrees body)] ()
67 | beforeWith : (outer -> IO inner) -> Spec inner () -> Spec outer ()
69 | let trees = mapTrees (\test, o => f o >>= test) (getSpecTrees body)
70 | in MkSpec (Lin <>< trees) ()
74 | aroundWith : ((inner -> IO (TestResult ())) -> outer -> IO (TestResult ())) -> Spec inner () -> Spec outer ()
76 | let trees = mapTrees f (getSpecTrees body)
77 | in MkSpec (Lin <>< trees) ()
81 | afterWith : (a -> IO ()) -> Spec a () -> Spec a ()
82 | afterWith teardown body =
83 | let trees = mapTrees (\test, res => do r <- test res;
teardown res;
pure r) (getSpecTrees body)
84 | in MkSpec (Lin <>< trees) ()
89 | beforeAllWith : (outer -> IO inner) -> Spec inner () -> Spec outer ()
90 | beforeAllWith f body =
91 | let ref : IORef (Maybe inner) = unsafePerformIO (newIORef Nothing)
92 | mtx = unsafePerformIO makeMutex
95 | cached <- readIORef ref
96 | val <- case cached of
97 | Just val => pure val
98 | Nothing => do val <- f o;
writeIORef ref (Just val);
pure val
101 | trees = mapTrees (\test, o => cachedF o >>= test) (getSpecTrees body)
102 | in MkSpec (Lin <>< trees) ()
106 | provide : IO a -> Spec a () -> Spec () ()
107 | provide setup = beforeWith (\() => setup)