From a3736e97a6ca517c2cd7d3d93a8f2ef86e39e5b5 Mon Sep 17 00:00:00 2001 From: eregon Date: Sun, 7 May 2017 12:04:49 +0000 Subject: Add in-tree mspec and ruby/spec * For easier modifications of ruby/spec by MRI developers. * .gitignore: track changes under spec. * spec/mspec, spec/rubyspec: add in-tree mspec and ruby/spec. These files can therefore be updated like any other file in MRI. Instructions are provided in spec/README. [Feature #13156] [ruby-core:79246] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58595 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- spec/rubyspec/core/class/new_spec.rb | 154 +++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 spec/rubyspec/core/class/new_spec.rb (limited to 'spec/rubyspec/core/class/new_spec.rb') diff --git a/spec/rubyspec/core/class/new_spec.rb b/spec/rubyspec/core/class/new_spec.rb new file mode 100644 index 0000000000..86323b1575 --- /dev/null +++ b/spec/rubyspec/core/class/new_spec.rb @@ -0,0 +1,154 @@ +require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../fixtures/classes', __FILE__) + +describe "Class.new with a block given" do + it "yields the new class as self in the block" do + self_in_block = nil + klass = Class.new do + self_in_block = self + end + self_in_block.should equal klass + end + + it "uses the given block as the class' body" do + klass = Class.new do + def self.message + "text" + end + + def hello + "hello again" + end + end + + klass.message.should == "text" + klass.new.hello.should == "hello again" + end + + it "creates a subclass of the given superclass" do + sc = Class.new do + def self.body + @body + end + @body = self + def message; "text"; end + end + klass = Class.new(sc) do + def self.body + @body + end + @body = self + def message2; "hello"; end + end + + klass.body.should == klass + sc.body.should == sc + klass.superclass.should == sc + klass.new.message.should == "text" + klass.new.message2.should == "hello" + end + + it "runs the inherited hook after yielding the block" do + ScratchPad.record [] + klass = Class.new(CoreClassSpecs::Inherited::D) do + ScratchPad << self + end + + ScratchPad.recorded.should == [CoreClassSpecs::Inherited::D, klass] + end +end + +describe "Class.new" do + it "creates a new anonymous class" do + klass = Class.new + klass.is_a?(Class).should == true + + klass_instance = klass.new + klass_instance.is_a?(klass).should == true + end + + it "raises a TypeError if passed a metaclass" do + obj = mock("Class.new metaclass") + meta = obj.singleton_class + lambda { Class.new meta }.should raise_error(TypeError) + end + + it "creates a class without a name" do + Class.new.name.should be_nil + end + + it "creates a class that can be given a name by assigning it to a constant" do + ::MyClass = Class.new + ::MyClass.name.should == "MyClass" + a = Class.new + MyClass::NestedClass = a + MyClass::NestedClass.name.should == "MyClass::NestedClass" + end + + it "sets the new class' superclass to the given class" do + top = Class.new + Class.new(top).superclass.should == top + end + + it "sets the new class' superclass to Object when no class given" do + Class.new.superclass.should == Object + end + + it "raises a TypeError when given a non-Class" do + error_msg = /superclass must be a Class/ + lambda { Class.new("") }.should raise_error(TypeError, error_msg) + lambda { Class.new(1) }.should raise_error(TypeError, error_msg) + lambda { Class.new(:symbol) }.should raise_error(TypeError, error_msg) + lambda { Class.new(mock('o')) }.should raise_error(TypeError, error_msg) + lambda { Class.new(Module.new) }.should raise_error(TypeError, error_msg) + end +end + +describe "Class#new" do + it "returns a new instance of self" do + klass = Class.new + klass.new.is_a?(klass).should == true + end + + it "invokes #initialize on the new instance with the given args" do + klass = Class.new do + def initialize(*args) + @initialized = true + @args = args + end + + def args + @args + end + + def initialized? + @initialized || false + end + end + + klass.new.initialized?.should == true + klass.new(1, 2, 3).args.should == [1, 2, 3] + end + + it "uses the internal allocator and does not call #allocate" do + klass = Class.new do + def self.allocate + raise "allocate should not be called" + end + end + + instance = klass.new + instance.should be_kind_of klass + instance.class.should equal klass + end + + it "passes the block to #initialize" do + klass = Class.new do + def initialize + yield + end + end + + klass.new { break 42 }.should == 42 + end +end -- cgit v1.2.3