diff --git a/ruby/ext/google/protobuf_c/repeated_field.c b/ruby/ext/google/protobuf_c/repeated_field.c index 8f4c4212bd..29e829ef2c 100644 --- a/ruby/ext/google/protobuf_c/repeated_field.c +++ b/ruby/ext/google/protobuf_c/repeated_field.c @@ -223,6 +223,12 @@ VALUE RepeatedField_push(VALUE _self, VALUE val) { 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. void RepeatedField_push_native(VALUE _self, void* data) { @@ -635,7 +641,7 @@ void RepeatedField_register(VALUE module) { rb_define_method(klass, "[]", RepeatedField_index, -1); rb_define_method(klass, "at", RepeatedField_index, -1); 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_private_method(klass, "pop_one", RepeatedField_pop_one, 0); rb_define_method(klass, "replace", RepeatedField_replace, 1); diff --git a/ruby/tests/common_tests.rb b/ruby/tests/common_tests.rb index a9c44f5a36..38763001c9 100644 --- a/ruby/tests/common_tests.rb +++ b/ruby/tests/common_tests.rb @@ -708,6 +708,27 @@ module CommonTests assert proto_module::TestEnum::resolve(:C) == 3 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 m = proto_module::TestMessage.new(:optional_int32 => 42, :optional_string => "hello world", diff --git a/ruby/tests/repeated_field_test.rb b/ruby/tests/repeated_field_test.rb index df8ede42cd..ced9de8381 100644 --- a/ruby/tests/repeated_field_test.rb +++ b/ruby/tests/repeated_field_test.rb @@ -221,7 +221,7 @@ class RepeatedFieldTest < Test::Unit::TestCase def test_push m = TestMessage.new - reference_arr = %w(foo bar baz) + reference_arr = %w[foo bar baz] m.repeated_string += reference_arr.clone check_self_modifying_method(m.repeated_string, reference_arr) do |arr| @@ -230,10 +230,9 @@ class RepeatedFieldTest < Test::Unit::TestCase check_self_modifying_method(m.repeated_string, reference_arr) do |arr| arr << 'fizz' end - #TODO: push should support multiple - # check_self_modifying_method(m.repeated_string, reference_arr) do |arr| - # arr.push('fizz', 'buzz') - # end + check_self_modifying_method(m.repeated_string, reference_arr) do |arr| + arr.push('fizz', 'buzz') + end end def test_clear