@@ -1,17 +1,110 @@
1{-# LANGUAGE OverloadedStrings #-}
1{-# LANGUAGE OverloadedStrings #-}
2+{-# LANGUAGE TypeOperators #-}
3+{-# LANGUAGE DataKinds #-}
4+{-# LANGUAGE MultiParamTypeClasses #-}
5+{-# LANGUAGE FlexibleContexts #-}
6+{-# LANGUAGE FlexibleInstances #-}
7+{-# LANGUAGE TypeSynonymInstances #-}
8+{-# LANGUAGE ScopedTypeVariables #-}
3module Servant.ForeignSpec where
10module Servant.ForeignSpec where
12+import Data.Monoid ((<>))
5−import Servant.Foreign (camelCase)
14+import Servant.Foreign
15+import Servant.Foreign.Internal
7import Test.Hspec
17import Test.Hspec
9spec :: Spec
19spec :: Spec
10spec = describe "Servant.Foreign" $ do
20spec = describe "Servant.Foreign" $ do
11 camelCaseSpec
21 camelCaseSpec
13camelCaseSpec :: Spec
24camelCaseSpec :: Spec
14camelCaseSpec = describe "camelCase" $ do
25camelCaseSpec = describe "camelCase" $ do
15 it "converts FunctionNames to camelCase" $ do
26 it "converts FunctionNames to camelCase" $ do
16 camelCase ["post", "counter", "inc"] `shouldBe` "postCounterInc"
27 camelCase ["post", "counter", "inc"] `shouldBe` "postCounterInc"
17 camelCase ["get", "hyphen-ated", "counter"] `shouldBe` "getHyphenatedCounter"
28 camelCase ["get", "hyphen-ated", "counter"] `shouldBe` "getHyphenatedCounter"
30+----------------------------------------------------------------------
34+instance HasForeignType LangX () where
35+ typeFor _ _ = "voidX"
36+instance HasForeignType LangX Int where
38+instance HasForeignType LangX Bool where
39+ typeFor _ _ = "boolX"
40+instance {-# Overlapping #-} HasForeignType LangX String where
41+ typeFor _ _ = "stringX"
42+instance {-# Overlapable #-} HasForeignType LangX a => HasForeignType LangX [a] where
43+ typeFor lang _ = "listX of " <> typeFor lang (Proxy :: Proxy a)
46+ = "test" :> Header "header" [String] :> QueryFlag "flag" :> Get '[JSON] Int
47+ :<|> "test" :> QueryParam "param" Int :> ReqBody '[JSON] [String] :> Post '[JSON] ()
48+ :<|> "test" :> QueryParams "params" Int :> ReqBody '[JSON] String :> Put '[JSON] ()
49+ :<|> "test" :> Capture "id" Int :> Delete '[JSON] ()
52+testApi = listFromAPI (Proxy :: Proxy LangX) (Proxy :: Proxy TestApi)
54+listFromAPISpec :: Spec
55+listFromAPISpec = describe "listFromAPI" $ do
56+ it "generates 4 endpoints for TestApi" $ do
57+ length testApi `shouldBe` 4
59+ let [getReq, postReq, putReq, deleteReq] = testApi
61+ it "collects all info for get request" $ do
62+ shouldBe getReq $ defReq
64+ [ Segment $ Static "test" ]
65+ [ QueryArg ("flag", "boolX") Flag ]
67+ , _reqHeaders = [HeaderArg ("header", "listX of stringX")]
69+ , _reqReturnType = "intX"
70+ , _funcName = ["get", "test"]
73+ it "collects all info for post request" $ do
74+ shouldBe postReq $ defReq
76+ [ Segment $ Static "test" ]
77+ [ QueryArg ("param", "intX") Normal ]
78+ , _reqMethod = "POST"
80+ , _reqBody = Just "listX of stringX"
81+ , _reqReturnType = "voidX"
82+ , _funcName = ["post", "test"]
85+ it "collects all info for put request" $ do
86+ shouldBe putReq $ defReq
88+ [ Segment $ Static "test" ]
89+ -- Shoud this be |intX| or |listX of intX| ?
90+ [ QueryArg ("params", "listX of intX") List ]
93+ , _reqBody = Just "stringX"
94+ , _reqReturnType = "voidX"
95+ , _funcName = ["put", "test"]
98+ it "collects all info for delete request" $ do
99+ shouldBe deleteReq $ defReq
101+ [ Segment $ Static "test"
102+ , Segment $ Cap ("id", "intX") ]
104+ , _reqMethod = "DELETE"
106+ , _reqBody = Nothing
107+ , _reqReturnType = "voidX"
108+ , _funcName = ["delete", "test", "by", "id"]