1Code.require_file("../../test_helper.exs", __DIR__)
2
3defmodule Mix.Tasks.Compile.YeccTest do
4  use MixTest.Case
5  import ExUnit.CaptureIO
6
7  if System.otp_release() >= "24" do
8    defmacro position(line, column), do: {line, column}
9  else
10    defmacro position(line, _column), do: line
11  end
12
13  setup do
14    Mix.Project.push(MixTest.Case.Sample)
15    :ok
16  end
17
18  test "compilation continues if one file fails to compile" do
19    in_fixture("compile_yecc", fn ->
20      file = Path.absname("src/zzz.yrl")
21
22      File.write!(file, """
23      oops.
24      """)
25
26      capture_io(fn ->
27        assert {:error, [diagnostic]} = Mix.Tasks.Compile.Yecc.run(["--force"])
28
29        assert %Mix.Task.Compiler.Diagnostic{
30                 compiler_name: "yecc",
31                 file: ^file,
32                 message: message,
33                 position: position(1, 5),
34                 severity: :error
35               } = diagnostic
36
37        assert message =~ "syntax error before: "
38      end)
39
40      assert File.regular?("src/test_ok.erl")
41    end)
42  end
43
44  test "returns warning diagnostics on conflicts" do
45    in_fixture("compile_yecc", fn ->
46      file = Path.absname("src/conflict.yrl")
47
48      File.write!(file, """
49      Nonterminals exp.
50      Terminals number '+'.
51      Rootsymbol exp.
52      exp -> exp '+' exp.
53      exp -> number.
54      """)
55
56      capture_io(fn ->
57        assert {:ok, [diagnostic]} = Mix.Tasks.Compile.Yecc.run(["--force"])
58
59        assert %Mix.Task.Compiler.Diagnostic{
60                 compiler_name: "yecc",
61                 file: ^file,
62                 message: "conflicts: 1 shift/reduce, 0 reduce/reduce",
63                 position: 0,
64                 severity: :warning
65               } = diagnostic
66      end)
67    end)
68  end
69
70  test "compiles src/test_ok.yrl" do
71    in_fixture("compile_yecc", fn ->
72      assert Mix.Tasks.Compile.Yecc.run(["--verbose"]) == {:ok, []}
73
74      assert_received {:mix_shell, :info, ["Compiled src/test_ok.yrl"]}
75      assert File.regular?("src/test_ok.erl")
76
77      assert Mix.Tasks.Compile.Yecc.run(["--verbose"]) == {:noop, []}
78      refute_received {:mix_shell, :info, ["Compiled src/test_ok.yrl"]}
79
80      assert Mix.Tasks.Compile.Yecc.run(["--force", "--verbose"]) == {:ok, []}
81      assert_received {:mix_shell, :info, ["Compiled src/test_ok.yrl"]}
82    end)
83  end
84
85  test "removes old artifact files" do
86    in_fixture("compile_yecc", fn ->
87      assert Mix.Tasks.Compile.Yecc.run([]) == {:ok, []}
88      assert File.regular?("src/test_ok.erl")
89
90      File.rm!("src/test_ok.yrl")
91      assert Mix.Tasks.Compile.Yecc.run([]) == {:ok, []}
92      refute File.regular?("src/test_ok.erl")
93    end)
94  end
95end
96