sydtest-0.12.0.0: src/Test/Syd/Runner/Single.hs
{-# LANGUAGE ScopedTypeVariables #-}
module Test.Syd.Runner.Single (runSingleTestWithFlakinessMode) where
import Data.List.NonEmpty (NonEmpty (..))
import qualified Data.List.NonEmpty as NE
import Test.Syd.HList
import Test.Syd.Run
import Test.Syd.SpecDef
-- | Run a single test.
--
-- Run the test up to 'maxRetries' times.
-- Finish as soon as the test passes once, or when we run out of retries.
runSingleTestWithFlakinessMode ::
forall externalResources t.
-- | How to report test progress
ProgressReporter ->
-- | External resources
HList externalResources ->
-- | Test definition
TDef
( ProgressReporter ->
((HList externalResources -> () -> t) -> t) ->
IO TestRunResult
) ->
-- | Max retries
Word ->
-- | Flakiness mode
FlakinessMode ->
-- | Expectation mode
ExpectationMode ->
-- | Test result
IO TestRunReport
runSingleTestWithFlakinessMode progressReporter l td maxRetries fm em = do
results <- runSingleTestWithRetries progressReporter l td maxRetries em
pure
TestRunReport
{ testRunReportExpectationMode = em,
testRunReportRawResults = results,
testRunReportFlakinessMode = fm
}
runSingleTestWithRetries ::
forall externalResources t.
-- | How to report test progress
ProgressReporter ->
-- | External resources
HList externalResources ->
-- | Test definition
TDef
( ProgressReporter ->
((HList externalResources -> () -> t) -> t) ->
IO TestRunResult
) ->
-- | Max retries
Word ->
-- | Expectation mode
ExpectationMode ->
-- If the test ever passed, and the last test result
IO (NonEmpty TestRunResult)
runSingleTestWithRetries progressReporter l td maxRetries em = go maxRetries
where
go :: Word -> IO (NonEmpty TestRunResult)
go w
| w <= 1 = (:| []) <$> runFunc
| otherwise = do
result <- runFunc
if testStatusMatchesExpectationMode (testRunResultStatus result) em
then pure (result :| [])
else do
rest <- go (pred w)
pure (result NE.<| rest)
where
runFunc :: IO TestRunResult
runFunc = testDefVal td progressReporter (\f -> f l ())