protobuf 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. data/.gitignore +5 -0
  2. data/Gemfile +3 -0
  3. data/Gemfile.lock +28 -0
  4. data/README.md +216 -0
  5. data/Rakefile +1 -0
  6. data/bin/rpc_server +117 -0
  7. data/bin/rprotoc +46 -0
  8. data/examples/addressbook.pb.rb +55 -0
  9. data/examples/addressbook.proto +24 -0
  10. data/examples/reading_a_message.rb +32 -0
  11. data/examples/writing_a_message.rb +46 -0
  12. data/lib/protobuf.rb +6 -0
  13. data/lib/protobuf/common/exceptions.rb +11 -0
  14. data/lib/protobuf/common/logger.rb +64 -0
  15. data/lib/protobuf/common/util.rb +59 -0
  16. data/lib/protobuf/common/wire_type.rb +10 -0
  17. data/lib/protobuf/compiler/compiler.rb +52 -0
  18. data/lib/protobuf/compiler/nodes.rb +323 -0
  19. data/lib/protobuf/compiler/proto.y +216 -0
  20. data/lib/protobuf/compiler/proto2.ebnf +79 -0
  21. data/lib/protobuf/compiler/proto_parser.rb +1425 -0
  22. data/lib/protobuf/compiler/template/rpc_bin.erb +4 -0
  23. data/lib/protobuf/compiler/template/rpc_client.erb +18 -0
  24. data/lib/protobuf/compiler/template/rpc_service.erb +25 -0
  25. data/lib/protobuf/compiler/template/rpc_service_implementation.erb +42 -0
  26. data/lib/protobuf/compiler/visitors.rb +302 -0
  27. data/lib/protobuf/descriptor/descriptor.proto +286 -0
  28. data/lib/protobuf/descriptor/descriptor.rb +55 -0
  29. data/lib/protobuf/descriptor/descriptor_builder.rb +143 -0
  30. data/lib/protobuf/descriptor/descriptor_proto.rb +138 -0
  31. data/lib/protobuf/descriptor/enum_descriptor.rb +33 -0
  32. data/lib/protobuf/descriptor/field_descriptor.rb +49 -0
  33. data/lib/protobuf/descriptor/file_descriptor.rb +37 -0
  34. data/lib/protobuf/message/decoder.rb +83 -0
  35. data/lib/protobuf/message/encoder.rb +46 -0
  36. data/lib/protobuf/message/enum.rb +62 -0
  37. data/lib/protobuf/message/extend.rb +8 -0
  38. data/lib/protobuf/message/field.rb +701 -0
  39. data/lib/protobuf/message/message.rb +402 -0
  40. data/lib/protobuf/message/protoable.rb +38 -0
  41. data/lib/protobuf/rpc/buffer.rb +74 -0
  42. data/lib/protobuf/rpc/client.rb +268 -0
  43. data/lib/protobuf/rpc/client_connection.rb +225 -0
  44. data/lib/protobuf/rpc/error.rb +34 -0
  45. data/lib/protobuf/rpc/error/client_error.rb +31 -0
  46. data/lib/protobuf/rpc/error/server_error.rb +43 -0
  47. data/lib/protobuf/rpc/rpc.pb.rb +107 -0
  48. data/lib/protobuf/rpc/server.rb +183 -0
  49. data/lib/protobuf/rpc/service.rb +244 -0
  50. data/lib/protobuf/rpc/stat.rb +70 -0
  51. data/lib/protobuf/version.rb +3 -0
  52. data/proto/rpc.proto +73 -0
  53. data/protobuf.gemspec +25 -0
  54. data/script/mk_parser +2 -0
  55. data/spec/functional/embedded_service_spec.rb +7 -0
  56. data/spec/proto/test.pb.rb +31 -0
  57. data/spec/proto/test.proto +31 -0
  58. data/spec/proto/test_service.rb +30 -0
  59. data/spec/proto/test_service_impl.rb +17 -0
  60. data/spec/spec_helper.rb +26 -0
  61. data/spec/unit/client_spec.rb +128 -0
  62. data/spec/unit/common/logger_spec.rb +121 -0
  63. data/spec/unit/enum_spec.rb +13 -0
  64. data/spec/unit/message_spec.rb +67 -0
  65. data/spec/unit/server_spec.rb +27 -0
  66. data/spec/unit/service_spec.rb +75 -0
  67. data/test/check_unbuild.rb +30 -0
  68. data/test/data/data.bin +3 -0
  69. data/test/data/data_source.py +14 -0
  70. data/test/data/types.bin +0 -0
  71. data/test/data/types_source.py +22 -0
  72. data/test/data/unk.png +0 -0
  73. data/test/proto/addressbook.pb.rb +66 -0
  74. data/test/proto/addressbook.proto +33 -0
  75. data/test/proto/addressbook_base.pb.rb +58 -0
  76. data/test/proto/addressbook_base.proto +26 -0
  77. data/test/proto/addressbook_ext.pb.rb +20 -0
  78. data/test/proto/addressbook_ext.proto +6 -0
  79. data/test/proto/collision.pb.rb +17 -0
  80. data/test/proto/collision.proto +5 -0
  81. data/test/proto/ext_collision.pb.rb +24 -0
  82. data/test/proto/ext_collision.proto +8 -0
  83. data/test/proto/ext_range.pb.rb +22 -0
  84. data/test/proto/ext_range.proto +7 -0
  85. data/test/proto/float_default.proto +10 -0
  86. data/test/proto/lowercase.pb.rb +30 -0
  87. data/test/proto/lowercase.proto +9 -0
  88. data/test/proto/merge.pb.rb +39 -0
  89. data/test/proto/merge.proto +15 -0
  90. data/test/proto/nested.pb.rb +30 -0
  91. data/test/proto/nested.proto +9 -0
  92. data/test/proto/optional_field.pb.rb +35 -0
  93. data/test/proto/optional_field.proto +12 -0
  94. data/test/proto/packed.pb.rb +22 -0
  95. data/test/proto/packed.proto +6 -0
  96. data/test/proto/rpc.proto +6 -0
  97. data/test/proto/types.pb.rb +84 -0
  98. data/test/proto/types.proto +37 -0
  99. data/test/test_addressbook.rb +56 -0
  100. data/test/test_compiler.rb +325 -0
  101. data/test/test_descriptor.rb +122 -0
  102. data/test/test_enum_value.rb +41 -0
  103. data/test/test_extension.rb +36 -0
  104. data/test/test_lowercase.rb +11 -0
  105. data/test/test_message.rb +128 -0
  106. data/test/test_optional_field.rb +103 -0
  107. data/test/test_packed_field.rb +40 -0
  108. data/test/test_parse.rb +15 -0
  109. data/test/test_repeated_types.rb +132 -0
  110. data/test/test_serialize.rb +61 -0
  111. data/test/test_standard_message.rb +96 -0
  112. data/test/test_types.rb +226 -0
  113. metadata +261 -0
