ruby-protocol-buffers 1.5.1 → 1.6.0

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.
@@ -116,4 +116,26 @@ describe ProtocolBuffers, "message" do
116
116
 
117
117
  c.value_for_tag?(1).should == true
118
118
  end
119
+
120
+ it "correctly handles get" do
121
+ f = Featureful::A.new
122
+ f.i3 = 4
123
+ f.sub3.subsub1.subsub_payload = "sub3subsubpayload"
124
+
125
+ f.get(:sub3, :subsub1, :subsub_payload).should == "sub3subsubpayload"
126
+ f.get(:i3).should == 4
127
+ f.get(:i2).should == nil
128
+ f.get(:sub2).should == nil
129
+ end
130
+
131
+ it "correctly handles get!" do
132
+ f = Featureful::A.new
133
+ f.i3 = 4
134
+ f.sub3.subsub1.subsub_payload = "sub3subsubpayload"
135
+
136
+ f.get!(:sub3, :subsub1, :subsub_payload).should == "sub3subsubpayload"
137
+ f.get!(:i3).should == 4
138
+ proc { f.get!(:i2) }.should raise_error(ArgumentError)
139
+ proc { f.get!(:sub2) }.should raise_error(ArgumentError)
140
+ end
119
141
  end
@@ -9,25 +9,25 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
9
9
  require 'protocol_buffers'
10
10
 
11
11
  describe "Testing for decode errors for negative int32 fields" do
12
- # These should fail without the int32 negative handling fix
12
+ # These should fail without the int32 negative handling fix
13
13
  it "should return -1 given -1" do
14
- (validate_pbr(SignedIntTest, -1, true)).should be_true
14
+ (validate_pbr(SignedIntTest, -1, true)).should be true
15
15
  end
16
-
16
+
17
17
  it "should return -1111 given -1111" do
18
- (validate_pbr(SignedIntTest, -1111, true)).should be_true
18
+ (validate_pbr(SignedIntTest, -1111, true)).should be true
19
19
  end
20
-
20
+
21
21
  # These should pass with or without the negative handling fix
22
22
  it "should return 1 given 1" do
23
- (validate_pbr(SignedIntTest, 1, true)).should be_true
23
+ (validate_pbr(SignedIntTest, 1, true)).should be true
24
24
  end
25
-
25
+
26
26
  it "should return 0 given 0" do
27
- (validate_pbr(SignedIntTest, 0, true)).should be_true
27
+ (validate_pbr(SignedIntTest, 0, true)).should be true
28
28
  end
29
-
29
+
30
30
  it "should return 100000 given 100000" do
31
- (validate_pbr(SignedIntTest, 100000, true)).should be_true
31
+ (validate_pbr(SignedIntTest, 100000, true)).should be true
32
32
  end
33
33
  end
@@ -19,6 +19,6 @@ describe "testing handling of nil assignments to protobuffers" do
19
19
  test_pb.test_field_1 = nil
20
20
  test_pb.test_field_1 = nil
21
21
 
22
- (test_pb.to_s.length > 0).should be_true
22
+ (test_pb.to_s.length > 0).should be true
23
23
  end
24
24
  end
@@ -278,7 +278,7 @@ describe ProtocolBuffers, "runtime" do
278
278
  a1 = Featureful::A.new
279
279
  proc do
280
280
  a1.sub1 << Featureful::A::Sub.new
281
- end.should_not raise_error(TypeError)
281
+ end.should_not raise_error
282
282
 
283
283
  a1 = Featureful::A.new
284
284
  proc do
@@ -633,7 +633,7 @@ describe ProtocolBuffers, "runtime" do
633
633
  res2 = TehUnknown2::MyResult.parse(serialized)
634
634
  end.should_not raise_error()
635
635
 
636
- res2.value_for_tag?(1).should be_false
636
+ res2.value_for_tag?(1).should be false
637
637
  res2.unknown_field_count.should == 1
638
638
 
639
639
  serialized2 = res2.to_s
