prop-unit-1.0.0: test/Main.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE UndecidableInstances #-}
module Main (main) where
import Control.Monad (replicateM)
import Data.Proxy (Proxy (..))
import qualified Data.Set as Set
import GHC.Exts (IsList, IsString)
import GHC.Generics (Generic)
import PropUnit
( GenDefault (..)
, StdTag
, TestLimit
, TestTree
, assert
, forAll
, genDefaultEnum
, genDefaultGeneric
, genDefaultList
, genDefaultString
, genDefaultTag
, testGroup
, testMain
, testProp
, testUnit
, (===)
)
import PropUnit.Hedgehog (Gen)
import qualified PropUnit.Hedgehog.Gen as Gen
import qualified PropUnit.Hedgehog.Range as Range
testAsUnit :: TestTree
testAsUnit = testUnit "as unit" $ do
let actual = (1 + 1) :: Int
expected = 2 :: Int
actual === expected
testAsProp :: TestLimit -> TestTree
testAsProp lim = testProp "as gen" lim $ do
x <- forAll (Gen.int (Range.constant 1 10))
abs x * abs x === x * x
testBasic :: TestLimit -> TestTree
testBasic lim =
testGroup
"basic"
[ testAsUnit
, testAsProp lim
]
data Tag
instance GenDefault Tag Int where genDefault = genDefaultTag (Proxy @StdTag)
instance GenDefault Tag Char where genDefault = genDefaultTag (Proxy @StdTag)
newtype AList a = AList [a]
deriving newtype (Eq, Ord, Show, IsList)
instance (GenDefault Tag a) => GenDefault Tag (AList a) where genDefault = genDefaultList (Proxy @0) (Proxy @2)
newtype AString = AString String
deriving newtype (Eq, Ord, Show, IsString)
instance GenDefault Tag AString where genDefault = genDefaultString (Proxy @0) (Proxy @2)
data Choice = ChoiceA | ChoiceB
deriving stock (Eq, Ord, Show, Enum, Bounded)
instance GenDefault Tag Choice where genDefault = genDefaultEnum
instance (GenDefault Tag a) => GenDefault Tag (Maybe a) where genDefault = genDefaultGeneric
data Record = Record !Int !(Maybe Record)
deriving stock (Eq, Ord, Show, Generic)
instance GenDefault Tag Record where genDefault = genDefaultGeneric
data GenCase where
GenCase :: (Ord a) => String -> Gen a -> GenCase
genDefaultByProxy :: (GenDefault Tag a) => Proxy a -> Gen a
genDefaultByProxy _ = genDefault (Proxy @Tag)
mkGenCase :: (Ord a, GenDefault Tag a) => String -> Proxy a -> GenCase
mkGenCase name = GenCase name . genDefaultByProxy
genCases :: [GenCase]
genCases =
[ mkGenCase "Int" (Proxy @Int)
, mkGenCase "Char" (Proxy @Char)
, mkGenCase "Choice" (Proxy @Choice)
, mkGenCase "AList" (Proxy @(AList Char))
, mkGenCase "AString" (Proxy @AString)
, mkGenCase "Record" (Proxy @Record)
]
testGenCase :: GenCase -> TestTree
testGenCase (GenCase name gen) = testUnit name $ do
xs <- fmap Set.fromList (replicateM 10 (Gen.sample gen))
assert (Set.size xs > 1)
testDerive :: TestTree
testDerive = testGroup "derive" (fmap testGenCase genCases)
main :: IO ()
main = testMain $ \lim ->
testGroup
"PropUnit"
[ testBasic lim
, testDerive
]