aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/CHANGELOG5
-rw-r--r--activesupport/lib/active_support/dependencies.rb194
-rw-r--r--activesupport/lib/active_support/deprecation.rb24
-rw-r--r--activesupport/lib/active_support/reloadable.rb41
-rw-r--r--activesupport/test/autoloading_fixtures/conflict.rb1
-rw-r--r--activesupport/test/caching_tools_test.rb1
-rw-r--r--activesupport/test/dependencies/conflict.rb1
-rw-r--r--activesupport/test/dependencies_test.rb134
-rw-r--r--activesupport/test/deprecation_test.rb11
-rw-r--r--activesupport/test/reloadable_test.rb32
10 files changed, 381 insertions, 63 deletions
diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG
index 3ddfc19643..d8cc98cd97 100644
--- a/activesupport/CHANGELOG
+++ b/activesupport/CHANGELOG
@@ -1,5 +1,9 @@
*SVN*
+<<<<<<< .mine
+* Replace Reloadable with improvements to the Dependencies mechanism. [Nicholas Seckar]
+
+=======
* DateTime#to_time gives hour/minute/second resolution. #5747 [jon.evans@pobox.com]
* attr_internal to support namespacing and deprecation. Like attr_* except backed by internally-named instance variable. Set attr_internal_naming_format to change the format from the default '@_%s'. [Jeremy Kemper]
@@ -8,6 +12,7 @@
self.attr_internal_naming_format = '@%s__rofl'
attr_internal :foo
+>>>>>>> .r4727
* Raise fully qualified names upon name errors. #5533 [lars@pinds.com, Nicholas Seckar]
* Add extention to obtain the missing constant from NameError instances. [Nicholas Seckar]
diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb
index a58989173e..e845408137 100644
--- a/activesupport/lib/active_support/dependencies.rb
+++ b/activesupport/lib/active_support/dependencies.rb
@@ -22,12 +22,20 @@ module Dependencies #:nodoc:
mattr_accessor :mechanism
self.mechanism = :load
+ # The set of directories from which we may autoload files
+ mattr_accessor :autoload_paths
+ self.autoload_paths = []
+
+ mattr_accessor :autoloaded_constants
+ self.autoloaded_constants = []
+
def load?
mechanism == :load
end
def depend_on(file_name, swallow_load_errors = false)
- require_or_load(file_name)
+ path = search_for_autoload_file(file_name)
+ require_or_load(path || file_name)
rescue LoadError
raise unless swallow_load_errors
end
@@ -38,9 +46,10 @@ module Dependencies #:nodoc:
def clear
loaded.clear
+ remove_autoloaded_constants!
end
- def require_or_load(file_name)
+ def require_or_load(file_name, const_path = nil)
file_name = $1 if file_name =~ /^(.*)\.rb$/
return if loaded.include?(file_name)
@@ -52,10 +61,13 @@ module Dependencies #:nodoc:
begin
# Enable warnings iff this file has not been loaded before and
# warnings_on_first_load is set.
+ load_args = ["#{file_name}.rb"]
+ load_args << const_path unless const_path.nil?
+
if !warnings_on_first_load or history.include?(file_name)
- load "#{file_name}.rb"
+ load_file(*load_args)
else
- enable_warnings { load "#{file_name}.rb" }
+ enable_warnings { load_file(*load_args) }
end
rescue
loaded.delete file_name
@@ -69,9 +81,127 @@ module Dependencies #:nodoc:
history << file_name
end
- # Return the a constant path for the provided parent and constant name
- def constant_path_for(mod, name)
- ([Object, Kernel].include? mod) ? name.to_s : "#{mod}::#{name}"
+ # Is the provided constant path defined?
+ def qualified_const_defined?(path)
+ raise NameError, "#{path.inspect} is not a valid constant name!" unless
+ /^(::)?([A-Z]\w*)(::[A-Z]\w*)*$/ =~ path
+ Object.module_eval("defined?(#{path})", __FILE__, __LINE__)
+ end
+
+ # Given +path+ return an array of constant paths which would cause Dependencies
+ # to attempt to load +path+.
+ def autoloadable_constants_for_path(path)
+ path = $1 if path =~ /\A(.*)\.rb\Z/
+ expanded_path = File.expand_path(path)
+ autoload_paths.collect do |root|
+ expanded_root = File.expand_path root
+ next unless expanded_path.starts_with? expanded_root
+
+ nesting = expanded_path[(expanded_root.size)..-1]
+ nesting = nesting[1..-1] if nesting && nesting[0] == ?/
+ next if nesting.blank?
+
+ nesting.camelize
+ end.compact.uniq
+ end
+
+ # Search for a file in the autoload_paths matching the provided suffix.
+ def search_for_autoload_file(path_suffix)
+ path_suffix = path_suffix + '.rb' unless path_suffix.ends_with? '.rb'
+ autoload_paths.each do |root|
+ path = File.join(root, path_suffix)
+ return path if File.file? path
+ end
+ nil # Gee, I sure wish we had first_match ;-)
+ end
+
+ # Does the provided path_suffix correspond to an autoloadable module?
+ def autoloadable_module?(path_suffix)
+ autoload_paths.any? do |autoload_path|
+ File.directory? File.join(autoload_path, path_suffix)
+ end
+ end
+
+ # Load the file at the provided path. +const_paths+ is a set of qualified
+ # constant names. When loading the file, Dependencies will watch for the
+ # addition of these constants. Each that is defined will be marked as
+ # autoloaded, and will be removed when Dependencies.clear is next called.
+ #
+ # If the second parameter is left off, then Dependencies will construct a set
+ # of names that the file at +path+ may define. See
+ # +autoloadable_constants_for_path+ for more details.
+ def load_file(path, const_paths = autoloadable_constants_for_path(path))
+ const_paths = [const_paths].compact unless const_paths.is_a? Array
+ undefined_before = const_paths.reject(&method(:qualified_const_defined?))
+
+ load path
+
+ autoloaded_constants.concat const_paths.select(&method(:qualified_const_defined?))
+ autoloaded_constants.uniq!
+ end
+
+ # Return the constant path for the provided parent and constant name.
+ def qualified_name_for(mod, name)
+ mod_name = to_constant_name mod
+ (%w(Object Kernel).include? mod_name) ? name.to_s : "#{mod_name}::#{name}"
+ end
+
+ # Load the constant named +const_name+ which is missing from +from_mod+. If
+ # it is not possible to laod the constant into from_mod, try its parent module
+ # using const_missing.
+ def load_missing_constant(from_mod, const_name)
+ qualified_name = qualified_name_for from_mod, const_name
+ path_suffix = qualified_name.underscore
+ name_error = NameError.new("uninitialized constant #{qualified_name}")
+
+ file_path = search_for_autoload_file(path_suffix)
+ if file_path # We found a matching file to load
+ require_or_load file_path, qualified_name
+ raise LoadError, "Expected #{file_path} to define #{qualified_name}" unless from_mod.const_defined?(const_name)
+ return from_mod.const_get(const_name)
+ elsif autoloadable_module? path_suffix # Create modules for directories
+ mod = Module.new
+ from_mod.const_set const_name, mod
+ autoloaded_constants << qualified_name
+ return mod
+ elsif (parent = from_mod.parent) && parent != from_mod &&
+ ! from_mod.parents.any? { |p| p.const_defined?(const_name) }
+ # If our parents do not have a constant named +const_name+ then we are free
+ # to attempt to load upwards. If they do have such a constant, then this
+ # const_missing must be due to from_mod::const_name, which should not
+ # return constants from from_mod's parents.
+ begin
+ return parent.const_missing(const_name)
+ rescue NameError => e
+ raise unless e.missing_name? qualified_name_for(parent, const_name)
+ raise name_error
+ end
+ else
+ raise name_error
+ end
+ end
+
+ # Remove the constants that have been autoloaded.
+ def remove_autoloaded_constants!
+ until autoloaded_constants.empty?
+ const = autoloaded_constants.shift
+ next unless qualified_const_defined? const
+ names = const.split('::')
+ if names.size == 1 || names.first.empty? # It's under Object
+ parent = Object
+ else
+ parent = (names[0..-2] * '::').constantize
+ end
+ parent.send :remove_const, names.last
+ true
+ end
+ end
+
+ # Determine if the given constant has been automatically loaded.
+ def autoloaded?(desc)
+ name = to_constant_name desc
+ return false unless qualified_const_defined? name
+ return autoloaded_constants.include?(name)
end
class LoadingModule
@@ -84,6 +214,20 @@ module Dependencies #:nodoc:
end
end
end
+
+protected
+
+ # Convert the provided const desc to a qualified constant name (as a string).
+ # A module, class, symbol, or string may be provided.
+ def to_constant_name(desc)
+ name = case desc
+ when String then desc.starts_with?('::') ? desc[2..-1] : desc
+ when Symbol then desc.to_s
+ when Module then desc.name
+ else raise TypeError, "Not a valid constant descriptor: #{desc.inspect}"
+ end
+ end
+
end
Object.send(:define_method, :require_or_load) { |file_name| Dependencies.require_or_load(file_name) } unless Object.respond_to?(:require_or_load)
@@ -97,37 +241,7 @@ class Module #:nodoc:
# Use const_missing to autoload associations so we don't have to
# require_association when using single-table inheritance.
def const_missing(class_id)
- file_name = class_id.to_s.demodulize.underscore
- file_path = as_load_path.empty? ? file_name : "#{as_load_path}/#{file_name}"
- begin
- require_dependency(file_path)
- brief_name = self == Object ? '' : "#{name}::"
- raise NameError.new("uninitialized constant #{brief_name}#{class_id}") unless const_defined?(class_id)
- return const_get(class_id)
- rescue MissingSourceFile => e
- # Re-raise the error if it does not concern the file we were trying to load.
- raise unless e.is_missing? file_path
-
- # Look for a directory in the load path that we ought to load.
- if $LOAD_PATH.any? { |base| File.directory? "#{base}/#{file_path}" }
- mod = Module.new
- const_set class_id, mod # Create the new module
- return mod
- end
-
- # Attempt to access the name from the parent, unless we don't have a valid
- # parent, or the constant is already defined in the parent. If the latter
- # is the case, then we are being queried via self::class_id, and we should
- # avoid returning the constant from the parent if possible.
- if parent && parent != self && ! parents.any? { |p| p.const_defined?(class_id) }
- suppress(NameError) do
- return parent.send(:const_missing, class_id)
- end
- end
-
- qualified_name = Dependencies.constant_path_for self, class_id
- raise NameError.new("uninitialized constant #{qualified_name}").copy_blame!(e)
- end
+ Dependencies.load_missing_constant self, class_id
end
end
@@ -140,9 +254,9 @@ class Class
parent.send :const_missing, class_id
rescue NameError => e
# Make sure that the name we are missing is the one that caused the error
- parent_qualified_name = Dependencies.constant_path_for parent, class_id
+ parent_qualified_name = Dependencies.qualified_name_for parent, class_id
raise unless e.missing_name? parent_qualified_name
- qualified_name = Dependencies.constant_path_for self, class_id
+ qualified_name = Dependencies.qualified_name_for self, class_id
raise NameError.new("uninitialized constant #{qualified_name}").copy_blame!(e)
end
end
diff --git a/activesupport/lib/active_support/deprecation.rb b/activesupport/lib/active_support/deprecation.rb
index 5aff753616..d6c9317f06 100644
--- a/activesupport/lib/active_support/deprecation.rb
+++ b/activesupport/lib/active_support/deprecation.rb
@@ -49,24 +49,30 @@ module ActiveSupport
module Assertions
def assert_deprecated(match = nil, &block)
- last = with_last_message_tracking_deprecation_behavior(&block)
+ last = collect_deprecations(&block).last
assert last, "Expected a deprecation warning within the block but received none"
- match = Regexp.new(Regexp.escape(match)) unless match.is_a?(Regexp)
- assert_match match, last, "Deprecation warning didn't match #{match}: #{last}"
+ 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)
- last = with_last_message_tracking_deprecation_behavior(&block)
- assert_nil last, "Expected no deprecation warning within the block but received one: #{last}"
+ deprecations = collect_deprecations(&block)
+ assert deprecations.empty?, "Expected no deprecation warning within the block but received #{deprecations.size}: \n #{deprecations * "\n "}"
end
private
- def with_last_message_tracking_deprecation_behavior
+
+ def collect_deprecations
old_behavior = ActiveSupport::Deprecation.behavior
- last_message = nil
- ActiveSupport::Deprecation.behavior = Proc.new { |message| last_message = message; old_behavior.call(message) if old_behavior }
+ deprecations = []
+ ActiveSupport::Deprecation.behavior = Proc.new do |message|
+ deprecations << message
+ old_behavior.call(message) if old_behavior
+ end
yield
- last_message
+ return deprecations
ensure
ActiveSupport::Deprecation.behavior = old_behavior
end
diff --git a/activesupport/lib/active_support/reloadable.rb b/activesupport/lib/active_support/reloadable.rb
index 3fd13e3d0f..3f57723e15 100644
--- a/activesupport/lib/active_support/reloadable.rb
+++ b/activesupport/lib/active_support/reloadable.rb
@@ -1,13 +1,25 @@
-# Classes that include this module will automatically be reloaded
-# by the Rails dispatcher when Dependencies.mechanism = :load.
+require 'active_support/deprecation'
+
+# A deprecated mechanism to mark a class reloadable.
+#
+# Deprecated as of Rails 1.2.
+# All autoloaded objects are now unloaded.
module Reloadable
class << self
+
def included(base) #nodoc:
+ unless base.ancestors.include?(Reloadable::Subclasses) # Avoid double warning
+ ActiveSupport::Deprecation.warn "Reloadable has been deprecated and has no effect.", caller
+ end
+
raise TypeError, "Only Classes can be Reloadable!" unless base.is_a? Class
unless base.respond_to?(:reloadable?)
class << base
- define_method(:reloadable?) { true }
+ define_method(:reloadable?) do
+ ActiveSupport::Deprecation.warn "Reloadable has been deprecated and reloadable? has no effect", caller
+ true
+ end
end
end
end
@@ -15,16 +27,37 @@ module Reloadable
def reloadable_classes
included_in_classes.select { |klass| klass.reloadable? }
end
+ # Commented out so dispatcher doesn't warn. Should we just disable Reloadable?
+ # deprecate :reloadable_classes
end
# Captures the common pattern where a base class should not be reloaded,
# but its subclasses should be.
+ #
+ # Deprecated as of Rails 1.2.
+ # All autoloaded objects are now unloaded.
module Subclasses
def self.included(base) #nodoc:
base.send :include, Reloadable
+ ActiveSupport::Deprecation.warn "Reloadable::Subclasses has been deprecated and has no effect.", caller
(class << base; self; end).send(:define_method, :reloadable?) do
- base != self
+ ActiveSupport::Deprecation.warn "Reloadable has been deprecated and reloadable? has no effect", caller
+ base != self
end
end
end
+
+ module Deprecated
+
+ def self.included(base)
+ class << base
+ define_method(:reloadable?) do
+ ActiveSupport::Deprecation.warn "Reloadable has been deprecated and reloadable? has no effect", caller
+ true # This might not have the desired effect, as AR::B.reloadable? => true.
+ end
+ end
+ end
+
+ end
+
end \ No newline at end of file
diff --git a/activesupport/test/autoloading_fixtures/conflict.rb b/activesupport/test/autoloading_fixtures/conflict.rb
new file mode 100644
index 0000000000..4ac6201902
--- /dev/null
+++ b/activesupport/test/autoloading_fixtures/conflict.rb
@@ -0,0 +1 @@
+Conflict = 2 \ No newline at end of file
diff --git a/activesupport/test/caching_tools_test.rb b/activesupport/test/caching_tools_test.rb
index c9890e4d13..e1cd4e433c 100644
--- a/activesupport/test/caching_tools_test.rb
+++ b/activesupport/test/caching_tools_test.rb
@@ -1,4 +1,5 @@
require File.dirname(__FILE__) + '/abstract_unit'
+require File.join(File.dirname(File.dirname(__FILE__)), 'lib/active_support/caching_tools.rb')
class HashCachingTests < Test::Unit::TestCase
def cached(&proc)
diff --git a/activesupport/test/dependencies/conflict.rb b/activesupport/test/dependencies/conflict.rb
new file mode 100644
index 0000000000..e888b7b54c
--- /dev/null
+++ b/activesupport/test/dependencies/conflict.rb
@@ -0,0 +1 @@
+Conflict = 1 \ No newline at end of file
diff --git a/activesupport/test/dependencies_test.rb b/activesupport/test/dependencies_test.rb
index f19542bdb0..bf9aaac8c1 100644
--- a/activesupport/test/dependencies_test.rb
+++ b/activesupport/test/dependencies_test.rb
@@ -1,19 +1,19 @@
require File.dirname(__FILE__) + '/abstract_unit'
-#require 'dependencies'
class DependenciesTest < Test::Unit::TestCase
+
def teardown
Dependencies.clear
end
- def with_loading(from_dir = nil)
- prior_path = $LOAD_PATH.clone
- $LOAD_PATH.unshift "#{File.dirname(__FILE__)}/#{from_dir}" if from_dir
+ def with_loading(*from)
old_mechanism, Dependencies.mechanism = Dependencies.mechanism, :load
+ dir = File.dirname(__FILE__)
+ prior_autoload_paths = Dependencies.autoload_paths
+ Dependencies.autoload_paths = from.collect { |f| "#{dir}/#{f}" }
yield
ensure
- $LOAD_PATH.clear
- $LOAD_PATH.concat prior_path
+ Dependencies.autoload_paths = prior_autoload_paths
Dependencies.mechanism = old_mechanism
end
@@ -159,13 +159,13 @@ class DependenciesTest < Test::Unit::TestCase
def test_non_existing_const_raises_name_error_with_fully_qualified_name
with_loading 'autoloading_fixtures' do
begin
- A::DoesNotExist
+ A::DoesNotExist.nil?
flunk "No raise!!"
rescue NameError => e
assert_equal "uninitialized constant A::DoesNotExist", e.message
end
begin
- A::B::DoesNotExist
+ A::B::DoesNotExist.nil?
flunk "No raise!!"
rescue NameError => e
assert_equal "uninitialized constant A::B::DoesNotExist", e.message
@@ -182,4 +182,122 @@ class DependenciesTest < Test::Unit::TestCase
end
end
+ def test_autoloadable_constants_for_path_should_handle_empty_autoloads
+ assert_equal [], Dependencies.autoloadable_constants_for_path('hello')
+ end
+
+ def test_autoloadable_constants_for_path_should_handle_relative_paths
+ fake_root = 'dependencies'
+ relative_root = File.dirname(__FILE__) + '/dependencies'
+ ['', '/'].each do |suffix|
+ with_loading fake_root + suffix do
+ assert_equal ["A::B"], Dependencies.autoloadable_constants_for_path(relative_root + '/a/b')
+ end
+ end
+ end
+
+ def test_autoloadable_constants_for_path_should_provide_all_results
+ fake_root = '/usr/apps/backpack'
+ with_loading fake_root, fake_root + '/lib' do
+ root = Dependencies.autoload_paths.first
+ assert_equal ["Lib::A::B", "A::B"], Dependencies.autoloadable_constants_for_path(root + '/lib/a/b')
+ end
+ end
+
+ def test_autoloadable_constants_for_path_should_uniq_results
+ fake_root = '/usr/apps/backpack/lib'
+ with_loading fake_root, fake_root + '/' do
+ root = Dependencies.autoload_paths.first
+ assert_equal ["A::B"], Dependencies.autoloadable_constants_for_path(root + '/a/b')
+ end
+ end
+
+ def test_qualified_const_defined
+ assert Dependencies.qualified_const_defined?("Object")
+ assert Dependencies.qualified_const_defined?("::Object")
+ assert Dependencies.qualified_const_defined?("::Object::Kernel")
+ assert Dependencies.qualified_const_defined?("::Object::Dependencies")
+ assert Dependencies.qualified_const_defined?("::Test::Unit::TestCase")
+ end
+
+ def test_autoloaded?
+ with_loading 'autoloading_fixtures' do
+ assert ! Dependencies.autoloaded?("ModuleFolder")
+ assert ! Dependencies.autoloaded?("ModuleFolder::NestedClass")
+
+ assert Dependencies.autoloaded?(ModuleFolder)
+
+ assert Dependencies.autoloaded?("ModuleFolder")
+ assert ! Dependencies.autoloaded?("ModuleFolder::NestedClass")
+
+ assert Dependencies.autoloaded?(ModuleFolder::NestedClass)
+
+ assert Dependencies.autoloaded?("ModuleFolder")
+ assert Dependencies.autoloaded?("ModuleFolder::NestedClass")
+
+ assert Dependencies.autoloaded?("::ModuleFolder")
+ assert Dependencies.autoloaded?(:ModuleFolder)
+
+ Object.send :remove_const, :ModuleFolder
+ end
+ end
+
+ def test_qualified_name_for
+ assert_equal "A", Dependencies.qualified_name_for(Object, :A)
+ assert_equal "A", Dependencies.qualified_name_for(:Object, :A)
+ assert_equal "A", Dependencies.qualified_name_for("Object", :A)
+ assert_equal "A", Dependencies.qualified_name_for("::Object", :A)
+ assert_equal "A", Dependencies.qualified_name_for("::Kernel", :A)
+
+ assert_equal "Dependencies::A", Dependencies.qualified_name_for(:Dependencies, :A)
+ assert_equal "Dependencies::A", Dependencies.qualified_name_for(Dependencies, :A)
+ end
+
+ def test_file_search
+ with_loading 'dependencies' do
+ root = Dependencies.autoload_paths.first
+ assert_equal nil, Dependencies.search_for_autoload_file('service_three')
+ assert_equal nil, Dependencies.search_for_autoload_file('service_three.rb')
+ assert_equal root + '/service_one.rb', Dependencies.search_for_autoload_file('service_one')
+ assert_equal root + '/service_one.rb', Dependencies.search_for_autoload_file('service_one.rb')
+ end
+ end
+
+ def test_file_search_uses_first_in_autoload_path
+ with_loading 'dependencies', 'autoloading_fixtures' do
+ deps, autoload = Dependencies.autoload_paths
+ assert_match %r/dependencies/, deps
+ assert_match %r/autoloading_fixtures/, autoload
+
+ assert_equal deps + '/conflict.rb', Dependencies.search_for_autoload_file('conflict')
+ end
+ with_loading 'autoloading_fixtures', 'dependencies' do
+ autoload, deps = Dependencies.autoload_paths
+ assert_match %r/dependencies/, deps
+ assert_match %r/autoloading_fixtures/, autoload
+
+ assert_equal autoload + '/conflict.rb', Dependencies.search_for_autoload_file('conflict')
+ end
+
+ end
+
+ def test_custom_const_missing_should_work
+ Object.module_eval <<-end_eval
+ module ModuleWithCustomConstMissing
+ def self.const_missing(name)
+ const_set name, name.to_s.hash
+ end
+
+ module A
+ end
+ end
+ end_eval
+
+ with_loading 'autoloading_fixtures' do
+ assert_kind_of Integer, ::ModuleWithCustomConstMissing::B
+ assert_kind_of Module, ::ModuleWithCustomConstMissing::A
+ assert_kind_of String, ::ModuleWithCustomConstMissing::A::B
+ end
+ end
+
end
diff --git a/activesupport/test/deprecation_test.rb b/activesupport/test/deprecation_test.rb
index 472fdecaaf..1a054335d7 100644
--- a/activesupport/test/deprecation_test.rb
+++ b/activesupport/test/deprecation_test.rb
@@ -39,7 +39,7 @@ class DeprecationTest < Test::Unit::TestCase
@dtc.partially
end
end
-
+
def test_undeprecated
assert_not_deprecated do
assert_equal 2, @dtc.not
@@ -67,8 +67,15 @@ class DeprecationTest < Test::Unit::TestCase
def test_deprecated_instance_variable_proxy
assert_not_deprecated { @dtc.request.size }
-
+
assert_deprecated('@request.size') { assert_equal @dtc.request.size, @dtc.old_request.size }
assert_deprecated('@request.to_s') { assert_equal @dtc.request.to_s, @dtc.old_request.to_s }
end
+
+ def test_assert_deprecation_without_match
+ assert_deprecated do
+ @dtc.partially
+ end
+ end
+
end
diff --git a/activesupport/test/reloadable_test.rb b/activesupport/test/reloadable_test.rb
index c330394b29..2ab19db77e 100644
--- a/activesupport/test/reloadable_test.rb
+++ b/activesupport/test/reloadable_test.rb
@@ -78,4 +78,36 @@ class ReloadableTest < Test::Unit::TestCase
assert ! results.include?(ReloadableTestSandbox.const_get(name)), "Expected #{name} NOT to be reloadable"
end
end
+
+ def test_including_reloadable_should_warn
+ c = Class.new
+ assert_deprecated %r{Reloadable} do
+ c.send :include, Reloadable
+ end
+
+ assert_deprecated { c.reloadable? }
+ end
+
+ def test_include_subclasses_should_warn
+ c = Class.new
+ deps = collect_deprecations do
+ c.send :include, Reloadable::Subclasses
+ end
+ assert_equal 1, deps.size
+ assert_match %r{Reloadable::Subclasses}, deps.first
+
+ assert_deprecated { c.reloadable? }
+ end
+
+ def test_include_deprecated_should_not_warn
+ c = Class.new
+ deps = collect_deprecations do
+ c.send :include, Reloadable::Deprecated
+ end
+ assert_equal 0, deps.size
+
+ assert c.respond_to?(:reloadable?)
+ assert_deprecated { c.reloadable? }
+ end
+
end