packages feed

heap-1.0.0: Test/Heap/Common.hs

module Test.Heap.Common
    ( qc
    , eqProperty, ordProperty
    , readShowProperty
    , monoidProperty
    , functorProperty
    , foldableProperty
    ) where

import Data.Foldable ( Foldable(..) )
import Data.Monoid
import Prelude hiding ( foldl, foldr )
import Test.QuickCheck

qc :: (Testable prop) => String -> prop -> IO ()
qc msg prop = quickCheck
    $ whenFail (putStrLn msg)
    $ label msg prop

eqProperty :: (Eq a) => a -> a -> a -> Bool
eqProperty x y z = (x == y) == (y == x)
    && ((not (x == y && y == z)) || x == z)

ordProperty :: (Ord a) => a -> a -> a -> Bool
ordProperty x y z = let
    _min = minimum [x, y, z]
    _max = maximum [x, y, z]
    in case compare x y of
            LT -> x < y && x <= y && not (x > y) && not (x >= y)
            EQ -> x == y && x <= y && x >= y && not (x < y) && not (x > y)
            GT -> x > y && x >= y && not (x < y) && not (x <= y)
        && _min <= x && _min <= y && _min <= z
        && _max >= x && _max >= y && _max >= z

readShowProperty :: (Read a, Show a, Eq a) => [a] -> Bool
readShowProperty x = x == read (show x)
    && (null x || head x == read (show (head x)))

monoidProperty :: (Monoid m, Eq m) => m -> m -> m -> Bool
monoidProperty m1 m2 m3 = let
    result = mconcat [m1, m2, m3]
    in
    result == (m1 `mappend` m2) `mappend` m3
        && result == m1 `mappend` (m2 `mappend` m3)
        && m1 == mempty `mappend` m1
        && m1 == m1 `mappend` mempty

functorProperty :: (Functor f, Eq (f a), Eq (f c)) => (b -> c) -> (a -> b) -> f a -> Bool
functorProperty f g fun = fun == fmap id fun
    && fmap (f . g) fun == fmap f (fmap g fun)

foldableProperty :: (Foldable f, Eq a) => f a -> Bool
foldableProperty xs = foldl (flip (:)) [] xs == reverse (foldr (:) [] xs)