@@ -0,0 +1,22 @@
1
+ ### Generated by rprotoc. DO NOT EDIT!
2
+ ### <proto file: test/proto/packed.proto>
3
+ # package test.packed_field;
4
+ #
5
+ # message Message {
6
+ # repeated int32 a = 1 [packed = true];
7
+ # repeated fixed32 b = 2 [packed = true];
8
+ # }
9
+
10
+ require 'protobuf/message/message'
11
+ require 'protobuf/message/enum'
12
+ require 'protobuf/message/extend'
13
+
14
+ module Test
15
+ module PackedField
16
+ class Message < ::Protobuf::Message
17
+ defined_in __FILE__
18
+ repeated :int32, :a, 1, :packed => true
19
+ repeated :fixed32, :b, 2, :packed => true
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,6 @@
1
+ package test.packed_field;
2
+
3
+ message Message {
4
+ repeated int32 a = 1 [packed = true];
5
+ repeated fixed32 b = 2 [packed = true];
6
+ }
@@ -0,0 +1,6 @@
1
+ package tutorial;
2
+
3
+ service AddressBookService {
4
+ rpc Search (Person) returns (AddressBook);
5
+ rpc Add (Person) returns (Person);
6
+ }
@@ -0,0 +1,84 @@
1
+ ### Generated by rprotoc. DO NOT EDIT!
2
+ ### <proto file: test/proto/types.proto>
3
+ # package test.types;
4
+ #
5
+ # message TestTypes {
6
+ # required double type1 = 1;
7
+ # required float type2 = 2;
8
+ # required int32 type3 = 3;
9
+ # required int64 type4 = 4;
10
+ # required uint32 type5 = 5;
11
+ # required uint64 type6 = 6;
12
+ # required sint32 type7 = 7;
13
+ # required sint64 type8 = 8;
14
+ # required fixed32 type9 = 9;
15
+ # required fixed64 type10 = 10;
16
+ # required bool type11 = 11;
17
+ # required string type12 = 12;
18
+ # required bytes type13 = 13;
19
+ # required sfixed32 type14 = 14;
20
+ # required sfixed64 type15 = 15;
21
+ # }
22
+ #
23
+ # message RepeatedTypes {
24
+ # repeated double type1 = 1;
25
+ # repeated float type2 = 2;
26
+ # repeated int32 type3 = 3;
27
+ # repeated int64 type4 = 4;
28
+ # repeated uint32 type5 = 5;
29
+ # repeated uint64 type6 = 6;
30
+ # repeated sint32 type7 = 7;
31
+ # repeated sint64 type8 = 8;
32
+ # repeated fixed32 type9 = 9;
33
+ # repeated fixed64 type10 = 10;
34
+ # repeated bool type11 = 11;
35
+ # repeated string type12 = 12;
36
+ # repeated bytes type13 = 13;
37
+ # repeated sfixed32 type14 = 14;
38
+ # repeated sfixed64 type15 = 15;
39
+ # }
40
+
41
+ require 'protobuf/message/message'
42
+ require 'protobuf/message/enum'
43
+ require 'protobuf/message/extend'
44
+
45
+ module Test
46
+ module Types
47
+ class TestTypes < ::Protobuf::Message
48
+ defined_in __FILE__
49
+ required :double, :type1, 1
50
+ required :float, :type2, 2
51
+ required :int32, :type3, 3
52
+ required :int64, :type4, 4
53
+ required :uint32, :type5, 5
54
+ required :uint64, :type6, 6
55
+ required :sint32, :type7, 7
56
+ required :sint64, :type8, 8
57
+ required :fixed32, :type9, 9
58
+ required :fixed64, :type10, 10
59
+ required :bool, :type11, 11
60
+ required :string, :type12, 12
61
+ required :bytes, :type13, 13
62
+ required :sfixed32, :type14, 14
63
+ required :sfixed64, :type15, 15
64
+ end
65
+ class RepeatedTypes < ::Protobuf::Message
66
+ defined_in __FILE__
67
+ repeated :double, :type1, 1
68
+ repeated :float, :type2, 2
69
+ repeated :int32, :type3, 3
70
+ repeated :int64, :type4, 4
71
+ repeated :uint32, :type5, 5
72
+ repeated :uint64, :type6, 6
73
+ repeated :sint32, :type7, 7
74
+ repeated :sint64, :type8, 8
75
+ repeated :fixed32, :type9, 9
76
+ repeated :fixed64, :type10, 10
77
+ repeated :bool, :type11, 11
78
+ repeated :string, :type12, 12
79
+ repeated :bytes, :type13, 13
80
+ repeated :sfixed32, :type14, 14
81
+ repeated :sfixed64, :type15, 15
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,37 @@
1
+ package test.types;
2
+
3
+ message TestTypes {
4
+ required double type1 = 1;
5
+ required float type2 = 2;
6
+ required int32 type3 = 3;
7
+ required int64 type4 = 4;
8
+ required uint32 type5 = 5;
9
+ required uint64 type6 = 6;
10
+ required sint32 type7 = 7;
11
+ required sint64 type8 = 8;
12
+ required fixed32 type9 = 9;
13
+ required fixed64 type10 = 10;
14
+ required bool type11 = 11;
15
+ required string type12 = 12;
16
+ required bytes type13 = 13;
17
+ required sfixed32 type14 = 14;
18
+ required sfixed64 type15 = 15;
19
+ }
20
+
21
+ message RepeatedTypes {
22
+ repeated double type1 = 1;
23
+ repeated float type2 = 2;
24
+ repeated int32 type3 = 3;
25
+ repeated int64 type4 = 4;
26
+ repeated uint32 type5 = 5;
27
+ repeated uint64 type6 = 6;
28
+ repeated sint32 type7 = 7;
29
+ repeated sint64 type8 = 8;
30
+ repeated fixed32 type9 = 9;
31
+ repeated fixed64 type10 = 10;
32
+ repeated bool type11 = 11;
33
+ repeated string type12 = 12;
34
+ repeated bytes type13 = 13;
35
+ repeated sfixed32 type14 = 14;
36
+ repeated sfixed64 type15 = 15;
37
+ }
@@ -0,0 +1,56 @@
1
+ require 'test/unit'
2
+ require 'protobuf/message/message'
3
+ require 'protobuf/message/enum'
4
+ require 'test/proto/addressbook.pb'
5
+
6
+ class AddressbookTest < Test::Unit::TestCase
7
+ def test_enum
8
+ phone_number = Tutorial::Person::PhoneNumber.new
9
+ assert_equal(Tutorial::Person::PhoneType::HOME, phone_number.type)
10
+ phone_number.type = Tutorial::Person::PhoneType::MOBILE
11
+ assert_equal(0, phone_number.type)
12
+ phone_number.type = Tutorial::Person::PhoneType::HOME
13
+ assert_equal(1, phone_number.type)
14
+ phone_number.type = Tutorial::Person::PhoneType::WORK
15
+ assert_equal(2, phone_number.type)
16
+ assert_raise(TypeError) do
17
+ phone_number.type = 3
18
+ end
19
+ end
20
+
21
+ def test_symbol_enum
22
+ phone_number = Tutorial::Person::PhoneNumber.new
23
+ assert_equal(Tutorial::Person::PhoneType::HOME, phone_number.type)
24
+ phone_number.type = :MOBILE
25
+ assert_equal(0, phone_number.type)
26
+ phone_number.type = :HOME
27
+ assert_equal(1, phone_number.type)
28
+ phone_number.type = :WORK
29
+ assert_equal(2, phone_number.type)
30
+ assert_raise(TypeError) do
31
+ phone_number.type = :UNKNOWN
32
+ end
33
+ end
34
+
35
+ def test_initial_value
36
+ person = Tutorial::Person.new
37
+ assert_nil(person.name)
38
+ assert_nil(person.id)
39
+ assert_equal([], person.phone)
40
+ assert_equal('', person.email)
41
+ end
42
+
43
+ def test_repeatable
44
+ address_book = Tutorial::AddressBook.new
45
+ assert_equal([], address_book.person)
46
+ assert_instance_of(Protobuf::Field::FieldArray, address_book.person)
47
+ address_book.person << Tutorial::Person.new
48
+ assert_equal(1, address_book.person.size)
49
+ assert_raise(TypeError) do
50
+ address_book.person << 1
51
+ end
52
+ assert_equal(1, address_book.person.size)
53
+ address_book.person << Tutorial::Person.new
54
+ assert_equal(2, address_book.person.size)
55
+ end
56
+ end
@@ -0,0 +1,325 @@
1
+ require 'test/unit'
2
+ require 'protobuf/compiler/compiler'
3
+
4
+ class CompilerTest < Test::Unit::TestCase
5
+ # Issue 12: Parse error on float default value
6
+ def test_compile_float_default
7
+ assert_compile_proto(<<-EOS, 'test/proto/float_default.proto')
8
+ ### Generated by rprotoc. DO NOT EDIT!
9
+ ### <proto file: test/proto/float_default.proto>
10
+ # message M {
11
+ # optional float f = 1 [default = 4.2];
12
+ # optional float g = 2 [default = -4.2];
13
+ # optional float h = 3 [default = 4352];
14
+ # optional float i = 4 [default = 23145.2 ];
15
+ # optional float j = 5 [default = -5 ];
16
+ # optional float k = 6 [default = +23 ];
17
+ # optional float l = 7 [default = +23.42 ];
18
+ # }
19
+ #
20
+
21
+ require 'protobuf/message/message'
22
+ require 'protobuf/message/enum'
23
+ require 'protobuf/message/extend'
24
+
25
+ class M < ::Protobuf::Message
26
+ defined_in __FILE__
27
+ optional :float, :f, 1, :default => 4.2
28
+ optional :float, :g, 2, :default => -4.2
29
+ optional :float, :h, 3, :default => 4352
30
+ optional :float, :i, 4, :default => 23145.2
31
+ optional :float, :j, 5, :default => -5
32
+ optional :float, :k, 6, :default => 23
33
+ optional :float, :l, 7, :default => 23.42
34
+ end
35
+ EOS
36
+ end
37
+
38
+ def test_create_message
39
+ assert_compile_proto(<<-EOS, 'test/proto/addressbook.proto')
40
+ ### Generated by rprotoc. DO NOT EDIT!
41
+ ### <proto file: test/proto/addressbook.proto>
42
+ # package tutorial;
43
+ #
44
+ # message Person {
45
+ # required string name = 1;
46
+ # required int32 id = 2;
47
+ # optional string email = 3;
48
+ #
49
+ # enum PhoneType {
50
+ # MOBILE = 0;
51
+ # HOME = 1;
52
+ # WORK = 2;
53
+ # }
54
+ #
55
+ # message PhoneNumber {
56
+ # required string number = 1;
57
+ # optional PhoneType type = 2 [default = HOME];
58
+ # }
59
+ #
60
+ # repeated PhoneNumber phone = 4;
61
+ # optional uint32 age = 5 [default = 20];
62
+ #
63
+ # extensions 100 to 200;
64
+ # }
65
+ #
66
+ # /*
67
+ # extend Person {
68
+ # optional int32 age = 100;
69
+ # }
70
+ # */
71
+ #
72
+ # message AddressBook {
73
+ # repeated Person person = 1;
74
+ # }
75
+ require 'protobuf/message/message'
76
+ require 'protobuf/message/enum'
77
+ require 'protobuf/message/extend'
78
+
79
+ module Tutorial
80
+
81
+ class Person < ::Protobuf::Message
82
+ defined_in __FILE__
83
+ required :string, :name, 1
84
+ required :int32, :id, 2
85
+ optional :string, :email, 3
86
+
87
+ class PhoneType < ::Protobuf::Enum
88
+ defined_in __FILE__
89
+ define :MOBILE, 0
90
+ define :HOME, 1
91
+ define :WORK, 2
92
+ end
93
+
94
+ class PhoneNumber < ::Protobuf::Message
95
+ defined_in __FILE__
96
+ required :string, :number, 1
97
+ optional :PhoneType, :type, 2, :default => :HOME
98
+ end
99
+
100
+ repeated :PhoneNumber, :phone, 4
101
+ optional :uint32, :age, 5, :default => 20
102
+
103
+ extensions 100..200
104
+ end
105
+
106
+ class AddressBook < ::Protobuf::Message
107
+ defined_in __FILE__
108
+ repeated :Person, :person, 1
109
+ end
110
+ end
111
+ EOS
112
+ end
113
+
114
+ def test_create_nested_message
115
+ assert_compile_proto(<<-EOS, 'test/proto/nested.proto')
116
+ ### Generated by rprotoc. DO NOT EDIT!
117
+ ### <proto file: test/proto/nested.proto>
118
+ # package test.nested;
119
+ #
120
+ # message Foo {
121
+ # message Bar {
122
+ # }
123
+ # }
124
+ # message Baaz {
125
+ # optional Foo.Bar x = 1;
126
+ # }
127
+
128
+ require 'protobuf/message/message'
129
+ require 'protobuf/message/enum'
130
+ require 'protobuf/message/extend'
131
+
132
+ module Test
133
+ module Nested
134
+ class Foo < ::Protobuf::Message
135
+ defined_in __FILE__
136
+ class Bar < ::Protobuf::Message
137
+ defined_in __FILE__
138
+ end
139
+ end
140
+ class Baaz < ::Protobuf::Message
141
+ defined_in __FILE__
142
+ optional :'Foo::Bar', :x, 1
143
+ end
144
+ end
145
+ end
146
+ EOS
147
+ end
148
+
149
+ def test_nested_message
150
+ file_contents = Protobuf::Compiler.new.create_message('test/proto/nested.proto', '.', '.', false)
151
+ assert_nothing_raised {Object.class_eval file_contents}
152
+ assert_raise(TypeError) {Test::Nested::Baaz.new.x = 1}
153
+ assert_nothing_raised {Test::Nested::Baaz.new.x = Test::Nested::Foo::Bar.new}
154
+ end
155
+
156
+ def test_create_rpc
157
+ file_contents = Protobuf::Compiler.new.create_rpc('test/proto/rpc.proto', '.', 'test/proto', false)
158
+
159
+ assert_source(<<-EOS, file_contents['test/proto/address_book_service.rb'])
160
+ require 'protobuf/rpc/server'
161
+ require 'protobuf/rpc/handler'
162
+ require 'test/proto/rpc.pb'
163
+
164
+ class Tutorial::SearchHandler < Protobuf::Rpc::Handler
165
+ request Tutorial::Person
166
+ response Tutorial::AddressBook
167
+
168
+ def self.process_request(request, response)
169
+ # TODO: edit this method
170
+ end
171
+ end
172
+
173
+ class Tutorial::AddHandler < Protobuf::Rpc::Handler
174
+ request Tutorial::Person
175
+ response Tutorial::Person
176
+
177
+ def self.process_request(request, response)
178
+ # TODO: edit this method
179
+ end
180
+ end
181
+
182
+ class Tutorial::AddressBookService < Protobuf::Rpc::Server
183
+ def setup_handlers
184
+ @handlers = {
185
+ :search => Tutorial::SearchHandler,
186
+ :add => Tutorial::AddHandler,
187
+ }
188
+ end
189
+ end
190
+ EOS
191
+
192
+ assert_source(<<-EOS, file_contents['test/proto/start_address_book_service'])
193
+ #!/usr/bin/env ruby
194
+ require 'address_book_service'
195
+
196
+ Tutorial::AddressBookService.new(:Port => 9999).start
197
+ EOS
198
+
199
+ assert_source(<<-EOS, file_contents['test/proto/client_search.rb'])
200
+ #!/usr/bin/env ruby
201
+ require 'protobuf/rpc/client'
202
+ require 'test/proto/rpc.pb'
203
+
204
+ # build request
205
+ request = Tutorial::Person.new
206
+ # TODO: setup a request
207
+ raise StandardError, 'setup a request'
208
+
209
+ # create blunk response
210
+ response = Tutorial::AddressBook.new
211
+
212
+ # execute rpc
213
+ Protobuf::Rpc::Client.new('localhost', 9999).call :search, request, response
214
+
215
+ # show response
216
+ puts response
217
+ EOS
218
+
219
+ assert_source(<<-EOS, file_contents['test/proto/client_add.rb'])
220
+ #!/usr/bin/env ruby
221
+ require 'protobuf/rpc/client'
222
+ require 'test/proto/rpc.pb'
223
+
224
+ # build request
225
+ request = Tutorial::Person.new
226
+ # TODO: setup a request
227
+ raise StandardError, 'setup a request'
228
+
229
+ # create blunk response
230
+ response = Tutorial::Person.new
231
+
232
+ # execute rpc
233
+ Protobuf::Rpc::Client.new('localhost', 9999).call :add, request, response
234
+
235
+ # show response
236
+ puts response
237
+ EOS
238
+ end
239
+
240
+ def test_create_descriptor
241
+ proto_path = 'test/proto/addressbook.proto'
242
+ visitor = Protobuf::Visitor::CreateDescriptorVisitor.new(proto_path)
243
+ File.open(proto_path) do |file|
244
+ visitor.visit Protobuf::ProtoParser.new.parse(file)
245
+ end
246
+ file_descriptor = visitor.file_descriptor
247
+ assert_equal(proto_path, file_descriptor.name)
248
+ assert_equal('tutorial', file_descriptor.package)
249
+
250
+ person_descriptor = file_descriptor.message_type[0]
251
+ assert_equal('Person', person_descriptor.name)
252
+ assert_equal([:name, :id, :email, :phone, :age].size, person_descriptor.field.size)
253
+
254
+ name_field_descriptor = person_descriptor.field.find {|d| d.name == 'name'}
255
+ assert_equal(1, name_field_descriptor.number)
256
+ assert_equal(Google::Protobuf::FieldDescriptorProto::Type::TYPE_STRING, name_field_descriptor.type)
257
+ assert_equal(Google::Protobuf::FieldDescriptorProto::Label::LABEL_REQUIRED, name_field_descriptor.label)
258
+ assert_equal('string', name_field_descriptor.type_name)
259
+
260
+ phone_field_descriptor = person_descriptor.field.find {|d| d.name == 'phone'}
261
+ assert_equal(4, phone_field_descriptor.number)
262
+ assert_equal(0, phone_field_descriptor.type) #TODO: is this right?
263
+ assert_equal(Google::Protobuf::FieldDescriptorProto::Label::LABEL_REPEATED, phone_field_descriptor.label)
264
+ assert_equal('PhoneNumber', phone_field_descriptor.type_name)
265
+
266
+ age_field_descriptor = person_descriptor.field.find {|d| d.name == 'age'}
267
+ assert_equal(5, age_field_descriptor.number)
268
+ assert_equal(Google::Protobuf::FieldDescriptorProto::Type::TYPE_UINT32, age_field_descriptor.type)
269
+ assert_equal(Google::Protobuf::FieldDescriptorProto::Label::LABEL_OPTIONAL, age_field_descriptor.label)
270
+ assert_equal('uint32', age_field_descriptor.type_name)
271
+ assert_equal('20', age_field_descriptor.default_value)
272
+
273
+ phone_type_descriptor = person_descriptor.enum_type.first
274
+ assert_equal('PhoneType', phone_type_descriptor.name)
275
+ assert_equal(3, phone_type_descriptor.value.size)
276
+
277
+ phone_type_home_descriptor = phone_type_descriptor.value.find {|d| d.name == 'HOME'}
278
+ assert_equal('HOME', phone_type_home_descriptor.name)
279
+ assert_equal(1, phone_type_home_descriptor.number)
280
+
281
+ extensions_descriptor = person_descriptor.extension_range.first
282
+ assert_equal(100, extensions_descriptor.start)
283
+ assert_equal(200, extensions_descriptor.end)
284
+
285
+ phone_number_descriptor = person_descriptor.nested_type.first
286
+ assert_equal('PhoneNumber', phone_number_descriptor.name)
287
+ assert_equal([:number, :type].size, phone_number_descriptor.field.size)
288
+
289
+ #TODO: test extend
290
+ #extend_person_descriptor = ??
291
+ #assert_equal extend_person_descriptor
292
+
293
+ addressbook_descriptor = file_descriptor.message_type[1]
294
+ assert_equal('AddressBook', addressbook_descriptor.name)
295
+ end
296
+
297
+ def test_collision
298
+ assert_raise(Protobuf::TagCollisionError) do require 'test/proto/collision.pb' end
299
+ assert_raise(Protobuf::TagCollisionError) do
300
+ Protobuf::Compiler.new.create_message('test/proto/collision.proto', '.', '.', false)
301
+ end
302
+ end
303
+
304
+ def test_ext_collision
305
+ assert_raise(Protobuf::TagCollisionError) do require 'test/proto/ext_collision.pb' end
306
+ assert_raise(Protobuf::TagCollisionError) do
307
+ Protobuf::Compiler.new.create_message('test/proto/ext_collision.proto', '.', '.', false)
308
+ end
309
+ end
310
+
311
+ def test_ext_range
312
+ assert_raise(RangeError) do require 'test/proto/ext_range.pb' end
313
+ assert_raise(RangeError) do
314
+ Protobuf::Compiler.new.create_message('test/proto/ext_range.proto', '.', '.', false)
315
+ end
316
+ end
317
+
318
+ def assert_compile_proto(ideal, filename)
319
+ assert_equal(ideal.gsub(/^\s*\n/, '').strip, Protobuf::Compiler.new.create_message(filename, '.', '.', false).gsub(/^\s*\n/, '').strip)
320
+ end
321
+
322
+ def assert_source(ideal, real)
323
+ assert_equal(ideal.strip.gsub(/^\s*\n/, '').gsub(/\s+\n/, "\n"), real.strip.gsub(/^\s*\n/, '').gsub(/\s+\n/, "\n"))
324
+ end
325
+ end