diff options
author | Adam Cozzette <acozzette@google.com> | 2016-11-17 17:04:30 -0800 |
---|---|---|
committer | Adam Cozzette <acozzette@google.com> | 2016-11-17 17:04:30 -0800 |
commit | 5d63097fc2b7f405f53d6ca4ad3c1ebd98d80ddd (patch) | |
tree | 50d8116271f024e16334785464c794da85f3ce12 /ruby | |
parent | 5a76e633ea9b5adb215e93fdc11e1c0c08b3fc74 (diff) | |
parent | cd315dcbadc02569e145bde16e3f66c2fbb08e31 (diff) | |
download | protobuf-5d63097fc2b7f405f53d6ca4ad3c1ebd98d80ddd.tar.gz protobuf-5d63097fc2b7f405f53d6ca4ad3c1ebd98d80ddd.tar.bz2 protobuf-5d63097fc2b7f405f53d6ca4ad3c1ebd98d80ddd.zip |
Merge branch 'master' into down-integrate-with-msvc-fix
Diffstat (limited to 'ruby')
-rw-r--r-- | ruby/ext/google/protobuf_c/message.c | 44 | ||||
-rw-r--r-- | ruby/tests/basic.rb | 10 | ||||
-rwxr-xr-x | ruby/travis-test.sh | 2 |
3 files changed, 56 insertions, 0 deletions
diff --git a/ruby/ext/google/protobuf_c/message.c b/ruby/ext/google/protobuf_c/message.c index e16250f3..837a974b 100644 --- a/ruby/ext/google/protobuf_c/message.c +++ b/ruby/ext/google/protobuf_c/message.c @@ -178,6 +178,45 @@ VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self) { } } +VALUE Message_respond_to_missing(int argc, VALUE* argv, VALUE _self) { + MessageHeader* self; + VALUE method_name, method_str; + char* name; + size_t name_len; + bool setter; + const upb_oneofdef* o; + const upb_fielddef* f; + + TypedData_Get_Struct(_self, MessageHeader, &Message_type, self); + if (argc < 1) { + rb_raise(rb_eArgError, "Expected method name as first argument."); + } + method_name = argv[0]; + if (!SYMBOL_P(method_name)) { + rb_raise(rb_eArgError, "Expected symbol as method name."); + } + method_str = rb_id2str(SYM2ID(method_name)); + name = RSTRING_PTR(method_str); + name_len = RSTRING_LEN(method_str); + setter = false; + + // Setters have names that end in '='. + if (name[name_len - 1] == '=') { + setter = true; + name_len--; + } + + // See if this name corresponds to either a oneof or field in this message. + if (!upb_msgdef_lookupname(self->descriptor->msgdef, name, name_len, &f, + &o)) { + return rb_call_super(argc, argv); + } + if (o != NULL) { + return setter ? Qfalse : Qtrue; + } + return Qtrue; +} + int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self) { MessageHeader* self; VALUE method_str; @@ -305,6 +344,9 @@ VALUE Message_deep_copy(VALUE _self) { VALUE Message_eq(VALUE _self, VALUE _other) { MessageHeader* self; MessageHeader* other; + if (TYPE(_self) != TYPE(_other)) { + return Qfalse; + } TypedData_Get_Struct(_self, MessageHeader, &Message_type, self); TypedData_Get_Struct(_other, MessageHeader, &Message_type, other); @@ -459,6 +501,8 @@ VALUE build_class_from_descriptor(Descriptor* desc) { rb_define_method(klass, "method_missing", Message_method_missing, -1); + rb_define_method(klass, "respond_to_missing?", + Message_respond_to_missing, -1); rb_define_method(klass, "initialize", Message_initialize, -1); rb_define_method(klass, "dup", Message_dup, 0); // Also define #clone so that we don't inherit Object#clone. diff --git a/ruby/tests/basic.rb b/ruby/tests/basic.rb index 989a047e..967ff81f 100644 --- a/ruby/tests/basic.rb +++ b/ruby/tests/basic.rb @@ -1181,5 +1181,15 @@ module BasicTest m2 = MapMessage.decode_json(MapMessage.encode_json(m)) assert m == m2 end + + def test_comparison_with_arbitrary_object + assert_false MapMessage.new == nil + end + + def test_respond_to + msg = MapMessage.new + assert msg.respond_to?(:map_string_int32) + assert_false msg.respond_to?(:bacon) + end end end diff --git a/ruby/travis-test.sh b/ruby/travis-test.sh index d3022657..930165e6 100755 --- a/ruby/travis-test.sh +++ b/ruby/travis-test.sh @@ -10,12 +10,14 @@ test_version() { bash --login -c \ "rvm install $version && rvm use $version && rvm get head && \ which ruby && \ + git clean -f && \ gem install bundler && bundle && \ rake test" else bash --login -c \ "rvm install $version && rvm use $version && \ which ruby && \ + git clean -f && \ gem install bundler && bundle && \ rake test && cd ../conformance && make test_ruby" |