twirp 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -29,7 +29,11 @@ module Example
29
29
  class Haberdasher < Twirp::Service
30
30
  package "example"
31
31
  service "Haberdasher"
32
- rpc :MakeHat, Size, Hat, :handler_method => :make_hat
32
+ rpc :MakeHat, Size, Hat, :ruby_method => :make_hat
33
+ end
34
+
35
+ class HaberdasherClient < Twirp::Client
36
+ client_for Haberdasher
33
37
  end
34
38
  end
35
39
 
@@ -48,3 +52,19 @@ end
48
52
  # Twirp Service with no package and no rpc methods.
49
53
  class EmptyService < Twirp::Service
50
54
  end
55
+ class EmptyClient < Twirp::Client
56
+ end
57
+
58
+ # Foo message
59
+ Google::Protobuf::DescriptorPool.generated_pool.build do
60
+ add_message "Foo" do
61
+ optional :foo, :string, 1
62
+ end
63
+ end
64
+ Foo = Google::Protobuf::DescriptorPool.generated_pool.lookup("Foo").msgclass
65
+
66
+ # Foo Client
67
+ class FooClient < Twirp::Client
68
+ service "Foo"
69
+ rpc :Foo, Foo, Foo, :ruby_method => :foo
70
+ end
@@ -13,14 +13,14 @@ class ServiceTest < Minitest::Test
13
13
  end
14
14
 
15
15
  # The rpc DSL should properly build the base Twirp environment for each rpc method.
16
- def test_base_envs_accessor
17
- assert_equal 1, Example::Haberdasher.base_envs.size
16
+ def test_rpcs_accessor
17
+ assert_equal 1, Example::Haberdasher.rpcs.size
18
18
  assert_equal({
19
19
  rpc_method: :MakeHat,
20
20
  input_class: Example::Size,
21
21
  output_class: Example::Hat,
22
- handler_method: :make_hat,
23
- }, Example::Haberdasher.base_envs["MakeHat"])
22
+ ruby_method: :make_hat,
23
+ }, Example::Haberdasher.rpcs["MakeHat"])
24
24
  end
25
25
 
26
26
  # DSL package and service define the proper data on the service
@@ -33,7 +33,7 @@ class ServiceTest < Minitest::Test
33
33
  assert_equal "EmptyService", EmptyService.service_name # defaults to class name
34
34
  assert_equal "EmptyService", EmptyService.service_full_name # with no package is just the service name
35
35
  end
36
-
36
+
37
37
  def test_init_service
38
38
  svc = Example::Haberdasher.new(HaberdasherHandler.new)
39
39
  assert svc.respond_to?(:call) # so it is a Proc that can be used as Rack middleware
@@ -71,35 +71,35 @@ class ServiceTest < Minitest::Test
71
71
  assert_equal 404, status
72
72
  assert_equal 'application/json', headers['Content-Type']
73
73
  assert_equal({
74
- "code" => 'bad_route',
74
+ "code" => 'bad_route',
75
75
  "msg" => 'Invalid rpc method "MakeUnicorns"',
76
76
  "meta" => {"twirp_invalid_route" => "POST /twirp/example.Haberdasher/MakeUnicorns"},
77
- }, JSON.parse(body[0]))
77
+ }, JSON.parse(body[0]))
78
78
  end
79
79
 
80
80
  def test_bad_route_with_wrong_http_method
81
- rack_env = Rack::MockRequest.env_for "example.Haberdasher/MakeHat",
81
+ rack_env = Rack::MockRequest.env_for "example.Haberdasher/MakeHat",
82
82
  method: "GET", input: '{"inches": 10}', "CONTENT_TYPE" => "application/json"
83
83
  status, headers, body = haberdasher_service.call(rack_env)
84
84
 
85
85
  assert_equal 404, status
86
86
  assert_equal 'application/json', headers['Content-Type']
