module Test.Themis.Assertion (
    Assertion(..)
  , assertion
  , module Test.QuickCheck.Gen
  ) where

import           Test.QuickCheck.Gen

-- Simple test abtraction
data Assertion a
  = Equals a a String
  -- ^ Values must be equals, in order: expected, found, message
  | Satisfies (a -> Bool) a String
  -- ^ The given value must be satisfy the given predicate
  | Property (a -> Bool) (Gen a) String
  -- ^ The given predicate must be true for every possible value generated by the given generator
  | Error a String
  -- ^ Evaluationg the given expression should an error thrown

instance (Show a) => Show (Assertion a) where
  show = assertion equals satisfies property err
    where
      equals x y msg     = concat ["Equals ", show x, " ", show y, " ", msg]
      satisfies _p y msg = concat ["Satisfies [property] ", show y, " ", msg]
      property _p _g msg = concat ["Property ", msg]
      err _v         msg = concat ["Error ", msg]

assertion
  equals
  satisfies
  property
  err
  a = case a of
    Equals    expected found msg -> equals    expected found msg
    Satisfies prop     found msg -> satisfies prop     found msg
    Property  prop     gen   msg -> property  prop     gen   msg
    Error     value          msg -> err       value          msg
