Support hashes for struct initializers (#5716)

* support hashes for struct initalizers

* convert hash keys to string

* update tests

* add extra asserts
pull/6442/head
Joe Bolinger 5 years ago committed by Paul Yang
parent dcc8ffd9c6
commit 41e12344a1
  1. 8
      ruby/ext/google/protobuf_c/map.c
  2. 14
      ruby/tests/basic.rb
  3. 54
      ruby/tests/well_known_types_test.rb

@ -71,6 +71,9 @@ static VALUE table_key(Map* self, VALUE key,
case UPB_TYPE_BYTES:
case UPB_TYPE_STRING:
// Strings: use string content directly.
if (TYPE(key) == T_SYMBOL) {
key = rb_id2str(SYM2ID(key));
}
Check_Type(key, T_STRING);
key = native_slot_encode_and_freeze_string(self->key_type, key);
*out_key = RSTRING_PTR(key);
@ -397,6 +400,11 @@ VALUE Map_index_set(VALUE _self, VALUE key, VALUE value) {
void* mem;
key = table_key(self, key, keybuf, &keyval, &length);
if (TYPE(value) == T_HASH) {
VALUE args[1] = { value };
value = rb_class_new_instance(1, args, self->value_type_class);
}
mem = value_memory(&v);
native_slot_set("", self->value_type, self->value_type_class, mem, value);

@ -204,6 +204,20 @@ module BasicTest
end
end
def test_map_field_with_symbol
m = MapMessage.new
assert m.map_string_int32 == {}
assert m.map_string_msg == {}
m = MapMessage.new(
:map_string_int32 => {a: 1, "b" => 2},
:map_string_msg => {a: TestMessage2.new(:foo => 1),
b: TestMessage2.new(:foo => 10)})
assert_equal 1, m.map_string_int32[:a]
assert_equal 2, m.map_string_int32[:b]
assert_equal 10, m.map_string_msg[:b].foo
end
def test_map_inspect
m = MapMessage.new(
:map_string_int32 => {"a" => 1, "b" => 2},

@ -139,4 +139,58 @@ class TestWellKnownTypes < Test::Unit::TestCase
assert any.is(Google::Protobuf::Timestamp)
assert_equal ts, any.unpack(Google::Protobuf::Timestamp)
end
def test_struct_init
s = Google::Protobuf::Struct.new(fields: {'a' => Google::Protobuf::Value.new({number_value: 4.4})})
assert_equal 4.4, s['a']
s = Google::Protobuf::Struct.new(fields: {'a' => {number_value: 2.2}})
assert_equal 2.2, s['a']
s = Google::Protobuf::Struct.new(fields: {a: {number_value: 1.1}})
assert_equal 1.1, s[:a]
end
def test_struct_nested_init
s = Google::Protobuf::Struct.new(
fields: {
'a' => {string_value: 'A'},
'b' => {struct_value: {
fields: {
'x' => {list_value: {values: [{number_value: 1.0}, {string_value: "ok"}]}},
'y' => {bool_value: true}}}
},
'c' => {struct_value: {}}
}
)
assert_equal 'A', s['a']
assert_equal 'A', s[:a]
expected_b_x = [Google::Protobuf::Value.new(number_value: 1.0), Google::Protobuf::Value.new(string_value: "ok")]
assert_equal expected_b_x, s['b']['x'].values
assert_equal expected_b_x, s[:b][:x].values
assert_equal expected_b_x, s['b'][:x].values
assert_equal expected_b_x, s[:b]['x'].values
assert_equal true, s['b']['y']
assert_equal true, s[:b][:y]
assert_equal true, s[:b]['y']
assert_equal true, s['b'][:y]
assert_equal Google::Protobuf::Struct.new, s['c']
assert_equal Google::Protobuf::Struct.new, s[:c]
s = Google::Protobuf::Struct.new(
fields: {
a: {string_value: 'Eh'},
b: {struct_value: {
fields: {
y: {bool_value: false}}}
}
}
)
assert_equal 'Eh', s['a']
assert_equal 'Eh', s[:a]
assert_equal false, s['b']['y']
assert_equal false, s[:b][:y]
assert_equal false, s['b'][:y]
assert_equal false, s[:b]['y']
end
end

Loading…
Cancel
Save