google-protobuf 3.0.0.alpha.1.0 → 3.0.0.alpha.1.1
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.
- checksums.yaml +8 -8
- data/ext/google/protobuf_c/defs.c +107 -6
- data/ext/google/protobuf_c/encode_decode.c +327 -90
- data/ext/google/protobuf_c/extconf.rb +1 -1
- data/ext/google/protobuf_c/map.c +805 -0
- data/ext/google/protobuf_c/message.c +12 -3
- data/ext/google/protobuf_c/protobuf.c +1 -0
- data/ext/google/protobuf_c/protobuf.h +82 -4
- data/ext/google/protobuf_c/repeated_field.c +5 -1
- data/ext/google/protobuf_c/storage.c +148 -41
- data/ext/google/protobuf_c/upb.c +810 -453
- data/ext/google/protobuf_c/upb.h +71 -12
- data/tests/basic.rb +262 -3
- metadata +3 -2
data/ext/google/protobuf_c/upb.h
CHANGED
@@ -600,6 +600,9 @@ typedef struct {
|
|
600
600
|
|
601
601
|
// Like strdup(), which isn't always available since it's not ANSI C.
|
602
602
|
char *upb_strdup(const char *s);
|
603
|
+
// Variant that works with a length-delimited rather than NULL-delimited string,
|
604
|
+
// as supported by strtable.
|
605
|
+
char *upb_strdup2(const char *s, size_t len);
|
603
606
|
|
604
607
|
UPB_INLINE void _upb_value_setval(upb_value *v, _upb_value val,
|
605
608
|
upb_ctype_t ctype) {
|
@@ -654,12 +657,24 @@ FUNCS(fptr, fptr, upb_func*, UPB_CTYPE_FPTR);
|
|
654
657
|
|
655
658
|
typedef union {
|
656
659
|
uintptr_t num;
|
657
|
-
|
660
|
+
struct {
|
661
|
+
// We own this. NULL-terminated but may also contain binary data; see
|
662
|
+
// explicit length below.
|
663
|
+
// TODO: move the length to the start of the string in order to reduce
|
664
|
+
// tabkey's size (to one machine word) in a way that supports static
|
665
|
+
// initialization.
|
666
|
+
const char *str;
|
667
|
+
size_t length;
|
668
|
+
} s;
|
658
669
|
} upb_tabkey;
|
659
670
|
|
660
671
|
#define UPB_TABKEY_NUM(n) {n}
|
661
672
|
#ifdef UPB_C99
|
662
|
-
|
673
|
+
// Given that |s| is a string literal, sizeof(s) gives us a
|
674
|
+
// compile-time-constant strlen(). We must ensure that this works for static
|
675
|
+
// data initializers.
|
676
|
+
#define UPB_TABKEY_STR(strval) { .s = { .str = strval, \
|
677
|
+
.length = sizeof(strval) - 1 } }
|
663
678
|
#endif
|
664
679
|
// TODO(haberman): C++
|
665
680
|
#define UPB_TABKEY_NONE {0}
|
@@ -765,7 +780,14 @@ UPB_INLINE size_t upb_strtable_count(const upb_strtable *t) {
|
|
765
780
|
// If a table resize was required but memory allocation failed, false is
|
766
781
|
// returned and the table is unchanged.
|
767
782
|
bool upb_inttable_insert(upb_inttable *t, uintptr_t key, upb_value val);
|
768
|
-
bool
|
783
|
+
bool upb_strtable_insert2(upb_strtable *t, const char *key, size_t len,
|
784
|
+
upb_value val);
|
785
|
+
|
786
|
+
// For NULL-terminated strings.
|
787
|
+
UPB_INLINE bool upb_strtable_insert(upb_strtable *t, const char *key,
|
788
|
+
upb_value val) {
|
789
|
+
return upb_strtable_insert2(t, key, strlen(key), val);
|
790
|
+
}
|
769
791
|
|
770
792
|
// Looks up key in this table, returning "true" if the key was found.
|
771
793
|
// If v is non-NULL, copies the value for this key into *v.
|
@@ -782,7 +804,14 @@ UPB_INLINE bool upb_strtable_lookup(const upb_strtable *t, const char *key,
|
|
782
804
|
// Removes an item from the table. Returns true if the remove was successful,
|
783
805
|
// and stores the removed item in *val if non-NULL.
|
784
806
|
bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val);
|
785
|
-
bool
|
807
|
+
bool upb_strtable_remove2(upb_strtable *t, const char *key, size_t len,
|
808
|
+
upb_value *val);
|
809
|
+
|
810
|
+
// For NULL-terminated strings.
|
811
|
+
UPB_INLINE bool upb_strtable_remove(upb_strtable *t, const char *key,
|
812
|
+
upb_value *v) {
|
813
|
+
return upb_strtable_remove2(t, key, strlen(key), v);
|
814
|
+
}
|
786
815
|
|
787
816
|
// Updates an existing entry in an inttable. If the entry does not exist,
|
788
817
|
// returns false and does nothing. Unlike insert/remove, this does not
|
@@ -876,6 +905,7 @@ void upb_strtable_begin(upb_strtable_iter *i, const upb_strtable *t);
|
|
876
905
|
void upb_strtable_next(upb_strtable_iter *i);
|
877
906
|
bool upb_strtable_done(const upb_strtable_iter *i);
|
878
907
|
const char *upb_strtable_iter_key(upb_strtable_iter *i);
|
908
|
+
size_t upb_strtable_iter_keylength(upb_strtable_iter *i);
|
879
909
|
upb_value upb_strtable_iter_value(const upb_strtable_iter *i);
|
880
910
|
void upb_strtable_iter_setdone(upb_strtable_iter *i);
|
881
911
|
bool upb_strtable_iter_isequal(const upb_strtable_iter *i1,
|
@@ -1777,6 +1807,10 @@ UPB_DEFINE_DEF(upb::MessageDef, msgdef, MSG, UPB_QUOTE(
|
|
1777
1807
|
// just be moved into symtab.c?
|
1778
1808
|
MessageDef* Dup(const void* owner) const;
|
1779
1809
|
|
1810
|
+
// Is this message a map entry?
|
1811
|
+
void setmapentry(bool map_entry);
|
1812
|
+
bool mapentry() const;
|
1813
|
+
|
1780
1814
|
// Iteration over fields. The order is undefined.
|
1781
1815
|
class iterator : public std::iterator<std::forward_iterator_tag, FieldDef*> {
|
1782
1816
|
public:
|
@@ -1823,6 +1857,11 @@ UPB_DEFINE_STRUCT(upb_msgdef, upb_def,
|
|
1823
1857
|
upb_inttable itof; // int to field
|
1824
1858
|
upb_strtable ntof; // name to field
|
1825
1859
|
|
1860
|
+
// Is this a map-entry message?
|
1861
|
+
// TODO: set this flag properly for static descriptors; regenerate
|
1862
|
+
// descriptor.upb.c.
|
1863
|
+
bool map_entry;
|
1864
|
+
|
1826
1865
|
// TODO(haberman): proper extension ranges (there can be multiple).
|
1827
1866
|
));
|
1828
1867
|
|
@@ -1830,7 +1869,7 @@ UPB_DEFINE_STRUCT(upb_msgdef, upb_def,
|
|
1830
1869
|
refs, ref2s) \
|
1831
1870
|
{ \
|
1832
1871
|
UPB_DEF_INIT(name, UPB_DEF_MSG, refs, ref2s), selector_count, \
|
1833
|
-
submsg_field_count, itof, ntof
|
1872
|
+
submsg_field_count, itof, ntof, false \
|
1834
1873
|
}
|
1835
1874
|
|
1836
1875
|
UPB_BEGIN_EXTERN_C // {
|
@@ -1878,6 +1917,9 @@ UPB_INLINE upb_fielddef *upb_msgdef_ntof_mutable(upb_msgdef *m,
|
|
1878
1917
|
return (upb_fielddef *)upb_msgdef_ntof(m, name, len);
|
1879
1918
|
}
|
1880
1919
|
|
1920
|
+
void upb_msgdef_setmapentry(upb_msgdef *m, bool map_entry);
|
1921
|
+
bool upb_msgdef_mapentry(const upb_msgdef *m);
|
1922
|
+
|
1881
1923
|
// upb_msg_iter i;
|
1882
1924
|
// for(upb_msg_begin(&i, m); !upb_msg_done(&i); upb_msg_next(&i)) {
|
1883
1925
|
// upb_fielddef *f = upb_msg_iter_field(&i);
|
@@ -2331,6 +2373,12 @@ inline const FieldDef *MessageDef::FindFieldByName(const char *name,
|
|
2331
2373
|
inline MessageDef* MessageDef::Dup(const void *owner) const {
|
2332
2374
|
return upb_msgdef_dup(this, owner);
|
2333
2375
|
}
|
2376
|
+
inline void MessageDef::setmapentry(bool map_entry) {
|
2377
|
+
upb_msgdef_setmapentry(this, map_entry);
|
2378
|
+
}
|
2379
|
+
inline bool MessageDef::mapentry() const {
|
2380
|
+
return upb_msgdef_mapentry(this);
|
2381
|
+
}
|
2334
2382
|
inline MessageDef::iterator MessageDef::begin() { return iterator(this); }
|
2335
2383
|
inline MessageDef::iterator MessageDef::end() { return iterator::end(this); }
|
2336
2384
|
inline MessageDef::const_iterator MessageDef::begin() const {
|
@@ -6614,7 +6662,9 @@ typedef enum {
|
|
6614
6662
|
// | unused (24) | opc |
|
6615
6663
|
// | upb_inttable* (32 or 64) |
|
6616
6664
|
|
6617
|
-
|
6665
|
+
OP_DISPATCH = 36, // No arg.
|
6666
|
+
|
6667
|
+
OP_HALT = 37, // No arg.
|
6618
6668
|
} opcode;
|
6619
6669
|
|
6620
6670
|
#define OP_MAX OP_HALT
|
@@ -7291,15 +7341,24 @@ UPB_DEFINE_STRUCT0(upb_json_parser,
|
|
7291
7341
|
int parser_stack[UPB_JSON_MAX_DEPTH];
|
7292
7342
|
int parser_top;
|
7293
7343
|
|
7294
|
-
//
|
7295
|
-
const
|
7344
|
+
// The handle for the current buffer.
|
7345
|
+
const upb_bufhandle *handle;
|
7296
7346
|
|
7297
|
-
//
|
7298
|
-
// base64 partial results.
|
7347
|
+
// Accumulate buffer. See details in parser.rl.
|
7299
7348
|
const char *accumulated;
|
7300
7349
|
size_t accumulated_len;
|
7301
|
-
|
7302
|
-
|
7350
|
+
char *accumulate_buf;
|
7351
|
+
size_t accumulate_buf_size;
|
7352
|
+
|
7353
|
+
// Multi-part text data. See details in parser.rl.
|
7354
|
+
int multipart_state;
|
7355
|
+
upb_selector_t string_selector;
|
7356
|
+
|
7357
|
+
// Input capture. See details in parser.rl.
|
7358
|
+
const char *capture;
|
7359
|
+
|
7360
|
+
// Intermediate result of parsing a unicode escape sequence.
|
7361
|
+
uint32_t digit;
|
7303
7362
|
));
|
7304
7363
|
|
7305
7364
|
UPB_BEGIN_EXTERN_C
|
data/tests/basic.rb
CHANGED
@@ -36,23 +36,43 @@ module BasicTest
|
|
36
36
|
add_message "TestMessage2" do
|
37
37
|
optional :foo, :int32, 1
|
38
38
|
end
|
39
|
+
|
39
40
|
add_message "Recursive1" do
|
40
41
|
optional :foo, :message, 1, "Recursive2"
|
41
42
|
end
|
42
43
|
add_message "Recursive2" do
|
43
44
|
optional :foo, :message, 1, "Recursive1"
|
44
45
|
end
|
46
|
+
|
45
47
|
add_enum "TestEnum" do
|
46
48
|
value :Default, 0
|
47
49
|
value :A, 1
|
48
50
|
value :B, 2
|
49
51
|
value :C, 3
|
50
52
|
end
|
53
|
+
|
51
54
|
add_message "BadFieldNames" do
|
52
55
|
optional :dup, :int32, 1
|
53
56
|
optional :class, :int32, 2
|
54
57
|
optional :"a.b", :int32, 3
|
55
58
|
end
|
59
|
+
|
60
|
+
add_message "MapMessage" do
|
61
|
+
map :map_string_int32, :string, :int32, 1
|
62
|
+
map :map_string_msg, :string, :message, 2, "TestMessage2"
|
63
|
+
end
|
64
|
+
add_message "MapMessageWireEquiv" do
|
65
|
+
repeated :map_string_int32, :message, 1, "MapMessageWireEquiv_entry1"
|
66
|
+
repeated :map_string_msg, :message, 2, "MapMessageWireEquiv_entry2"
|
67
|
+
end
|
68
|
+
add_message "MapMessageWireEquiv_entry1" do
|
69
|
+
optional :key, :string, 1
|
70
|
+
optional :value, :int32, 2
|
71
|
+
end
|
72
|
+
add_message "MapMessageWireEquiv_entry2" do
|
73
|
+
optional :key, :string, 1
|
74
|
+
optional :value, :message, 2, "TestMessage2"
|
75
|
+
end
|
56
76
|
end
|
57
77
|
|
58
78
|
TestMessage = pool.lookup("TestMessage").msgclass
|
@@ -61,6 +81,12 @@ module BasicTest
|
|
61
81
|
Recursive2 = pool.lookup("Recursive2").msgclass
|
62
82
|
TestEnum = pool.lookup("TestEnum").enummodule
|
63
83
|
BadFieldNames = pool.lookup("BadFieldNames").msgclass
|
84
|
+
MapMessage = pool.lookup("MapMessage").msgclass
|
85
|
+
MapMessageWireEquiv = pool.lookup("MapMessageWireEquiv").msgclass
|
86
|
+
MapMessageWireEquiv_entry1 =
|
87
|
+
pool.lookup("MapMessageWireEquiv_entry1").msgclass
|
88
|
+
MapMessageWireEquiv_entry2 =
|
89
|
+
pool.lookup("MapMessageWireEquiv_entry2").msgclass
|
64
90
|
|
65
91
|
# ------------ test cases ---------------
|
66
92
|
|
@@ -300,7 +326,7 @@ module BasicTest
|
|
300
326
|
l.push :B
|
301
327
|
l.push :C
|
302
328
|
assert l.count == 3
|
303
|
-
assert_raise
|
329
|
+
assert_raise RangeError do
|
304
330
|
l.push :D
|
305
331
|
end
|
306
332
|
assert l[0] == :A
|
@@ -324,12 +350,244 @@ module BasicTest
|
|
324
350
|
end
|
325
351
|
end
|
326
352
|
|
353
|
+
def test_map_basic
|
354
|
+
# allowed key types:
|
355
|
+
# :int32, :int64, :uint32, :uint64, :bool, :string, :bytes.
|
356
|
+
|
357
|
+
m = Google::Protobuf::Map.new(:string, :int32)
|
358
|
+
m["asdf"] = 1
|
359
|
+
assert m["asdf"] == 1
|
360
|
+
m["jkl;"] = 42
|
361
|
+
assert m == { "jkl;" => 42, "asdf" => 1 }
|
362
|
+
assert m.has_key?("asdf")
|
363
|
+
assert !m.has_key?("qwerty")
|
364
|
+
assert m.length == 2
|
365
|
+
|
366
|
+
m2 = m.dup
|
367
|
+
assert m == m2
|
368
|
+
assert m.hash != 0
|
369
|
+
assert m.hash == m2.hash
|
370
|
+
|
371
|
+
collected = {}
|
372
|
+
m.each { |k,v| collected[v] = k }
|
373
|
+
assert collected == { 42 => "jkl;", 1 => "asdf" }
|
374
|
+
|
375
|
+
assert m.delete("asdf") == 1
|
376
|
+
assert !m.has_key?("asdf")
|
377
|
+
assert m["asdf"] == nil
|
378
|
+
assert !m.has_key?("asdf")
|
379
|
+
|
380
|
+
# We only assert on inspect value when there is one map entry because the
|
381
|
+
# order in which elements appear is unspecified (depends on the internal
|
382
|
+
# hash function). We don't want a brittle test.
|
383
|
+
assert m.inspect == "{\"jkl;\" => 42}"
|
384
|
+
|
385
|
+
assert m.keys == ["jkl;"]
|
386
|
+
assert m.values == [42]
|
387
|
+
|
388
|
+
m.clear
|
389
|
+
assert m.length == 0
|
390
|
+
assert m == {}
|
391
|
+
|
392
|
+
assert_raise TypeError do
|
393
|
+
m[1] = 1
|
394
|
+
end
|
395
|
+
assert_raise RangeError do
|
396
|
+
m["asdf"] = 0x1_0000_0000
|
397
|
+
end
|
398
|
+
end
|
399
|
+
|
400
|
+
def test_map_ctor
|
401
|
+
m = Google::Protobuf::Map.new(:string, :int32,
|
402
|
+
{"a" => 1, "b" => 2, "c" => 3})
|
403
|
+
assert m == {"a" => 1, "c" => 3, "b" => 2}
|
404
|
+
end
|
405
|
+
|
406
|
+
def test_map_keytypes
|
407
|
+
m = Google::Protobuf::Map.new(:int32, :int32)
|
408
|
+
m[1] = 42
|
409
|
+
m[-1] = 42
|
410
|
+
assert_raise RangeError do
|
411
|
+
m[0x8000_0000] = 1
|
412
|
+
end
|
413
|
+
assert_raise TypeError do
|
414
|
+
m["asdf"] = 1
|
415
|
+
end
|
416
|
+
|
417
|
+
m = Google::Protobuf::Map.new(:int64, :int32)
|
418
|
+
m[0x1000_0000_0000_0000] = 1
|
419
|
+
assert_raise RangeError do
|
420
|
+
m[0x1_0000_0000_0000_0000] = 1
|
421
|
+
end
|
422
|
+
assert_raise TypeError do
|
423
|
+
m["asdf"] = 1
|
424
|
+
end
|
425
|
+
|
426
|
+
m = Google::Protobuf::Map.new(:uint32, :int32)
|
427
|
+
m[0x8000_0000] = 1
|
428
|
+
assert_raise RangeError do
|
429
|
+
m[0x1_0000_0000] = 1
|
430
|
+
end
|
431
|
+
assert_raise RangeError do
|
432
|
+
m[-1] = 1
|
433
|
+
end
|
434
|
+
|
435
|
+
m = Google::Protobuf::Map.new(:uint64, :int32)
|
436
|
+
m[0x8000_0000_0000_0000] = 1
|
437
|
+
assert_raise RangeError do
|
438
|
+
m[0x1_0000_0000_0000_0000] = 1
|
439
|
+
end
|
440
|
+
assert_raise RangeError do
|
441
|
+
m[-1] = 1
|
442
|
+
end
|
443
|
+
|
444
|
+
m = Google::Protobuf::Map.new(:bool, :int32)
|
445
|
+
m[true] = 1
|
446
|
+
m[false] = 2
|
447
|
+
assert_raise TypeError do
|
448
|
+
m[1] = 1
|
449
|
+
end
|
450
|
+
assert_raise TypeError do
|
451
|
+
m["asdf"] = 1
|
452
|
+
end
|
453
|
+
|
454
|
+
m = Google::Protobuf::Map.new(:string, :int32)
|
455
|
+
m["asdf"] = 1
|
456
|
+
assert_raise TypeError do
|
457
|
+
m[1] = 1
|
458
|
+
end
|
459
|
+
assert_raise TypeError do
|
460
|
+
bytestring = ["FFFF"].pack("H*")
|
461
|
+
m[bytestring] = 1
|
462
|
+
end
|
463
|
+
|
464
|
+
m = Google::Protobuf::Map.new(:bytes, :int32)
|
465
|
+
bytestring = ["FFFF"].pack("H*")
|
466
|
+
m[bytestring] = 1
|
467
|
+
assert_raise TypeError do
|
468
|
+
m["asdf"] = 1
|
469
|
+
end
|
470
|
+
assert_raise TypeError do
|
471
|
+
m[1] = 1
|
472
|
+
end
|
473
|
+
end
|
474
|
+
|
475
|
+
def test_map_msg_enum_valuetypes
|
476
|
+
m = Google::Protobuf::Map.new(:string, :message, TestMessage)
|
477
|
+
m["asdf"] = TestMessage.new
|
478
|
+
assert_raise TypeError do
|
479
|
+
m["jkl;"] = TestMessage2.new
|
480
|
+
end
|
481
|
+
|
482
|
+
m = Google::Protobuf::Map.new(
|
483
|
+
:string, :message, TestMessage,
|
484
|
+
{ "a" => TestMessage.new(:optional_int32 => 42),
|
485
|
+
"b" => TestMessage.new(:optional_int32 => 84) })
|
486
|
+
assert m.length == 2
|
487
|
+
assert m.values.map{|msg| msg.optional_int32}.sort == [42, 84]
|
488
|
+
|
489
|
+
m = Google::Protobuf::Map.new(:string, :enum, TestEnum,
|
490
|
+
{ "x" => :A, "y" => :B, "z" => :C })
|
491
|
+
assert m.length == 3
|
492
|
+
assert m["z"] == :C
|
493
|
+
m["z"] = 2
|
494
|
+
assert m["z"] == :B
|
495
|
+
m["z"] = 4
|
496
|
+
assert m["z"] == 4
|
497
|
+
assert_raise RangeError do
|
498
|
+
m["z"] = :Z
|
499
|
+
end
|
500
|
+
assert_raise TypeError do
|
501
|
+
m["z"] = "z"
|
502
|
+
end
|
503
|
+
end
|
504
|
+
|
505
|
+
def test_map_dup_deep_copy
|
506
|
+
m = Google::Protobuf::Map.new(
|
507
|
+
:string, :message, TestMessage,
|
508
|
+
{ "a" => TestMessage.new(:optional_int32 => 42),
|
509
|
+
"b" => TestMessage.new(:optional_int32 => 84) })
|
510
|
+
|
511
|
+
m2 = m.dup
|
512
|
+
assert m == m2
|
513
|
+
assert m.object_id != m2.object_id
|
514
|
+
assert m["a"].object_id == m2["a"].object_id
|
515
|
+
assert m["b"].object_id == m2["b"].object_id
|
516
|
+
|
517
|
+
m2 = Google::Protobuf.deep_copy(m)
|
518
|
+
assert m == m2
|
519
|
+
assert m.object_id != m2.object_id
|
520
|
+
assert m["a"].object_id != m2["a"].object_id
|
521
|
+
assert m["b"].object_id != m2["b"].object_id
|
522
|
+
end
|
523
|
+
|
524
|
+
def test_map_field
|
525
|
+
m = MapMessage.new
|
526
|
+
assert m.map_string_int32 == {}
|
527
|
+
assert m.map_string_msg == {}
|
528
|
+
|
529
|
+
m = MapMessage.new(
|
530
|
+
:map_string_int32 => {"a" => 1, "b" => 2},
|
531
|
+
:map_string_msg => {"a" => TestMessage2.new(:foo => 1),
|
532
|
+
"b" => TestMessage2.new(:foo => 2)})
|
533
|
+
assert m.map_string_int32.keys.sort == ["a", "b"]
|
534
|
+
assert m.map_string_int32["a"] == 1
|
535
|
+
assert m.map_string_msg["b"].foo == 2
|
536
|
+
|
537
|
+
m.map_string_int32["c"] = 3
|
538
|
+
assert m.map_string_int32["c"] == 3
|
539
|
+
m.map_string_msg["c"] = TestMessage2.new(:foo => 3)
|
540
|
+
assert m.map_string_msg["c"] == TestMessage2.new(:foo => 3)
|
541
|
+
m.map_string_msg.delete("b")
|
542
|
+
m.map_string_msg.delete("c")
|
543
|
+
assert m.map_string_msg == { "a" => TestMessage2.new(:foo => 1) }
|
544
|
+
|
545
|
+
assert_raise TypeError do
|
546
|
+
m.map_string_msg["e"] = TestMessage.new # wrong value type
|
547
|
+
end
|
548
|
+
# ensure nothing was added by the above
|
549
|
+
assert m.map_string_msg == { "a" => TestMessage2.new(:foo => 1) }
|
550
|
+
|
551
|
+
m.map_string_int32 = Google::Protobuf::Map.new(:string, :int32)
|
552
|
+
assert_raise TypeError do
|
553
|
+
m.map_string_int32 = Google::Protobuf::Map.new(:string, :int64)
|
554
|
+
end
|
555
|
+
assert_raise TypeError do
|
556
|
+
m.map_string_int32 = {}
|
557
|
+
end
|
558
|
+
|
559
|
+
assert_raise TypeError do
|
560
|
+
m = MapMessage.new(:map_string_int32 => { 1 => "I am not a number" })
|
561
|
+
end
|
562
|
+
end
|
563
|
+
|
564
|
+
def test_map_encode_decode
|
565
|
+
m = MapMessage.new(
|
566
|
+
:map_string_int32 => {"a" => 1, "b" => 2},
|
567
|
+
:map_string_msg => {"a" => TestMessage2.new(:foo => 1),
|
568
|
+
"b" => TestMessage2.new(:foo => 2)})
|
569
|
+
m2 = MapMessage.decode(MapMessage.encode(m))
|
570
|
+
assert m == m2
|
571
|
+
|
572
|
+
m3 = MapMessageWireEquiv.decode(MapMessage.encode(m))
|
573
|
+
assert m3.map_string_int32.length == 2
|
574
|
+
|
575
|
+
kv = {}
|
576
|
+
m3.map_string_int32.map { |msg| kv[msg.key] = msg.value }
|
577
|
+
assert kv == {"a" => 1, "b" => 2}
|
578
|
+
|
579
|
+
kv = {}
|
580
|
+
m3.map_string_msg.map { |msg| kv[msg.key] = msg.value }
|
581
|
+
assert kv == {"a" => TestMessage2.new(:foo => 1),
|
582
|
+
"b" => TestMessage2.new(:foo => 2)}
|
583
|
+
end
|
584
|
+
|
327
585
|
def test_enum_field
|
328
586
|
m = TestMessage.new
|
329
587
|
assert m.optional_enum == :Default
|
330
588
|
m.optional_enum = :A
|
331
589
|
assert m.optional_enum == :A
|
332
|
-
assert_raise
|
590
|
+
assert_raise RangeError do
|
333
591
|
m.optional_enum = :ASDF
|
334
592
|
end
|
335
593
|
m.optional_enum = 1
|
@@ -384,7 +642,8 @@ module BasicTest
|
|
384
642
|
:repeated_string => ["a", "b", "c"],
|
385
643
|
:repeated_int32 => [42, 43, 44],
|
386
644
|
:repeated_enum => [:A, :B, :C, 100],
|
387
|
-
:repeated_msg => [TestMessage2.new(:foo => 1),
|
645
|
+
:repeated_msg => [TestMessage2.new(:foo => 1),
|
646
|
+
TestMessage2.new(:foo => 2)])
|
388
647
|
data = TestMessage.encode m
|
389
648
|
m2 = TestMessage.decode data
|
390
649
|
assert m == m2
|