diff --git a/lib/elixir/lib/uri.ex b/lib/elixir/lib/uri.ex index fd3754140a0..c4702bb904b 100644 --- a/lib/elixir/lib/uri.ex +++ b/lib/elixir/lib/uri.ex @@ -954,12 +954,12 @@ defmodule URI do defp remove_dot_segments([], acc), do: acc defp remove_dot_segments([:/ | tail], acc), do: remove_dot_segments(tail, [:/ | acc]) + defp remove_dot_segments([_, :+ | tail], acc), do: remove_dot_segments(tail, acc) defp remove_dot_segments(["."], acc), do: remove_dot_segments([], ["" | acc]) defp remove_dot_segments(["." | tail], acc), do: remove_dot_segments(tail, acc) defp remove_dot_segments([".." | tail], [:/]), do: remove_dot_segments(tail, [:/]) defp remove_dot_segments([".."], [_ | acc]), do: remove_dot_segments([], ["" | acc]) defp remove_dot_segments([".." | tail], [_ | acc]), do: remove_dot_segments(tail, acc) - defp remove_dot_segments([_, :+ | tail], acc), do: remove_dot_segments(tail, acc) defp remove_dot_segments([head | tail], acc), do: remove_dot_segments(tail, [head | acc]) defp join_reversed_segments(segments) do diff --git a/lib/elixir/test/elixir/uri_test.exs b/lib/elixir/test/elixir/uri_test.exs index 869d1f3eb67..0f219bfc7e1 100644 --- a/lib/elixir/test/elixir/uri_test.exs +++ b/lib/elixir/test/elixir/uri_test.exs @@ -520,6 +520,115 @@ defmodule URITest do end end + test "merge/2 (with W3C examples)" do + # These examples are from the W3C JSON-LD test suite: + # + # https://w3c.github.io/json-ld-api/tests/toRdf-manifest#t0124 + # https://w3c.github.io/json-ld-api/tests/toRdf-manifest#t0125 + + base1 = "http://a/bb/ccc/." + + rel_and_result1 = %{ + "g:h" => "g:h", + "g" => "http://a/bb/ccc/g", + "./g" => "http://a/bb/ccc/g", + "g/" => "http://a/bb/ccc/g/", + "/g" => "http://a/g", + "//g" => "http://g", + "?y" => "http://a/bb/ccc/.?y", + "g?y" => "http://a/bb/ccc/g?y", + "#s" => "http://a/bb/ccc/.#s", + "g#s" => "http://a/bb/ccc/g#s", + "g?y#s" => "http://a/bb/ccc/g?y#s", + ";x" => "http://a/bb/ccc/;x", + "g;x" => "http://a/bb/ccc/g;x", + "g;x?y#s" => "http://a/bb/ccc/g;x?y#s", + "" => "http://a/bb/ccc/.", + "." => "http://a/bb/ccc/", + "./" => "http://a/bb/ccc/", + ".." => "http://a/bb/", + "../" => "http://a/bb/", + "../g" => "http://a/bb/g", + "../.." => "http://a/", + "../../" => "http://a/", + "../../g" => "http://a/g", + "../../../g" => "http://a/g", + "../../../../g" => "http://a/g", + "/./g" => "http://a/g", + "/../g" => "http://a/g", + "g." => "http://a/bb/ccc/g.", + ".g" => "http://a/bb/ccc/.g", + "g.." => "http://a/bb/ccc/g..", + "..g" => "http://a/bb/ccc/..g", + "./../g" => "http://a/bb/g", + "./g/." => "http://a/bb/ccc/g/", + "g/./h" => "http://a/bb/ccc/g/h", + "g/../h" => "http://a/bb/ccc/h", + "g;x=1/./y" => "http://a/bb/ccc/g;x=1/y", + "g;x=1/../y" => "http://a/bb/ccc/y", + "g?y/./x" => "http://a/bb/ccc/g?y/./x", + "g?y/../x" => "http://a/bb/ccc/g?y/../x", + "g#s/./x" => "http://a/bb/ccc/g#s/./x", + "g#s/../x" => "http://a/bb/ccc/g#s/../x", + "http:g" => "http:g" + } + + for {rel, result} <- rel_and_result1 do + assert URI.merge(base1, rel) |> URI.to_string() == result + end + + base2 = "http://a/bb/ccc/.." + + rel_and_result2 = %{ + "g:h" => "g:h", + "g" => "http://a/bb/ccc/g", + "./g" => "http://a/bb/ccc/g", + "g/" => "http://a/bb/ccc/g/", + "/g" => "http://a/g", + "//g" => "http://g", + "?y" => "http://a/bb/ccc/..?y", + "g?y" => "http://a/bb/ccc/g?y", + "#s" => "http://a/bb/ccc/..#s", + "g#s" => "http://a/bb/ccc/g#s", + "g?y#s" => "http://a/bb/ccc/g?y#s", + ";x" => "http://a/bb/ccc/;x", + "g;x" => "http://a/bb/ccc/g;x", + "g;x?y#s" => "http://a/bb/ccc/g;x?y#s", + "" => "http://a/bb/ccc/..", + "." => "http://a/bb/ccc/", + "./" => "http://a/bb/ccc/", + ".." => "http://a/bb/", + "../" => "http://a/bb/", + "../g" => "http://a/bb/g", + "../.." => "http://a/", + "../../" => "http://a/", + "../../g" => "http://a/g", + "../../../g" => "http://a/g", + "../../../../g" => "http://a/g", + "/./g" => "http://a/g", + "/../g" => "http://a/g", + "g." => "http://a/bb/ccc/g.", + ".g" => "http://a/bb/ccc/.g", + "g.." => "http://a/bb/ccc/g..", + "..g" => "http://a/bb/ccc/..g", + "./../g" => "http://a/bb/g", + "./g/." => "http://a/bb/ccc/g/", + "g/./h" => "http://a/bb/ccc/g/h", + "g/../h" => "http://a/bb/ccc/h", + "g;x=1/./y" => "http://a/bb/ccc/g;x=1/y", + "g;x=1/../y" => "http://a/bb/ccc/y", + "g?y/./x" => "http://a/bb/ccc/g?y/./x", + "g?y/../x" => "http://a/bb/ccc/g?y/../x", + "g#s/./x" => "http://a/bb/ccc/g#s/./x", + "g#s/../x" => "http://a/bb/ccc/g#s/../x", + "http:g" => "http:g" + } + + for {rel, result} <- rel_and_result2 do + assert URI.merge(base2, rel) |> URI.to_string() == result + end + end + test "append_query/2" do assert URI.append_query(URI.parse("http://example.com/?x=1"), "x=2").query == "x=1&x=2" assert URI.append_query(URI.parse("http://example.com/?x=1&"), "x=2").query == "x=1&x=2"