@@ -2,6 +2,7 @@
22module Servant.QuickCheck.InternalSpec (spec) where
33
44import Control.Concurrent.MVar (newMVar, readMVar, swapMVar)
5+import Control.Exception
56import Control.Monad.IO.Class (liftIO)
67import qualified Data.ByteString as BS
78import qualified Data.ByteString.Char8 as C
@@ -9,8 +10,8 @@ import Prelude.Compat
910import Servant
1011import Test.Hspec (Spec, context, describe, it, shouldBe,
1112 shouldContain)
12−import Test.Hspec.Core.Spec (Arg, Example, Result (..),
13− defaultParams, evaluateExample)
13+import Test.Hspec.Core.Spec (Arg, Example, Result (..), FailureReason (..),
14+ defaultParams, evaluateExample, safeEvaluateExample)
1415import Test.QuickCheck.Gen (unGen)
1516import Test.QuickCheck.Random (mkQCGen)
1617import Network.HTTP.Client (queryString, path)
@@ -46,11 +47,11 @@ serversEqualSpec = describe "serversEqual" $ do
4647
4748 context "when servers are not equal" $ do
4849
49−
5050 it "provides the failing responses in the error message" $ do
51− Fail _ err <- withServantServer api2 server2 $ \burl1 ->
51+ Right (Failure _ err) <- withServantServer api2 server2 $ \burl1 ->
5252 withServantServer api2 server3 $ \burl2 -> do
53− evalExample $ serversEqual api2 burl1 burl2 args bodyEquality
53+ safeEvalExample $ serversEqual api2 burl1 burl2 args bodyEquality
54+ show err `shouldContain` "Server equality failed"
5455 show err `shouldContain` "Body: 1"
5556 show err `shouldContain` "Body: 2"
5657 show err `shouldContain` "Path: /failplz"
@@ -75,20 +76,20 @@ serverSatisfiesSpec = describe "serverSatisfies" $ do
7576 context "when predicates are false" $ do
7677
7778 it "fails with informative error messages" $ do
78− Fail _ err <- withServantServerAndContext api ctx server $ \burl -> do
79− evalExample $ serverSatisfies api burl args (getsHaveCacheControlHeader <%> mempty)
80− err `shouldContain` "getsHaveCacheControlHeader"
81− err `shouldContain` "Headers"
82− err `shouldContain` "Body"
79+ Right (Failure _ err) <- withServantServerAndContext api ctx server $ \burl -> do
80+ safeEvalExample $ serverSatisfies api burl args (getsHaveCacheControlHeader <%> mempty)
81+ show err `shouldContain` "getsHaveCacheControlHeader"
82+ show err `shouldContain` "Headers"
83+ show err `shouldContain` "Body"
8384
8485onlyJsonObjectSpec :: Spec
8586onlyJsonObjectSpec = describe "onlyJsonObjects" $ do
8687
8788 it "fails correctly" $ do
88− Fail _ err <- withServantServerAndContext api ctx server $ \burl -> do
89− evalExample $ serverSatisfies (Proxy :: Proxy (Get '[JSON] Int)) burl args
89+ Right (Failure _ err) <- withServantServerAndContext api ctx server $ \burl -> do
90+ safeEvalExample $ serverSatisfies (Proxy :: Proxy (Get '[JSON] Int)) burl args
9091 (onlyJsonObjects <%> mempty)
91− err `shouldContain` "onlyJsonObjects"
92+ show err `shouldContain` "onlyJsonObjects"
9293
9394 it "accepts non-JSON endpoints" $ do
9495 withServantServerAndContext octetAPI ctx serverOctetAPI $ \burl ->
@@ -98,10 +99,10 @@ notLongerThanSpec :: Spec
9899notLongerThanSpec = describe "notLongerThan" $ do
99100
100101 it "fails correctly" $ do
101− Fail _ err <- withServantServerAndContext api ctx server $ \burl -> do
102− evalExample $ serverSatisfies (Proxy :: Proxy (Get '[JSON] Int)) burl args
102+ Right (Failure _ err) <- withServantServerAndContext api ctx server $ \burl -> do
103+ safeEvalExample $ serverSatisfies (Proxy :: Proxy (Get '[JSON] Int)) burl args
103104 (notLongerThan 1 <%> mempty)
104− err `shouldContain` "notLongerThan"
105+ show err `shouldContain` "notLongerThan"
105106
106107 it "succeeds correctly" $ do
107108 withServantServerAndContext api ctx server $ \burl ->
@@ -213,6 +214,12 @@ evalExample e = evaluateExample e defaultParams ($ ()) progCallback
213214 where
214215 progCallback _ = return ()
215216
217+safeEvalExample :: (Example e, Arg e ~ ()) => e -> IO (Either SomeException Result)
218+safeEvalExample e = safeEvaluateExample e defaultParams ($ ()) progCallback
219+ where
220+ progCallback _ = return ()
221+
222+
216223args :: Args
217224args = defaultArgs { maxSuccess = noOfTestCases }
218225