module Test.Validity.Property.Utils
  ( forAllValid,
    shouldBeValid,
    shouldBeInvalid,
    (<==>),
    (===>),
  )
where

import Data.GenValidity
import Test.Hspec
import Test.QuickCheck
import Text.Show.Pretty (ppShow)

forAllValid :: (Show a, GenValid a, Testable prop) => (a -> prop) -> Property
forAllValid :: (a -> prop) -> Property
forAllValid = Gen a -> (a -> [a]) -> (a -> prop) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> [a]) -> (a -> prop) -> Property
forAllShrink Gen a
forall a. GenValid a => Gen a
genValid a -> [a]
forall a. GenValid a => a -> [a]
shrinkValid

(===>) :: Bool -> Bool -> Bool
===> :: Bool -> Bool -> Bool
(===>) Bool
a Bool
b = Bool -> Bool
not Bool
a Bool -> Bool -> Bool
|| Bool
b

(<==>) :: Bool -> Bool -> Bool
<==> :: Bool -> Bool -> Bool
(<==>) Bool
a Bool
b = Bool
a Bool -> Bool -> Bool
===> Bool
b Bool -> Bool -> Bool
&& Bool
b Bool -> Bool -> Bool
===> Bool
a

shouldBeValid :: (Show a, Validity a) => a -> Expectation
shouldBeValid :: a -> Expectation
shouldBeValid a
a =
  case a -> Either String a
forall a. Validity a => a -> Either String a
prettyValidate a
a of
    Right a
_ -> () -> Expectation
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
    Left String
err ->
      HasCallStack => String -> Expectation
String -> Expectation
expectationFailure (String -> Expectation) -> String -> Expectation
forall a b. (a -> b) -> a -> b
$
        [String] -> String
unlines
          [ String
"'validate' reported this value to be invalid: ",
            a -> String
forall a. Show a => a -> String
show a
a,
            String
"pretty version:",
            a -> String
forall a. Show a => a -> String
ppShow a
a,
            String
"with explanation:",
            String
err,
            String
""
          ]

shouldBeInvalid :: (Show a, Validity a) => a -> Expectation
shouldBeInvalid :: a -> Expectation
shouldBeInvalid a
a =
  case a -> Either String a
forall a. Validity a => a -> Either String a
prettyValidate a
a of
    Right a
_ ->
      HasCallStack => String -> Expectation
String -> Expectation
expectationFailure (String -> Expectation) -> String -> Expectation
forall a b. (a -> b) -> a -> b
$
        [String] -> String
unlines
          [ String
"'validate' reported this value to be valid: ",
            a -> String
forall a. Show a => a -> String
show a
a,
            String
"pretty version:",
            a -> String
forall a. Show a => a -> String
ppShow a
a,
            String
"where we expected it to be invalid"
          ]
    Left String
_ -> () -> Expectation
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()