Skip to content

Commit

Permalink
Implements Zeitwerk::Loader#all_expected_paths
Browse files Browse the repository at this point in the history
  • Loading branch information
fxn committed May 12, 2024
1 parent 33fe4a2 commit f9bd460
Show file tree
Hide file tree
Showing 2 changed files with 188 additions and 0 deletions.
34 changes: 34 additions & 0 deletions lib/zeitwerk/loader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,40 @@ def reload
setup
end

# Returns a hash that maps the absolute paths of the managed files and
# directories to their respective expected constant paths.
#
# @sig () -> Hash[String, String]
def all_expected_cpaths
result = {}

actual_roots.each do |root_dir, root_namespace|
queue = [[root_dir, real_mod_name(root_namespace)]]

until queue.empty?
dir, cpath = queue.shift
result[dir] = cpath

prefix = cpath == "Object" ? "" : cpath + "::"

ls(dir) do |basename, abspath|
if dir?(abspath)
if collapse?(abspath)
queue << [abspath, cpath]
else
queue << [abspath, prefix + inflector.camelize(basename, abspath)]
end
else
basename.delete_suffix!(".rb")
result[abspath] = prefix + inflector.camelize(basename, abspath)
end
end
end
end

result
end

# @sig (String | Pathname) -> String?
def cpath_expected_at(path)
abspath = File.expand_path(path)
Expand Down
154 changes: 154 additions & 0 deletions test/lib/zeitwerk/test_all_expected_capths.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
# frozen_string_literal: true

require "test_helper"

class TestAllExpectedCpaths < LoaderTest
module Namespace
def self.name
"overridden"
end
end

test "returns an empty hash if there are no root directories" do
with_setup do
expected_cpaths({})
end
end

test "honors a real root module name" do
files = [["x.rb", "#{self.class}::Namespace::X = 1"]]
with_setup(files, namespace: Namespace) do
expected_cpaths(
"." => "#{self.class.name}::Namespace",
"x.rb" => "#{self.class.name}::Namespace::X"
)
end
end

test "does not include ignored files and directories" do
files = [
["x.rb", "X = 1"],
["ignored.rb", ""],
["ignored/x.rb", ""]
]
with_setup(files) do
expected_cpaths(
"." => "Object",
"x.rb" => "X"
)
end
end

test "does not include hidden files" do
files = [
[".foo.rb", ""],
["x.rb", "X = 1"]
]
with_setup(files) do
expected_cpaths(
"." => "Object",
"x.rb" => "X"
)
end
end

test "does not include directories without Ruby files " do
files = [
["x.rb", "X = 1"],
["empty", ""],
["assets/js/index.js", ""],
["assets/css/index.css", ""],
["m/ignored.rb", ""]
]
with_setup(files) do
expected_cpaths(
"." => "Object",
"x.rb" => "X"
)
end
end

test "includes shadowed files" do
files = [
["rd1/x.rb", "X = 1"],
["rd2/x.rb", "X = 1"],
]
with_setup(files) do
expected_cpaths(
"rd1" => "Object",
"rd1/x.rb" => "X",
"rd2" => "Object",
"rd2/x.rb" => "X"
)
end
end

test "honors collapsed directories" do
files = [
["x.rb", "X = 1"],
["collapsed/y.rb", "Y = 1"],
["m/collapsed/n/x.rb", "M::N::X = 1"]
]
with_setup(files) do
expected_cpaths(
"." => "Object",
"x.rb" => "X",
"collapsed" => "Object",
"collapsed/y.rb" => "Y",
"m" => "M",
"m/collapsed" => "M",
"m/collapsed/n" => "M::N",
"m/collapsed/n/x.rb" => "M::N::X"
)
end
end

test "implicit namespaces" do
files = [
["x.rb", "X = 1"],
["m/x.rb", "M::X = 1"],
["m/n/x.rb", "M::N::X = 1"]
]
with_setup(files) do
expected_cpaths(
"." => "Object",
"x.rb" => "X",
"m" => "M",
"m/x.rb" => "M::X",
"m/n" => "M::N",
"m/n/x.rb" => "M::N::X"
)
end
end

test "explicit namespaces" do
files = [
["x.rb", "X = 1"],
["m.rb", "module M; end"],
["m/x.rb", "M::X = 1"],
["m/n.rb", "module M::N; end"],
["m/n/x.rb", "M::N::X = 1"]
]
with_setup(files) do
expected_cpaths(
"." => "Object",
"x.rb" => "X",
"m.rb" => "M",
"m" => "M",
"m/x.rb" => "M::X",
"m/n.rb" => "M::N",
"m/n" => "M::N",
"m/n/x.rb" => "M::N::X"
)
end
end

private def expected_cpaths(expected)
actual = loader.all_expected_cpaths

assert_equal expected.size, actual.size
expected.each do |relpath, expected_cpath|
assert_equal expected_cpath, actual[File.expand_path(relpath)]
end
end
end

0 comments on commit f9bd460

Please sign in to comment.