1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
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 && ! silenced?
end
def default_behavior
DEFAULT_BEHAVIORS[RAILS_ENV.to_s] if defined?(RAILS_ENV)
end
# Have deprecations been silenced?
def silenced?
@silenced
end
# Silence deprecations for the duration of the provided block. For internal
# use only.
def silence
old_silenced, @silenced = @silenced, true # We could have done behavior = nil...
yield
ensure
@silenced = old_silenced
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 = collect_deprecations(&block).last
assert last, "Expected a deprecation warning within the block but received none"
if match
match = Regexp.new(Regexp.escape(match)) unless match.is_a?(Regexp)
assert_match match, last, "Deprecation warning didn't match #{match}: #{last}"
end
end
def assert_not_deprecated(&block)
deprecations = collect_deprecations(&block)
assert deprecations.empty?, "Expected no deprecation warning within the block but received #{deprecations.size}: \n #{deprecations * "\n "}"
end
private
def collect_deprecations
old_behavior = ActiveSupport::Deprecation.behavior
deprecations = []
ActiveSupport::Deprecation.behavior = Proc.new do |message|
deprecations << message
old_behavior.call(message) if old_behavior
end
yield
return deprecations
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 warn(callstack, called, args)
ActiveSupport::Deprecation.warn("#{@var} is deprecated! Call #{@method}.#{called} instead of #{@var}.#{called}. Args: #{args.inspect}", callstack)
end
def method_missing(called, *args, &block)
warn caller, called, args
@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
|