87
87
  assert_equal({
88
- "code" => 'bad_route',
88
+ "code" => 'bad_route',
89
89
  "msg" => 'HTTP request method must be POST',
90
90
  "meta" => {"twirp_invalid_route" => "GET /example.Haberdasher/MakeHat"},
91
91
  }, JSON.parse(body[0]))
92
92
  end
93
93
 
94
94
  def test_bad_route_with_wrong_content_type
95
- rack_env = Rack::MockRequest.env_for "example.Haberdasher/MakeHat",
95
+ rack_env = Rack::MockRequest.env_for "example.Haberdasher/MakeHat",
96
96
  method: "POST", input: 'free text', "CONTENT_TYPE" => "text/plain"
97
97
  status, headers, body = haberdasher_service.call(rack_env)
98
98
 
99
99
  assert_equal 404, status
100
100
  assert_equal 'application/json', headers['Content-Type']
101
101
  assert_equal({
102
- "code" => 'bad_route',
102
+ "code" => 'bad_route',
103
103
  "msg" => 'unexpected Content-Type: "text/plain". Content-Type header must be one of application/json or application/protobuf',
104
104
  "meta" => {"twirp_invalid_route" => "POST /example.Haberdasher/MakeHat"},
105
105
  }, JSON.parse(body[0]))
@@ -112,7 +112,7 @@ class ServiceTest < Minitest::Test
112
112
  assert_equal 404, status
113
113
  assert_equal 'application/json', headers['Content-Type']
114
114
  assert_equal({
115
- "code" => 'bad_route',
115
+ "code" => 'bad_route',
116
116
  "msg" => 'Invalid route. Expected format: POST {BaseURL}/example.Haberdasher/{Method}',
117
117
  "meta" => {"twirp_invalid_route" => "POST /wrongpath"},
118
118
  }, JSON.parse(body[0]))
@@ -125,35 +125,35 @@ class ServiceTest < Minitest::Test
125
125
  assert_equal 404, status
126
126
  assert_equal 'application/json', headers['Content-Type'] # error responses are always JSON, even for Protobuf requests
127
127
  assert_equal({
128
- "code" => 'bad_route',
128
+ "code" => 'bad_route',
129
129
  "msg" => 'Invalid route. Expected format: POST {BaseURL}/example.Haberdasher/{Method}',
130
130
  "meta" => {"twirp_invalid_route" => "POST /another/wrong.Path/MakeHat"},
131
131
  }, JSON.parse(body[0]))
132
132
  end
133
133
 
134
134
  def test_bad_route_with_wrong_json_body
135
- rack_env = Rack::MockRequest.env_for "example.Haberdasher/MakeHat",
135
+ rack_env = Rack::MockRequest.env_for "example.Haberdasher/MakeHat",
136
136
  method: "POST", input: 'bad json', "CONTENT_TYPE" => "application/json"
137
137
  status, headers, body = haberdasher_service.call(rack_env)
138
138
 
139
139
  assert_equal 404, status
140
140
  assert_equal 'application/json', headers['Content-Type']
141
141
  assert_equal({
142
- "code" => 'bad_route',
142
+ "code" => 'bad_route',
143
143
  "msg" => 'Invalid request body for rpc method "MakeHat" with Content-Type=application/json',
144
144
  "meta" => {"twirp_invalid_route" => "POST /example.Haberdasher/MakeHat"},
145
145
  }, JSON.parse(body[0]))
146
146
  end
147
147
 
148
148
  def test_bad_route_with_wrong_protobuf_body
149
- rack_env = Rack::MockRequest.env_for "example.Haberdasher/MakeHat",
149
+ rack_env = Rack::MockRequest.env_for "example.Haberdasher/MakeHat",
150
150
  method: "POST", input: 'bad protobuf', "CONTENT_TYPE" => "application/protobuf"
151
151
  status, headers, body = haberdasher_service.call(rack_env)
