protobuf 2.8.13 → 3.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +84 -5
  3. data/CONTRIBUTING.md +3 -3
  4. data/Rakefile +46 -7
  5. data/lib/protobuf/cli.rb +2 -20
  6. data/lib/protobuf/decoder.rb +74 -0
  7. data/lib/protobuf/deprecator.rb +42 -0
  8. data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +17 -16
  9. data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +86 -85
  10. data/lib/protobuf/encoder.rb +62 -0
  11. data/lib/protobuf/enum.rb +298 -37
  12. data/lib/protobuf/field/base_field.rb +41 -27
  13. data/lib/protobuf/field/bool_field.rb +22 -4
  14. data/lib/protobuf/field/bytes_field.rb +36 -15
  15. data/lib/protobuf/field/double_field.rb +10 -3
  16. data/lib/protobuf/field/enum_field.rb +21 -18
  17. data/lib/protobuf/field/field_array.rb +26 -16
  18. data/lib/protobuf/field/fixed32_field.rb +10 -4
  19. data/lib/protobuf/field/fixed64_field.rb +10 -3
  20. data/lib/protobuf/field/float_field.rb +18 -5
  21. data/lib/protobuf/field/int32_field.rb +14 -4
  22. data/lib/protobuf/field/int64_field.rb +14 -4
  23. data/lib/protobuf/field/integer_field.rb +9 -4
  24. data/lib/protobuf/field/message_field.rb +16 -7
  25. data/lib/protobuf/field/sfixed32_field.rb +10 -3
  26. data/lib/protobuf/field/sfixed64_field.rb +12 -7
  27. data/lib/protobuf/field/signed_integer_field.rb +7 -0
  28. data/lib/protobuf/field/sint32_field.rb +14 -4
  29. data/lib/protobuf/field/sint64_field.rb +14 -4
  30. data/lib/protobuf/field/string_field.rb +11 -1
  31. data/lib/protobuf/field/uint32_field.rb +14 -4
  32. data/lib/protobuf/field/uint64_field.rb +14 -4
  33. data/lib/protobuf/field/varint_field.rb +11 -9
  34. data/lib/protobuf/field.rb +42 -25
  35. data/lib/protobuf/generators/enum_generator.rb +12 -1
  36. data/lib/protobuf/generators/field_generator.rb +1 -1
  37. data/lib/protobuf/lifecycle.rb +3 -4
  38. data/lib/protobuf/message/fields.rb +122 -0
  39. data/lib/protobuf/message/serialization.rb +84 -0
  40. data/lib/protobuf/message.rb +21 -221
  41. data/lib/protobuf/optionable.rb +23 -0
  42. data/lib/protobuf/rpc/client.rb +2 -4
  43. data/lib/protobuf/rpc/connector.rb +0 -2
  44. data/lib/protobuf/rpc/connectors/common.rb +2 -2
  45. data/lib/protobuf/rpc/dynamic_discovery.pb.rb +14 -16
  46. data/lib/protobuf/rpc/env.rb +58 -0
  47. data/lib/protobuf/rpc/error.rb +8 -5
  48. data/lib/protobuf/rpc/middleware/exception_handler.rb +36 -0
  49. data/lib/protobuf/rpc/middleware/logger.rb +91 -0
  50. data/lib/protobuf/rpc/middleware/request_decoder.rb +83 -0
  51. data/lib/protobuf/rpc/middleware/response_encoder.rb +88 -0
  52. data/lib/protobuf/rpc/middleware/runner.rb +18 -0
  53. data/lib/protobuf/rpc/middleware.rb +25 -0
  54. data/lib/protobuf/rpc/rpc.pb.rb +15 -16
  55. data/lib/protobuf/rpc/server.rb +14 -64
  56. data/lib/protobuf/rpc/servers/socket/server.rb +0 -2
  57. data/lib/protobuf/rpc/servers/socket/worker.rb +11 -15
  58. data/lib/protobuf/rpc/servers/zmq/util.rb +4 -1
  59. data/lib/protobuf/rpc/servers/zmq/worker.rb +5 -13
  60. data/lib/protobuf/rpc/servers/zmq_runner.rb +1 -1
  61. data/lib/protobuf/rpc/service.rb +38 -72
  62. data/lib/protobuf/rpc/service_dispatcher.rb +20 -108
  63. data/lib/protobuf/version.rb +1 -2
  64. data/lib/protobuf.rb +5 -13
  65. data/protobuf.gemspec +5 -5
  66. data/spec/benchmark/tasks.rb +2 -77
  67. data/spec/functional/zmq_server_spec.rb +13 -21
  68. data/spec/lib/protobuf/cli_spec.rb +5 -43
  69. data/spec/lib/protobuf/enum_spec.rb +194 -61
  70. data/spec/lib/protobuf/field_spec.rb +194 -0
  71. data/spec/lib/protobuf/generators/enum_generator_spec.rb +24 -1
  72. data/spec/lib/protobuf/generators/field_generator_spec.rb +6 -6
  73. data/spec/lib/protobuf/message_spec.rb +52 -70
  74. data/spec/lib/protobuf/optionable_spec.rb +46 -0
  75. data/spec/lib/protobuf/rpc/client_spec.rb +1 -93
  76. data/spec/lib/protobuf/rpc/connector_spec.rb +1 -7
  77. data/spec/lib/protobuf/rpc/connectors/zmq_spec.rb +8 -0
  78. data/spec/lib/protobuf/rpc/middleware/exception_handler_spec.rb +62 -0
  79. data/spec/lib/protobuf/rpc/middleware/logger_spec.rb +49 -0
  80. data/spec/lib/protobuf/rpc/middleware/request_decoder_spec.rb +115 -0
  81. data/spec/lib/protobuf/rpc/middleware/response_encoder_spec.rb +75 -0
  82. data/spec/lib/protobuf/rpc/servers/socket_server_spec.rb +0 -6
  83. data/spec/lib/protobuf/rpc/servers/zmq/util_spec.rb +10 -0
  84. data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +30 -105
  85. data/spec/lib/protobuf/rpc/service_filters_spec.rb +4 -4
  86. data/spec/lib/protobuf/rpc/service_spec.rb +20 -24
  87. data/spec/lib/protobuf_spec.rb +3 -3
  88. data/spec/spec_helper.rb +5 -4
  89. data/spec/support/packed_field.rb +15 -14
  90. data/spec/support/server.rb +4 -21
  91. data/spec/support/test/defaults.pb.rb +4 -4
  92. data/spec/support/test/enum.pb.rb +13 -1
  93. data/spec/support/test/enum.proto +15 -0
  94. data/spec/support/test/extended.pb.rb +1 -1
  95. data/spec/support/test/google_unittest.pb.rb +239 -241
  96. data/spec/support/test/google_unittest_import.pb.rb +2 -2
  97. data/spec/support/test/multi_field_extensions.pb.rb +2 -2
  98. data/spec/support/test/resource.pb.rb +19 -18
  99. data/spec/support/test/resource.proto +1 -0
  100. data/spec/support/test/resource_service.rb +5 -0
  101. metadata +78 -57
  102. data/bin/rprotoc +0 -8
  103. data/lib/protobuf/enum_value.rb +0 -85
  104. data/lib/protobuf/evented.rb +0 -37
  105. data/lib/protobuf/ext/eventmachine.rb +0 -14
  106. data/lib/protobuf/field/extension_fields.rb +0 -32
  107. data/lib/protobuf/message/decoder.rb +0 -72
  108. data/lib/protobuf/message/message.rb +0 -1
  109. data/lib/protobuf/rpc/connectors/em_client.rb +0 -84
  110. data/lib/protobuf/rpc/connectors/eventmachine.rb +0 -87
  111. data/lib/protobuf/rpc/servers/evented/server.rb +0 -36
  112. data/lib/protobuf/rpc/servers/evented_runner.rb +0 -31
  113. data/spec/functional/embedded_service_spec.rb +0 -7
  114. data/spec/functional/evented_server_spec.rb +0 -64
  115. data/spec/lib/protobuf/enum_value_spec.rb +0 -29
  116. data/spec/lib/protobuf/rpc/servers/evented_server_spec.rb +0 -19
