{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE ScopedTypeVariables #-} -- | Tests for shrinking functions module Test.Validity.Shrinking.Property ( shrinkPreservesValidOnGenValid , shrinkPreservesInvalidOnGenInvalid , shrinkValidPreservesValid , shrinkInvalidPreservesInvalid , shrinkingStaysValid , shrinkingStaysValidWithLimit , shrinkingStaysInvalid , shrinkingPreserves , shrinkingPreservesWithLimit , shrinkDoesNotShrinkToItself , shrinkDoesNotShrinkToItselfWithLimit , shrinkDoesNotShrinkToItselfOnValid , shrinkDoesNotShrinkToItselfOnValidWithLimit , shrinkDoesNotShrinkToItselfOnInvalid , shrinkDoesNotShrinkToItselfOnInvalidWithLimit , doesNotShrinkToItself , doesNotShrinkToItselfWithLimit ) where import Data.GenValidity import Test.QuickCheck -- | -- -- prop> shrinkPreservesValidOnGenValid ((:[]) :: Int -> [Int]) shrinkPreservesValidOnGenValid :: forall a. (Show a, GenValid a) => (a -> [a]) -> Property shrinkPreservesValidOnGenValid = shrinkingStaysValid genValid -- | -- -- prop> shrinkPreservesInvalidOnGenInvalid ((:[]) :: Rational -> [Rational]) shrinkPreservesInvalidOnGenInvalid :: forall a. (Show a, GenInvalid a) => (a -> [a]) -> Property shrinkPreservesInvalidOnGenInvalid = shrinkingStaysValid genInvalid -- | -- -- prop> shrinkValidPreservesValid (pure 5 :: Gen Rational) shrinkValidPreservesValid :: forall a. (Show a, GenValid a) => Gen a -> Property shrinkValidPreservesValid gen = shrinkingStaysValid gen shrinkValid -- | -- shrinkInvalidPreservesInvalid :: forall a. (Show a, GenInvalid a) => Gen a -> Property shrinkInvalidPreservesInvalid gen = shrinkingStaysValid gen shrinkInvalid -- | -- -- prop> shrinkingStaysValid (pure 5 :: Gen Double) (\d -> [d - 1, d - 2]) shrinkingStaysValid :: forall a. (Show a, Validity a) => Gen a -> (a -> [a]) -> Property shrinkingStaysValid gen s = shrinkingPreserves gen s isValid -- | -- -- prop> shrinkingStaysValidWithLimit (pure 5 :: Gen Double) (\d -> [d - 1, read "NaN"]) 1 shrinkingStaysValidWithLimit :: forall a. (Show a, Validity a) => Gen a -> (a -> [a]) -> Int -> Property shrinkingStaysValidWithLimit gen s l = shrinkingPreservesWithLimit gen s l isValid -- | -- -- prop> shrinkingStaysInvalid (pure (1/0) :: Gen Double) (:[]) shrinkingStaysInvalid :: forall a. (Show a, Validity a) => Gen a -> (a -> [a]) -> Property shrinkingStaysInvalid gen s = shrinkingPreserves gen s isInvalid -- | -- -- prop> shrinkingPreserves (pure 5 :: Gen Int) (:[]) (== 5) shrinkingPreserves :: forall a. Show a => Gen a -> (a -> [a]) -> (a -> Bool) -> Property shrinkingPreserves gen s p = forAll gen $ \d -> not (p d) || all p (s d) -- | -- -- prop> shrinkingPreservesWithLimit (pure 4) (:[]) 100 (== 4) shrinkingPreservesWithLimit :: forall a. Show a => Gen a -> (a -> [a]) -> Int -> (a -> Bool) -> Property shrinkingPreservesWithLimit gen s l p = forAll gen $ \d -> not (p d) || all p (take l $ s d) -- | -- -- prop> shrinkDoesNotShrinkToItself (shrinkUnchecked :: Double -> [Double]) shrinkDoesNotShrinkToItself :: forall a. (Show a, Eq a, GenUnchecked a) => (a -> [a]) -> Property shrinkDoesNotShrinkToItself = doesNotShrinkToItself genUnchecked -- | -- -- prop> shrinkDoesNotShrinkToItselfWithLimit (shrinkUnchecked :: Double -> [Double]) 100 shrinkDoesNotShrinkToItselfWithLimit :: forall a. (Show a, Eq a, GenUnchecked a) => (a -> [a]) -> Int -> Property shrinkDoesNotShrinkToItselfWithLimit = doesNotShrinkToItselfWithLimit genUnchecked -- | -- -- prop> shrinkDoesNotShrinkToItselfOnValid (shrinkValid :: Rational -> [Rational]) shrinkDoesNotShrinkToItselfOnValid :: forall a. (Show a, Eq a, GenValid a) => (a -> [a]) -> Property shrinkDoesNotShrinkToItselfOnValid = doesNotShrinkToItself genValid -- | -- -- prop> shrinkDoesNotShrinkToItselfOnValidWithLimit (shrinkValid :: Rational -> [Rational]) 100 shrinkDoesNotShrinkToItselfOnValidWithLimit :: forall a. (Show a, Eq a, GenValid a) => (a -> [a]) -> Int -> Property shrinkDoesNotShrinkToItselfOnValidWithLimit = doesNotShrinkToItselfWithLimit genValid -- | -- -- prop> shrinkDoesNotShrinkToItselfOnInvalid (shrinkInvalid :: Rational -> [Rational]) shrinkDoesNotShrinkToItselfOnInvalid :: forall a. (Show a, Eq a, GenInvalid a) => (a -> [a]) -> Property shrinkDoesNotShrinkToItselfOnInvalid = doesNotShrinkToItself genInvalid -- | -- -- prop> shrinkDoesNotShrinkToItselfOnInvalidWithLimit (shrinkInvalid :: Rational -> [Rational]) 100 shrinkDoesNotShrinkToItselfOnInvalidWithLimit :: forall a. (Show a, Eq a, GenInvalid a) => (a -> [a]) -> Int -> Property shrinkDoesNotShrinkToItselfOnInvalidWithLimit = doesNotShrinkToItselfWithLimit genInvalid -- | -- -- prop> doesNotShrinkToItself (pure 5 :: Gen Double) shrinkUnchecked doesNotShrinkToItself :: forall a. (Show a, Eq a) => Gen a -> (a -> [a]) -> Property doesNotShrinkToItself gen s = forAll gen $ \a -> all (/= a) $ s a -- | -- -- prop> doesNotShrinkToItselfWithLimit (pure 5 :: Gen Double) shrinkUnchecked 100 doesNotShrinkToItselfWithLimit :: forall a. (Show a, Eq a) => Gen a -> (a -> [a]) -> Int -> Property doesNotShrinkToItselfWithLimit gen s l = forAll gen $ \a -> all (/= a) $ take l $ s a