ruby-protocol-buffers 1.5.1 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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