@@ -1,4 +1,5 @@
1
1
  require 'benchmark'
2
+ require 'protobuf/socket'
2
3
  require 'support/all'
3
4
  require 'support/test/resource_service'
4
5
 
@@ -28,43 +29,8 @@ namespace :benchmark do
28
29
  end
29
30
  end
30
31
 
31
- def em_client_em_server(number_tests, test_length, global_bench = nil)
32
- EM.stop if EM.reactor_running?
33
-
34
- EventMachine.fiber_run do
35
- StubServer.new(:server => Protobuf::Rpc::Evented::Server) do |server|
36
- benchmark_wrapper(global_bench) do |bench|
37
- bench.report("ES / EC") do
38
- (1..number_tests.to_i).each { client.find(:name => "Test Name" * test_length.to_i, :active => true) }
39
- end
40
- end
41
- end
42
-
43
- EM.stop
44
- end
45
- end
46
-
47
- def em_client_sock_server(number_tests, test_length, global_bench = nil)
48
- EM.stop if EM.reactor_running?
49
-
50
- EventMachine.fiber_run do
51
- StubServer.new(:server => Protobuf::Rpc::Socket::Server, :port => 9399) do |server|
52
- client = ::Test::ResourceService.client(:port => 9399)
53
-
54
- benchmark_wrapper(global_bench) do |bench|
55
- bench.report("SS / EC") do
56
- (1..number_tests.to_i).each { client.find(:name => "Test Name" * test_length.to_i, :active => true) }
57
- end
58
- end
59
- end
60
-
61
- EM.stop
62
- end
63
- end
64
-
65
32
  def sock_client_sock_server(number_tests, test_length, global_bench = nil)
