validation-0.6.1: test/hedgehog.hs
{-# LANGUAGE OverloadedStrings #-}
import Control.Applicative (liftA3)
import Control.Monad (join, unless)
import Data.Semigroup ((<>))
import Data.Monoid (Monoid (mappend))
import Hedgehog
import qualified Hedgehog.Gen as Gen
import qualified Hedgehog.Range as Range
import System.IO (BufferMode(..), hSetBuffering, stdout, stderr)
import System.Exit (exitFailure)
import Data.Validation (AccValidation (AccSuccess, AccFailure))
main :: IO ()
main = do
hSetBuffering stdout LineBuffering
hSetBuffering stderr LineBuffering
result <- checkParallel $ Group "Validation"
[ ("prop_semigroup", prop_semigroup)
, ("prop_monoid_assoc", prop_monoid_assoc)
, ("prop_monoid_left_id", prop_monoid_left_id)
, ("prop_monoid_right_id", prop_monoid_right_id)
]
unless result $
exitFailure
genAccValidation :: Gen e -> Gen a -> Gen (AccValidation e a)
genAccValidation e a = Gen.choice [fmap AccFailure e, fmap AccSuccess a]
testGen :: Gen (AccValidation [String] Int)
testGen =
let range = Range.linear 1 50
string = Gen.string range Gen.unicode
strings = Gen.list range string
in genAccValidation strings Gen.enumBounded
mkAssoc :: (AccValidation [String] Int -> AccValidation [String] Int -> AccValidation [String] Int) -> Property
mkAssoc f =
let g = forAll testGen
assoc = \x y z -> ((x `f` y) `f` z) === (x `f` (y `f` z))
in property $ join (liftA3 assoc g g g)
prop_semigroup :: Property
prop_semigroup = mkAssoc (<>)
prop_monoid_assoc :: Property
prop_monoid_assoc = mkAssoc mappend
prop_monoid_left_id :: Property
prop_monoid_left_id =
property $ do
x <- forAll testGen
(mempty `mappend` x) === x
prop_monoid_right_id :: Property
prop_monoid_right_id =
property $ do
x <- forAll testGen
(x `mappend` mempty) === x