defmodule Refactorex.Refactor.Variable.UnderscoreNotUsedTest do
  use Refactorex.RefactorCase

  alias Refactorex.Refactor.Variable.UnderscoreNotUsed

  test "underlines unused args on function header" do
    assert_refactored(
      UnderscoreNotUsed,
      """
      #       v
      def foo(bar1, bar2, bar3) do
        bar1
      end
      """,
      """
      def foo(bar1, _bar2, _bar3) do
        bar1
      end
      """
    )
  end

  test "underlines unused args on anonymous function" do
    assert_refactored(
      UnderscoreNotUsed,
      """
      fn
      #       v
        %{bar1: bar1, bar2: bar2} -> bar1
      end
      """,
      """
      fn
        %{bar1: bar1, bar2: _bar2} -> bar1
      end
      """
    )
  end

  test "underlines unused args inside pattern matching" do
    assert_refactored(
      UnderscoreNotUsed,
      """
      #       v
      def foo(%{bar1: bar1, bar2: bar2}) do
        bar1
      end
      """,
      """
      def foo(%{bar1: bar1, bar2: _bar2}) do
        bar1
      end
      """
    )
  end

  test "underlines unused args generated by an assignment" do
    assert_refactored(
      UnderscoreNotUsed,
      """
      def foo() do
      #       v
        foo = bar = 10
      end
      """,
      """
      def foo() do
        _foo = _bar = 10
      end
      """
    )
  end

  test "ignores repeated args used for pattern matching" do
    assert_ignored(
      UnderscoreNotUsed,
      """
      #       v
      def foo(bar1, bar2, bar2) do
        bar1
      end
      """
    )
  end

  test "ignores functions with no args" do
    assert_ignored(
      UnderscoreNotUsed,
      """
      #       v
      def foo, do: 25
      """
    )
  end

  test "ignores anonymous functions with no args" do
    assert_ignored(
      UnderscoreNotUsed,
      """
      #       v
      fn -> 25 end
      """
    )
  end

  test "ignores already underlined args" do
    assert_ignored(
      UnderscoreNotUsed,
      """
      #       v
      def foo(bar1, _bar2) do
        bar1
      end
      """
    )
  end

  test "ignores pinned args" do
    assert_ignored(
      UnderscoreNotUsed,
      """
      def foo(bar) do
        #       v
        fn %{bar: ^bar} -> :stop end
      end
      """
    )
  end

  test "ignores args used on guards" do
    assert_ignored(
      UnderscoreNotUsed,
      """
      #       v
      def foo(bar1, bar2) when bar2 == 2 do
        bar1
      end
      """
    )
  end
end