66
33
  load "protobuf/socket.rb"
67
- EM.stop if EM.reactor_running?
68
34
 
69
35
  StubServer.new(:server => Protobuf::Rpc::Socket::Server, :port => 9399) do |server|
70
36
  client = ::Test::ResourceService.client(:port => 9399)
@@ -77,26 +43,6 @@ namespace :benchmark do
77
43
  end
78
44
  end
79
45
 
80
- def sock_client_em_server(number_tests, test_length, global_bench = nil)
81
- load "protobuf/socket.rb"
82
- EM.stop if EM.reactor_running?
83
- em_thread = Thread.new { EM.run }
84
- Thread.pass until EM.reactor_running?
85
-
86
- StubServer.new(:port => 9399) do |server|
87
- client = ::Test::ResourceService.client(:port => 9399)
88
-
89
- benchmark_wrapper(global_bench) do |bench|
90
- bench.report("ES / SC") do
91
- (1..number_tests.to_i).each { client.find(:name => "Test Name" * test_length.to_i, :active => true) }
92
- end
93
- end
94
- end
95
-
96
- EM.stop
97
- Thread.kill(em_thread) if em_thread
98
- end
99
-
100
46
  def zmq_client_zmq_server(number_tests, test_length, global_bench = nil)
101
47
  load "protobuf/zmq.rb"
102
48
  StubServer.new(:port => 9399, :server => Protobuf::Rpc::Zmq::Server) do |server|
@@ -149,40 +95,19 @@ namespace :benchmark do
149
95
  puts args[:profile_output]
150
96
  end
151
97
 
152
- desc "benchmark EventMachine client with EventMachine server"
153
- task :em_client_em_server, [:number, :length] do |t, args|
154
- args.with_defaults(:number => 1000, :length => 100)
155
- em_client_em_server(args[:number], args[:length])
156
- end
157
-
158
- desc "benchmark EventMachine client with Socket server"
159
- task :em_client_sock_server, [:number, :length] do |t, args|
160
- args.with_defaults(:number => 1000, :length => 100)
161
- em_client_sock_server(args[:number], args[:length])
162
- end
163
-
164
98
  desc "benchmark Socket client with Socket server"
165
99
  task :sock_client_sock_server, [:number, :length] do |t, args|
166
100
  args.with_defaults(:number => 1000, :length => 100)
167
101
  sock_client_sock_server(args[:number], args[:length])
168
102
  end
169
103
 
170
- desc "benchmark Socket client with EventMachine server"
171
- task :sock_client_em_server, [:number, :length] do |t, args|
172
- args.with_defaults(:number => 1000, :length => 100)
173
- sock_client_em_server(args[:number], args[:length])
174
- end
175
-
176
104
  desc "benchmark server performance"
177
105
  task :servers, [:number, :length] do |t, args|
178
106
  args.with_defaults(:number => 1000, :length => 100)
179
107
 
180
108
  Benchmark.bm(10) do |bench|
