Add tests for Servant.Client.Generic
This commit is contained in:
parent
31e1ceb6d0
commit
3cc667892c
2 changed files with 67 additions and 0 deletions
|
@ -98,3 +98,4 @@ test-suite spec
|
||||||
, transformers-compat
|
, transformers-compat
|
||||||
, wai
|
, wai
|
||||||
, warp
|
, warp
|
||||||
|
, generics-sop
|
||||||
|
|
|
@ -36,6 +36,7 @@ import Data.Char (chr, isPrint)
|
||||||
import Data.Foldable (forM_)
|
import Data.Foldable (forM_)
|
||||||
import Data.Monoid hiding (getLast)
|
import Data.Monoid hiding (getLast)
|
||||||
import Data.Proxy
|
import Data.Proxy
|
||||||
|
import qualified Generics.SOP as SOP
|
||||||
import GHC.Generics (Generic)
|
import GHC.Generics (Generic)
|
||||||
import qualified Network.HTTP.Client as C
|
import qualified Network.HTTP.Client as C
|
||||||
import Network.HTTP.Media
|
import Network.HTTP.Media
|
||||||
|
@ -55,6 +56,7 @@ import Web.FormUrlEncoded (FromForm, ToForm)
|
||||||
import Servant.API
|
import Servant.API
|
||||||
import Servant.API.Internal.Test.ComprehensiveAPI
|
import Servant.API.Internal.Test.ComprehensiveAPI
|
||||||
import Servant.Client
|
import Servant.Client
|
||||||
|
import Servant.Client.Generic
|
||||||
import qualified Servant.Common.Req as SCR
|
import qualified Servant.Common.Req as SCR
|
||||||
import Servant.Server
|
import Servant.Server
|
||||||
import Servant.Server.Experimental.Auth
|
import Servant.Server.Experimental.Auth
|
||||||
|
@ -69,6 +71,7 @@ spec = describe "Servant.Client" $ do
|
||||||
wrappedApiSpec
|
wrappedApiSpec
|
||||||
basicAuthSpec
|
basicAuthSpec
|
||||||
genAuthSpec
|
genAuthSpec
|
||||||
|
genericClientSpec
|
||||||
|
|
||||||
-- * test data types
|
-- * test data types
|
||||||
|
|
||||||
|
@ -222,6 +225,53 @@ genAuthServerContext = genAuthHandler :. EmptyContext
|
||||||
genAuthServer :: Application
|
genAuthServer :: Application
|
||||||
genAuthServer = serveWithContext genAuthAPI genAuthServerContext (const (return alice))
|
genAuthServer = serveWithContext genAuthAPI genAuthServerContext (const (return alice))
|
||||||
|
|
||||||
|
-- * generic client stuff
|
||||||
|
|
||||||
|
type GenericClientAPI
|
||||||
|
= QueryParam "sqr" Int :> Get '[JSON] Int
|
||||||
|
:<|> Capture "foo" String :> NestedAPI1
|
||||||
|
|
||||||
|
data GenericClient = GenericClient
|
||||||
|
{ getSqr :: Maybe Int -> SCR.ClientM Int
|
||||||
|
, mkNestedClient1 :: String -> NestedClient1
|
||||||
|
} deriving Generic
|
||||||
|
instance SOP.Generic GenericClient
|
||||||
|
instance (Client GenericClientAPI ~ client) => ClientLike client GenericClient
|
||||||
|
|
||||||
|
type NestedAPI1
|
||||||
|
= QueryParam "int" Int :> NestedAPI2
|
||||||
|
:<|> QueryParam "id" Char :> Get '[JSON] Char
|
||||||
|
|
||||||
|
data NestedClient1 = NestedClient1
|
||||||
|
{ mkNestedClient2 :: Maybe Int -> NestedClient2
|
||||||
|
, idChar :: Maybe Char -> SCR.ClientM Char
|
||||||
|
} deriving Generic
|
||||||
|
instance SOP.Generic NestedClient1
|
||||||
|
instance (Client NestedAPI1 ~ client) => ClientLike client NestedClient1
|
||||||
|
|
||||||
|
type NestedAPI2
|
||||||
|
= "sum" :> Capture "first" Int :> Capture "second" Int :> Get '[JSON] Int
|
||||||
|
:<|> "void" :> Post '[JSON] ()
|
||||||
|
|
||||||
|
data NestedClient2 = NestedClient2
|
||||||
|
{ getSum :: Int -> Int -> SCR.ClientM Int
|
||||||
|
, doNothing :: SCR.ClientM ()
|
||||||
|
} deriving Generic
|
||||||
|
instance SOP.Generic NestedClient2
|
||||||
|
instance (Client NestedAPI2 ~ client) => ClientLike client NestedClient2
|
||||||
|
|
||||||
|
genericClientServer :: Application
|
||||||
|
genericClientServer = serve (Proxy :: Proxy GenericClientAPI) (
|
||||||
|
(\ mx -> case mx of
|
||||||
|
Just x -> return (x*x)
|
||||||
|
Nothing -> throwE $ ServantErr 400 "missing parameter" "" []
|
||||||
|
)
|
||||||
|
:<|> nestedServer1
|
||||||
|
)
|
||||||
|
where
|
||||||
|
nestedServer1 _str = nestedServer2 :<|> (maybe (throwE $ ServantErr 400 "missing parameter" "" []) return)
|
||||||
|
nestedServer2 _int = (\ x y -> return (x + y)) :<|> return ()
|
||||||
|
|
||||||
{-# NOINLINE manager #-}
|
{-# NOINLINE manager #-}
|
||||||
manager :: C.Manager
|
manager :: C.Manager
|
||||||
manager = unsafePerformIO $ C.newManager C.defaultManagerSettings
|
manager = unsafePerformIO $ C.newManager C.defaultManagerSettings
|
||||||
|
@ -392,6 +442,22 @@ genAuthSpec = beforeAll (startWaiApp genAuthServer) $ afterAll endWaiApp $ do
|
||||||
Left FailureResponse{..} <- runClientM (getProtected authRequest) (ClientEnv manager baseUrl)
|
Left FailureResponse{..} <- runClientM (getProtected authRequest) (ClientEnv manager baseUrl)
|
||||||
responseStatus `shouldBe` (HTTP.Status 401 "Unauthorized")
|
responseStatus `shouldBe` (HTTP.Status 401 "Unauthorized")
|
||||||
|
|
||||||
|
genericClientSpec :: Spec
|
||||||
|
genericClientSpec = beforeAll (startWaiApp genericClientServer) $ afterAll endWaiApp $ do
|
||||||
|
describe "Servant.Client.Generic" $ do
|
||||||
|
|
||||||
|
let GenericClient{..} = mkClient (client (Proxy :: Proxy GenericClientAPI))
|
||||||
|
NestedClient1{..} = mkNestedClient1 "example"
|
||||||
|
NestedClient2{..} = mkNestedClient2 (Just 42)
|
||||||
|
|
||||||
|
it "works for top-level client function" $ \(_, baseUrl) -> do
|
||||||
|
(left show <$> (runClientM (getSqr (Just 5)) (ClientEnv manager baseUrl))) `shouldReturn` Right 25
|
||||||
|
|
||||||
|
it "works for nested clients" $ \(_, baseUrl) -> do
|
||||||
|
(left show <$> (runClientM (idChar (Just 'c')) (ClientEnv manager baseUrl))) `shouldReturn` Right 'c'
|
||||||
|
(left show <$> (runClientM (getSum 3 4) (ClientEnv manager baseUrl))) `shouldReturn` Right 7
|
||||||
|
(left show <$> (runClientM doNothing (ClientEnv manager baseUrl))) `shouldReturn` Right ()
|
||||||
|
|
||||||
-- * utils
|
-- * utils
|
||||||
|
|
||||||
startWaiApp :: Application -> IO (ThreadId, BaseUrl)
|
startWaiApp :: Application -> IO (ThreadId, BaseUrl)
|
||||||
|
|
Loading…
Add table
Reference in a new issue