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,122 @@
1
+ require 'test/unit'
2
+ require 'test/proto/addressbook.pb'
3
+ require 'protobuf/descriptor/descriptor_builder'
4
+ require 'protobuf/descriptor/descriptor_proto'
5
+
6
+ class DescriptorTest < Test::Unit::TestCase
7
+ include Google::Protobuf
8
+ def test_build
9
+ tutorial_proto = FileDescriptorProto.new
10
+ tutorial_proto.package = 'Build::Tutorial'
11
+
12
+ person_proto = DescriptorProto.new
13
+ tutorial_proto.message_type << person_proto
14
+ person_proto.name = 'Person'
15
+
16
+ person_name_proto = FieldDescriptorProto.new
17
+ person_proto.field << person_name_proto
18
+ person_name_proto.label = FieldDescriptorProto::Label::LABEL_REQUIRED
19
+ person_name_proto.type = FieldDescriptorProto::Type::TYPE_STRING
20
+ person_name_proto.name = 'name'
21
+ person_name_proto.number = 1
22
+
23
+ person_id_proto = FieldDescriptorProto.new
24
+ person_proto.field << person_id_proto
25
+ person_id_proto.label = FieldDescriptorProto::Label::LABEL_REQUIRED
26
+ person_id_proto.type = FieldDescriptorProto::Type::TYPE_INT32
27
+ person_id_proto.name = 'id'
28
+ person_id_proto.number = 2
29
+
30
+ person_email_proto = FieldDescriptorProto.new
31
+ person_proto.field << person_email_proto
32
+ person_email_proto.label = FieldDescriptorProto::Label::LABEL_OPTIONAL
33
+ person_email_proto.type = FieldDescriptorProto::Type::TYPE_STRING
34
+ person_email_proto.name = 'email'
35
+ person_email_proto.number = 3
36
+
37
+ person_phone_type_proto = EnumDescriptorProto.new
38
+ person_proto.enum_type << person_phone_type_proto
39
+ person_phone_type_proto.name = 'PhoneType'
40
+
41
+ person_phone_type_mobile_proto = EnumValueDescriptorProto.new
42
+ person_phone_type_proto.value << person_phone_type_mobile_proto
43
+ person_phone_type_mobile_proto.name = 'MOBILE'
44
+ person_phone_type_mobile_proto.number = 0
45
+
46
+ person_phone_type_home_proto = EnumValueDescriptorProto.new
47
+ person_phone_type_proto.value << person_phone_type_home_proto
48
+ person_phone_type_home_proto.name = 'HOME'
49
+ person_phone_type_home_proto.number = 1
50
+
51
+ person_phone_type_work_proto = EnumValueDescriptorProto.new
52
+ person_phone_type_proto.value << person_phone_type_work_proto
53
+ person_phone_type_work_proto.name = 'WORK'
54
+ person_phone_type_work_proto.number = 2
55
+
56
+ person_phone_number_proto = DescriptorProto.new
57
+ person_proto.nested_type << person_phone_number_proto
58
+ person_phone_number_proto.name = 'PhoneNumber'
59
+
60
+ person_phone_number_number_proto = FieldDescriptorProto.new
61
+ person_phone_number_proto.field << person_phone_number_number_proto
62
+ person_phone_number_number_proto.label = FieldDescriptorProto::Label::LABEL_REQUIRED
63
+ person_phone_number_number_proto.type = FieldDescriptorProto::Type::TYPE_STRING
64
+ person_phone_number_number_proto.name = 'number'
65
+ person_phone_number_number_proto.number = 1
66
+
67
+ person_phone_number_type_proto = FieldDescriptorProto.new
68
+ person_phone_number_proto.field << person_phone_number_type_proto
69
+ person_phone_number_type_proto.label = FieldDescriptorProto::Label::LABEL_OPTIONAL
70
+ person_phone_number_type_proto.type = FieldDescriptorProto::Type::TYPE_ENUM
71
+ person_phone_number_type_proto.type_name = 'PhoneType'
72
+ person_phone_number_type_proto.name = 'type'
73
+ person_phone_number_type_proto.number = 2
74
+ person_phone_number_type_proto.default_value = 'HOME'
75
+
76
+ person_phone_phone_number_proto = FieldDescriptorProto.new
77
+ person_proto.field << person_phone_phone_number_proto
78
+ person_phone_phone_number_proto.label = FieldDescriptorProto::Label::LABEL_REPEATED
79
+ person_phone_phone_number_proto.type = FieldDescriptorProto::Type::TYPE_MESSAGE
80
+ person_phone_phone_number_proto.type_name = 'PhoneNumber'
81
+ person_phone_phone_number_proto.name = 'phone'
82
+ person_phone_phone_number_proto.number = 4
83
+
84
+ address_book_proto = DescriptorProto.new
85
+ tutorial_proto.message_type << address_book_proto
86
+ address_book_proto.name = 'AddressBook'
87
+
88
+ address_book_person_proto = FieldDescriptorProto.new
89
+ address_book_proto.field << address_book_person_proto
90
+ address_book_person_proto.label = FieldDescriptorProto::Label::LABEL_REPEATED
91
+ address_book_person_proto.type = FieldDescriptorProto::Type::TYPE_MESSAGE
92
+ address_book_person_proto.type_name = 'Person'
93
+ address_book_person_proto.name = 'person'
94
+ address_book_person_proto.number = 1
95
+
96
+ Protobuf::Descriptor::DescriptorBuilder.build(tutorial_proto)
97
+
98
+ assert_nothing_raised {Build::Tutorial::Person}
99
+ assert_nothing_raised {Build::Tutorial::Person.new}
100
+ assert_equal(['email', 'id', 'name', 'phone'],
101
+ Build::Tutorial::Person.fields.map{|tag, field| field.name}.sort)
102
+
103
+ assert_nothing_raised {Build::Tutorial::Person::PhoneNumber}
104
+ assert_nothing_raised {Build::Tutorial::Person::PhoneNumber.new}
105
+ assert_equal(['number', 'type'],
106
+ Build::Tutorial::Person::PhoneNumber.fields.map{|tag, field| field.name}.sort)
107
+
108
+ assert_nothing_raised {Build::Tutorial::Person::PhoneType}
109
+ assert_equal(0, Build::Tutorial::Person::PhoneType::MOBILE)
110
+ assert_equal(1, Build::Tutorial::Person::PhoneType::HOME)
111
+ assert_equal(2, Build::Tutorial::Person::PhoneType::WORK)
112
+
113
+ assert_nothing_raised {Build::Tutorial::AddressBook}
114
+ end
115
+
116
+ def test_unbuild
117
+ proto = Protobuf::Descriptor::FileDescriptor.unbuild(Tutorial::Person)
118
+ proto.serialize_to_file('person.bin')
119
+ puts
120
+ puts "run `test/check_unbuild.rb'"
121
+ end
122
+ end
@@ -0,0 +1,41 @@
1
+ require 'test/unit'
2
+ require 'protobuf/message/message'
3
+ require 'protobuf/message/enum'
4
+ require 'test/proto/addressbook.pb'
5
+ require 'test/proto/addressbook_base.pb'
6
+
7
+ class EnumValueTest < Test::Unit::TestCase
8
+ def test_enum_value
9
+ e = Protobuf::EnumValue.new(Object, :name, 100)
10
+ assert_kind_of(Protobuf::EnumValue, e)
11
+ assert_equal(:name, e.name)
12
+ assert_equal(100, e.value)
13
+ assert_equal('name', e.to_s)
14
+ assert_equal('name', "#{e}")
15
+ assert(e == 100)
16
+ assert(100 == e)
17
+ assert(101, e + 1)
18
+ assert(101, 1 + e)
19
+ end
20
+
21
+ def test_enum_field_and_enum_value
22
+ phone_number = Tutorial::Person::PhoneNumber.new
23
+
24
+ assert_kind_of(Protobuf::EnumValue, phone_number.type)
25
+ assert_equal(Tutorial::Person::PhoneType::HOME, phone_number.type)
26
+
27
+ phone_number.type = 1
28
+ assert_kind_of(Protobuf::EnumValue, phone_number.type)
29
+ assert_equal(Tutorial::Person::PhoneType::HOME, phone_number.type)
30
+ assert_equal(1, phone_number.type)
31
+
32
+ phone_number.type = :HOME
33
+ assert_kind_of(Protobuf::EnumValue, phone_number.type)
34
+ assert_equal(Tutorial::Person::PhoneType::HOME, phone_number.type)
35
+ assert_equal(1, phone_number.type)
36
+
37
+ assert_raise(TypeError) do
38
+ phone_number.type = TutorialExt::Person::PhoneType::HOME
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,36 @@
1
+ require 'test/unit'
2
+ require 'test/proto/addressbook_ext.pb'
3
+
4
+ class ExtensionTest < Test::Unit::TestCase
5
+ def test_accessor
6
+ assert(TutorialExt::Person.extension_fields.to_a.map{|t, f| f.name}.include?(:age))
7
+ person = TutorialExt::Person.new
8
+ assert_nothing_raised {person.age = 100}
9
+ assert_equal(100, person.age)
10
+ end
11
+
12
+ def test_serialize
13
+ # serialize to string
14
+ person = TutorialExt::Person.new
15
+ person.id = 1234
16
+ person.age = 70
17
+ person.name = 'John Doe'
18
+ person.email = 'jdoe@example.com'
19
+ phone = TutorialExt::Person::PhoneNumber.new
20
+ phone.number = '555-4321'
21
+ phone.type = TutorialExt::Person::PhoneType::HOME
22
+ person.phone << phone
23
+ serialized_string = person.serialize_to_string
24
+
25
+ # parse the serialized string
26
+ person2 = TutorialExt::Person.new
27
+ person2.parse_from_string serialized_string
28
+ assert_equal(1234, person2.id)
29
+ assert_equal(70, person2.age)
30
+ assert_equal('John Doe', person2.name)
31
+ assert_equal('jdoe@example.com', person2.email)
32
+ assert_equal(1, person2.phone.size)
33
+ assert_equal('555-4321', person2.phone[0].number)
34
+ assert_equal(TutorialExt::Person::PhoneType::HOME, person2.phone[0].type)
35
+ end
36
+ end
@@ -0,0 +1,11 @@
1
+ require 'test/unit'
2
+ require 'test/proto/lowercase.pb'
3
+
4
+ class LowercaseTest < Test::Unit::TestCase
5
+ def test_lowercase
6
+ message = nil
7
+ assert_nothing_raised { message = Test::Lowercase::Baaz.new }
8
+ assert_nothing_raised { message.x = Test::Lowercase::Foo::Bar.new }
9
+ assert_equal(Test::Lowercase::Foo::Bar, message.get_field_by_name(:x).type)
10
+ end
11
+ end
@@ -0,0 +1,128 @@
1
+ require 'protobuf/message/message'
2
+ require 'test/proto/addressbook.pb'
3
+ require 'test/proto/merge.pb'
4
+ require 'test/unit'
5
+
6
+ # It should not conflict with Test::InnerMessage1 which is included in merge.proto
7
+ class InnerMessage1; end
8
+
9
+ class MessageTest < Test::Unit::TestCase
10
+ def test_equality
11
+ person1 = Tutorial::Person.new :name => 'ando'
12
+ person2 = Tutorial::Person.new :name => 'ando'
13
+ person3 = Tutorial::Person.new :name => 'Ando'
14
+ assert(person1 == person2)
15
+ assert(person1 != person3)
16
+ assert(person1 != 'ando')
17
+ end
18
+
19
+ def test_bracketed_access
20
+ person = Tutorial::Person.new
21
+ name_tag = 1
22
+ person[name_tag] = 'Ichiro'
23
+ assert_equal('Ichiro', person.name)
24
+ assert_equal('Ichiro', person[name_tag])
25
+
26
+ person[:id] = 100
27
+ assert_equal(100, person.id)
28
+ person['id'] = 200
29
+ assert_equal(200, person.id)
30
+ assert_equal(200, person[:id])
31
+ assert_equal(200, person['id'])
32
+ end
33
+
34
+ def test_initialize_with_hash
35
+ person = Tutorial::Person.new(:name => 'Jiro', :id => 300, :email => 'jiro@ema.il')
36
+ assert_equal('Jiro', person.name)
37
+ assert_equal(300, person.id)
38
+ assert_equal('jiro@ema.il', person.email)
39
+
40
+ # initialize with array of hash
41
+ person = Tutorial::Person.new(:phone => [{:number => 'phone1'}, {:number => 'phone2'}])
42
+ assert_equal('phone1', person.phone[0].number)
43
+ assert_equal('phone2', person.phone[1].number)
44
+
45
+ # initalize with hash in hash
46
+ message = Test::MergeMessage.new(:require_message => { :name => 'name1', :repeate_message => [{:name => 'name2'}] })
47
+ assert_equal('name1', message.require_message.name)
48
+ assert_equal('name2', message.require_message.repeate_message[0].name)
49
+
50
+ message.require_message = { :name => 'name21' }
51
+ message.require_message.repeate_message = [ {:name => 'name22'} ]
52
+ assert_equal('name21', message.require_message.name)
53
+ assert_equal('name22', message.require_message.repeate_message[0].name)
54
+ assert_equal(1, message.require_message.repeate_message.size)
55
+ end
56
+
57
+ def test_defined_filenames
58
+ assert(Tutorial::Person.defined_filenames)
59
+ assert_equal(1, Tutorial::Person.defined_filenames.size)
60
+ assert_match(%r{/.*/proto/addressbook\.pb\.rb}, Tutorial::Person.defined_filenames.first)
61
+ end
62
+
63
+ def test_proto_filenames
64
+ assert(Tutorial::Person.proto_filenames)
65
+ assert_equal(1, Tutorial::Person.proto_filenames.size)
66
+ assert_equal('test/proto/addressbook.proto', Tutorial::Person.proto_filenames.first)
67
+ end
68
+
69
+ def test_proto_contents
70
+ assert_equal(<<-EOS.strip, Tutorial::Person.proto_contents.values.first.strip)
71
+ package tutorial;
72
+
73
+ message Person {
74
+ required string name = 1;
75
+ required int32 id = 2;
76
+ optional string email = 3;
77
+
78
+ enum PhoneType {
79
+ MOBILE = 0;
80
+ HOME = 1;
81
+ WORK = 2;
82
+ }
83
+
84
+ message PhoneNumber {
85
+ required string number = 1;
86
+ optional PhoneType type = 2 [default = HOME];
87
+ }
88
+
89
+ repeated PhoneNumber phone = 4;
90
+ optional uint32 age = 5 [default = 20];
91
+
92
+ extensions 100 to 200;
93
+ }
94
+
95
+ /*
96
+ extend Person {
97
+ optional int32 age = 100;
98
+ }
99
+ */
100
+
101
+ message AddressBook {
102
+ repeated Person person = 1;
103
+ }
104
+ EOS
105
+ end
106
+
107
+ def test_merge_field
108
+ inner_message1_2 = Test::MergeMessage::InnerMessage2.new(:name => 'name12')
109
+ inner_message1_2.repeate_message << Test::MergeMessage::InnerMessage1.new(:name => 'name121')
110
+ message1 = Test::MergeMessage.new(:name => 'name1', :require_message => inner_message1_2)
111
+ message1.repeate_message << Test::MergeMessage::InnerMessage1.new(:name => 'name11')
112
+
113
+ inner_message2_2 = Test::MergeMessage::InnerMessage2.new(:name => 'name22')
114
+ inner_message2_2.repeate_message << Test::MergeMessage::InnerMessage1.new(:name => 'name221')
115
+ message2 = Test::MergeMessage.new(:name => 'name2', :require_message => inner_message2_2)
116
+ message2.repeate_message << Test::MergeMessage::InnerMessage1.new(:name => 'name21')
117
+
118
+ message1.merge_from(message2)
119
+ assert_equal('name2', message1.name)
120
+ assert_equal(2, message1.repeate_message.size)
121
+ assert_equal('name11', message1.repeate_message[0].name)
122
+ assert_equal('name21', message1.repeate_message[1].name)
123
+ assert_equal('name22', message1.require_message.name)
124
+ assert_equal(2, message1.require_message.repeate_message.size)
125
+ assert_equal('name121', message1.require_message.repeate_message[0].name)
126
+ assert_equal('name221', message1.require_message.repeate_message[1].name)
127
+ end
128
+ end
@@ -0,0 +1,103 @@
1
+ require 'test/unit'
2
+ require 'test/proto/optional_field.pb'
3
+
4
+ class OptionalFieldTest < Test::Unit::TestCase
5
+ def test_accessor
6
+ message = Test::OptionalField::Message.new
7
+
8
+ # default values
9
+ assert(!message.has_field?(:number))
10
+ assert_equal(20, message.number)
11
+
12
+ assert(!message.has_field?(:text))
13
+ assert_equal('default string', message.text)
14
+
15
+ assert(!message.has_field?(:enum))
16
+ assert_equal(2, message.enum)
17
+
18
+ assert(!message.has_field?(:signed))
19
+ assert_equal(-100, message.signed)
20
+
21
+ # assign values
22
+ assert_nothing_raised { message.number = 100 }
23
+ assert(message.has_field?(:number))
24
+ assert_equal(100, message.number)
25
+
26
+ assert_nothing_raised { message.text = 'abc' }
27
+ assert(message.has_field?(:text))
28
+ assert_equal('abc', message.text)
29
+
30
+ assert_nothing_raised { message.enum = Test::OptionalField::Message::Enum::A }
31
+ assert(message.has_field?(:enum))
32
+ assert_equal(1, message.enum)
33
+
34
+ assert_nothing_raised { message.signed = -20 }
35
+ assert(message.has_field?(:signed))
36
+ assert_equal(-20, message.signed)
37
+ end
38
+
39
+ def test_serialize
40
+ message1 = Test::OptionalField::Message.new
41
+ message2 = Test::OptionalField::Message.new
42
+
43
+ # all fields are empty
44
+ serialized_string = message1.to_s
45
+ assert(serialized_string.empty?)
46
+ message2.parse_from_string(serialized_string)
47
+ assert_equal(message1.number, message2.number)
48
+ assert_equal(message1.text, message2.text)
49
+ assert_equal(message1.enum, message2.enum)
50
+ assert_equal(message1.signed, message2.signed)
51
+ assert(!message2.has_field?(:number))
52
+ assert(!message2.has_field?(:text))
53
+ assert(!message2.has_field?(:enum))
54
+ assert(!message2.has_field?(:signed))
55
+
56
+ # assign the value whith is equal to default value
57
+ message1 = Test::OptionalField::Message.new
58
+ message1.number = message1.number
59
+ message1.text = message1.text
60
+ message1.enum = message1.enum
61
+ message1.signed = message1.signed
62
+ serialized_string = message1.to_s
63
+ assert !serialized_string.empty?
64
+
65
+ # set some fields
66
+ message1 = Test::OptionalField::Message.new
67
+ message1.number = 100
68
+ message1.text = 'new text'
69
+ serialized_string = message1.to_s
70
+ message2.parse_from_string(serialized_string)
71
+ assert_equal(message1.number, message2.number)
72
+ assert_equal(message1.text, message2.text)
73
+ assert_equal(message1.enum, message2.enum)
74
+ assert_equal(message1.signed, message2.signed)
75
+ assert( message2.has_field?(:number))
76
+ assert( message2.has_field?(:text))
77
+ assert(!message2.has_field?(:enum))
78
+ assert(!message2.has_field?(:signed))
79
+ end
80
+
81
+ def test_merge_optional_fields
82
+ src1 = Test::OptionalField::Message.new
83
+ src2 = Test::OptionalField::Message.new
84
+ dst = Test::OptionalField::Message.new
85
+
86
+ src1.number = 100
87
+ src1.text = 'old'
88
+ src2.text = 'new'
89
+ src2.signed = 20
90
+
91
+ serialized_string = src1.to_s + src2.to_s
92
+ dst.parse_from_string(serialized_string)
93
+
94
+ assert_equal(100, dst.number)
95
+ assert_equal('new', dst.text)
96
+ assert_equal(20, dst.signed)
97
+ assert dst.has_field?(:number)
98
+ assert dst.has_field?(:text)
99
+ assert !dst.has_field?(:enum)
100
+ assert dst.has_field?(:signed)
101
+ end
102
+
103
+ end