{-# LANGUAGE Unsafe #-} module Yaya.Hedgehog ( evalNonterminating, nonterminatingProperty, ) where import safe "base" Control.Category (Category ((.))) import safe "base" Control.Monad ((<=<)) import safe "base" Control.Monad.IO.Class (MonadIO) import safe "base" Data.Function (const) import safe "base" Data.Maybe (maybe) import "base" GHC.IO (evaluate) import safe "base" GHC.Stack (HasCallStack) import safe "base" System.Timeout (timeout) import safe "base" Text.Show (Show) import qualified "hedgehog" Hedgehog as HH -- | Returns success if the expression doesn’t terminate, failure otherwise. -- Termination is just checked with a 1 second timeout, so this isn’t -- foolproof. evalNonterminating :: (HasCallStack, MonadIO m, HH.MonadTest m, Show a) => a -> m () evalNonterminating = maybe HH.success (const HH.failure <=< HH.annotateShow) <=< HH.evalIO . timeout 1_000_000 . evaluate -- | Returns success if the expression doesn’t terminate, failure otherwise. -- The value passed here should termina nonterminatingProperty :: (HasCallStack, Show a) => a -> HH.Property nonterminatingProperty = HH.withTests 1 . HH.property . evalNonterminating