Skip to content

Instantly share code, notes, and snippets.

@jfischoff
Created December 23, 2019 15:38
Show Gist options
  • Save jfischoff/5cf62b82e1dd7d03c8a610ef7fd933ff to your computer and use it in GitHub Desktop.
Save jfischoff/5cf62b82e1dd7d03c8a610ef7fd933ff to your computer and use it in GitHub Desktop.
aroundAll :: forall a. ((a -> IO ()) -> IO ()) -> SpecWith a -> Spec
aroundAll withFunc specWith = do
(var, stopper, asyncer) <- runIO $
(,,) <$> newEmptyMVar <*> newEmptyMVar <*> newIORef Nothing
let theStart :: IO a
theStart = do
thread <- async $ do
withFunc $ \x -> do
putMVar var x
takeMVar stopper
pure $ error "Don't evaluate this"
writeIORef asyncer $ Just thread
either pure pure =<< (wait thread `race` takeMVar var)
theStop :: a -> IO ()
theStop _ = do
putMVar stopper ()
traverse_ cancel =<< readIORef asyncer
beforeAll theStart $ afterAll theStop $ specWith
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment