Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion lib/phoenix/verified_routes.ex
Original file line number Diff line number Diff line change
Expand Up @@ -321,9 +321,12 @@ defmodule Phoenix.VerifiedRoutes do
test_path = split_test_path(route.test_path)

unless route.router.verified_route?([], test_path) do
# The file is stored relative to the project, so expand it against the
# current directory here, where the warning is emitted. Mix persists
# warnings by their absolute source path and drops relative ones.
IO.warn(
"no route path for #{inspect(route.router)} matches #{route.inspected_route}",
route.warn_location
Keyword.update!(route.warn_location, :file, &Path.expand/1)
)
end
end)
Expand Down Expand Up @@ -984,6 +987,10 @@ defmodule Phoenix.VerifiedRoutes do

defp warn_location(meta, %{line: line, file: file, function: function, module: module}) do
column = if column = meta[:column], do: column + 2
# Relative to the project, so copies of the project (git worktrees,
# copy-on-write clones) that reuse the build point to their own files.
# It is expanded again when the warning is emitted, see __verify__/1.
file = Path.relative_to_cwd(file)
[line: line, function: function, module: module, file: file, column: column]
end

Expand Down
29 changes: 29 additions & 0 deletions test/phoenix/verified_routes_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,35 @@ defmodule Phoenix.VerifiedRoutesTest do
:code.delete(__MODULE__.Unmatched)
end

test "~p warning location resolves to the current directory" do
{_, diagnostics} =
Code.with_diagnostics(fn ->
defmodule WarnLocation do
use Phoenix.VerifiedRoutes, endpoint: unquote(@endpoint), router: unquote(@router)

def test, do: ~p"/unknown"
end
end)

assert [%{file: file} = diagnostic] = diagnostics

assert diagnostic.message =~
~s|no route path for Phoenix.VerifiedRoutesTest.Router matches "/unknown"|

# the file is stored relative to the project and expanded when the
# warning is emitted, which Mix needs to persist the warning
assert Path.expand(file) == __ENV__.file

# Elixir 1.15 always reports IO.warn locations relative to the current directory
if Version.match?(System.version(), ">= 1.16.0") do
assert Path.type(file) == :absolute
assert diagnostic.source == file
end
after
:code.purge(__MODULE__.WarnLocation)
:code.delete(__MODULE__.WarnLocation)
end

test "~p warns on warn_on_verify: true route" do
warnings =
ExUnit.CaptureIO.capture_io(:stderr, fn ->
Expand Down
Loading