google-protobuf 3.1.0-java

Sign up to get free protection for your applications and to get access to all the features.

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