@@ -0,0 +1,679 @@
1
+ # -*- coding: UTF-8 -*-
2
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
3
+
4
+ describe ProtocolBuffers::TextScanner do
5
+ def scanned_list(text)
6
+ s = ProtocolBuffers::TextScanner.new(text)
7
+ s.enum_for(:scan).to_a
8
+ end
9
+
10
+ it "returns [false, nil] on the end" do
11
+ expect(scanned_list("")).to eq [[false, nil]]
12
+ end
13
+
14
+ it "returns [:bool, true] for 'true'" do
15
+ expect(scanned_list("true")).to eq [[:bool, true], [false, nil]]
16
+ end
17
+
18
+ it "returns [:bool, false] for 'false'" do
19
+ expect(scanned_list("false")).to eq [[:bool, false], [false, nil]]
20
+ end
21
+
22
+ %w( . : [ ] < > { } ).each do |c|
23
+ it "returns a single character token for #{c}" do
24
+ expect(scanned_list(c)).to eq [[c, c], [false, nil]]
25
+ end
26
+ end
27
+
28
+ it 'returns [:string, str] for a simple single quoted text' do
29
+ expect(scanned_list(%q['str'])).to eq [[:string, 'str'], [false, nil]]
30
+ end
31
+
32
+ it 'returns [:string, str] for a simple doubl quoted text' do
33
+ expect(scanned_list(%q["str"])).to eq [[:string, 'str'], [false, nil]]
34
+ end
35
+
36
+ it 'raises Racc::ParseError on unterminated quotation' do
37
+ expect {
38
+ scanned_list(%q['str])
39
+ }.to raise_error(Racc::ParseError, /unterminated string from line 1/)
40
+
41
+ expect {
42
+ scanned_list(%Q['str '\n'str])
43
+ }.to raise_error(Racc::ParseError, /unterminated string from line 2/)
44
+
45
+ expect {
46
+ scanned_list(%Q['str" 'str'])
47
+ }.to raise_error(Racc::ParseError, /unterminated string from line 1/)
48
+ end
49
+
50
+ it 'raises Racc::ParseError on multiline string' do
51
+ expect {
52
+ scanned_list(%Q['str\n'])
53
+ }.to raise_error(Racc::ParseError, /unterminated string from line 1/)
54
+ end
55
+
56
+ it 'understands hex escaped string' do
57
+ expect(scanned_list(%q["\\x12"])).to eq [[:string, "\x12"], [false, nil]]
58
+ expect(scanned_list(%q["\\X12"])).to eq [[:string, "\x12"], [false, nil]]
59
+
60
+ expect(scanned_list(%q['\\x12'])).to eq [[:string, "\x12"], [false, nil]]
61
+
62
+ expect(scanned_list(%q['\\xfghijk'])).to eq [[:string, "\x0f" + "ghijk"], [false, nil]]
63
+ end
64
+
65
+ it 'understands octal escaped string' do
66
+ expect(scanned_list(%q["\\012"])).to eq [[:string, "\012"], [false, nil]]
67
+ expect(scanned_list(%q['\\12'])).to eq [[:string, "\012"], [false, nil]]
68
+
69
+ expect(scanned_list(%q['\\0'])).to eq [[:string, "\0"], [false, nil]]
70
+
71
+ expect(scanned_list(%q['\\0012'])).to eq [[:string, "\001" + "2"], [false, nil]]
72
+ expect(scanned_list(%q['\\6789'])).to eq [[:string, "\067" + "89"], [false, nil]]
73
+ end
74
+
75
+ it 'understands named escaped string' do
76
+ input = %q[
77
+ "
78
+ \\a
79
+ \\b
80
+ \\f
81
+ \\n
82
+ \\r
83
+ \\t
84
+ \\v
85
+ \\\\
86
+ \\"
87
+ \\'
88
+ "
89
+ ].gsub(/\s/, '')
90
+ expect(scanned_list(input)).to eq [
91
+ [:string, "\a\b\f\n\r\t\v\\\"'"],
92
+ [false, nil]
93
+ ]
94
+ end
95
+
96
+ it 'accepts quoted punctuations' do
97
+ expect(scanned_list(%q[".:[]<>{}"])).to eq [[:string, ".:[]<>{}"], [false, nil]]
98
+ expect(scanned_list(%q["'"])).to eq [[:string, "'"], [false, nil]]
99
+ expect(scanned_list(%q['"'])).to eq [[:string, '"'], [false, nil]]
100
+ end
101
+
102
+ it 'leaves uninterpretable escape as is' do
103
+ expect(scanned_list(%q["\\c"])).to eq [[:string, "\\c"], [false, nil]]
104
+ expect(scanned_list(%q["\\u0030"])).to eq [[:string, "\\u0030"], [false, nil]]
105
+ end
106
+
107
+ it 'returns [:integer, value] for binary integer literal' do
108
+ expect(scanned_list('0b0101')).to eq [[:integer, 0b0101], [false, nil]]
109
+ expect(scanned_list('0B0101')).to eq [[:integer, 0b0101], [false, nil]]
110
+ expect(scanned_list('+0B0101')).to eq [[:integer, +0b0101], [false, nil]]
111
+ expect(scanned_list('-0B0101')).to eq [[:integer, -0b0101], [false, nil]]
112
+ end
113
+
114
+ it 'returns [:integer, value] for octal integer literal' do
115
+ expect(scanned_list('0123')).to eq [[:integer, 0123], [false, nil]]
116
+ expect(scanned_list('0o123')).to eq [[:integer, 0123], [false, nil]]
117
+ expect(scanned_list('0O123')).to eq [[:integer, 0123], [false, nil]]
118
+ expect(scanned_list('+0123')).to eq [[:integer, 0123], [false, nil]]
119
+ expect(scanned_list('+0o123')).to eq [[:integer, 0123], [false, nil]]
120
+ expect(scanned_list('-0123')).to eq [[:integer, -0123], [false, nil]]
121
+ expect(scanned_list('-0o123')).to eq [[:integer, -0123], [false, nil]]
122
+ end
123
+
124
+ it 'returns [:integer, value] for decimal integer literal' do
125
+ expect(scanned_list('12345')).to eq [[:integer, 12345], [false, nil]]
126
+ expect(scanned_list('0d12345')).to eq [[:integer, 12345], [false, nil]]
127
+ expect(scanned_list('0D12345')).to eq [[:integer, 12345], [false, nil]]
128
+ expect(scanned_list('+12345')).to eq [[:integer, 12345], [false, nil]]
129
+ expect(scanned_list('+0d12345')).to eq [[:integer, 12345], [false, nil]]
130
+ expect(scanned_list('-12345')).to eq [[:integer, -12345], [false, nil]]
131
+ expect(scanned_list('-0d12345')).to eq [[:integer, -12345], [false, nil]]
132
+ end
133
+
134
+ it 'returns [:integer, value] for hex integer literal' do
135
+ expect(scanned_list('0xABC12')).to eq [[:integer, 0xABC12], [false, nil]]
136
+ expect(scanned_list('0XABC12')).to eq [[:integer, 0xABC12], [false, nil]]
137
+ expect(scanned_list('+0xABC12')).to eq [[:integer, 0xABC12], [false, nil]]
138
+ expect(scanned_list('-0xABC12')).to eq [[:integer, -0xABC12], [false, nil]]
139
+ end
140
+
141
+ it 'returns [:integer, 0] for "0"' do
142
+ expect(scanned_list('0')).to eq [[:integer, 0], [false, nil]]
143
+ expect(scanned_list('+0')).to eq [[:integer, 0], [false, nil]]
144
+ expect(scanned_list('-0')).to eq [[:integer, 0], [false, nil]]
145
+ end
146
+
147
+ it 'returns [:float, value] for decimal float literal' do
148
+ expect(scanned_list('0.123')).to eq [[:float, 0.123], [false, nil]]
149
+ expect(scanned_list('12.34')).to eq [[:float, 12.34], [false, nil]]
150
+ expect(scanned_list('+0.123')).to eq [[:float, 0.123], [false, nil]]
151
+ expect(scanned_list('+12.34')).to eq [[:float, 12.34], [false, nil]]
152
+ expect(scanned_list('-0.123')).to eq [[:float, -0.123], [false, nil]]
153
+ expect(scanned_list('-12.34')).to eq [[:float, -12.34], [false, nil]]
154
+ expect(scanned_list('0.0')).to eq [[:float, 0.0], [false, nil]]
155
+ expect(scanned_list('+0.0')).to eq [[:float, 0.0], [false, nil]]
156
+ expect(scanned_list('-0.0')).to eq [[:float, -0.0], [false, nil]]
157
+ end
158
+
159
+ it 'returns [:float, value] for scientific float literal' do
160
+ expect(scanned_list('1.1e5')).to eq [[:float, 1.1e5], [false, nil]]
161
+ expect(scanned_list('1.1E5')).to eq [[:float, 1.1e5], [false, nil]]
162
+ expect(scanned_list('1.1e+5')).to eq [[:float, 1.1e5], [false, nil]]
163
+ expect(scanned_list('1.1e-5')).to eq [[:float, 1.1e-5], [false, nil]]
164
+ expect(scanned_list('1.1e0')).to eq [[:float, 1.1], [false, nil]]
165
+ expect(scanned_list('1.1e+0')).to eq [[:float, 1.1], [false, nil]]
166
+ expect(scanned_list('1.1e-0')).to eq [[:float, 1.1], [false, nil]]
167
+ end
168
+
169
+ it 'returns [:identifier, str] for identifiers' do
170
+ %w! abc ab_c _abc abc_ ABC AB_C _ABC ABC_ Abc AbC aBc !.each do |name|
171
+ expect(scanned_list(name)).to eq [[:identifier, name], [false, nil]]
172
+ end
173
+ end
174
+
175
+ it 'ignores spaces between tokens' do
176
+ expect(scanned_list("abc\n: def . ghi jk :\t'l : m' n\r: 012")).to eq [
177
+ [:identifier, 'abc'],
178
+ [':', ':'],
179
+ [:identifier, 'def'],
180
+ ['.', '.'],
181
+ [:identifier, 'ghi'],
182
+ [:identifier, 'jk'],
183
+ [':', ':'],
184
+ [:string, 'l : m'],
185
+ [:identifier, 'n'],
186
+ [':', ':'],
187
+ [:integer, 012],
188
+ [false, nil]
189
+ ]
190
+ end
191
+
192
+ it 'splits tokens without spaces' do
193
+ expect(scanned_list("abc:def.ghi jk:'l : m'n:012")).to eq [
194
+ [:identifier, 'abc'],
195
+ [':', ':'],
196
+ [:identifier, 'def'],
197
+ ['.', '.'],
198
+ [:identifier, 'ghi'],
199
+ [:identifier, 'jk'],
200
+ [':', ':'],
201
+ [:string, 'l : m'],
202
+ [:identifier, 'n'],
203
+ [':', ':'],
204
+ [:integer, 012],
205
+ [false, nil]
206
+ ]
207
+ end
208
+
209
+ it 'ignores comments' do
210
+ expect(scanned_list("#")).to eq [[false, nil]]
211
+ expect(scanned_list("#\n")).to eq [[false, nil]]
212
+ expect(scanned_list("# abc\n")).to eq [[false, nil]]
213
+ expect(scanned_list("abc #\n")).to eq [[:identifier, 'abc'], [false, nil]]
214
+ end
215
+ end
216
+
217
+ describe ProtocolBuffers::TextParser do
218
+ before(:each) do
219
+ @parser = ProtocolBuffers::TextParser.new
220
+ load File.join(File.dirname(__FILE__), "proto_files", "simple.pb.rb")
221
+ load File.join(File.dirname(__FILE__), "proto_files", "featureful.pb.rb")
222
+ end
223
+
224
+ it 'returns parsed message' do
225
+ m = ::Simple::Foo.new
226
+ tokens = [[false, nil]]
227
+ expect(@parser.parse_from_scanner(tokens, m)).to be_equal(m)
228
+ end
229
+
230
+ it 'accepts simple field' do
231
+ m = ::Simple::Test1.new
232
+ tokens = [
233
+ [:identifier, 'test_field'],
234
+ [':', ':'],
235
+ [:string, 'str'],
236
+ [false, nil]
237
+ ]
238
+ expect(@parser.parse_from_scanner(tokens, m)).to be_equal(m)
239
+ expect(m.test_field).to eq 'str'
240
+ end
241
+
242
+ it 'rejects unknown field name' do
243
+ m = ::Simple::Test1.new
244
+ tokens = [
245
+ [:identifier, 'no_such_field'],
246
+ [':', ':'],
247
+ [:string, 'str'],
248
+ [false, nil]
249
+ ]
250
+ expect {
251
+ @parser.parse_from_scanner(tokens, m)
252
+ }.to raise_error(Racc::ParseError, /no such field/)
253
+ end
254
+
255
+ it 'accepts nested field' do
256
+ m = ::Simple::Bar.new
257
+ tokens = [
258
+ [:identifier, 'foo'],
259
+ ['<', '<'],
260
+ ['>', '>'],
261
+ [false, nil]
262
+ ]
263
+ expect(@parser.parse_from_scanner(tokens, m)).to be_equal(m)
264
+ expect(m).to have_foo
265
+ end
266
+
267
+ it 'accepts nested field with colon' do
268
+ m = ::Simple::Bar.new
269
+ tokens = [
270
+ [:identifier, 'foo'],
271
+ [':', ':'],
272
+ ['<', '<'],
273
+ ['>', '>'],
274
+ [false, nil]
275
+ ]
276
+ expect(@parser.parse_from_scanner(tokens, m)).to be_equal(m)
277
+ expect(m).to have_foo
278
+ end
279
+
280
+
281
+ it 'accepts deeply nested field' do
282
+ m = ::Featureful::C.new
283
+ tokens = [
284
+ [:identifier, 'e'],
285
+ ['<', '<'],
286
+ [:identifier, 'd'],
287
+ ['<', '<'],
288
+ [:identifier, 'f'],
289
+ ['<', '<'],
290
+ [:identifier, 's'],
291
+ [':', ':'],
292
+ [:string, 'str'],
293
+ ['>', '>'],
294
+ ['>', '>'],
295
+ ['>', '>'],
296
+ [false, nil]
297
+ ]
298
+ expect(@parser.parse_from_scanner(tokens, m)).to be_equal(m)
299
+
300
+ expect(m).not_to have_d
301
+ expect(m).to have(1).e
302
+
303
+ expect(m.e[0]).to have_d
304
+ expect(m.e[0].d).to have(1).f
305
+
306
+ expect(m.e[0].d.f[0]).to have_s
307
+ expect(m.e[0].d.f[0].s).to eq 'str'
308
+ end
309
+
310
+ it 'accepts group field' do
311
+ m = ::Featureful::A::Group1.new
312
+ tokens = [
313
+ [:identifier, 'i1'],
314
+ [':', ':'],
315
+ [:integer, 1],
316
+ [:identifier, 'Subgroup'],
317
+ ['{', '{'],
318
+ [:identifier, 'i1'],
319
+ [':', ':'],
320
+ [:integer, 1],
321
+ ['}', '}'],
322
+ [false, nil]
323
+ ]
324
+ expect(@parser.parse_from_scanner(tokens, m)).to be_equal(m)
325
+
326
+ expect(m.i1).to eq(1)
327
+ expect(m).to have(1).subgroup
328
+ expect(m.subgroup[0].i1).to eq(1)
329
+ end
330
+
331
+ it 'accepts multiple values for repeated field' do
332
+ m = ::Featureful::D.new
333
+ tokens = [
334
+ [:identifier, 'f'],
335
+ ['<', '<'],
336
+ [:identifier, 's'],
337
+ [':', ':'],
338
+ [:string, 'str'],
339
+ ['>', '>'],
340
+ [:identifier, 'f'],
341
+ ['{', '{'],
342
+ [:identifier, 's'],
343
+ [':', ':'],
344
+ [:string, 'str2'],
345
+ ['}', '}'],
346
+ [:identifier, 'f'],
347
+ ['<', '<'],
348
+ ['>', '>'],
349
+ [false, nil]
350
+ ]
351
+ expect(@parser.parse_from_scanner(tokens, m)).to be_equal(m)
352
+
353
+ expect(m).to have(3).f
354
+ expect(m.f[0]).to have_s
355
+ expect(m.f[0].s).to eq 'str'
356
+ expect(m.f[1]).to have_s
357
+ expect(m.f[1].s).to eq 'str2'
358
+ expect(m.f[2]).not_to have_s
359
+ end
360
+
361
+ it 'rejects unterminated field' do
362
+ m = ::Simple::Test1.new
363
+ tokens = [
364
+ [:identifier, 'test_field'],
365
+ [':', ':'],
366
+ [false, nil]
367
+ ]
368
+ expect {
369
+ @parser.parse_from_scanner(tokens, m)
370
+ }.to raise_error(Racc::ParseError)
371
+
372
+ m = ::Simple::Test1.new
373
+ tokens = [
374
+ [:identifier, 'test_field'],
375
+ [false, nil]
376
+ ]
377
+ expect {
378
+ @parser.parse_from_scanner(tokens, m)
379
+ }.to raise_error(Racc::ParseError)
380
+ end
381
+
382
+ it 'accepts string field' do
383
+ m = ::Featureful::ABitOfEverything.new
384
+ tokens = [
385
+ [:identifier, 'string_field'],
386
+ [':', ':'],
387
+ [:string, 'str'],
388
+ [false, nil]
389
+ ]
390
+ expect(@parser.parse_from_scanner(tokens, m)).to be_equal(m)
391
+ expect(m.string_field).to eq 'str'
392
+ expect(m.string_field.encoding).to eq Encoding::UTF_8
393
+ end
394
+
395
+ it 'accepts bytes field' do
396
+ m = ::Featureful::ABitOfEverything.new
397
+ tokens = [
398
+ [:identifier, 'bytes_field'],
399
+ [':', ':'],
400
+ [:string, "bytes\x00\x01\x02\x03"],
401
+ [false, nil]
402
+ ]
403
+ expect(@parser.parse_from_scanner(tokens, m)).to be_equal(m)
404
+ expect(m.bytes_field).to eq "bytes\x00\x01\x02\x03"
405
+ end
406
+
407
+ it 'accepts float field' do
408
+ m = ::Featureful::ABitOfEverything.new
409
+ tokens = [
410
+ [:identifier, 'float_field'],
411
+ [':', ':'],
412
+ [:float, 1.1],
413
+ [:identifier, 'double_field'],
414
+ [':', ':'],
415
+ [:float, 1.1],
416
+ [false, nil]
417
+ ]
418
+ expect(@parser.parse_from_scanner(tokens, m)).to be_equal(m)
419
+ expect(m.float_field).to eq 1.1
420
+ expect(m.double_field).to eq 1.1
421
+ end
422
+
423
+ it 'accepts int field' do
424
+ m = ::Featureful::ABitOfEverything.new
425
+ tokens = [
426
+ [:identifier, 'int32_field'],
427
+ [':', ':'],
428
+ [:integer, 1],
429
+ [false, nil]
430
+ ]
431
+ expect(@parser.parse_from_scanner(tokens, m)).to be_equal(m)
432
+ expect(m.int32_field).to eq 1
433
+ end
434
+
435
+ it 'accepts bool field' do
436
+ m = ::Featureful::ABitOfEverything.new
437
+ tokens = [
438
+ [:identifier, 'bool_field'],
439
+ [':', ':'],
440
+ [:bool, true],
441
+ [false, nil]
442
+ ]
443
+ expect(@parser.parse_from_scanner(tokens, m)).to be_equal(m)
444
+ expect(m.bool_field).to be_true
445
+ end
446
+
447
+ it 'accepts integer as a enum field' do
448
+ m = ::Featureful::A::Sub.new
449
+ tokens = [
450
+ [:identifier, 'payload_type'],
451
+ [':', ':'],
452
+ [:integer, 1],
453
+ [false, nil]
454
+ ]
455
+ expect(@parser.parse_from_scanner(tokens, m)).to be_equal(m)
456
+ expect(m).to have_payload_type
457
+ expect(m.payload_type).to eq ::Featureful::A::Sub::Payloads::P2
458
+ end
459
+
460
+ it 'accepts enum name as a enum field' do
461
+ m = ::Featureful::A::Sub.new
462
+ tokens = [
463
+ [:identifier, 'payload_type'],
464
+ [':', ':'],
465
+ [:identifier, 'P2'],
466
+ [false, nil]
467
+ ]
468
+ expect(@parser.parse_from_scanner(tokens, m)).to be_equal(m)
469
+ expect(m).to have_payload_type
470
+ expect(m.payload_type).to eq ::Featureful::A::Sub::Payloads::P2
471
+ end
472
+
473
+ it 'concatenates strings' do
474
+ m = ::Simple::Test1.new
475
+ tokens = [
476
+ [:identifier, 'test_field'],
477
+ [':', ':'],
478
+ [:string, 'str'],
479
+ [:string, 'another str'],
480
+ [false, nil]
481
+ ]
482
+ expect(@parser.parse_from_scanner(tokens, m)).to be_equal(m)
483
+ expect(m.test_field).to eq 'stranother str'
484
+ end
485
+
486
+ it 'rejects unknown field' do
487
+ # The text format for unknown field is designed only for displaying a
488
+ # message to human.
489
+ # Since wire_types in it are ambigous, we cannot parse the notation.
490
+ m = ::Simple::Test1.new
491
+ tokens = [
492
+ [:integer, 1],
493
+ [':', ':'],
494
+ [:string, 'str'],
495
+ [false, nil]
496
+ ]
497
+ expect {
498
+ @parser.parse_from_scanner(tokens, m)
499
+ }.to raise_error(Racc::ParseError)
500
+ end
501
+ end
502
+
503
+ describe ProtocolBuffers::TextFormatter do
504
+ def formatter(options = nil)
505
+ ProtocolBuffers::TextFormatter.new(options)
506
+ end
507
+
508
+ # Returns a dummy instance of Featureful::A
509
+ def dummy_a
510
+ m = Featureful::A.new
511
+ m.i1 = [1, 2, 3]
512
+ m.i3 = 4
513
+
514
+ subsub = Featureful::A::Sub::SubSub.new(:subsub_payload => "foo")
515
+ m.sub1 = [
516
+ Featureful::A::Sub.new(:payload => "bar",
517
+ :payload_type => Featureful::A::Sub::Payloads::P1,
518
+ :subsub1 => subsub),
519
+ Featureful::A::Sub.new(:payload => "baz",
520
+ :payload_type => Featureful::A::Sub::Payloads::P2),
521
+ ]
522
+ m.sub3.payload = "qux"
523
+ m.sub3.payload_type = Featureful::A::Sub::Payloads::P1
524
+ m.sub3.subsub1.subsub_payload = "quux"
525
+
526
+ sg = Featureful::A::Group1::Subgroup.new(:i1 => 1)
527
+ m.group1 = [
528
+ Featureful::A::Group1.new(:i1 => 1, :subgroup => [sg]),
529
+ Featureful::A::Group1.new(:i1 => 2),
530
+ ]
531
+ m.group3.i1 = 5
532
+ m.group3.subgroup << Featureful::A::Group3::Subgroup.new(:i1 => 1)
533
+
534
+ m
535
+ end
536
+
537
+ before(:each) do
538
+ @parser = ProtocolBuffers::TextParser.new
539
+ load File.join(File.dirname(__FILE__), "proto_files", "simple.pb.rb")
540
+ load File.join(File.dirname(__FILE__), "proto_files", "featureful.pb.rb")
541
+ end
542
+
543
+ it "formats integer field in decimal" do
544
+ m = Featureful::ABitOfEverything.new
545
+ m.int32_field = 123
546
+ expect(m.text_format_to_string).to eq "int32_field: 123\n"
547
+ end
548
+
549
+ it "formats float field in decimal" do
550
+ m = Featureful::ABitOfEverything.new
551
+ m.float_field = 0.123
552
+ expect(m.text_format_to_string).to eq "float_field: 0.123\n"
553
+ end
554
+
555
+ it "formats string field with quotation" do
556
+ m = Featureful::ABitOfEverything.new
557
+ m.string_field = "str"
558
+ expect(m.text_format_to_string).to eq "string_field: \"str\"\n"
559
+ end
560
+
561
+ it "escapes non ascii printable characters in string field" do
562
+ str = "\xe3\x81\x82\0\n"
563
+ str.force_encoding(Encoding::UTF_8) if str.respond_to?(:force_encoding)
564
+ m = Featureful::ABitOfEverything.new
565
+ m.string_field = str
566
+
567
+ formatted = m.text_format_to_string
568
+ expect(formatted).to match(/\Astring_field: "(.*?)"\n/)
569
+
570
+ escaped = formatted[/string_field: (".*?")/, 1]
571
+ expect(escaped).to match(/\A[[:ascii:]&&[:print:]]+\z/)
572
+ expect(eval(escaped)).to eq str
573
+ end
574
+
575
+ it "escapes bytes in bytes field" do
576
+ m = Featureful::ABitOfEverything.new
577
+ m.bytes_field = "bytes"
578
+ expect(m.text_format_to_string).to eq "bytes_field: \"\\x62\\x79\\x74\\x65\\x73\"\n"
579
+ end
580
+
581
+ it "formats message field with indent" do
582
+ m = Featureful::E.new
583
+ m.d.f2.s = "str"
584
+ expect(m.text_format_to_string).to eq <<-EOS
585
+ d {
586
+ f2 {
587
+ s: "str"
588
+ }
589
+ }
590
+ EOS
591
+ end
592
+
593
+ it "formats group field with indent" do
594
+ m = Featureful::A::Group1.new
595
+ m.i1 = 1
596
+ m.subgroup << Featureful::A::Group1::Subgroup.new(:i1 => 1)
597
+ expect(m.text_format_to_string).to eq <<-EOS
598
+ i1: 1
599
+ Subgroup {
600
+ i1: 1
601
+ }
602
+ EOS
603
+ end
604
+
605
+ it "rejects invalid message" do
606
+ m = Featureful::A.new
607
+ expect {
608
+ m.text_format_to_string
609
+ }.to raise_error(ProtocolBuffers::EncodeError)
610
+ end
611
+
612
+ it "formats unknown field with tag number" do
613
+ m = ::Simple::Foo.new
614
+ m.remember_unknown_field(100 << 3 | ProtocolBuffers::WireTypes::VARINT, 1)
615
+ m.remember_unknown_field(101 << 3 | ProtocolBuffers::WireTypes::FIXED32, "\x01\x02\x03\x04")
616
+ m.remember_unknown_field(102 << 3 | ProtocolBuffers::WireTypes::FIXED64, "\x01\x02\x03\x04\x05\x06\x07\x08")
617
+ m.remember_unknown_field(103 << 3 | ProtocolBuffers::WireTypes::LENGTH_DELIMITED, "str")
618
+
619
+ group = ProtocolBuffers::Message.new
620
+ group.remember_unknown_field(1 << 3 | ProtocolBuffers::WireTypes::VARINT, 1)
621
+ subgroup = ProtocolBuffers::Message.new
622
+ subgroup.remember_unknown_field(1 << 3 | ProtocolBuffers::WireTypes::VARINT, 1)
623
+ group.remember_unknown_field(2 << 3 | ProtocolBuffers::WireTypes::START_GROUP, subgroup)
624
+ m.remember_unknown_field(104 << 3 | ProtocolBuffers::WireTypes::START_GROUP, group)
625
+
626
+ expect(m.text_format_to_string).to eq <<-EOS
627
+ 100: 1
628
+ 101: 0x04030201
629
+ 102: 0x0807060504030201
630
+ 103: "\\x73\\x74\\x72"
631
+ 104 {
632
+ 1: 1
633
+ 2 {
634
+ 1: 1
635
+ }
636
+ }
637
+ EOS
638
+ end
639
+
640
+ it "roundtrips with TextParser" do
641
+ m = dummy_a
642
+ parser = ProtocolBuffers::TextParser.new
643
+ parsed = Featureful::A.new
644
+ parser.parse_text(m.text_format_to_string, parsed)
645
+
646
+ expect(parsed).to eq(m)
647
+ end
648
+
649
+ context "if option[:short] is specified" do
650
+ it "doesn't emit newline" do
651
+ m = Featureful::ABitOfEverything.new
652
+ m.int32_field = 123
653
+ expect(m.text_format_to_string(:short => true)).to eq "int32_field: 123"
654
+ end
655
+
656
+ it "separates fields with space" do
657
+ m = Featureful::ABitOfEverything.new
658
+ m.int32_field = 123
659
+ m.string_field = "str"
660
+ expect(m.text_format_to_string(:short => true)).to eq "int32_field: 123 string_field: \"str\""
661
+ end
662
+
663
+ it "formats message field with spaces" do
664
+ m = Featureful::E.new
665
+ m.d.f2.s = "str"
666
+ expect(m.text_format_to_string(:short => true)).to eq "d { f2 { s: \"str\" } }"
667
+ end
668
+
669
+ it "roundtrips with TextParser" do
670
+ m = dummy_a
671
+
672
+ parser = ProtocolBuffers::TextParser.new
673
+ parsed = Featureful::A.new
674
+ parser.parse_text(m.text_format_to_string(:short => true), parsed)
675
+
676
+ expect(parsed).to eq(m)
677
+ end
678
+ end
679
+ end