summaryrefslogtreecommitdiff
path: root/spec/ruby/core/class
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ruby/core/class')
-rw-r--r--spec/ruby/core/class/attached_object_spec.rb31
-rw-r--r--spec/ruby/core/class/descendants_spec.rb38
-rw-r--r--spec/ruby/core/class/dup_spec.rb3
-rw-r--r--spec/ruby/core/class/subclasses_spec.rb87
4 files changed, 121 insertions, 38 deletions
diff --git a/spec/ruby/core/class/attached_object_spec.rb b/spec/ruby/core/class/attached_object_spec.rb
new file mode 100644
index 0000000000..f1c0f63a44
--- /dev/null
+++ b/spec/ruby/core/class/attached_object_spec.rb
@@ -0,0 +1,31 @@
+require_relative '../../spec_helper'
+
+ruby_version_is '3.2' do
+ describe "Class#attached_object" do
+ it "returns the object that is attached to a singleton class" do
+ a = Class.new
+
+ a_obj = a.new
+ a_obj.singleton_class.attached_object.should == a_obj
+ end
+
+ it "returns the class object that is attached to a class's singleton class" do
+ a = Class.new
+ singleton_class = (class << a; self; end)
+
+ singleton_class.attached_object.should == a
+ end
+
+ it "raises TypeError if the class is not a singleton class" do
+ a = Class.new
+
+ -> { a.attached_object }.should raise_error(TypeError, /is not a singleton class/)
+ end
+
+ it "raises TypeError for special singleton classes" do
+ -> { nil.singleton_class.attached_object }.should raise_error(TypeError, /[`']NilClass' is not a singleton class/)
+ -> { true.singleton_class.attached_object }.should raise_error(TypeError, /[`']TrueClass' is not a singleton class/)
+ -> { false.singleton_class.attached_object }.should raise_error(TypeError, /[`']FalseClass' is not a singleton class/)
+ end
+ end
+end
diff --git a/spec/ruby/core/class/descendants_spec.rb b/spec/ruby/core/class/descendants_spec.rb
deleted file mode 100644
index f87cd68be8..0000000000
--- a/spec/ruby/core/class/descendants_spec.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-require_relative '../../spec_helper'
-require_relative '../module/fixtures/classes'
-
-ruby_version_is '3.1' do
- describe "Class#descendants" do
- it "returns a list of classes descended from self (excluding self)" do
- assert_descendants(ModuleSpecs::Parent, [ModuleSpecs::Child, ModuleSpecs::Child2, ModuleSpecs::Grandchild])
- end
-
- it "does not return included modules" do
- parent = Class.new
- child = Class.new(parent)
- mod = Module.new
- parent.include(mod)
-
- assert_descendants(parent, [child])
- end
-
- it "does not return singleton classes" do
- a = Class.new
-
- a_obj = a.new
- def a_obj.force_singleton_class
- 42
- end
-
- a.descendants.should_not include(a_obj.singleton_class)
- end
-
- it "has 1 entry per module or class" do
- ModuleSpecs::Parent.descendants.should == ModuleSpecs::Parent.descendants.uniq
- end
-
- def assert_descendants(mod, descendants)
- mod.descendants.sort_by(&:inspect).should == descendants.sort_by(&:inspect)
- end
- end
-end
diff --git a/spec/ruby/core/class/dup_spec.rb b/spec/ruby/core/class/dup_spec.rb
index 701fd72e19..c09ed71b31 100644
--- a/spec/ruby/core/class/dup_spec.rb
+++ b/spec/ruby/core/class/dup_spec.rb
@@ -61,4 +61,7 @@ describe "Class#dup" do
CoreClassSpecs::RecordCopy.name.should == "CoreClassSpecs::RecordCopy"
end
+ it "raises TypeError if called on BasicObject" do
+ -> { BasicObject.dup }.should raise_error(TypeError, "can't copy the root class")
+ end
end
diff --git a/spec/ruby/core/class/subclasses_spec.rb b/spec/ruby/core/class/subclasses_spec.rb
new file mode 100644
index 0000000000..50eb5358d9
--- /dev/null
+++ b/spec/ruby/core/class/subclasses_spec.rb
@@ -0,0 +1,87 @@
+require_relative '../../spec_helper'
+require_relative '../module/fixtures/classes'
+
+ruby_version_is '3.1' do
+ describe "Class#subclasses" do
+ it "returns a list of classes directly inheriting from self" do
+ assert_subclasses(ModuleSpecs::Parent, [ModuleSpecs::Child, ModuleSpecs::Child2])
+ end
+
+ it "does not return included modules from the parent" do
+ parent = Class.new
+ child = Class.new(parent)
+ mod = Module.new
+ parent.include(mod)
+
+ assert_subclasses(parent, [child])
+ end
+
+ it "does not return included modules from the child" do
+ parent = Class.new
+ child = Class.new(parent)
+ mod = Module.new
+ parent.include(mod)
+
+ assert_subclasses(parent, [child])
+ end
+
+ it "does not return prepended modules from the parent" do
+ parent = Class.new
+ child = Class.new(parent)
+ mod = Module.new
+ parent.prepend(mod)
+
+ assert_subclasses(parent, [child])
+ end
+
+ it "does not return prepended modules from the child" do
+ parent = Class.new
+ child = Class.new(parent)
+ mod = Module.new
+ child.prepend(mod)
+
+ assert_subclasses(parent, [child])
+ end
+
+ it "does not return singleton classes" do
+ a = Class.new
+
+ a_obj = a.new
+ def a_obj.force_singleton_class
+ 42
+ end
+
+ a.subclasses.should_not include(a_obj.singleton_class)
+ end
+
+ it "has 1 entry per module or class" do
+ ModuleSpecs::Parent.subclasses.should == ModuleSpecs::Parent.subclasses.uniq
+ end
+
+ it "works when creating subclasses concurrently" do
+ t = 16
+ n = 1000
+ go = false
+ superclass = Class.new
+
+ threads = t.times.map do
+ Thread.new do
+ Thread.pass until go
+ n.times.map do
+ Class.new(superclass)
+ end
+ end
+ end
+
+ go = true
+ classes = threads.map(&:value)
+
+ superclass.subclasses.size.should == t * n
+ superclass.subclasses.each { |c| c.should be_kind_of(Class) }
+ end
+
+ def assert_subclasses(mod,subclasses)
+ mod.subclasses.sort_by(&:inspect).should == subclasses.sort_by(&:inspect)
+ end
+ end
+end