genvalidity-hspec-0.2.0.5: src/Test/Validity/RelativeValidity.hs
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Test.Validity.RelativeValidity
( -- * Tests for RelativeValidity instances
relativeValiditySpec
, relativeValidityImpliesValidA
, relativeValidityImpliesValidB
) where
import Data.Data
import Data.Proxy
import Data.GenRelativeValidity
import Data.GenValidity
import Test.Hspec
import Test.QuickCheck
import Test.Validity.Utils
-- | A @Spec@ that specifies that @isValidFor@ implies @isValid@
--
-- In general it is a good idea to add this spec to your test suite if
-- the @a@ and @b@ in @RelativeValidity a b@ also have a @Validity@ instance.
--
-- Example usage:
--
-- > relativeValiditySpec
-- > (Proxy :: Proxy MyDataFor)
-- > (Proxy :: Proxy MyOtherData)
relativeValiditySpec
:: (Typeable a, Typeable b,
Show a, Show b,
GenValidity a, GenValidity b, GenRelativeValidity a b)
=> Proxy a
-> Proxy b
-> Spec
relativeValiditySpec one two = do
let nameOne = nameOf one
nameTwo = nameOf two
describe ("RelativeValidity " ++ nameOne ++ " " ++ nameTwo) $
describe ("isValidFor :: "
++ nameOne
++ " -> "
++ nameTwo
++ " -> Bool") $ do
it ("implies isValid " ++ nameOne ++ " for any " ++ nameTwo) $
relativeValidityImpliesValidA one two
it ("implies isValid " ++ nameTwo ++ " for any " ++ nameOne) $
relativeValidityImpliesValidB one two
-- | @isValidFor a b@ implies @isValid a@ for all @b@
relativeValidityImpliesValidA
:: (Show a, Show b,
GenValidity a, GenValidity b, RelativeValidity a b)
=> Proxy a
-> Proxy b
-> Property
relativeValidityImpliesValidA one two =
forAll genUnchecked $ \a ->
forAll genUnchecked $ \b ->
not ((a `asProxyTypeOf` one) `isValidFor` (b `asProxyTypeOf` two))
|| isValid a
-- | @isValidFor a b@ implies @isValid b@ for all @a@
relativeValidityImpliesValidB
:: (Show a, Show b,
GenValidity a, GenValidity b, RelativeValidity a b)
=> Proxy a
-> Proxy b
-> Property
relativeValidityImpliesValidB one two =
forAll genUnchecked $ \a ->
forAll genUnchecked $ \b ->
not ((a `asProxyTypeOf` one) `isValidFor` (b `asProxyTypeOf` two))
|| isValid b