|
1 | 1 | -- | Core types and definitions |
2 | 2 | {-# LANGUAGE DeriveGeneric #-} |
3 | 3 | {-# LANGUAGE ExistentialQuantification #-} |
| 4 | +{-# LANGUAGE FlexibleInstances #-} |
4 | 5 | {-# LANGUAGE LambdaCase #-} |
5 | 6 | {-# LANGUAGE RankNTypes #-} |
| 7 | +{-# LANGUAGE TypeApplications #-} |
6 | 8 | module Test.Tasty.Core |
7 | 9 | ( FailureReason(..) |
8 | 10 | , Outcome(..) |
@@ -31,11 +33,15 @@ module Test.Tasty.Core |
31 | 33 | , foldTestTree |
32 | 34 | , foldTestTree0 |
33 | 35 | , treeOptions |
| 36 | + , testFailed |
34 | 37 | ) where |
35 | 38 |
|
36 | 39 | import Control.Exception |
| 40 | +import Control.Monad.Trans.Cont (ContT(..)) |
| 41 | +import Data.Coerce (coerce) |
37 | 42 | import qualified Data.Map as Map |
38 | 43 | import Data.Bifunctor (Bifunctor(second, bimap)) |
| 44 | +import Data.IORef (newIORef, readIORef, atomicModifyIORef') |
39 | 45 | import Data.List (mapAccumR) |
40 | 46 | import Data.Monoid (Any (getAny, Any)) |
41 | 47 | import Data.Sequence ((|>)) |
@@ -217,6 +223,36 @@ class Typeable t => IsTest t where |
217 | 223 | -- | The list of options that affect execution of tests of this type |
218 | 224 | testOptions :: Tagged t [OptionDescription] |
219 | 225 |
|
| 226 | +instance IsTest t => IsTest (ContT () IO t) where |
| 227 | + testOptions = coerce (testOptions @t) |
| 228 | + run opts (ContT k) yieldProgress = do |
| 229 | + resRef <- newIORef Nothing |
| 230 | + let runInIORef :: t -> IO () |
| 231 | + runInIORef t = do |
| 232 | + res <- run opts t yieldProgress |
| 233 | + let err = testFailed "Continuation was called multiple times" |
| 234 | + atomicModifyIORef' resRef $ \prev -> |
| 235 | + (Just $ maybe res (const err) prev, ()) |
| 236 | + k runInIORef |
| 237 | + maybeRes <- readIORef resRef |
| 238 | + pure $ case maybeRes of |
| 239 | + Nothing -> testFailed "Continuation was not called" |
| 240 | + Just r -> r |
| 241 | + |
| 242 | +-- | 'Result' of a failed test. |
| 243 | +-- |
| 244 | +-- @since 0.8 |
| 245 | +testFailed |
| 246 | + :: String -- ^ description |
| 247 | + -> Result |
| 248 | +testFailed desc = Result |
| 249 | + { resultOutcome = Failure TestFailed |
| 250 | + , resultDescription = desc |
| 251 | + , resultShortDescription = "FAIL" |
| 252 | + , resultTime = 0 |
| 253 | + , resultDetailsPrinter = noResultDetails |
| 254 | + } |
| 255 | + |
220 | 256 | -- | The name of a test or a group of tests. |
221 | 257 | -- |
222 | 258 | -- @since 0.1 |
|
0 commit comments