tomland-1.3.2.0: test/Test/Toml/Codec/Combinator/Common.hs
module Test.Toml.Codec.Combinator.Common
( codecRoundtrip
, exactCodecRoundtrip
-- * Double helpers
, Batman (..)
, _BatmanDouble
, batmanDoubleCodec
, batmanFloatCodec
) where
import Data.Text (Text)
import Hedgehog (Gen, forAll, tripping)
import Test.Hspec (Arg, Expectation, SpecWith, it)
import Test.Hspec.Hedgehog (hedgehog)
import Toml.Codec.BiMap (TomlBiMap)
import Toml.Codec.Code (decode, decodeExact, encode)
import Toml.Codec.Error (TomlDecodeError)
import Toml.Codec.Types (TomlCodec)
import Toml.Type.AnyValue (AnyValue)
import Toml.Type.Key (Key)
import qualified Toml.Codec as Toml
codecRoundtripWith
:: forall a
. (Eq a, Show a)
=> (TomlCodec a -> Text -> Either [TomlDecodeError] a)
-> String
-> (Key -> TomlCodec a)
-> Gen a
-> SpecWith (Arg Expectation)
codecRoundtripWith dcode typeName mkCodec genA = it label $ hedgehog $ do
a <- forAll genA
let codec = mkCodec "a"
tripping a (encode codec) (dcode codec)
where
label :: String
label = typeName ++ ": decode . encode ≡ id"
codecRoundtrip
:: forall a
. (Eq a, Show a)
=> String
-> (Key -> TomlCodec a)
-> Gen a
-> SpecWith (Arg Expectation)
codecRoundtrip = codecRoundtripWith decode
exactCodecRoundtrip
:: forall a
. (Eq a, Show a)
=> String
-> (Key -> TomlCodec a)
-> Gen a
-> SpecWith (Arg Expectation)
exactCodecRoundtrip str = codecRoundtripWith decodeExact ("Exact " <> str)
-- | Wrapper over 'Double' and 'Float' to be equal on @NaN@ values.
newtype Batman a = Batman
{ unBatman :: a
} deriving stock (Show)
instance Toml.HasCodec a => Toml.HasCodec (Batman a) where
hasCodec = Toml.diwrap . Toml.hasCodec @a
instance RealFloat a => Eq (Batman a) where
Batman a == Batman b =
if isNaN a
then isNaN b
else a == b
_BatmanDouble :: TomlBiMap (Batman Double) AnyValue
_BatmanDouble = Toml._Coerce Toml._Double
batmanDoubleCodec :: Key -> TomlCodec (Batman Double)
batmanDoubleCodec = Toml.match _BatmanDouble
batmanFloatCodec :: Key -> TomlCodec (Batman Float)
batmanFloatCodec = Toml.diwrap . Toml.float