diff options
Diffstat (limited to 'spec/ruby/language/class_spec.rb')
| -rw-r--r-- | spec/ruby/language/class_spec.rb | 103 |
1 files changed, 83 insertions, 20 deletions
diff --git a/spec/ruby/language/class_spec.rb b/spec/ruby/language/class_spec.rb index d07454a3a7..6fb785fd56 100644 --- a/spec/ruby/language/class_spec.rb +++ b/spec/ruby/language/class_spec.rb @@ -17,6 +17,19 @@ describe "The class keyword" do eval "class ClassSpecsKeywordWithoutSemicolon end" ClassSpecsKeywordWithoutSemicolon.should be_an_instance_of(Class) end + + it "can redefine a class when called from a block" do + ClassSpecs::DEFINE_CLASS.call + A.should be_an_instance_of(Class) + + Object.send(:remove_const, :A) + defined?(A).should be_nil + + ClassSpecs::DEFINE_CLASS.call + A.should be_an_instance_of(Class) + ensure + Object.send(:remove_const, :A) if defined?(::A) + end end describe "A class definition" do @@ -30,27 +43,34 @@ describe "A class definition" do end it "raises TypeError if constant given as class name exists and is not a Module" do - lambda { + -> { class ClassSpecsNumber end - }.should raise_error(TypeError) + }.should raise_error(TypeError, /\AClassSpecsNumber is not a class/) + end + + it "raises TypeError if constant given as class name exists and is a Module but not a Class" do + -> { + class ClassSpecs + end + }.should raise_error(TypeError, /\AClassSpecs is not a class/) end # test case known to be detecting bugs (JRuby, MRI) it "raises TypeError if the constant qualifying the class is nil" do - lambda { + -> { class nil::Foo end }.should raise_error(TypeError) end it "raises TypeError if any constant qualifying the class is not a Module" do - lambda { + -> { class ClassSpecs::Number::MyClass end }.should raise_error(TypeError) - lambda { + -> { class ClassSpecsNumber::MyClass end }.should raise_error(TypeError) @@ -64,7 +84,7 @@ describe "A class definition" do module ClassSpecs class SuperclassResetToSubclass < L end - lambda { + -> { class SuperclassResetToSubclass < M end }.should raise_error(TypeError, /superclass mismatch/) @@ -77,7 +97,7 @@ describe "A class definition" do end SuperclassReopenedBasicObject.superclass.should == A - lambda { + -> { class SuperclassReopenedBasicObject < BasicObject end }.should raise_error(TypeError, /superclass mismatch/) @@ -92,7 +112,7 @@ describe "A class definition" do end SuperclassReopenedObject.superclass.should == A - lambda { + -> { class SuperclassReopenedObject < Object end }.should raise_error(TypeError, /superclass mismatch/) @@ -117,7 +137,7 @@ describe "A class definition" do class NoSuperclassSet end - lambda { + -> { class NoSuperclassSet < String end }.should raise_error(TypeError, /superclass mismatch/) @@ -127,7 +147,7 @@ describe "A class definition" do it "allows using self as the superclass if self is a class" do ClassSpecs::I::J.superclass.should == ClassSpecs::I - lambda { + -> { class ShouldNotWork < self; end }.should raise_error(TypeError) end @@ -148,7 +168,7 @@ describe "A class definition" do it "raises a TypeError if inheriting from a metaclass" do obj = mock("metaclass super") meta = obj.singleton_class - lambda { class ClassSpecs::MetaclassSuper < meta; end }.should raise_error(TypeError) + -> { class ClassSpecs::MetaclassSuper < meta; end }.should raise_error(TypeError) end it "allows the declaration of class variables in the body" do @@ -258,6 +278,8 @@ describe "A class definition" do AnonWithConstant.name.should == 'AnonWithConstant' klass.get_class_name.should == 'AnonWithConstant' + ensure + Object.send(:remove_const, :AnonWithConstant) end end end @@ -274,7 +296,7 @@ describe "A class definition extending an object (sclass)" do end it "raises a TypeError when trying to extend numbers" do - lambda { + -> { eval <<-CODE class << 1 def xyz @@ -285,12 +307,20 @@ describe "A class definition extending an object (sclass)" do }.should raise_error(TypeError) end - ruby_version_is ""..."3.0" do - it "allows accessing the block of the original scope" do - suppress_warning do - ClassSpecs.sclass_with_block { 123 }.should == 123 - end - end + it "raises a TypeError when trying to extend non-Class" do + error_msg = /superclass must be a.* Class/ + -> { class TestClass < ""; end }.should raise_error(TypeError, error_msg) + -> { class TestClass < 1; end }.should raise_error(TypeError, error_msg) + -> { class TestClass < :symbol; end }.should raise_error(TypeError, error_msg) + -> { class TestClass < mock('o'); end }.should raise_error(TypeError, error_msg) + -> { class TestClass < Module.new; end }.should raise_error(TypeError, error_msg) + -> { class TestClass < BasicObject.new; end }.should raise_error(TypeError, error_msg) + end + + it "does not allow accessing the block of the original scope" do + -> { + ClassSpecs.sclass_with_block { 123 } + }.should raise_error(SyntaxError) end it "can use return to cause the enclosing method to return" do @@ -310,11 +340,11 @@ describe "Reopening a class" do end it "raises a TypeError when superclasses mismatch" do - lambda { class ClassSpecs::A < Array; end }.should raise_error(TypeError) + -> { class ClassSpecs::A < Array; end }.should raise_error(TypeError) end it "adds new methods to subclasses" do - lambda { ClassSpecs::M.m }.should raise_error(NoMethodError) + -> { ClassSpecs::M.m }.should raise_error(NoMethodError) class ClassSpecs::L def self.m 1 @@ -323,6 +353,39 @@ describe "Reopening a class" do ClassSpecs::M.m.should == 1 ClassSpecs::L.singleton_class.send(:remove_method, :m) end + + it "does not reopen a class included in Object" do + ruby_exe(<<~RUBY).should == "false" + module IncludedInObject + class IncludedClass + end + end + class Object + include IncludedInObject + end + class IncludedClass + end + print IncludedInObject::IncludedClass == Object::IncludedClass + RUBY + end + + it "does not reopen a class included in non-Object modules" do + ruby_exe(<<~RUBY).should == "false/false" + module Included + module IncludedClass; end + end + module M + include Included + module IncludedClass; end + end + class C + include Included + module IncludedClass; end + end + print Included::IncludedClass == M::IncludedClass, "/", + Included::IncludedClass == C::IncludedClass + RUBY + end end describe "class provides hooks" do |
