vgrep-0.1.3.0: test/Test/Case.hs
{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE RecordWildCards #-}
module Test.Case (
TestCase (..)
, runTestCase
, runTestCases
, (~~)
, testPropertyVgrep
, monadicVgrep
, module Vgrep.Type
, TestTree ()
) where
import Control.Lens
import Test.QuickCheck.Monadic
import Test.Tasty
import Test.Tasty.QuickCheck
import Vgrep.Environment.Testable
import Vgrep.Type
data TestCase
= forall s a prop. (Arbitrary s, Show s, Testable prop)
=> TestProperty
{ description :: TestName
, testData :: Gen (s, Environment)
, testCase :: PropertyM (Vgrep s) a
, assertion :: a -> PropertyM (Vgrep s) prop }
| forall s a r. (Arbitrary s, Show s, Eq r, Show r)
=> TestInvariant
{ description :: TestName
, testData :: Gen (s, Environment)
, testCase :: PropertyM (Vgrep s) a
, invariant :: Getter s r }
runTestCase :: TestCase -> TestTree
runTestCase = \case
TestProperty {..} -> testProperty description $ do
(initialState, initialEnv) <- testData
pure . monadic (`runVgrepForTest` (initialState, initialEnv)) $ do
monitor (counterexample (show initialState))
monitor (counterexample (show initialEnv))
params <- testCase
stop =<< assertion params
TestInvariant {..} -> testProperty description $ do
(initialState, initialEnv) <- testData
pure . monadic (`runVgrepForTest` (initialState, initialEnv)) $ do
monitor (counterexample (show initialState))
monitor (counterexample (show initialEnv))
before <- use invariant
void testCase
after <- use invariant
stop (after === before)
runTestCases :: TestName -> [TestCase] -> TestTree
runTestCases name cases = testGroup name (map runTestCase cases)
instance Monad m => MonadState s (PropertyM (VgrepT s m)) where
get = run get
put = run . put
instance Monad m => MonadReader Environment (PropertyM (VgrepT s m)) where
ask = run ask
local f action = MkPropertyM $ \k -> fmap (local f) (unPropertyM action k)
runVgrepForTest
:: Vgrep s a
-> (s, Environment)
-> a
runVgrepForTest action (s, env) = fst (runIdentity (runVgrepT action s env))
monadicVgrep
:: Arbitrary s
=> PropertyM (Vgrep s) a
-> Gen Property
monadicVgrep testcase = do
initialState <- arbitrary
initialEnv <- arbitrary
pure (monadic (`runVgrepForTest` (initialState, initialEnv)) testcase)
testPropertyVgrep
:: Arbitrary s
=> TestName
-> PropertyM (Vgrep s) a
-> TestTree
testPropertyVgrep name prop = testProperty name (monadicVgrep prop)
infix 4 ~~
(~~)
:: (Eq a, Show a)
=> Getter s a
-> Getter s a
-> PropertyM (Vgrep s) Property
prop1 ~~ prop2 = do
p1 <- use prop1
p2 <- use prop2
pure (p1 === p2)