1Code.require_file("../../test_helper.exs", __DIR__)
2
3defmodule Mix.Tasks.HelpTest do
4  use MixTest.Case
5
6  import ExUnit.CaptureIO
7
8  test "help lists all tasks", context do
9    in_tmp(context.test, fn ->
10      Mix.Tasks.Help.run([])
11      assert_received {:mix_shell, :info, ["mix" <> _]}
12      assert_received {:mix_shell, :info, ["mix help" <> _]}
13      assert_received {:mix_shell, :info, ["mix compile" <> _]}
14    end)
15  end
16
17  test "help list default task", context do
18    in_tmp(context.test, fn ->
19      Mix.Tasks.Help.run([])
20
21      assert_received {:mix_shell, :info, [output]}
22      assert output =~ ~r/^mix\s+# Runs the default task \(current: \"mix run\"\)/m
23    end)
24  end
25
26  defmodule Aliases do
27    def project do
28      [aliases: [h: "hello", c: "compile"]]
29    end
30  end
31
32  test "help lists all aliases", context do
33    in_tmp(context.test, fn ->
34      Mix.Project.push(Aliases)
35
36      Mix.Tasks.Help.run([])
37
38      assert_received {:mix_shell, :info, ["mix h" <> message]}
39      assert message =~ ~r/# Alias defined in mix.exs/
40
41      assert_received {:mix_shell, :info, ["mix c" <> message]}
42      assert message =~ ~r/# Alias defined in mix.exs/
43    end)
44  end
45
46  test "help --names", context do
47    in_tmp(context.test, fn ->
48      Mix.Project.push(Aliases)
49
50      Mix.Tasks.Help.run(["--names"])
51      assert_received {:mix_shell, :info, ["c"]}
52      assert_received {:mix_shell, :info, ["compile"]}
53      assert_received {:mix_shell, :info, ["h"]}
54      assert_received {:mix_shell, :info, ["help"]}
55      assert_received {:mix_shell, :info, ["escript.build"]}
56      refute_received {:mix_shell, :info, ["compile.all"]}
57    end)
58  end
59
60  defmodule ComplexAliases do
61    def project do
62      [
63        aliases: [
64          h: "hello",
65          p: &inspect/1,
66          help: ["help", "hello"],
67          "nested.h": [&Mix.shell().info(inspect(&1)), "h foo bar"]
68        ]
69      ]
70    end
71  end
72
73  test "help ALIAS", context do
74    in_tmp(context.test, fn ->
75      Mix.Project.push(ComplexAliases)
76
77      output =
78        capture_io(fn ->
79          Mix.Tasks.Help.run(["h"])
80        end)
81
82      assert output =~ "mix h\n\n"
83      assert output =~ "Alias for \"hello\"\n"
84      assert output =~ ~r/^Location: mix.exs/m
85
86      output =
87        capture_io(fn ->
88          Mix.Tasks.Help.run(["p"])
89        end)
90
91      assert output =~ "mix p\n\n"
92      assert output =~ "Alias for &Kernel.inspect/1\n"
93      assert output =~ ~r/^Location: mix.exs/m
94
95      output =
96        capture_io(fn ->
97          Mix.Tasks.Help.run(["help"])
98        end)
99
100      assert output =~ "mix help\n\n"
101      assert output =~ "Alias for [\"help\", \"hello\"]\n"
102      assert output =~ ~r/^Location: mix.exs/m
103
104      output =
105        capture_io(fn ->
106          Mix.Tasks.Help.run(["nested.h"])
107        end)
108
109      assert output =~ "mix nested.h\n\n"
110      assert output =~ ~r/Alias for \[#Function/
111      assert output =~ ~r/^Location: mix.exs/m
112    end)
113  end
114
115  test "help TASK", context do
116    in_tmp(context.test, fn ->
117      output =
118        capture_io(fn ->
119          Mix.Tasks.Help.run(["compile"])
120        end)
121
122      assert output =~ "mix compile\n"
123      assert output =~ "## Command line options"
124      assert output =~ ~r/^Location:/m
125
126      output =
127        capture_io(fn ->
128          Mix.Tasks.Help.run(["compile.all"])
129        end)
130
131      assert output =~ "mix compile.all\n"
132      assert output =~ "There is no documentation for this task"
133    end)
134  end
135
136  defmodule ShadowedAliases do
137    def project do
138      [aliases: [compile: "compile"]]
139    end
140  end
141
142  test "help TASK && ALIAS", context do
143    in_tmp(context.test, fn ->
144      Mix.Project.push(ShadowedAliases)
145
146      output =
147        capture_io(fn ->
148          Mix.Tasks.Help.run(["compile"])
149        end)
150
151      assert output =~ "mix compile\n\n"
152      assert output =~ "Alias for \"compile\"\n"
153      assert output =~ ~r/^Location: mix.exs/m
154
155      assert output =~
156               "\nThere is also a task named \"compile\". The documentation is shown next.\n"
157
158      assert output =~ "## Command line options"
159      assert output =~ ~r/^Location:/m
160    end)
161  end
162
163  test "help --search PATTERN", context do
164    in_tmp(context.test, fn ->
165      Mix.Tasks.Help.run(["--search", "deps"])
166      assert_received {:mix_shell, :info, ["mix deps" <> _]}
167      assert_received {:mix_shell, :info, ["mix deps.clean" <> _]}
168    end)
169
170    in_tmp(context.test, fn ->
171      Mix.Project.push(Aliases)
172
173      Mix.Tasks.Help.run(["--search", "h"])
174      assert_received {:mix_shell, :info, ["mix h" <> message]}
175      assert message =~ ~r/# Alias defined in mix.exs/
176    end)
177  end
178
179  test "help --search without pattern" do
180    assert_raise Mix.Error, "Unexpected arguments, expected \"mix help --search PATTERN\"", fn ->
181      Mix.Tasks.Help.run(["--search"])
182    end
183  end
184
185  test "help --search without results", context do
186    in_tmp(context.test, fn ->
187      output =
188        capture_io(fn ->
189          Mix.Tasks.Help.run(["--search", "foo"])
190        end)
191
192      assert output == ""
193    end)
194  end
195
196  test "bad arguments" do
197    message = "Unexpected arguments, expected \"mix help\" or \"mix help TASK\""
198
199    assert_raise Mix.Error, message, fn ->
200      Mix.Tasks.Help.run(["foo", "bar"])
201    end
202  end
203end
204