Skip to content
Browse files

extend ActiveSupport::Deprecation with self, allow other objects to e…

…xtend/include it also.

test local deprecation

deprecator object

Test ActiveSupport::Deprecation when included
  • Loading branch information...
1 parent c4b8572 commit 2c690a0f5b36896da9b003d4e24159a27ebd7f71 @paneq paneq committed with LTe Jul 25, 2011
View
2 activesupport/lib/active_support/deprecation.rb
@@ -16,4 +16,4 @@ class << self
self.silenced = false
self.debug = false
end
-end
+end
View
64 activesupport/lib/active_support/deprecation/behaviors.rb
@@ -2,46 +2,44 @@
module ActiveSupport
module Deprecation
- class << self
- # Whether to print a backtrace along with the warning.
- attr_accessor :debug
+ # Whether to print a backtrace along with the warning.
+ attr_accessor :debug
- # Returns the current behavior or if one isn't set, defaults to +:stderr+
- def behavior
- @behavior ||= [DEFAULT_BEHAVIORS[:stderr]]
- end
+ # Returns the current behavior or if one isn't set, defaults to +:stderr+
+ def behavior
+ @behavior ||= [DEFAULT_BEHAVIORS[:stderr]]
+ end
- # Sets the behavior to the specified value. Can be a single value, array, or
- # an object that responds to +call+.
- #
- # Available behaviors:
- #
- # [+stderr+] Log all deprecation warnings to <tt>$stderr</tt>.
- # [+log+] Log all deprecation warnings to +Rails.logger+.
- # [+notify+] Use <tt>ActiveSupport::Notifications</tt> to notify +deprecation.rails+.
- # [+silence+] Do nothing.
- #
- # Setting behaviors only affects deprecations that happen after boot time.
- # Deprecation warnings raised by gems are not affected by this setting because
- # they happen before Rails boots up.
- #
- # ActiveSupport::Deprecation.behavior = :stderr
- # ActiveSupport::Deprecation.behavior = [:stderr, :log]
- # ActiveSupport::Deprecation.behavior = MyCustomHandler
- # ActiveSupport::Deprecation.behavior = proc { |message, callstack|
- # # custom stuff
- # }
- def behavior=(behavior)
- @behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || b }
- end
+ # Sets the behavior to the specified value. Can be a single value, array, or
+ # an object that responds to +call+.
+ #
+ # Available behaviors:
+ #
+ # [+stderr+] Log all deprecation warnings to +$stderr+.
+ # [+log+] Log all deprecation warnings to +Rails.logger+.
+ # [+notify] Use +ActiveSupport::Notifications+ to notify +deprecation.rails+.
+ # [+silence+] Do nothing.
+ #
+ # Setting behaviors only affects deprecations that happen after boot time.
+ # Deprecation warnings raised by gems are not affected by this setting because
+ # they happen before Rails boots up.
+ #
+ # ActiveSupport::Deprecation.behavior = :stderr
+ # ActiveSupport::Deprecation.behavior = [:stderr, :log]
+ # ActiveSupport::Deprecation.behavior = MyCustomHandler
+ # ActiveSupport::Deprecation.behavior = proc { |message, callstack|
+ # # custom stuff
+ # }
+ def behavior=(behavior)
+ @behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || b }
end
# Default warning behaviors per Rails.env.
DEFAULT_BEHAVIORS = {
:stderr => Proc.new { |message, callstack|
- $stderr.puts(message)
- $stderr.puts callstack.join("\n ") if debug
- },
+ $stderr.puts(message)
+ $stderr.puts callstack.join("\n ") if debug
+ },
:log => Proc.new { |message, callstack|
logger =
if defined?(Rails) && Rails.logger
View
5 activesupport/lib/active_support/deprecation/method_wrappers.rb
@@ -32,8 +32,9 @@ def self.deprecate_methods(target_module, *method_names)
target_module.alias_method_chain(method_name, :deprecation) do |target, punctuation|
target_module.module_eval(<<-end_eval, __FILE__, __LINE__ + 1)
def #{target}_with_deprecation#{punctuation}(*args, &block)
- ::ActiveSupport::Deprecation.warn(
- ::ActiveSupport::Deprecation.deprecated_method_warning(
+ deprecator = respond_to?(:deprecator) ? deprecator() : ActiveSupport::Deprecation
+ deprecator.warn(
+ deprecator.deprecated_method_warning(
:#{method_name},
#{options[method_name].inspect}),
caller
View
19 activesupport/lib/active_support/deprecation/proxy_wrappers.rb
@@ -26,9 +26,10 @@ def method_missing(called, *args, &block)
end
class DeprecatedObjectProxy < DeprecationProxy #:nodoc:
- def initialize(object, message)
+ def initialize(object, message, deprecator = ActiveSupport::Deprecation)
@object = object
@message = message
+ @deprecator = deprecator
end
private
@@ -37,15 +38,18 @@ def target
end
def warn(callstack, called, args)
- ActiveSupport::Deprecation.warn(@message, callstack)
+ @deprecator.warn(@message, callstack)
end
end
# Stand-in for <tt>@request</tt>, <tt>@attributes</tt>, <tt>@params</tt>, etc.
# which emits deprecation warnings on any method call (except +inspect+).
class DeprecatedInstanceVariableProxy < DeprecationProxy #:nodoc:
- def initialize(instance, method, var = "@#{method}")
- @instance, @method, @var = instance, method, var
+ def initialize(instance, method, var = :"@#{method}", deprecator = nil)
+ @instance = instance
+ @method = method
+ @var = var
+ @deprecator = deprecator || (@instance.respond_to?(:deprecator) ? @instance.deprecator : ActiveSupport::Deprecation)
end
private
@@ -54,14 +58,15 @@ def target
end
def warn(callstack, called, args)
- ActiveSupport::Deprecation.warn("#{@var} is deprecated! Call #{@method}.#{called} instead of #{@var}.#{called}. Args: #{args.inspect}", callstack)
+ @deprecator.warn("#{@var} is deprecated! Call #{@method}.#{called} instead of #{@var}.#{called}. Args: #{args.inspect}", callstack)
end
end
class DeprecatedConstantProxy < DeprecationProxy #:nodoc:all
- def initialize(old_const, new_const)
+ def initialize(old_const, new_const, deprecator = ActiveSupport::Deprecation)
@old_const = old_const
@new_const = new_const
+ @deprecator = deprecator
end
def class
@@ -74,7 +79,7 @@ def target
end
def warn(callstack, called, args)
- ActiveSupport::Deprecation.warn("#{@old_const} is deprecated! Use #{@new_const} instead.", callstack)
+ @deprecator.warn("#{@old_const} is deprecated! Use #{@new_const} instead.", callstack)
end
end
end
View
117 activesupport/lib/active_support/deprecation/reporting.rb
@@ -1,74 +1,73 @@
module ActiveSupport
module Deprecation
- class << self
- attr_accessor :silenced
+ attr_accessor :silenced
- # Outputs a deprecation warning to the output configured by
- # <tt>ActiveSupport::Deprecation.behavior</tt>.
- #
- # ActiveSupport::Deprecation.warn("something broke!")
- # # => "DEPRECATION WARNING: something broke! (called from your_code.rb:1)"
- def warn(message = nil, callstack = caller)
- return if silenced
- deprecation_message(callstack, message).tap do |m|
- behavior.each { |b| b.call(m, callstack) }
- end
+ # Outputs a deprecation warning to the output configured by
+ # <tt>ActiveSupport::Deprecation.behavior</tt>.
+ #
+ # ActiveSupport::Deprecation.warn("something broke!")
+ # # => "DEPRECATION WARNING: something broke! (called from your_code.rb:1)"
+ def warn(message = nil, callstack = caller)
+ return if silenced
+ deprecation_message(callstack, message).tap do |m|
+ behavior.each { |b| b.call(m, callstack) }
end
+ end
- # Silence deprecation warnings within the block.
- #
- # ActiveSupport::Deprecation.warn("something broke!")
- # # => "DEPRECATION WARNING: something broke! (called from your_code.rb:1)"
- #
- # ActiveSupport::Deprecation.silence do
- # ActiveSupport::Deprecation.warn("something broke!")
- # end
- # # => nil
- def silence
- old_silenced, @silenced = @silenced, true
- yield
- ensure
- @silenced = old_silenced
- end
+ # Silence deprecation warnings within the block.
+ #
+ # ActiveSupport::Deprecation.warn("something broke!")
+ # # => "DEPRECATION WARNING: something broke! (called from your_code.rb:1)"
+ #
+ # ActiveSupport::Deprecation.silence do
+ # ActiveSupport::Deprecation.warn("something broke!")
+ # end
+ # # => nil
+ def silence
+ old_silenced, @silenced = @silenced, true
+ yield
+ ensure
+ @silenced = old_silenced
+ end
- def deprecated_method_warning(method_name, message = nil)
- warning = "#{method_name} is deprecated and will be removed from Rails #{deprecation_horizon}"
- case message
- when Symbol then "#{warning} (use #{message} instead)"
- when String then "#{warning} (#{message})"
- else warning
- end
+ def deprecated_method_warning(method_name, message = nil)
+ warning = "#{method_name} is deprecated and will be removed from Rails #{deprecation_horizon}"
+ case message
+ when Symbol then warning << " (use #{message} instead)"
+ when String then warning << " (#{message})"
end
+ warning
+ end
- private
- def deprecation_message(callstack, message = nil)
- message ||= "You are using deprecated behavior which will be removed from the next major or minor release."
- message += '.' unless message =~ /\.$/
- "DEPRECATION WARNING: #{message} #{deprecation_caller_message(callstack)}"
- end
+ private
+
+ def deprecation_message(callstack, message = nil)
+ message ||= "You are using deprecated behavior which will be removed from the next major or minor release."
+ message += '.' unless message =~ /\.$/
+ "DEPRECATION WARNING: #{message} #{deprecation_caller_message(callstack)}"
+ end
- def deprecation_caller_message(callstack)
- file, line, method = extract_callstack(callstack)
- if file
- if line && method
- "(called from #{method} at #{file}:#{line})"
- else
- "(called from #{file}:#{line})"
- end
- end
+ def deprecation_caller_message(callstack)
+ file, line, method = extract_callstack(callstack)
+ if file
+ if line && method
+ "(called from #{method} at #{file}:#{line})"
+ else
+ "(called from #{file}:#{line})"
end
+ end
+ end
- def extract_callstack(callstack)
- rails_gem_root = File.expand_path("../../../../..", __FILE__) + "/"
- offending_line = callstack.find { |line| !line.start_with?(rails_gem_root) } || callstack.first
- if offending_line
- if md = offending_line.match(/^(.+?):(\d+)(?::in `(.*?)')?/)
- md.captures
- else
- offending_line
- end
- end
+ def extract_callstack(callstack)
+ rails_gem_root = File.expand_path("../../../../..", __FILE__) + "/"
+ offending_line = callstack.find { |line| !line.start_with?(rails_gem_root) } || callstack.first
+ if offending_line
+ if md = offending_line.match(/^(.+?):(\d+)(?::in `(.*?)')?/)
+ md.captures
+ else
+ offending_line
end
+ end
end
end
end
View
127 activesupport/test/deprecation_test.rb
@@ -186,4 +186,131 @@ def test_deprecation_with_alternate_method
def test_deprecation_with_explicit_message
assert_deprecated(/you now need to do something extra for this one/) { @dtc.d }
end
+
+ def test_deprecation_in_other_module_does_not_interfere
+ messages = []
+
+ m = Module.new
+ m.extend ActiveSupport::Deprecation
+ m.behavior = Proc.new{|message, callstack| messages << message}
+ assert_not_deprecated do # not globally
+ assert_difference("messages.size") do # but locally
+ m.warn("warning")
+ end
+ end
+ end
+
+ def test_deprecated_method_with_deprecator_implemented
+ deprecator = deprecator_with_messages
+ def deprecator.deprecated_method_warning(method, *params)
+ "deprecator.deprecated_method_warning.#{method}"
+ end
+
+ deprecatee = Class.new() do
+ def method
+ end
+ deprecate :method
+ define_method(:deprecator){ deprecator }
+ end
+
+ deprecatee.new.method
+ assert deprecator.messages.first.match("DEPRECATION WARNING: deprecator.deprecated_method_warning.method")
+ end
+
+ def test_deprecated_constant_with_deprecator_given
+ deprecator = deprecator_with_messages
+ klass = Class.new()
+ klass.const_set(:OLD, ActiveSupport::Deprecation::DeprecatedConstantProxy.new('klass::OLD', 'Object', deprecator) )
+ assert_difference("deprecator.messages.size") do
+ klass::OLD.to_s
+ end
+ end
+
+ def test_deprecated_instance_variable_with_instance_deprecator
+ deprecator = deprecator_with_messages
+
+ klass = Class.new() do
+ def initialize
+ @request = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(self, :request)
+ @_request = :a_request
+ end
+ def request; @_request end
+ def old_request; @request end
+ define_method(:deprecator) { deprecator }
+ end
+
+ assert_difference("deprecator.messages.size") { klass.new.old_request.to_s }
+
+ end
+
+ def test_deprecated_instance_variable_with_given_deprecator
+ deprecator = deprecator_with_messages
+
+ klass = Class.new() do
+ define_method(:initialize) do
+ @request = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(self, :request, :@request, deprecator)
+ @_request = :a_request
+ end
+ def request; @_request end
+ def old_request; @request end
+ end
+
+ assert_difference("deprecator.messages.size") { klass.new.old_request.to_s }
+ end
+
+ def test_included_deprecation_module
+ klass = Class.new() do
+ attr_reader :last_message
+ include ActiveSupport::Deprecation
+ def deprecated_method
+ warn(deprecated_method_warning(:deprecated_method, "You are calling deprecated method"))
+ end
+
+ private
+
+ def deprecated_method_warning(method_name, message = nil)
+ message || "#{method_name} is deprecated and will be removed from This Library"
+ end
+
+ def behavior
+ @behavior ||= [Proc.new { |message| @last_message = message }]
+ end
+ end
+
+ object = klass.new
+ object.deprecated_method
+ assert_match(/You are calling deprecated method/, object.last_message)
+ end
+
+ unless defined?(::MiniTest)
+ def test_assertion_failed_error_doesnt_spout_deprecation_warnings
+ error_class = Class.new(StandardError) do
+ def message
+ ActiveSupport::Deprecation.warn 'warning in error message'
+ super
+ end
+ end
+
+ raise error_class.new('hmm')
+
+ rescue => e
+ error = Test::Unit::Error.new('testing ur doodz', e)
+ assert_not_deprecated { error.message }
+ assert_nil @last_message
+ end
+ end
+
+
+ private
+
+
+ def deprecator_with_messages
+ deprecator = Object.new
+ deprecator.extend(ActiveSupport::Deprecation)
+ deprecator.behavior = Proc.new{|message, callstack| deprecator.messages << message}
+ def deprecator.messages
+ @messages ||= []
+ end
+ deprecator
+ end
end

0 comments on commit 2c690a0

Please sign in to comment.
Something went wrong with that request. Please try again.