{-# LANGUAGE FlexibleInstances #-}
module Test.Hspec.Wai.QuickCheck (
  property
, (==>)
, Arbitrary (..)
, module Test.QuickCheck.Gen
, Testable (..)
, WaiProperty (..)
) where
import           Test.QuickCheck hiding (Testable, property, (==>))
import qualified Test.QuickCheck as QuickCheck
import           Test.QuickCheck.Gen
import           Network.Wai (Application)
import           Test.Hspec.Wai.Internal
property :: Testable a => a -> Application -> Property
property = unWaiProperty . toProperty
data WaiProperty = WaiProperty {unWaiProperty :: Application -> Property}
class Testable a where
  toProperty :: a -> WaiProperty
instance Testable WaiProperty where
  toProperty = id
instance Testable WaiExpectation where
  toProperty action = WaiProperty (QuickCheck.property . runWaiSession action)
instance (Arbitrary a, Show a, Testable prop) => Testable (a -> prop) where
  toProperty prop = WaiProperty $ QuickCheck.property . (flip $ unWaiProperty . toProperty . prop)
infixr 0 ==>
(==>) :: Testable prop => Bool -> prop -> WaiProperty
(==>) = lift (QuickCheck.==>)
lift :: Testable prop => (a -> Property -> Property) -> a -> prop -> WaiProperty
lift f a prop = WaiProperty $ \app -> f a (unWaiProperty (toProperty prop) app)