roc-id-0.3.0.0: components/roc-id-test/Test/QuickCheck/Classes/Hspec.hs
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
-- | Provides testing functions to check that type class instances obey laws.
module Test.QuickCheck.Classes.Hspec
( testLaws
, testLawsMany
) where
import Prelude
import Control.Monad
( forM_
)
import Data.Proxy
( Proxy (..)
)
import Data.Typeable
( Typeable
, typeRep
)
import Test.Hspec
( Spec
, describe
, it
, parallel
)
import Test.QuickCheck.Classes
( Laws (..)
)
-- | Constructs a test to check that the given type class instance obeys the
-- given set of laws.
--
-- Example usage:
--
-- >>> testLaws @Natural ordLaws
-- >>> testLaws @(Map Int) functorLaws
testLaws
:: forall a
. Typeable a
=> (Proxy a -> Laws)
-> Spec
testLaws getLaws =
parallel
$ describe description
$ forM_ (lawsProperties laws)
$ uncurry it
where
description =
mconcat
[ "Testing "
, lawsTypeclass laws
, " laws for type "
, show (typeRep $ Proxy @a)
]
laws = getLaws $ Proxy @a
-- | Calls `testLaws` with multiple sets of laws.
--
-- Example usage:
--
-- >>> testLawsMany @Natural [eqLaws, ordLaws]
-- >>> testLawsMany @(Map Int) [foldableLaws, functorLaws]
testLawsMany
:: forall a
. Typeable a
=> [Proxy a -> Laws]
-> Spec
testLawsMany getLawsMany =
testLaws @a `mapM_` getLawsMany