152
152
 
153
153
  assert_equal 404, status
154
154
  assert_equal 'application/json', headers['Content-Type']
155
155
  assert_equal({
156
- "code" => 'bad_route',
156
+ "code" => 'bad_route',
157
157
  "msg" => 'Invalid request body for rpc method "MakeHat" with Content-Type=application/protobuf',
158
158
  "meta" => {"twirp_invalid_route" => "POST /example.Haberdasher/MakeHat"},
159
159
  }, JSON.parse(body[0]))
@@ -230,7 +230,7 @@ class ServiceTest < Minitest::Test
230
230
  assert_equal 400, status
231
231
  assert_equal 'application/json', headers['Content-Type'] # error responses are always JSON, even for Protobuf requests
232
232
  assert_equal({
233
- "code" => 'invalid_argument',
233
+ "code" => 'invalid_argument',
234
234
  "msg" => "I don't like that size",
235
235
  }, JSON.parse(body[0]))
236
236
  end
@@ -243,7 +243,7 @@ class ServiceTest < Minitest::Test
243
243
 
244
244
  rack_env = proto_req "/example.Haberdasher/MakeHat", Example::Size.new
245
245
  status, headers, body = svc.call(rack_env)
246
-
246
+
247
247
  assert_equal 200, status
248
248
  assert_equal "public, max-age=60", headers["Cache-Control"] # set by the handler
249
249
  assert_equal "application/protobuf", headers["Content-Type"] # set by Twirp::Service
@@ -397,7 +397,7 @@ class ServiceTest < Minitest::Test
397
397
  assert_equal 500, status
398
398
  refute handler_called
399
399
  assert_equal({
400
- "code" => 'intenal',
400
+ "code" => 'intenal',
401
401
  "msg" => 'error from before hook',
402
402
  }, JSON.parse(body[0]))
403
403
  end
@@ -474,7 +474,7 @@ class ServiceTest < Minitest::Test
474
474
  assert_equal 500, status
475
475
  assert_equal 'application/json', headers['Content-Type']
476
476
  assert_equal({
477
- "code" => 'intenal',
477
+ "code" => 'intenal',
478
478
  "msg" => 'hook1 failed',
479
479
  }, JSON.parse(body[0]))
480
480
 
@@ -517,7 +517,7 @@ class ServiceTest < Minitest::Test
517
517
  assert_equal 500, status
518
518
  refute success_called # after hook not called
519
519
  assert_equal({
520
- "code" => 'intenal',
520
+ "code" => 'intenal',
521
521
  "msg" => 'error from handler',
522
522
  }, JSON.parse(body[0]))
523
523
  end
@@ -591,7 +591,7 @@ class ServiceTest < Minitest::Test
591
591
 
592
592
  assert_equal 500, status
593
593
  assert_equal({
594
- "code" => 'intenal',
594
+ "code" => 'intenal',
595
595
  "msg" => 'before failed',
596
596
  }, JSON.parse(body[0]))
597
597
  assert error_called
@@ -634,7 +634,7 @@ class ServiceTest < Minitest::Test
634
634
  svc = Example::Haberdasher.new(HaberdasherHandler.new do |size, env|
635
635
  return Twirp::Error.internal "handler error"
636
636
  end)
637
-
637
+
638
638
  error_called = false
639
639
  svc.on_error do |twerr, env|
640
640
  error_called = true
@@ -647,7 +647,7 @@ class ServiceTest < Minitest::Test
647
647
 
648
648
  assert_equal 500, status
649
649
  assert_equal({
650
- "code" => 'intenal',
650
+ "code" => 'intenal',
651
651
  "msg" => 'handler error',
652
652
  }, JSON.parse(body[0]))
653
653
  assert error_called
@@ -771,18 +771,17 @@ class ServiceTest < Minitest::Test
771
771
 
772
772
 
773
773
 
774
-
775
774
  # Test Helpers
