{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE RankNTypes #-} module Encoder.Laws (encoderLaws) where import Test.Tasty (TestTree, testGroup) import Test.Tasty.Hedgehog (testProperty) import Data.Functor.Contravariant (contramap) import Data.Functor.Identity (Identity) import Data.Text.Lazy (Text) import Hedgehog import qualified Hedgehog.Function as Fn import qualified Hedgehog.Gen as Gen import Waargonaut.Encode (Encoder) import qualified Waargonaut.Encode as E import qualified Laws runSE :: ShowEncoder a -> a -> Text runSE (SE e) = E.simplePureEncodeTextNoSpaces 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) genShowEncoder :: Encoder Identity a -> Gen a -> Gen (ShowEncoder a) genShowEncoder enc _ = Gen.constant (SE enc) encoderLaws :: TestTree encoderLaws = testGroup "Encoder Laws" [ testGroup "Contravariant" [ testProperty "composition" $ Laws.contravariant_composition_with_run (genShowEncoder E.bool) runSE Gen.bool (Gen.maybe Gen.bool) Gen.bool , testProperty "identity" $ Laws.contravariant_identity_with_run (genShowEncoder E.bool) runSE Gen.bool ] ]