{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module Test.Validity.Show
( showReadSpecOnValid
, showReadSpec
, showReadSpecOnArbitrary
, showReadSpecOnGen
, showReadRoundTripOnValid
, showReadRoundTrip
, showReadRoundTripOnArbitrary
, showReadRoundTripOnGen
) where
import Data.GenValidity
import Data.Data
import Text.Read
import Test.Hspec
import Test.QuickCheck
import Test.Validity.Utils
showReadSpecOnValid ::
forall a. (Show a, Eq a, Read a, Typeable a, GenValid a)
=> Spec
showReadSpecOnValid = showReadSpecOnGen @a genValid "valid" shrinkValid
showReadSpec ::
forall a. (Show a, Eq a, Read a, Typeable a, GenUnchecked a)
=> Spec
showReadSpec = showReadSpecOnGen @a genUnchecked "unchecked" shrinkUnchecked
showReadSpecOnArbitrary ::
forall a. (Show a, Eq a, Read a, Typeable a, Arbitrary a)
=> Spec
showReadSpecOnArbitrary = showReadSpecOnGen @a arbitrary "arbitrary" shrink
showReadSpecOnGen ::
forall a. (Show a, Eq a, Read a, Typeable a)
=> Gen a
-> String
-> (a -> [a])
-> Spec
showReadSpecOnGen gen n s =
describe (unwords ["Show", nameOf @a, "and Read", nameOf @a]) $
it (unwords ["are implemented such that read . show == id for", n, "values"]) $
showReadRoundTripOnGen gen s
showReadRoundTripOnValid ::
forall a. (Show a, Eq a, Read a, GenValid a)
=> Property
showReadRoundTripOnValid =
showReadRoundTripOnGen (genValid :: Gen a) shrinkValid
showReadRoundTrip ::
forall a. (Show a, Eq a, Read a, GenUnchecked a)
=> Property
showReadRoundTrip =
showReadRoundTripOnGen (genUnchecked :: Gen a) shrinkUnchecked
showReadRoundTripOnArbitrary ::
forall a. (Show a, Eq a, Read a, Arbitrary a)
=> Property
showReadRoundTripOnArbitrary =
showReadRoundTripOnGen (arbitrary :: Gen a) shrink
showReadRoundTripOnGen ::
(Show a, Eq a, Read a) => Gen a -> (a -> [a]) -> Property
showReadRoundTripOnGen gen s =
forAllShrink gen s $ \v -> readMaybe (show v) `shouldBe` Just v