genvalidity-0.11.0.2: test/Data/InstanceSpec.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Data.InstanceSpec
( spec,
)
where
#if !MIN_VERSION_base(4,8,0)
import Control.Applicative ((<*>), pure)
import Data.Functor ((<$>))
#endif
#if MIN_VERSION_base(4,9,0)
import Data.List.NonEmpty (NonEmpty)
#endif
import Control.Monad
import Data.Data
import Data.Fixed
#if MIN_VERSION_base(4,8,0)
import GHC.Natural
#endif
import Data.GenValidity
import Data.Int
import Data.Ratio
import Data.Word
import Test.Hspec
import Test.Hspec.Core.QuickCheck (modifyMaxSize, modifyMaxSuccess)
import Test.QuickCheck
spec :: Spec
spec = do
twoTests (Proxy :: Proxy ())
twoTests (Proxy :: Proxy Bool)
twoTests (Proxy :: Proxy Ordering)
twoTests (Proxy :: Proxy Char)
twoTests (Proxy :: Proxy Word)
twoTests (Proxy :: Proxy Word8)
twoTests (Proxy :: Proxy Word16)
twoTests (Proxy :: Proxy Word32)
twoTests (Proxy :: Proxy Word64)
twoTests (Proxy :: Proxy Int)
twoTests (Proxy :: Proxy Int8)
twoTests (Proxy :: Proxy Int16)
twoTests (Proxy :: Proxy Int32)
twoTests (Proxy :: Proxy Int64)
twoTests (Proxy :: Proxy Integer)
twoTests (Proxy :: Proxy Float)
twoTupleTests (Proxy :: Proxy Float)
-- Regression tests
describe "shrinkUnchecked Float" $ do
let sf :: Float -> Spec
sf f = it (unwords ["Does not shrink", show f, "to itself"]) $ f `shouldNotSatisfy` (`elem` shrinkUnchecked f)
sf (-2.1393704e20)
sf 1.2223988e-12
sf 2.7896812e10
describe "shrinkUnchecked Double" $ do
let sd :: Double -> Spec
sd d = it (unwords ["Does not shrink", show d, "to itself"]) $ d `shouldNotSatisfy` (`elem` shrinkUnchecked d)
sd (-1.032730679986007e18)
twoTests (Proxy :: Proxy Double)
twoTupleTests (Proxy :: Proxy Double)
threeTests (Proxy :: Proxy (Ratio Int))
modifyMaxSuccess (`quot` 2) $
modifyMaxSize (`quot` 2) $ twoTests (Proxy :: Proxy (Either Bool Ordering))
twoTests (Proxy :: Proxy (Maybe Ordering))
twoTests (Proxy :: Proxy (Maybe (Maybe (Ordering))))
threeTests (Proxy :: Proxy (Ratio Integer))
-- threeTupleTests (Proxy :: Proxy (Ratio Integer))
threeTests (Proxy :: Proxy (Ratio Int))
-- threeTupleTests (Proxy :: Proxy (Ratio Int))
threeTests (Proxy :: Proxy (Ratio Int8))
describe "shrinking (Ratio Int)" $
it "can shrink this example" $
let v = ((-9223372036854775808) % 9223372036854775761) :: Ratio Int
in v `notElem` shrinkValid v
describe "shrinking (Ratio Int8)" $
it "can shrink this example" $
let v = ((-128) % 113) :: Ratio Int8
in v `notElem` shrinkValid v
twoTests (Proxy :: Proxy Uni)
twoTupleTests (Proxy :: Proxy Uni)
twoTests (Proxy :: Proxy Deci)
twoTupleTests (Proxy :: Proxy Deci)
twoTests (Proxy :: Proxy Centi)
twoTupleTests (Proxy :: Proxy Centi)
twoTests (Proxy :: Proxy Milli)
twoTupleTests (Proxy :: Proxy Milli)
twoTests (Proxy :: Proxy Micro)
twoTupleTests (Proxy :: Proxy Micro)
twoTests (Proxy :: Proxy Nano)
twoTupleTests (Proxy :: Proxy Nano)
twoTests (Proxy :: Proxy Pico)
twoTupleTests (Proxy :: Proxy Pico)
#if MIN_VERSION_base(4,8,0)
twoTests (Proxy :: Proxy Natural)
twoTupleTests (Proxy :: Proxy Natural)
#endif
#if MIN_VERSION_base(4,9,0)
twoTests (Proxy :: Proxy (NonEmpty Ordering))
#endif
twoTupleTests ::
forall a.
(Show a, Eq a, Typeable a, GenUnchecked a, GenValid a) =>
Proxy a ->
Spec
twoTupleTests proxy = do
modifyMaxSuccess (`quot` 2) $ modifyMaxSize (`quot` 2) $ twoTests $ (,) <$> proxy <*> proxy
twoTests ::
forall a.
(Show a, Eq a, Typeable a, GenUnchecked a, GenValid a) =>
Proxy a ->
Spec
twoTests proxy =
describe (nameOf proxy) $ do
genUncheckedTest proxy
genValidTest proxy
threeTests ::
forall a.
(Show a, Eq a, Typeable a, GenUnchecked a, GenValid a, GenInvalid a) =>
Proxy a ->
Spec
threeTests proxy =
describe (nameOf proxy) $ do
genUncheckedTest proxy
genValidTest proxy
genInvalidTest proxy
genUncheckedTest ::
forall a.
(Show a, Eq a, Typeable a, GenUnchecked a, GenValid a) =>
Proxy a ->
Spec
genUncheckedTest proxy = do
it (unwords ["genUnchecked of", nameOf proxy, "does not crash while validating"]) $
forAll genUnchecked $ \a ->
case prettyValidate (a :: a) of
Right v -> seq v True
Left err -> seq err True
modifyMaxSuccess (`quot` 5) $
it
( unwords
[ "shrinkUnchecked of",
nameOf proxy,
"only produces values that do not crash while validating"
]
)
$ forAll genUnchecked $ \a ->
forM_ (shrinkUnchecked a) $ \v ->
case prettyValidate (v :: a) of
Right v_ -> seq v_ $ pure () :: IO ()
Left err -> seq err $ pure ()
modifyMaxSuccess (`quot` 5) $
it (unwords ["shrinkUnchecked of", nameOf proxy, "does not shrink to itself"]) $
forAll genValid $ \a ->
forM_ (shrinkUnchecked a) $ \a' ->
unless (a /= a') $
expectationFailure $ unlines ["The value", show (a :: a), "was shrunk to itself"]
genValidTest ::
forall a.
(Show a, Eq a, Typeable a, GenValid a) =>
Proxy a ->
Spec
genValidTest proxy = do
it (unwords ["genValid of", nameOf proxy, "generates only valid values"]) $
forAll genValid $ \a ->
case prettyValidate (a :: a) of
Right v -> seq v $ pure ()
Left err ->
expectationFailure $
unlines ["'validate' reported this value to be invalid:", show a, err, ""]
modifyMaxSuccess (`quot` 5) $
it (unwords ["shrinkValid of", nameOf proxy, "shrinks to only valid values"]) $
forAll genValid $ \a ->
forM_ (shrinkValid a) $ \v ->
case prettyValidate (v :: a) of
Right v_ -> seq v_ $ pure ()
Left err ->
expectationFailure $
unlines ["'validate' reported this value to be invalid:", show v, err, ""]
modifyMaxSuccess (`quot` 5) $
it
( unwords
["shrinkValid of", nameOf proxy, "only produces values that do not crash while validating"]
)
$ forAll genValid $ \a ->
forM_ (shrinkValid a) $ \v ->
case prettyValidate (v :: a) of
Right v_ -> seq v_ $ pure () :: IO ()
Left err -> seq err $ pure ()
modifyMaxSuccess (`quot` 5) $
it (unwords ["shrinkValid of", nameOf proxy, "does not shrink to itself"]) $
forAll genValid $ \a ->
forM_ (shrinkValid a) $ \a' ->
unless (a /= a') $
expectationFailure $ unlines ["The value", show (a :: a), "was shrunk to itself"]
genInvalidTest ::
forall a.
(Show a, Typeable a, GenInvalid a) =>
Proxy a ->
Spec
genInvalidTest proxy = do
it (unwords ["genInvalid of", nameOf proxy, "generates only invalid values"]) $
forAll genInvalid $ \a ->
case prettyValidate (a :: a) of
Right _ ->
expectationFailure $ unlines ["'validate' reported this value to be valid: ", show a]
Left e -> seq e $ pure ()
modifyMaxSuccess (`quot` 5) $
it (unwords ["shrinkInvalid of", nameOf proxy, "shrinks to only invalid values"]) $
forAll genInvalid $ \a ->
forM_ (shrinkInvalid a) $ \v ->
case prettyValidate (v :: a) of
Right _ ->
expectationFailure $ unlines ["'validate' reported this value to be valid: ", show v]
Left e -> seq e $ pure ()
modifyMaxSuccess (`quot` 5) $
it
( unwords
[ "shrinkInvalid of",
nameOf proxy,
"only produces values that do not crash while validating"
]
)
$ forAll genInvalid $ \a ->
forM_ (shrinkInvalid a) $ \v ->
case prettyValidate (v :: a) of
Right _ ->
expectationFailure $ unlines ["'validate' reported this value to be valid: ", show v]
Left e -> seq e $ pure ()
nameOf ::
forall a.
Typeable a =>
Proxy a ->
String
nameOf = show . typeRep