diff options
Diffstat (limited to 'spec/ruby/core/basicobject')
18 files changed, 763 insertions, 0 deletions
diff --git a/spec/ruby/core/basicobject/__id__spec.rb b/spec/ruby/core/basicobject/__id__spec.rb new file mode 100644 index 0000000000..fba9ed3b34 --- /dev/null +++ b/spec/ruby/core/basicobject/__id__spec.rb @@ -0,0 +1,6 @@ +require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../../../shared/kernel/object_id', __FILE__) + +describe "BasicObject#__id__" do + it_behaves_like :object_id, :__id__, BasicObject +end diff --git a/spec/ruby/core/basicobject/__send___spec.rb b/spec/ruby/core/basicobject/__send___spec.rb new file mode 100644 index 0000000000..f25339fac7 --- /dev/null +++ b/spec/ruby/core/basicobject/__send___spec.rb @@ -0,0 +1,10 @@ +require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../../../shared/basicobject/send', __FILE__) + +describe "BasicObject#__send__" do + it "is a public instance method" do + BasicObject.should have_public_instance_method(:__send__) + end + + it_behaves_like(:basicobject_send, :__send__) +end diff --git a/spec/ruby/core/basicobject/basicobject_spec.rb b/spec/ruby/core/basicobject/basicobject_spec.rb new file mode 100644 index 0000000000..f58c17a0c0 --- /dev/null +++ b/spec/ruby/core/basicobject/basicobject_spec.rb @@ -0,0 +1,87 @@ +require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../fixtures/common', __FILE__) + +describe "BasicObject" do + it "raises NoMethodError for nonexistent methods after #method_missing is removed" do + script = fixture __FILE__, "remove_method_missing.rb" + ruby_exe(script).chomp.should == "NoMethodError" + end + + it "raises NameError when referencing built-in constants" do + lambda { class BasicObjectSpecs::BOSubclass; Kernel; end }.should raise_error(NameError) + end + + it "does not define built-in constants (according to const_defined?)" do + BasicObject.const_defined?(:Kernel).should be_false + end + + it "does not define built-in constants (according to defined?)" do + BasicObjectSpecs::BOSubclass.kernel_defined?.should be_nil + end + + it "includes itself in its list of constants" do + BasicObject.constants.should include(:BasicObject) + end +end + +describe "BasicObject metaclass" do + before :each do + @meta = class << BasicObject; self; end + end + + it "is an instance of Class" do + @meta.should be_an_instance_of(Class) + end + + it "has Class as superclass" do + @meta.superclass.should equal(Class) + end + + it "contains methods for the BasicObject class" do + @meta.class_eval do + def rubyspec_test_method() :test end + end + + BasicObject.rubyspec_test_method.should == :test + end +end + +describe "BasicObject instance metaclass" do + before :each do + @object = BasicObject.new + @meta = class << @object; self; end + end + + it "is an instance of Class" do + @meta.should be_an_instance_of(Class) + end + + it "has BasicObject as superclass" do + @meta.superclass.should equal(BasicObject) + end + + it "contains methods defined for the BasicObject instance" do + @meta.class_eval do + def test_method() :test end + end + + @object.test_method.should == :test + end +end + +describe "BasicObject subclass" do + it "contains Kernel methods when including Kernel" do + obj = BasicObjectSpecs::BOSubclass.new + + obj.instance_variable_set(:@test, :value) + obj.instance_variable_get(:@test).should == :value + + obj.respond_to?(:hash).should == true + end + + describe "BasicObject references" do + it "can refer to BasicObject from within itself" do + lambda { BasicObject::BasicObject }.should_not raise_error + end + end +end diff --git a/spec/ruby/core/basicobject/equal_spec.rb b/spec/ruby/core/basicobject/equal_spec.rb new file mode 100644 index 0000000000..8120df836f --- /dev/null +++ b/spec/ruby/core/basicobject/equal_spec.rb @@ -0,0 +1,52 @@ +require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../../../shared/kernel/equal', __FILE__) + +describe "BasicObject#equal?" do + it "is a public instance method" do + BasicObject.should have_public_instance_method(:equal?) + end + + it_behaves_like :object_equal, :equal? + + it "is unaffected by overriding __id__" do + o1 = mock("object") + o2 = mock("object") + def o1.__id__; 10; end + def o2.__id__; 10; end + o1.equal?(o2).should be_false + end + + it "is unaffected by overriding object_id" do + o1 = mock("object") + o1.stub!(:object_id).and_return(10) + o2 = mock("object") + o2.stub!(:object_id).and_return(10) + o1.equal?(o2).should be_false + end + + it "is unaffected by overriding ==" do + # different objects, overriding == to return true + o1 = mock("object") + o1.stub!(:==).and_return(true) + o2 = mock("object") + o1.equal?(o2).should be_false + + # same objects, overriding == to return false + o3 = mock("object") + o3.stub!(:==).and_return(false) + o3.equal?(o3).should be_true + end + + it "is unaffected by overriding eql?" do + # different objects, overriding eql? to return true + o1 = mock("object") + o1.stub!(:eql?).and_return(true) + o2 = mock("object") + o1.equal?(o2).should be_false + + # same objects, overriding eql? to return false + o3 = mock("object") + o3.stub!(:eql?).and_return(false) + o3.equal?(o3).should be_true + end +end diff --git a/spec/ruby/core/basicobject/equal_value_spec.rb b/spec/ruby/core/basicobject/equal_value_spec.rb new file mode 100644 index 0000000000..7d67634884 --- /dev/null +++ b/spec/ruby/core/basicobject/equal_value_spec.rb @@ -0,0 +1,10 @@ +require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../../../shared/kernel/equal', __FILE__) + +describe "BasicObject#==" do + it "is a public instance method" do + BasicObject.should have_public_instance_method(:==) + end + + it_behaves_like :object_equal, :== +end diff --git a/spec/ruby/core/basicobject/fixtures/classes.rb b/spec/ruby/core/basicobject/fixtures/classes.rb new file mode 100644 index 0000000000..d1785afe31 --- /dev/null +++ b/spec/ruby/core/basicobject/fixtures/classes.rb @@ -0,0 +1,33 @@ +module BasicObjectSpecs + class IVars + def initialize + @secret = 99 + end + end + + module InstExec + def self.included(base) + base.instance_exec { @@count = 2 } + end + end + + module InstExecIncluded + include InstExec + end + + module InstEvalCVar + instance_eval { @@count = 2 } + end + + class InstEvalConst + INST_EVAL_CONST_X = 2 + end + + module InstEvalOuter + module Inner + obj = InstEvalConst.new + X_BY_STR = obj.instance_eval("INST_EVAL_CONST_X") rescue nil + X_BY_BLOCK = obj.instance_eval { INST_EVAL_CONST_X } rescue nil + end + end +end diff --git a/spec/ruby/core/basicobject/fixtures/common.rb b/spec/ruby/core/basicobject/fixtures/common.rb new file mode 100644 index 0000000000..3447a3a5e7 --- /dev/null +++ b/spec/ruby/core/basicobject/fixtures/common.rb @@ -0,0 +1,9 @@ +module BasicObjectSpecs + class BOSubclass < BasicObject + def self.kernel_defined? + defined?(Kernel) + end + + include ::Kernel + end +end diff --git a/spec/ruby/core/basicobject/fixtures/remove_method_missing.rb b/spec/ruby/core/basicobject/fixtures/remove_method_missing.rb new file mode 100644 index 0000000000..095b982d3a --- /dev/null +++ b/spec/ruby/core/basicobject/fixtures/remove_method_missing.rb @@ -0,0 +1,9 @@ +class BasicObject + remove_method :method_missing +end + +begin + Object.new.test_method +rescue NoMethodError => e + puts e.class.name +end diff --git a/spec/ruby/core/basicobject/fixtures/singleton_method.rb b/spec/ruby/core/basicobject/fixtures/singleton_method.rb new file mode 100644 index 0000000000..0e00e035fa --- /dev/null +++ b/spec/ruby/core/basicobject/fixtures/singleton_method.rb @@ -0,0 +1,10 @@ +module BasicObjectSpecs + class SingletonMethod + def self.singleton_method_added name + ScratchPad.record [:singleton_method_added, name] + end + + def self.singleton_method_to_alias + end + end +end diff --git a/spec/ruby/core/basicobject/initialize_spec.rb b/spec/ruby/core/basicobject/initialize_spec.rb new file mode 100644 index 0000000000..7e6680df61 --- /dev/null +++ b/spec/ruby/core/basicobject/initialize_spec.rb @@ -0,0 +1,13 @@ +require File.expand_path('../../../spec_helper', __FILE__) + +describe "BasicObject#initialize" do + it "is a private instance method" do + BasicObject.should have_private_instance_method(:initialize) + end + + it "does not accept arguments" do + lambda { + BasicObject.new("This", "makes it easier", "to call super", "from other constructors") + }.should raise_error(ArgumentError) + end +end diff --git a/spec/ruby/core/basicobject/instance_eval_spec.rb b/spec/ruby/core/basicobject/instance_eval_spec.rb new file mode 100644 index 0000000000..3898e96b8b --- /dev/null +++ b/spec/ruby/core/basicobject/instance_eval_spec.rb @@ -0,0 +1,180 @@ +require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../fixtures/classes', __FILE__) + +describe "BasicObject#instance_eval" do + before :each do + ScratchPad.clear + end + + it "is a public instance method" do + BasicObject.should have_public_instance_method(:instance_eval) + end + + it "sets self to the receiver in the context of the passed block" do + a = BasicObject.new + a.instance_eval { self }.equal?(a).should be_true + end + + it "evaluates strings" do + a = BasicObject.new + a.instance_eval('self').equal?(a).should be_true + end + + it "expects a block with no arguments" do + lambda { "hola".instance_eval }.should raise_error(ArgumentError) + end + + it "takes no arguments with a block" do + lambda { "hola".instance_eval(4, 5) {|a,b| a + b } }.should raise_error(ArgumentError) + end + + it "yields the object to the block" do + "hola".instance_eval {|o| ScratchPad.record o } + ScratchPad.recorded.should == "hola" + end + + it "returns the result of the block" do + "hola".instance_eval { :result }.should == :result + end + + it "only binds the eval to the receiver" do + f = Object.new + f.instance_eval do + def foo + 1 + end + end + f.foo.should == 1 + lambda { Object.new.foo }.should raise_error(NoMethodError) + end + + it "preserves self in the original block when passed a block argument" do + prc = proc { self } + + old_self = prc.call + + new_self = Object.new + new_self.instance_eval(&prc).should == new_self + + prc.call.should == old_self + end + + # TODO: This should probably be replaced with a "should behave like" that uses + # the many scoping/binding specs from kernel/eval_spec, since most of those + # behaviors are the same for instance_eval. See also module_eval/class_eval. + + it "binds self to the receiver" do + s = "hola" + (s == s.instance_eval { self }).should be_true + o = mock('o') + (o == o.instance_eval("self")).should be_true + end + + it "executes in the context of the receiver" do + "Ruby-fu".instance_eval { size }.should == 7 + "hola".instance_eval("size").should == 4 + Object.class_eval { "hola".instance_eval("to_s") }.should == "hola" + Object.class_eval { "Ruby-fu".instance_eval{ to_s } }.should == "Ruby-fu" + + end + + it "has access to receiver's instance variables" do + BasicObjectSpecs::IVars.new.instance_eval { @secret }.should == 99 + BasicObjectSpecs::IVars.new.instance_eval("@secret").should == 99 + end + + it "treats block-local variables as local to the block" do + prc = instance_eval <<-CODE + proc do |x, prc| + if x + n = 2 + else + n = 1 + prc.call(true, prc) + n + end + end + CODE + + prc.call(false, prc).should == 1 + end + + it "sets class variables in the receiver" do + BasicObjectSpecs::InstEvalCVar.class_variables.should include(:@@count) + BasicObjectSpecs::InstEvalCVar.send(:class_variable_get, :@@count).should == 2 + end + + it "makes the receiver metaclass the scoped class when used with a string" do + obj = Object.new + obj.instance_eval %{ + class B; end + B + } + obj.singleton_class.const_get(:B).should be_an_instance_of(Class) + end + + it "gets constants in the receiver if a string given" do + BasicObjectSpecs::InstEvalOuter::Inner::X_BY_STR.should == 2 + end + + it "doesn't get constants in the receiver if a block given" do + BasicObjectSpecs::InstEvalOuter::Inner::X_BY_BLOCK.should be_nil + end + + it "raises a TypeError when defining methods on an immediate" do + lambda do + 1.instance_eval { def foo; end } + end.should raise_error(TypeError) + lambda do + :foo.instance_eval { def foo; end } + end.should raise_error(TypeError) + end + +quarantine! do # Not clean, leaves cvars lying around to break other specs + it "scopes class var accesses in the caller when called on a Fixnum" do + # Fixnum can take instance vars + Fixnum.class_eval "@@__tmp_instance_eval_spec = 1" + (defined? @@__tmp_instance_eval_spec).should be_nil + + @@__tmp_instance_eval_spec = 2 + 1.instance_eval { @@__tmp_instance_eval_spec }.should == 2 + Fixnum.__send__(:remove_class_variable, :@@__tmp_instance_eval_spec) + end +end + + it "raises a TypeError when defining methods on numerics" do + lambda do + (1.0).instance_eval { def foo; end } + end.should raise_error(TypeError) + lambda do + (1 << 64).instance_eval { def foo; end } + end.should raise_error(TypeError) + end + + it "evaluates procs originating from methods" do + def meth(arg); arg; end + + m = method(:meth) + obj = Object.new + + obj.instance_eval(&m).should == obj + end + + it "evaluates string with given filename and linenumber" do + err = begin + Object.new.instance_eval("raise", "a_file", 10) + rescue => e + e + end + err.backtrace.first.split(":")[0..1].should == ["a_file", "10"] + end + + it "evaluates string with given filename and negative linenumber" do + err = begin + Object.new.instance_eval("\n\nraise\n", "b_file", -100) + rescue => e + e + end + err.backtrace.first.split(":")[0..1].should == ["b_file", "-98"] + end +end diff --git a/spec/ruby/core/basicobject/instance_exec_spec.rb b/spec/ruby/core/basicobject/instance_exec_spec.rb new file mode 100644 index 0000000000..f41af6f64f --- /dev/null +++ b/spec/ruby/core/basicobject/instance_exec_spec.rb @@ -0,0 +1,107 @@ +require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../fixtures/classes', __FILE__) + +describe "BasicObject#instance_exec" do + it "is a public instance method" do + BasicObject.should have_public_instance_method(:instance_exec) + end + + it "sets self to the receiver in the context of the passed block" do + a = BasicObject.new + a.instance_exec { self }.equal?(a).should be_true + end + + it "passes arguments to the block" do + a = BasicObject.new + a.instance_exec(1) { |b| b }.should equal(1) + end + + it "raises a LocalJumpError unless given a block" do + lambda { "hola".instance_exec }.should raise_error(LocalJumpError) + end + + it "has an arity of -1" do + Object.new.method(:instance_exec).arity.should == -1 + end + + it "accepts arguments with a block" do + lambda { "hola".instance_exec(4, 5) { |a,b| a + b } }.should_not raise_error + end + + it "doesn't pass self to the block as an argument" do + "hola".instance_exec { |o| o }.should be_nil + end + + it "passes any arguments to the block" do + Object.new.instance_exec(1,2) {|one, two| one + two}.should == 3 + end + + it "only binds the exec to the receiver" do + f = Object.new + f.instance_exec do + def foo + 1 + end + end + f.foo.should == 1 + lambda { Object.new.foo }.should raise_error(NoMethodError) + end + + # TODO: This should probably be replaced with a "should behave like" that uses + # the many scoping/binding specs from kernel/eval_spec, since most of those + # behaviors are the same for instance_exec. See also module_eval/class_eval. + + it "binds self to the receiver" do + s = "hola" + (s == s.instance_exec { self }).should == true + end + + it "binds the block's binding self to the receiver" do + s = "hola" + (s == s.instance_exec { eval "self", binding }).should == true + end + + it "executes in the context of the receiver" do + "Ruby-fu".instance_exec { size }.should == 7 + Object.class_eval { "Ruby-fu".instance_exec{ to_s } }.should == "Ruby-fu" + end + + it "has access to receiver's instance variables" do + BasicObjectSpecs::IVars.new.instance_exec { @secret }.should == 99 + end + + it "sets class variables in the receiver" do + BasicObjectSpecs::InstExec.class_variables.should include(:@@count) + BasicObjectSpecs::InstExec.send(:class_variable_get, :@@count).should == 2 + end + + it "raises a TypeError when defining methods on an immediate" do + lambda do + 1.instance_exec { def foo; end } + end.should raise_error(TypeError) + lambda do + :foo.instance_exec { def foo; end } + end.should raise_error(TypeError) + end + +quarantine! do # Not clean, leaves cvars lying around to break other specs + it "scopes class var accesses in the caller when called on a Fixnum" do + # Fixnum can take instance vars + Fixnum.class_eval "@@__tmp_instance_exec_spec = 1" + (defined? @@__tmp_instance_exec_spec).should == nil + + @@__tmp_instance_exec_spec = 2 + 1.instance_exec { @@__tmp_instance_exec_spec }.should == 2 + Fixnum.__send__(:remove_class_variable, :@@__tmp_instance_exec_spec) + end +end + + it "raises a TypeError when defining methods on numerics" do + lambda do + (1.0).instance_exec { def foo; end } + end.should raise_error(TypeError) + lambda do + (1 << 64).instance_exec { def foo; end } + end.should raise_error(TypeError) + end +end diff --git a/spec/ruby/core/basicobject/method_missing_spec.rb b/spec/ruby/core/basicobject/method_missing_spec.rb new file mode 100644 index 0000000000..eea45a8ddc --- /dev/null +++ b/spec/ruby/core/basicobject/method_missing_spec.rb @@ -0,0 +1,39 @@ +require File.expand_path('../../../shared/basicobject/method_missing', __FILE__) + +describe "BasicObject#method_missing" do + it "is a private method" do + BasicObject.should have_private_instance_method(:method_missing) + end +end + +describe "BasicObject#method_missing" do + it_behaves_like :method_missing_class, nil, BasicObject +end + +describe "BasicObject#method_missing" do + it_behaves_like :method_missing_instance, nil, BasicObject +end + +describe "BasicObject#method_missing" do + it_behaves_like :method_missing_defined_module, nil, KernelSpecs::ModuleMM +end + +describe "BasicObject#method_missing" do + it_behaves_like :method_missing_module, nil, KernelSpecs::ModuleNoMM +end + +describe "BasicObject#method_missing" do + it_behaves_like :method_missing_defined_class, nil, KernelSpecs::ClassMM +end + +describe "BasicObject#method_missing" do + it_behaves_like :method_missing_class, nil, KernelSpecs::ClassNoMM +end + +describe "BasicObject#method_missing" do + it_behaves_like :method_missing_defined_instance, nil, KernelSpecs::ClassMM +end + +describe "BasicObject#method_missing" do + it_behaves_like :method_missing_instance, nil, KernelSpecs::ClassNoMM +end diff --git a/spec/ruby/core/basicobject/not_equal_spec.rb b/spec/ruby/core/basicobject/not_equal_spec.rb new file mode 100644 index 0000000000..9177380154 --- /dev/null +++ b/spec/ruby/core/basicobject/not_equal_spec.rb @@ -0,0 +1,53 @@ +require File.expand_path('../../../spec_helper', __FILE__) + +describe "BasicObject#!=" do + it "is a public instance method" do + BasicObject.should have_public_instance_method(:'!=') + end + + it "returns true if other is not identical to self" do + a = BasicObject.new + b = BasicObject.new + (a != b).should be_true + end + + it "returns true if other is an Object" do + a = BasicObject.new + b = Object.new + (a != b).should be_true + end + + it "returns false if other is identical to self" do + a = BasicObject.new + (a != a).should be_false + end + + it "dispatches to #==" do + a = mock("not_equal") + b = BasicObject.new + a.should_receive(:==).and_return(true) + + (a != b).should be_false + end + + describe "when invoked using Kernel#send" do + it "returns true if other is not identical to self" do + a = Object.new + b = Object.new + a.send(:!=, b).should be_true + end + + it "returns false if other is identical to self" do + a = Object.new + a.send(:!=, a).should be_false + end + + it "dispatches to #==" do + a = mock("not_equal") + b = Object.new + a.should_receive(:==).and_return(true) + + a.send(:!=, b).should be_false + end + end +end diff --git a/spec/ruby/core/basicobject/not_spec.rb b/spec/ruby/core/basicobject/not_spec.rb new file mode 100644 index 0000000000..f02b31edb2 --- /dev/null +++ b/spec/ruby/core/basicobject/not_spec.rb @@ -0,0 +1,11 @@ +require File.expand_path('../../../spec_helper', __FILE__) + +describe "BasicObject#!" do + it "is a public instance method" do + BasicObject.should have_public_instance_method(:'!') + end + + it "returns false" do + (!BasicObject.new).should be_false + end +end diff --git a/spec/ruby/core/basicobject/singleton_method_added_spec.rb b/spec/ruby/core/basicobject/singleton_method_added_spec.rb new file mode 100644 index 0000000000..7622798dee --- /dev/null +++ b/spec/ruby/core/basicobject/singleton_method_added_spec.rb @@ -0,0 +1,86 @@ +require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../fixtures/singleton_method', __FILE__) + +describe "BasicObject#singleton_method_added" do + before :each do + ScratchPad.clear + end + + it "is a private method" do + BasicObject.should have_private_instance_method(:singleton_method_added) + end + + it "is called when a singleton method is defined on an object" do + obj = BasicObject.new + + def obj.singleton_method_added(name) + ScratchPad.record [:singleton_method_added, name] + end + + def obj.new_singleton_method + end + + ScratchPad.recorded.should == [:singleton_method_added, :new_singleton_method] + end + + it "is not called for instance methods" do + ScratchPad.record [] + + Module.new do + def self.singleton_method_added(name) + ScratchPad << name + end + + def new_instance_method + end + end + + ScratchPad.recorded.should_not include(:new_instance_method) + end + + it "is called when a singleton method is defined on a module" do + class BasicObjectSpecs::SingletonMethod + def self.new_method_on_self + end + end + ScratchPad.recorded.should == [:singleton_method_added, :new_method_on_self] + end + + it "is called when a method is defined in the singleton class" do + class BasicObjectSpecs::SingletonMethod + class << self + def new_method_on_singleton + end + end + end + ScratchPad.recorded.should == [:singleton_method_added, :new_method_on_singleton] + end + + it "is called when a method is defined with alias_method in the singleton class" do + class BasicObjectSpecs::SingletonMethod + class << self + alias_method :new_method_on_singleton_with_alias_method, :singleton_method_to_alias + end + end + ScratchPad.recorded.should == [:singleton_method_added, :new_method_on_singleton_with_alias_method] + end + + it "is called when a method is defined with syntax alias in the singleton class" do + class BasicObjectSpecs::SingletonMethod + class << self + alias new_method_on_singleton_with_syntax_alias singleton_method_to_alias + end + end + ScratchPad.recorded.should == [:singleton_method_added, :new_method_on_singleton_with_syntax_alias] + end + + it "is called when define_method is used in the singleton class" do + class BasicObjectSpecs::SingletonMethod + class << self + define_method :new_method_with_define_method do + end + end + end + ScratchPad.recorded.should == [:singleton_method_added, :new_method_with_define_method] + end +end diff --git a/spec/ruby/core/basicobject/singleton_method_removed_spec.rb b/spec/ruby/core/basicobject/singleton_method_removed_spec.rb new file mode 100644 index 0000000000..406f4a888e --- /dev/null +++ b/spec/ruby/core/basicobject/singleton_method_removed_spec.rb @@ -0,0 +1,24 @@ +require File.expand_path('../../../spec_helper', __FILE__) + +describe "BasicObject#singleton_method_removed" do + before :each do + ScratchPad.clear + end + + it "is a private method" do + BasicObject.should have_private_instance_method(:singleton_method_removed) + end + + it "is called when a method is removed on self" do + klass = Class.new + def klass.singleton_method_removed(name) + ScratchPad.record [:singleton_method_removed, name] + end + def klass.singleton_method_to_remove + end + class << klass + remove_method :singleton_method_to_remove + end + ScratchPad.recorded.should == [:singleton_method_removed, :singleton_method_to_remove] + end +end diff --git a/spec/ruby/core/basicobject/singleton_method_undefined_spec.rb b/spec/ruby/core/basicobject/singleton_method_undefined_spec.rb new file mode 100644 index 0000000000..4f33cc5dbe --- /dev/null +++ b/spec/ruby/core/basicobject/singleton_method_undefined_spec.rb @@ -0,0 +1,24 @@ +require File.expand_path('../../../spec_helper', __FILE__) + +describe "BasicObject#singleton_method_undefined" do + before :each do + ScratchPad.clear + end + + it "is a private method" do + BasicObject.should have_private_instance_method(:singleton_method_undefined) + end + + it "is called when a method is removed on self" do + klass = Class.new + def klass.singleton_method_undefined(name) + ScratchPad.record [:singleton_method_undefined, name] + end + def klass.singleton_method_to_undefine + end + class << klass + undef_method :singleton_method_to_undefine + end + ScratchPad.recorded.should == [:singleton_method_undefined, :singleton_method_to_undefine] + end +end |