aboutsummaryrefslogblamecommitdiffstats
path: root/activesupport/lib/active_support/deprecation.rb
blob: d7acdc2bd8a3ee20f9d73db754c95150f478233d (plain) (tree)
1
2
3
4
5
6
7
8
9

                    






                                                                                
                 


                                                                          
 

                                                                
         









                                                                                                        
           
       




                                                        
                       









                                                               
           

         

                     
                                                

                                                                                        

                                                                                      

















                                                                                                                                         






                                                                    











                                                                                                                       


     










                                                    
module ActiveSupport
  module Deprecation
    # 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 default_behavior
        DEFAULT_BEHAVIORS[RAILS_ENV.to_s] if defined?(RAILS_ENV)
      end

      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

    # Behavior is a block that takes a message argument.
    mattr_accessor :behavior
    self.behavior = default_behavior

    module ClassMethods
      # 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
      end
    end

    module Assertions
      def assert_deprecated(match = nil, &block)
        last = with_last_message_tracking_deprecation_behavior(&block)
        assert last, "Expected a deprecation warning within the block but received none"
        match = Regexp.new(match) unless match.is_a?(Regexp)
        assert_match match, last, "Deprecation warning didn't match #{match}: #{last}"
      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

    # Stand-in for @request, @attributes, etc.
    class DeprecatedInstanceVariableProxy
      instance_methods.each { |m| undef_method m unless m =~ /^__/ }

      def initialize(instance, method, var = "@#{method}")
        @instance, @method, @var = instance, method, var
      end

      private
        def deprecation_warning(called, callstack)
          ActiveSupport::Deprecation.warn("Using #{@var} directly is deprecated - call #{@method} instead.", callstack)
        end

        def method_missing(called, *args, &block)
          deprecation_warning called, caller
          @instance.__send__(@method).__send__(called, *args, &block)
        end
    end
  end
end

class Class
  include ActiveSupport::Deprecation::ClassMethods
end

module Test
  module Unit
    class TestCase
      include ActiveSupport::Deprecation::Assertions
    end
  end
end