181
- # zmq_client_zmq_server(args[:number], args[:length], bench)
182
- # em_client_em_server(args[:number], args[:length], bench)
183
- # em_client_sock_server(args[:number], args[:length], bench)
109
+ zmq_client_zmq_server(args[:number], args[:length], bench)
184
110
  sock_client_sock_server(args[:number], args[:length], bench)
185
- # sock_client_em_server(args[:number], args[:length], bench)
186
111
  end
187
112
  end
188
113
  end
@@ -4,29 +4,21 @@ require 'spec/support/test/resource_service'
4
4
  require 'protobuf/rpc/service_directory'
5
5
 
6
6
  describe 'Functional ZMQ Client' do
7
- let(:options) {{
8
- :host => "127.0.0.1",
9
- :port => 9399,
10
- :worker_port => 9400,
11
- :backlog => 100,
12
- :threshold => 100,
13
- :threads => 5
14
- }}
15
-
16
- let(:server) { ::Protobuf::Rpc::Zmq::Server.new(options) }
17
- let!(:server_thread) { Thread.new(server) { |server| server.run } }
18
-
19
7
  before(:all) do
20
8
  load "protobuf/zmq.rb"
9
+ @runner = ::Protobuf::Rpc::ZmqRunner.new({ :host => "127.0.0.1",
10
+ :port => 9399,
11
+ :worker_port => 9408,
12
+ :backlog => 100,
13
+ :threshold => 100,
14
+ :threads => 5 })
15
+ @server_thread = Thread.new(@runner) { |runner| runner.run }
16
+ Thread.pass until @runner.running?
21
17
  end
22
18
 
23
- before do
24
- Thread.pass until server.running?
25
- end
26
-
27
- after do
28
- server.stop
29
- server_thread.join
19
+ after(:all) do
20
+ @runner.stop
21
+ @server_thread.join
30
22
  end
31
23
 
32
24
  it 'runs fine when required fields are set' do
@@ -47,8 +39,8 @@ describe 'Functional ZMQ Client' do
47
39
  end
48
40
 
49
41
  it 'runs under heavy load' do
50
- 100.times do |x|
51
- 50.times.map do |y|
42
+ 10.times do |x|
43
+ 5.times.map do |y|
52
44
  Thread.new do
53
45
  client = ::Test::ResourceService.client
54
46
 
@@ -7,28 +7,21 @@ describe ::Protobuf::CLI do
7
7
  File.expand_path('../../../support/test_app_file.rb', __FILE__)
8
8
  end
9
9
 