776
775
  # ------------
777
776
 
778
777
  def json_req(path, attrs)
779
- Rack::MockRequest.env_for path, method: "POST",
778
+ Rack::MockRequest.env_for path, method: "POST",
780
779
  input: JSON.generate(attrs),
781
780
  "CONTENT_TYPE" => "application/json"
782
781
  end
783
782
 
784
783
  def proto_req(path, proto_message)
785
- Rack::MockRequest.env_for path, method: "POST",
784
+ Rack::MockRequest.env_for path, method: "POST",
786
785
  input: proto_message.class.encode(proto_message),
787
786
  "CONTENT_TYPE" => "application/protobuf"
788
787
  end
@@ -10,16 +10,16 @@ Gem::Specification.new do |spec|
10
10
  spec.authors = ["Cyrus A. Forbes", "Mario Izquierdo"]
11
11
  spec.email = ["forbescyrus@gmail.com", "tothemario@gmail.com"]
12
12
  spec.summary = %q{Twirp services in Ruby.}
13
- spec.description = %q{Twirp is a simple RPC framework with protobuf service definitions. The Twirp gem provides support for Ruby.}
13
+ spec.description = %q{Twirp is a simple RPC framework with protobuf service definitions. The Twirp gem provides native support for Ruby.}
14
14
  spec.homepage = "https://github.com/cyrusaf/ruby-twirp"
15
15
  spec.license = "MIT"
16
16
 
17
- spec.files = `git ls-files -z`.split("\x0")
18
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
+ spec.files = Dir['lib/**/*'] + %w(Gemfile LICENSE README.md twirp.gemspec)
18
+ spec.test_files = Dir['test/**/*']
20
19
  spec.require_paths = ["lib"]
21
20
 
22
- spec.add_runtime_dependency 'google-protobuf', '>= 3.0.0'
21
+ spec.add_runtime_dependency 'google-protobuf', '~> 3.0', '>= 3.0.0'
22
+ spec.add_runtime_dependency 'faraday', '~> 0'
23
23
 
24
- spec.add_development_dependency 'bundler', '>= 1'
24
+ spec.add_development_dependency 'bundler', '~> 1'
25
25
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twirp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cyrus A. Forbes
@@ -9,12 +9,15 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-03-12 00:00:00.000000000 Z
12
+ date: 2018-04-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: google-protobuf
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '3.0'
18
21
  - - ">="
19
22
  - !ruby/object:Gem::Version
20
23
  version: 3.0.0
@@ -22,25 +25,42 @@ dependencies:
22
25
  prerelease: false
23
26
  version_requirements: !ruby/object:Gem::Requirement
24
27
  requirements:
28
+ - - "~>"
29
+ - !ruby/object:Gem::Version
30
+ version: '3.0'
25
31
  - - ">="
26
32
  - !ruby/object:Gem::Version
27
33
  version: 3.0.0
34
+ - !ruby/object:Gem::Dependency
35
+ name: faraday
36
+ requirement: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ type: :runtime
42
+ prerelease: false
43
+ version_requirements: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
28
48
  - !ruby/object:Gem::Dependency
29
49
  name: bundler
30
50
  requirement: !ruby/object:Gem::Requirement
31
51
  requirements:
32
- - - ">="
52
+ - - "~>"
33
53
  - !ruby/object:Gem::Version
34
54
  version: '1'
35
55
  type: :development
36
56
  prerelease: false
37
57
  version_requirements: !ruby/object:Gem::Requirement
38
58
  requirements:
39
- - - ">="
59
+ - - "~>"
40
60
  - !ruby/object:Gem::Version
41
61
  version: '1'
42
62
  description: Twirp is a simple RPC framework with protobuf service definitions. The
43
- Twirp gem provides support for Ruby.
63
+ Twirp gem provides native support for Ruby.
44
64
  email:
45
65
  - forbescyrus@gmail.com
