Merge pull request #91 from darronschall/service-suffix-handling

Code generation should only append "Service" when necessary.
This commit is contained in:
Arthur Nogueira Neves 2023-01-05 08:32:09 -05:00 коммит произвёл GitHub
Родитель cd830052b4 01ce2e8642
Коммит d9a946d829
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
7 изменённых файлов: 142 добавлений и 133 удалений

Просмотреть файл

@ -2,7 +2,7 @@ syntax = "proto3";
package example.hello_world;
service HelloWorld {
service HelloWorldService {
rpc Hello(HelloRequest) returns (HelloResponse);
}

Просмотреть файл

@ -6,7 +6,7 @@ module Example
module HelloWorld
class HelloWorldService < ::Twirp::Service
package 'example.hello_world'
service 'HelloWorld'
service 'HelloWorldService'
rpc :Hello, HelloRequest, HelloResponse, :ruby_method => :hello
end

Просмотреть файл

@ -109,7 +109,15 @@ func (g *generator) generateRubyCode(file *descriptor.FileDescriptorProto, pbFil
for i, service := range file.Service {
svcName := service.GetName()
print(b, "%sclass %sService < ::Twirp::Service", indent, camelCase(svcName))
// Well-named services already end in "Service"; fixup services that don't.
if !strings.HasSuffix(svcName, "Service") {
svcName += "Service"
}
// The client name strips the "Service" suffix for better readability.
clientName := strings.TrimSuffix(svcName, "Service")
print(b, "%sclass %s < ::Twirp::Service", indent, camelCase(svcName))
if pkgName != "" {
print(b, "%s package '%s'", indent, pkgName)
}
@ -124,8 +132,8 @@ func (g *generator) generateRubyCode(file *descriptor.FileDescriptorProto, pbFil
print(b, "%send", indent)
print(b, "")
print(b, "%sclass %sClient < ::Twirp::Client", indent, camelCase(svcName))
print(b, "%s client_for %sService", indent, camelCase(svcName))
print(b, "%sclass %sClient < ::Twirp::Client", indent, camelCase(clientName))
print(b, "%s client_for %s", indent, camelCase(svcName))
print(b, "%send", indent)
if i < len(file.Service)-1 {
print(b, "")

Просмотреть файл

@ -16,12 +16,12 @@ class ClientJSONTest < Minitest::Test
end
def test_client_json_success
c = Twirp::ClientJSON.new(conn_stub("/my.pkg.Talking/Blah") {|req|
c = Twirp::ClientJSON.new(conn_stub("/my.pkg.TalkingService/Blah") {|req|
assert_equal "application/json", req.request_headers['Content-Type']
assert_equal '{"blah1":1,"blah2":2}', req.body # body is json
[200, {}, '{"blah_resp": 3}']
}, package: "my.pkg", service: "Talking")
}, package: "my.pkg", service: "TalkingService")
resp = c.rpc :Blah, blah1: 1, blah2: 2
assert_nil resp.error
@ -30,12 +30,12 @@ class ClientJSONTest < Minitest::Test
end
def test_client_json_thennable
c = Twirp::ClientJSON.new(conn_stub_thennable("/my.pkg.Talking/Blah") {|req|
c = Twirp::ClientJSON.new(conn_stub_thennable("/my.pkg.TalkingService/Blah") {|req|
assert_equal "application/json", req.request_headers['Content-Type']
assert_equal '{"blah1":1,"blah2":2}', req.body # body is json
[200, {}, '{"blah_resp": 3}']
}, package: "my.pkg", service: "Talking")
}, package: "my.pkg", service: "TalkingService")
resp_thennable = c.rpc :Blah, blah1: 1, blah2: 2
# the final `.then {}` call will yield a ClientResp
@ -54,12 +54,12 @@ class ClientJSONTest < Minitest::Test
end
def test_client_json_strict_encoding
c = Twirp::ClientJSON.new(conn_stub("/my.pkg.Talking/Blah") {|req|
c = Twirp::ClientJSON.new(conn_stub("/my.pkg.TalkingService/Blah") {|req|
assert_equal "application/json; strict=true", req.request_headers['Content-Type']
assert_equal '{"blah1":1,"blah2":2}', req.body # body is json
[200, {}, '{"blah_resp": 3}']
}, package: "my.pkg", service: "Talking", strict: true)
}, package: "my.pkg", service: "TalkingService", strict: true)
resp = c.rpc :Blah, blah1: 1, blah2: 2
assert_nil resp.error

Просмотреть файл

@ -12,7 +12,7 @@ class ClientTest < Minitest::Test
c = EmptyClient.new("http://localhost:8080")
refute_nil c
refute_nil c.instance_variable_get(:@conn) # make sure that connection was assigned
assert_equal "EmptyClient", c.instance_variable_get(:@service_full_name)
assert_equal "EmptyService", c.instance_variable_get(:@service_full_name)
end
def test_new_with_invalid_url
@ -31,13 +31,13 @@ class ClientTest < Minitest::Test
# To avoid collisions, the Twirp::Client class should only have the rpc method.
assert_equal [:rpc], Twirp::Client.instance_methods(false)
# If one of the methods is being implemented through the DSL, the colision should be avoided, keeping the previous method.
# If one of the methods is being implemented through the DSL, the collision should be avoided, keeping the previous method.
num_mthds = EmptyClient.instance_methods.size
EmptyClient.rpc :Rpc, Example::Empty, Example::Empty, :ruby_method => :rpc
assert_equal num_mthds, EmptyClient.instance_methods.size # no new method was added (is a collision)
# Make sure that the previous .rpc method was not modified
c = EmptyClient.new(conn_stub("/EmptyClient/Rpc") {|req|
c = EmptyClient.new(conn_stub("/EmptyService/Rpc") {|req|
[200, protoheader, proto(Example::Empty, {})]
})
resp = c.rpc(:Rpc, {})
@ -63,7 +63,7 @@ class ClientTest < Minitest::Test
# ----------------------------
def test_proto_success
c = Example::HaberdasherClient.new(conn_stub("/example.Haberdasher/MakeHat") {|req|
c = Example::HaberdasherClient.new(conn_stub("/example.HaberdasherService/MakeHat") {|req|
[200, protoheader, proto(Example::Hat, inches: 99, color: "red")]
})
resp = c.make_hat({})
@ -73,7 +73,7 @@ class ClientTest < Minitest::Test
end
def test_proto_thennable
c = Example::HaberdasherClient.new(conn_stub_thennable("/example.Haberdasher/MakeHat") {|req|
c = Example::HaberdasherClient.new(conn_stub_thennable("/example.HaberdasherService/MakeHat") {|req|
[200, protoheader, proto(Example::Hat, inches: 99, color: "red")]
})
resp_thennable = c.make_hat({})
@ -94,7 +94,7 @@ class ClientTest < Minitest::Test
end
def test_proto_send_headers
c = Example::HaberdasherClient.new(conn_stub("/example.Haberdasher/MakeHat") {|req|
c = Example::HaberdasherClient.new(conn_stub("/example.HaberdasherService/MakeHat") {|req|
assert_equal "Bar", req.request_headers['My-Foo-Header']
[200, protoheader, proto(Example::Hat, inches: 99, color: "red")]
})
@ -105,7 +105,7 @@ class ClientTest < Minitest::Test
end
def test_proto_serialized_request_body_attrs
c = Example::HaberdasherClient.new(conn_stub("/example.Haberdasher/MakeHat") {|req|
c = Example::HaberdasherClient.new(conn_stub("/example.HaberdasherService/MakeHat") {|req|
size = Example::Size.decode(req.body) # body is valid protobuf
assert_equal 666, size.inches
@ -117,7 +117,7 @@ class ClientTest < Minitest::Test
end
def test_proto_serialized_request_body
c = Example::HaberdasherClient.new(conn_stub("/example.Haberdasher/MakeHat") {|req|
c = Example::HaberdasherClient.new(conn_stub("/example.HaberdasherService/MakeHat") {|req|
assert_equal "application/protobuf", req.request_headers['Content-Type']
size = Example::Size.decode(req.body) # body is valid protobuf
@ -131,7 +131,7 @@ class ClientTest < Minitest::Test
end
def test_proto_twirp_error
c = Example::HaberdasherClient.new(conn_stub("/example.Haberdasher/MakeHat") {|req|
c = Example::HaberdasherClient.new(conn_stub("/example.HaberdasherService/MakeHat") {|req|
[500, {}, json(code: "internal", msg: "something went wrong")]
})
resp = c.make_hat(inches: 1)
@ -142,7 +142,7 @@ class ClientTest < Minitest::Test
end
def test_proto_intermediary_plain_error
c = Example::HaberdasherClient.new(conn_stub("/example.Haberdasher/MakeHat") {|req|
c = Example::HaberdasherClient.new(conn_stub("/example.HaberdasherService/MakeHat") {|req|
[503, {}, 'plain text error from proxy']
})
resp = c.make_hat(inches: 1)
@ -156,7 +156,7 @@ class ClientTest < Minitest::Test
end
def test_proto_redirect_error
c = Example::HaberdasherClient.new(conn_stub("/example.Haberdasher/MakeHat") {|req|
c = Example::HaberdasherClient.new(conn_stub("/example.HaberdasherService/MakeHat") {|req|
[300, {'location' => "http://rainbow.com"}, '']
})
resp = c.make_hat(inches: 1)
@ -169,7 +169,7 @@ class ClientTest < Minitest::Test
end
def test_proto_missing_response_header
c = Example::HaberdasherClient.new(conn_stub("/example.Haberdasher/MakeHat") {|req|
c = Example::HaberdasherClient.new(conn_stub("/example.HaberdasherService/MakeHat") {|req|
[200, {}, proto(Example::Hat, inches: 99, color: "red")]
})
resp = c.make_hat({})
@ -179,7 +179,7 @@ class ClientTest < Minitest::Test
end
def test_error_with_invalid_code
c = Example::HaberdasherClient.new(conn_stub("/example.Haberdasher/MakeHat") {|req|
c = Example::HaberdasherClient.new(conn_stub("/example.HaberdasherService/MakeHat") {|req|
[500, {}, json(code: "unicorn", msg: "the unicorn is here")]
})
resp = c.make_hat({})
@ -190,7 +190,7 @@ class ClientTest < Minitest::Test
end
def test_error_with_no_code
c = Example::HaberdasherClient.new(conn_stub("/example.Haberdasher/MakeHat") {|req|
c = Example::HaberdasherClient.new(conn_stub("/example.HaberdasherService/MakeHat") {|req|
[500, {}, json(msg: "I have no code of honor")]
})
resp = c.make_hat({})
@ -207,7 +207,7 @@ class ClientTest < Minitest::Test
# ------------------------
def test_json_success
c = Example::HaberdasherClient.new(conn_stub("/example.Haberdasher/MakeHat") {|req|
c = Example::HaberdasherClient.new(conn_stub("/example.HaberdasherService/MakeHat") {|req|
[200, jsonheader, '{"inches": 99, "color": "red"}']
}, content_type: "application/json")
@ -218,7 +218,7 @@ class ClientTest < Minitest::Test
end
def test_json_thennable
c = Example::HaberdasherClient.new(conn_stub_thennable("/example.Haberdasher/MakeHat") {|req|
c = Example::HaberdasherClient.new(conn_stub_thennable("/example.HaberdasherService/MakeHat") {|req|
[200, jsonheader, '{"inches": 99, "color": "red"}']
}, content_type: "application/json")
@ -239,7 +239,7 @@ class ClientTest < Minitest::Test
end
def test_json_send_headers
c = Example::HaberdasherClient.new(conn_stub("/example.Haberdasher/MakeHat") {|req|
c = Example::HaberdasherClient.new(conn_stub("/example.HaberdasherService/MakeHat") {|req|
assert_equal "Bar", req.request_headers['My-Foo-Header']
[200, jsonheader, '{"inches": 99, "color": "red"}']
}, content_type: "application/json")
@ -250,7 +250,7 @@ class ClientTest < Minitest::Test
end
def test_json_serialized_request_body_attrs
c = Example::HaberdasherClient.new(conn_stub("/example.Haberdasher/MakeHat") {|req|
c = Example::HaberdasherClient.new(conn_stub("/example.HaberdasherService/MakeHat") {|req|
assert_equal "application/json", req.request_headers['Content-Type']
assert_equal '{"inches":666}', req.body # body is valid json
[200, jsonheader, '{}']
@ -262,7 +262,7 @@ class ClientTest < Minitest::Test
end
def test_json_serialized_request_body_object
c = Example::HaberdasherClient.new(conn_stub("/example.Haberdasher/MakeHat") {|req|
c = Example::HaberdasherClient.new(conn_stub("/example.HaberdasherService/MakeHat") {|req|
assert_equal "application/json", req.request_headers['Content-Type']
assert_equal '{"inches":666}', req.body # body is valid json
[200, jsonheader, '{}']
@ -274,7 +274,7 @@ class ClientTest < Minitest::Test
end
def test_json_error
c = Example::HaberdasherClient.new(conn_stub("/example.Haberdasher/MakeHat") {|req|
c = Example::HaberdasherClient.new(conn_stub("/example.HaberdasherService/MakeHat") {|req|
[500, {}, json(code: "internal", msg: "something went wrong")]
}, content_type: "application/json")
@ -286,7 +286,7 @@ class ClientTest < Minitest::Test
end
def test_json_missing_response_header
c = Example::HaberdasherClient.new(conn_stub("/example.Haberdasher/MakeHat") {|req|
c = Example::HaberdasherClient.new(conn_stub("/example.HaberdasherService/MakeHat") {|req|
[200, {}, json(inches: 99, color: "red")]
}, content_type: "application/json")
@ -301,7 +301,7 @@ class ClientTest < Minitest::Test
# ------------------
def test_rpc_success
c = FooClient.new(conn_stub("/Foo/Foo") {|req|
c = FooClient.new(conn_stub("/FooService/Foo") {|req|
[200, protoheader, proto(Foo, foo: "out")]
})
resp = c.rpc :Foo, foo: "in"
@ -311,7 +311,7 @@ class ClientTest < Minitest::Test
end
def test_rpc_send_headers
c = FooClient.new(conn_stub("/Foo/Foo") {|req|
c = FooClient.new(conn_stub("/FooService/Foo") {|req|
assert_equal "Bar", req.request_headers['My-Foo-Header']
[200, protoheader, proto(Foo, foo: "out")]
})
@ -322,7 +322,7 @@ class ClientTest < Minitest::Test
end
def test_rpc_error
c = FooClient.new(conn_stub("/Foo/Foo") {|req|
c = FooClient.new(conn_stub("/FooService/Foo") {|req|
[400, {}, json(code: "invalid_argument", msg: "dont like empty")]
})
resp = c.rpc :Foo, foo: ""
@ -333,7 +333,7 @@ class ClientTest < Minitest::Test
end
def test_rpc_serialization_exception
c = FooClient.new(conn_stub("/Foo/Foo") {|req|
c = FooClient.new(conn_stub("/FooService/Foo") {|req|
[200, protoheader, "badstuff"]
})
assert_raises Google::Protobuf::ParseError do

Просмотреть файл

@ -26,14 +26,14 @@ end
# Twirp Service.
# An example of the result of the protoc twirp_ruby plugin code generator.
module Example
class Haberdasher < Twirp::Service
class HaberdasherService < Twirp::Service
package "example"
service "Haberdasher"
service "HaberdasherService"
rpc :MakeHat, Size, Hat, :ruby_method => :make_hat
end
class HaberdasherClient < Twirp::Client
client_for Haberdasher
client_for HaberdasherService
end
end
@ -53,6 +53,7 @@ end
class EmptyService < Twirp::Service
end
class EmptyClient < Twirp::Client
client_for EmptyService
end
# Foo message
@ -63,8 +64,8 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
end
Foo = Google::Protobuf::DescriptorPool.generated_pool.lookup("Foo").msgclass
# Foo Client
# Foo Service Client
class FooClient < Twirp::Client
service "Foo"
service "FooService"
rpc :Foo, Foo, Foo, :ruby_method => :foo
end

Просмотреть файл

@ -9,7 +9,7 @@ require_relative './fake_services'
class ServiceTest < Minitest::Test
def setup
Example::Haberdasher.raise_exceptions = true # configure for testing to make debugging easier
Example::HaberdasherService.raise_exceptions = true # configure for testing to make debugging easier
end
# Class method to make a Rack response with a Twirp errpr
@ -23,20 +23,20 @@ class ServiceTest < Minitest::Test
# The rpc DSL should properly build the base Twirp environment for each rpc method.
def test_rpcs_accessor
assert_equal 1, Example::Haberdasher.rpcs.size
assert_equal 1, Example::HaberdasherService.rpcs.size
assert_equal({
rpc_method: :MakeHat,
input_class: Example::Size,
output_class: Example::Hat,
ruby_method: :make_hat,
}, Example::Haberdasher.rpcs["MakeHat"])
}, Example::HaberdasherService.rpcs["MakeHat"])
end
# DSL package and service define the proper data on the service
def test_package_service_getters
assert_equal "example", Example::Haberdasher.package_name
assert_equal "Haberdasher", Example::Haberdasher.service_name
assert_equal "example.Haberdasher", Example::Haberdasher.service_full_name
assert_equal "example", Example::HaberdasherService.package_name
assert_equal "HaberdasherService", Example::HaberdasherService.service_name
assert_equal "example.HaberdasherService", Example::HaberdasherService.service_full_name
assert_equal "", EmptyService.package_name # defaults to empty string
assert_equal "EmptyService", EmptyService.service_name # defaults to class name
@ -44,9 +44,9 @@ class ServiceTest < Minitest::Test
end
def test_init_service
svc = Example::Haberdasher.new(HaberdasherHandler.new)
svc = Example::HaberdasherService.new(HaberdasherHandler.new)
assert svc.respond_to?(:call) # so it is a Proc that can be used as Rack middleware
assert_equal "example.Haberdasher", svc.full_name
assert_equal "example.HaberdasherService", svc.full_name
end
def test_init_empty_service
@ -56,7 +56,7 @@ class ServiceTest < Minitest::Test
end
def test_successful_json_request
rack_env = json_req "/example.Haberdasher/MakeHat", inches: 10
rack_env = json_req "/example.HaberdasherService/MakeHat", inches: 10
status, headers, body = haberdasher_service.call(rack_env)
assert_equal 200, status
@ -65,7 +65,7 @@ class ServiceTest < Minitest::Test
end
def test_successful_json_strict_request_emit_defaults
rack_env = json_strict_req "/example.Haberdasher/MakeHat", inches: 0 # default int value
rack_env = json_strict_req "/example.HaberdasherService/MakeHat", inches: 0 # default int value
status, headers, body = haberdasher_service.call(rack_env)
assert_equal 200, status
@ -74,7 +74,7 @@ class ServiceTest < Minitest::Test
end
def test_successful_json_request_emit_defaults
rack_env = json_req "/example.Haberdasher/MakeHat", inches: 0 # default int value
rack_env = json_req "/example.HaberdasherService/MakeHat", inches: 0 # default int value
status, headers, body = haberdasher_service.call(rack_env)
assert_equal 200, status
@ -83,7 +83,7 @@ class ServiceTest < Minitest::Test
end
def test_successful_proto_request
rack_env = proto_req "/example.Haberdasher/MakeHat", Example::Size.new(inches: 10)
rack_env = proto_req "/example.HaberdasherService/MakeHat", Example::Size.new(inches: 10)
status, headers, body = haberdasher_service.call(rack_env)
assert_equal 200, status
@ -92,7 +92,7 @@ class ServiceTest < Minitest::Test
end
def test_bad_route_with_wrong_rpc_method
rack_env = json_req "/twirp/example.Haberdasher/MakeUnicorns", and_rainbows: true
rack_env = json_req "/twirp/example.HaberdasherService/MakeUnicorns", and_rainbows: true
status, headers, body = haberdasher_service.call(rack_env)
assert_equal 404, status
@ -100,12 +100,12 @@ class ServiceTest < Minitest::Test
assert_equal({
"code" => 'bad_route',
"msg" => 'Invalid rpc method "MakeUnicorns"',
"meta" => {"twirp_invalid_route" => "POST /twirp/example.Haberdasher/MakeUnicorns"},
"meta" => {"twirp_invalid_route" => "POST /twirp/example.HaberdasherService/MakeUnicorns"},
}, JSON.parse(body[0]))
end
def test_bad_route_with_wrong_http_method
rack_env = Rack::MockRequest.env_for "example.Haberdasher/MakeHat",
rack_env = Rack::MockRequest.env_for "example.HaberdasherService/MakeHat",
method: "GET", input: '{"inches": 10}', "CONTENT_TYPE" => "application/json"
status, headers, body = haberdasher_service.call(rack_env)
@ -114,12 +114,12 @@ class ServiceTest < Minitest::Test
assert_equal({
"code" => 'bad_route',
"msg" => 'HTTP request method must be POST',
"meta" => {"twirp_invalid_route" => "GET /example.Haberdasher/MakeHat"},
"meta" => {"twirp_invalid_route" => "GET /example.HaberdasherService/MakeHat"},
}, JSON.parse(body[0]))
end
def test_bad_route_with_wrong_content_type
rack_env = Rack::MockRequest.env_for "example.Haberdasher/MakeHat",
rack_env = Rack::MockRequest.env_for "example.HaberdasherService/MakeHat",
method: "POST", input: 'free text', "CONTENT_TYPE" => "text/plain"
status, headers, body = haberdasher_service.call(rack_env)
@ -128,7 +128,7 @@ class ServiceTest < Minitest::Test
assert_equal({
"code" => 'bad_route',
"msg" => 'Unexpected Content-Type: "text/plain". Content-Type header must be one of ["application/json", "application/protobuf"]',
"meta" => {"twirp_invalid_route" => "POST /example.Haberdasher/MakeHat"},
"meta" => {"twirp_invalid_route" => "POST /example.HaberdasherService/MakeHat"},
}, JSON.parse(body[0]))
end
@ -140,7 +140,7 @@ class ServiceTest < Minitest::Test
assert_equal 'application/json', headers['Content-Type']
assert_equal({
"code" => 'bad_route',
"msg" => 'Invalid route. Expected format: POST {BaseURL}/example.Haberdasher/{Method}',
"msg" => 'Invalid route. Expected format: POST {BaseURL}/example.HaberdasherService/{Method}',
"meta" => {"twirp_invalid_route" => "POST /wrongpath"},
}, JSON.parse(body[0]))
end
@ -153,13 +153,13 @@ class ServiceTest < Minitest::Test
assert_equal 'application/json', headers['Content-Type'] # error responses are always JSON, even for Protobuf requests
assert_equal({
"code" => 'bad_route',
"msg" => 'Invalid route. Expected format: POST {BaseURL}/example.Haberdasher/{Method}',
"msg" => 'Invalid route. Expected format: POST {BaseURL}/example.HaberdasherService/{Method}',
"meta" => {"twirp_invalid_route" => "POST /another/wrong.Path/MakeHat"},
}, JSON.parse(body[0]))
end
def test_bad_route_with_wrong_json_body
rack_env = Rack::MockRequest.env_for "example.Haberdasher/MakeHat",
rack_env = Rack::MockRequest.env_for "example.HaberdasherService/MakeHat",
method: "POST", input: 'bad json', "CONTENT_TYPE" => "application/json"
status, headers, body = haberdasher_service.call(rack_env)
@ -169,12 +169,12 @@ class ServiceTest < Minitest::Test
"code" => 'malformed',
"msg" => 'Invalid request body for rpc method "MakeHat" with Content-Type=application/json: ' +
"Error occurred during parsing: Error parsing JSON @1:0: Expected: '{'",
"meta" => {"twirp_invalid_route" => "POST /example.Haberdasher/MakeHat"},
"meta" => {"twirp_invalid_route" => "POST /example.HaberdasherService/MakeHat"},
}, JSON.parse(body[0]))
end
def test_bad_route_with_wrong_protobuf_body
rack_env = Rack::MockRequest.env_for "example.Haberdasher/MakeHat",
rack_env = Rack::MockRequest.env_for "example.HaberdasherService/MakeHat",
method: "POST", input: 'bad protobuf', "CONTENT_TYPE" => "application/protobuf"
status, headers, body = haberdasher_service.call(rack_env)
@ -184,12 +184,12 @@ class ServiceTest < Minitest::Test
"code" => 'malformed',
"msg" => 'Invalid request body for rpc method "MakeHat" with Content-Type=application/protobuf: ' +
'Error occurred during parsing',
"meta" => {"twirp_invalid_route" => "POST /example.Haberdasher/MakeHat"},
"meta" => {"twirp_invalid_route" => "POST /example.HaberdasherService/MakeHat"},
}, JSON.parse(body[0]))
end
def test_route_with_query_string
rack_env = json_req "/example.Haberdasher/MakeHat?extra=1", inches: 10
rack_env = json_req "/example.HaberdasherService/MakeHat?extra=1", inches: 10
status, headers, body = haberdasher_service.call(rack_env)
assert_equal 200, status
@ -198,7 +198,7 @@ class ServiceTest < Minitest::Test
end
def test_json_request_ignores_unknown_fields
rack_env = json_req "/example.Haberdasher/MakeHat", inches: 10, fake: 3
rack_env = json_req "/example.HaberdasherService/MakeHat", inches: 10, fake: 3
status, headers, body = haberdasher_service.call(rack_env)
assert_equal 200, status
@ -207,7 +207,7 @@ class ServiceTest < Minitest::Test
end
def test_json_strict_request_fails_unknown_fields
rack_env = json_strict_req "/example.Haberdasher/MakeHat", inches: 10, fake: 3
rack_env = json_strict_req "/example.HaberdasherService/MakeHat", inches: 10, fake: 3
status, headers, body = haberdasher_service.call(rack_env)
assert_equal 400, status
@ -216,7 +216,7 @@ class ServiceTest < Minitest::Test
"code" => 'malformed',
"msg" => 'Invalid request body for rpc method "MakeHat" with Content-Type=application/json; strict=true: ' +
"Error occurred during parsing: Error parsing JSON @1:20: No such field: fake",
"meta" => {"twirp_invalid_route" => "POST /example.Haberdasher/MakeHat"},
"meta" => {"twirp_invalid_route" => "POST /example.HaberdasherService/MakeHat"},
}, JSON.parse(body[0]))
end
@ -238,7 +238,7 @@ class ServiceTest < Minitest::Test
error_called = true
end
rack_env = json_req "/example.Haberdasher/BadRouteMethod", inches: 10
rack_env = json_req "/example.HaberdasherService/BadRouteMethod", inches: 10
status, _, body = svc.call(rack_env)
assert_equal 404, status
@ -248,7 +248,7 @@ class ServiceTest < Minitest::Test
end
def test_long_base_url
rack_env = json_req "long-ass/base/url/twirp/example.Haberdasher/MakeHat", {inches: 10}
rack_env = json_req "long-ass/base/url/twirp/example.HaberdasherService/MakeHat", {inches: 10}
status, _, body = haberdasher_service.call(rack_env)
assert_equal 200, status
@ -256,11 +256,11 @@ class ServiceTest < Minitest::Test
# Handler should be able to return an instance of the proto message
def test_handler_returns_a_proto_message
svc = Example::Haberdasher.new(HaberdasherHandler.new do |size, env|
svc = Example::HaberdasherService.new(HaberdasherHandler.new do |size, env|
Example::Hat.new(inches: 11)
end)
rack_env = proto_req "/example.Haberdasher/MakeHat", Example::Size.new
rack_env = proto_req "/example.HaberdasherService/MakeHat", Example::Size.new
status, _, body = svc.call(rack_env)
assert_equal 200, status
@ -269,11 +269,11 @@ class ServiceTest < Minitest::Test
# Handler should be able to return a hash with attributes
def test_handler_returns_hash_attributes
svc = Example::Haberdasher.new(HaberdasherHandler.new do |size, env|
svc = Example::HaberdasherService.new(HaberdasherHandler.new do |size, env|
{inches: 11}
end)
rack_env = proto_req "/example.Haberdasher/MakeHat", Example::Size.new
rack_env = proto_req "/example.HaberdasherService/MakeHat", Example::Size.new
status, headers, body = svc.call(rack_env)
assert_equal 200, status
@ -282,11 +282,11 @@ class ServiceTest < Minitest::Test
# Handler should be able to return Twirp::Error values, that will trigger error responses
def test_handler_returns_twirp_error
svc = Example::Haberdasher.new(HaberdasherHandler.new do |size, env|
svc = Example::HaberdasherService.new(HaberdasherHandler.new do |size, env|
return Twirp::Error.invalid_argument "I don't like that size"
end)
rack_env = proto_req "/example.Haberdasher/MakeHat", Example::Size.new(inches: 666)
rack_env = proto_req "/example.HaberdasherService/MakeHat", Example::Size.new(inches: 666)
status, headers, body = svc.call(rack_env)
assert_equal 400, status
assert_equal 'application/json', headers['Content-Type'] # error responses are always JSON, even for Protobuf requests
@ -297,12 +297,12 @@ class ServiceTest < Minitest::Test
end
def test_handler_method_can_set_response_headers_through_the_env
svc = Example::Haberdasher.new(HaberdasherHandler.new do |size, env|
svc = Example::HaberdasherService.new(HaberdasherHandler.new do |size, env|
env[:http_response_headers]["Cache-Control"] = "public, max-age=60"
{}
end)
rack_env = proto_req "/example.Haberdasher/MakeHat", Example::Size.new
rack_env = proto_req "/example.HaberdasherService/MakeHat", Example::Size.new
status, headers, body = svc.call(rack_env)
assert_equal 200, status
@ -311,11 +311,11 @@ class ServiceTest < Minitest::Test
end
def test_handler_returns_invalid_type_nil
svc = Example::Haberdasher.new(HaberdasherHandler.new do |size, env|
svc = Example::HaberdasherService.new(HaberdasherHandler.new do |size, env|
nil
end)
rack_env = proto_req "/example.Haberdasher/MakeHat", Example::Size.new
rack_env = proto_req "/example.HaberdasherService/MakeHat", Example::Size.new
status, headers, body = svc.call(rack_env)
assert_equal 500, status
@ -326,11 +326,11 @@ class ServiceTest < Minitest::Test
end
def test_handler_returns_invalid_type_string
svc = Example::Haberdasher.new(HaberdasherHandler.new do |size, env|
svc = Example::HaberdasherService.new(HaberdasherHandler.new do |size, env|
"bad type"
end)
rack_env = proto_req "/example.Haberdasher/MakeHat", Example::Size.new
rack_env = proto_req "/example.HaberdasherService/MakeHat", Example::Size.new
status, headers, body = svc.call(rack_env)
assert_equal 500, status
@ -341,9 +341,9 @@ class ServiceTest < Minitest::Test
end
def test_handler_not_implementing_method
svc = Example::Haberdasher.new("foo")
svc = Example::HaberdasherService.new("foo")
rack_env = proto_req "/example.Haberdasher/MakeHat", Example::Size.new
rack_env = proto_req "/example.HaberdasherService/MakeHat", Example::Size.new
status, headers, body = svc.call(rack_env)
assert_equal 501, status
@ -354,12 +354,12 @@ class ServiceTest < Minitest::Test
end
def test_handler_returns_invalid_attributes
Example::Haberdasher.raise_exceptions = false
svc = Example::Haberdasher.new(HaberdasherHandler.new do |size, env|
Example::HaberdasherService.raise_exceptions = false
svc = Example::HaberdasherService.new(HaberdasherHandler.new do |size, env|
{bad_attribute: "bad value", lol: 666}
end)
rack_env = proto_req "/example.Haberdasher/MakeHat", Example::Size.new
rack_env = proto_req "/example.HaberdasherService/MakeHat", Example::Size.new
status, headers, body = svc.call(rack_env)
assert_equal 500, status
@ -371,19 +371,19 @@ class ServiceTest < Minitest::Test
end
def test_handler_raises_standard_error
svc = Example::Haberdasher.new(HaberdasherHandler.new do |size, env|
svc = Example::HaberdasherService.new(HaberdasherHandler.new do |size, env|
10 / 0 # divided by 0
end)
# check that tests can see raised errors from the handler with raise_exceptions = true
assert_raises ZeroDivisionError do
rack_env = proto_req "/example.Haberdasher/MakeHat", Example::Size.new
rack_env = proto_req "/example.HaberdasherService/MakeHat", Example::Size.new
svc.call(rack_env)
end
# check that the error is properly wrapped with raise_exceptions = false
Example::Haberdasher.raise_exceptions = false
rack_env = proto_req "/example.Haberdasher/MakeHat", Example::Size.new
Example::HaberdasherService.raise_exceptions = false
rack_env = proto_req "/example.HaberdasherService/MakeHat", Example::Size.new
status, headers, body = svc.call(rack_env)
assert_equal 500, status
@ -403,14 +403,14 @@ class ServiceTest < Minitest::Test
called_with_env = nil
called_with_rack_env = nil
svc = Example::Haberdasher.new(handler)
svc = Example::HaberdasherService.new(handler)
svc.before do |rack_env, env|
env[:raw_contet_type] = rack_env["CONTENT_TYPE"]
called_with_env = env
called_with_rack_env = rack_env
end
rack_env = json_req "/example.Haberdasher/MakeHat", inches: 10
rack_env = json_req "/example.HaberdasherService/MakeHat", inches: 10
status, headers, body = svc.call(rack_env)
refute_nil called_with_env, "the before hook was called with a Twirp env"
@ -427,7 +427,7 @@ class ServiceTest < Minitest::Test
def test_before_add_data_in_env_for_the_handler_method
val = nil
svc = Example::Haberdasher.new(HaberdasherHandler.new do |size, env|
svc = Example::HaberdasherService.new(HaberdasherHandler.new do |size, env|
val = env[:from_the_hook]
{}
end)
@ -435,7 +435,7 @@ class ServiceTest < Minitest::Test
env[:from_the_hook] = "hello handler"
end
rack_env = json_req "/example.Haberdasher/MakeHat", inches: 10
rack_env = json_req "/example.HaberdasherService/MakeHat", inches: 10
status, headers, body = svc.call(rack_env)
assert_equal 200, status
@ -444,7 +444,7 @@ class ServiceTest < Minitest::Test
def test_before_returning_twirp_error_cancels_request
handler_called = false
svc = Example::Haberdasher.new(HaberdasherHandler.new do |size, env|
svc = Example::HaberdasherService.new(HaberdasherHandler.new do |size, env|
handler_called = true
{}
end)
@ -452,7 +452,7 @@ class ServiceTest < Minitest::Test
return Twirp::Error.internal "error from before hook"
end
rack_env = json_req "/example.Haberdasher/MakeHat", inches: 10
rack_env = json_req "/example.HaberdasherService/MakeHat", inches: 10
status, headers, body = svc.call(rack_env)
assert_equal 500, status
@ -465,7 +465,7 @@ class ServiceTest < Minitest::Test
def test_before_raising_exception_cancels_request
handler_called = false
svc = Example::Haberdasher.new(HaberdasherHandler.new do |size, env|
svc = Example::HaberdasherService.new(HaberdasherHandler.new do |size, env|
handler_called = true
{}
end)
@ -473,8 +473,8 @@ class ServiceTest < Minitest::Test
1 / 0 # divided by 0.
end
Example::Haberdasher.raise_exceptions = false
rack_env = json_req "/example.Haberdasher/MakeHat", inches: 10
Example::HaberdasherService.raise_exceptions = false
rack_env = json_req "/example.HaberdasherService/MakeHat", inches: 10
status, headers, body = svc.call(rack_env)
assert_equal 500, status
@ -488,7 +488,7 @@ class ServiceTest < Minitest::Test
def test_before_multiple_run_in_order
handler_called = false
svc = Example::Haberdasher.new(HaberdasherHandler.new do |size, env|
svc = Example::HaberdasherService.new(HaberdasherHandler.new do |size, env|
handler_called = true
refute_nil env[:from_hook_1]
refute_nil env[:from_hook_2]
@ -505,7 +505,7 @@ class ServiceTest < Minitest::Test
env[:from_hook_2] = true
end
rack_env = json_req "/example.Haberdasher/MakeHat", inches: 10
rack_env = json_req "/example.HaberdasherService/MakeHat", inches: 10
status, headers, body = svc.call(rack_env)
assert_equal 200, status
@ -516,7 +516,7 @@ class ServiceTest < Minitest::Test
hook1_called = false
hook2_called = false
handler_called = false
svc = Example::Haberdasher.new(HaberdasherHandler.new do |size, env|
svc = Example::HaberdasherService.new(HaberdasherHandler.new do |size, env|
handler_called = true
{}
end)
@ -529,7 +529,7 @@ class ServiceTest < Minitest::Test
return Twirp::Error.internal "hook2 failed"
end
rack_env = json_req "/example.Haberdasher/MakeHat", inches: 10
rack_env = json_req "/example.HaberdasherService/MakeHat", inches: 10
status, headers, body = svc.call(rack_env)
assert_equal 500, status
@ -545,7 +545,7 @@ class ServiceTest < Minitest::Test
end
def test_on_success_has_env_output
svc = Example::Haberdasher.new(HaberdasherHandler.new do |input, env|
svc = Example::HaberdasherService.new(HaberdasherHandler.new do |input, env|
env[:handler_called] = true
{inches: 88, color: "blue"}
end)
@ -556,7 +556,7 @@ class ServiceTest < Minitest::Test
assert_equal Example::Hat.new(inches: 88, color: "blue"), env[:output] # output from hadnler
end
rack_env = json_req "/example.Haberdasher/MakeHat", inches: 10
rack_env = json_req "/example.HaberdasherService/MakeHat", inches: 10
status, headers, body = svc.call(rack_env)
assert_equal 200, status
@ -564,7 +564,7 @@ class ServiceTest < Minitest::Test
end
def test_on_success_does_not_trigger_error
svc = Example::Haberdasher.new(HaberdasherHandler.new do |input, env|
svc = Example::HaberdasherService.new(HaberdasherHandler.new do |input, env|
return Twirp::Error.internal "error from handler"
end)
success_called = false
@ -572,7 +572,7 @@ class ServiceTest < Minitest::Test
success_called = true
end
rack_env = json_req "/example.Haberdasher/MakeHat", inches: 10
rack_env = json_req "/example.HaberdasherService/MakeHat", inches: 10
status, headers, body = svc.call(rack_env)
assert_equal 500, status
@ -584,7 +584,7 @@ class ServiceTest < Minitest::Test
end
def test_on_success_multiple_run_in_order
svc = Example::Haberdasher.new(HaberdasherHandler.new do |size, env|
svc = Example::HaberdasherService.new(HaberdasherHandler.new do |size, env|
env[:from_handler] = true
{}
end)
@ -603,7 +603,7 @@ class ServiceTest < Minitest::Test
hook2_called = true
end
rack_env = json_req "/example.Haberdasher/MakeHat", inches: 10
rack_env = json_req "/example.HaberdasherService/MakeHat", inches: 10
status, headers, body = svc.call(rack_env)
assert_equal 200, status
@ -612,7 +612,7 @@ class ServiceTest < Minitest::Test
def test_on_success_raising_exception_is_handled_as_internal
handler_called = false
svc = Example::Haberdasher.new(HaberdasherHandler.new do |size, env|
svc = Example::HaberdasherService.new(HaberdasherHandler.new do |size, env|
handler_called = true
{}
end)
@ -620,8 +620,8 @@ class ServiceTest < Minitest::Test
1 / 0 # divided by 0
end
Example::Haberdasher.raise_exceptions = false
rack_env = json_req "/example.Haberdasher/MakeHat", inches: 10
Example::HaberdasherService.raise_exceptions = false
rack_env = json_req "/example.HaberdasherService/MakeHat", inches: 10
status, headers, body = svc.call(rack_env)
assert_equal 500, status
@ -634,7 +634,7 @@ class ServiceTest < Minitest::Test
end
def test_on_error_after_before_fails
svc = Example::Haberdasher.new(HaberdasherHandler.new do |size, env|
svc = Example::HaberdasherService.new(HaberdasherHandler.new do |size, env|
{}
end)
svc.before do |rack_env, env|
@ -647,7 +647,7 @@ class ServiceTest < Minitest::Test
assert_equal "before failed", twerr.msg
end
rack_env = json_req "/example.Haberdasher/MakeHat", inches: 10
rack_env = json_req "/example.HaberdasherService/MakeHat", inches: 10
status, headers, body = svc.call(rack_env)
assert_equal 500, status
@ -659,13 +659,13 @@ class ServiceTest < Minitest::Test
end
def test_on_error_after_before_raises_exception
svc = Example::Haberdasher.new(HaberdasherHandler.new do |size, env|
svc = Example::HaberdasherService.new(HaberdasherHandler.new do |size, env|
{}
end)
svc.before do |rack_env, env|
1 / 0 # divided by 0
end
Example::Haberdasher.raise_exceptions = false
Example::HaberdasherService.raise_exceptions = false
error_called = false
svc.on_error do |twerr, env|
@ -678,7 +678,7 @@ class ServiceTest < Minitest::Test
assert_equal "divided by 0", e.message
end
rack_env = json_req "/example.Haberdasher/MakeHat", inches: 10
rack_env = json_req "/example.HaberdasherService/MakeHat", inches: 10
status, headers, body = svc.call(rack_env)
assert_equal 500, status
@ -692,7 +692,7 @@ class ServiceTest < Minitest::Test
end
def test_on_error_after_handler_returns_twirp_error
svc = Example::Haberdasher.new(HaberdasherHandler.new do |size, env|
svc = Example::HaberdasherService.new(HaberdasherHandler.new do |size, env|
return Twirp::Error.internal "handler error"
end)
@ -703,7 +703,7 @@ class ServiceTest < Minitest::Test
assert_equal "handler error", twerr.msg
end
rack_env = json_req "/example.Haberdasher/MakeHat", inches: 10
rack_env = json_req "/example.HaberdasherService/MakeHat", inches: 10
status, headers, body = svc.call(rack_env)
assert_equal 500, status
@ -715,10 +715,10 @@ class ServiceTest < Minitest::Test
end
def test_on_error_after_handler_raises_exception
svc = Example::Haberdasher.new(HaberdasherHandler.new do |size, env|
svc = Example::HaberdasherService.new(HaberdasherHandler.new do |size, env|
1 / 0 # divided by 0
end)
Example::Haberdasher.raise_exceptions = false
Example::HaberdasherService.raise_exceptions = false
error_called = false
svc.on_error do |twerr, env|
@ -731,7 +731,7 @@ class ServiceTest < Minitest::Test
assert_equal "divided by 0", e.message
end
rack_env = json_req "/example.Haberdasher/MakeHat", inches: 10
rack_env = json_req "/example.HaberdasherService/MakeHat", inches: 10
status, headers, body = svc.call(rack_env)
assert_equal 500, status
@ -745,13 +745,13 @@ class ServiceTest < Minitest::Test
end
def test_on_error_is_not_called_after_success_raises_exception
svc = Example::Haberdasher.new(HaberdasherHandler.new do |size, env|
svc = Example::HaberdasherService.new(HaberdasherHandler.new do |size, env|
{}
end)
svc.on_success do |env|
1 / 0 # divided by 0
end
Example::Haberdasher.raise_exceptions = false
Example::HaberdasherService.raise_exceptions = false
error_called = false
svc.on_error do |twerr, env|
@ -764,7 +764,7 @@ class ServiceTest < Minitest::Test
assert_equal "divided by 0", e.message
end
rack_env = json_req "/example.Haberdasher/MakeHat", inches: 10
rack_env = json_req "/example.HaberdasherService/MakeHat", inches: 10
status, headers, body = svc.call(rack_env)
assert_equal 500, status
@ -778,7 +778,7 @@ class ServiceTest < Minitest::Test
end
def test_on_error_multiple_run_in_order
svc = Example::Haberdasher.new(HaberdasherHandler.new do |size, env|
svc = Example::HaberdasherService.new(HaberdasherHandler.new do |size, env|
env[:from_handler] = true
Twirp::Error.not_found "my friend"
end)
@ -797,7 +797,7 @@ class ServiceTest < Minitest::Test
hook2_called = true
end
rack_env = json_req "/example.Haberdasher/MakeHat", inches: 10
rack_env = json_req "/example.HaberdasherService/MakeHat", inches: 10
status, headers, body = svc.call(rack_env)
assert_equal 404, status
@ -805,20 +805,20 @@ class ServiceTest < Minitest::Test
end
def test_on_error_raising_exception_is_handled_as_internal
svc = Example::Haberdasher.new(HaberdasherHandler.new do |size, env|
svc = Example::HaberdasherService.new(HaberdasherHandler.new do |size, env|
Twirp::Error.permission_denied "blah blah"
end)
svc.on_error do |twerr, env|
1 / 0 # divided by 0
end
Example::Haberdasher.raise_exceptions = false
Example::HaberdasherService.raise_exceptions = false
exception_raised_called = false
svc.exception_raised do |e, env|
exception_raised_called = true
end
rack_env = json_req "/example.Haberdasher/MakeHat", inches: 10
rack_env = json_req "/example.HaberdasherService/MakeHat", inches: 10
status, headers, body = svc.call(rack_env)
assert_equal 500, status
@ -854,7 +854,7 @@ class ServiceTest < Minitest::Test
end
def haberdasher_service
Example::Haberdasher.new(HaberdasherHandler.new do |size, _|
Example::HaberdasherService.new(HaberdasherHandler.new do |size, _|
{inches: size.inches, color: "white"}
end)
end