10
- let(:sock_runner) {
10
+ let(:sock_runner) {
11
11
  runner = double("SocketRunner", :register_signals => nil)
12
12
  runner.stub(:run) { ::ActiveSupport::Notifications.publish( "after_server_bind" ) }
13
13
  runner
14
14
  }
15
15
 
16
- let(:zmq_runner) {
16
+ let(:zmq_runner) {
17
17
  runner = double "ZmqRunner", register_signals: nil
18
18
  runner.stub(:run) { ::ActiveSupport::Notifications.publish( "after_server_bind" ) }
19
19
  runner
20
20
  }
21
21
 
22
- let(:evented_runner) {
23
- runner = double "EventedRunner", register_signals: nil
24
- runner.stub(:run) { ::Protobuf::Lifecycle.trigger( "after_server_bind" ) }
25
- runner
26
- }
27
-
28
22
  before(:each) do
29
23
  ::Protobuf::Rpc::SocketRunner.stub(:new) { sock_runner }
30
24
  ::Protobuf::Rpc::ZmqRunner.stub(:new) { zmq_runner }
31
- ::Protobuf::Rpc::EventedRunner.stub(:new) { evented_runner }
32
25
  end
33
26
 
34
27
  describe '#start' do
@@ -176,7 +169,6 @@ describe ::Protobuf::CLI do
176
169
  let(:runner) { ::Protobuf::Rpc::SocketRunner }
177
170
 
178
171
  before do
179
- ::Protobuf::Rpc::EventedRunner.should_not_receive(:new)
180
172
  ::Protobuf::Rpc::ZmqRunner.should_not_receive(:new)
181
173
  end
182
174
 
@@ -185,7 +177,7 @@ describe ::Protobuf::CLI do
185
177
  described_class.start(args)
186
178
  end
187
179
 
188
- it 'is activated by PB_SERVER_TYPE=Socket ENV variable' do
180
+ it 'is activated by PB_SERVER_TYPE=Socket ENV variable' do
189
181
  ENV['PB_SERVER_TYPE'] = "Socket"
190
182
  runner.should_receive(:new).and_return(sock_runner)
191
183
  described_class.start(args)
@@ -198,40 +190,12 @@ describe ::Protobuf::CLI do
198
190
  end
199
191
  end
200
192
 
201
- context 'evented' do
202
- let(:test_args) { [ '--evented' ] }
203
- let(:runner) { ::Protobuf::Rpc::EventedRunner }
204
-
205
- before do
206
- ::Protobuf::Rpc::SocketRunner.should_not_receive(:new)
207
- ::Protobuf::Rpc::ZmqRunner.should_not_receive(:new)
208
- end
209
-
210
- it 'is activated by the --evented switch' do
211
- runner.should_receive(:new).and_return(evented_runner)
212
- described_class.start(args)
213
- end
214
-
215
- it 'is activated by PB_SERVER_TYPE=Evented ENV variable' do
216
- ENV['PB_SERVER_TYPE'] = "Evented"
217
- runner.should_receive(:new).and_return(evented_runner)
218
- described_class.start(args)
219
- ENV.delete('PB_SERVER_TYPE')
220
- end
221
-
222
- it 'configures the connector type to be evented' do
223
- load "protobuf/evented.rb"
224
- ::Protobuf.connector_type.should == :evented
225
- end
226
- end
227
-
228
193
  context 'zmq workers only' do
229
194
  let(:test_args) { [ '--workers_only', '--zmq' ] }
230
195
  let(:runner) { ::Protobuf::Rpc::ZmqRunner }
231
196
 
232
197
  before do
233
198
  ::Protobuf::Rpc::SocketRunner.should_not_receive(:new)
234
- ::Protobuf::Rpc::EventedRunner.should_not_receive(:new)
235
199
  end
236
200
 
237
201
  it 'is activated by the --workers_only switch' do
@@ -242,7 +206,7 @@ describe ::Protobuf::CLI do
242
206
  described_class.start(args)
243
207
  end
244
208
 
245
- it 'is activated by PB_WORKERS_ONLY=1 ENV variable' do
209
+ it 'is activated by PB_WORKERS_ONLY=1 ENV variable' do
246
210
  ENV['PB_WORKERS_ONLY'] = "1"
247
211
  runner.should_receive(:new) do |options|
248
212
  options[:workers_only].should be_true
@@ -259,7 +223,6 @@ describe ::Protobuf::CLI do
259
223
 
260
224
  before do
261
225
  ::Protobuf::Rpc::SocketRunner.should_not_receive(:new)
262
- ::Protobuf::Rpc::EventedRunner.should_not_receive(:new)
263
226
  end
264
227
 
265
228
  it 'is activated by the --worker_port switch' do
@@ -277,7 +240,6 @@ describe ::Protobuf::CLI do
277
240
 
278
241
  before do
279
242
  ::Protobuf::Rpc::SocketRunner.should_not_receive(:new)
280
- ::Protobuf::Rpc::EventedRunner.should_not_receive(:new)
281
243
  end
282
244
 
283
245
  it 'is activated by the --zmq switch' do
@@ -285,7 +247,7 @@ describe ::Protobuf::CLI do
285
247
  described_class.start(args)
286
248
  end
287
249
 
288
- it 'is activated by PB_SERVER_TYPE=Zmq ENV variable' do
250
+ it 'is activated by PB_SERVER_TYPE=Zmq ENV variable' do
289
251
  ENV['PB_SERVER_TYPE'] = "Zmq"
290
252
  runner.should_receive(:new)
291
253
  described_class.start(args)
@@ -1,98 +1,231 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Protobuf::Enum do
4
- let(:name) { :THREE }
5
- let(:tag) { 3 }
6
4
 
7
- before(:all) do
8
- Test::EnumTestType.define(:MINUS_ONE, -1)
9
- Test::EnumTestType.define(:THREE, 3)
10
- end
5
+ describe 'class dsl' do
6
+ let(:name) { :THREE }
7
+ let(:tag) { 3 }
11
8
 
12
- describe '.define' do
13
- it 'defines a constant enum value on the parent class' do
14
- Test::EnumTestType.constants.should include(name)
15
- Test::EnumTestType::THREE.should be_a(Protobuf::EnumValue)
9
+ before(:all) do
10
+ Test::EnumTestType.define(:MINUS_ONE, -1)
11
+ Test::EnumTestType.define(:THREE, 3)
16
12
  end
17
- end
18
13
 
19
- describe '.fetch' do
20
- context 'when value is an EnumValue' do
21
- it 'responds with that object' do
22
- Test::EnumTestType.fetch(Test::EnumTestType::THREE).name.should eq Test::EnumTestType::THREE.name
14
+ before(:all) do
15
+ EnumAliasTest = ::Class.new(::Protobuf::Enum) do
16
+ set_option :allow_alias
17
+ define :FOO, 1
18
+ define :BAR, 1
19
+ define :BAZ, 2
23
20
  end
24
21
  end
25
22
 
26
- context 'when value can be coerced to a symbol' do
27
- it 'fetches based on the symbol name value' do
28
- Test::EnumTestType.fetch("ONE").should eq Test::EnumTestType::ONE
29
- Test::EnumTestType.fetch(:ONE).should eq Test::EnumTestType::ONE
23
+ describe '.aliases_allowed?' do
24
+ it 'is false when the option is not set' do
25
+ expect(Test::EnumTestType.aliases_allowed?).to be_false
30
26
  end
31
27
  end
32
28
 
33
- context 'when value can be coerced to an integer' do
34
- it 'fetches based on the integer tag value' do
35
- Test::EnumTestType.fetch(3.0).should eq Test::EnumTestType::THREE
36
- Test::EnumTestType.fetch(3).should eq Test::EnumTestType::THREE
29
+ describe '.define' do
30
+ it 'defines a constant enum on the parent class' do
31
+ expect(Test::EnumTestType.constants).to include(name)
32
+ expect(Test::EnumTestType::THREE).to be_a(Protobuf::Enum)
33
+ end
34
+
35
+ context 'when enum allows aliases' do
36
+ before(:all) do
37
+ DefineEnumAlias = ::Class.new(::Protobuf::Enum) do
38
+ set_option :allow_alias
39
+ end
40
+ end
41
+
42
+ it 'allows defining enums with the same tag number' do
43
+ expect {
44
+ DefineEnumAlias.define(:FOO, 1)
45
+ DefineEnumAlias.define(:BAR, 1)
46
+ }.not_to raise_error
47
+ end
37
48
  end
38
49
  end
39
50
 
40
- context 'when value is not an applicable type' do
41
- it 'returns a nil' do
42
- Test::EnumTestType.fetch(Test::Resource.new).should be_nil
43
- Test::EnumTestType.fetch(nil).should be_nil
44
- Test::EnumTestType.fetch(false).should be_nil
51
+ describe '.enums' do
52
+ it 'provides an array of defined Enums' do
53
+ expect(Test::EnumTestType.enums).to eq([
54
+ Test::EnumTestType::ONE,
55
+ Test::EnumTestType::TWO,
56
+ Test::EnumTestType::MINUS_ONE,
57
+ Test::EnumTestType::THREE
58
+ ])
59
+ end
60
+
61
+ context 'when enum allows aliases' do
62
+ it 'treats aliased enums as valid' do
63
+ expect(EnumAliasTest.enums).to eq([
64
+ EnumAliasTest::FOO,
65
+ EnumAliasTest::BAR,
66
+ EnumAliasTest::BAZ
67
+ ])
68
+ end
45
69
  end
46
70
  end
47
- end
48
71
 
49
- describe '.enum_by_value' do
50
- it 'gets the EnumValue corresponding to the given value (tag)' do
51
- Test::EnumTestType.enum_by_value(tag).should eq Test::EnumTestType.const_get(name)
72
+
73
+ describe '.enums_for_tag' do
74
+ it 'returns an array of Enums for the given tag, if any' do
75
+ expect(EnumAliasTest.enums_for_tag(1)).to eq([ EnumAliasTest::FOO, EnumAliasTest::BAR ])
76
+ expect(EnumAliasTest.enums_for_tag(2)).to eq([ EnumAliasTest::BAZ ])
77
+ expect(EnumAliasTest.enums_for_tag(3)).to eq([])
78
+ end
52
79
  end
53
- end
54
80
 
55
- describe '.name_by_value' do
56
- it 'get the name by value of the enum given the enum' do
57
- Test::EnumTestType.name_by_value(::Test::EnumTestType::THREE).should eq name
81
+ describe '.fetch' do
82
+ context 'when candidate is an Enum' do
83
+ it 'responds with the Enum' do
84
+ expect(Test::EnumTestType.fetch(Test::EnumTestType::THREE)).to eq(Test::EnumTestType::THREE)
85
+ end
86
+ end
87
+
88
+ context 'when candidate can be coerced to a symbol' do
89
+ it 'fetches based on the symbol name' do
90
+ expect(Test::EnumTestType.fetch("ONE")).to eq(Test::EnumTestType::ONE)
91
+ expect(Test::EnumTestType.fetch(:ONE)).to eq(Test::EnumTestType::ONE)
92
+ end
93
+ end
94
+
95
+ context 'when candidate can be coerced to an integer' do
96
+ it 'fetches based on the integer tag' do
97
+ expect(Test::EnumTestType.fetch(3.0)).to eq(Test::EnumTestType::THREE)
98
+ expect(Test::EnumTestType.fetch(3)).to eq(Test::EnumTestType::THREE)
99
+ end
100
+
101
+ context 'when enum allows aliases' do
102
+ it 'fetches the first defined Enum' do
103
+ expect(EnumAliasTest.fetch(1)).to eq(EnumAliasTest::FOO)
104
+ end
105
+ end
106
+ end
107
+
108
+ context 'when candidate is not an applicable type' do
109
+ it 'returns a nil' do
110
+ expect(Test::EnumTestType.fetch(EnumAliasTest::FOO)).to be_nil
111
+ expect(Test::EnumTestType.fetch(Test::Resource.new)).to be_nil
112
+ expect(Test::EnumTestType.fetch(nil)).to be_nil
113
+ expect(Test::EnumTestType.fetch(false)).to be_nil
114
+ expect(Test::EnumTestType.fetch(-10)).to be_nil
115
+ end
116
+ end
58
117
  end
59
118
 
60
- it 'gets the name of the enum corresponding to the given value (tag)' do
61
- Test::EnumTestType.name_by_value(tag).should eq name
119
+ describe '.enum_for_tag' do
120
+ it 'gets the Enum corresponding to the given tag' do
121
+ expect(Test::EnumTestType.enum_for_tag(tag)).to eq(Test::EnumTestType.const_get(name))
122
+ expect(Test::EnumTestType.enum_for_tag(-5)).to be_nil
123
+ end
62
124
  end
63
125
 
64
- context 'when given name is nil' do
65
- it 'returns a nil' do
66
- Test::EnumTestType.name_by_value(nil).should be_nil
126
+ describe '.name_for_tag' do
127
+ it 'get the name of the enum given the enum' do
128
+ expect(Test::EnumTestType.name_for_tag(::Test::EnumTestType::THREE)).to eq(name)
129
+ end
130
+
131
+ it 'gets the name of the enum corresponding to the given tag' do
132
+ expect(Test::EnumTestType.name_for_tag(tag)).to eq(name)
133
+ end
134
+
135
+ it 'gets the name when the tag is coercable to an int' do
136
+ expect(Test::EnumTestType.name_for_tag("3")).to eq(name)
137
+ end
138
+
139
+ it 'returns nil when tag does not correspond to a name' do
140
+ expect(Test::EnumTestType.name_for_tag(12345)).to be_nil
141
+ end
142
+
143
+ context 'when given name is nil' do
144
+ it 'returns a nil' do
145
+ expect(Test::EnumTestType.name_for_tag(nil)).to be_nil
146
+ end
147
+ end
148
+
149
+ context 'when enum allows aliases' do
150
+ it 'returns the first defined name for the given tag' do
151
+ expect(EnumAliasTest.name_for_tag(1)).to eq(:FOO)
152
+ end
153
+ end
154
+ end
155
+
156
+ describe '.valid_tag?' do
157
+ context 'when tag is defined' do
158
+ specify { expect(Test::EnumTestType.valid_tag?(tag)).to be_true }
159
+ end
160
+
161
+ context 'when tag is not defined' do
162
+ specify { expect(Test::EnumTestType.valid_tag?(300)).to be_false }
163
+ end
164
+
165
+ context 'is true for aliased enums' do
166
+ specify { expect(EnumAliasTest.valid_tag?(1)).to be_true }
67
167
  end
68
168
  end
69
- end
70
169
 
71
- describe '.valid_tag?' do
72
- context 'when tag is defined' do
73
- specify { Test::EnumTestType.valid_tag?(tag).should be_true }
170
+ describe '.enum_for_name' do
171
+ it 'gets the Enum corresponding to the given name' do
172
+ expect(Test::EnumTestType.enum_for_name(name)).to eq(Test::EnumTestType::THREE)
173
+ end
74
174
  end
75
175
 
76
- context 'when tag is not defined' do
77
- specify { Test::EnumTestType.valid_tag?(300).should be_false }
176
+ describe '.values' do
177
+ it 'provides a hash of defined Enums' do
178
+ expect(Test::EnumTestType.values).to eq({
179
+ :MINUS_ONE => Test::EnumTestType::MINUS_ONE,
180
+ :ONE => Test::EnumTestType::ONE,
181
+ :TWO => Test::EnumTestType::TWO,
182
+ :THREE => Test::EnumTestType::THREE
183
+ })
184
+ end
185
+
186
+ it 'contains aliased Enums' do
187
+ expect(EnumAliasTest.values).to eq({
188
+ :FOO => EnumAliasTest::FOO,
189
+ :BAR => EnumAliasTest::BAR,
190
+ :BAZ => EnumAliasTest::BAZ
191
+ })
192
+ end
78
193
  end
79
- end
80
194
 
81
- describe '.value_by_name' do
82
- it 'gets the EnumValue corresponding to the given name' do
83
- Test::EnumTestType.value_by_name(name).should eq Test::EnumTestType::THREE
195
+ describe '.all_tags' do
196
+ it 'provides a unique array of defined tags' do
197
+ expect(Test::EnumTestType.all_tags).to include(1, 2, -1, 3)
198
+ expect(EnumAliasTest.all_tags).to include(1, 2)
199
+ end
84
200
  end
85
201
  end
86
202
 
87
- describe '.values' do
88
- it 'provides a hash of defined EnumValues' do
89
- Test::EnumTestType.values.should eq({
90
- :MINUS_ONE => Test::EnumTestType::MINUS_ONE,
91
- :ONE => Test::EnumTestType::ONE,
92
- :TWO => Test::EnumTestType::TWO,
93
- :THREE => Test::EnumTestType::THREE
94
- })
95
- end
203
+ subject { Test::EnumTestType::ONE }
204
+ its(:class) { should eq(Fixnum) }
205
+ its(:parent_class) { should eq(Test::EnumTestType) }
206
+ its(:name) { should eq(:ONE) }
207
+ its(:tag) { should eq(1) }
208
+ its(:value) { should eq(1) }
209
+ its(:to_hash_value) { should eq(1) }
210
+ its(:to_s) { should eq("1") }
211
+ its(:inspect) { should eq('#<Protobuf::Enum(Test::EnumTestType)::ONE=1>') }
212
+ specify { subject.to_s(:tag).should eq("1") }
213
+ specify { subject.to_s(:name).should eq("ONE") }
214
+
215
+ it "can be used as the index to an array" do
216
+ array = [0, 1, 2, 3]
217
+ array[::Test::EnumTestType::ONE].should eq(1)
218
+ end
219
+
220
+ describe '#try' do
221
+ specify { subject.try(:parent_class).should eq(subject.parent_class) }
222
+ specify { subject.try(:class).should eq(subject.class) }
223
+ specify { subject.try(:name).should eq(subject.name) }
224
+ specify { subject.try(:tag).should eq(subject.tag) }
225
+ specify { subject.try(:value).should eq(subject.value) }
226
+ specify { subject.try(:to_i).should eq(subject.to_i) }
227
+ specify { subject.try(:to_int).should eq(subject.to_int) }
228
+ specify { subject.try { |yielded| yielded.should eq(subject) } }
96
229
  end
97
230
 
98
231
  context 'when coercing from enum' do
@@ -101,6 +234,6 @@ describe Protobuf::Enum do
101
234
  end
102
235
 
103
236
  context 'when coercing from integer' do
104
- specify { 0.should eq(Test::StatusType::PENDING) }
237
+ specify { expect(0).to eq(Test::StatusType::PENDING) }
105
238
  end
106
239
  end