| 1 |
require 'yaml' |
|---|
| 2 |
|
|---|
| 3 |
module ActiveSupport |
|---|
| 4 |
module Deprecation |
|---|
| 5 |
mattr_accessor :debug |
|---|
| 6 |
self.debug = false |
|---|
| 7 |
|
|---|
| 8 |
|
|---|
| 9 |
|
|---|
| 10 |
DEFAULT_BEHAVIORS = { |
|---|
| 11 |
'test' => Proc.new { |message, callstack| |
|---|
| 12 |
$stderr.puts(message) |
|---|
| 13 |
$stderr.puts callstack.join("\n ") if debug |
|---|
| 14 |
}, |
|---|
| 15 |
'development' => Proc.new { |message, callstack| |
|---|
| 16 |
logger = defined?(::RAILS_DEFAULT_LOGGER) ? ::RAILS_DEFAULT_LOGGER : Logger.new($stderr) |
|---|
| 17 |
logger.warn message |
|---|
| 18 |
logger.debug callstack.join("\n ") if debug |
|---|
| 19 |
} |
|---|
| 20 |
} |
|---|
| 21 |
|
|---|
| 22 |
class << self |
|---|
| 23 |
def warn(message = nil, callstack = caller) |
|---|
| 24 |
behavior.call(deprecation_message(callstack, message), callstack) if behavior && !silenced? |
|---|
| 25 |
end |
|---|
| 26 |
|
|---|
| 27 |
def default_behavior |
|---|
| 28 |
if defined?(RAILS_ENV) |
|---|
| 29 |
DEFAULT_BEHAVIORS[RAILS_ENV.to_s] |
|---|
| 30 |
else |
|---|
| 31 |
DEFAULT_BEHAVIORS['test'] |
|---|
| 32 |
end |
|---|
| 33 |
end |
|---|
| 34 |
|
|---|
| 35 |
|
|---|
| 36 |
def silenced? |
|---|
| 37 |
@silenced = false unless defined?(@silenced) |
|---|
| 38 |
@silenced |
|---|
| 39 |
end |
|---|
| 40 |
|
|---|
| 41 |
|
|---|
| 42 |
def silence |
|---|
| 43 |
old_silenced, @silenced = @silenced, true |
|---|
| 44 |
yield |
|---|
| 45 |
ensure |
|---|
| 46 |
@silenced = old_silenced |
|---|
| 47 |
end |
|---|
| 48 |
|
|---|
| 49 |
attr_writer :silenced |
|---|
| 50 |
|
|---|
| 51 |
|
|---|
| 52 |
private |
|---|
| 53 |
def deprecation_message(callstack, message = nil) |
|---|
| 54 |
message ||= "You are using deprecated behavior which will be removed from Rails 2.0." |
|---|
| 55 |
"DEPRECATION WARNING: #{message} See http://www.rubyonrails.org/deprecation for details. #{deprecation_caller_message(callstack)}" |
|---|
| 56 |
end |
|---|
| 57 |
|
|---|
| 58 |
def deprecation_caller_message(callstack) |
|---|
| 59 |
file, line, method = extract_callstack(callstack) |
|---|
| 60 |
if file |
|---|
| 61 |
if line && method |
|---|
| 62 |
"(called from #{method} at #{file}:#{line})" |
|---|
| 63 |
else |
|---|
| 64 |
"(called from #{file}:#{line})" |
|---|
| 65 |
end |
|---|
| 66 |
end |
|---|
| 67 |
end |
|---|
| 68 |
|
|---|
| 69 |
def extract_callstack(callstack) |
|---|
| 70 |
if md = callstack.first.match(/^(.+?):(\d+)(?::in `(.*?)')?/) |
|---|
| 71 |
md.captures |
|---|
| 72 |
else |
|---|
| 73 |
callstack.first |
|---|
| 74 |
end |
|---|
| 75 |
end |
|---|
| 76 |
end |
|---|
| 77 |
|
|---|
| 78 |
|
|---|
| 79 |
mattr_accessor :behavior |
|---|
| 80 |
self.behavior = default_behavior |
|---|
| 81 |
|
|---|
| 82 |
|
|---|
| 83 |
self.silenced = false |
|---|
| 84 |
|
|---|
| 85 |
module ClassMethods |
|---|
| 86 |
|
|---|
| 87 |
def deprecate(*method_names) |
|---|
| 88 |
options = method_names.last.is_a?(Hash) ? method_names.pop : {} |
|---|
| 89 |
method_names = method_names + options.keys |
|---|
| 90 |
method_names.each do |method_name| |
|---|
| 91 |
alias_method_chain(method_name, :deprecation) do |target, punctuation| |
|---|
| 92 |
class_eval(<<-EOS, __FILE__, __LINE__) |
|---|
| 93 |
def |
|---|
| 94 |
::ActiveSupport::Deprecation.warn(self.class.deprecated_method_warning(: |
|---|
| 95 |
|
|---|
| 96 |
end |
|---|
| 97 |
EOS |
|---|
| 98 |
end |
|---|
| 99 |
end |
|---|
| 100 |
end |
|---|
| 101 |
|
|---|
| 102 |
def deprecated_method_warning(method_name, message=nil) |
|---|
| 103 |
warning = "#{method_name} is deprecated and will be removed from Rails #{deprecation_horizon}" |
|---|
| 104 |
case message |
|---|
| 105 |
when Symbol then "#{warning} (use #{message} instead)" |
|---|
| 106 |
when String then "#{warning} (#{message})" |
|---|
| 107 |
else warning |
|---|
| 108 |
end |
|---|
| 109 |
end |
|---|
| 110 |
|
|---|
| 111 |
def deprecation_horizon |
|---|
| 112 |
'2.0' |
|---|
| 113 |
end |
|---|
| 114 |
end |
|---|
| 115 |
|
|---|
| 116 |
module Assertions |
|---|
| 117 |
def assert_deprecated(match = nil, &block) |
|---|
| 118 |
result, warnings = collect_deprecations(&block) |
|---|
| 119 |
assert !warnings.empty?, "Expected a deprecation warning within the block but received none" |
|---|
| 120 |
if match |
|---|
| 121 |
match = Regexp.new(Regexp.escape(match)) unless match.is_a?(Regexp) |
|---|
| 122 |
assert warnings.any? { |w| w =~ match }, "No deprecation warning matched #{match}: #{warnings.join(', ')}" |
|---|
| 123 |
end |
|---|
| 124 |
result |
|---|
| 125 |
end |
|---|
| 126 |
|
|---|
| 127 |
def assert_not_deprecated(&block) |
|---|
| 128 |
result, deprecations = collect_deprecations(&block) |
|---|
| 129 |
assert deprecations.empty?, "Expected no deprecation warning within the block but received #{deprecations.size}: \n #{deprecations * "\n "}" |
|---|
| 130 |
result |
|---|
| 131 |
end |
|---|
| 132 |
|
|---|
| 133 |
private |
|---|
| 134 |
def collect_deprecations |
|---|
| 135 |
old_behavior = ActiveSupport::Deprecation.behavior |
|---|
| 136 |
deprecations = [] |
|---|
| 137 |
ActiveSupport::Deprecation.behavior = Proc.new do |message, callstack| |
|---|
| 138 |
deprecations << message |
|---|
| 139 |
end |
|---|
| 140 |
result = yield |
|---|
| 141 |
[result, deprecations] |
|---|
| 142 |
ensure |
|---|
| 143 |
ActiveSupport::Deprecation.behavior = old_behavior |
|---|
| 144 |
end |
|---|
| 145 |
end |
|---|
| 146 |
|
|---|
| 147 |
|
|---|
| 148 |
|
|---|
| 149 |
class DeprecatedInstanceVariableProxy |
|---|
| 150 |
instance_methods.each { |m| undef_method m unless m =~ /^__/ } |
|---|
| 151 |
|
|---|
| 152 |
def initialize(instance, method, var = "@#{method}") |
|---|
| 153 |
@instance, @method, @var = instance, method, var |
|---|
| 154 |
end |
|---|
| 155 |
|
|---|
| 156 |
|
|---|
| 157 |
|
|---|
| 158 |
def inspect |
|---|
| 159 |
target.inspect |
|---|
| 160 |
end |
|---|
| 161 |
|
|---|
| 162 |
private |
|---|
| 163 |
def method_missing(called, *args, &block) |
|---|
| 164 |
warn caller, called, args |
|---|
| 165 |
target.__send__(called, *args, &block) |
|---|
| 166 |
end |
|---|
| 167 |
|
|---|
| 168 |
def target |
|---|
| 169 |
@instance.__send__(@method) |
|---|
| 170 |
end |
|---|
| 171 |
|
|---|
| 172 |
def warn(callstack, called, args) |
|---|
| 173 |
ActiveSupport::Deprecation.warn("#{@var} is deprecated! Call #{@method}.#{called} instead of #{@var}.#{called}. Args: #{args.inspect}", callstack) |
|---|
| 174 |
end |
|---|
| 175 |
end |
|---|
| 176 |
end |
|---|
| 177 |
end |
|---|
| 178 |
|
|---|
| 179 |
class Module |
|---|
| 180 |
include ActiveSupport::Deprecation::ClassMethods |
|---|
| 181 |
end |
|---|
| 182 |
|
|---|
| 183 |
require 'test/unit/error' |
|---|
| 184 |
|
|---|
| 185 |
module Test |
|---|
| 186 |
module Unit |
|---|
| 187 |
class TestCase |
|---|
| 188 |
include ActiveSupport::Deprecation::Assertions |
|---|
| 189 |
end |
|---|
| 190 |
|
|---|
| 191 |
class Error |
|---|
| 192 |
|
|---|
| 193 |
def message_with_silenced_deprecation |
|---|
| 194 |
ActiveSupport::Deprecation.silence do |
|---|
| 195 |
message_without_silenced_deprecation |
|---|
| 196 |
end |
|---|
| 197 |
end |
|---|
| 198 |
|
|---|
| 199 |
alias_method_chain :message, :silenced_deprecation |
|---|
| 200 |
end |
|---|
| 201 |
end |
|---|
| 202 |
end |
|---|