easytest-0.3: src/EasyTest/Internal/Hedgehog.hs
{-# LANGUAGE CPP #-}
-- |
-- Module : EasyTest.Internal.Hedgehog
-- Copyright : (c) Joel Burget, 2018-2019
-- License : MIT
-- Maintainer : joelburget@gmail.com
-- Stability : experimental
--
-- This module defines 'recheckSeed', which just checks a 'Group' using a given
-- seed.
module EasyTest.Internal.Hedgehog (recheckSeed) where
import Control.Monad.IO.Class
import Control.Concurrent.STM.TVar (TVar, modifyTVar', newTVar,
readTVar)
import Control.Monad.STM (atomically)
#if !(MIN_VERSION_base(4,11,0))
import Data.Semigroup
#endif
import Hedgehog hiding (Test)
import Hedgehog.Internal.Config
import Hedgehog.Internal.Property
import Hedgehog.Internal.Queue
import Hedgehog.Internal.Region
import Hedgehog.Internal.Report
import Hedgehog.Internal.Runner hiding (checkNamed)
-- | 'Hedgehog.Internal.Runner.checkNamed' modified to take a 'Seed'
checkNamed ::
MonadIO m
=> Region
-> Maybe UseColor
-> Maybe PropertyName
-> Seed
-> Property
-> m (Report Result)
checkNamed region mcolor name seed prop
= checkRegion region mcolor name 0 seed prop
-- | 'Hedgehog.Internal.Runner.updateSummary' exposed.
updateSummary :: Region -> TVar Summary -> Maybe UseColor -> (Summary -> Summary) -> IO ()
updateSummary sregion svar mcolor f = do
summary <- atomically (modifyTVar' svar f >> readTVar svar)
setRegion sregion =<< renderSummary mcolor summary
-- | 'Hedgehog.Internal.Runner.checkGroupWith' modified to take a 'Seed'
checkGroupWith ::
WorkerCount
-> Verbosity
-> Maybe UseColor
-> Seed
-> [(PropertyName, Property)]
-> IO Summary
checkGroupWith n verbosity mcolor seed props =
displayRegion $ \sregion -> do
svar <- atomically . newTVar $ mempty { summaryWaiting = PropertyCount (length props) }
let
start (TasksRemaining tasks) _ix (name, prop) =
liftIO $ do
updateSummary sregion svar mcolor $ \x -> x {
summaryWaiting =
PropertyCount tasks
, summaryRunning =
summaryRunning x + 1
}
atomically $ do
region <-
case verbosity of
Quiet ->
newEmptyRegion
Normal ->
newOpenRegion
moveToBottom sregion
pure (name, prop, region)
finish (_name, _prop, _region) =
updateSummary sregion svar mcolor $ \x -> x {
summaryRunning =
summaryRunning x - 1
}
finalize (_name, _prop, region) =
finishRegion region
summary <-
fmap (mconcat . fmap (fromResult . reportStatus)) $
runTasks n props start finish finalize $ \(name, prop, region) -> do
result <- checkNamed region mcolor (Just name) seed prop
updateSummary sregion svar mcolor
(<> fromResult (reportStatus result))
pure result
updateSummary sregion svar mcolor (const summary)
pure summary
-- | 'Hedgehog.checkSequential' modified to take a seed and exit on failure
recheckSeed :: MonadIO m => Seed -> Group -> m Summary
recheckSeed seed (Group group props) = liftIO $ do
let config = RunnerConfig {
runnerWorkers =
Just 1
, runnerColor =
Nothing
, runnerVerbosity =
Nothing
}
n <- resolveWorkers (runnerWorkers config)
-- ensure few spare capabilities for concurrent-output, it's likely that
-- our tests will saturate all the capabilities they're given.
updateNumCapabilities (n + 2)
#if mingw32_HOST_OS
hSetEncoding stdout utf8
hSetEncoding stderr utf8
#endif
putStrLn $ "━━━ " ++ unGroupName group ++ " ━━━"
verbosity <- resolveVerbosity (runnerVerbosity config)
checkGroupWith n verbosity (runnerColor config) seed props