diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c2b3bb5d..93df1096 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,7 +9,7 @@ jobs: name: Ex${{matrix.elixir}}/OTP${{matrix.otp}} strategy: matrix: - elixir: ['1.14.2'] + elixir: ['1.14.2', '1.15.0'] otp: ['25.1.2'] steps: - uses: actions/checkout@v3 diff --git a/lib/style/single_node.ex b/lib/style/single_node.ex index 713043f9..3447a0cb 100644 --- a/lib/style/single_node.ex +++ b/lib/style/single_node.ex @@ -95,6 +95,23 @@ defmodule Styler.Style.SingleNode do defp style({{:., dm, [{:__aliases__, am, [:Logger]}, :warn]}, funm, args}), do: {{:., dm, [{:__aliases__, am, [:Logger]}, :warning]}, funm, args} + # Transform Timex defdelegates + defp style({{:., dm, [{:__aliases__, am, [:Timex]}, :today]}, funm, args}), + do: {{:., dm, [{:__aliases__, am, [:Date]}, :utc_today]}, funm, args} + + defp style({{:., dm, [{:__aliases__, am, [:Timex]}, :now]}, funm, args}), + do: {{:., dm, [{:__aliases__, am, [:DateTime]}, :utc_now]}, funm, args} + + if Version.match?(System.version(), ">= 1.15.0-dev") do + # {DateTime,NaiveDateTime,Time,Date}.compare(a, b) == :lt -> {DateTime,NaiveDateTime,Time,Date}.before?(a, b) + # {DateTime,NaiveDateTime,Time,Date}.compare(a, b) == :gt -> {DateTime,NaiveDateTime,Time,Date}.after?(a, b) + defp style({:==, _, [{{:., dm, [{:__aliases__, am, [mod]}, :compare]}, funm, args}, {:__block__, _, [result]}]}) + when mod in ~w[DateTime NaiveDateTime Time Date]a and result in [:lt, :gt] do + fun = if result == :lt, do: :before?, else: :after? + {{:., dm, [{:__aliases__, am, [mod]}, fun]}, funm, args} + end + end + # Remove parens from 0 arity funs (Credo.Check.Readability.ParenthesesOnZeroArityDefs) defp style({def, dm, [{fun, funm, []} | rest]}) when def in ~w(def defp)a and is_atom(fun), do: style({def, dm, [{fun, Keyword.delete(funm, :closing), nil} | rest]}) diff --git a/test/style/single_node_test.exs b/test/style/single_node_test.exs index c231dcc0..a3d8c237 100644 --- a/test/style/single_node_test.exs +++ b/test/style/single_node_test.exs @@ -21,6 +21,30 @@ defmodule Styler.Style.SingleNodeTest do assert_style("Logger.warn(foo, bar)", "Logger.warning(foo, bar)") end + test "Timex.now -> DateTime.utc_now" do + assert_style("Timex.now()", "DateTime.utc_now()") + end + + test "Timex.today -> Date.utc_today" do + assert_style("Timex.today()", "Date.utc_today()") + end + + if Version.match?(System.version(), ">= 1.15.0-dev") do + test "{DateTime,NaiveDateTime,Time,Date}.compare to {DateTime,NaiveDateTime,Time,Date}.before?" do + assert_style("DateTime.compare(foo, bar) == :lt", "DateTime.before?(foo, bar)") + assert_style("NaiveDateTime.compare(foo, bar) == :lt", "NaiveDateTime.before?(foo, bar)") + assert_style("Time.compare(foo, bar) == :lt", "Time.before?(foo, bar)") + assert_style("Date.compare(foo, bar) == :lt", "Date.before?(foo, bar)") + end + + test "{DateTime,NaiveDateTime,Time,Date}.compare to {DateTime,NaiveDateTime,Time,Date}.after?" do + assert_style("DateTime.compare(foo, bar) == :gt", "DateTime.after?(foo, bar)") + assert_style("NaiveDateTime.compare(foo, bar) == :gt", "NaiveDateTime.after?(foo, bar)") + assert_style("Time.compare(foo, bar) == :gt", "Time.after?(foo, bar)") + assert_style("Time.compare(foo, bar) == :gt", "Time.after?(foo, bar)") + end + end + describe "def / defp" do test "0-arity functions have parens removed" do assert_style("def foo(), do: :ok", "def foo, do: :ok")