waargonaut-0.2.1.0: test/Encoder/Laws.hs
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}
module Encoder.Laws (encoderLaws) where
import Test.Tasty (TestTree, testGroup)
import Test.Tasty.Hedgehog (testProperty)
import Data.ByteString.Lazy (ByteString)
import Data.Functor.Identity (Identity)
import Hedgehog
import Hedgehog.Function (Arg, Vary)
import qualified Hedgehog.Function as Fn
import qualified Hedgehog.Gen as Gen
import Waargonaut.Encode (Encoder)
import qualified Waargonaut.Encode as E
runSE :: ShowEncoder a -> a -> ByteString
runSE (SE e) = E.simplePureEncodeNoSpaces e
newtype ShowEncoder a = SE (Encoder Identity a)
instance Show a => Show (ShowEncoder a) where
show (SE _) = "an encoder of type a"
instance Fn.Contravariant ShowEncoder where
contramap f (SE a) = SE (Fn.contramap f a)
-- |
-- contravariant
--
-- contramap f . contramap g = contramap (g . f)
contravariant_composition
:: forall f a.
( Show f, Arg f, Vary f, Eq f
, Show a, Arg a, Vary a
)
=> Gen f
-> Gen Bool
-> Gen a
-> Property
contravariant_composition genF genG genA = property $ do
f <- Fn.forAllFn $ Fn.fn genF
g <- Fn.forAllFn $ Fn.fn genG
let ea = SE E.bool
a <- forAll genA
runSE (Fn.contramap f $ Fn.contramap g ea) a === runSE (Fn.contramap (g . f) ea) a
contravariant_identity :: Property
contravariant_identity = property $ do
a <- forAll Gen.bool
let ea = SE E.bool
runSE (Fn.contramap id ea) a === runSE ea a
encoderLaws :: TestTree
encoderLaws = testGroup "Encoder Laws"
[ testProperty "Contravariant 'composition'" $ contravariant_composition Gen.bool Gen.bool Gen.bool
, testProperty "Contravariant 'identity'" contravariant_identity
]