summaryrefslogtreecommitdiff
path: root/spec/ruby/optional/capi/class_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ruby/optional/capi/class_spec.rb')
-rw-r--r--spec/ruby/optional/capi/class_spec.rb270
1 files changed, 195 insertions, 75 deletions
diff --git a/spec/ruby/optional/capi/class_spec.rb b/spec/ruby/optional/capi/class_spec.rb
index a25e80af60..07e9e42ad1 100644
--- a/spec/ruby/optional/capi/class_spec.rb
+++ b/spec/ruby/optional/capi/class_spec.rb
@@ -1,5 +1,6 @@
-require File.expand_path('../spec_helper', __FILE__)
-require File.expand_path('../fixtures/class', __FILE__)
+require_relative 'spec_helper'
+require_relative 'fixtures/class'
+require_relative '../../core/module/fixtures/classes'
load_extension("class")
compile_extension("class_under_autoload")
@@ -10,7 +11,8 @@ autoload :ClassIdUnderAutoload, "#{object_path}/class_id_under_autoload_spec"
describe :rb_path_to_class, shared: true do
it "returns a class or module from a scoped String" do
- @s.send(@method, "CApiClassSpecs::A::B").should equal(CApiClassSpecs::A::B)
+ @s.send(@method, "CApiClassSpecs::A::B").should.equal?(CApiClassSpecs::A::B)
+ @s.send(@method, "CApiClassSpecs::A::M").should.equal?(CApiClassSpecs::A::M)
end
it "resolves autoload constants" do
@@ -18,19 +20,21 @@ describe :rb_path_to_class, shared: true do
end
it "raises an ArgumentError if a constant in the path does not exist" do
- lambda { @s.send(@method, "CApiClassSpecs::NotDefined::B") }.should raise_error(ArgumentError)
+ -> { @s.send(@method, "CApiClassSpecs::NotDefined::B") }.should.raise(ArgumentError)
end
it "raises an ArgumentError if the final constant does not exist" do
- lambda { @s.send(@method, "CApiClassSpecs::NotDefined") }.should raise_error(ArgumentError)
+ -> { @s.send(@method, "CApiClassSpecs::NotDefined") }.should.raise(ArgumentError)
end
it "raises a TypeError if the constant is not a class or module" do
- lambda { @s.send(@method, "CApiClassSpecs::A::C") }.should raise_error(TypeError)
+ -> {
+ @s.send(@method, "CApiClassSpecs::A::C")
+ }.should.raise(TypeError, 'CApiClassSpecs::A::C does not refer to class/module')
end
it "raises an ArgumentError even if a constant in the path exists on toplevel" do
- lambda { @s.send(@method, "CApiClassSpecs::Object") }.should raise_error(ArgumentError)
+ -> { @s.send(@method, "CApiClassSpecs::Object") }.should.raise(ArgumentError)
end
end
@@ -39,26 +43,109 @@ 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)
+ methods.should.include?(:public_module)
+
+ methods = @s.rb_class_instance_methods(ModuleSpecs::Basic, true)
+ methods.should.include?(:protected_module)
+ methods.should.include?(: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.to_set.should >= Set[: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)
+ o = @s.rb_class_new_instance([], CApiClassSpecs::Alloc)
o.class.should == CApiClassSpecs::Alloc
- o.initialized.should be_true
+ o.initialized.should == true
end
it "passes arguments to the #initialize method" do
- o = @s.rb_class_new_instance(2, [:one, :two], CApiClassSpecs::Alloc)
+ o = @s.rb_class_new_instance([:one, :two], CApiClassSpecs::Alloc)
o.arguments.should == [:one, :two]
end
end
+ describe "rb_class_new_instance_kw" do
+ it "passes arguments and keywords to the #initialize method" do
+ obj = @s.rb_class_new_instance_kw([{pos: 1}, {kw: 2}], CApiClassSpecs::KeywordAlloc)
+ obj.args.should == [{pos: 1}]
+ obj.kwargs.should == {kw: 2}
+
+ obj = @s.rb_class_new_instance_kw([{}], CApiClassSpecs::KeywordAlloc)
+ obj.args.should == []
+ obj.kwargs.should == {}
+ end
+
+ it "raises TypeError if the last argument is not a Hash" do
+ -> {
+ @s.rb_class_new_instance_kw([42], CApiClassSpecs::KeywordAlloc)
+ }.should.raise(TypeError, 'no implicit conversion of Integer into Hash')
+ end
+ end
+
describe "rb_include_module" do
it "includes a module into a class" do
c = Class.new
o = c.new
- lambda { o.included? }.should raise_error(NameError)
+ -> { o.included? }.should.raise(NameError)
@s.rb_include_module(c, CApiClassSpecs::M)
- o.included?.should be_true
+ o.included?.should == true
end
end
@@ -70,12 +157,12 @@ describe "C-API Class function" do
it "defines an attr_reader when passed true, false" do
@s.rb_define_attr(CApiClassSpecs::Attr, :foo, true, false)
@a.foo.should == 1
- lambda { @a.foo = 5 }.should raise_error(NameError)
+ -> { @a.foo = 5 }.should.raise(NameError)
end
it "defines an attr_writer when passed false, true" do
@s.rb_define_attr(CApiClassSpecs::Attr, :bar, false, true)
- lambda { @a.bar }.should raise_error(NameError)
+ -> { @a.bar }.should.raise(NameError)
@a.bar = 5
@a.instance_variable_get(:@bar).should == 5
end
@@ -95,6 +182,12 @@ describe "C-API Class function" do
obj.call_super_method.should == :super_method
end
+ it "calls the method in the superclass with the correct self" do
+ @s.define_call_super_method CApiClassSpecs::SubSelf, "call_super_method"
+ obj = CApiClassSpecs::SubSelf.new
+ obj.call_super_method.should.equal? obj
+ end
+
it "calls the method in the superclass through two native levels" do
@s.define_call_super_method CApiClassSpecs::Sub, "call_super_method"
@s.define_call_super_method CApiClassSpecs::SubSub, "call_super_method"
@@ -109,7 +202,11 @@ describe "C-API Class function" do
end
it "returns a string for an anonymous class" do
- @s.rb_class2name(Class.new).should be_kind_of(String)
+ @s.rb_class2name(Class.new).should.is_a?(String)
+ end
+
+ it "returns a string beginning with # for an anonymous class" do
+ @s.rb_class2name(Struct.new(:x, :y).new(1, 2).class).should.start_with?('#')
end
end
@@ -129,7 +226,7 @@ describe "C-API Class function" do
end
it "returns a string for an anonymous class" do
- @s.rb_class_name(Class.new).should be_kind_of(String)
+ @s.rb_class_name(Class.new).should.is_a?(String)
end
end
@@ -143,22 +240,22 @@ describe "C-API Class function" do
describe "rb_cvar_defined" do
it "returns false when the class variable is not defined" do
- @s.rb_cvar_defined(CApiClassSpecs::CVars, "@@nocvar").should be_false
+ @s.rb_cvar_defined(CApiClassSpecs::CVars, "@@nocvar").should == false
end
it "returns true when the class variable is defined" do
- @s.rb_cvar_defined(CApiClassSpecs::CVars, "@@cvar").should be_true
+ @s.rb_cvar_defined(CApiClassSpecs::CVars, "@@cvar").should == true
end
it "returns true if the class instance variable is defined" do
- @s.rb_cvar_defined(CApiClassSpecs::CVars, "@c_ivar").should be_true
+ @s.rb_cvar_defined(CApiClassSpecs::CVars, "@c_ivar").should == true
end
end
describe "rb_cv_set" do
it "sets a class variable" do
o = CApiClassSpecs::CVars.new
- o.new_cv.should be_nil
+ o.new_cv.should == nil
@s.rb_cv_set(CApiClassSpecs::CVars, "@@new_cv", 1)
o.new_cv.should == 1
CApiClassSpecs::CVars.remove_class_variable :@@new_cv
@@ -171,16 +268,16 @@ describe "C-API Class function" do
end
it "raises a NameError if the class variable is not defined" do
- lambda {
+ -> {
@s.rb_cv_get(CApiClassSpecs::CVars, "@@no_cvar")
- }.should raise_error(NameError, /class variable @@no_cvar/)
+ }.should.raise(NameError, /class variable @@no_cvar/)
end
end
describe "rb_cvar_set" do
it "sets a class variable" do
o = CApiClassSpecs::CVars.new
- o.new_cvar.should be_nil
+ o.new_cvar.should == nil
@s.rb_cvar_set(CApiClassSpecs::CVars, "@@new_cvar", 1)
o.new_cvar.should == 1
CApiClassSpecs::CVars.remove_class_variable :@@new_cvar
@@ -194,8 +291,8 @@ describe "C-API Class function" do
end
it "creates a subclass of the superclass" do
- @cls.should be_kind_of(Class)
- ClassSpecDefineClass.should equal(@cls)
+ @cls.should.is_a?(Class)
+ ClassSpecDefineClass.should.equal?(@cls)
@cls.superclass.should == CApiClassSpecs::Super
end
@@ -210,23 +307,30 @@ describe "C-API Class function" do
end
it "raises a TypeError when given a non class object to superclass" do
- lambda {
+ -> {
@s.rb_define_class("ClassSpecDefineClass3", Module.new)
- }.should raise_error(TypeError)
+ }.should.raise(TypeError)
end
it "raises a TypeError when given a mismatched class to superclass" do
- lambda {
+ -> {
@s.rb_define_class("ClassSpecDefineClass", Object)
- }.should raise_error(TypeError)
+ }.should.raise(TypeError)
+ end
+
+ it "raises a ArgumentError when given NULL as superclass" do
+ -> {
+ @s.rb_define_class("ClassSpecDefineClass4", nil)
+ }.should.raise(ArgumentError)
end
- ruby_version_is "2.4" do
- it "raises a ArgumentError when given NULL as superclass" do
- lambda {
- @s.rb_define_class("ClassSpecDefineClass4", nil)
- }.should raise_error(ArgumentError)
- end
+ it "allows arbitrary names, including constant names not valid in Ruby" do
+ cls = @s.rb_define_class("_INVALID_CLASS", CApiClassSpecs::Super)
+ cls.name.should == "_INVALID_CLASS"
+
+ -> {
+ Object.const_get(cls.name)
+ }.should.raise(NameError, /wrong constant name/)
end
end
@@ -235,8 +339,8 @@ describe "C-API Class function" do
cls = @s.rb_define_class_under(CApiClassSpecs,
"ClassUnder1",
CApiClassSpecs::Super)
- cls.should be_kind_of(Class)
- CApiClassSpecs::Super.should be_ancestor_of(CApiClassSpecs::ClassUnder1)
+ cls.should.is_a?(Class)
+ CApiClassSpecs::ClassUnder1.ancestors.should.include?(CApiClassSpecs::Super)
end
it "sets the class name" do
@@ -251,48 +355,45 @@ describe "C-API Class function" do
end
it "raises a TypeError when given a non class object to superclass" do
- lambda { @s.rb_define_class_under(CApiClassSpecs,
+ -> { @s.rb_define_class_under(CApiClassSpecs,
"ClassUnder5",
Module.new)
- }.should raise_error(TypeError)
- end
-
- ruby_version_is "2.3" do
- it "raises a TypeError when given a mismatched class to superclass" do
- CApiClassSpecs::ClassUnder6 = Class.new(CApiClassSpecs::Super)
- lambda { @s.rb_define_class_under(CApiClassSpecs,
- "ClassUnder6",
- Class.new)
- }.should raise_error(TypeError)
- end
+ }.should.raise(TypeError)
end
- ruby_version_is ""..."2.3" do
- it "raises a NameError when given a mismatched class to superclass" do
- CApiClassSpecs::ClassUnder6 = Class.new(CApiClassSpecs::Super)
- lambda { @s.rb_define_class_under(CApiClassSpecs,
- "ClassUnder6",
- Class.new)
- }.should raise_error(NameError)
- end
+ it "raises a TypeError when given a mismatched class to superclass" do
+ CApiClassSpecs::ClassUnder6 = Class.new(CApiClassSpecs::Super)
+ -> { @s.rb_define_class_under(CApiClassSpecs,
+ "ClassUnder6",
+ Class.new)
+ }.should.raise(TypeError)
+ ensure
+ CApiClassSpecs.send(:remove_const, :ClassUnder6)
end
it "defines a class for an existing Autoload" do
ClassUnderAutoload.name.should == "ClassUnderAutoload"
end
- ruby_version_is "2.3" do
- it "raises a TypeError if class is defined and its superclass mismatches the given one" do
- lambda { @s.rb_define_class_under(CApiClassSpecs, "Sub", Object) }.should raise_error(TypeError)
- end
+ it "raises a TypeError if class is defined and its superclass mismatches the given one" do
+ -> { @s.rb_define_class_under(CApiClassSpecs, "Sub", Object) }.should.raise(TypeError)
+ end
+
+ it "allows arbitrary names, including constant names not valid in Ruby" do
+ cls = @s.rb_define_class_under(CApiClassSpecs, "_INVALID_CLASS", CApiClassSpecs::Super)
+ cls.name.should == "CApiClassSpecs::_INVALID_CLASS"
+
+ -> {
+ CApiClassSpecs.const_get(cls.name)
+ }.should.raise(NameError, /wrong constant name/)
end
end
describe "rb_define_class_id_under" do
it "creates a subclass of the superclass contained in a module" do
cls = @s.rb_define_class_id_under(CApiClassSpecs, :ClassIdUnder1, CApiClassSpecs::Super)
- cls.should be_kind_of(Class)
- CApiClassSpecs::Super.should be_ancestor_of(CApiClassSpecs::ClassIdUnder1)
+ cls.should.is_a?(Class)
+ CApiClassSpecs::ClassIdUnder1.ancestors.should.include?(CApiClassSpecs::Super)
end
it "sets the class name" do
@@ -310,17 +411,24 @@ describe "C-API Class function" do
ClassIdUnderAutoload.name.should == "ClassIdUnderAutoload"
end
- ruby_version_is "2.3" do
- it "raises a TypeError if class is defined and its superclass mismatches the given one" do
- lambda { @s.rb_define_class_id_under(CApiClassSpecs, :Sub, Object) }.should raise_error(TypeError)
- end
+ it "raises a TypeError if class is defined and its superclass mismatches the given one" do
+ -> { @s.rb_define_class_id_under(CApiClassSpecs, :Sub, Object) }.should.raise(TypeError)
+ end
+
+ it "allows arbitrary names, including constant names not valid in Ruby" do
+ cls = @s.rb_define_class_id_under(CApiClassSpecs, :_INVALID_CLASS2, CApiClassSpecs::Super)
+ cls.name.should == "CApiClassSpecs::_INVALID_CLASS2"
+
+ -> {
+ CApiClassSpecs.const_get(cls.name)
+ }.should.raise(NameError, /wrong constant name/)
end
end
describe "rb_define_class_variable" do
it "sets a class variable" do
o = CApiClassSpecs::CVars.new
- o.rbdcv_cvar.should be_nil
+ o.rbdcv_cvar.should == nil
@s.rb_define_class_variable(CApiClassSpecs::CVars, "@@rbdcv_cvar", 1)
o.rbdcv_cvar.should == 1
CApiClassSpecs::CVars.remove_class_variable :@@rbdcv_cvar
@@ -333,25 +441,25 @@ describe "C-API Class function" do
end
it "raises a NameError if the class variable is not defined" do
- lambda {
+ -> {
@s.rb_cvar_get(CApiClassSpecs::CVars, "@@no_cvar")
- }.should raise_error(NameError, /class variable @@no_cvar/)
+ }.should.raise(NameError, /class variable @@no_cvar/)
end
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)
+ subclass.ancestors.should.include?(CApiClassSpecs::NewClass)
end
it "raises a TypeError if passed Class as the superclass" do
- lambda { @s.rb_class_new(Class) }.should raise_error(TypeError)
+ -> { @s.rb_class_new(Class) }.should.raise(TypeError)
end
it "raises a TypeError if passed a singleton class as the superclass" do
metaclass = Object.new.singleton_class
- lambda { @s.rb_class_new(metaclass) }.should raise_error(TypeError)
+ -> { @s.rb_class_new(metaclass) }.should.raise(TypeError)
end
end
@@ -362,7 +470,7 @@ describe "C-API Class function" do
end
it "returns nil if the class has no superclass" do
- @s.rb_class_superclass(BasicObject).should be_nil
+ @s.rb_class_superclass(BasicObject).should == nil
end
end
@@ -383,4 +491,16 @@ describe "C-API Class function" do
@s.rb_class_real(0).should == 0
end
end
+
+ describe "rb_class_get_superclass" do
+ it "returns parent class for a provided class" do
+ a = Class.new
+ @s.rb_class_get_superclass(Class.new(a)).should == a
+ end
+
+ it "returns false when there is no parent class" do
+ @s.rb_class_get_superclass(BasicObject).should == false
+ @s.rb_class_get_superclass(Module.new).should == false
+ end
+ end
end