diff --git a/LICENSE.md b/LICENSE.md
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -1,6 +1,6 @@
 [The MIT License (MIT)][]
 
-Copyright (c) 2016 Taylor Fausak
+Copyright (c) 2017 Taylor Fausak
 
 Permission is hereby granted, free of charge, to any person obtaining a copy of
 this software and associated documentation files (the "Software"), to deal in
diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -1,4 +1,4 @@
-import qualified Distribution.Simple
+import qualified Distribution.Simple as Cabal
 
 main :: IO ()
-main = Distribution.Simple.defaultMain
+main = Cabal.defaultMain
diff --git a/lackey.cabal b/lackey.cabal
--- a/lackey.cabal
+++ b/lackey.cabal
@@ -3,7 +3,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           lackey
-version:        0.4.5
+version:        0.4.6
 synopsis:       Generate Ruby clients from Servant APIs.
 description:    Lackey generates Ruby clients from Servant APIs.
 category:       Web
@@ -30,25 +30,25 @@
       library
   ghc-options: -Wall
   build-depends:
-      base >=4.8 && <4.11
-    , servant >=0.8 && <0.12
-    , servant-foreign >=0.8 && <0.11
-    , text >=1.2 && <1.3
+      base >= 4.8 && < 4.11
+    , servant >= 0.8 && < 0.13
+    , servant-foreign >= 0.8 && < 0.11
+    , text >= 1.2 && < 1.3
   exposed-modules:
       Lackey
   default-language: Haskell2010
 
-test-suite lackey-test-suite
+test-suite test
   type: exitcode-stdio-1.0
   main-is: Main.hs
   hs-source-dirs:
-      test-suite
+      tests
   ghc-options: -Wall -rtsopts -threaded -with-rtsopts=-N
   build-depends:
-      base
+      base >= 4.8 && < 4.11
+    , servant >= 0.8 && < 0.13
+    , servant-foreign >= 0.8 && < 0.11
+    , text >= 1.2 && < 1.3
     , lackey
-    , servant
-    , tasty >=0.11 && <0.13
-    , tasty-hspec >=1.1 && <1.2
-    , text
+    , hspec >= 2.4.4 && < 2.5
   default-language: Haskell2010
diff --git a/library/Lackey.hs b/library/Lackey.hs
--- a/library/Lackey.hs
+++ b/library/Lackey.hs
@@ -1,7 +1,9 @@
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE OverloadedStrings #-}
 
-module Lackey (rubyForAPI) where
+module Lackey
+  ( rubyForAPI
+  ) where
 
 import qualified Data.Char as Char
 import Data.Function ((&))
@@ -30,157 +32,161 @@
 
 hasBody :: Servant.Req Request -> Bool
 hasBody request =
-    case Servant._reqBody request of
-        Nothing -> False
-        Just _ -> True
+  case Servant._reqBody request of
+    Nothing -> False
+    Just _ -> True
 
 bodyArgument :: Text.Text
 bodyArgument = "body"
 
 underscore :: Text.Text -> Text.Text
 underscore text =
-    text & Text.toLower &
-    Text.map
-        (\c ->
-              if Char.isAlphaNum c
-                  then c
-                  else '_')
+  text & Text.toLower &
+  Text.map
+    (\c ->
+       if Char.isAlphaNum c
+         then c
+         else '_')
 
 getHeaders :: Servant.Req Request -> [Text.Text]
 getHeaders request =
-    request & Servant._reqHeaders &
-    Maybe.mapMaybe
-        (\h ->
-              case h of
-                  Servant.HeaderArg x -> Just x
-                  Servant.ReplaceHeaderArg _ _ -> Nothing) &
-    map Servant._argName &
-    map Servant.unPathSegment
+  request & Servant._reqHeaders &
+  Maybe.mapMaybe
+    (\h ->
+       case h of
+         Servant.HeaderArg x -> Just x
+         Servant.ReplaceHeaderArg _ _ -> Nothing) &
+  map Servant._argName &
+  map Servant.unPathSegment
 
 getURLPieces :: Servant.Req Request -> [Either Text.Text Text.Text]
 getURLPieces request =
-    let url = request & Servant._reqUrl
-        path =
-            url & Servant._path & map Servant.unSegment &
-            Maybe.mapMaybe
-                (\segment ->
-                      case segment of
-                          Servant.Static _ -> Nothing
-                          Servant.Cap arg -> Just arg) &
-            map Servant._argName &
-            map Servant.unPathSegment
-        query =
-            url & Servant._queryStr & map Servant._queryArgName &
-            map Servant._argName &
-            map Servant.unPathSegment
-    in map Left path ++ map Right query
+  let url = request & Servant._reqUrl
+      path =
+        url & Servant._path & map Servant.unSegment &
+        Maybe.mapMaybe
+          (\segment ->
+             case segment of
+               Servant.Static _ -> Nothing
+               Servant.Cap arg -> Just arg) &
+        map Servant._argName &
+        map Servant.unPathSegment
+      query =
+        url & Servant._queryStr & map Servant._queryArgName &
+        map Servant._argName &
+        map Servant.unPathSegment
+  in map Left path ++ map Right query
 
 functionArguments :: Servant.Req Request -> Text.Text
 functionArguments request =
-    Text.concat
-        [ "("
-        , [ [Just "excon"]
-          , request & getURLPieces &
-            map
-                (\piece ->
-                      case piece of
-                          Left capture -> underscore capture
-                          Right param -> underscore param <> ": nil") &
-            map Just
-          , request & getHeaders & map underscore & map (<> ": nil") & map Just
-          , [ if hasBody request
-                  then Just bodyArgument
-                  else Nothing]] &
-          concat &
-          Maybe.catMaybes &
-          Text.intercalate ","
-        , ")"]
+  Text.concat
+    [ "("
+    , [ [Just "excon"]
+      , request & getURLPieces &
+        map
+          (\piece ->
+             case piece of
+               Left capture -> underscore capture
+               Right param -> underscore param <> ": nil") &
+        map Just
+      , request & getHeaders & map underscore & map (<> ": nil") & map Just
+      , [ if hasBody request
+            then Just bodyArgument
+            else Nothing
+        ]
+      ] &
+      concat &
+      Maybe.catMaybes &
+      Text.intercalate ","
+    , ")"
+    ]
 
 requestMethod :: Servant.Req Request -> Text.Text
 requestMethod request =
-    request & Servant._reqMethod & Text.decodeUtf8 & Text.toLower &
-    Text.cons ':'
+  request & Servant._reqMethod & Text.decodeUtf8 & Text.toLower & Text.cons ':'
 
 requestPath :: Servant.Req Request -> Text.Text
 requestPath request =
-    let path =
-            request & Servant._reqUrl & Servant._path & map Servant.unSegment &
-            map
-                (\x ->
-                      case x of
-                          Servant.Static y -> Servant.unPathSegment y
-                          Servant.Cap y ->
-                              let z =
-                                      y & Servant._argName &
-                                      Servant.unPathSegment &
-                                      underscore
-                              in "#{" <> z <> "}") &
-            Text.intercalate "/"
-        query =
-            request & Servant._reqUrl & Servant._queryStr &
-            map Servant._queryArgName &
-            map Servant._argName &
-            map Servant.unPathSegment &
-            map
-                (\x ->
-                      x <> "=#{" <> underscore x <> "}") &
-            Text.intercalate "&"
-        url =
-            "/" <> path <>
-            (if Text.null query
-                 then ""
-                 else "?" <> query)
-    in "\"" <> url <> "\""
+  let path =
+        request & Servant._reqUrl & Servant._path & map Servant.unSegment &
+        map
+          (\x ->
+             case x of
+               Servant.Static y -> Servant.unPathSegment y
+               Servant.Cap y ->
+                 let z =
+                       y & Servant._argName & Servant.unPathSegment & underscore
+                 in "#{" <> z <> "}") &
+        Text.intercalate "/"
+      query =
+        request & Servant._reqUrl & Servant._queryStr &
+        map Servant._queryArgName &
+        map Servant._argName &
+        map Servant.unPathSegment &
+        map (\x -> x <> "=#{" <> underscore x <> "}") &
+        Text.intercalate "&"
+      url =
+        "/" <> path <>
+        (if Text.null query
+           then ""
+           else "?" <> query)
+  in "\"" <> url <> "\""
 
 requestHeaders :: Servant.Req Request -> Text.Text
 requestHeaders request =
-    [ ["{"]
-    , request & getHeaders &
-      map
-          (\x ->
-                "\"" <> x <> "\"=>" <> underscore x)
-    , ["}"]] &
-    concat &
-    Text.concat
+  [ ["{"]
+  , request & getHeaders & map (\x -> "\"" <> x <> "\"=>" <> underscore x)
+  , ["}"]
+  ] &
+  concat &
+  Text.concat
 
 requestBody :: Servant.Req Request -> Text.Text
 requestBody request =
-    if hasBody request
-        then bodyArgument
-        else "nil"
+  if hasBody request
+    then bodyArgument
+    else "nil"
 
 functionBody :: Servant.Req Request -> Text.Text
 functionBody request =
-    Text.concat
-        [ "excon.request("
-        , ":method=>"
-        , requestMethod request
-        , ","
-        , ":path=>"
-        , requestPath request
-        , ","
-        , ":headers=>"
-        , requestHeaders request
-        , ","
-        , ":body=>"
-        , requestBody request
-        , ")"]
+  Text.concat
+    [ "excon.request("
+    , ":method=>"
+    , requestMethod request
+    , ","
+    , ":path=>"
+    , requestPath request
+    , ","
+    , ":headers=>"
+    , requestHeaders request
+    , ","
+    , ":body=>"
+    , requestBody request
+    , ")"
+    ]
 
 renderRequest :: Servant.Req Request -> Text.Text
 renderRequest request =
-    Text.concat
-        [ "def "
-        , functionName request
-        , functionArguments request
-        , functionBody request
-        , "end"]
+  Text.concat
+    [ "def "
+    , functionName request
+    , functionArguments request
+    , functionBody request
+    , "end"
+    ]
 
-requestsForAPI
-    :: (Servant.HasForeign Language Request api, Servant.GenerateList Request (Servant.Foreign Request api))
-    => Proxy.Proxy api -> [Servant.Req Request]
+requestsForAPI ::
+     ( Servant.HasForeign Language Request api
+     , Servant.GenerateList Request (Servant.Foreign Request api)
+     )
+  => Proxy.Proxy api
+  -> [Servant.Req Request]
 requestsForAPI api = api & Servant.listFromAPI languageProxy requestProxy
 
-rubyForAPI
-    :: (Servant.HasForeign Language Request api, Servant.GenerateList Request (Servant.Foreign Request api))
-    => Proxy.Proxy api -> Text.Text
+rubyForAPI ::
+     ( Servant.HasForeign Language Request api
+     , Servant.GenerateList Request (Servant.Foreign Request api)
+     )
+  => Proxy.Proxy api
+  -> Text.Text
 rubyForAPI api = api & requestsForAPI & renderRequests
diff --git a/package.yaml b/package.yaml
--- a/package.yaml
+++ b/package.yaml
@@ -1,37 +1,38 @@
+name: lackey
+version: 0.4.6
+
 category: Web
 description: Lackey generates Ruby clients from Servant APIs.
 extra-source-files:
-- CHANGELOG.md
-- LICENSE.md
-- package.yaml
-- README.md
-- stack.yaml
-ghc-options: -Wall
+  - CHANGELOG.md
+  - LICENSE.md
+  - package.yaml
+  - README.md
+  - stack.yaml
 github: tfausak/lackey
-library:
-  dependencies:
-  - base >=4.8 && <4.11
-  - servant >=0.8 && <0.12
-  - servant-foreign >=0.8 && <0.11
-  - text >=1.2 && <1.3
-  source-dirs: library
 license: MIT
 maintainer: Taylor Fausak
