1717
1818module Servant.ServerSpec where
1919
20- import Control.Monad (forM_ , when , unless )
21- import Control.Monad.Error.Class (MonadError (.. ))
22- import Data.Aeson (FromJSON , ToJSON , decode' , encode )
23- import qualified Data.ByteString.Base64 as Base64
24- import Data.Char (toUpper )
20+ import Control.Monad
21+ (forM_ , unless , when )
22+ import Control.Monad.Error.Class
23+ (MonadError (.. ))
24+ import Data.Aeson
25+ (FromJSON , ToJSON , decode' , encode )
26+ import qualified Data.ByteString as BS
27+ import qualified Data.ByteString.Base64 as Base64
28+ import Data.Char
29+ (toUpper )
2530import Data.Monoid
26- import Data.Proxy ( Proxy ( Proxy ))
27- import Data.String ( fromString )
28- import Data.String.Conversions ( cs )
29- import qualified Data.Text as T
30- import GHC.Generics ( Generic )
31- import Network.HTTP.Types ( Status ( .. ), hAccept , hContentType ,
32- methodDelete , methodGet ,
33- methodHead , methodPatch ,
34- methodPost , methodPut , ok200 ,
35- imATeapot418 ,
36- parseQuery )
37- import Network.Wai ( Application , Request , requestHeaders , pathInfo ,
38- queryString , rawQueryString ,
39- responseLBS )
40- import Network.Wai.Test ( defaultRequest , request ,
41- runSession , simpleBody ,
42- simpleHeaders , simpleStatus )
43- import Servant.API ( (:<|>) ( .. ), (:>) , AuthProtect ,
44- BasicAuth , BasicAuthData ( BasicAuthData ),
45- Capture , CaptureAll , Delete , Get , Header ,
46- Headers , HttpVersion ,
47- IsSecure ( .. ), JSON ,
48- NoContent (.. ), Patch , PlainText ,
49- Post , Put , EmptyAPI ,
50- QueryFlag , QueryParam , QueryParams ,
51- Raw , RemoteHost , ReqBody ,
52- StdMethod (.. ), Verb , addHeader )
31+ import Data.Proxy
32+ ( Proxy ( Proxy ) )
33+ import Data.String
34+ ( fromString )
35+ import Data.String.Conversions
36+ ( cs )
37+ import qualified Data.Text as T
38+ import GHC.Generics
39+ ( Generic )
40+ import Network.HTTP.Types
41+ ( Status ( .. ), hAccept , hContentType , imATeapot418 ,
42+ methodDelete , methodGet , methodHead , methodPatch , methodPost ,
43+ methodPut , ok200 , parseQuery )
44+ import Network.Wai
45+ ( Application , Request , pathInfo , queryString , rawQueryString ,
46+ requestHeaders , responseLBS )
47+ import Network.Wai.Test
48+ ( defaultRequest , request , runSession , simpleBody ,
49+ simpleHeaders , simpleStatus )
50+ import Servant.API
51+ ( (:<|>) ( .. ), (:>) , AuthProtect , BasicAuth ,
52+ BasicAuthData ( BasicAuthData ), Capture , CaptureAll , Delete ,
53+ EmptyAPI , Get , Header , Headers , HttpVersion , IsSecure (.. ),
54+ JSON , NoContent ( .. ), NoFraming , OctetStream , Patch ,
55+ PlainText , Post , Put , QueryFlag , QueryParam , QueryParams , Raw ,
56+ RemoteHost , ReqBody , StdMethod ( .. ), Stream ,
57+ StreamGenerator (.. ), Verb , addHeader )
5358import Servant.API.Internal.Test.ComprehensiveAPI
54- import Servant.Server (Server , Handler , Tagged (.. ), err401 , err403 ,
55- err404 , serve , serveWithContext ,
56- Context ((:.) , EmptyContext ), emptyServer )
57- import Test.Hspec (Spec , context , describe , it ,
58- shouldBe , shouldContain )
59- import qualified Test.Hspec.Wai as THW
60- import Test.Hspec.Wai (get , liftIO , matchHeaders ,
61- matchStatus , shouldRespondWith ,
62- with , (<:>) )
63-
64- import Servant.Server.Internal.BasicAuth (BasicAuthCheck (BasicAuthCheck ),
65- BasicAuthResult (Authorized ,Unauthorized ))
59+ import Servant.Server
60+ (Context ((:.) , EmptyContext ), Handler , Server , Tagged (.. ),
61+ emptyServer , err401 , err403 , err404 , serve , serveWithContext )
62+ import Test.Hspec
63+ (Spec , context , describe , it , shouldBe , shouldContain )
64+ import Test.Hspec.Wai
65+ (get , liftIO , matchHeaders , matchStatus , shouldRespondWith ,
66+ with , (<:>) )
67+ import qualified Test.Hspec.Wai as THW
68+
6669import Servant.Server.Experimental.Auth
67- (AuthHandler , AuthServerData ,
68- mkAuthHandler )
70+ (AuthHandler , AuthServerData , mkAuthHandler )
71+ import Servant.Server.Internal.BasicAuth
72+ (BasicAuthCheck (BasicAuthCheck ),
73+ BasicAuthResult (Authorized , Unauthorized ))
6974import Servant.Server.Internal.Context
70- (NamedContext (.. ))
75+ (NamedContext (.. ))
7176
7277-- * comprehensive api test
7378
@@ -105,6 +110,7 @@ type VerbApi method status
105110 :<|> " accept" :> ( Verb method status '[JSON ] Person
106111 :<|> Verb method status '[PlainText ] String
107112 )
113+ :<|> " stream" :> Stream method status NoFraming OctetStream (StreamGenerator BS. ByteString )
108114
109115verbSpec :: Spec
110116verbSpec = describe " Servant.API.Verb" $ do
@@ -114,6 +120,8 @@ verbSpec = describe "Servant.API.Verb" $ do
114120 :<|> return (addHeader 5 alice)
115121 :<|> return (addHeader 10 NoContent )
116122 :<|> (return alice :<|> return " B" )
123+ :<|> return (StreamGenerator $ \ f _ -> f " bytestring" )
124+
117125 get200 = Proxy :: Proxy (VerbApi 'GET 200 )
118126 post210 = Proxy :: Proxy (VerbApi 'POST 210 )
119127 put203 = Proxy :: Proxy (VerbApi 'PUT 203 )
@@ -179,6 +187,11 @@ verbSpec = describe "Servant.API.Verb" $ do
179187 liftIO $ simpleHeaders response `shouldContain`
180188 [(" Content-Type" , " application/json;charset=utf-8" )]
181189
190+ it " works for Stream as for Result" $ do
191+ response <- THW. request method " /stream" [] " "
192+ liftIO $ statusCode (simpleStatus response) `shouldBe` status
193+ liftIO $ simpleBody response `shouldBe` " bytestring"
194+
182195 test " GET 200" get200 methodGet 200
183196 test " POST 210" post210 methodPost 210
184197 test " PUT 203" put203 methodPut 203
0 commit comments