Skip to content

Commit ea96794

Browse files
committed
Add tests for a more complete server with capture all branches.
* This fails two of the tests. We should probably add a catch all at the end that captures anything not matches by the Symbols for the preceding branches `arms` and `legs`. * When using `CaptureAll` from the root "/" and empty path becomes an empty list. when using it from a branch though an empty path, ie. a trailing separator, becomes `mempty` for the type. Where is this happening? I think this is definitely happening before `parseUrlpieces` gets run, so it happens in the machinery for Delayed and DelayedIO. I am still looking for the code that produces the `txts` argument for the `captureD` lambda created in the `HasServer` instance for `CaptureAll`.
1 parent 7a770b5 commit ea96794

File tree

1 file changed

+27
-14
lines changed

1 file changed

+27
-14
lines changed

servant-server/test/Servant/ServerSpec.hs

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -268,45 +268,58 @@ captureSpec = do
268268
-- * captureAllSpec {{{
269269
------------------------------------------------------------------------------
270270

271-
type CaptureAllApi = CaptureAll "legs" Integer :> Get '[JSON] Animal
271+
type CaptureAllApi = "legs" :> CaptureAll "legs" Integer :> Get '[JSON] Animal
272+
:<|> "arms" :> CaptureAll "arms" String :> Get '[JSON] [String]
272273
captureAllApi :: Proxy CaptureAllApi
273274
captureAllApi = Proxy
274-
captureAllServer :: [Integer] -> Handler Animal
275-
captureAllServer legs = case sum legs of
276-
4 -> return jerry
277-
2 -> return tweety
278-
0 -> return beholder
279-
_ -> throwError err404
275+
captureAllServer :: Server CaptureAllApi
276+
captureAllServer = handleLegs :<|> (return :: [String] -> Handler [String])
277+
where
278+
handleLegs [] = return beholder
279+
handleLegs legs = case sum legs of
280+
4 -> return jerry
281+
2 -> return tweety
282+
_ -> throwError err404
280283

281284
captureAllSpec :: Spec
282285
captureAllSpec = do
283286
describe "Servant.API.CaptureAll" $ do
284287
with (return (serve captureAllApi captureAllServer)) $ do
285288

286289
it "can capture a single element of the 'pathInfo'" $ do
287-
response <- get "/2"
290+
response <- get "/legs/2"
288291
liftIO $ decode' (simpleBody response) `shouldBe` Just tweety
289292

290293
it "can capture multiple elements of the 'pathInfo'" $ do
291-
response <- get "/2/2"
294+
response <- get "/legs/2/2"
292295
liftIO $ decode' (simpleBody response) `shouldBe` Just jerry
293296

294297
it "can capture arbitrarily many elements of the 'pathInfo'" $ do
295-
response <- get "/1/1/0/1/0/1"
298+
response <- get "/legs/1/1/0/1/0/1"
296299
liftIO $ decode' (simpleBody response) `shouldBe` Just jerry
297300

298301
it "can capture when there are no elements in 'pathInfo'" $ do
299-
response <- get "/"
302+
response <- get "/legs/"
300303
liftIO $ decode' (simpleBody response) `shouldBe` Just beholder
301304

302305
it "returns 400 if the decoding fails" $ do
303-
get "/notAnInt" `shouldRespondWith` 400
306+
get "/legs/notAnInt" `shouldRespondWith` 400
304307

305308
it "returns 400 if the decoding fails, regardless of which element" $ do
306-
get "/1/0/0/notAnInt/3/" `shouldRespondWith` 400
309+
get "/legs/1/0/0/notAnInt/3/" `shouldRespondWith` 400
307310

308311
it "returns 400 if the decoding fails, even when it's multiple elements" $ do
309-
get "/1/0/0/notAnInt/3/orange/" `shouldRespondWith` 400
312+
get "/legs/1/0/0/notAnInt/3/orange/" `shouldRespondWith` 400
313+
314+
let getStringList = decode' @[String] . simpleBody
315+
316+
it "can capture single String" $ do
317+
response <- get "/arms/jerry"
318+
liftIO $ getStringList response `shouldBe` Just ["jerry"]
319+
320+
it "can capture when there are no elements in 'pathinfo'" $ do
321+
response <- get "/arms/"
322+
liftIO $ getStringList response `shouldBe` Just []
310323

311324
with (return (serve
312325
(Proxy :: Proxy (CaptureAll "segments" String :> Raw))

0 commit comments

Comments
 (0)