-name: lackey
 synopsis: Generate Ruby clients from Servant APIs.
+
+dependencies:
+  - base >= 4.8 && < 4.11
+  - servant >= 0.8 && < 0.13
+  - servant-foreign >= 0.8 && < 0.11
+  - text >= 1.2 && < 1.3
+ghc-options:
+  - -Wall
+
+library:
+  source-dirs: library
+
 tests:
-  lackey-test-suite:
+  test:
     dependencies:
-    - base
-    - lackey
-    - servant
-    - tasty >=0.11 && <0.13
-    - tasty-hspec >=1.1 && <1.2
-    - text
+      - lackey
+      - hspec >= 2.4.4 && < 2.5
     ghc-options:
-    - -rtsopts
-    - -threaded
-    - -with-rtsopts=-N
-    source-dirs: test-suite
+      - -rtsopts
+      - -threaded
+      - -with-rtsopts=-N
+    source-dirs: tests
     main: Main.hs
-version: '0.4.5'
diff --git a/stack.yaml b/stack.yaml
--- a/stack.yaml
+++ b/stack.yaml
@@ -1,1 +1,1 @@
-resolver: lts-8.0
+resolver: lts-9.0
diff --git a/test-suite/Main.hs b/test-suite/Main.hs
deleted file mode 100644
--- a/test-suite/Main.hs
+++ /dev/null
@@ -1,141 +0,0 @@
-{-# LANGUAGE DataKinds #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE TypeOperators #-}
-
-import Data.Monoid ((<>))
-import qualified Data.Proxy as Proxy
-import qualified Data.Text as Text
-import qualified Lackey
-import qualified Servant.API as Servant
-import qualified Test.Tasty as Tasty
-import Test.Tasty.Hspec
-
-main :: IO ()
-main = do
-    test <- testSpec "Lackey" spec
-    Tasty.defaultMain test
-
-spec :: Spec
-spec = parallel $ do
-    describe "rubyForAPI" $ do
-        it "supports delete requests" $ do
-            let api = Proxy.Proxy :: Proxy.Proxy (Servant.Delete '[Servant.JSON] ())
-            Lackey.rubyForAPI api `shouldBe`
-                ruby "delete" "" "delete" "" "" False
-
-        it "supports get requests" $ do
-            let api = Proxy.Proxy :: Proxy.Proxy (Servant.Get '[Servant.JSON] ())
-            Lackey.rubyForAPI api `shouldBe`
-                ruby "get" "" "get" "" "" False
-
-        it "supports patch requests" $ do
-            let api = Proxy.Proxy :: Proxy.Proxy (Servant.Patch '[Servant.JSON] ())
-            Lackey.rubyForAPI api `shouldBe`
-                ruby "patch" "" "patch" "" "" False
-
-        it "supports post requests" $ do
-            let api = Proxy.Proxy :: Proxy.Proxy (Servant.Post '[Servant.JSON] ())
-            Lackey.rubyForAPI api `shouldBe`
-                ruby "post" "" "post" "" "" False
-
-        it "supports put requests" $ do
-            let api = Proxy.Proxy :: Proxy.Proxy (Servant.Put '[Servant.JSON] ())
-            Lackey.rubyForAPI api `shouldBe`
-                ruby "put" "" "put" "" "" False
-
-        it "supports alternatives" $ do
-            let api = Proxy.Proxy :: Proxy.Proxy (Servant.Get '[Servant.JSON] () Servant.:<|> Servant.Delete '[Servant.JSON] ())
-            Lackey.rubyForAPI api `shouldBe` Text.concat
-                [ ruby "get" "" "get" "" "" False
-                , ";"
-                , ruby "delete" "" "delete" "" "" False
-                ]
-
-        it "supports captures" $ do
-            let api = Proxy.Proxy :: Proxy.Proxy (Servant.Capture "id" () Servant.:> Servant.Get '[Servant.JSON] ())
-            Lackey.rubyForAPI api `shouldBe`
-                ruby "get_by_id" ",id" "get" "#{id}" "" False
-
-        it "supports query flags" $ do
-            let api = Proxy.Proxy :: Proxy.Proxy (Servant.QueryFlag "flag" Servant.:> Servant.Get '[Servant.JSON] ())
-            Lackey.rubyForAPI api `shouldBe`
-                ruby "get" ",flag: nil" "get" "?flag=#{flag}" "" False
-
-        it "supports query params" $ do
-            let api = Proxy.Proxy :: Proxy.Proxy (Servant.QueryParam "param" () Servant.:> Servant.Get '[Servant.JSON] ())
-            Lackey.rubyForAPI api `shouldBe`
-                ruby "get" ",param: nil" "get" "?param=#{param}" "" False
-
-        it "supports multiple query params" $ do
-            let api = Proxy.Proxy :: Proxy.Proxy (Servant.QueryParams "params" () Servant.:> Servant.Get '[Servant.JSON] ())
-            Lackey.rubyForAPI api `shouldBe`
-                ruby "get" ",params: nil" "get" "?params=#{params}" "" False
-
-        it "supports request bodies" $ do
-            let api = Proxy.Proxy :: Proxy.Proxy (Servant.ReqBody '[Servant.JSON] () Servant.:> Servant.Get '[Servant.JSON] ())
-            Lackey.rubyForAPI api `shouldBe`
-                ruby "get" ",body" "get" "" "" True
-
-        it "supports request headers" $ do
-            let api = Proxy.Proxy :: Proxy.Proxy (Servant.Header "cookie" () Servant.:> Servant.Get '[Servant.JSON] ())
-            Lackey.rubyForAPI api `shouldBe`
-                ruby "get" ",cookie: nil" "get" "" "\"cookie\"=>cookie" False
-
-        it "supports response headers" $ do
-            let api = Proxy.Proxy :: Proxy.Proxy (Servant.Get '[Servant.JSON] (Servant.Headers '[] ()))
-            Lackey.rubyForAPI api `shouldBe`
-                ruby "get" "" "get" "" "" False
-
-        it "puts the body param after captures" $ do
-            let api = Proxy.Proxy :: Proxy.Proxy (Servant.Capture "segment" () Servant.:> Servant.ReqBody '[Servant.JSON] () Servant.:> Servant.Get '[Servant.JSON] ())
-            Lackey.rubyForAPI api `shouldBe`
-                ruby "get_by_segment" ",segment,body" "get" "#{segment}" "" True
-
-        it "puts the body param after query params" $ do
-            let api = Proxy.Proxy :: Proxy.Proxy (Servant.QueryFlag "flag" Servant.:> Servant.ReqBody '[Servant.JSON] () Servant.:> Servant.Get '[Servant.JSON] ())
-            Lackey.rubyForAPI api `shouldBe`
-                ruby "get" ",flag: nil,body" "get" "?flag=#{flag}" "" True
-
-        it "sanitizes path segments" $ do
-            let api = Proxy.Proxy :: Proxy.Proxy ("A!" Servant.:> Servant.Get '[Servant.JSON] ())
-            Lackey.rubyForAPI api `shouldBe`
-                ruby "get_A!" "" "get" "A!" "" False
-
-        it "sanitizes captures" $ do
-            let api = Proxy.Proxy :: Proxy.Proxy (Servant.Capture "A!" () Servant.:> Servant.Get '[Servant.JSON] ())
-            Lackey.rubyForAPI api `shouldBe`
-                ruby "get_by_A!" ",a_" "get" "#{a_}" "" False
-
-        it "sanitizes query flags" $ do
-            let api = Proxy.Proxy :: Proxy.Proxy (Servant.QueryFlag "A!" Servant.:> Servant.Get '[Servant.JSON] ())
-            Lackey.rubyForAPI api `shouldBe`
-                ruby "get" ",a_: nil" "get" "?A!=#{a_}" "" False
-
-        it "sanitizes query params" $ do
-            let api = Proxy.Proxy :: Proxy.Proxy (Servant.QueryParam "A!" () Servant.:> Servant.Get '[Servant.JSON] ())
-            Lackey.rubyForAPI api `shouldBe`
-                ruby "get" ",a_: nil" "get" "?A!=#{a_}" "" False
-
-        it "sanitizes multiple query params" $ do
-            let api = Proxy.Proxy :: Proxy.Proxy (Servant.QueryParams "A!" () Servant.:> Servant.Get '[Servant.JSON] ())
-            Lackey.rubyForAPI api `shouldBe`
-                ruby "get" ",a_: nil" "get" "?A!=#{a_}" "" False
-
-        it "sanitizes headers" $ do
-            let api = Proxy.Proxy :: Proxy.Proxy (Servant.Header "A!" () Servant.:> Servant.Get '[Servant.JSON] ())
-            Lackey.rubyForAPI api `shouldBe`
-                ruby "get" ",a_: nil" "get" "" "\"A!\"=>a_" False
-
--- Since every generated function has the same structure, it can be abstracted
--- away behind this function.
-ruby :: Text.Text -> Text.Text -> Text.Text -> Text.Text -> Text.Text -> Bool -> Text.Text
-ruby name params method path headers body = "\
-    \def " <> name <> "(excon" <> params <> ")\
-      \excon.request(\
-        \:method=>:" <> method <> ",\
-        \:path=>\"/" <> path <> "\",\
-        \:headers=>{" <> headers <> "},\
-        \:body=>" <> (if body then "body" else "nil") <> "\
-      \)\
-    \end\
-\"
diff --git a/tests/Main.hs b/tests/Main.hs
new file mode 100644
--- /dev/null
+++ b/tests/Main.hs
@@ -0,0 +1,133 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE TypeOperators #-}
+
+import Data.Proxy
+import Data.Text
+import Lackey
+import Servant.API
+import Test.Hspec
+
+main :: IO ()
+main = hspec . parallel . describe "Lackey" . describe "rubyForAPI" $ do
+
+  it "supports delete requests" $ do
+    let api = Proxy :: Proxy (Delete '[JSON] ())
+    rubyForAPI api `shouldBe`
+      ruby "delete" "" "delete" "" "" False
+
+  it "supports get requests" $ do
+    let api = Proxy :: Proxy (Get '[JSON] ())
+    rubyForAPI api `shouldBe`
+      ruby "get" "" "get" "" "" False
+
+  it "supports patch requests" $ do
+    let api = Proxy :: Proxy (Patch '[JSON] ())
+    rubyForAPI api `shouldBe`
+      ruby "patch" "" "patch" "" "" False
+
+  it "supports post requests" $ do
+    let api = Proxy :: Proxy (Post '[JSON] ())
+    rubyForAPI api `shouldBe`
+      ruby "post" "" "post" "" "" False
+
+  it "supports put requests" $ do
+    let api = Proxy :: Proxy (Put '[JSON] ())
+    rubyForAPI api `shouldBe`
+      ruby "put" "" "put" "" "" False
+
+  it "supports alternatives" $ do
+    let api = Proxy :: Proxy (Get '[JSON] () :<|> Delete '[JSON] ())
+    rubyForAPI api `shouldBe` mconcat
+      [ ruby "get" "" "get" "" "" False
+      , singleton ';'
+      , ruby "delete" "" "delete" "" "" False
+      ]
+
+  it "supports captures" $ do
+    let api = Proxy :: Proxy (Capture "id" () :> Get '[JSON] ())
+    rubyForAPI api `shouldBe`
+      ruby "get_by_id" ",id" "get" "#{id}" "" False
+
+  it "supports query flags" $ do
+    let api = Proxy :: Proxy (QueryFlag "flag" :> Get '[JSON] ())
+    rubyForAPI api `shouldBe`
+      ruby "get" ",flag: nil" "get" "?flag=#{flag}" "" False
+
+  it "supports query params" $ do
+    let api = Proxy :: Proxy (QueryParam "param" () :> Get '[JSON] ())
+    rubyForAPI api `shouldBe`
+      ruby "get" ",param: nil" "get" "?param=#{param}" "" False
+
+  it "supports multiple query params" $ do
+    let api = Proxy :: Proxy (QueryParams "params" () :> Get '[JSON] ())
+    rubyForAPI api `shouldBe`
+      ruby "get" ",params: nil" "get" "?params=#{params}" "" False
+
+  it "supports request bodies" $ do
+    let api = Proxy :: Proxy (ReqBody '[JSON] () :> Get '[JSON] ())
+    rubyForAPI api `shouldBe`
+      ruby "get" ",body" "get" "" "" True
+
+  it "supports request headers" $ do
+    let api = Proxy :: Proxy (Header "cookie" () :> Get '[JSON] ())
+    rubyForAPI api `shouldBe`
+      ruby "get" ",cookie: nil" "get" "" "\"cookie\"=>cookie" False
+
+  it "supports response headers" $ do
+    let api = Proxy :: Proxy (Get '[JSON] (Headers '[] ()))
+    rubyForAPI api `shouldBe`
+      ruby "get" "" "get" "" "" False
+
+  it "puts the body param after captures" $ do
+    let api = Proxy :: Proxy (Capture "segment" () :> ReqBody '[JSON] () :> Get '[JSON] ())
+    rubyForAPI api `shouldBe`
+      ruby "get_by_segment" ",segment,body" "get" "#{segment}" "" True
+
+  it "puts the body param after query params" $ do
+    let api = Proxy :: Proxy (QueryFlag "flag" :> ReqBody '[JSON] () :> Get '[JSON] ())
+    rubyForAPI api `shouldBe`
+      ruby "get" ",flag: nil,body" "get" "?flag=#{flag}" "" True
+
+  it "sanitizes path segments" $ do
+    let api = Proxy :: Proxy ("A!" :> Get '[JSON] ())
+    rubyForAPI api `shouldBe`
+      ruby "get_A!" "" "get" "A!" "" False
+
+  it "sanitizes captures" $ do
+    let api = Proxy :: Proxy (Capture "A!" () :> Get '[JSON] ())
+    rubyForAPI api `shouldBe`
+      ruby "get_by_A!" ",a_" "get" "#{a_}" "" False
+
+  it "sanitizes query flags" $ do
+    let api = Proxy :: Proxy (QueryFlag "A!" :> Get '[JSON] ())
+    rubyForAPI api `shouldBe`
+      ruby "get" ",a_: nil" "get" "?A!=#{a_}" "" False
+
+  it "sanitizes query params" $ do
+    let api = Proxy :: Proxy (QueryParam "A!" () :> Get '[JSON] ())
+    rubyForAPI api `shouldBe`
+      ruby "get" ",a_: nil" "get" "?A!=#{a_}" "" False
+
+  it "sanitizes multiple query params" $ do
+    let api = Proxy :: Proxy (QueryParams "A!" () :> Get '[JSON] ())
+    rubyForAPI api `shouldBe`
+      ruby "get" ",a_: nil" "get" "?A!=#{a_}" "" False
+
+  it "sanitizes headers" $ do
+    let api = Proxy :: Proxy (Header "A!" () :> Get '[JSON] ())
+    rubyForAPI api `shouldBe`
+      ruby "get" ",a_: nil" "get" "" "\"A!\"=>a_" False
+
+-- Since every generated function has the same structure, it can be abstracted
+-- away behind this function.
+ruby :: String -> String -> String -> String -> String -> Bool -> Text
+ruby name params method path headers body = pack (mconcat
+  [ "def ", name, "(excon", params, ")"
+  , "excon.request("
+  , ":method=>:", method, ","
+  , ":path=>\"/", path, "\","
+  , ":headers=>{", headers, "},"
+  , ":body=>", if body then "body" else "nil"
+  , ")"
+  , "end"
+  ])
