From c9213aa864fb8527388679c21f1ea8ce129e2f1a Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Sat, 2 May 2020 16:03:14 +0200 Subject: Update to ruby/spec@d394dfd --- spec/ruby/optional/capi/class_spec.rb | 66 +++++++++++++++++++++- spec/ruby/optional/capi/ext/class_spec.c | 24 ++++++++ spec/ruby/optional/capi/ext/rbasic_spec.c | 71 +++++++++++++++++++++++ spec/ruby/optional/capi/ext/symbol_spec.c | 5 ++ spec/ruby/optional/capi/ext/tracepoint_spec.c | 49 ++++++++++++++++ spec/ruby/optional/capi/rbasic_spec.rb | 22 ++++++++ spec/ruby/optional/capi/shared/rbasic.rb | 81 +++++++++++++++++++++++++++ spec/ruby/optional/capi/symbol_spec.rb | 16 ++++++ spec/ruby/optional/capi/tracepoint_spec.rb | 56 ++++++++++++++++++ 9 files changed, 389 insertions(+), 1 deletion(-) create mode 100644 spec/ruby/optional/capi/ext/rbasic_spec.c create mode 100644 spec/ruby/optional/capi/ext/tracepoint_spec.c create mode 100644 spec/ruby/optional/capi/rbasic_spec.rb create mode 100644 spec/ruby/optional/capi/shared/rbasic.rb create mode 100644 spec/ruby/optional/capi/tracepoint_spec.rb (limited to 'spec/ruby/optional') diff --git a/spec/ruby/optional/capi/class_spec.rb b/spec/ruby/optional/capi/class_spec.rb index 0b03fb9e6c..c2424668b9 100644 --- a/spec/ruby/optional/capi/class_spec.rb +++ b/spec/ruby/optional/capi/class_spec.rb @@ -1,5 +1,6 @@ require_relative 'spec_helper' require_relative 'fixtures/class' +require_relative '../../core/module/fixtures/classes' load_extension("class") compile_extension("class_under_autoload") @@ -39,6 +40,69 @@ describe "C-API Class function" do @s = CApiClassSpecs.new end + describe "rb_class_instance_methods" do + it "returns the public and protected methods of self and its ancestors" do + methods = @s.rb_class_instance_methods(ModuleSpecs::Basic) + methods.should include(:protected_module, :public_module) + + methods = @s.rb_class_instance_methods(ModuleSpecs::Basic, true) + methods.should include(:protected_module, :public_module) + end + + it "when passed false as a parameter, returns the instance methods of the class" do + methods = @s.rb_class_instance_methods(ModuleSpecs::Child, false) + methods.should include(:protected_child, :public_child) + end + end + + describe "rb_class_public_instance_methods" do + it "returns a list of public methods in module and its ancestors" do + methods = @s.rb_class_public_instance_methods(ModuleSpecs::CountsChild) + methods.should include(:public_3) + methods.should include(:public_2) + methods.should include(:public_1) + + methods = @s.rb_class_public_instance_methods(ModuleSpecs::CountsChild, true) + methods.should include(:public_3) + methods.should include(:public_2) + methods.should include(:public_1) + end + + it "when passed false as a parameter, should return only methods defined in that module" do + @s.rb_class_public_instance_methods(ModuleSpecs::CountsChild, false).should == [:public_1] + end + end + + describe "rb_class_protected_instance_methods" do + it "returns a list of protected methods in module and its ancestors" do + methods = @s.rb_class_protected_instance_methods(ModuleSpecs::CountsChild) + methods.should include(:protected_3) + methods.should include(:protected_2) + methods.should include(:protected_1) + + methods = @s.rb_class_protected_instance_methods(ModuleSpecs::CountsChild, true) + methods.should include(:protected_3) + methods.should include(:protected_2) + methods.should include(:protected_1) + end + + it "when passed false as a parameter, should return only methods defined in that module" do + @s.rb_class_public_instance_methods(ModuleSpecs::CountsChild, false).should == [:public_1] + end + end + + describe "rb_class_private_instance_methods" do + it "returns a list of private methods in module and its ancestors" do + @s.rb_class_private_instance_methods(ModuleSpecs::CountsChild).should == ModuleSpecs::CountsChild.private_instance_methods + @s.rb_class_private_instance_methods(ModuleSpecs::CountsChild, true).should == ModuleSpecs::CountsChild.private_instance_methods + end + + it "when passed false as a parameter, should return only methods defined in that module" do + methods = @s.rb_class_private_instance_methods(ModuleSpecs::CountsChild, false) + methods.should == [:private_1] + end + end + describe "rb_class_new_instance" do it "allocates and initializes a new object" do o = @s.rb_class_new_instance(0, nil, CApiClassSpecs::Alloc) @@ -338,7 +402,7 @@ describe "C-API Class function" do end describe "rb_class_new" do - it "returns an new subclass of the superclass" do + it "returns a new subclass of the superclass" do subclass = @s.rb_class_new(CApiClassSpecs::NewClass) CApiClassSpecs::NewClass.should be_ancestor_of(subclass) end diff --git a/spec/ruby/optional/capi/ext/class_spec.c b/spec/ruby/optional/capi/ext/class_spec.c index e62b9efe2e..36b8c8f2f3 100644 --- a/spec/ruby/optional/capi/ext/class_spec.c +++ b/spec/ruby/optional/capi/ext/class_spec.c @@ -37,6 +37,26 @@ static VALUE class_spec_rb_path_to_class(VALUE self, VALUE path) { return rb_path_to_class(path); } +static VALUE class_spec_rb_class_instance_methods(int argc, VALUE* argv, VALUE self) { + VALUE mod = argv[0]; + return rb_class_instance_methods(--argc, ++argv, mod); +} + +static VALUE class_spec_rb_class_public_instance_methods(int argc, VALUE* argv, VALUE self) { + VALUE mod = argv[0]; + return rb_class_public_instance_methods(--argc, ++argv, mod); +} + +static VALUE class_spec_rb_class_protected_instance_methods(int argc, VALUE* argv, VALUE self) { + VALUE mod = argv[0]; + return rb_class_protected_instance_methods(--argc, ++argv, mod); +} + +static VALUE class_spec_rb_class_private_instance_methods(int argc, VALUE* argv, VALUE self) { + VALUE mod = argv[0]; + return rb_class_private_instance_methods(--argc, ++argv, mod); +} + static VALUE class_spec_rb_class_new(VALUE self, VALUE super) { return rb_class_new(super); } @@ -146,6 +166,10 @@ void Init_class_spec(void) { rb_define_method(cls, "rb_class2name", class_spec_rb_class2name, 1); rb_define_method(cls, "rb_path2class", class_spec_rb_path2class, 1); rb_define_method(cls, "rb_path_to_class", class_spec_rb_path_to_class, 1); + rb_define_method(cls, "rb_class_instance_methods", class_spec_rb_class_instance_methods, -1); + rb_define_method(cls, "rb_class_public_instance_methods", class_spec_rb_class_public_instance_methods, -1); + rb_define_method(cls, "rb_class_protected_instance_methods", class_spec_rb_class_protected_instance_methods, -1); + rb_define_method(cls, "rb_class_private_instance_methods", class_spec_rb_class_private_instance_methods, -1); rb_define_method(cls, "rb_class_new", class_spec_rb_class_new, 1); rb_define_method(cls, "rb_class_new_instance", class_spec_rb_class_new_instance, 3); rb_define_method(cls, "rb_class_real", class_spec_rb_class_real, 1); diff --git a/spec/ruby/optional/capi/ext/rbasic_spec.c b/spec/ruby/optional/capi/ext/rbasic_spec.c new file mode 100644 index 0000000000..b5779ef062 --- /dev/null +++ b/spec/ruby/optional/capi/ext/rbasic_spec.c @@ -0,0 +1,71 @@ +#include "ruby.h" +#include "rubyspec.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +VALUE rbasic_spec_taint_flag(VALUE self) { + return INT2FIX(RUBY_FL_TAINT); +} + +VALUE rbasic_spec_freeze_flag(VALUE self) { + return INT2FIX(RUBY_FL_FREEZE); +} + +VALUE rbasic_spec_get_flags(VALUE self, VALUE val) { + return INT2FIX(RBASIC(val)->flags); +} + +VALUE rbasic_spec_set_flags(VALUE self, VALUE val, VALUE flags) { + RBASIC(val)->flags = FIX2INT(flags); + return INT2FIX(RBASIC(val)->flags); +} + +VALUE rbasic_spec_copy_flags(VALUE self, VALUE to, VALUE from) { + RBASIC(to)->flags = RBASIC(from)->flags; + return INT2FIX(RBASIC(to)->flags); +} + +VALUE rbasic_spec_get_klass(VALUE self, VALUE val) { + return RBASIC(val)->klass; +} + +VALUE rbasic_rdata_spec_get_flags(VALUE self, VALUE structure) { + return INT2FIX(RDATA(structure)->basic.flags); +} + +VALUE rbasic_rdata_spec_set_flags(VALUE self, VALUE structure, VALUE flags) { + RDATA(structure)->basic.flags = FIX2INT(flags); + return INT2FIX(RDATA(structure)->basic.flags); +} + +VALUE rbasic_rdata_spec_copy_flags(VALUE self, VALUE to, VALUE from) { + RDATA(to)->basic.flags = RDATA(from)->basic.flags; + return INT2FIX(RDATA(to)->basic.flags); +} + +VALUE rbasic_rdata_spec_get_klass(VALUE self, VALUE structure) { + return RDATA(structure)->basic.klass; +} + +void Init_rbasic_spec(void) { + VALUE cls = rb_define_class("CApiRBasicSpecs", rb_cObject); + rb_define_method(cls, "taint_flag", rbasic_spec_taint_flag, 0); + rb_define_method(cls, "freeze_flag", rbasic_spec_freeze_flag, 0); + rb_define_method(cls, "get_flags", rbasic_spec_get_flags, 1); + rb_define_method(cls, "set_flags", rbasic_spec_set_flags, 2); + rb_define_method(cls, "copy_flags", rbasic_spec_copy_flags, 2); + rb_define_method(cls, "get_klass", rbasic_spec_get_klass, 1); + + cls = rb_define_class("CApiRBasicRDataSpecs", rb_cObject); + rb_define_method(cls, "get_flags", rbasic_rdata_spec_get_flags, 1); + rb_define_method(cls, "set_flags", rbasic_rdata_spec_set_flags, 2); + rb_define_method(cls, "copy_flags", rbasic_rdata_spec_copy_flags, 2); + rb_define_method(cls, "get_klass", rbasic_rdata_spec_get_klass, 1); +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/spec/ruby/optional/capi/ext/symbol_spec.c b/spec/ruby/optional/capi/ext/symbol_spec.c index d2ca62d81e..7d9a7b4379 100644 --- a/spec/ruby/optional/capi/ext/symbol_spec.c +++ b/spec/ruby/optional/capi/ext/symbol_spec.c @@ -75,6 +75,10 @@ VALUE symbol_spec_rb_sym2str(VALUE self, VALUE sym) { return rb_sym2str(sym); } +VALUE symbol_spec_rb_to_symbol(VALUE self, VALUE val) { + return rb_to_symbol(val); +} + void Init_symbol_spec(void) { VALUE cls = rb_define_class("CApiSymbolSpecs", rb_cObject); rb_define_method(cls, "SYMBOL_P", symbol_spec_SYMBOL_P, 1); @@ -93,6 +97,7 @@ void Init_symbol_spec(void) { rb_define_method(cls, "rb_is_const_id", symbol_spec_rb_is_const_id, 1); rb_define_method(cls, "rb_is_instance_id", symbol_spec_rb_is_instance_id, 1); rb_define_method(cls, "rb_sym2str", symbol_spec_rb_sym2str, 1); + rb_define_method(cls, "rb_to_symbol", symbol_spec_rb_to_symbol, 1); } #ifdef __cplusplus diff --git a/spec/ruby/optional/capi/ext/tracepoint_spec.c b/spec/ruby/optional/capi/ext/tracepoint_spec.c new file mode 100644 index 0000000000..78c459d6cb --- /dev/null +++ b/spec/ruby/optional/capi/ext/tracepoint_spec.c @@ -0,0 +1,49 @@ +#include "ruby.h" +#include "rubyspec.h" + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +static VALUE callback_called = Qnil; + +static void callback(VALUE tpval, void *data) { + callback_called = (VALUE) data; +} + +static VALUE tracepoint_spec_rb_tracepoint_new(VALUE self, VALUE data) { + return rb_tracepoint_new(Qnil, RUBY_EVENT_LINE, callback, (void*) data); +} + +static VALUE tracepoint_spec_callback_called(VALUE self){ + return callback_called; +} + +static VALUE tracepoint_spec_rb_tracepoint_disable(VALUE self, VALUE trace) { + rb_tracepoint_disable(trace); + return rb_tracepoint_enabled_p(trace); +} + +static VALUE tracepoint_spec_rb_tracepoint_enable(VALUE self, VALUE trace) { + rb_tracepoint_enable(trace); + return rb_tracepoint_enabled_p(trace); +} + +static VALUE tracepoint_spec_rb_tracepoint_enabled_p(VALUE self, VALUE trace) { + return rb_tracepoint_enabled_p(trace); +} + +void Init_tracepoint_spec(void) { + VALUE cls = rb_define_class("CApiTracePointSpecs", rb_cObject); + rb_define_method(cls, "rb_tracepoint_new", tracepoint_spec_rb_tracepoint_new, 1); + rb_define_method(cls, "rb_tracepoint_disable", tracepoint_spec_rb_tracepoint_disable, 1); + rb_define_method(cls, "rb_tracepoint_enable", tracepoint_spec_rb_tracepoint_enable, 1); + rb_define_method(cls, "rb_tracepoint_enabled_p", tracepoint_spec_rb_tracepoint_enabled_p, 1); + rb_define_method(cls, "callback_called?", tracepoint_spec_callback_called, 0); +} + +#ifdef __cplusplus +} +#endif diff --git a/spec/ruby/optional/capi/rbasic_spec.rb b/spec/ruby/optional/capi/rbasic_spec.rb new file mode 100644 index 0000000000..283e70db70 --- /dev/null +++ b/spec/ruby/optional/capi/rbasic_spec.rb @@ -0,0 +1,22 @@ +require_relative 'spec_helper' +require_relative 'shared/rbasic' +load_extension("rbasic") +load_extension("data") +load_extension("array") + +describe "RBasic support for regular objects" do + before :all do + @specs = CApiRBasicSpecs.new + @data = -> { [Object.new, Object.new] } + end + it_should_behave_like :rbasic +end + +describe "RBasic support for RData" do + before :all do + @specs = CApiRBasicRDataSpecs.new + @wrapping = CApiWrappedStructSpecs.new + @data = -> { [@wrapping.wrap_struct(1024), @wrapping.wrap_struct(1025)] } + end + it_should_behave_like :rbasic +end diff --git a/spec/ruby/optional/capi/shared/rbasic.rb b/spec/ruby/optional/capi/shared/rbasic.rb new file mode 100644 index 0000000000..efd5c85e61 --- /dev/null +++ b/spec/ruby/optional/capi/shared/rbasic.rb @@ -0,0 +1,81 @@ +describe :rbasic, shared: true do + + before :all do + specs = CApiRBasicSpecs.new + @taint = specs.taint_flag + @freeze = specs.freeze_flag + end + + it "reports the appropriate FREEZE flag for the object when reading" do + obj, _ = @data.call + initial = @specs.get_flags(obj) + obj.freeze + @specs.get_flags(obj).should == @freeze | initial + end + + it "supports setting the FREEZE flag" do + obj, _ = @data.call + initial = @specs.get_flags(obj) + @specs.set_flags(obj, @freeze | initial).should == @freeze | initial + obj.frozen?.should == true + end + + ruby_version_is ""..."2.7" do + it "reports the appropriate FREEZE and TAINT flags for the object when reading" do + obj, _ = @data.call + initial = @specs.get_flags(obj) + obj.taint + @specs.get_flags(obj).should == @taint | initial + obj.untaint + @specs.get_flags(obj).should == initial + obj.freeze + @specs.get_flags(obj).should == @freeze | initial + + obj, _ = @data.call + obj.taint + obj.freeze + @specs.get_flags(obj).should == @freeze | @taint | initial + end + + it "supports setting the FREEZE and TAINT flags" do + obj, _ = @data.call + initial = @specs.get_flags(obj) + @specs.set_flags(obj, @taint | initial).should == @taint | initial + obj.tainted?.should == true + @specs.set_flags(obj, initial).should == initial + obj.tainted?.should == false + @specs.set_flags(obj, @freeze | initial).should == @freeze | initial + obj.frozen?.should == true + + obj, _ = @data.call + @specs.set_flags(obj, @freeze | @taint | initial).should == @freeze | @taint | initial + obj.tainted?.should == true + obj.frozen?.should == true + end + end + + it "supports user flags" do + obj, _ = @data.call + @specs.get_flags(obj) == 0 + @specs.set_flags(obj, 1 << 14 | 1 << 16).should == 1 << 14 | 1 << 16 + @specs.get_flags(obj).should == 1 << 14 | 1 << 16 + @specs.set_flags(obj, 0).should == 0 + end + + it "supports copying the flags from one object over to the other" do + obj1, obj2 = @data.call + @specs.set_flags(obj1, @taint | 1 << 14 | 1 << 16) + @specs.copy_flags(obj2, obj1) + @specs.get_flags(obj2).should == @taint | 1 << 14 | 1 << 16 + @specs.set_flags(obj1, 0) + @specs.copy_flags(obj2, obj1) + @specs.get_flags(obj2).should == 0 + end + + it "supports retrieving the (meta)class" do + obj, _ = @data.call + @specs.get_klass(obj).should == obj.class + obj.singleton_class # ensure the singleton class exists + @specs.get_klass(obj).should == obj.singleton_class + end +end diff --git a/spec/ruby/optional/capi/symbol_spec.rb b/spec/ruby/optional/capi/symbol_spec.rb index 0d71c1c711..b8fda34c0e 100644 --- a/spec/ruby/optional/capi/symbol_spec.rb +++ b/spec/ruby/optional/capi/symbol_spec.rb @@ -153,4 +153,20 @@ describe "C-API Symbol function" do @s.rb_sym2str(:bacon).should == "bacon" end end + + describe "rb_to_symbol" do + it "returns a Symbol for a Symbol" do + @s.rb_to_symbol(:foo).should == :foo + end + + it "returns a Symbol for a String" do + @s.rb_to_symbol("foo").should == :foo + end + + it "coerces to Symbol using to_str" do + o = mock('o') + o.should_receive(:to_str).and_return("foo") + @s.rb_to_symbol(o).should == :foo + end + end end diff --git a/spec/ruby/optional/capi/tracepoint_spec.rb b/spec/ruby/optional/capi/tracepoint_spec.rb new file mode 100644 index 0000000000..6aeac54921 --- /dev/null +++ b/spec/ruby/optional/capi/tracepoint_spec.rb @@ -0,0 +1,56 @@ +require_relative 'spec_helper' + +load_extension("tracepoint") + +describe "CApiTracePointSpecs" do + before :each do + @s = CApiTracePointSpecs.new + end + + after :each do + @trace.disable if @trace and @trace.enabled? + end + + describe "rb_tracepoint_new" do + it "returns a tracepoint object" do + @trace = @s.rb_tracepoint_new(7) + @trace.should be_an_instance_of(TracePoint) + @trace.enabled?.should == false + end + + it "traces lines when given RUBY_EVENT_LINE" do + @trace = @s.rb_tracepoint_new(8) + @trace.enable + @s.callback_called?.should == 8 + end + end + + describe "rb_tracepoint_disable" do + it "disables an enabled TracePoint" do + @trace = @s.rb_tracepoint_new(9) + @trace.enabled?.should == false + @trace.enable + @trace.enabled?.should == true + @s.rb_tracepoint_disable(@trace).should == false + @trace.enabled?.should == false + end + end + + describe "rb_tracepoint_enable" do + it "enables a disabled TracePoint" do + @trace = @s.rb_tracepoint_new(10) + @trace.enabled?.should == false + @s.rb_tracepoint_enable(@trace).should == true + @trace.enabled?.should == true + end + end + + describe "rb_tracepoint_enabled_p" do + it "returns correct enabled status" do + @trace = @s.rb_tracepoint_new(11) + @s.rb_tracepoint_enabled_p(@trace).should == false + @trace.enable + @s.rb_tracepoint_enabled_p(@trace).should == true + end + end +end -- cgit v1.2.3