46
66
  - tothemario@gmail.com
@@ -48,22 +68,16 @@ executables: []
48
68
  extensions: []
49
69
  extra_rdoc_files: []
50
70
  files:
51
- - ".gitignore"
52
71
  - Gemfile
53
- - Gemfile.lock
54
72
  - LICENSE
55
73
  - README.md
56
- - example/Gemfile
57
- - example/Gemfile.lock
58
- - example/gen/haberdasher_pb.rb
59
- - example/gen/haberdasher_twirp.rb
60
- - example/haberdasher.proto
61
- - example/main.rb
62
74
  - lib/twirp.rb
75
+ - lib/twirp/client.rb
63
76
  - lib/twirp/error.rb
64
77
  - lib/twirp/service.rb
78
+ - lib/twirp/service_dsl.rb
65
79
  - lib/twirp/version.rb
66
- - protoc-gen-twirp_ruby/main.go
80
+ - test/client_test.rb
67
81
  - test/error_test.rb
68
82
  - test/fake_services.rb
69
83
  - test/service_test.rb
@@ -88,11 +102,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
88
102
  version: '0'
89
103
  requirements: []
90
104
  rubyforge_project:
91
- rubygems_version: 2.6.14
105
+ rubygems_version: 2.6.8
92
106
  signing_key:
93
107
  specification_version: 4
94
108
  summary: Twirp services in Ruby.
95
109
  test_files:
110
+ - test/client_test.rb
96
111
  - test/error_test.rb
97
112
  - test/fake_services.rb
98
113
  - test/service_test.rb
data/.gitignore DELETED
@@ -1 +0,0 @@
1
- *.gem
@@ -1,20 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- twirp (0.0.1)
5
- google-protobuf (>= 3.0.0)
6
-
7
- GEM
8
- remote: https://rubygems.org/
9
- specs:
10
- google-protobuf (3.5.1.2)
11
-
12
- PLATFORMS
13
- ruby
14
-
15
- DEPENDENCIES
16
- bundler (>= 1)
17
- twirp!
18
-
19
- BUNDLED WITH
20
- 1.14.6
@@ -1,7 +0,0 @@
1
-
2
- source "https://rubygems.org"
3
-
4
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
5
-
6
- gem "twirp"
7
- gem "rack"
@@ -1,17 +0,0 @@
1
- GEM
2
- remote: https://rubygems.org/
3
- specs:
4
- google-protobuf (3.5.1.2)
5
- rack (2.0.1)
6
- twirp (0.0.1)
7
- google-protobuf (>= 3.0.0)
8
-
9
- PLATFORMS
10
- ruby
11
-
12
- DEPENDENCIES
13
- rack
14
- twirp
15
-
16
- BUNDLED WITH
17
- 1.16.1
@@ -1,18 +0,0 @@
1
- # Generated by the protocol buffer compiler. DO NOT EDIT!
2
- # source: haberdasher.proto
3
-
4
- require 'google/protobuf'
5
-
6
- Google::Protobuf::DescriptorPool.generated_pool.build do
7
- add_message "example.HelloWorldRequest" do
8
- optional :name, :string, 1
9
- end
10
- add_message "example.HelloWorldResponse" do
11
- optional :message, :string, 1
12
- end
13
- end
14
-
15
- module Example
16
- HelloWorldRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("example.HelloWorldRequest").msgclass
17
- HelloWorldResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("example.HelloWorldResponse").msgclass
18
- end
@@ -1,10 +0,0 @@
1
- # Code generated by protoc-gen-twirp_ruby, DO NOT EDIT.
2
- require 'twirp'
3
-
4
- module Example
5
- class HaberdasherService < Twirp::Service
6
- package "example"
7
- service "Haberdasher"
8
- rpc :HelloWorld, HelloWorldRequest, HelloWorldResponse, :handler_method => :hello_world
9
- end
10
- end