    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 :: forall a prop.
    (Show a, GenValid a, Testable prop) =>
    (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 :: forall a. (Show a, Validity a) => 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 a. a -> IO a
    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 :: forall a. (Show a, Validity a) => 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 a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure ()