summaryrefslogtreecommitdiff
path: root/spec/ruby/optional
diff options
context:
space:
mode:
authorBenoit Daloze <eregontp@gmail.com>2020-05-02 16:03:14 +0200
committerBenoit Daloze <eregontp@gmail.com>2020-05-02 16:03:14 +0200
commitc9213aa864fb8527388679c21f1ea8ce129e2f1a (patch)
treea6ef2403c73ef61a2aaddad6c0f8d9d09e4e6151 /spec/ruby/optional
parenta68ddf42879005905176bc38285906fe01707aff (diff)
Update to ruby/spec@d394dfd
Diffstat (limited to 'spec/ruby/optional')
-rw-r--r--spec/ruby/optional/capi/class_spec.rb66
-rw-r--r--spec/ruby/optional/capi/ext/class_spec.c24
-rw-r--r--spec/ruby/optional/capi/ext/rbasic_spec.c71
-rw-r--r--spec/ruby/optional/capi/ext/symbol_spec.c5
-rw-r--r--spec/ruby/optional/capi/ext/tracepoint_spec.c49
-rw-r--r--spec/ruby/optional/capi/rbasic_spec.rb22
-rw-r--r--spec/ruby/optional/capi/shared/rbasic.rb81
-rw-r--r--spec/ruby/optional/capi/symbol_spec.rb16
-rw-r--r--spec/ruby/optional/capi/tracepoint_spec.rb56
9 files changed, 389 insertions, 1 deletions
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 <ruby/debug.h>
+
+#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