Commit e780681e authored by Joe Bolinger's avatar Joe Bolinger Committed by Paul Yang

Allow repeated fields in Ruby to accept multiple arguments on push (#5736)

* let repeated fields push arrays

* add varargs push

* better test
parent 2adde396
...@@ -223,6 +223,12 @@ VALUE RepeatedField_push(VALUE _self, VALUE val) { ...@@ -223,6 +223,12 @@ VALUE RepeatedField_push(VALUE _self, VALUE val) {
return _self; return _self;
} }
VALUE RepeatedField_push_vararg(VALUE _self, VALUE args) {
for (int i = 0; i < RARRAY_LEN(args); i++) {
RepeatedField_push(_self, rb_ary_entry(args, i));
}
return _self;
}
// Used by parsing handlers. // Used by parsing handlers.
void RepeatedField_push_native(VALUE _self, void* data) { void RepeatedField_push_native(VALUE _self, void* data) {
...@@ -635,7 +641,7 @@ void RepeatedField_register(VALUE module) { ...@@ -635,7 +641,7 @@ void RepeatedField_register(VALUE module) {
rb_define_method(klass, "[]", RepeatedField_index, -1); rb_define_method(klass, "[]", RepeatedField_index, -1);
rb_define_method(klass, "at", RepeatedField_index, -1); rb_define_method(klass, "at", RepeatedField_index, -1);
rb_define_method(klass, "[]=", RepeatedField_index_set, 2); rb_define_method(klass, "[]=", RepeatedField_index_set, 2);
rb_define_method(klass, "push", RepeatedField_push, 1); rb_define_method(klass, "push", RepeatedField_push_vararg, -2);
rb_define_method(klass, "<<", RepeatedField_push, 1); rb_define_method(klass, "<<", RepeatedField_push, 1);
rb_define_private_method(klass, "pop_one", RepeatedField_pop_one, 0); rb_define_private_method(klass, "pop_one", RepeatedField_pop_one, 0);
rb_define_method(klass, "replace", RepeatedField_replace, 1); rb_define_method(klass, "replace", RepeatedField_replace, 1);
......
...@@ -708,6 +708,27 @@ module CommonTests ...@@ -708,6 +708,27 @@ module CommonTests
assert proto_module::TestEnum::resolve(:C) == 3 assert proto_module::TestEnum::resolve(:C) == 3
end end
def test_repeated_push
m = proto_module::TestMessage.new
m.repeated_string += ['one']
m.repeated_string += %w[two three]
assert_equal %w[one two three], m.repeated_string
m.repeated_string.push *['four', 'five']
assert_equal %w[one two three four five], m.repeated_string
m.repeated_string.push 'six', 'seven'
assert_equal %w[one two three four five six seven], m.repeated_string
m = proto_module::TestMessage.new
m.repeated_msg += [proto_module::TestMessage2.new(:foo => 1), proto_module::TestMessage2.new(:foo => 2)]
m.repeated_msg += [proto_module::TestMessage2.new(:foo => 3)]
m.repeated_msg.push proto_module::TestMessage2.new(:foo => 4), proto_module::TestMessage2.new(:foo => 5)
assert_equal [1, 2, 3, 4, 5], m.repeated_msg.map {|x| x.foo}
end
def test_parse_serialize def test_parse_serialize
m = proto_module::TestMessage.new(:optional_int32 => 42, m = proto_module::TestMessage.new(:optional_int32 => 42,
:optional_string => "hello world", :optional_string => "hello world",
......
...@@ -221,7 +221,7 @@ class RepeatedFieldTest < Test::Unit::TestCase ...@@ -221,7 +221,7 @@ class RepeatedFieldTest < Test::Unit::TestCase
def test_push def test_push
m = TestMessage.new m = TestMessage.new
reference_arr = %w(foo bar baz) reference_arr = %w[foo bar baz]
m.repeated_string += reference_arr.clone m.repeated_string += reference_arr.clone
check_self_modifying_method(m.repeated_string, reference_arr) do |arr| check_self_modifying_method(m.repeated_string, reference_arr) do |arr|
...@@ -230,10 +230,9 @@ class RepeatedFieldTest < Test::Unit::TestCase ...@@ -230,10 +230,9 @@ class RepeatedFieldTest < Test::Unit::TestCase
check_self_modifying_method(m.repeated_string, reference_arr) do |arr| check_self_modifying_method(m.repeated_string, reference_arr) do |arr|
arr << 'fizz' arr << 'fizz'
end end
#TODO: push should support multiple check_self_modifying_method(m.repeated_string, reference_arr) do |arr|
# check_self_modifying_method(m.repeated_string, reference_arr) do |arr| arr.push('fizz', 'buzz')
# arr.push('fizz', 'buzz') end
# end
end end
def test_clear def test_clear
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment