{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE StandaloneDeriving #-}

module Test.QuickCheck.HigherOrder.Internal.TestEq where

import Data.Functor.Identity
import qualified Data.Monoid as Monoid
import Test.QuickCheck

import Test.QuickCheck.HigherOrder.Internal.Constructible
import Test.QuickCheck.HigherOrder.Internal.Testable.Class

-- | Testable equality
class TestEq a where
  -- | A property that /probably/ fails if the two values are not equal.
  --
  -- @
  -- (a '=?' a)  =  'property' 'True'
  -- @
  (=?) :: a -> a -> Property

-- | Default method to convert 'Eq' (decidable equality) into 'TestEq'.
decEq :: (Eq a, Show a) => a -> a -> Property
decEq :: a -> a -> Property
decEq a
a a
b = a
a a -> a -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== a
b

infix 4 =?


-- 'TestEq' instances

instance (Constructible a, TestEq b) => TestEq (a -> b) where
  a -> b
f =? :: (a -> b) -> (a -> b) -> Property
=? a -> b
g = (a -> Property) -> Property
forall prop. Testable' prop => prop -> Property
property' (\a
a -> a -> b
f a
a b -> b -> Property
forall a. TestEq a => a -> a -> Property
=? a -> b
g a
a)

deriving instance TestEq a => TestEq (Identity a)

instance (TestEq a, TestEq b) => TestEq (a, b) where
  (a
a1, b
b1) =? :: (a, b) -> (a, b) -> Property
=? (a
a2, b
b2) =
    String -> Property -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample String
"(_, _) =? (_, _)   (1) ..." (a
a1 a -> a -> Property
forall a. TestEq a => a -> a -> Property
=? a
a2) Property -> Property -> Property
forall prop1 prop2.
(Testable prop1, Testable prop2) =>
prop1 -> prop2 -> Property
.&&.
    String -> Property -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample String
"(_, _) =? (_, _)   (2) ..." (b
b1 b -> b -> Property
forall a. TestEq a => a -> a -> Property
=? b
b2)

instance (TestEq a, TestEq b) => TestEq (Either a b) where
  Left a
a1  =? :: Either a b -> Either a b -> Property
=? Left a
a2  = String -> Property -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample String
"Left _ =? Left _   ..."   (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$ a
a1 a -> a -> Property
forall a. TestEq a => a -> a -> Property
=? a
a2
  Right b
b1 =? Right b
b2 = String -> Property -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample String
"Right _ =? Right _   ..." (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$ b
b1 b -> b -> Property
forall a. TestEq a => a -> a -> Property
=? b
b2
  Left a
_ =? Right b
_ = String -> Property -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample String
"Left _ /= Right _" (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$ Bool -> Property
forall prop. Testable prop => prop -> Property
property Bool
False
  Right b
_ =? Left a
_ = String -> Property -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample String
"Right _ /= Left _" (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$ Bool -> Property
forall prop. Testable prop => prop -> Property
property Bool
False

instance TestEq a => TestEq (Maybe a) where
  Just a
a =? :: Maybe a -> Maybe a -> Property
=? Just a
b = String -> Property -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample String
"Just _ =? Just _   ..." (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$ a
a a -> a -> Property
forall a. TestEq a => a -> a -> Property
=? a
b
  Maybe a
Nothing =? Maybe a
Nothing = Bool -> Property
forall prop. Testable prop => prop -> Property
property Bool
True
  Just a
_ =? Maybe a
Nothing = String -> Property -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample String
"Just _ /= Nothing" (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$ Bool -> Property
forall prop. Testable prop => prop -> Property
property Bool
False
  Maybe a
Nothing =? Just a
_ = String -> Property -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample String
"Nothing /= Just _" (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$ Bool -> Property
forall prop. Testable prop => prop -> Property
property Bool
False

instance TestEq a => TestEq [a] where
  [] =? :: [a] -> [a] -> Property
=? [] = Bool -> Property
forall prop. Testable prop => prop -> Property
property Bool
True
  a
a : [a]
as =? a
b : [a]
bs =
    String -> Property -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample String
"(_ : _) =? (_ : _)   (1) ..." (a
a a -> a -> Property
forall a. TestEq a => a -> a -> Property
=? a
b) Property -> Property -> Property
forall prop1 prop2.
(Testable prop1, Testable prop2) =>
prop1 -> prop2 -> Property
.&&.
    String -> Property -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample String
"(_ : _) =? (_ : _)   (2) ..." ([a]
as [a] -> [a] -> Property
forall a. TestEq a => a -> a -> Property
=? [a]
bs)
  [] =? a
_ : [a]
_ = String -> Property -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample String
"[] /= (_ : _)" (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$ Bool -> Property
forall prop. Testable prop => prop -> Property
property Bool
False
  a
_ : [a]
_ =? [] = String -> Property -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample String
"(_ : _) /= []" (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$ Bool -> Property
forall prop. Testable prop => prop -> Property
property Bool
False

instance TestEq Integer where =? :: Integer -> Integer -> Property
(=?) = Integer -> Integer -> Property
forall a. (Eq a, Show a) => a -> a -> Property
decEq
instance TestEq Int where =? :: Int -> Int -> Property
(=?) = Int -> Int -> Property
forall a. (Eq a, Show a) => a -> a -> Property
decEq
instance TestEq Word where =? :: Word -> Word -> Property
(=?) = Word -> Word -> Property
forall a. (Eq a, Show a) => a -> a -> Property
decEq
instance TestEq Double where =? :: Double -> Double -> Property
(=?) = Double -> Double -> Property
forall a. (Eq a, Show a) => a -> a -> Property
decEq
instance TestEq Char where =? :: Char -> Char -> Property
(=?) = Char -> Char -> Property
forall a. (Eq a, Show a) => a -> a -> Property
decEq
instance TestEq () where =? :: () -> () -> Property
(=?) = () -> () -> Property
forall a. (Eq a, Show a) => a -> a -> Property
decEq
instance TestEq Bool where =? :: Bool -> Bool -> Property
(=?) = Bool -> Bool -> Property
forall a. (Eq a, Show a) => a -> a -> Property
decEq
instance TestEq Ordering where =? :: Ordering -> Ordering -> Property
(=?) = Ordering -> Ordering -> Property
forall a. (Eq a, Show a) => a -> a -> Property
decEq

deriving instance TestEq a => TestEq (Monoid.Sum a)