genvalidity-property-1.0.0.0: src/Test/Validity/Functions/Inverse.hs
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
-- | Standard tests involving inverse functions
module Test.Validity.Functions.Inverse
( inverseFunctionsOnGen,
inverseFunctions,
inverseFunctionsOnArbitrary,
inverseFunctionsIfFirstSucceedsOnGen,
inverseFunctionsIfFirstSucceeds,
inverseFunctionsIfFirstSucceedsOnArbitrary,
inverseFunctionsIfSecondSucceedsOnGen,
inverseFunctionsIfSecondSucceeds,
inverseFunctionsIfSecondSucceedsOnArbitrary,
inverseFunctionsIfSucceedOnGen,
inverseFunctionsIfSucceed,
inverseFunctionsIfSucceedOnArbitrary,
)
where
import Data.GenValidity
import Test.Hspec
import Test.QuickCheck
import Test.Validity.Types
inverseFunctionsOnGen ::
(Show a, Eq a) => (a -> b) -> (b -> a) -> Gen a -> (a -> [a]) -> Property
inverseFunctionsOnGen f g gen s =
forAllShrink gen s $ \a -> g (f a) `shouldBe` a
inverseFunctions ::
(Show a, Eq a, GenValid a) => (a -> b) -> (b -> a) -> Property
inverseFunctions f g = inverseFunctionsOnGen f g genValid shrinkValid
-- |
-- 'id' is its own inverse function for every type:
-- prop> inverseFunctionsOnArbitrary id (id :: Int -> Int)
inverseFunctionsOnArbitrary ::
(Show a, Eq a, Arbitrary a) => (a -> b) -> (b -> a) -> Property
inverseFunctionsOnArbitrary f g = inverseFunctionsOnGen f g arbitrary shrink
inverseFunctionsIfFirstSucceedsOnGen ::
(Show a, Eq a, CanFail f) =>
(a -> f b) ->
(b -> a) ->
Gen a ->
(a -> [a]) ->
Property
inverseFunctionsIfFirstSucceedsOnGen f g gen s =
forAllShrink gen s $ \a ->
case resultIfSucceeded (f a) of
Nothing -> return () -- fine
Just b -> g b `shouldBe` a
inverseFunctionsIfFirstSucceeds ::
(Show a, Eq a, GenValid a, CanFail f) =>
(a -> f b) ->
(b -> a) ->
Property
inverseFunctionsIfFirstSucceeds f g =
inverseFunctionsIfFirstSucceedsOnGen f g genValid shrinkValid
inverseFunctionsIfFirstSucceedsOnArbitrary ::
(Show a, Eq a, Arbitrary a, CanFail f) =>
(a -> f b) ->
(b -> a) ->
Property
inverseFunctionsIfFirstSucceedsOnArbitrary f g =
inverseFunctionsIfFirstSucceedsOnGen f g arbitrary shrink
inverseFunctionsIfSecondSucceedsOnGen ::
(Show a, Eq a, CanFail f) =>
(a -> b) ->
(b -> f a) ->
Gen a ->
(a -> [a]) ->
Property
inverseFunctionsIfSecondSucceedsOnGen f g gen s =
forAllShrink gen s $ \a ->
case resultIfSucceeded (g (f a)) of
Nothing -> return () -- fine
Just r -> r `shouldBe` a
inverseFunctionsIfSecondSucceeds ::
(Show a, Eq a, GenValid a, CanFail f) =>
(a -> b) ->
(b -> f a) ->
Property
inverseFunctionsIfSecondSucceeds f g =
inverseFunctionsIfSecondSucceedsOnGen f g genValid shrinkValid
inverseFunctionsIfSecondSucceedsOnArbitrary ::
(Show a, Eq a, Arbitrary a, CanFail f) =>
(a -> b) ->
(b -> f a) ->
Property
inverseFunctionsIfSecondSucceedsOnArbitrary f g =
inverseFunctionsIfSecondSucceedsOnGen f g arbitrary shrink
inverseFunctionsIfSucceedOnGen ::
(Show a, Eq a, CanFail f, CanFail g) =>
(a -> f b) ->
(b -> g a) ->
Gen a ->
(a -> [a]) ->
Property
inverseFunctionsIfSucceedOnGen f g gen s =
forAllShrink gen s $ \a ->
case do
fa <- resultIfSucceeded $ f a
resultIfSucceeded $ g fa of
Nothing -> return () -- fine
Just r -> r `shouldBe` a
inverseFunctionsIfSucceed ::
(Show a, Eq a, GenValid a, CanFail f, CanFail g) =>
(a -> f b) ->
(b -> g a) ->
Property
inverseFunctionsIfSucceed f g =
inverseFunctionsIfSucceedOnGen f g genValid shrinkValid
inverseFunctionsIfSucceedOnArbitrary ::
(Show a, Eq a, Arbitrary a, CanFail f, CanFail g) =>
(a -> f b) ->
(b -> g a) ->
Property
inverseFunctionsIfSucceedOnArbitrary f g =
inverseFunctionsIfSucceedOnGen f g arbitrary shrink