diff --git a/lib/elixir/lib/version.ex b/lib/elixir/lib/version.ex index 076964b300..ec359f93d2 100644 --- a/lib/elixir/lib/version.ex +++ b/lib/elixir/lib/version.ex @@ -362,11 +362,21 @@ defmodule Version do """ @spec compare(version, version) :: :gt | :eq | :lt + def compare( + %Version{major: major1, minor: minor1, patch: patch1, pre: pre1}, + %Version{major: major2, minor: minor2, patch: patch2, pre: pre2} + ) do + do_compare(major1, minor1, patch1, pre1, major2, minor2, patch2, pre2) + end + def compare(version1, version2) do - do_compare(to_matchable(version1, true), to_matchable(version2, true)) + {major1, minor1, patch1, pre1, _} = to_matchable(version1, true) + {major2, minor2, patch2, pre2, _} = to_matchable(version2, true) + + do_compare(major1, minor1, patch1, pre1, major2, minor2, patch2, pre2) end - defp do_compare({major1, minor1, patch1, pre1, _}, {major2, minor2, patch2, pre2, _}) do + defp do_compare(major1, minor1, patch1, pre1, major2, minor2, patch2, pre2) do cond do major1 > major2 -> :gt major1 < major2 -> :lt diff --git a/lib/elixir/test/elixir/version_test.exs b/lib/elixir/test/elixir/version_test.exs index 6de54b01eb..3b7844a5c6 100644 --- a/lib/elixir/test/elixir/version_test.exs +++ b/lib/elixir/test/elixir/version_test.exs @@ -38,6 +38,26 @@ defmodule VersionTest do assert Version.compare("1.5.0-rc.0", "1.5.0-rc0") == :lt end + test "compare/2 with Version structs" do + large_major = Bitwise.bsl(1, 256) + large_pre = Bitwise.bsl(1, 128) + left = %Version{major: large_major, minor: 2, patch: 3, pre: ["alpha", large_pre]} + right = %Version{major: large_major, minor: 2, patch: 3, pre: ["alpha", large_pre + 1]} + + assert Version.compare(left, right) == :lt + assert Version.compare(right, left) == :gt + assert Version.compare(left, %{left | major: large_major + 1}) == :lt + assert Version.compare(%{left | minor: 1}, %{left | minor: 2}) == :lt + assert Version.compare(%{left | patch: 2}, %{left | patch: 3}) == :lt + assert Version.compare(%{left | pre: [1]}, %{left | pre: ["alpha"]}) == :lt + assert Version.compare(%{left | pre: ["alpha"]}, %{left | pre: ["alpha", 1]}) == :lt + assert Version.compare(%{left | pre: ["alpha"]}, %{left | pre: []}) == :lt + assert Version.compare(%{left | pre: []}, %{left | pre: ["alpha"]}) == :gt + assert Version.compare(%{left | build: "left"}, %{left | build: "right"}) == :eq + assert Version.compare(%{left | major: 1}, "2.0.0") == :lt + assert Version.compare("2.0.0", %{left | major: 1}) == :gt + end + test "compare/2 with invalid versions" do assert_raise Version.InvalidVersionError, fn -> Version.compare("1.0", "1.0.0")