genvalidity-hspec-0.2.0.5: src/Test/Validity/Arbitrary.hs
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Test.Validity.Arbitrary
( -- * Tests for Arbitrary instances involving Validity
arbitrarySpec
, arbitraryGeneratesOnlyValid
, shrinkProducesOnlyValids
) where
import Data.Data
import Data.Proxy
import Data.GenValidity
import Test.Hspec
import Test.QuickCheck
import Test.Validity.Utils
import Test.Validity.GenValidity
-- | A @Spec@ that specifies that @arbitrary@ only generates data that
-- satisfy @isValid@ and that @shrink@ only produces data that satisfy
-- @isValid@.
--
-- Example usage:
--
-- > arbitrarySpec (Proxy :: Proxy MyData)
arbitrarySpec
:: (Typeable a, Show a, Validity a, Arbitrary a)
=> Proxy a
-> Spec
arbitrarySpec proxy = do
let name = nameOf proxy
describe ("Arbitrary " ++ name) $ do
it ("is instantiated such that 'arbitrary' only generates valid \'"
++ name
++ "\'s.") $
arbitraryGeneratesOnlyValid proxy
it ("is instantiated such that 'shrink' only produces valid \'"
++ name
++ "\'s.") $
forAll arbitrary $ \a ->
shrink (a `asProxyTypeOf` proxy) `shouldSatisfy` all isValid
-- | @arbitrary@ only generates valid data
arbitraryGeneratesOnlyValid
:: forall a. (Show a, Validity a, Arbitrary a)
=> Proxy a
-> Property
arbitraryGeneratesOnlyValid _ =
genGeneratesValid (arbitrary :: Gen a)
-- | @shrink@, applied to valid data only produces valid data
shrinkProducesOnlyValids
:: forall a. (Show a, Validity a, Arbitrary a)
=> Proxy a
-> Property
shrinkProducesOnlyValids _ =
genGeneratesValid (shrink <$> arbitrary :: Gen [a])