servant-docs 0.11.4 → 0.11.5
raw patch · 5 files changed
+107/−22 lines, 5 filesdep ~servant
Dependency ranges changed: servant
Files
- CHANGELOG.md +40/−0
- golden/comprehensive.md +23/−10
- servant-docs.cabal +3/−3
- src/Servant/Docs/Internal.hs +26/−5
- test/Servant/DocsSpec.hs +15/−4
CHANGELOG.md view
@@ -1,6 +1,46 @@ [The latest version of this document is on GitHub.](https://github.com/haskell-servant/servant/blob/master/servant-docs/CHANGELOG.md) [Changelog for `servant` package contains significant entries for all core packages.](https://github.com/haskell-servant/servant/blob/master/servant/CHANGELOG.md) +0.11.5+----+++- Add NoContentVerb [#1028](https://github.com/haskell-servant/servant/issues/1028) [#1219](https://github.com/haskell-servant/servant/pull/1219) [#1228](https://github.com/haskell-servant/servant/pull/1228)++ The `NoContent` API endpoints should now use `NoContentVerb` combinator.+ The API type changes are usually of the kind++ ```diff+ - :<|> PostNoContent '[JSON] NoContent+ + :<|> PostNoContent+ ```++ i.e. one doesn't need to specify the content-type anymore. There is no content.++- `Capture` can be `Lenient` [#1155](https://github.com/haskell-servant/servant/issues/1155) [#1156](https://github.com/haskell-servant/servant/pull/1156)++ You can specify a lenient capture as++ ```haskell+ :<|> "capture-lenient" :> Capture' '[Lenient] "foo" Int :> GET+ ```++ which will make the capture always succeed. Handlers will be of the+ type `Either String CapturedType`, where `Left err` represents+ the possible parse failure.++- *servant-docs* Merge documentation from duplicate routes [#1240](https://github.com/haskell-servant/servant/issues/1240) [#1241](https://github.com/haskell-servant/servant/pull/1241)++ Servant supports defining the same route multiple times with different+ content-types and result-types, but servant-docs was only documenting+ the first of copy of such duplicated routes. It now combines the+ documentation from all the copies.++ Unfortunately, it is not yet possible for the documentation to specify+ multiple status codes.++- *servant-docs* Prevent race-conditions in testing [#1194](https://github.com/haskell-servant/servant/pull/1194)+ 0.11.4 ------
golden/comprehensive.md view
@@ -96,6 +96,28 @@ ``` +## GET /capture-lenient/:foo++### Captures:++- *foo*: Capture foo Int++### Response:++- Status code 200+- Headers: []++- Supported content types are:++ - `application/json;charset=utf-8`+ - `application/json`++- Example (`application/json;charset=utf-8`, `application/json`):++```javascript++```+ ## GET /description ### foo@@ -377,16 +399,7 @@ - Status code 204 - Headers: [] -- Supported content types are:-- - `application/json;charset=utf-8`- - `application/json`--- Example (`application/json;charset=utf-8`, `application/json`):--```javascript--```+- No response body ## GET /raw
servant-docs.cabal view
@@ -1,6 +1,6 @@ cabal-version: >=1.10 name: servant-docs-version: 0.11.4+version: 0.11.5 synopsis: generate API docs for your servant webservice category: Servant, Web@@ -24,7 +24,7 @@ || ==8.2.2 || ==8.4.4 || ==8.6.5- || ==8.8.1+ || ==8.8.2 extra-source-files: CHANGELOG.md@@ -52,7 +52,7 @@ -- Servant dependencies build-depends:- servant >= 0.15 && <0.17+ servant >= 0.17 && <0.18 -- Other dependencies: Lower bound around what is in the latest Stackage LTS. -- Here can be exceptions if we really need features from the newer versions.
src/Servant/Docs/Internal.hs view
@@ -131,7 +131,8 @@ (<>) = mappend instance Monoid API where- API a1 b1 `mappend` API a2 b2 = API (a1 `mappend` a2) (b1 `mappend` b2)+ API a1 b1 `mappend` API a2 b2 = API (a1 `mappend` a2)+ (HM.unionWith combineAction b1 b2) mempty = API mempty mempty -- | An empty 'API'@@ -240,6 +241,15 @@ , _respHeaders :: [HTTP.Header] } deriving (Eq, Ord, Show) +-- | Combine two Responses, we can't make a monoid because merging Status breaks+-- the laws.+--+-- As such, we invent a non-commutative, left associative operation+-- 'combineResponse' to mush two together taking the status from the very left.+combineResponse :: Response -> Response -> Response+Response s ts bs hs `combineResponse` Response _ ts' bs' hs'+ = Response s (ts <> ts') (bs <> bs') (hs <> hs')+ -- | Default response: status code 200, no response body. -- -- Can be tweaked with four lenses.@@ -284,11 +294,10 @@ -- laws. -- -- As such, we invent a non-commutative, left associative operation--- 'combineAction' to mush two together taking the response, body and content--- types from the very left.+-- 'combineAction' to mush two together taking the response from the very left. combineAction :: Action -> Action -> Action-Action a c h p n m ts body resp `combineAction` Action a' c' h' p' n' m' _ _ _ =- Action (a <> a') (c <> c') (h <> h') (p <> p') (n <> n') (m <> m') ts body resp+Action a c h p n m ts body resp `combineAction` Action a' c' h' p' n' m' ts' body' resp' =+ Action (a <> a') (c <> c') (h <> h') (p <> p') (n <> n') (m <> m') (ts <> ts') (body <> body') (resp `combineResponse` resp') -- | Default 'Action'. Has no 'captures', no query 'params', expects -- no request body ('rqbody') and the typical response is 'defResponse'.@@ -861,6 +870,18 @@ method' = reflectMethod (Proxy :: Proxy method) status = fromInteger $ natVal (Proxy :: Proxy status) p = Proxy :: Proxy a++instance (ReflectMethod method) =>+ HasDocs (NoContentVerb method) where+ docsFor Proxy (endpoint, action) DocOptions{..} =+ single endpoint' action'++ where endpoint' = endpoint & method .~ method'+ action' = action & response.respStatus .~ 204+ & response.respTypes .~ []+ & response.respBody .~ []+ & response.respHeaders .~ []+ method' = reflectMethod (Proxy :: Proxy method) -- | TODO: mention the endpoint is streaming, its framing strategy --
test/Servant/DocsSpec.hs view
@@ -66,8 +66,10 @@ golden "comprehensive API" "golden/comprehensive.md" (markdown comprehensiveDocs) describe "markdown" $ do- let md = markdown (docs (Proxy :: Proxy TestApi1))- tests md+ let md1 = markdown (docs (Proxy :: Proxy TestApi1))+ tests1 md1+ let md2 = markdown (docs (Proxy :: Proxy TestApi2))+ tests2 md2 describe "markdown with extra info" $ do let@@ -79,7 +81,7 @@ (Proxy :: Proxy (ReqBody '[JSON] String :> Post '[JSON] Datatype1)) (defAction & notes <>~ [DocNote "Post data" ["Posts some Json data"]]) md = markdown (docsWith defaultDocOptions [] extra (Proxy :: Proxy TestApi1))- tests md+ tests1 md it "contains the extra info provided" $ do md `shouldContain` "Get an Integer" md `shouldContain` "Post data"@@ -107,7 +109,7 @@ where- tests md = do+ tests1 md = do it "mentions supported content-types" $ do md `shouldContain` "application/json" md `shouldContain` "text/plain;charset=utf-8"@@ -130,7 +132,12 @@ it "does not generate any docs mentioning the 'empty-api' path" $ md `shouldNotContain` "empty-api" + tests2 md = do+ it "mentions the content-types from both copies of the route" $ do+ md `shouldContain` "application/json"+ md `shouldContain` "text/plain;charset=utf-8" + -- * APIs data Datatype1 = Datatype1 { dt1field1 :: String@@ -155,6 +162,10 @@ :<|> ReqBody '[JSON] String :> Post '[JSON] Datatype1 :<|> Header "X-Test" Int :> Put '[JSON] Int :<|> "empty-api" :> EmptyAPI++type TestApi2 = "duplicate-endpoint" :> Get '[JSON] Datatype1+ :<|> "duplicate-endpoint" :> Get '[PlainText] Int+ data TT = TT1 | TT2 deriving (Show, Eq) data UT = UT1 | UT2 deriving (Show, Eq)