Skip to content

Commit 9f6bc43

Browse files
committed
Add specs for rb_check_funcall()
1 parent 3f0834f commit 9f6bc43

File tree

3 files changed

+52
-7
lines changed

3 files changed

+52
-7
lines changed

spec/ruby/optional/capi/ext/kernel_spec.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,15 @@ static VALUE kernel_spec_rb_funcall_many_args(VALUE self, VALUE obj, VALUE metho
355355
INT2FIX(5), INT2FIX(4), INT2FIX(3), INT2FIX(2), INT2FIX(1));
356356
}
357357

358+
static VALUE kernel_spec_rb_check_funcall(VALUE self, VALUE receiver, VALUE method, VALUE args) {
359+
VALUE ret = rb_check_funcall(receiver, SYM2ID(method), RARRAY_LENINT(args), RARRAY_PTR(args));
360+
if (ret == Qundef) {
361+
return ID2SYM(rb_intern("Qundef"));
362+
} else {
363+
return ret;
364+
}
365+
}
366+
358367
void Init_kernel_spec(void) {
359368
VALUE cls = rb_define_class("CApiKernelSpecs", rb_cObject);
360369
rb_define_method(cls, "rb_block_given_p", kernel_spec_rb_block_given_p, 0);
@@ -403,6 +412,7 @@ void Init_kernel_spec(void) {
403412
rb_define_method(cls, "rb_funcall_many_args", kernel_spec_rb_funcall_many_args, 2);
404413
rb_define_method(cls, "rb_funcall_with_block", kernel_spec_rb_funcall_with_block, 4);
405414
rb_define_method(cls, "rb_funcall_with_block_kw", kernel_spec_rb_funcall_with_block_kw, 4);
415+
rb_define_method(cls, "rb_check_funcall", kernel_spec_rb_check_funcall, 3);
406416
}
407417

408418
#ifdef __cplusplus
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
class CApiKernelSpecs
22
class ClassWithPublicMethod
33
def public_method(*, **)
4-
0
4+
:public
55
end
66
end
77

88
class ClassWithPrivateMethod
99
private def private_method(*, **)
10-
0
10+
:private
1111
end
1212
end
1313

1414
class ClassWithProtectedMethod
1515
protected def protected_method(*, **)
16-
0
16+
:protected
1717
end
1818
end
1919
end

spec/ruby/optional/capi/kernel_spec.rb

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -606,12 +606,12 @@ def sum(a, b)
606606

607607
it "calls a private method" do
608608
object = CApiKernelSpecs::ClassWithPrivateMethod.new
609-
@s.rb_funcallv(object, :private_method, []).should == 0
609+
@s.rb_funcallv(object, :private_method, []).should == :private
610610
end
611611

612612
it "calls a protected method" do
613613
object = CApiKernelSpecs::ClassWithProtectedMethod.new
614-
@s.rb_funcallv(object, :protected_method, []).should == 0
614+
@s.rb_funcallv(object, :protected_method, []).should == :protected
615615
end
616616
end
617617

@@ -629,12 +629,12 @@ def m(*args, **kwargs)
629629

630630
it "calls a private method" do
631631
object = CApiKernelSpecs::ClassWithPrivateMethod.new
632-
@s.rb_funcallv_kw(object, :private_method, [{}]).should == 0
632+
@s.rb_funcallv_kw(object, :private_method, [{}]).should == :private
633633
end
634634

635635
it "calls a protected method" do
636636
object = CApiKernelSpecs::ClassWithProtectedMethod.new
637-
@s.rb_funcallv_kw(object, :protected_method, [{}]).should == 0
637+
@s.rb_funcallv_kw(object, :protected_method, [{}]).should == :protected
638638
end
639639

640640
it "raises TypeError if the last argument is not a Hash" do
@@ -752,4 +752,39 @@ def method_public(*args, **kw, &block); [args, kw, block.call] end
752752
}.should raise_error(NoMethodError, /protected/)
753753
end
754754
end
755+
756+
describe "rb_check_funcall" do
757+
it "calls a method" do
758+
@s.rb_check_funcall(1, :+, [2]).should == 3
759+
end
760+
761+
it "returns Qundef if the method is not defined" do
762+
obj = Object.new
763+
@s.rb_check_funcall(obj, :foo, []).should == :Qundef
764+
end
765+
766+
it "uses #respond_to? to check if the method is defined" do
767+
ScratchPad.record []
768+
obj = Object.new
769+
def obj.respond_to?(name, priv)
770+
ScratchPad << name
771+
name == :foo || super
772+
end
773+
def obj.method_missing(name, *args)
774+
name == :foo ? [name, 42] : super
775+
end
776+
@s.rb_check_funcall(obj, :foo, []).should == [:foo, 42]
777+
ScratchPad.recorded.should == [:foo]
778+
end
779+
780+
it "calls a private method" do
781+
object = CApiKernelSpecs::ClassWithPrivateMethod.new
782+
@s.rb_check_funcall(object, :private_method, []).should == :private
783+
end
784+
785+
it "calls a protected method" do
786+
object = CApiKernelSpecs::ClassWithProtectedMethod.new
787+
@s.rb_check_funcall(object, :protected_method, []).should == :protected
788+
end
789+
end
755790
end

0 commit comments

Comments
 (0)