mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Ruby 1.9.2: disallow explicit coercion via method_missing. Only give friendly nil errors for Array and Active Record methods.
This commit is contained in:
parent
0214d337b3
commit
9acc824d96
4 changed files with 35 additions and 19 deletions
|
@ -1,7 +1,9 @@
|
|||
class NameError
|
||||
# Extract the name of the missing constant from the exception message.
|
||||
def missing_name
|
||||
$1 if /((::)?([A-Z]\w*)(::[A-Z]\w*)*)$/ =~ message
|
||||
if /undefined local variable or method/ !~ message
|
||||
$1 if /((::)?([A-Z]\w*)(::[A-Z]\w*)*)$/ =~ message
|
||||
end
|
||||
end
|
||||
|
||||
# Was this exception raised because the given name was missing?
|
||||
|
|
|
@ -43,7 +43,14 @@ class NilClass
|
|||
|
||||
private
|
||||
def method_missing(method, *args, &block)
|
||||
raise_nil_warning_for METHOD_CLASS_MAP[method], method, caller
|
||||
# Ruby 1.9.2: disallow explicit coercion via method_missing.
|
||||
if method == :to_ary || method == :to_str
|
||||
super
|
||||
elsif klass = METHOD_CLASS_MAP[method]
|
||||
raise_nil_warning_for klass, method, caller
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
# Raises a NoMethodError when you attempt to call a method on +nil+.
|
||||
|
@ -55,4 +62,3 @@ class NilClass
|
|||
raise NoMethodError, message, with_caller || caller
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -3,23 +3,19 @@ require 'active_support/core_ext/name_error'
|
|||
|
||||
class NameErrorTest < Test::Unit::TestCase
|
||||
def test_name_error_should_set_missing_name
|
||||
begin
|
||||
SomeNameThatNobodyWillUse____Really ? 1 : 0
|
||||
flunk "?!?!"
|
||||
rescue NameError => exc
|
||||
assert_equal "NameErrorTest::SomeNameThatNobodyWillUse____Really", exc.missing_name
|
||||
assert exc.missing_name?(:SomeNameThatNobodyWillUse____Really)
|
||||
assert exc.missing_name?("NameErrorTest::SomeNameThatNobodyWillUse____Really")
|
||||
end
|
||||
SomeNameThatNobodyWillUse____Really ? 1 : 0
|
||||
flunk "?!?!"
|
||||
rescue NameError => exc
|
||||
assert_equal "NameErrorTest::SomeNameThatNobodyWillUse____Really", exc.missing_name
|
||||
assert exc.missing_name?(:SomeNameThatNobodyWillUse____Really)
|
||||
assert exc.missing_name?("NameErrorTest::SomeNameThatNobodyWillUse____Really")
|
||||
end
|
||||
|
||||
def test_missing_method_should_ignore_missing_name
|
||||
begin
|
||||
some_method_that_does_not_exist
|
||||
flunk "?!?!"
|
||||
rescue NameError => exc
|
||||
assert_equal nil, exc.missing_name
|
||||
assert ! exc.missing_name?(:Foo)
|
||||
end
|
||||
some_method_that_does_not_exist
|
||||
flunk "?!?!"
|
||||
rescue NameError => exc
|
||||
assert !exc.missing_name?(:Foo)
|
||||
assert_nil exc.missing_name
|
||||
end
|
||||
end
|
||||
|
|
|
@ -13,7 +13,7 @@ class WhinyNilTest < Test::Unit::TestCase
|
|||
def test_unchanged
|
||||
nil.method_thats_not_in_whiners
|
||||
rescue NoMethodError => nme
|
||||
assert_match(/nil.method_thats_not_in_whiners/, nme.message)
|
||||
assert(nme.message =~ /nil:NilClass/)
|
||||
end
|
||||
|
||||
def test_active_record
|
||||
|
@ -35,4 +35,16 @@ class WhinyNilTest < Test::Unit::TestCase
|
|||
rescue RuntimeError => nme
|
||||
assert(!(nme.message =~ /nil:NilClass/))
|
||||
end
|
||||
|
||||
def test_no_to_ary_coercion
|
||||
nil.to_ary
|
||||
rescue NoMethodError => nme
|
||||
assert(nme.message =~ /nil:NilClass/)
|
||||
end
|
||||
|
||||
def test_no_to_str_coercion
|
||||
nil.to_str
|
||||
rescue NoMethodError => nme
|
||||
assert(nme.message =~ /nil:NilClass/)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue