packages feed

speculate-0.2.0: src/Test/Speculate/Utils/Timeout.hs

module Test.Speculate.Utils.Timeout
  ( timeoutToNothing
  , fromTimeout
  , timeoutToFalse
  , timeoutToTrue
  , timeoutToError
  )
where

import System.IO.Unsafe (unsafePerformIO)
import Control.Exception (evaluate)
import System.Timeout
import Data.Maybe (fromMaybe)

-- TODO: Move this into LeanCheck?

-- | In microseconds
usTimeoutToNothing :: Int -> a -> Maybe a
usTimeoutToNothing n = unsafePerformIO . timeout n . evaluate

-- | Returns Nothing if value cannot be evaluated to WHNF in a given number of seconds
timeoutToNothing :: RealFrac s => s -> a -> Maybe a
timeoutToNothing n = usTimeoutToNothing $ round (n * 1000000)

fromTimeout :: RealFrac s => s -> a -> a -> a
fromTimeout n x = fromMaybe x . timeoutToNothing n

timeoutToFalse :: RealFrac s => s -> Bool -> Bool
timeoutToFalse n = fromTimeout n False

timeoutToTrue :: RealFrac s => s -> Bool -> Bool
timeoutToTrue n = fromTimeout n True

timeoutToError :: RealFrac s => s -> a -> a
timeoutToError n = fromTimeout n (error "timeoutToError: timed out")