{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE TypeFamilies #-} module Test.Hspec.Wai.QuickCheck ( property , (==>) -- * Re-exports , Arbitrary (..) , module Test.QuickCheck.Gen -- * Internals , 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 -> (State a, Application) -> Property property = unWaiProperty . toProperty data WaiProperty st = WaiProperty {unWaiProperty :: (st, Application) -> Property} class Testable a where type State a toProperty :: a -> WaiProperty (State a) instance Testable (WaiProperty st) where type State (WaiProperty st) = st toProperty = id instance Testable (WaiExpectation st) where type State (WaiExpectation st) = st toProperty action = WaiProperty (QuickCheck.property . runWithState action) instance (Arbitrary a, Show a, Testable prop) => Testable (a -> prop) where type State (a -> prop) = State prop toProperty prop = WaiProperty $ QuickCheck.property . (flip $ unWaiProperty . toProperty . prop) infixr 0 ==> (==>) :: Testable prop => Bool -> prop -> WaiProperty (State prop) (==>) = lift (QuickCheck.==>) lift :: Testable prop => (a -> Property -> Property) -> a -> prop -> WaiProperty (State prop) lift f a prop = WaiProperty $ \app -> f a (unWaiProperty (toProperty prop) app)