git.iko.soy/servant-quickcheck
on master help sign in
prelude-compat
commiteb51069cb505f8e2b28556316804714cee98d398 authorJulian K. Arni <jkarni@gmail.com> dateMon 9 May 2016, 17:49 (10 years ago) parentb48b1e8
8 files changed+35−106
.gitignore+1 servant-quickcheck.cabal+3−15 src/Servant/QuickCheck/Internal.hs−1 src/Servant/QuickCheck/Internal/Benchmarking.hs−83 src/Servant/QuickCheck/Internal/Equality.hs+7−2 src/Servant/QuickCheck/Internal/HasGenRequest.hs+6−5 src/Servant/QuickCheck/Internal/Predicates.hs+9 src/Servant/QuickCheck/Internal/QuickCheck.hs+9
.gitignore+1
@@ -1 +1,2 @@
11doc/_build/
2+scripts/
servant-quickcheck.cabal+3−15
@@ -1,5 +1,5 @@
11name: servant-quickcheck
2−version: 0.1.0.0
2+version: 0.0.0.0
33synopsis: QuickCheck entire APIs
44description:
55 This packages provides QuickCheck properties that are tested across an entire
@@ -20,12 +20,12 @@ flag long-tests
2020library
2121 exposed-modules: Servant.QuickCheck
2222 , Servant.QuickCheck.Internal
23− -- , Servant.QuickCheck.Internal.Benchmarking
2423 , Servant.QuickCheck.Internal.Predicates
2524 , Servant.QuickCheck.Internal.HasGenRequest
2625 , Servant.QuickCheck.Internal.QuickCheck
2726 , Servant.QuickCheck.Internal.Equality
2827 build-depends: base >=4.7 && <4.9
28+ , base-compat == 0.9.*
2929 , QuickCheck == 2.8.*
3030 , bytestring == 0.10.*
3131 , aeson > 0.10 && < 0.12
@@ -63,6 +63,7 @@ library
6363 , ScopedTypeVariables
6464 , OverloadedStrings
6565 , FunctionalDependencies
66+ , NoImplicitPrelude
6667 default-language: Haskell2010
6768
6869test-suite spec
@@ -89,16 +90,3 @@ test-suite spec
8990 , DataKinds
9091 if flag(long-tests)
9192 cpp-options: -DLONG_TESTS
92−
93−-- test-suite doctests
94−-- default-language: Haskell2010
95−-- type: exitcode-stdio-1.0
96−-- ghc-options: -threaded
97−-- main-is: Doctest.hs
98−-- hs-source-dirs: test
99−-- build-depends: base >4 && <5
100−-- , doctest
101−-- , filemanip
102−-- , directory
103−-- , filepath
104−-- HS-Source-Dirs: test
src/Servant/QuickCheck/Internal.hs−1
@@ -4,4 +4,3 @@ import Servant.QuickCheck.Internal.HasGenRequest as X
44import Servant.QuickCheck.Internal.Predicates as X
55import Servant.QuickCheck.Internal.QuickCheck as X
66import Servant.QuickCheck.Internal.Equality as X
7−import Servant.QuickCheck.Internal.Benchmarking as X
src/Servant/QuickCheck/Internal/Benchmarking.hsdeleted−83
@@ -1,83 +0,0 @@
1−-- This is a WIP module that shouldn't be used.
2−module Servant.QuickCheck.Internal.Benchmarking where
3−
4−import Data.ByteString (ByteString)
5−import Data.ByteString.Lazy (toStrict)
6−import Network.HTTP.Client
7−import Network.HTTP.Types
8−import Servant.Client
9−
10−data BenchOptions = BenchOptions
11− { duration :: Int
12− , threads :: Int
13− , connections :: Int
14− , noOfTests :: Int
15− } deriving (Eq, Show, Read)
16−
17−defaultBenchOptions :: BenchOptions
18−defaultBenchOptions = BenchOptions
19− { duration = 10
20− , threads = 1
21− , connections = 10
22− , noOfTests = 10
23− }
24−
25−data WrkScript = WrkScript
26− { wrkScheme :: Scheme
27− , wrkHost :: ByteString
28− , wrkPort :: Int
29− , wrkMethod :: Method
30− , wrkPath :: ByteString
31− , wrkHeaders :: [Header]
32− , wrkBody :: ByteString
33− } deriving (Eq, Show)
34−
35−mkScript :: WrkScript -> String
36−mkScript w
37− = "wrk.scheme = \"" ++ sscheme (wrkScheme w) ++ "\""
38− ++ "\nwrk.host = " ++ show (wrkHost w)
39− ++ "\nwrk.port = " ++ show (wrkPort w)
40− ++ "\nwrk.method = " ++ show (wrkMethod w)
41− ++ "\nwrk.path = " ++ show (wrkPath w)
42− ++ foldr (\(h,v) old -> old ++ "\nwrk.headers[" ++ show h ++ "] = " ++ show v)
43− ""
44− (wrkHeaders w)
45− ++ "\nwrk.body = " ++ show (wrkBody w)
46− ++ "\n" ++ reportFmt
47− where
48− sscheme Http = "http"
49− sscheme Https = "https"
50−
51−reqToWrk :: Request -> WrkScript
52−reqToWrk r = WrkScript
53− { wrkScheme = Http
54− , wrkHost = host r
55− , wrkPort = port r
56− , wrkMethod = method r
57− , wrkPath = path r
58− , wrkHeaders = requestHeaders r
59− , wrkBody = case requestBody r of
60− RequestBodyLBS r' -> toStrict r'
61− _ -> error "expecting RequestBodyLBS"
62− }
63−
64−reportFmt :: String
65−reportFmt
66− = "done = function(summary, latency, requests)\n"
67− ++ " for _, p in pairs({ 50, 75, 99, 99.999 }) do\n"
68− ++ " n = latency:percentile(p)\n"
69− ++ " io.write(string.format(\"%g%%, %d\\n\", p, n))\n"
70− ++ " end\n"
71− ++ "end\n"
72−
73−{-data BenchResult = BenchResult-}
74− {-{ benchReq :: Request-}
75− {-, benchLatencyDist :: [(Percentile, Microsecs)]-}
76− {-, benchLatencyAvg :: Microsecs-}
77− {-} deriving (Eq, Show, Read, Generic)-}
78−
79−{-newtype Microsecs = Microsecs { unMicroSecs :: Int }-}
80− {-deriving (Eq, Show, Read, Generic)-}
81−
82−{-newtype Percentile = Percentile { unPercentile :: Int }-}
83− {-deriving (Eq, Show, Read, Generic)-}
src/Servant/QuickCheck/Internal/Equality.hs+7−2
@@ -1,7 +1,8 @@
11module Servant.QuickCheck.Internal.Equality where
22
3−import Network.HTTP.Client
4−import Data.Function (on)
3+import Data.Function (on)
4+import Network.HTTP.Client (Response, responseBody)
5+import Prelude.Compat
56
67newtype ResponseEquality b
78 = ResponseEquality { getResponseEquality :: Response b -> Response b -> Bool }
@@ -12,9 +13,13 @@ instance Monoid (ResponseEquality b) where
1213 a x y && b x y
1314
1415-- | Use `Eq` instance for `Response`
16+--
17+-- #SINCE#
1518allEquality :: Eq b => ResponseEquality b
1619allEquality = ResponseEquality (==)
1720
1821-- | ByteString `Eq` instance over the response body.
22+--
23+-- #SINCE#
1924bodyEquality :: Eq b => ResponseEquality b
2025bodyEquality = ResponseEquality ((==) `on` responseBody)
src/Servant/QuickCheck/Internal/HasGenRequest.hs+6−5
@@ -5,15 +5,16 @@ import Data.Default.Class (def)
55import Data.Monoid ((<>))
66import Data.String (fromString)
77import Data.String.Conversions (cs)
8−import GHC.TypeLits
8+import GHC.TypeLits (KnownSymbol, Nat, symbolVal)
99import Network.HTTP.Client (Request, RequestBody (..), host,
10− method, path, port, requestBody,
11− requestHeaders, secure, queryString)
10+ method, path, port, queryString,
11+ requestBody, requestHeaders, secure)
1212import Network.HTTP.Media (renderHeader)
13+import Prelude.Compat
1314import Servant
14−import Servant.API.ContentTypes
15+import Servant.API.ContentTypes (AllMimeRender (..))
1516import Servant.Client (BaseUrl (..), Scheme (..))
16−import Test.QuickCheck
17+import Test.QuickCheck (Arbitrary (..), Gen, elements, oneof)
1718
1819
1920class HasGenRequest a where
src/Servant/QuickCheck/Internal/Predicates.hs+9
@@ -3,6 +3,7 @@ module Servant.QuickCheck.Internal.Predicates where
33import Control.Monad (liftM2)
44import Data.Aeson (Object, decode)
55import Data.Bifunctor (Bifunctor (..))
6+import Prelude.Compat
67import qualified Data.ByteString as SBS
78import qualified Data.ByteString.Char8 as SBSC
89import qualified Data.ByteString.Lazy as LBS
@@ -169,6 +170,8 @@ honoursAcceptHeader
169170-- __References__:
170171--
171172-- * @Cache-Control@ header: <https://tools.ietf.org/html/rfc7234#section-5.2 RFC 7234 Section 5.2>
173+--
174+-- #SINCE#
172175getsHaveCacheControlHeader :: RequestPredicate Text Bool
173176getsHaveCacheControlHeader
174177 = RequestPredicate
@@ -184,6 +187,8 @@ getsHaveCacheControlHeader
184187-- | [__Best Practice__]
185188--
186189-- Like 'getsHaveCacheControlHeader', but for @HEAD@ requests.
190+--
191+-- #SINCE#
187192headsHaveCacheControlHeader :: RequestPredicate Text Bool
188193headsHaveCacheControlHeader
189194 = RequestPredicate
@@ -254,6 +259,8 @@ linkHeadersAreValid
254259-- __References__:
255260--
256261-- * @WWW-Authenticate@ header: <https://tools.ietf.org/html/rfc7235#section-4.1 RFC 7235 Section 4.1>
262+--
263+-- #SINCE#
257264unauthorizedContainsWWWAuthenticate :: ResponsePredicate Text Bool
258265unauthorizedContainsWWWAuthenticate
259266 = ResponsePredicate "unauthorizedContainsWWWAuthenticate" (\resp ->
@@ -331,6 +338,8 @@ instance JoinPreds (ResponsePredicate Text Bool) where
331338-- the existing predicates.
332339--
333340-- > not500 <%> onlyJsonObjects <%> empty
341+--
342+-- #SINCE#
334343(<%>) :: JoinPreds a => a -> Predicates [Text] [Text] -> Predicates [Text] [Text]
335344(<%>) = joinPreds
336345infixr 6 <%>
src/Servant/QuickCheck/Internal/QuickCheck.hs+9
@@ -7,6 +7,7 @@ import Network.HTTP.Client (Manager, Request, checkStatus,
77 defaultManagerSettings, httpLbs,
88 newManager)
99import Network.Wai.Handler.Warp (withApplication)
10+import Prelude.Compat
1011import Servant (Context (EmptyContext), HasServer,
1112 Server, serveWithContext)
1213import Servant.Client (BaseUrl (..), Scheme (..))
@@ -23,12 +24,16 @@ import Servant.QuickCheck.Internal.Equality
2324
2425-- | Start a servant application on an open port, run the provided function,
2526-- then stop the application.
27+--
28+-- #SINCE#
2629withServantServer :: HasServer a '[] => Proxy a -> IO (Server a)
2730 -> (BaseUrl -> IO r) -> IO r
2831withServantServer api = withServantServerAndContext api EmptyContext
2932
3033-- | Like 'withServantServer', but allows passing in a 'Context' to the
3134-- application.
35+--
36+-- #SINCE#
3237withServantServerAndContext :: HasServer a ctx
3338 => Proxy a -> Context ctx -> IO (Server a) -> (BaseUrl -> IO r) -> IO r
3439withServantServerAndContext api ctx server t
@@ -46,6 +51,8 @@ withServantServerAndContext api ctx server t
4651--
4752-- Evidently, if the behaviour of the server is expected to be
4853-- non-deterministic, this function may produce spurious failures
54+--
55+-- #SINCE#
4956serversEqual :: HasGenRequest a =>
5057 Proxy a -> BaseUrl -> BaseUrl -> Args -> ResponseEquality LBS.ByteString -> Expectation
5158serversEqual api burl1 burl2 args req = do
@@ -78,6 +85,8 @@ serversEqual api burl1 burl2 args req = do
7885-- > <%> onlyJsonObjects
7986-- > <%> notAllowedContainsAllowHeader
8087-- > <%> mempty)
88+--
89+-- #SINCE#
8190serverSatisfies :: (HasGenRequest a) =>
8291 Proxy a -> BaseUrl -> Args -> Predicates [Text] [Text] -> Expectation
8392serverSatisfies api burl args preds = do