{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Test.Validity.Functions.Idempotence
( idempotentOnGen
, idempotentOnValid
, idempotent
, idempotentOnArbitrary
) where
import Data.GenValidity
import Test.Hspec
import Test.QuickCheck
idempotentOnGen :: (Show a, Eq a) => (a -> a) -> Gen a -> (a -> [a]) -> Property
idempotentOnGen f gen s = forAllShrink gen s $ \a -> f (f a) `shouldBe` f a
idempotentOnValid :: (Show a, Eq a, GenValid a) => (a -> a) -> Property
idempotentOnValid func = idempotentOnGen func genValid shrinkValid
idempotent :: (Show a, Eq a, GenUnchecked a) => (a -> a) -> Property
idempotent func = idempotentOnGen func genUnchecked shrinkUnchecked
idempotentOnArbitrary :: (Show a, Eq a, Arbitrary a) => (a -> a) -> Property
idempotentOnArbitrary func = idempotentOnGen func arbitrary shrink