diff --git a/servant-ruby.cabal b/servant-ruby.cabal index 83f58d6..781b9c4 100644 --- a/servant-ruby.cabal +++ b/servant-ruby.cabal @@ -27,12 +27,26 @@ library test-suite doc-test type: exitcode-stdio-1.0 main-is: Main.hs - hs-source-dirs: test + hs-source-dirs: test/doc build-depends: base , doctest >= 0.11 , QuickCheck >= 2.9 default-language: Haskell2010 +test-suite golden-test + type: exitcode-stdio-1.0 + main-is: Main.hs + hs-source-dirs: test/golden + build-depends: base + , bytestring >= 0.10.8.2 + , servant >= 0.9 && < 0.16 + , servant-foreign >= 0.9 && < 0.16 + , servant-ruby + , tasty >= 0.11.3 + , tasty-golden >= 2.3.1.1 + , text >= 1.2 && < 1.3 + default-language: Haskell2010 + source-repository head type: git location: https://github.com/joneshf/servant-ruby diff --git a/src/Servant/Ruby.hs b/src/Servant/Ruby.hs index 6174255..ec85b09 100644 --- a/src/Servant/Ruby.hs +++ b/src/Servant/Ruby.hs @@ -383,7 +383,7 @@ paramToStr :: QueryArg f -> Text paramToStr qarg = case qarg ^. queryArgType of Normal -> key <> "=#{" <> val <> "}" - Flag -> key + Flag -> "#{" <> key <> " ? '" <> key <> "' : ''}" List -> "#{ " <> val <> ".collect { |x| '" <> key <> "[]=' + x.to_s }.join('&') }" where key = qarg ^. queryArgName.argName._PathSegment diff --git a/test/Main.hs b/test/doc/Main.hs similarity index 100% rename from test/Main.hs rename to test/doc/Main.hs diff --git a/test/golden/Main.hs b/test/golden/Main.hs new file mode 100644 index 0000000..53fe35a --- /dev/null +++ b/test/golden/Main.hs @@ -0,0 +1,48 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE TypeOperators #-} + +module Main where + +import Data.ByteString.Lazy (ByteString) +import Data.Proxy (Proxy(Proxy)) +import Test.Tasty (defaultMain, testGroup) +import Test.Tasty.Golden (goldenVsString) +import Servant.API ((:>), Get, Post, JSON, Capture, Header, ReqBody, QueryParam, QueryParams, QueryFlag) +import Servant.Ruby (ruby, NameSpace(NameSpace)) +import Data.Text.Lazy.Encoding (encodeUtf8) +import Data.Text.Lazy (fromStrict) +import Servant.Foreign (GenerateList, NoContent, Foreign, HasForeign, NoTypes) + +main :: IO () +main = defaultMain $ testGroup "golden tests" + [ goldenVsString "static" "test/golden/expected/static.rb" (test (Proxy :: Proxy StaticApi)) + , goldenVsString "parameters" "test/golden/expected/parameters.rb" (test (Proxy :: Proxy ParametersApi)) + , goldenVsString "body" "test/golden/expected/body.rb" (test (Proxy :: Proxy BodyApi)) + , goldenVsString "header" "test/golden/expected/header.rb" (test (Proxy :: Proxy HeaderApi)) + , goldenVsString "query param" "test/golden/expected/query_param.rb" (test (Proxy :: Proxy QueryParamApi)) + , goldenVsString "query params" "test/golden/expected/query_params.rb" (test (Proxy :: Proxy QueryParamsApi)) + , goldenVsString "query flag" "test/golden/expected/query_flag.rb" (test (Proxy :: Proxy QueryFlagApi)) + ] + + +type StaticApi = "hello" :> "world" :> Get '[JSON] () + +type ParametersApi = Capture "butterfly" () :> Get '[JSON] () + +type BodyApi = ReqBody '[JSON] () :> Post '[JSON] () + +type HeaderApi = Header "moth" () :> Post '[JSON] () + +type QueryParamApi = QueryParam "spider" () :> Get '[JSON] () + +type QueryParamsApi = QueryParams "spiders" () :> Get '[JSON] () + +type QueryFlagApi = QueryFlag "beetle" :> Get '[JSON] () + +test + :: (GenerateList NoContent (Foreign NoContent api), HasForeign NoTypes NoContent api) + => Proxy api + -> IO ByteString +test = pure . encodeUtf8 . fromStrict . ruby (NameSpace ["Generated", "V1"] "Things") diff --git a/test/golden/expected/body.rb b/test/golden/expected/body.rb new file mode 100644 index 0000000..883f0c5 --- /dev/null +++ b/test/golden/expected/body.rb @@ -0,0 +1,31 @@ +require "json" +require "net/http" +require "uri" + +module Generated + module V1 + class Things + def initialize(origin, timeout = nil) + @origin = URI(origin) + @http = Net::HTTP.new(@origin.host, @origin.port) + + unless timeout.nil? + @http.open_timeout = timeout + @http.read_timeout = timeout + end + @http.use_ssl = @origin.scheme == 'https' + end + + def post_uri() + URI("#{@origin}") + end + + def post(body:) + req = Net::HTTP::Post.new(post_uri()) + req["Content-Type"] = "application/json" + + @http.request(req, body) + end + end + end +end diff --git a/test/golden/expected/header.rb b/test/golden/expected/header.rb new file mode 100644 index 0000000..9885e43 --- /dev/null +++ b/test/golden/expected/header.rb @@ -0,0 +1,31 @@ +require "json" +require "net/http" +require "uri" + +module Generated + module V1 + class Things + def initialize(origin, timeout = nil) + @origin = URI(origin) + @http = Net::HTTP.new(@origin.host, @origin.port) + + unless timeout.nil? + @http.open_timeout = timeout + @http.read_timeout = timeout + end + @http.use_ssl = @origin.scheme == 'https' + end + + def post_uri() + URI("#{@origin}") + end + + def post(moth:) + req = Net::HTTP::Post.new(post_uri()) + req["moth"] = moth + + @http.request(req) + end + end + end +end diff --git a/test/golden/expected/parameters.rb b/test/golden/expected/parameters.rb new file mode 100644 index 0000000..f586457 --- /dev/null +++ b/test/golden/expected/parameters.rb @@ -0,0 +1,34 @@ +require "json" +require "net/http" +require "uri" + +module Generated + module V1 + class Things + def initialize(origin, timeout = nil) + @origin = URI(origin) + @http = Net::HTTP.new(@origin.host, @origin.port) + + unless timeout.nil? + @http.open_timeout = timeout + @http.read_timeout = timeout + end + @http.use_ssl = @origin.scheme == 'https' + end + + def get_by_butterfly_uri(butterfly) + butterfly = if butterfly.kind_of?(Array) then butterfly.join(',') else butterfly end + + URI("#{@origin}/#{butterfly}") + end + + def get_by_butterfly(butterfly) + butterfly = if butterfly.kind_of?(Array) then butterfly.join(',') else butterfly end + + req = Net::HTTP::Get.new(get_by_butterfly_uri(butterfly)) + + @http.request(req) + end + end + end +end diff --git a/test/golden/expected/query_flag.rb b/test/golden/expected/query_flag.rb new file mode 100644 index 0000000..da39b9b --- /dev/null +++ b/test/golden/expected/query_flag.rb @@ -0,0 +1,30 @@ +require "json" +require "net/http" +require "uri" + +module Generated + module V1 + class Things + def initialize(origin, timeout = nil) + @origin = URI(origin) + @http = Net::HTTP.new(@origin.host, @origin.port) + + unless timeout.nil? + @http.open_timeout = timeout + @http.read_timeout = timeout + end + @http.use_ssl = @origin.scheme == 'https' + end + + def get_uri(beetle) + URI("#{@origin}?#{beetle ? 'beetle' : ''}") + end + + def get(beetle) + req = Net::HTTP::Get.new(get_uri(beetle)) + + @http.request(req) + end + end + end +end diff --git a/test/golden/expected/query_param.rb b/test/golden/expected/query_param.rb new file mode 100644 index 0000000..39524cf --- /dev/null +++ b/test/golden/expected/query_param.rb @@ -0,0 +1,30 @@ +require "json" +require "net/http" +require "uri" + +module Generated + module V1 + class Things + def initialize(origin, timeout = nil) + @origin = URI(origin) + @http = Net::HTTP.new(@origin.host, @origin.port) + + unless timeout.nil? + @http.open_timeout = timeout + @http.read_timeout = timeout + end + @http.use_ssl = @origin.scheme == 'https' + end + + def get_uri(spider) + URI("#{@origin}?spider=#{spider}") + end + + def get(spider) + req = Net::HTTP::Get.new(get_uri(spider)) + + @http.request(req) + end + end + end +end diff --git a/test/golden/expected/query_params.rb b/test/golden/expected/query_params.rb new file mode 100644 index 0000000..6e1d8d5 --- /dev/null +++ b/test/golden/expected/query_params.rb @@ -0,0 +1,30 @@ +require "json" +require "net/http" +require "uri" + +module Generated + module V1 + class Things + def initialize(origin, timeout = nil) + @origin = URI(origin) + @http = Net::HTTP.new(@origin.host, @origin.port) + + unless timeout.nil? + @http.open_timeout = timeout + @http.read_timeout = timeout + end + @http.use_ssl = @origin.scheme == 'https' + end + + def get_uri(spiders) + URI("#{@origin}?#{ spiders.collect { |x| 'spiders[]=' + x.to_s }.join('&') }") + end + + def get(spiders) + req = Net::HTTP::Get.new(get_uri(spiders)) + + @http.request(req) + end + end + end +end diff --git a/test/golden/expected/static.rb b/test/golden/expected/static.rb new file mode 100644 index 0000000..02f4f0f --- /dev/null +++ b/test/golden/expected/static.rb @@ -0,0 +1,30 @@ +require "json" +require "net/http" +require "uri" + +module Generated + module V1 + class Things + def initialize(origin, timeout = nil) + @origin = URI(origin) + @http = Net::HTTP.new(@origin.host, @origin.port) + + unless timeout.nil? + @http.open_timeout = timeout + @http.read_timeout = timeout + end + @http.use_ssl = @origin.scheme == 'https' + end + + def get_hello_world_uri() + URI("#{@origin}/hello/world") + end + + def get_hello_world() + req = Net::HTTP::Get.new(get_hello_world_uri()) + + @http.request(req) + end + end + end +end