提交 7d017781 编写于 作者: J Jeremy Kemper

Deprecation: easier to work with warning behavior as procs; default behaviors...

Deprecation: easier to work with warning behavior as procs; default behaviors for each environment so users needn't update env.rb; and testing pleasure with assert_deprecated, assert_not_deprecated. Test prints to , dev logs, production ignores.

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4647 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
上级 4f017bb1
*SVN*
* Deprecation: easier to work with warning behavior as procs; default behaviors for each environment so users needn't update env.rb; and testing pleasure with assert_deprecated, assert_not_deprecated. [Jeremy Kemper]
By default, test prints to $stderr, dev logs, production ignores.
Provide your own per-environment in e.g. config/environments/development.rb:
ActiveSupport::Deprecation.behavior = Proc.new { |message| raise message }
* First cut of the Rails Deprecation system. [Koz]
* Strip boolean XML content before checking for 'true' [Rick Olson]
......
module ActiveSupport
module Deprecation
@@warning_method = :print
mattr_accessor :warning_method
# Choose the default warn behavior according to RAILS_ENV.
# Ignore deprecation warnings in production.
DEFAULT_BEHAVIORS = {
'test' => Proc.new { |message| $stderr.puts message },
'development' => Proc.new { |message| RAILS_DEFAULT_LOGGER.warn message },
}
class << self
def warn(message = nil, callstack = caller)
behavior.call(deprecation_message(callstack, message)) if behavior
end
def print_warning(lines)
lines.each {|l| $stderr.write("#{l}\n")}
def default_behavior
DEFAULT_BEHAVIORS[RAILS_ENV.to_s] if defined?(RAILS_ENV)
end
def log_warning(lines)
if Object.const_defined?("RAILS_DEFAULT_LOGGER")
lines.each {|l| RAILS_DEFAULT_LOGGER.warn l}
else
print_warning(lines)
private
def deprecation_message(callstack, message = nil)
file, line, method = extract_callstack(callstack)
message ||= "WARNING: #{method} is deprecated and will be removed from the next Rails release"
"#{message} (#{method} at #{file}:#{line})"
end
def extract_callstack(callstack)
callstack.first.match(/^(.+?):(\d+)(?::in `(.*?)')?/).captures
end
end
def issue_warning(line)
lines =
["@@@@@@@@@@ Deprecation Warning @@@@@@@@@@", line,
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"]
self.send("#{@@warning_method}_warning", lines)
end
def instance_method_warning(clazz, method)
issue_warning("Your application calls #{clazz}##{method}, which is now deprecated. Please see the API documents at http://api.rubyonrails.org/ for more information.")
end
end
# Behavior is a block that takes a message argument.
mattr_accessor :behavior
self.behavior = default_behavior
module ClassMethods
def deprecate(method_name)
alias_method "#{method_name}_before_deprecation", method_name
class_eval(<<-EOS, __FILE__, __LINE__)
def #{method_name}(*args)
::ActiveSupport::Deprecation.instance_method_warning(self.class, :#{method_name})
#{method_name}_before_deprecation *args
# Declare that a method has been deprecated.
def deprecate(*method_names)
method_names.each do |method_name|
class_eval(<<-EOS, __FILE__, __LINE__)
def #{method_name}_with_deprecation(*args, &block)
::ActiveSupport::Deprecation.warn
#{method_name}_without_deprecation(*args, &block)
end
EOS
alias_method_chain(method_name, :deprecation)
end
EOS
end
end
module Assertions
def assert_deprecated(regexp = nil, &block)
last = with_last_message_tracking_deprecation_behavior(&block)
assert last, "Expected a deprecation warning within the block but received none"
if regexp
assert_match regexp, last, "Deprecation warning didn't match #{regexp}: #{last}"
end
end
def assert_not_deprecated(&block)
last = with_last_message_tracking_deprecation_behavior(&block)
assert_nil last, "Expected no deprecation warning within the block but received one: #{last}"
end
private
def with_last_message_tracking_deprecation_behavior
old_behavior = ActiveSupport::Deprecation.behavior
last_message = nil
ActiveSupport::Deprecation.behavior = Proc.new { |message| last_message = message; old_behavior.call(message) if old_behavior }
yield
last_message
ensure
ActiveSupport::Deprecation.behavior = old_behavior
end
end
end
end
Object.extend(ActiveSupport::Deprecation::ClassMethods)
class Class
include ActiveSupport::Deprecation::ClassMethods
end
module Test
module Unit
class TestCase
include ActiveSupport::Deprecation::Assertions
end
end
end
require 'test/unit'
require File.dirname(__FILE__) + '/../lib/active_support/deprecation'
require File.dirname(__FILE__) + '/abstract_unit'
# Stub out the warnings to allow assertions
module ActiveSupport
module Deprecation
class << self
def issue_warning(message)
@@warning = message
end
def last_warning
@@warning
end
end
class Deprecatee
def partially(foo = nil)
ActiveSupport::Deprecation.warn 'calling with foo=nil is out' if foo.nil?
end
end
class DeprecationTestingClass
def partiallly_deprecated(foo = nil)
if foo.nil?
ActiveSupport::Deprecation.issue_warning("calling partially_deprecated with foo=nil is now deprecated")
end
end
def not_deprecated
2
end
def deprecated_no_args
1
end
deprecate :deprecated_no_args
def deprecated_one_arg(a)
a
end
deprecate :deprecated_one_arg
def deprecated_multiple_args(a,b,c)
[a,b,c]
end
deprecate :deprecated_multiple_args
def not() 2 end
def none() 1 end
def one(a) a end
def multi(a,b,c) [a,b,c] end
deprecate :none, :one, :multi
end
class DeprecationTest < Test::Unit::TestCase
def setup
@dtc = DeprecationTestingClass.new
ActiveSupport::Deprecation.issue_warning(nil) # reset
end
def test_partial_deprecation
@dtc.partiallly_deprecated
assert_warning_matches /foo=nil/
end
def test_raises_nothing
assert_equal 2, @dtc.not_deprecated
# Track the last warning.
@old_behavior = ActiveSupport::Deprecation.behavior
@last_message = nil
ActiveSupport::Deprecation.behavior = Proc.new { |message| @last_message = message }
@dtc = Deprecatee.new
end
def test_deprecating_class_method
assert_equal 1, @dtc.deprecated_no_args
assert_deprecation_warning
assert_warning_matches /DeprecationTestingClass#deprecated_no_args/
def teardown
ActiveSupport::Deprecation.behavior = @old_behavior
end
def test_deprecating_class_method_with_argument
assert_equal 1, @dtc.deprecated_one_arg(1)
def test_inline_deprecation_warning
assert_deprecated(/foo=nil/) do
@dtc.partially
end
end
def test_deprecating_class_method_with_argument
assert_equal [1,2,3], @dtc.deprecated_multiple_args(1,2,3)
def test_undeprecated
assert_not_deprecated do
assert_equal 2, @dtc.not
end
end
private
def assert_warning_matches(rx)
assert ActiveSupport::Deprecation.last_warning =~ rx, "The deprecation warning did not match #{rx}"
def test_deprecate_class_method
assert_deprecated(/none is deprecated/) do
assert_equal 1, @dtc.none
end
assert_deprecated(/one is deprecated/) do
assert_equal 1, @dtc.one(1)
end
assert_deprecated(/multi is deprecated/) do
assert_equal [1,2,3], @dtc.multi(1,2,3)
end
end
def assert_deprecation_warning
assert_not_nil ActiveSupport::Deprecation.last_warning, "No Deprecation warnings were issued"
def test_nil_behavior_is_ignored
ActiveSupport::Deprecation.behavior = nil
assert_deprecated(/foo=nil/) { @dtc.partially }
end
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册