@@ -1,5 +1,4 @@
1−{-# LANGUAGE CPP #-}
1+{-# LANGUAGE CPP #-}
2−{-# LANGUAGE ScopedTypeVariables #-}
3module Servant.QuickCheck.InternalSpec (spec) where
2module Servant.QuickCheck.InternalSpec (spec) where
5import Control.Concurrent.MVar (newMVar, readMVar,
4import Control.Concurrent.MVar (newMVar, readMVar,
@@ -8,11 +7,16 @@ import Control.Monad.IO.Class (liftIO)
8import Prelude.Compat
7import Prelude.Compat
9import Servant
8import Servant
10import Servant.API.Internal.Test.ComprehensiveAPI (comprehensiveAPI)
9import Servant.API.Internal.Test.ComprehensiveAPI (comprehensiveAPI)
11−import Test.Hspec (Spec, describe, it,
10+import Test.Hspec (Spec, context,
12− shouldBe)
12+ pending, shouldBe)
13+import Test.Hspec.Core.Spec (Arg, Example,
14import Servant.QuickCheck
18import Servant.QuickCheck
15−import Servant.QuickCheck.Internal (genRequest, serverDoesntSatisfy)
19+import Servant.QuickCheck.Internal (genRequest, Failure(..), serverDoesntSatisfy)
17spec :: Spec
21spec :: Spec
@@ -28,6 +32,23 @@ serversEqualSpec = describe "serversEqual" $ do
28 withServantServerAndContext api ctx server $ \burl2 -> do
32 withServantServerAndContext api ctx server $ \burl2 -> do
29 serversEqual api burl1 burl2 args bodyEquality
33 serversEqual api burl1 burl2 args bodyEquality
35+ context "when servers are not equal" $ do
37+ it "provides the failing requests in the error message" $ do
38+ Fail _ err <- withServantServer api2 server2 $ \burl1 ->
39+ withServantServer api2 server3 $ \burl2 -> do
40+ evalExample $ serversEqual api2 burl1 burl2 args bodyEquality
41+ let ServerEqualityFailure req _ _ = read err
42+ req `shouldBe` "failplz"
44+ it "provides the failing responses in the error message" $ do
45+ Fail _ err <- withServantServer api2 server2 $ \burl1 ->
46+ withServantServer api2 server3 $ \burl2 -> do
47+ evalExample $ serversEqual api2 burl1 burl2 args bodyEquality
48+ let ServerEqualityFailure _ r1 r2 = read err
32serverSatisfiesSpec :: Spec
53serverSatisfiesSpec :: Spec
33serverSatisfiesSpec = describe "serverSatisfies" $ do
54serverSatisfiesSpec = describe "serverSatisfies" $ do
@@ -46,6 +67,9 @@ serverSatisfiesSpec = describe "serverSatisfies" $ do
46 <%> notAllowedContainsAllowHeader
67 <%> notAllowedContainsAllowHeader
47 <%> mempty)
68 <%> mempty)
70+ context "when predicates are false" $
71+ it "fails with informative error messages" $ pending
49isComprehensiveSpec :: Spec
73isComprehensiveSpec :: Spec
50isComprehensiveSpec = describe "HasGenRequest" $ do
74isComprehensiveSpec = describe "HasGenRequest" $ do
@@ -72,12 +96,29 @@ server = do
72 :<|> (liftIO $ readMVar mvar >>= return . length)
96 :<|> (liftIO $ readMVar mvar >>= return . length)
73 :<|> (const $ return ())
97 :<|> (const $ return ())
100+type API2 = "failplz" :> Get '[JSON] Int
105+server2 :: IO (Server API2)
106+server2 = return $ return 1
108+server3 :: IO (Server API2)
109+server3 = return $ return 2
75ctx :: Context '[BasicAuthCheck ()]
111ctx :: Context '[BasicAuthCheck ()]
76ctx = BasicAuthCheck (const . return $ NoSuchUser) :. EmptyContext
112ctx = BasicAuthCheck (const . return $ NoSuchUser) :. EmptyContext
77------------------------------------------------------------------------------
113------------------------------------------------------------------------------
79------------------------------------------------------------------------------
115------------------------------------------------------------------------------
117+evalExample :: (Example e, Arg e ~ ()) => e -> IO Result
118+evalExample e = evaluateExample e defaultParams ($ ()) progCallback
120+ progCallback _ = return ()
81args :: Args
122args :: Args
82args = defaultArgs { maxSuccess = noOfTestCases }
123args = defaultArgs { maxSuccess = noOfTestCases }