Improve the logic that detects non-autoloaded constants

If you require `nokogiri` from `app/models/user.rb`, dependencies.rb
does not mark `Nokogiri` as an autoloaded constant, as expected.
But the logic to detect these non-autoloaded constants is incomplete.
See the tests defined in the patch for some cases incorrectly handled.
This commit is contained in:
Jan Habermann 2018-10-18 19:05:20 +02:00
parent 3295e23755
commit e302725751
5 changed files with 52 additions and 1 deletions

@ -103,6 +103,8 @@ class WatchStack
# parent.rb then requires namespace/child.rb, the stack will look like # parent.rb then requires namespace/child.rb, the stack will look like
# [[Object], [Namespace]]. # [[Object], [Namespace]].
attr_reader :watching
def initialize def initialize
@watching = [] @watching = []
@stack = Hash.new { |h, k| h[k] = [] } @stack = Hash.new { |h, k| h[k] = [] }
@ -254,7 +256,9 @@ def require_dependency(file_name, message = "No such file to load -- %s.rb")
def load_dependency(file) def load_dependency(file)
if Dependencies.load? && Dependencies.constant_watch_stack.watching? if Dependencies.load? && Dependencies.constant_watch_stack.watching?
Dependencies.new_constants_in(Object) { yield } descs = Dependencies.constant_watch_stack.watching.flatten.uniq
Dependencies.new_constants_in(*descs) { yield }
else else
yield yield
end end

@ -0,0 +1,8 @@
# frozen_string_literal: true
require "dependencies/module_folder/lib_class"
module ModuleFolder
class NestedWithRequire
end
end

@ -0,0 +1,5 @@
# frozen_string_literal: true
class NestedWithRequireParent
ModuleFolder::NestedWithRequire
end

@ -0,0 +1,8 @@
# frozen_string_literal: true
ConstFromLib = 1
module ModuleFolder
class LibClass
end
end

@ -282,6 +282,32 @@ def test_module_with_nested_inline_class
remove_constants(:ModuleFolder) remove_constants(:ModuleFolder)
end end
def test_module_with_nested_class_requiring_lib_class
with_autoloading_fixtures do
ModuleFolder::NestedWithRequire
assert defined?(ModuleFolder::LibClass)
assert_not ActiveSupport::Dependencies.autoloaded_constants.include?("ModuleFolder::LibClass")
assert_not ActiveSupport::Dependencies.autoloaded_constants.include?("ConstFromLib")
end
ensure
remove_constants(:ModuleFolder)
remove_constants(:ConstFromLib)
end
def test_module_with_nested_class_and_parent_requiring_lib_class
with_autoloading_fixtures do
NestedWithRequireParent
assert defined?(ModuleFolder::LibClass)
assert_not ActiveSupport::Dependencies.autoloaded_constants.include?("ModuleFolder::LibClass")
assert_not ActiveSupport::Dependencies.autoloaded_constants.include?("ConstFromLib")
end
ensure
remove_constants(:ModuleFolder)
remove_constants(:ConstFromLib)
end
def test_directories_may_manifest_as_nested_classes def test_directories_may_manifest_as_nested_classes
with_autoloading_fixtures do with_autoloading_fixtures do
assert_kind_of Class, ClassFolder assert_kind_of Class, ClassFolder