protobuffy 3.1.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.
Files changed (192) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.travis.yml +12 -0
  4. data/.yardopts +5 -0
  5. data/CHANGES.md +261 -0
  6. data/CONTRIBUTING.md +16 -0
  7. data/Gemfile +3 -0
  8. data/LICENSE.txt +14 -0
  9. data/README.md +58 -0
  10. data/Rakefile +61 -0
  11. data/bin/protoc-gen-ruby +17 -0
  12. data/bin/rpc_server +4 -0
  13. data/examples/bin/reverse-client-http +4 -0
  14. data/examples/bin/reverse-client-socket +4 -0
  15. data/examples/bin/reverse-client-zmq +4 -0
  16. data/examples/config.ru +6 -0
  17. data/examples/definitions/example/reverse.proto +12 -0
  18. data/examples/lib/example/reverse-client.rb +23 -0
  19. data/examples/lib/example/reverse-service.rb +9 -0
  20. data/examples/lib/example/reverse.pb.rb +36 -0
  21. data/lib/protobuf.rb +106 -0
  22. data/lib/protobuf/cli.rb +249 -0
  23. data/lib/protobuf/code_generator.rb +41 -0
  24. data/lib/protobuf/decoder.rb +74 -0
  25. data/lib/protobuf/deprecator.rb +42 -0
  26. data/lib/protobuf/descriptors.rb +3 -0
  27. data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +52 -0
  28. data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +249 -0
  29. data/lib/protobuf/encoder.rb +62 -0
  30. data/lib/protobuf/enum.rb +319 -0
  31. data/lib/protobuf/exceptions.rb +9 -0
  32. data/lib/protobuf/field.rb +74 -0
  33. data/lib/protobuf/field/base_field.rb +280 -0
  34. data/lib/protobuf/field/bool_field.rb +53 -0
  35. data/lib/protobuf/field/bytes_field.rb +81 -0
  36. data/lib/protobuf/field/double_field.rb +26 -0
  37. data/lib/protobuf/field/enum_field.rb +57 -0
  38. data/lib/protobuf/field/field_array.rb +86 -0
  39. data/lib/protobuf/field/fixed32_field.rb +25 -0
  40. data/lib/protobuf/field/fixed64_field.rb +29 -0
  41. data/lib/protobuf/field/float_field.rb +38 -0
  42. data/lib/protobuf/field/int32_field.rb +22 -0
  43. data/lib/protobuf/field/int64_field.rb +22 -0
  44. data/lib/protobuf/field/integer_field.rb +24 -0
  45. data/lib/protobuf/field/message_field.rb +66 -0
  46. data/lib/protobuf/field/sfixed32_field.rb +28 -0
  47. data/lib/protobuf/field/sfixed64_field.rb +29 -0
  48. data/lib/protobuf/field/signed_integer_field.rb +30 -0
  49. data/lib/protobuf/field/sint32_field.rb +22 -0
  50. data/lib/protobuf/field/sint64_field.rb +22 -0
  51. data/lib/protobuf/field/string_field.rb +35 -0
  52. data/lib/protobuf/field/uint32_field.rb +22 -0
  53. data/lib/protobuf/field/uint64_field.rb +22 -0
  54. data/lib/protobuf/field/varint_field.rb +68 -0
  55. data/lib/protobuf/generators/base.rb +71 -0
  56. data/lib/protobuf/generators/enum_generator.rb +42 -0
  57. data/lib/protobuf/generators/extension_generator.rb +28 -0
  58. data/lib/protobuf/generators/field_generator.rb +132 -0
  59. data/lib/protobuf/generators/file_generator.rb +140 -0
  60. data/lib/protobuf/generators/group_generator.rb +113 -0
  61. data/lib/protobuf/generators/message_generator.rb +99 -0
  62. data/lib/protobuf/generators/printable.rb +161 -0
  63. data/lib/protobuf/generators/service_generator.rb +27 -0
  64. data/lib/protobuf/http.rb +20 -0
  65. data/lib/protobuf/lifecycle.rb +46 -0
  66. data/lib/protobuf/logger.rb +86 -0
  67. data/lib/protobuf/message.rb +182 -0
  68. data/lib/protobuf/message/fields.rb +122 -0
  69. data/lib/protobuf/message/serialization.rb +84 -0
  70. data/lib/protobuf/optionable.rb +23 -0
  71. data/lib/protobuf/rpc/buffer.rb +79 -0
  72. data/lib/protobuf/rpc/client.rb +168 -0
  73. data/lib/protobuf/rpc/connector.rb +21 -0
  74. data/lib/protobuf/rpc/connectors/base.rb +54 -0
  75. data/lib/protobuf/rpc/connectors/common.rb +172 -0
  76. data/lib/protobuf/rpc/connectors/http.rb +90 -0
  77. data/lib/protobuf/rpc/connectors/socket.rb +73 -0
  78. data/lib/protobuf/rpc/connectors/zmq.rb +205 -0
  79. data/lib/protobuf/rpc/dynamic_discovery.pb.rb +47 -0
  80. data/lib/protobuf/rpc/env.rb +58 -0
  81. data/lib/protobuf/rpc/error.rb +28 -0
  82. data/lib/protobuf/rpc/error/client_error.rb +31 -0
  83. data/lib/protobuf/rpc/error/server_error.rb +43 -0
  84. data/lib/protobuf/rpc/middleware.rb +25 -0
  85. data/lib/protobuf/rpc/middleware/exception_handler.rb +36 -0
  86. data/lib/protobuf/rpc/middleware/logger.rb +91 -0
  87. data/lib/protobuf/rpc/middleware/request_decoder.rb +83 -0
  88. data/lib/protobuf/rpc/middleware/response_encoder.rb +88 -0
  89. data/lib/protobuf/rpc/middleware/runner.rb +18 -0
  90. data/lib/protobuf/rpc/rpc.pb.rb +53 -0
  91. data/lib/protobuf/rpc/server.rb +39 -0
  92. data/lib/protobuf/rpc/servers/http/server.rb +101 -0
  93. data/lib/protobuf/rpc/servers/http_runner.rb +34 -0
  94. data/lib/protobuf/rpc/servers/socket/server.rb +113 -0
  95. data/lib/protobuf/rpc/servers/socket/worker.rb +56 -0
  96. data/lib/protobuf/rpc/servers/socket_runner.rb +34 -0
  97. data/lib/protobuf/rpc/servers/zmq/broker.rb +155 -0
  98. data/lib/protobuf/rpc/servers/zmq/server.rb +313 -0
  99. data/lib/protobuf/rpc/servers/zmq/util.rb +47 -0
  100. data/lib/protobuf/rpc/servers/zmq/worker.rb +105 -0
  101. data/lib/protobuf/rpc/servers/zmq_runner.rb +51 -0
  102. data/lib/protobuf/rpc/service.rb +179 -0
  103. data/lib/protobuf/rpc/service_directory.rb +245 -0
  104. data/lib/protobuf/rpc/service_dispatcher.rb +46 -0
  105. data/lib/protobuf/rpc/service_filters.rb +273 -0
  106. data/lib/protobuf/rpc/stat.rb +148 -0
  107. data/lib/protobuf/socket.rb +22 -0
  108. data/lib/protobuf/tasks.rb +1 -0
  109. data/lib/protobuf/tasks/compile.rake +61 -0
  110. data/lib/protobuf/version.rb +3 -0
  111. data/lib/protobuf/wire_type.rb +10 -0
  112. data/lib/protobuf/zmq.rb +21 -0
  113. data/proto/dynamic_discovery.proto +44 -0
  114. data/proto/google/protobuf/compiler/plugin.proto +147 -0
  115. data/proto/google/protobuf/descriptor.proto +620 -0
  116. data/proto/rpc.proto +62 -0
  117. data/protobuffy.gemspec +37 -0
  118. data/spec/benchmark/tasks.rb +113 -0
  119. data/spec/bin/protoc-gen-ruby_spec.rb +18 -0
  120. data/spec/data/data.bin +3 -0
  121. data/spec/data/types.bin +0 -0
  122. data/spec/encoding/all_types_spec.rb +91 -0
  123. data/spec/encoding/extreme_values_spec.rb +0 -0
  124. data/spec/functional/socket_server_spec.rb +59 -0
  125. data/spec/functional/zmq_server_spec.rb +103 -0
  126. data/spec/lib/protobuf/cli_spec.rb +267 -0
  127. data/spec/lib/protobuf/code_generator_spec.rb +60 -0
  128. data/spec/lib/protobuf/enum_spec.rb +239 -0
  129. data/spec/lib/protobuf/field/int32_field_spec.rb +7 -0
  130. data/spec/lib/protobuf/field/string_field_spec.rb +46 -0
  131. data/spec/lib/protobuf/field_spec.rb +194 -0
  132. data/spec/lib/protobuf/generators/base_spec.rb +87 -0
  133. data/spec/lib/protobuf/generators/enum_generator_spec.rb +68 -0
  134. data/spec/lib/protobuf/generators/extension_generator_spec.rb +43 -0
  135. data/spec/lib/protobuf/generators/field_generator_spec.rb +99 -0
  136. data/spec/lib/protobuf/generators/file_generator_spec.rb +29 -0
  137. data/spec/lib/protobuf/generators/message_generator_spec.rb +0 -0
  138. data/spec/lib/protobuf/generators/service_generator_spec.rb +43 -0
  139. data/spec/lib/protobuf/lifecycle_spec.rb +89 -0
  140. data/spec/lib/protobuf/logger_spec.rb +136 -0
  141. data/spec/lib/protobuf/message_spec.rb +368 -0
  142. data/spec/lib/protobuf/optionable_spec.rb +46 -0
  143. data/spec/lib/protobuf/rpc/client_spec.rb +66 -0
  144. data/spec/lib/protobuf/rpc/connector_spec.rb +26 -0
  145. data/spec/lib/protobuf/rpc/connectors/base_spec.rb +50 -0
  146. data/spec/lib/protobuf/rpc/connectors/common_spec.rb +170 -0
  147. data/spec/lib/protobuf/rpc/connectors/connector_spec.rb +13 -0
  148. data/spec/lib/protobuf/rpc/connectors/http_spec.rb +61 -0
  149. data/spec/lib/protobuf/rpc/connectors/socket_spec.rb +24 -0
  150. data/spec/lib/protobuf/rpc/connectors/zmq_spec.rb +129 -0
  151. data/spec/lib/protobuf/rpc/middleware/exception_handler_spec.rb +62 -0
  152. data/spec/lib/protobuf/rpc/middleware/logger_spec.rb +49 -0
  153. data/spec/lib/protobuf/rpc/middleware/request_decoder_spec.rb +115 -0
  154. data/spec/lib/protobuf/rpc/middleware/response_encoder_spec.rb +75 -0
  155. data/spec/lib/protobuf/rpc/servers/http/server_spec.rb +104 -0
  156. data/spec/lib/protobuf/rpc/servers/socket_server_spec.rb +38 -0
  157. data/spec/lib/protobuf/rpc/servers/zmq/server_spec.rb +41 -0
  158. data/spec/lib/protobuf/rpc/servers/zmq/util_spec.rb +55 -0
  159. data/spec/lib/protobuf/rpc/servers/zmq/worker_spec.rb +35 -0
  160. data/spec/lib/protobuf/rpc/service_directory_spec.rb +295 -0
  161. data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +52 -0
  162. data/spec/lib/protobuf/rpc/service_filters_spec.rb +484 -0
  163. data/spec/lib/protobuf/rpc/service_spec.rb +161 -0
  164. data/spec/lib/protobuf/rpc/stat_spec.rb +151 -0
  165. data/spec/lib/protobuf_spec.rb +78 -0
  166. data/spec/spec_helper.rb +57 -0
  167. data/spec/support/all.rb +7 -0
  168. data/spec/support/packed_field.rb +22 -0
  169. data/spec/support/server.rb +94 -0
  170. data/spec/support/test/all_types.data.bin +0 -0
  171. data/spec/support/test/all_types.data.txt +119 -0
  172. data/spec/support/test/defaults.pb.rb +25 -0
  173. data/spec/support/test/defaults.proto +9 -0
  174. data/spec/support/test/enum.pb.rb +59 -0
  175. data/spec/support/test/enum.proto +34 -0
  176. data/spec/support/test/extended.pb.rb +22 -0
  177. data/spec/support/test/extended.proto +10 -0
  178. data/spec/support/test/extreme_values.data.bin +0 -0
  179. data/spec/support/test/google_unittest.pb.rb +543 -0
  180. data/spec/support/test/google_unittest.proto +713 -0
  181. data/spec/support/test/google_unittest_import.pb.rb +37 -0
  182. data/spec/support/test/google_unittest_import.proto +64 -0
  183. data/spec/support/test/google_unittest_import_public.pb.rb +8 -0
  184. data/spec/support/test/google_unittest_import_public.proto +38 -0
  185. data/spec/support/test/multi_field_extensions.pb.rb +56 -0
  186. data/spec/support/test/multi_field_extensions.proto +33 -0
  187. data/spec/support/test/resource.pb.rb +117 -0
  188. data/spec/support/test/resource.proto +94 -0
  189. data/spec/support/test/resource_service.rb +26 -0
  190. data/spec/support/test_app_file.rb +2 -0
  191. data/spec/support/tolerance_matcher.rb +40 -0
  192. metadata +367 -0
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+ require 'protobuf/optionable'
3
+
4
+ describe 'Optionable' do
5
+
6
+ describe '.set_option' do
7
+ before(:all) do
8
+ OptionableSetOptionTest = ::Class.new do
9
+ include ::Protobuf::Optionable
10
+ end
11
+ end
12
+
13
+ it 'stores the given option and value' do
14
+ expect(OptionableSetOptionTest).to respond_to(:set_option)
15
+ expect(OptionableSetOptionTest.method(:set_option).arity).to eq(-2)
16
+ expect {
17
+ OptionableSetOptionTest.set_option(:foo, :bar)
18
+ }.to_not raise_error
19
+ end
20
+
21
+ it 'defaults the value to true' do
22
+ OptionableSetOptionTest.set_option(:baz_enabled)
23
+ expect(OptionableSetOptionTest.get_option(:baz_enabled)).to be_true
24
+ end
25
+ end
26
+
27
+ describe '.get_option' do
28
+ before(:all) do
29
+ OptionableGetOptionTest = ::Class.new do
30
+ include ::Protobuf::Optionable
31
+ set_option :foo, :bar
32
+ end
33
+ end
34
+
35
+ it 'retrieves the option for the given name, if any' do
36
+ expect(OptionableGetOptionTest.get_option(:foo)).to eq(:bar)
37
+ expect(OptionableGetOptionTest.get_option(:baz)).to be_nil
38
+ end
39
+
40
+ it 'retrieves the option in the context of an instance' do
41
+ expect(OptionableGetOptionTest.new.get_option(:foo)).to eq(:bar)
42
+ expect(OptionableGetOptionTest.new.get_option(:baz)).to be_nil
43
+ end
44
+ end
45
+
46
+ end
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+ require 'spec/support/test/resource_service'
3
+
4
+ describe Protobuf::Rpc::Client do
5
+ before(:each) do
6
+ load 'protobuf/socket.rb'
7
+ end
8
+
9
+ context 'when creating a client from a service' do
10
+ before { reset_service_location(Test::ResourceService) }
11
+
12
+ it 'should be able to get a client through the Service#client helper method' do
13
+ Test::ResourceService.client(:port => 9191).should eq(Protobuf::Rpc::Client.new(:service => Test::ResourceService, :port => 9191))
14
+ end
15
+
16
+ it "should be able to override a service location's host and port" do
17
+ Test::ResourceService.located_at 'somewheregreat.com:12345'
18
+ clean_client = Test::ResourceService.client
19
+ clean_client.options[:host].should eq('somewheregreat.com')
20
+ clean_client.options[:port].should eq(12345)
21
+
22
+ updated_client = Test::ResourceService.client(:host => 'amazing.com', :port => 54321)
23
+ updated_client.options[:host].should eq('amazing.com')
24
+ updated_client.options[:port].should eq(54321)
25
+ end
26
+
27
+ it 'should be able to define which service to create itself for' do
28
+ client = Protobuf::Rpc::Client.new :service => Test::ResourceService
29
+ client.options[:service].should eq(Test::ResourceService)
30
+ end
31
+
32
+ it 'should have a hard default for host and port on a service that has not been configured' do
33
+ client = Test::ResourceService.client
34
+ client.options[:host].should eq(Protobuf::Rpc::Service::DEFAULT_HOST)
35
+ client.options[:port].should eq(Protobuf::Rpc::Service::DEFAULT_PORT)
36
+ end
37
+
38
+ end
39
+
40
+ context 'when calling methods on a service client' do
41
+
42
+ # NOTE: we are assuming the service methods are accurately
43
+ # defined inside spec/proto/test_service.rb,
44
+ # namely the :find method
45
+
46
+ it 'should respond to defined service methods' do
47
+ client = Test::ResourceService.client
48
+ client.should_receive(:send_request).and_return(nil)
49
+ expect { client.find(nil) }.to_not raise_error
50
+ end
51
+ end
52
+
53
+ context 'when receiving request objects' do
54
+
55
+ it 'should be able to create the correct request object if passed a hash' do
56
+ client = Test::ResourceService.client
57
+ client.should_receive(:send_request)
58
+ client.find({:name => 'Test Name', :active => false})
59
+ client.options[:request].should be_a(Test::ResourceFindRequest)
60
+ client.options[:request].name.should eq('Test Name')
61
+ client.options[:request].active.should eq(false)
62
+ end
63
+
64
+ end
65
+
66
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+ require 'protobuf/socket'
3
+ require 'protobuf/zmq'
4
+
5
+ describe ::Protobuf::Rpc::Connector do
6
+
7
+ describe '.connector_for_client(true)' do
8
+ subject { described_class.connector_for_client }
9
+
10
+ context 'Protobuf.connector_type is socket' do
11
+ before { ::Protobuf.connector_type = :socket }
12
+ it { should eq ::Protobuf::Rpc::Connectors::Socket }
13
+ end
14
+
15
+ context 'Protobuf.connector_type is not a known value' do
16
+ before { ::Protobuf.stub(:connector_type) { :foo } }
17
+ it { should eq ::Protobuf::Rpc::Connectors::Socket }
18
+ end
19
+
20
+ context 'Protobuf.connector_type is zmq' do
21
+ before { ::Protobuf.connector_type = :zmq }
22
+ it { should eq ::Protobuf::Rpc::Connectors::Zmq }
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ describe Protobuf::Rpc::Connectors::Base do
4
+
5
+ let(:options) do
6
+ { :timeout => 60 }
7
+ end
8
+
9
+ subject { Protobuf::Rpc::Connectors::Base.new(options) }
10
+
11
+ describe "#send_request" do
12
+ it "raising an error when 'send_request' is not overridden" do
13
+ expect{ subject.send_request }.to raise_error(RuntimeError, /inherit a Connector/)
14
+ end
15
+
16
+ it "does not raise error when 'send_request' is overridden" do
17
+ new_sub = Class.new(subject.class){ def send_request; end }.new(options)
18
+ expect{ new_sub.send_request }.to_not raise_error
19
+ end
20
+ end
21
+
22
+ describe '.new' do
23
+ it 'assigns passed options and initializes success/failure callbacks' do
24
+ subject.options.should eq(Protobuf::Rpc::Connectors::DEFAULT_OPTIONS.merge(options))
25
+ subject.success_cb.should be_nil
26
+ subject.failure_cb.should be_nil
27
+ end
28
+ end
29
+
30
+ describe '#success_cb' do
31
+ it 'allows setting the success callback and calling it' do
32
+ subject.success_cb.should be_nil
33
+ cb = proc {|res| raise res }
34
+ subject.success_cb = cb
35
+ subject.success_cb.should eq(cb)
36
+ expect { subject.success_cb.call('an error from cb') }.to raise_error 'an error from cb'
37
+ end
38
+ end
39
+
40
+ describe '#failure_cb' do
41
+ it 'allows setting the failure callback and calling it' do
42
+ subject.failure_cb.should be_nil
43
+ cb = proc {|res| raise res }
44
+ subject.failure_cb = cb
45
+ subject.failure_cb.should eq(cb)
46
+ expect { subject.failure_cb.call('an error from cb') }.to raise_error 'an error from cb'
47
+ end
48
+ end
49
+
50
+ end
@@ -0,0 +1,170 @@
1
+ require 'spec_helper'
2
+ require 'protobuf/rpc/service'
3
+
4
+ describe Protobuf::Rpc::Connectors::Common do
5
+ let(:common_class) do
6
+ Class.new(Protobuf::Rpc::Connectors::Base) do
7
+ include Protobuf::Rpc::Connectors::Common
8
+ attr_accessor :options
9
+ attr_accessor :stats
10
+ end
11
+ end
12
+
13
+ let(:subject_options) { {} }
14
+
15
+ subject { @subject ||= common_class.new(subject_options) }
16
+
17
+ context "API" do
18
+ specify { subject.respond_to?(:any_callbacks?).should be_true }
19
+ specify { subject.respond_to?(:request_caller).should be_true }
20
+ specify { subject.respond_to?(:data_callback).should be_true }
21
+ specify { subject.respond_to?(:error).should be_true }
22
+ specify { subject.respond_to?(:fail).should be_true }
23
+ specify { subject.respond_to?(:complete).should be_true }
24
+ specify { subject.respond_to?(:parse_response).should be_true }
25
+ specify { subject.respond_to?(:verify_options!).should be_true }
26
+ specify { subject.respond_to?(:verify_callbacks).should be_true }
27
+ end
28
+
29
+ describe "#any_callbacks?" do
30
+
31
+ [:@complete_cb, :@success_cb, :@failure_cb].each do |cb|
32
+ it "returns true if #{cb} is provided" do
33
+ subject.instance_variable_set(cb, "something")
34
+ subject.any_callbacks?.should be_true
35
+ end
36
+ end
37
+
38
+ it "returns false when all callbacks are not provided" do
39
+ subject.instance_variable_set(:@complete_cb, nil)
40
+ subject.instance_variable_set(:@success_cb, nil)
41
+ subject.instance_variable_set(:@failure_cb, nil)
42
+
43
+ subject.any_callbacks?.should be_false
44
+ end
45
+
46
+ end
47
+
48
+ describe '#request_caller' do
49
+ its(:request_caller) { should eq ::Protobuf.client_host }
50
+
51
+ context 'when "client_host" option is given to initializer' do
52
+ let(:hostname) { 'myhost.myserver.com' }
53
+ let(:subject_options) { { :client_host => hostname } }
54
+
55
+ its(:request_caller) { should_not eq ::Protobuf.client_host }
56
+ its(:request_caller) { should eq hostname }
57
+ end
58
+ end
59
+
60
+ describe "#data_callback" do
61
+ it "changes state to use the data callback" do
62
+ subject.data_callback("data")
63
+ subject.instance_variable_get(:@used_data_callback).should be_true
64
+ end
65
+
66
+ it "sets the data var when using the data_callback" do
67
+ subject.data_callback("data")
68
+ subject.instance_variable_get(:@data).should eq("data")
69
+ end
70
+ end
71
+
72
+ describe '#request_bytes' do
73
+ let(:service) { Test::ResourceService }
74
+ let(:method) { :find }
75
+ let(:request) { '' }
76
+ let(:client_host) { 'myhost.myservice.com' }
77
+ let(:subject_options) { { :service => service,
78
+ :method => method,
79
+ :request => request,
80
+ :client_host => client_host } }
81
+
82
+ let(:expected) { ::Protobuf::Socketrpc::Request.new({ :service_name => service.name,
83
+ :method_name => 'find',
84
+ :request_proto => '',
85
+ :caller => client_host }) }
86
+
87
+ before { subject.stub(:validate_request_type!).and_return(true) }
88
+ before { subject.should_not_receive(:fail) }
89
+
90
+ its(:request_bytes) { should eq expected.encode }
91
+ end
92
+
93
+ describe "#verify_callbacks" do
94
+
95
+ it "sets @failure_cb to #data_callback when no callbacks are defined" do
96
+ subject.verify_callbacks
97
+ subject.instance_variable_get(:@failure_cb).should eq(subject.method(:data_callback))
98
+ end
99
+
100
+ it "sets @success_cb to #data_callback when no callbacks are defined" do
101
+ subject.verify_callbacks
102
+ subject.instance_variable_get(:@success_cb).should eq(subject.method(:data_callback))
103
+ end
104
+
105
+ it "doesn't set @failure_cb when already defined" do
106
+ set_cb = lambda{ true }
107
+ subject.instance_variable_set(:@failure_cb, set_cb)
108
+ subject.verify_callbacks
109
+ subject.instance_variable_get(:@failure_cb).should eq(set_cb)
110
+ subject.instance_variable_get(:@failure_cb).should_not eq(subject.method(:data_callback))
111
+ end
112
+
113
+ it "doesn't set @success_cb when already defined" do
114
+ set_cb = lambda{ true }
115
+ subject.instance_variable_set(:@success_cb, set_cb)
116
+ subject.verify_callbacks
117
+ subject.instance_variable_get(:@success_cb).should eq(set_cb)
118
+ subject.instance_variable_get(:@success_cb).should_not eq(subject.method(:data_callback))
119
+ end
120
+
121
+ end
122
+
123
+ shared_examples "a ConnectorDisposition" do |meth, cb, *args|
124
+
125
+ it "calls #complete before exit" do
126
+ stats = double("Object")
127
+ stats.stub(:success) { true }
128
+ stats.stub(:failure) { true }
129
+ stats.stub(:stop) { true }
130
+ subject.stats = stats
131
+
132
+ subject.should_receive(:complete)
133
+ subject.method(meth).call(*args)
134
+ end
135
+
136
+ it "calls the #{cb} callback when provided" do
137
+ stats = double("Object")
138
+ stats.stub(:success) { true }
139
+ stats.stub(:failure) { true }
140
+ stats.stub(:stop) { true }
141
+ subject.stats = stats
142
+ _cb = double("Object")
143
+
144
+ subject.instance_variable_set("@#{cb}", _cb)
145
+ _cb.should_receive(:call).and_return(true)
146
+ subject.method(meth).call(*args)
147
+ end
148
+
149
+ it "calls the complete callback when provided" do
150
+ stats = double("Object")
151
+ stats.stub(:success) { true }
152
+ stats.stub(:failure) { true }
153
+ stats.stub(:stop) { true }
154
+ subject.stats = stats
155
+ comp_cb = double("Object")
156
+
157
+ subject.instance_variable_set(:@complete_cb, comp_cb)
158
+ comp_cb.should_receive(:call).and_return(true)
159
+ subject.method(meth).call(*args)
160
+ end
161
+
162
+ end
163
+
164
+ it_behaves_like("a ConnectorDisposition", :fail, "failure_cb", "code", "message")
165
+ it_behaves_like("a ConnectorDisposition", :fail, "complete_cb", "code", "message")
166
+ it_behaves_like("a ConnectorDisposition", :succeed, "complete_cb", "response")
167
+ it_behaves_like("a ConnectorDisposition", :succeed, "success_cb", "response")
168
+ it_behaves_like("a ConnectorDisposition", :complete, "complete_cb")
169
+
170
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples "a Protobuf Connector" do
4
+ subject{ described_class.new({}) }
5
+
6
+ context "API" do
7
+ # Check the API
8
+ specify{ subject.respond_to?(:send_request, true).should be_true }
9
+ specify{ subject.respond_to?(:post_init, true).should be_true }
10
+ specify{ subject.respond_to?(:close_connection, true).should be_true }
11
+ specify{ subject.respond_to?(:error?, true).should be_true }
12
+ end
13
+ end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+ require 'protobuf/http'
3
+ require 'faraday'
4
+
5
+ describe ::Protobuf::Rpc::Connectors::Http do
6
+ subject { described_class.new({}) }
7
+
8
+ it_behaves_like "a Protobuf Connector"
9
+
10
+ specify{ described_class.include?(Protobuf::Rpc::Connectors::Common).should be_true }
11
+
12
+ let(:client_double) do
13
+ Faraday.new do |builder|
14
+ builder.adapter :test do |stub|
15
+ stub.post("/Foo/UserService/find") {[ 200, {}, "\n\n\n\x03foo\x12\x03bar" ]}
16
+ stub.post("/Foo/UserService/foo1") {[ 404, {
17
+ 'x-protobuf-error' => "Foo::UserService#foo1 is not a defined RPC method.",
18
+ 'x-protobuf-error-reason' => Protobuf::Socketrpc::ErrorReason::METHOD_NOT_FOUND.to_s
19
+ }, "" ]}
20
+ stub.post("/Foo/UserService/foo2") {[ 500, {}, "" ]}
21
+ stub.post("/base/Foo/UserService/foo3") {[ 200, {}, "\n\n\n\x03foo\x12\x03bar" ]}
22
+ end
23
+ end
24
+ end
25
+
26
+ describe "#send_data" do
27
+ before do
28
+ subject.stub(:client) { client_double }
29
+ subject.stub(:parse_response) {}
30
+ end
31
+
32
+ it "handles RPC success correctly" do
33
+ subject.stub(:request_bytes) { "\n\x10Foo::UserService\x12\x04find\x1A\r\n\vfoo@bar.com\"\rabcdefghijklm" }
34
+ subject.send(:setup_connection)
35
+ subject.send(:send_data)
36
+ subject.instance_variable_get(:@response_data).should eq "\n\f\n\n\n\x03foo\x12\x03bar"
37
+ end
38
+
39
+ it "handles RPC error correctly" do
40
+ subject.stub(:request_bytes) { "\n\x10Foo::UserService\x12\x04foo1\x1A\r\n\vfoo@bar.com\"\rabcdefghijklm" }
41
+ subject.send(:setup_connection)
42
+ subject.send(:send_data)
43
+ subject.instance_variable_get(:@response_data).should eq "\n\x00\x122Foo::UserService#foo1 is not a defined RPC method. \x03"
44
+ end
45
+
46
+ it "handles server error correctly" do
47
+ subject.stub(:request_bytes) { "\n\x10Foo::UserService\x12\x04foo2\x1A\r\n\vfoo@bar.com\"\rabcdefghijklm" }
48
+ subject.send(:setup_connection)
49
+ subject.send(:send_data)
50
+ subject.instance_variable_get(:@response_data).should eq "\n\x00\x12\x1DBad response from the server. \x07"
51
+ end
52
+
53
+ it "prepends base path option correctly" do
54
+ subject.stub(:options) { { :base => "/base" }}
55
+ subject.stub(:request_bytes) { "\n\x10Foo::UserService\x12\x04foo3\x1A\r\n\vfoo@bar.com\"\rabcdefghijklm" }
56
+ subject.send(:setup_connection)
57
+ subject.send(:send_data)
58
+ subject.instance_variable_get(:@response_data).should eq "\n\f\n\n\n\x03foo\x12\x03bar"
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+ require 'protobuf/socket'
3
+
4
+ describe Protobuf::Rpc::Connectors::Socket do
5
+ subject{ described_class.new({}) }
6
+
7
+ it_behaves_like "a Protobuf Connector"
8
+
9
+ specify{ described_class.include?(Protobuf::Rpc::Connectors::Common).should be_true }
10
+
11
+ context "#read_response" do
12
+ let(:data){ "New data" }
13
+
14
+ it "fills the buffer with data from the socket" do
15
+ socket = StringIO.new("#{data.bytesize}-#{data}")
16
+ subject.instance_variable_set(:@socket, socket)
17
+ subject.instance_variable_set(:@stats, OpenStruct.new)
18
+ subject.should_receive(:parse_response).and_return(true)
19
+
20
+ subject.__send__(:read_response)
21
+ subject.instance_variable_get(:@response_data).should eq(data)
22
+ end
23
+ end
24
+ end