google-protobuf 3.1.0-java

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.

Potentially problematic release.


This version of google-protobuf might be problematic. Click here for more details.

@@ -0,0 +1,35 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # source: google/protobuf/struct.proto
3
+
4
+ require 'google/protobuf'
5
+
6
+ Google::Protobuf::DescriptorPool.generated_pool.build do
7
+ add_message "google.protobuf.Struct" do
8
+ map :fields, :string, :message, 1, "google.protobuf.Value"
9
+ end
10
+ add_message "google.protobuf.Value" do
11
+ oneof :kind do
12
+ optional :null_value, :enum, 1, "google.protobuf.NullValue"
13
+ optional :number_value, :double, 2
14
+ optional :string_value, :string, 3
15
+ optional :bool_value, :bool, 4
16
+ optional :struct_value, :message, 5, "google.protobuf.Struct"
17
+ optional :list_value, :message, 6, "google.protobuf.ListValue"
18
+ end
19
+ end
20
+ add_message "google.protobuf.ListValue" do
21
+ repeated :values, :message, 1, "google.protobuf.Value"
22
+ end
23
+ add_enum "google.protobuf.NullValue" do
24
+ value :NULL_VALUE, 0
25
+ end
26
+ end
27
+
28
+ module Google
29
+ module Protobuf
30
+ Struct = Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Struct").msgclass
31
+ Value = Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Value").msgclass
32
+ ListValue = Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.ListValue").msgclass
33
+ NullValue = Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.NullValue").enummodule
34
+ end
35
+ end
@@ -0,0 +1,17 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # source: google/protobuf/timestamp.proto
3
+
4
+ require 'google/protobuf'
5
+
6
+ Google::Protobuf::DescriptorPool.generated_pool.build do
7
+ add_message "google.protobuf.Timestamp" do
8
+ optional :seconds, :int64, 1
9
+ optional :nanos, :int32, 2
10
+ end
11
+ end
12
+
13
+ module Google
14
+ module Protobuf
15
+ Timestamp = Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Timestamp").msgclass
16
+ end
17
+ end
@@ -0,0 +1,89 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # source: google/protobuf/type.proto
3
+
4
+ require 'google/protobuf'
5
+
6
+ require 'google/protobuf/any_pb'
7
+ require 'google/protobuf/source_context_pb'
8
+ Google::Protobuf::DescriptorPool.generated_pool.build do
9
+ add_message "google.protobuf.Type" do
10
+ optional :name, :string, 1
11
+ repeated :fields, :message, 2, "google.protobuf.Field"
12
+ repeated :oneofs, :string, 3
13
+ repeated :options, :message, 4, "google.protobuf.Option"
14
+ optional :source_context, :message, 5, "google.protobuf.SourceContext"
15
+ optional :syntax, :enum, 6, "google.protobuf.Syntax"
16
+ end
17
+ add_message "google.protobuf.Field" do
18
+ optional :kind, :enum, 1, "google.protobuf.Field.Kind"
19
+ optional :cardinality, :enum, 2, "google.protobuf.Field.Cardinality"
20
+ optional :number, :int32, 3
21
+ optional :name, :string, 4
22
+ optional :type_url, :string, 6
23
+ optional :oneof_index, :int32, 7
24
+ optional :packed, :bool, 8
25
+ repeated :options, :message, 9, "google.protobuf.Option"
26
+ optional :json_name, :string, 10
27
+ optional :default_value, :string, 11
28
+ end
29
+ add_enum "google.protobuf.Field.Kind" do
30
+ value :TYPE_UNKNOWN, 0
31
+ value :TYPE_DOUBLE, 1
32
+ value :TYPE_FLOAT, 2
33
+ value :TYPE_INT64, 3
34
+ value :TYPE_UINT64, 4
35
+ value :TYPE_INT32, 5
36
+ value :TYPE_FIXED64, 6
37
+ value :TYPE_FIXED32, 7
38
+ value :TYPE_BOOL, 8
39
+ value :TYPE_STRING, 9
40
+ value :TYPE_GROUP, 10
41
+ value :TYPE_MESSAGE, 11
42
+ value :TYPE_BYTES, 12
43
+ value :TYPE_UINT32, 13
44
+ value :TYPE_ENUM, 14
45
+ value :TYPE_SFIXED32, 15
46
+ value :TYPE_SFIXED64, 16
47
+ value :TYPE_SINT32, 17
48
+ value :TYPE_SINT64, 18
49
+ end
50
+ add_enum "google.protobuf.Field.Cardinality" do
51
+ value :CARDINALITY_UNKNOWN, 0
52
+ value :CARDINALITY_OPTIONAL, 1
53
+ value :CARDINALITY_REQUIRED, 2
54
+ value :CARDINALITY_REPEATED, 3
55
+ end
56
+ add_message "google.protobuf.Enum" do
57
+ optional :name, :string, 1
58
+ repeated :enumvalue, :message, 2, "google.protobuf.EnumValue"
59
+ repeated :options, :message, 3, "google.protobuf.Option"
60
+ optional :source_context, :message, 4, "google.protobuf.SourceContext"
61
+ optional :syntax, :enum, 5, "google.protobuf.Syntax"
62
+ end
63
+ add_message "google.protobuf.EnumValue" do
64
+ optional :name, :string, 1
65
+ optional :number, :int32, 2
66
+ repeated :options, :message, 3, "google.protobuf.Option"
67
+ end
68
+ add_message "google.protobuf.Option" do
69
+ optional :name, :string, 1
70
+ optional :value, :message, 2, "google.protobuf.Any"
71
+ end
72
+ add_enum "google.protobuf.Syntax" do
73
+ value :SYNTAX_PROTO2, 0
74
+ value :SYNTAX_PROTO3, 1
75
+ end
76
+ end
77
+
78
+ module Google
79
+ module Protobuf
80
+ Type = Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Type").msgclass
81
+ Field = Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Field").msgclass
82
+ Field::Kind = Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Field.Kind").enummodule
83
+ Field::Cardinality = Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Field.Cardinality").enummodule
84
+ Enum = Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Enum").msgclass
85
+ EnumValue = Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.EnumValue").msgclass
86
+ Option = Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Option").msgclass
87
+ Syntax = Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Syntax").enummodule
88
+ end
89
+ end
@@ -0,0 +1,212 @@
1
+ #!/usr/bin/ruby
2
+ # Protocol Buffers - Google's data interchange format
3
+ # Copyright 2008 Google Inc. All rights reserved.
4
+ # https://developers.google.com/protocol-buffers/
5
+ #
6
+ # Redistribution and use in source and binary forms, with or without
7
+ # modification, are permitted provided that the following conditions are
8
+ # met:
9
+ #
10
+ # * Redistributions of source code must retain the above copyright
11
+ # notice, this list of conditions and the following disclaimer.
12
+ # * Redistributions in binary form must reproduce the above
13
+ # copyright notice, this list of conditions and the following disclaimer
14
+ # in the documentation and/or other materials provided with the
15
+ # distribution.
16
+ # * Neither the name of Google Inc. nor the names of its
17
+ # contributors may be used to endorse or promote products derived from
18
+ # this software without specific prior written permission.
19
+ #
20
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24
+ # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+
32
+ require 'google/protobuf/any_pb'
33
+ require 'google/protobuf/duration_pb'
34
+ require 'google/protobuf/field_mask_pb'
35
+ require 'google/protobuf/struct_pb'
36
+ require 'google/protobuf/timestamp_pb'
37
+
38
+ module Google
39
+ module Protobuf
40
+
41
+ Any.class_eval do
42
+ def pack(msg, type_url_prefix='type.googleapis.com/')
43
+ if type_url_prefix.empty? or type_url_prefix[-1] != '/' then
44
+ self.type_url = "#{type_url_prefix}/#{msg.class.descriptor.name}"
45
+ else
46
+ self.type_url = "#{type_url_prefix}#{msg.class.descriptor.name}"
47
+ end
48
+ self.value = msg.to_proto
49
+ end
50
+
51
+ def unpack(klass)
52
+ if self.is(klass) then
53
+ klass.decode(self.value)
54
+ else
55
+ nil
56
+ end
57
+ end
58
+
59
+ def type_name
60
+ return self.type_url.split("/")[-1]
61
+ end
62
+
63
+ def is(klass)
64
+ return self.type_name == klass.descriptor.name
65
+ end
66
+ end
67
+
68
+ Timestamp.class_eval do
69
+ def to_time
70
+ Time.at(self.to_f)
71
+ end
72
+
73
+ def from_time(time)
74
+ self.seconds = time.to_i
75
+ self.nanos = time.nsec
76
+ end
77
+
78
+ def to_i
79
+ self.seconds
80
+ end
81
+
82
+ def to_f
83
+ self.seconds + (self.nanos.to_f / 1_000_000_000)
84
+ end
85
+ end
86
+
87
+ Duration.class_eval do
88
+ def to_f
89
+ self.seconds + (self.nanos.to_f / 1_000_000_000)
90
+ end
91
+ end
92
+
93
+ class UnexpectedStructType < Google::Protobuf::Error; end
94
+
95
+ Value.class_eval do
96
+ def to_ruby(recursive = false)
97
+ case self.kind
98
+ when :struct_value
99
+ if recursive
100
+ self.struct_value.to_h
101
+ else
102
+ self.struct_value
103
+ end
104
+ when :list_value
105
+ if recursive
106
+ self.list_value.to_a
107
+ else
108
+ self.list_value
109
+ end
110
+ when :null_value
111
+ nil
112
+ when :number_value
113
+ self.number_value
114
+ when :string_value
115
+ self.string_value
116
+ when :bool_value
117
+ self.bool_value
118
+ else
119
+ raise UnexpectedStructType
120
+ end
121
+ end
122
+
123
+ def from_ruby(value)
124
+ case value
125
+ when NilClass
126
+ self.null_value = 0
127
+ when Numeric
128
+ self.number_value = value
129
+ when String
130
+ self.string_value = value
131
+ when TrueClass
132
+ self.bool_value = true
133
+ when FalseClass
134
+ self.bool_value = false
135
+ when Struct
136
+ self.struct_value = value
137
+ when Hash
138
+ self.struct_value = Struct.from_hash(value)
139
+ when ListValue
140
+ self.list_value = value
141
+ when Array
142
+ self.list_value = ListValue.from_a(value)
143
+ else
144
+ raise UnexpectedStructType
145
+ end
146
+ end
147
+ end
148
+
149
+ Struct.class_eval do
150
+ def [](key)
151
+ self.fields[key].to_ruby
152
+ end
153
+
154
+ def []=(key, value)
155
+ unless key.is_a?(String)
156
+ raise UnexpectedStructType, "Struct keys must be strings."
157
+ end
158
+ self.fields[key] ||= Google::Protobuf::Value.new
159
+ self.fields[key].from_ruby(value)
160
+ end
161
+
162
+ def to_h
163
+ ret = {}
164
+ self.fields.each { |key, val| ret[key] = val.to_ruby(true) }
165
+ ret
166
+ end
167
+
168
+ def self.from_hash(hash)
169
+ ret = Struct.new
170
+ hash.each { |key, val| ret[key] = val }
171
+ ret
172
+ end
173
+ end
174
+
175
+ ListValue.class_eval do
176
+ include Enumerable
177
+
178
+ def length
179
+ self.values.length
180
+ end
181
+
182
+ def [](index)
183
+ self.values[index].to_ruby
184
+ end
185
+
186
+ def []=(index, value)
187
+ self.values[index].from_ruby(value)
188
+ end
189
+
190
+ def <<(value)
191
+ wrapper = Google::Protobuf::Value.new
192
+ wrapper.from_ruby(value)
193
+ self.values << wrapper
194
+ end
195
+
196
+ def each
197
+ self.values.each { |x| yield(x.to_ruby) }
198
+ end
199
+
200
+ def to_a
201
+ self.values.map { |x| x.to_ruby(true) }
202
+ end
203
+
204
+ def self.from_a(arr)
205
+ ret = ListValue.new
206
+ arr.each { |val| ret << val }
207
+ ret
208
+ end
209
+ end
210
+
211
+ end
212
+ end
@@ -0,0 +1,48 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # source: google/protobuf/wrappers.proto
3
+
4
+ require 'google/protobuf'
5
+
6
+ Google::Protobuf::DescriptorPool.generated_pool.build do
7
+ add_message "google.protobuf.DoubleValue" do
8
+ optional :value, :double, 1
9
+ end
10
+ add_message "google.protobuf.FloatValue" do
11
+ optional :value, :float, 1
12
+ end
13
+ add_message "google.protobuf.Int64Value" do
14
+ optional :value, :int64, 1
15
+ end
16
+ add_message "google.protobuf.UInt64Value" do
17
+ optional :value, :uint64, 1
18
+ end
19
+ add_message "google.protobuf.Int32Value" do
20
+ optional :value, :int32, 1
21
+ end
22
+ add_message "google.protobuf.UInt32Value" do
23
+ optional :value, :uint32, 1
24
+ end
25
+ add_message "google.protobuf.BoolValue" do
26
+ optional :value, :bool, 1
27
+ end
28
+ add_message "google.protobuf.StringValue" do
29
+ optional :value, :string, 1
30
+ end
31
+ add_message "google.protobuf.BytesValue" do
32
+ optional :value, :bytes, 1
33
+ end
34
+ end
35
+
36
+ module Google
37
+ module Protobuf
38
+ DoubleValue = Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.DoubleValue").msgclass
39
+ FloatValue = Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.FloatValue").msgclass
40
+ Int64Value = Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Int64Value").msgclass
41
+ UInt64Value = Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.UInt64Value").msgclass
42
+ Int32Value = Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Int32Value").msgclass
43
+ UInt32Value = Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.UInt32Value").msgclass
44
+ BoolValue = Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.BoolValue").msgclass
45
+ StringValue = Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.StringValue").msgclass
46
+ BytesValue = Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.BytesValue").msgclass
47
+ end
48
+ end
@@ -0,0 +1,1185 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'google/protobuf'
4
+ require 'test/unit'
5
+
6
+ # ------------- generated code --------------
7
+
8
+ module BasicTest
9
+ pool = Google::Protobuf::DescriptorPool.new
10
+ pool.build do
11
+ add_message "Foo" do
12
+ optional :bar, :message, 1, "Bar"
13
+ repeated :baz, :message, 2, "Baz"
14
+ end
15
+
16
+ add_message "Bar" do
17
+ optional :msg, :string, 1
18
+ end
19
+
20
+ add_message "Baz" do
21
+ optional :msg, :string, 1
22
+ end
23
+
24
+ add_message "TestMessage" do
25
+ optional :optional_int32, :int32, 1
26
+ optional :optional_int64, :int64, 2
27
+ optional :optional_uint32, :uint32, 3
28
+ optional :optional_uint64, :uint64, 4
29
+ optional :optional_bool, :bool, 5
30
+ optional :optional_float, :float, 6
31
+ optional :optional_double, :double, 7
32
+ optional :optional_string, :string, 8
33
+ optional :optional_bytes, :bytes, 9
34
+ optional :optional_msg, :message, 10, "TestMessage2"
35
+ optional :optional_enum, :enum, 11, "TestEnum"
36
+
37
+ repeated :repeated_int32, :int32, 12
38
+ repeated :repeated_int64, :int64, 13
39
+ repeated :repeated_uint32, :uint32, 14
40
+ repeated :repeated_uint64, :uint64, 15
41
+ repeated :repeated_bool, :bool, 16
42
+ repeated :repeated_float, :float, 17
43
+ repeated :repeated_double, :double, 18
44
+ repeated :repeated_string, :string, 19
45
+ repeated :repeated_bytes, :bytes, 20
46
+ repeated :repeated_msg, :message, 21, "TestMessage2"
47
+ repeated :repeated_enum, :enum, 22, "TestEnum"
48
+ end
49
+ add_message "TestMessage2" do
50
+ optional :foo, :int32, 1
51
+ end
52
+
53
+ add_message "Recursive1" do
54
+ optional :foo, :message, 1, "Recursive2"
55
+ end
56
+ add_message "Recursive2" do
57
+ optional :foo, :message, 1, "Recursive1"
58
+ end
59
+
60
+ add_enum "TestEnum" do
61
+ value :Default, 0
62
+ value :A, 1
63
+ value :B, 2
64
+ value :C, 3
65
+ end
66
+
67
+ add_message "BadFieldNames" do
68
+ optional :dup, :int32, 1
69
+ optional :class, :int32, 2
70
+ optional :"a.b", :int32, 3
71
+ end
72
+
73
+ add_message "MapMessage" do
74
+ map :map_string_int32, :string, :int32, 1
75
+ map :map_string_msg, :string, :message, 2, "TestMessage2"
76
+ end
77
+ add_message "MapMessageWireEquiv" do
78
+ repeated :map_string_int32, :message, 1, "MapMessageWireEquiv_entry1"
79
+ repeated :map_string_msg, :message, 2, "MapMessageWireEquiv_entry2"
80
+ end
81
+ add_message "MapMessageWireEquiv_entry1" do
82
+ optional :key, :string, 1
83
+ optional :value, :int32, 2
84
+ end
85
+ add_message "MapMessageWireEquiv_entry2" do
86
+ optional :key, :string, 1
87
+ optional :value, :message, 2, "TestMessage2"
88
+ end
89
+
90
+ add_message "OneofMessage" do
91
+ oneof :my_oneof do
92
+ optional :a, :string, 1
93
+ optional :b, :int32, 2
94
+ optional :c, :message, 3, "TestMessage2"
95
+ optional :d, :enum, 4, "TestEnum"
96
+ end
97
+ end
98
+ end
99
+
100
+ Foo = pool.lookup("Foo").msgclass
101
+ Bar = pool.lookup("Bar").msgclass
102
+ Baz = pool.lookup("Baz").msgclass
103
+ TestMessage = pool.lookup("TestMessage").msgclass
104
+ TestMessage2 = pool.lookup("TestMessage2").msgclass
105
+ Recursive1 = pool.lookup("Recursive1").msgclass
106
+ Recursive2 = pool.lookup("Recursive2").msgclass
107
+ TestEnum = pool.lookup("TestEnum").enummodule
108
+ BadFieldNames = pool.lookup("BadFieldNames").msgclass
109
+ MapMessage = pool.lookup("MapMessage").msgclass
110
+ MapMessageWireEquiv = pool.lookup("MapMessageWireEquiv").msgclass
111
+ MapMessageWireEquiv_entry1 =
112
+ pool.lookup("MapMessageWireEquiv_entry1").msgclass
113
+ MapMessageWireEquiv_entry2 =
114
+ pool.lookup("MapMessageWireEquiv_entry2").msgclass
115
+ OneofMessage = pool.lookup("OneofMessage").msgclass
116
+
117
+ # ------------ test cases ---------------
118
+
119
+ class MessageContainerTest < Test::Unit::TestCase
120
+
121
+ def test_defaults
122
+ m = TestMessage.new
123
+ assert m.optional_int32 == 0
124
+ assert m.optional_int64 == 0
125
+ assert m.optional_uint32 == 0
126
+ assert m.optional_uint64 == 0
127
+ assert m.optional_bool == false
128
+ assert m.optional_float == 0.0
129
+ assert m.optional_double == 0.0
130
+ assert m.optional_string == ""
131
+ assert m.optional_bytes == ""
132
+ assert m.optional_msg == nil
133
+ assert m.optional_enum == :Default
134
+ end
135
+
136
+ def test_setters
137
+ m = TestMessage.new
138
+ m.optional_int32 = -42
139
+ assert m.optional_int32 == -42
140
+ m.optional_int64 = -0x1_0000_0000
141
+ assert m.optional_int64 == -0x1_0000_0000
142
+ m.optional_uint32 = 0x9000_0000
143
+ assert m.optional_uint32 == 0x9000_0000
144
+ m.optional_uint64 = 0x9000_0000_0000_0000
145
+ assert m.optional_uint64 == 0x9000_0000_0000_0000
146
+ m.optional_bool = true
147
+ assert m.optional_bool == true
148
+ m.optional_float = 0.5
149
+ assert m.optional_float == 0.5
150
+ m.optional_double = 0.5
151
+ m.optional_string = "hello"
152
+ assert m.optional_string == "hello"
153
+ m.optional_bytes = "world".encode!('ASCII-8BIT')
154
+ assert m.optional_bytes == "world"
155
+ m.optional_msg = TestMessage2.new(:foo => 42)
156
+ assert m.optional_msg == TestMessage2.new(:foo => 42)
157
+ m.optional_msg = nil
158
+ assert m.optional_msg == nil
159
+ end
160
+
161
+ def test_ctor_args
162
+ m = TestMessage.new(:optional_int32 => -42,
163
+ :optional_msg => TestMessage2.new,
164
+ :optional_enum => :C,
165
+ :repeated_string => ["hello", "there", "world"])
166
+ assert m.optional_int32 == -42
167
+ assert m.optional_msg.class == TestMessage2
168
+ assert m.repeated_string.length == 3
169
+ assert m.optional_enum == :C
170
+ assert m.repeated_string[0] == "hello"
171
+ assert m.repeated_string[1] == "there"
172
+ assert m.repeated_string[2] == "world"
173
+ end
174
+
175
+ def test_inspect
176
+ m = TestMessage.new(:optional_int32 => -42,
177
+ :optional_enum => :A,
178
+ :optional_msg => TestMessage2.new,
179
+ :repeated_string => ["hello", "there", "world"])
180
+ expected = '<BasicTest::TestMessage: optional_int32: -42, optional_int64: 0, optional_uint32: 0, optional_uint64: 0, optional_bool: false, optional_float: 0.0, optional_double: 0.0, optional_string: "", optional_bytes: "", optional_msg: <BasicTest::TestMessage2: foo: 0>, optional_enum: :A, repeated_int32: [], repeated_int64: [], repeated_uint32: [], repeated_uint64: [], repeated_bool: [], repeated_float: [], repeated_double: [], repeated_string: ["hello", "there", "world"], repeated_bytes: [], repeated_msg: [], repeated_enum: []>'
181
+ assert_equal expected, m.inspect
182
+ end
183
+
184
+ def test_hash
185
+ m1 = TestMessage.new(:optional_int32 => 42)
186
+ m2 = TestMessage.new(:optional_int32 => 102, repeated_string: ['please', 'work', 'ok?'])
187
+ m3 = TestMessage.new(:optional_int32 => 102, repeated_string: ['please', 'work', 'ok?'])
188
+ assert m1.hash != 0
189
+ assert m2.hash != 0
190
+ assert m3.hash != 0
191
+ # relying on the randomness here -- if hash function changes and we are
192
+ # unlucky enough to get a collision, then change the values above.
193
+ assert m1.hash != m2.hash
194
+ assert_equal m2.hash, m3.hash
195
+ end
196
+
197
+ def test_unknown_field_errors
198
+ e = assert_raise NoMethodError do
199
+ TestMessage.new.hello
200
+ end
201
+ assert_match(/hello/, e.message)
202
+
203
+ e = assert_raise NoMethodError do
204
+ TestMessage.new.hello = "world"
205
+ end
206
+ assert_match(/hello/, e.message)
207
+ end
208
+
209
+ def test_initialization_map_errors
210
+ e = assert_raise ArgumentError do
211
+ TestMessage.new(:hello => "world")
212
+ end
213
+ assert_match(/hello/, e.message)
214
+
215
+ e = assert_raise ArgumentError do
216
+ MapMessage.new(:map_string_int32 => "hello")
217
+ end
218
+ assert_equal e.message, "Expected Hash object as initializer value for map field 'map_string_int32'."
219
+
220
+ e = assert_raise ArgumentError do
221
+ TestMessage.new(:repeated_uint32 => "hello")
222
+ end
223
+ assert_equal e.message, "Expected array as initializer value for repeated field 'repeated_uint32'."
224
+ end
225
+
226
+ def test_type_errors
227
+ m = TestMessage.new
228
+ assert_raise TypeError do
229
+ m.optional_int32 = "hello"
230
+ end
231
+ assert_raise TypeError do
232
+ m.optional_string = 42
233
+ end
234
+ assert_raise TypeError do
235
+ m.optional_string = nil
236
+ end
237
+ assert_raise TypeError do
238
+ m.optional_bool = 42
239
+ end
240
+ assert_raise TypeError do
241
+ m.optional_msg = TestMessage.new # expects TestMessage2
242
+ end
243
+
244
+ assert_raise TypeError do
245
+ m.repeated_int32 = [] # needs RepeatedField
246
+ end
247
+
248
+ assert_raise TypeError do
249
+ m.repeated_int32.push "hello"
250
+ end
251
+
252
+ assert_raise TypeError do
253
+ m.repeated_msg.push TestMessage.new
254
+ end
255
+ end
256
+
257
+ def test_string_encoding
258
+ m = TestMessage.new
259
+
260
+ # Assigning a normal (ASCII or UTF8) string to a bytes field, or
261
+ # ASCII-8BIT to a string field will convert to the proper encoding.
262
+ m.optional_bytes = "Test string ASCII".encode!('ASCII')
263
+ assert m.optional_bytes.frozen?
264
+ assert_equal Encoding::ASCII_8BIT, m.optional_bytes.encoding
265
+ assert_equal "Test string ASCII", m.optional_bytes
266
+
267
+ assert_raise Encoding::UndefinedConversionError do
268
+ m.optional_bytes = "Test string UTF-8 \u0100".encode!('UTF-8')
269
+ end
270
+
271
+ assert_raise Encoding::UndefinedConversionError do
272
+ m.optional_string = ["FFFF"].pack('H*')
273
+ end
274
+
275
+ # "Ordinary" use case.
276
+ m.optional_bytes = ["FFFF"].pack('H*')
277
+ m.optional_string = "\u0100"
278
+
279
+ # strings are immutable so we can't do this, but serialize should catch it.
280
+ m.optional_string = "asdf".encode!('UTF-8')
281
+ assert_raise RuntimeError do
282
+ m.optional_string.encode!('ASCII-8BIT')
283
+ end
284
+ end
285
+
286
+ def test_rptfield_int32
287
+ l = Google::Protobuf::RepeatedField.new(:int32)
288
+ assert l.count == 0
289
+ l = Google::Protobuf::RepeatedField.new(:int32, [1, 2, 3])
290
+ assert l.count == 3
291
+ assert_equal [1, 2, 3], l
292
+ assert_equal l, [1, 2, 3]
293
+ l.push 4
294
+ assert l == [1, 2, 3, 4]
295
+ dst_list = []
296
+ l.each { |val| dst_list.push val }
297
+ assert dst_list == [1, 2, 3, 4]
298
+ assert l.to_a == [1, 2, 3, 4]
299
+ assert l[0] == 1
300
+ assert l[3] == 4
301
+ l[0] = 5
302
+ assert l == [5, 2, 3, 4]
303
+
304
+ l2 = l.dup
305
+ assert l == l2
306
+ assert l.object_id != l2.object_id
307
+ l2.push 6
308
+ assert l.count == 4
309
+ assert l2.count == 5
310
+
311
+ assert l.inspect == '[5, 2, 3, 4]'
312
+
313
+ l.concat([7, 8, 9])
314
+ assert l == [5, 2, 3, 4, 7, 8, 9]
315
+ assert l.pop == 9
316
+ assert l == [5, 2, 3, 4, 7, 8]
317
+
318
+ assert_raise TypeError do
319
+ m = TestMessage.new
320
+ l.push m
321
+ end
322
+
323
+ m = TestMessage.new
324
+ m.repeated_int32 = l
325
+ assert m.repeated_int32 == [5, 2, 3, 4, 7, 8]
326
+ assert m.repeated_int32.object_id == l.object_id
327
+ l.push 42
328
+ assert m.repeated_int32.pop == 42
329
+
330
+ l3 = l + l.dup
331
+ assert l3.count == l.count * 2
332
+ l.count.times do |i|
333
+ assert l3[i] == l[i]
334
+ assert l3[l.count + i] == l[i]
335
+ end
336
+
337
+ l.clear
338
+ assert l.count == 0
339
+ l += [1, 2, 3, 4]
340
+ l.replace([5, 6, 7, 8])
341
+ assert l == [5, 6, 7, 8]
342
+
343
+ l4 = Google::Protobuf::RepeatedField.new(:int32)
344
+ l4[5] = 42
345
+ assert l4 == [0, 0, 0, 0, 0, 42]
346
+
347
+ l4 << 100
348
+ assert l4 == [0, 0, 0, 0, 0, 42, 100]
349
+ l4 << 101 << 102
350
+ assert l4 == [0, 0, 0, 0, 0, 42, 100, 101, 102]
351
+ end
352
+
353
+ def test_parent_rptfield
354
+ #make sure we set the RepeatedField and can add to it
355
+ m = TestMessage.new
356
+ assert m.repeated_string == []
357
+ m.repeated_string << 'ok'
358
+ m.repeated_string.push('ok2')
359
+ assert m.repeated_string == ['ok', 'ok2']
360
+ m.repeated_string += ['ok3']
361
+ assert m.repeated_string == ['ok', 'ok2', 'ok3']
362
+ end
363
+
364
+ def test_rptfield_msg
365
+ l = Google::Protobuf::RepeatedField.new(:message, TestMessage)
366
+ l.push TestMessage.new
367
+ assert l.count == 1
368
+ assert_raise TypeError do
369
+ l.push TestMessage2.new
370
+ end
371
+ assert_raise TypeError do
372
+ l.push 42
373
+ end
374
+
375
+ l2 = l.dup
376
+ assert l2[0] == l[0]
377
+ assert l2[0].object_id == l[0].object_id
378
+
379
+ l2 = Google::Protobuf.deep_copy(l)
380
+ assert l2[0] == l[0]
381
+ assert l2[0].object_id != l[0].object_id
382
+
383
+ l3 = l + l2
384
+ assert l3.count == 2
385
+ assert l3[0] == l[0]
386
+ assert l3[1] == l2[0]
387
+ l3[0].optional_int32 = 1000
388
+ assert l[0].optional_int32 == 1000
389
+
390
+ new_msg = TestMessage.new(:optional_int32 => 200)
391
+ l4 = l + [new_msg]
392
+ assert l4.count == 2
393
+ new_msg.optional_int32 = 1000
394
+ assert l4[1].optional_int32 == 1000
395
+ end
396
+
397
+ def test_rptfield_enum
398
+ l = Google::Protobuf::RepeatedField.new(:enum, TestEnum)
399
+ l.push :A
400
+ l.push :B
401
+ l.push :C
402
+ assert l.count == 3
403
+ assert_raise RangeError do
404
+ l.push :D
405
+ end
406
+ assert l[0] == :A
407
+
408
+ l.push 4
409
+ assert l[3] == 4
410
+ end
411
+
412
+ def test_rptfield_initialize
413
+ assert_raise ArgumentError do
414
+ l = Google::Protobuf::RepeatedField.new
415
+ end
416
+ assert_raise ArgumentError do
417
+ l = Google::Protobuf::RepeatedField.new(:message)
418
+ end
419
+ assert_raise ArgumentError do
420
+ l = Google::Protobuf::RepeatedField.new([1, 2, 3])
421
+ end
422
+ assert_raise ArgumentError do
423
+ l = Google::Protobuf::RepeatedField.new(:message, [TestMessage2.new])
424
+ end
425
+ end
426
+
427
+ def test_rptfield_array_ducktyping
428
+ l = Google::Protobuf::RepeatedField.new(:int32)
429
+ length_methods = %w(count length size)
430
+ length_methods.each do |lm|
431
+ assert l.send(lm) == 0
432
+ end
433
+ # out of bounds returns a nil
434
+ assert l[0] == nil
435
+ assert l[1] == nil
436
+ assert l[-1] == nil
437
+ l.push 4
438
+ length_methods.each do |lm|
439
+ assert l.send(lm) == 1
440
+ end
441
+ assert l[0] == 4
442
+ assert l[1] == nil
443
+ assert l[-1] == 4
444
+ assert l[-2] == nil
445
+
446
+ l.push 2
447
+ length_methods.each do |lm|
448
+ assert l.send(lm) == 2
449
+ end
450
+ assert l[0] == 4
451
+ assert l[1] == 2
452
+ assert l[2] == nil
453
+ assert l[-1] == 2
454
+ assert l[-2] == 4
455
+ assert l[-3] == nil
456
+
457
+ #adding out of scope will backfill with empty objects
458
+ end
459
+
460
+ def test_map_basic
461
+ # allowed key types:
462
+ # :int32, :int64, :uint32, :uint64, :bool, :string, :bytes.
463
+
464
+ m = Google::Protobuf::Map.new(:string, :int32)
465
+ m["asdf"] = 1
466
+ assert m["asdf"] == 1
467
+ m["jkl;"] = 42
468
+ assert m == { "jkl;" => 42, "asdf" => 1 }
469
+ assert m.has_key?("asdf")
470
+ assert !m.has_key?("qwerty")
471
+ assert m.length == 2
472
+
473
+ m2 = m.dup
474
+ assert_equal m, m2
475
+ assert m.hash != 0
476
+ assert_equal m.hash, m2.hash
477
+
478
+ collected = {}
479
+ m.each { |k,v| collected[v] = k }
480
+ assert collected == { 42 => "jkl;", 1 => "asdf" }
481
+
482
+ assert m.delete("asdf") == 1
483
+ assert !m.has_key?("asdf")
484
+ assert m["asdf"] == nil
485
+ assert !m.has_key?("asdf")
486
+
487
+ # We only assert on inspect value when there is one map entry because the
488
+ # order in which elements appear is unspecified (depends on the internal
489
+ # hash function). We don't want a brittle test.
490
+ assert m.inspect == "{\"jkl;\"=>42}"
491
+
492
+ assert m.keys == ["jkl;"]
493
+ assert m.values == [42]
494
+
495
+ m.clear
496
+ assert m.length == 0
497
+ assert m == {}
498
+
499
+ assert_raise TypeError do
500
+ m[1] = 1
501
+ end
502
+ assert_raise RangeError do
503
+ m["asdf"] = 0x1_0000_0000
504
+ end
505
+ end
506
+
507
+ def test_map_ctor
508
+ m = Google::Protobuf::Map.new(:string, :int32,
509
+ {"a" => 1, "b" => 2, "c" => 3})
510
+ assert m == {"a" => 1, "c" => 3, "b" => 2}
511
+ end
512
+
513
+ def test_map_keytypes
514
+ m = Google::Protobuf::Map.new(:int32, :int32)
515
+ m[1] = 42
516
+ m[-1] = 42
517
+ assert_raise RangeError do
518
+ m[0x8000_0000] = 1
519
+ end
520
+ assert_raise TypeError do
521
+ m["asdf"] = 1
522
+ end
523
+
524
+ m = Google::Protobuf::Map.new(:int64, :int32)
525
+ m[0x1000_0000_0000_0000] = 1
526
+ assert_raise RangeError do
527
+ m[0x1_0000_0000_0000_0000] = 1
528
+ end
529
+ assert_raise TypeError do
530
+ m["asdf"] = 1
531
+ end
532
+
533
+ m = Google::Protobuf::Map.new(:uint32, :int32)
534
+ m[0x8000_0000] = 1
535
+ assert_raise RangeError do
536
+ m[0x1_0000_0000] = 1
537
+ end
538
+ assert_raise RangeError do
539
+ m[-1] = 1
540
+ end
541
+
542
+ m = Google::Protobuf::Map.new(:uint64, :int32)
543
+ m[0x8000_0000_0000_0000] = 1
544
+ assert_raise RangeError do
545
+ m[0x1_0000_0000_0000_0000] = 1
546
+ end
547
+ assert_raise RangeError do
548
+ m[-1] = 1
549
+ end
550
+
551
+ m = Google::Protobuf::Map.new(:bool, :int32)
552
+ m[true] = 1
553
+ m[false] = 2
554
+ assert_raise TypeError do
555
+ m[1] = 1
556
+ end
557
+ assert_raise TypeError do
558
+ m["asdf"] = 1
559
+ end
560
+
561
+ m = Google::Protobuf::Map.new(:string, :int32)
562
+ m["asdf"] = 1
563
+ assert_raise TypeError do
564
+ m[1] = 1
565
+ end
566
+ assert_raise Encoding::UndefinedConversionError do
567
+ bytestring = ["FFFF"].pack("H*")
568
+ m[bytestring] = 1
569
+ end
570
+
571
+ m = Google::Protobuf::Map.new(:bytes, :int32)
572
+ bytestring = ["FFFF"].pack("H*")
573
+ m[bytestring] = 1
574
+ # Allowed -- we will automatically convert to ASCII-8BIT.
575
+ m["asdf"] = 1
576
+ assert_raise TypeError do
577
+ m[1] = 1
578
+ end
579
+ end
580
+
581
+ def test_map_msg_enum_valuetypes
582
+ m = Google::Protobuf::Map.new(:string, :message, TestMessage)
583
+ m["asdf"] = TestMessage.new
584
+ assert_raise TypeError do
585
+ m["jkl;"] = TestMessage2.new
586
+ end
587
+
588
+ m = Google::Protobuf::Map.new(
589
+ :string, :message, TestMessage,
590
+ { "a" => TestMessage.new(:optional_int32 => 42),
591
+ "b" => TestMessage.new(:optional_int32 => 84) })
592
+ assert m.length == 2
593
+ assert m.values.map{|msg| msg.optional_int32}.sort == [42, 84]
594
+
595
+ m = Google::Protobuf::Map.new(:string, :enum, TestEnum,
596
+ { "x" => :A, "y" => :B, "z" => :C })
597
+ assert m.length == 3
598
+ assert m["z"] == :C
599
+ m["z"] = 2
600
+ assert m["z"] == :B
601
+ m["z"] = 4
602
+ assert m["z"] == 4
603
+ assert_raise RangeError do
604
+ m["z"] = :Z
605
+ end
606
+ assert_raise TypeError do
607
+ m["z"] = "z"
608
+ end
609
+ end
610
+
611
+ def test_map_dup_deep_copy
612
+ m = Google::Protobuf::Map.new(
613
+ :string, :message, TestMessage,
614
+ { "a" => TestMessage.new(:optional_int32 => 42),
615
+ "b" => TestMessage.new(:optional_int32 => 84) })
616
+
617
+ m2 = m.dup
618
+ assert m == m2
619
+ assert m.object_id != m2.object_id
620
+ assert m["a"].object_id == m2["a"].object_id
621
+ assert m["b"].object_id == m2["b"].object_id
622
+
623
+ m2 = Google::Protobuf.deep_copy(m)
624
+ assert m == m2
625
+ assert m.object_id != m2.object_id
626
+ assert m["a"].object_id != m2["a"].object_id
627
+ assert m["b"].object_id != m2["b"].object_id
628
+ end
629
+
630
+ def test_map_field
631
+ m = MapMessage.new
632
+ assert m.map_string_int32 == {}
633
+ assert m.map_string_msg == {}
634
+
635
+ m = MapMessage.new(
636
+ :map_string_int32 => {"a" => 1, "b" => 2},
637
+ :map_string_msg => {"a" => TestMessage2.new(:foo => 1),
638
+ "b" => TestMessage2.new(:foo => 2)})
639
+ assert m.map_string_int32.keys.sort == ["a", "b"]
640
+ assert m.map_string_int32["a"] == 1
641
+ assert m.map_string_msg["b"].foo == 2
642
+
643
+ m.map_string_int32["c"] = 3
644
+ assert m.map_string_int32["c"] == 3
645
+ m.map_string_msg["c"] = TestMessage2.new(:foo => 3)
646
+ assert m.map_string_msg["c"] == TestMessage2.new(:foo => 3)
647
+ m.map_string_msg.delete("b")
648
+ m.map_string_msg.delete("c")
649
+ assert m.map_string_msg == { "a" => TestMessage2.new(:foo => 1) }
650
+
651
+ assert_raise TypeError do
652
+ m.map_string_msg["e"] = TestMessage.new # wrong value type
653
+ end
654
+ # ensure nothing was added by the above
655
+ assert m.map_string_msg == { "a" => TestMessage2.new(:foo => 1) }
656
+
657
+ m.map_string_int32 = Google::Protobuf::Map.new(:string, :int32)
658
+ assert_raise TypeError do
659
+ m.map_string_int32 = Google::Protobuf::Map.new(:string, :int64)
660
+ end
661
+ assert_raise TypeError do
662
+ m.map_string_int32 = {}
663
+ end
664
+
665
+ assert_raise TypeError do
666
+ m = MapMessage.new(:map_string_int32 => { 1 => "I am not a number" })
667
+ end
668
+ end
669
+
670
+ def test_map_encode_decode
671
+ m = MapMessage.new(
672
+ :map_string_int32 => {"a" => 1, "b" => 2},
673
+ :map_string_msg => {"a" => TestMessage2.new(:foo => 1),
674
+ "b" => TestMessage2.new(:foo => 2)})
675
+ m2 = MapMessage.decode(MapMessage.encode(m))
676
+ assert m == m2
677
+
678
+ m3 = MapMessageWireEquiv.decode(MapMessage.encode(m))
679
+ assert m3.map_string_int32.length == 2
680
+
681
+ kv = {}
682
+ m3.map_string_int32.map { |msg| kv[msg.key] = msg.value }
683
+ assert kv == {"a" => 1, "b" => 2}
684
+
685
+ kv = {}
686
+ m3.map_string_msg.map { |msg| kv[msg.key] = msg.value }
687
+ assert kv == {"a" => TestMessage2.new(:foo => 1),
688
+ "b" => TestMessage2.new(:foo => 2)}
689
+ end
690
+
691
+ def test_oneof_descriptors
692
+ d = OneofMessage.descriptor
693
+ o = d.lookup_oneof("my_oneof")
694
+ assert o != nil
695
+ assert o.class == Google::Protobuf::OneofDescriptor
696
+ assert o.name == "my_oneof"
697
+ oneof_count = 0
698
+ d.each_oneof{ |oneof|
699
+ oneof_count += 1
700
+ assert oneof == o
701
+ }
702
+ assert oneof_count == 1
703
+ assert o.count == 4
704
+ field_names = o.map{|f| f.name}.sort
705
+ assert field_names == ["a", "b", "c", "d"]
706
+ end
707
+
708
+ def test_oneof
709
+ d = OneofMessage.new
710
+ assert d.a == ""
711
+ assert d.b == 0
712
+ assert d.c == nil
713
+ assert d.d == :Default
714
+ assert d.my_oneof == nil
715
+
716
+ d.a = "hi"
717
+ assert d.a == "hi"
718
+ assert d.b == 0
719
+ assert d.c == nil
720
+ assert d.d == :Default
721
+ assert d.my_oneof == :a
722
+
723
+ d.b = 42
724
+ assert d.a == ""
725
+ assert d.b == 42
726
+ assert d.c == nil
727
+ assert d.d == :Default
728
+ assert d.my_oneof == :b
729
+
730
+ d.c = TestMessage2.new(:foo => 100)
731
+ assert d.a == ""
732
+ assert d.b == 0
733
+ assert d.c.foo == 100
734
+ assert d.d == :Default
735
+ assert d.my_oneof == :c
736
+
737
+ d.d = :C
738
+ assert d.a == ""
739
+ assert d.b == 0
740
+ assert d.c == nil
741
+ assert d.d == :C
742
+ assert d.my_oneof == :d
743
+
744
+ d2 = OneofMessage.decode(OneofMessage.encode(d))
745
+ assert d2 == d
746
+
747
+ encoded_field_a = OneofMessage.encode(OneofMessage.new(:a => "string"))
748
+ encoded_field_b = OneofMessage.encode(OneofMessage.new(:b => 1000))
749
+ encoded_field_c = OneofMessage.encode(
750
+ OneofMessage.new(:c => TestMessage2.new(:foo => 1)))
751
+ encoded_field_d = OneofMessage.encode(OneofMessage.new(:d => :B))
752
+
753
+ d3 = OneofMessage.decode(
754
+ encoded_field_c + encoded_field_a + encoded_field_d)
755
+ assert d3.a == ""
756
+ assert d3.b == 0
757
+ assert d3.c == nil
758
+ assert d3.d == :B
759
+
760
+ d4 = OneofMessage.decode(
761
+ encoded_field_c + encoded_field_a + encoded_field_d +
762
+ encoded_field_c)
763
+ assert d4.a == ""
764
+ assert d4.b == 0
765
+ assert d4.c.foo == 1
766
+ assert d4.d == :Default
767
+
768
+ d5 = OneofMessage.new(:a => "hello")
769
+ assert d5.a == "hello"
770
+ d5.a = nil
771
+ assert d5.a == ""
772
+ assert OneofMessage.encode(d5) == ''
773
+ assert d5.my_oneof == nil
774
+ end
775
+
776
+ def test_enum_field
777
+ m = TestMessage.new
778
+ assert m.optional_enum == :Default
779
+ m.optional_enum = :A
780
+ assert m.optional_enum == :A
781
+ assert_raise RangeError do
782
+ m.optional_enum = :ASDF
783
+ end
784
+ m.optional_enum = 1
785
+ assert m.optional_enum == :A
786
+ m.optional_enum = 100
787
+ assert m.optional_enum == 100
788
+ end
789
+
790
+ def test_dup
791
+ m = TestMessage.new
792
+ m.optional_string = "hello"
793
+ m.optional_int32 = 42
794
+ tm1 = TestMessage2.new(:foo => 100)
795
+ tm2 = TestMessage2.new(:foo => 200)
796
+ m.repeated_msg.push tm1
797
+ assert m.repeated_msg[-1] == tm1
798
+ m.repeated_msg.push tm2
799
+ assert m.repeated_msg[-1] == tm2
800
+ m2 = m.dup
801
+ assert m == m2
802
+ m.optional_int32 += 1
803
+ assert m != m2
804
+ assert m.repeated_msg[0] == m2.repeated_msg[0]
805
+ assert m.repeated_msg[0].object_id == m2.repeated_msg[0].object_id
806
+ end
807
+
808
+ def test_deep_copy
809
+ m = TestMessage.new(:optional_int32 => 42,
810
+ :repeated_msg => [TestMessage2.new(:foo => 100)])
811
+ m2 = Google::Protobuf.deep_copy(m)
812
+ assert m == m2
813
+ assert m.repeated_msg == m2.repeated_msg
814
+ assert m.repeated_msg.object_id != m2.repeated_msg.object_id
815
+ assert m.repeated_msg[0].object_id != m2.repeated_msg[0].object_id
816
+ end
817
+
818
+ def test_eq
819
+ m = TestMessage.new(:optional_int32 => 42,
820
+ :repeated_int32 => [1, 2, 3])
821
+ m2 = TestMessage.new(:optional_int32 => 43,
822
+ :repeated_int32 => [1, 2, 3])
823
+ assert m != m2
824
+ end
825
+
826
+ def test_enum_lookup
827
+ assert TestEnum::A == 1
828
+ assert TestEnum::B == 2
829
+ assert TestEnum::C == 3
830
+
831
+ assert TestEnum::lookup(1) == :A
832
+ assert TestEnum::lookup(2) == :B
833
+ assert TestEnum::lookup(3) == :C
834
+
835
+ assert TestEnum::resolve(:A) == 1
836
+ assert TestEnum::resolve(:B) == 2
837
+ assert TestEnum::resolve(:C) == 3
838
+ end
839
+
840
+ def test_parse_serialize
841
+ m = TestMessage.new(:optional_int32 => 42,
842
+ :optional_string => "hello world",
843
+ :optional_enum => :B,
844
+ :repeated_string => ["a", "b", "c"],
845
+ :repeated_int32 => [42, 43, 44],
846
+ :repeated_enum => [:A, :B, :C, 100],
847
+ :repeated_msg => [TestMessage2.new(:foo => 1),
848
+ TestMessage2.new(:foo => 2)])
849
+ data = TestMessage.encode m
850
+ m2 = TestMessage.decode data
851
+ assert m == m2
852
+
853
+ data = Google::Protobuf.encode m
854
+ m2 = Google::Protobuf.decode(TestMessage, data)
855
+ assert m == m2
856
+ end
857
+
858
+ def test_encode_decode_helpers
859
+ m = TestMessage.new(:optional_string => 'foo', :repeated_string => ['bar1', 'bar2'])
860
+ assert_equal 'foo', m.optional_string
861
+ assert_equal ['bar1', 'bar2'], m.repeated_string
862
+
863
+ json = m.to_json
864
+ m2 = TestMessage.decode_json(json)
865
+ assert_equal 'foo', m2.optional_string
866
+ assert_equal ['bar1', 'bar2'], m2.repeated_string
867
+ if RUBY_PLATFORM != "java"
868
+ assert m2.optional_string.frozen?
869
+ assert m2.repeated_string[0].frozen?
870
+ end
871
+
872
+ proto = m.to_proto
873
+ m2 = TestMessage.decode(proto)
874
+ assert_equal 'foo', m2.optional_string
875
+ assert_equal ['bar1', 'bar2'], m2.repeated_string
876
+ end
877
+
878
+ def test_protobuf_encode_decode_helpers
879
+ m = TestMessage.new(:optional_string => 'foo', :repeated_string => ['bar1', 'bar2'])
880
+ encoded_msg = Google::Protobuf.encode(m)
881
+ assert_equal m.to_proto, encoded_msg
882
+
883
+ decoded_msg = Google::Protobuf.decode(TestMessage, encoded_msg)
884
+ assert_equal TestMessage.decode(m.to_proto), decoded_msg
885
+ end
886
+
887
+ def test_protobuf_encode_decode_json_helpers
888
+ m = TestMessage.new(:optional_string => 'foo', :repeated_string => ['bar1', 'bar2'])
889
+ encoded_msg = Google::Protobuf.encode_json(m)
890
+ assert_equal m.to_json, encoded_msg
891
+
892
+ decoded_msg = Google::Protobuf.decode_json(TestMessage, encoded_msg)
893
+ assert_equal TestMessage.decode_json(m.to_json), decoded_msg
894
+ end
895
+
896
+ def test_to_h
897
+ m = TestMessage.new(:optional_bool => true, :optional_double => -10.100001, :optional_string => 'foo', :repeated_string => ['bar1', 'bar2'])
898
+ expected_result = {
899
+ :optional_bool=>true,
900
+ :optional_bytes=>"",
901
+ :optional_double=>-10.100001,
902
+ :optional_enum=>:Default,
903
+ :optional_float=>0.0,
904
+ :optional_int32=>0,
905
+ :optional_int64=>0,
906
+ :optional_msg=>nil,
907
+ :optional_string=>"foo",
908
+ :optional_uint32=>0,
909
+ :optional_uint64=>0,
910
+ :repeated_bool=>[],
911
+ :repeated_bytes=>[],
912
+ :repeated_double=>[],
913
+ :repeated_enum=>[],
914
+ :repeated_float=>[],
915
+ :repeated_int32=>[],
916
+ :repeated_int64=>[],
917
+ :repeated_msg=>[],
918
+ :repeated_string=>["bar1", "bar2"],
919
+ :repeated_uint32=>[],
920
+ :repeated_uint64=>[]
921
+ }
922
+ assert_equal expected_result, m.to_h
923
+ end
924
+
925
+
926
+ def test_def_errors
927
+ s = Google::Protobuf::DescriptorPool.new
928
+ assert_raise TypeError do
929
+ s.build do
930
+ # enum with no default (integer value 0)
931
+ add_enum "MyEnum" do
932
+ value :A, 1
933
+ end
934
+ end
935
+ end
936
+ assert_raise TypeError do
937
+ s.build do
938
+ # message with required field (unsupported in proto3)
939
+ add_message "MyMessage" do
940
+ required :foo, :int32, 1
941
+ end
942
+ end
943
+ end
944
+ end
945
+
946
+ def test_corecursive
947
+ # just be sure that we can instantiate types with corecursive field-type
948
+ # references.
949
+ m = Recursive1.new(:foo => Recursive2.new(:foo => Recursive1.new))
950
+ assert Recursive1.descriptor.lookup("foo").subtype ==
951
+ Recursive2.descriptor
952
+ assert Recursive2.descriptor.lookup("foo").subtype ==
953
+ Recursive1.descriptor
954
+
955
+ serialized = Recursive1.encode(m)
956
+ m2 = Recursive1.decode(serialized)
957
+ assert m == m2
958
+ end
959
+
960
+ def test_serialize_cycle
961
+ m = Recursive1.new(:foo => Recursive2.new)
962
+ m.foo.foo = m
963
+ assert_raise RuntimeError do
964
+ serialized = Recursive1.encode(m)
965
+ end
966
+ end
967
+
968
+ def test_bad_field_names
969
+ m = BadFieldNames.new(:dup => 1, :class => 2)
970
+ m2 = m.dup
971
+ assert m == m2
972
+ assert m['dup'] == 1
973
+ assert m['class'] == 2
974
+ m['dup'] = 3
975
+ assert m['dup'] == 3
976
+ m['a.b'] = 4
977
+ assert m['a.b'] == 4
978
+ end
979
+
980
+ def test_int_ranges
981
+ m = TestMessage.new
982
+
983
+ m.optional_int32 = 0
984
+ m.optional_int32 = -0x8000_0000
985
+ m.optional_int32 = +0x7fff_ffff
986
+ m.optional_int32 = 1.0
987
+ m.optional_int32 = -1.0
988
+ m.optional_int32 = 2e9
989
+ assert_raise RangeError do
990
+ m.optional_int32 = -0x8000_0001
991
+ end
992
+ assert_raise RangeError do
993
+ m.optional_int32 = +0x8000_0000
994
+ end
995
+ assert_raise RangeError do
996
+ m.optional_int32 = +0x1000_0000_0000_0000_0000_0000 # force Bignum
997
+ end
998
+ assert_raise RangeError do
999
+ m.optional_int32 = 1e12
1000
+ end
1001
+ assert_raise RangeError do
1002
+ m.optional_int32 = 1.5
1003
+ end
1004
+
1005
+ m.optional_uint32 = 0
1006
+ m.optional_uint32 = +0xffff_ffff
1007
+ m.optional_uint32 = 1.0
1008
+ m.optional_uint32 = 4e9
1009
+ assert_raise RangeError do
1010
+ m.optional_uint32 = -1
1011
+ end
1012
+ assert_raise RangeError do
1013
+ m.optional_uint32 = -1.5
1014
+ end
1015
+ assert_raise RangeError do
1016
+ m.optional_uint32 = -1.5e12
1017
+ end
1018
+ assert_raise RangeError do
1019
+ m.optional_uint32 = -0x1000_0000_0000_0000
1020
+ end
1021
+ assert_raise RangeError do
1022
+ m.optional_uint32 = +0x1_0000_0000
1023
+ end
1024
+ assert_raise RangeError do
1025
+ m.optional_uint32 = +0x1000_0000_0000_0000_0000_0000 # force Bignum
1026
+ end
1027
+ assert_raise RangeError do
1028
+ m.optional_uint32 = 1e12
1029
+ end
1030
+ assert_raise RangeError do
1031
+ m.optional_uint32 = 1.5
1032
+ end
1033
+
1034
+ m.optional_int64 = 0
1035
+ m.optional_int64 = -0x8000_0000_0000_0000
1036
+ m.optional_int64 = +0x7fff_ffff_ffff_ffff
1037
+ m.optional_int64 = 1.0
1038
+ m.optional_int64 = -1.0
1039
+ m.optional_int64 = 8e18
1040
+ m.optional_int64 = -8e18
1041
+ assert_raise RangeError do
1042
+ m.optional_int64 = -0x8000_0000_0000_0001
1043
+ end
1044
+ assert_raise RangeError do
1045
+ m.optional_int64 = +0x8000_0000_0000_0000
1046
+ end
1047
+ assert_raise RangeError do
1048
+ m.optional_int64 = +0x1000_0000_0000_0000_0000_0000 # force Bignum
1049
+ end
1050
+ assert_raise RangeError do
1051
+ m.optional_int64 = 1e50
1052
+ end
1053
+ assert_raise RangeError do
1054
+ m.optional_int64 = 1.5
1055
+ end
1056
+
1057
+ m.optional_uint64 = 0
1058
+ m.optional_uint64 = +0xffff_ffff_ffff_ffff
1059
+ m.optional_uint64 = 1.0
1060
+ m.optional_uint64 = 16e18
1061
+ assert_raise RangeError do
1062
+ m.optional_uint64 = -1
1063
+ end
1064
+ assert_raise RangeError do
1065
+ m.optional_uint64 = -1.5
1066
+ end
1067
+ assert_raise RangeError do
1068
+ m.optional_uint64 = -1.5e12
1069
+ end
1070
+ assert_raise RangeError do
1071
+ m.optional_uint64 = -0x1_0000_0000_0000_0000
1072
+ end
1073
+ assert_raise RangeError do
1074
+ m.optional_uint64 = +0x1_0000_0000_0000_0000
1075
+ end
1076
+ assert_raise RangeError do
1077
+ m.optional_uint64 = +0x1000_0000_0000_0000_0000_0000 # force Bignum
1078
+ end
1079
+ assert_raise RangeError do
1080
+ m.optional_uint64 = 1e50
1081
+ end
1082
+ assert_raise RangeError do
1083
+ m.optional_uint64 = 1.5
1084
+ end
1085
+ end
1086
+
1087
+ def test_stress_test
1088
+ m = TestMessage.new
1089
+ m.optional_int32 = 42
1090
+ m.optional_int64 = 0x100000000
1091
+ m.optional_string = "hello world"
1092
+ 10.times do m.repeated_msg.push TestMessage2.new(:foo => 42) end
1093
+ 10.times do m.repeated_string.push "hello world" end
1094
+
1095
+ data = TestMessage.encode(m)
1096
+
1097
+ l = 0
1098
+ 10_000.times do
1099
+ m = TestMessage.decode(data)
1100
+ data_new = TestMessage.encode(m)
1101
+ assert data_new == data
1102
+ data = data_new
1103
+ end
1104
+ end
1105
+
1106
+ def test_reflection
1107
+ m = TestMessage.new(:optional_int32 => 1234)
1108
+ msgdef = m.class.descriptor
1109
+ assert msgdef.class == Google::Protobuf::Descriptor
1110
+ assert msgdef.any? {|field| field.name == "optional_int32"}
1111
+ optional_int32 = msgdef.lookup "optional_int32"
1112
+ assert optional_int32.class == Google::Protobuf::FieldDescriptor
1113
+ assert optional_int32 != nil
1114
+ assert optional_int32.name == "optional_int32"
1115
+ assert optional_int32.type == :int32
1116
+ optional_int32.set(m, 5678)
1117
+ assert m.optional_int32 == 5678
1118
+ m.optional_int32 = 1000
1119
+ assert optional_int32.get(m) == 1000
1120
+
1121
+ optional_msg = msgdef.lookup "optional_msg"
1122
+ assert optional_msg.subtype == TestMessage2.descriptor
1123
+
1124
+ optional_msg.set(m, optional_msg.subtype.msgclass.new)
1125
+
1126
+ assert msgdef.msgclass == TestMessage
1127
+
1128
+ optional_enum = msgdef.lookup "optional_enum"
1129
+ assert optional_enum.subtype == TestEnum.descriptor
1130
+ assert optional_enum.subtype.class == Google::Protobuf::EnumDescriptor
1131
+ optional_enum.subtype.each do |k, v|
1132
+ # set with integer, check resolution to symbolic name
1133
+ optional_enum.set(m, v)
1134
+ assert optional_enum.get(m) == k
1135
+ end
1136
+ end
1137
+
1138
+ def test_json
1139
+ # TODO: Fix JSON in JRuby version.
1140
+ return if RUBY_PLATFORM == "java"
1141
+ m = TestMessage.new(:optional_int32 => 1234,
1142
+ :optional_int64 => -0x1_0000_0000,
1143
+ :optional_uint32 => 0x8000_0000,
1144
+ :optional_uint64 => 0xffff_ffff_ffff_ffff,
1145
+ :optional_bool => true,
1146
+ :optional_float => 1.0,
1147
+ :optional_double => -1e100,
1148
+ :optional_string => "Test string",
1149
+ :optional_bytes => ["FFFFFFFF"].pack('H*'),
1150
+ :optional_msg => TestMessage2.new(:foo => 42),
1151
+ :repeated_int32 => [1, 2, 3, 4],
1152
+ :repeated_string => ["a", "b", "c"],
1153
+ :repeated_bool => [true, false, true, false],
1154
+ :repeated_msg => [TestMessage2.new(:foo => 1),
1155
+ TestMessage2.new(:foo => 2)])
1156
+
1157
+ json_text = TestMessage.encode_json(m)
1158
+ m2 = TestMessage.decode_json(json_text)
1159
+ assert m == m2
1160
+
1161
+ # Crash case from GitHub issue 283.
1162
+ bar = Bar.new(msg: "bar")
1163
+ baz1 = Baz.new(msg: "baz")
1164
+ baz2 = Baz.new(msg: "quux")
1165
+ Foo.encode_json(Foo.new)
1166
+ Foo.encode_json(Foo.new(bar: bar))
1167
+ Foo.encode_json(Foo.new(bar: bar, baz: [baz1, baz2]))
1168
+ end
1169
+
1170
+ def test_json_maps
1171
+ # TODO: Fix JSON in JRuby version.
1172
+ return if RUBY_PLATFORM == "java"
1173
+ m = MapMessage.new(:map_string_int32 => {"a" => 1})
1174
+ expected = '{"mapStringInt32":{"a":1},"mapStringMsg":{}}'
1175
+ expected_preserve = '{"map_string_int32":{"a":1},"map_string_msg":{}}'
1176
+ assert MapMessage.encode_json(m) == expected
1177
+
1178
+ json = MapMessage.encode_json(m, :preserve_proto_fieldnames => true)
1179
+ assert json == expected_preserve
1180
+
1181
+ m2 = MapMessage.decode_json(MapMessage.encode_json(m))
1182
+ assert m == m2
1183
+ end
1184
+ end
1185
+ end