{-# LANGUAGE CPP #-}
{-# LANGUAGE KindSignatures #-}
{-# OPTIONS_GHC -Wall #-}
module Test.QuickCheck.Classes.Base
(
lawsCheck
, lawsCheckMany
, lawsCheckOne
#if MIN_VERSION_base(4,7,0)
, bitsLaws
#endif
, eqLaws
, substitutiveEqLaws
, numLaws
, integralLaws
, ixLaws
#if MIN_VERSION_base(4,7,0)
, isListLaws
#endif
, monoidLaws
, commutativeMonoidLaws
, semigroupMonoidLaws
, ordLaws
, enumLaws
, boundedEnumLaws
, semigroupLaws
, commutativeSemigroupLaws
, exponentialSemigroupLaws
, idempotentSemigroupLaws
, rectangularBandSemigroupLaws
, showLaws
, showReadLaws
, storableLaws
#if MIN_VERSION_base(4,5,0)
, genericLaws
, generic1Laws
#endif
#if HAVE_UNARY_LAWS
, alternativeLaws
, applicativeLaws
, contravariantLaws
, foldableLaws
, functorLaws
, monadLaws
, monadPlusLaws
, monadZipLaws
, traversableLaws
#endif
#if HAVE_BINARY_LAWS
, bifoldableLaws
, bifunctorLaws
, bitraversableLaws
, categoryLaws
, commutativeCategoryLaws
#endif
, Laws(..)
, Proxy1(..)
, Proxy2(..)
) where
import Test.QuickCheck.Classes.Bits
import Test.QuickCheck.Classes.Enum
import Test.QuickCheck.Classes.Eq
import Test.QuickCheck.Classes.Num
import Test.QuickCheck.Classes.Integral
import Test.QuickCheck.Classes.Ix
#if MIN_VERSION_base(4,7,0)
import Test.QuickCheck.Classes.Base.IsList
#endif
import Test.QuickCheck.Classes.Monoid
import Test.QuickCheck.Classes.Ord
import Test.QuickCheck.Classes.Semigroup
import Test.QuickCheck.Classes.Show
import Test.QuickCheck.Classes.ShowRead
import Test.QuickCheck.Classes.Storable
#if MIN_VERSION_base(4,5,0)
import Test.QuickCheck.Classes.Generic
#endif
#if HAVE_UNARY_LAWS
import Test.QuickCheck.Classes.Alternative
import Test.QuickCheck.Classes.Applicative
import Test.QuickCheck.Classes.Contravariant
import Test.QuickCheck.Classes.Foldable
import Test.QuickCheck.Classes.Functor
import Test.QuickCheck.Classes.Monad
import Test.QuickCheck.Classes.MonadPlus
import Test.QuickCheck.Classes.MonadZip
import Test.QuickCheck.Classes.Traversable
#endif
#if HAVE_BINARY_LAWS
import Test.QuickCheck.Classes.Bifunctor
import Test.QuickCheck.Classes.Bifoldable
import Test.QuickCheck.Classes.Bitraversable
import Test.QuickCheck.Classes.Category
#if HAVE_SEMIGROUPOIDS
import Test.QuickCheck.Classes.Semigroupoid
#endif
#endif
import Test.QuickCheck
import Test.QuickCheck.Classes.Internal (foldMapA, Laws(..))
import Control.Monad
import Data.Foldable
import Data.Monoid (Monoid(..))
import Data.Proxy (Proxy(..))
import Data.Semigroup (Semigroup)
import System.Exit (exitFailure)
import qualified Data.List as List
import qualified Data.Semigroup as SG
lawsCheck :: Laws -> IO ()
lawsCheck :: Laws -> IO ()
lawsCheck (Laws String
className [(String, Property)]
properties) = do
(((String, Property) -> IO ()) -> [(String, Property)] -> IO ())
-> [(String, Property)] -> ((String, Property) -> IO ()) -> IO ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((String, Property) -> IO ()) -> [(String, Property)] -> IO ()
forall (t :: * -> *) m (f :: * -> *) a.
(Foldable t, Monoid m, Semigroup m, Applicative f) =>
(a -> f m) -> t a -> f m
foldMapA [(String, Property)]
properties (((String, Property) -> IO ()) -> IO ())
-> ((String, Property) -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \(String
name,Property
p) -> do
String -> IO ()
putStr (String
className String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" ")
Property -> IO ()
forall prop. Testable prop => prop -> IO ()
quickCheck Property
p
lawsCheckOne :: Proxy a -> [Proxy a -> Laws] -> IO ()
lawsCheckOne :: Proxy a -> [Proxy a -> Laws] -> IO ()
lawsCheckOne Proxy a
p [Proxy a -> Laws]
ls = ((Proxy a -> Laws) -> IO ()) -> [Proxy a -> Laws] -> IO ()
forall (t :: * -> *) b (m :: * -> *) a.
(Foldable t, Monoid b, Monad m) =>
(a -> m b) -> t a -> m b
foldlMapM (Laws -> IO ()
lawsCheck (Laws -> IO ())
-> ((Proxy a -> Laws) -> Laws) -> (Proxy a -> Laws) -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Proxy a -> Laws) -> Proxy a -> Laws
forall a b. (a -> b) -> a -> b
$ Proxy a
p)) [Proxy a -> Laws]
ls
lawsCheckMany ::
[(String,[Laws])]
-> IO ()
lawsCheckMany :: [(String, [Laws])] -> IO ()
lawsCheckMany [(String, [Laws])]
xs = do
String -> IO ()
putStrLn String
"Testing properties for common typeclasses"
Status
r <- (((String, [Laws]) -> IO Status)
-> [(String, [Laws])] -> IO Status)
-> [(String, [Laws])]
-> ((String, [Laws]) -> IO Status)
-> IO Status
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((String, [Laws]) -> IO Status) -> [(String, [Laws])] -> IO Status
forall (t :: * -> *) m (f :: * -> *) a.
(Foldable t, Monoid m, Semigroup m, Applicative f) =>
(a -> f m) -> t a -> f m
foldMapA [(String, [Laws])]
xs (((String, [Laws]) -> IO Status) -> IO Status)
-> ((String, [Laws]) -> IO Status) -> IO Status
forall a b. (a -> b) -> a -> b
$ \(String
typeName,[Laws]
laws) -> do
String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ Int -> Char -> String
forall a. Int -> a -> [a]
List.replicate (String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
typeName Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
6) Char
'-'
String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"-- " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
typeName String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" --"
String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ Int -> Char -> String
forall a. Int -> a -> [a]
List.replicate (String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
typeName Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
6) Char
'-'
((Laws -> IO Status) -> [Laws] -> IO Status)
-> [Laws] -> (Laws -> IO Status) -> IO Status
forall a b c. (a -> b -> c) -> b -> a -> c
flip (Laws -> IO Status) -> [Laws] -> IO Status
forall (t :: * -> *) m (f :: * -> *) a.
(Foldable t, Monoid m, Semigroup m, Applicative f) =>
(a -> f m) -> t a -> f m
foldMapA [Laws]
laws ((Laws -> IO Status) -> IO Status)
-> (Laws -> IO Status) -> IO Status
forall a b. (a -> b) -> a -> b
$ \(Laws String
typeClassName [(String, Property)]
properties) -> do
(((String, Property) -> IO Status)
-> [(String, Property)] -> IO Status)
-> [(String, Property)]
-> ((String, Property) -> IO Status)
-> IO Status
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((String, Property) -> IO Status)
-> [(String, Property)] -> IO Status
forall (t :: * -> *) m (f :: * -> *) a.
(Foldable t, Monoid m, Semigroup m, Applicative f) =>
(a -> f m) -> t a -> f m
foldMapA [(String, Property)]
properties (((String, Property) -> IO Status) -> IO Status)
-> ((String, Property) -> IO Status) -> IO Status
forall a b. (a -> b) -> a -> b
$ \(String
name,Property
p) -> do
String -> IO ()
putStr (String
typeClassName String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" ")
Result
r <- Property -> IO Result
forall prop. Testable prop => prop -> IO Result
quickCheckResult Property
p
Status -> IO Status
forall (m :: * -> *) a. Monad m => a -> m a
return (Status -> IO Status) -> Status -> IO Status
forall a b. (a -> b) -> a -> b
$ case Result
r of
Success{} -> Status
Good
Result
_ -> Status
Bad
String -> IO ()
putStrLn String
""
case Status
r of
Status
Good -> String -> IO ()
putStrLn String
"All tests succeeded"
Status
Bad -> do
String -> IO ()
putStrLn String
"One or more tests failed"
IO ()
forall a. IO a
exitFailure
data Status = Bad | Good
instance Semigroup Status where
Status
Good <> :: Status -> Status -> Status
<> Status
x = Status
x
Status
Bad <> Status
_ = Status
Bad
instance Monoid Status where
mempty :: Status
mempty = Status
Good
mappend :: Status -> Status -> Status
mappend = Status -> Status -> Status
forall a. Semigroup a => a -> a -> a
(SG.<>)
data Proxy1 (f :: * -> *) = Proxy1
data Proxy2 (f :: * -> * -> *) = Proxy2
foldlMapM :: (Foldable t, Monoid b, Monad m) => (a -> m b) -> t a -> m b
foldlMapM :: (a -> m b) -> t a -> m b
foldlMapM a -> m b
f = (b -> a -> m b) -> b -> t a -> m b
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldlM (\b
b a
a -> (b -> b) -> m b -> m b
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (b -> b -> b
forall a. Monoid a => a -> a -> a
mappend b
b) (a -> m b
f a
a)) b
forall a. Monoid a => a
mempty