hedgehog-extras-0.3.0.1: src/Hedgehog/Extras/Aeson.hs
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# OPTIONS_GHC -Wno-unused-imports #-}
{-# OPTIONS_GHC -Wno-redundant-constraints #-}
{-# OPTIONS_GHC -Wno-unused-local-binds #-}
module Hedgehog.Extras.Aeson
( goldenTestJsonValue
, goldenTestJsonValuePretty
) where
import Control.Monad
import Control.Monad.IO.Class
import Data.Aeson
import Data.Aeson.Encode.Pretty
import Data.Bool
import Data.Either
import Data.Eq
import Data.Function
import Data.Functor
import Data.Maybe
import Data.Semigroup
import GHC.Stack
import Hedgehog
import System.IO
import Text.Show
import qualified Data.ByteString.Lazy as LBS
import qualified Hedgehog.Internal.Property as H
writeNewGoldFiles :: Bool
writeNewGoldFiles = False
strictComparison :: Bool
strictComparison = False
goldenTestJsonValue :: forall a. ()
=> Eq a
=> FromJSON a
=> Show a
=> ToJSON a
=> HasCallStack
=> a
-> FilePath
-> Property
goldenTestJsonValue x path = withFrozenCallStack $ withTests 1 . property $ do
bs <- liftIO (LBS.readFile path)
when writeNewGoldFiles $ liftIO . LBS.writeFile (path <> ".gold") $ encode x
when strictComparison $ fmap encode (eitherDecode @a bs) === Right bs
case eitherDecode bs of
Left err -> H.failWith Nothing $ "could not decode: " <> show err
Right x' -> x === x'
goldenTestJsonValuePretty
:: forall a. ()
=> Eq a
=> FromJSON a
=> HasCallStack
=> Show a
=> ToJSON a
=> a
-> FilePath
-> Property
goldenTestJsonValuePretty x path =
withFrozenCallStack
$ withTests 1
. property
$ do
bs <- liftIO (LBS.readFile path)
-- Sort keys by their order of appearance in the argument list
-- of `keyOrder`. Keys not in the argument list are moved to the
-- end, while their order is preserved.
let
defConfig' = Config
{ confIndent = Spaces 4
, confCompare = keyOrder ["file", "hash"]
, confNumFormat = Generic
, confTrailingNewline = False
}
when writeNewGoldFiles $ liftIO . LBS.writeFile (path <> ".gold") $ encodePretty' defConfig' x
when strictComparison $ fmap (encodePretty' defConfig') (eitherDecode @a bs) === Right bs
case eitherDecode bs of
Left err -> H.failWith Nothing $ "could not decode: " <> show err
Right x' -> x === x'