Skip to content

Commit f6e2b30

Browse files
Avoid race conditions in tests (#1569)
Use tmp_dir in tests to avoid CI failures: https://github.com/elixir-lang/ex_doc/runs/6293776556?check_suite_focus=true
1 parent c6ed542 commit f6e2b30

2 files changed

Lines changed: 59 additions & 43 deletions

File tree

test/ex_doc_test.exs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
defmodule ExDocTest do
22
use ExUnit.Case, async: true
33

4+
@moduletag :tmp_dir
5+
46
# Simple retriever that returns whatever is passed into it
57
defmodule IdentityRetriever do
68
def docs_from_dir(source, config) do
@@ -15,15 +17,15 @@ defmodule ExDocTest do
1517
end
1618
end
1719

18-
test "uses custom markdown processor" do
20+
test "uses custom markdown processor", %{tmp_dir: tmp_dir} do
1921
project = "Elixir"
2022
version = "1"
2123

2224
options = [
2325
apps: [:test_app],
2426
formatter: IdentityFormatter,
2527
markdown_processor: Sample,
26-
output: "test/tmp/ex_doc",
28+
output: tmp_dir <> "/ex_doc",
2729
retriever: IdentityRetriever,
2830
source_beam: "beam_dir"
2931
]
@@ -34,15 +36,15 @@ defmodule ExDocTest do
3436
Application.delete_env(:ex_doc, :markdown_processor)
3537
end
3638

37-
test "uses custom markdown processor with custom options" do
39+
test "uses custom markdown processor with custom options", %{tmp_dir: tmp_dir} do
3840
project = "Elixir"
3941
version = "1"
4042

4143
options = [
4244
apps: [:test_app],
4345
formatter: IdentityFormatter,
4446
markdown_processor: {Sample, [foo: :bar]},
45-
output: "test/tmp/ex_doc",
47+
output: tmp_dir <> "/ex_doc",
4648
retriever: IdentityRetriever,
4749
source_beam: "beam_dir"
4850
]

test/mix/tasks/docs_test.exs

Lines changed: 53 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3,109 +3,123 @@ Mix.shell(Mix.Shell.Process)
33

44
defmodule Mix.Tasks.DocsTest do
55
# Cannot run concurrently due to Mix compile/deps calls
6-
use ExUnit.Case
6+
use ExUnit.Case, async: false
77

8-
def run(args, opts) do
8+
@moduletag :tmp_dir
9+
10+
def run(context, args, opts) do
11+
opts = Keyword.put_new(opts, :output, context[:tmp_dir])
912
Mix.Tasks.Docs.run(args, opts, &{&1, &2, &3})
1013
end
1114

12-
test "inflects values from app and version" do
15+
test "inflects values from app and version", context do
1316
assert [
1417
{"ex_doc", "0.1.0", [formatter: "html", deps: _, apps: _, source_beam: _]},
1518
{"ex_doc", "0.1.0", [formatter: "epub", deps: _, apps: _, source_beam: _]}
16-
] = run([], app: :ex_doc, version: "0.1.0")
19+
] = run(context, [], app: :ex_doc, version: "0.1.0")
1720
end
1821

19-
test "accepts multiple formatters from CLI" do
22+
test "accepts multiple formatters from CLI", context do
2023
assert [
2124
{"ex_doc", "0.1.0", [formatter: "html", deps: _, apps: _, source_beam: _]},
2225
{"ex_doc", "0.1.0", [formatter: "epub", deps: _, apps: _, source_beam: _]}
23-
] = run(["-f", "html", "-f", "epub"], app: :ex_doc, version: "0.1.0")
26+
] = run(context, ["-f", "html", "-f", "epub"], app: :ex_doc, version: "0.1.0")
2427
end
2528

26-
test "accepts multiple formatters from config" do
29+
test "accepts multiple formatters from config", context do
2730
assert [
2831
{"ex_doc", "0.1.0",
2932
[formatter: "html", deps: _, apps: _, source_beam: _, formatters: _]},
3033
{"ex_doc", "0.1.0",
3134
[formatter: "epub", deps: _, apps: _, source_beam: _, formatters: _]}
32-
] = run([], app: :ex_doc, version: "0.1.0", docs: [formatters: ["html", "epub"]])
35+
] =
36+
run(context, [], app: :ex_doc, version: "0.1.0", docs: [formatters: ["html", "epub"]])
3337
end
3438

35-
test "uses the given name" do
39+
test "uses the given name", context do
3640
assert [
3741
{"ExDoc", "0.1.0", [formatter: "html", deps: _, apps: _, source_beam: _]},
3842
{"ExDoc", "0.1.0", [formatter: "epub", deps: _, apps: _, source_beam: _]}
39-
] = run([], app: :ex_doc, version: "0.1.0", name: "ExDoc")
43+
] = run(context, [], app: :ex_doc, version: "0.1.0", name: "ExDoc")
4044
end
4145

42-
test "accepts modules in :main" do
46+
test "accepts modules in :main", context do
4347
assert [
4448
{"ex_doc", "dev",
4549
[formatter: "html", deps: _, main: "Sample", apps: _, source_beam: _]},
4650
{"ex_doc", "dev",
4751
[formatter: "epub", deps: _, main: "Sample", apps: _, source_beam: _]}
48-
] = run([], app: :ex_doc, docs: [main: Sample])
52+
] = run(context, [], app: :ex_doc, docs: [main: Sample])
4953
end
5054

51-
test "accepts files in :main" do
55+
test "accepts files in :main", context do
5256
assert [
5357
{"ex_doc", "dev",
5458
[formatter: "html", deps: _, apps: _, source_beam: _, main: "another"]},
5559
{"ex_doc", "dev",
5660
[formatter: "epub", deps: _, apps: _, source_beam: _, main: "another"]}
57-
] = run([], app: :ex_doc, docs: [main: "another"])
61+
] = run(context, [], app: :ex_doc, docs: [main: "another"])
5862
end
5963

60-
test "accepts output in :output" do
64+
test "accepts output in :output", %{tmp_dir: tmp_dir} = context do
65+
[{_, _, html_options}, {_, _, epub_options}] =
66+
run_results = run(context, [], app: :ex_doc, docs: [output: tmp_dir <> "/hello"])
67+
6168
assert [
62-
{"ex_doc", "dev",
63-
[formatter: "html", deps: _, apps: _, source_beam: _, output: "hello"]},
64-
{"ex_doc", "dev",
65-
[formatter: "epub", deps: _, apps: _, source_beam: _, output: "hello"]}
66-
] = run([], app: :ex_doc, docs: [output: "hello"])
69+
{"ex_doc", "dev", [formatter: "html", deps: _, apps: _, source_beam: _, output: _]},
70+
{"ex_doc", "dev", [formatter: "epub", deps: _, apps: _, source_beam: _, output: _]}
71+
] = run_results
72+
73+
assert html_options[:output] == "#{tmp_dir}/hello"
74+
assert epub_options[:output] == "#{tmp_dir}/hello"
6775
end
6876

69-
test "parses output with lower preference than options" do
77+
test "parses output with lower preference than options", %{tmp_dir: tmp_dir} = context do
78+
output = tmp_dir <> "/world"
79+
80+
[{_, _, html_options}, {_, _, epub_options}] =
81+
run_results = run(context, ["-o", "#{output}"], app: :ex_doc, docs: [output: output])
82+
7083
assert [
71-
{"ex_doc", "dev",
72-
[formatter: "html", deps: _, apps: _, source_beam: _, output: "world"]},
73-
{"ex_doc", "dev",
74-
[formatter: "epub", deps: _, apps: _, source_beam: _, output: "world"]}
75-
] = run(~w(-o world), app: :ex_doc, docs: [output: "world"])
84+
{"ex_doc", "dev", [formatter: "html", deps: _, apps: _, source_beam: _, output: _]},
85+
{"ex_doc", "dev", [formatter: "epub", deps: _, apps: _, source_beam: _, output: _]}
86+
] = run_results
87+
88+
assert html_options[:output] == "#{tmp_dir}/world"
89+
assert epub_options[:output] == "#{tmp_dir}/world"
7690
end
7791

78-
test "includes dependencies" do
92+
test "includes dependencies", context do
7993
assert [
8094
{"ex_doc", "dev", [formatter: "html", deps: deps, apps: _, source_beam: _]},
8195
{"ex_doc", "dev", [formatter: "epub", deps: deps, apps: _, source_beam: _]}
82-
] = run([], app: :ex_doc, docs: [])
96+
] = run(context, [], app: :ex_doc, docs: [])
8397

8498
assert List.keyfind(deps, :earmark_parser, 0) ==
8599
{:earmark_parser,
86100
"https://hexdocs.pm/earmark_parser/#{Application.spec(:earmark_parser, :vsn)}/"}
87101
end
88102

89-
test "allows custom dependency paths" do
103+
test "allows custom dependency paths", context do
90104
assert [
91105
{"ex_doc", "dev", [formatter: "html", deps: deps, apps: _, source_beam: _]},
92106
{"ex_doc", "dev", [formatter: "epub", deps: deps, apps: _, source_beam: _]}
93-
] = run([], app: :ex_doc, docs: [deps: [earmark_parser: "foo"]])
107+
] = run(context, [], app: :ex_doc, docs: [deps: [earmark_parser: "foo"]])
94108

95109
assert List.keyfind(deps, :earmark_parser, 0) ==
96110
{:earmark_parser, "foo"}
97111
end
98112

99-
test "accepts lazy docs" do
113+
test "accepts lazy docs", context do
100114
assert [
101115
{"ex_doc", "dev",
102116
[formatter: "html", deps: _, apps: _, source_beam: _, main: "another"]},
103117
{"ex_doc", "dev",
104118
[formatter: "epub", deps: _, apps: _, source_beam: _, main: "another"]}
105-
] = run([], app: :ex_doc, docs: fn -> [main: "another"] end)
119+
] = run(context, [], app: :ex_doc, docs: fn -> [main: "another"] end)
106120
end
107121

108-
test "accepts options from root" do
122+
test "accepts options from root", context do
109123
# accepted options are: `app`, `name`, `source_url`, `homepage_url`, `version`
110124
assert [
111125
{"ExDoc", "1.2.3-dev",
@@ -127,18 +141,18 @@ defmodule Mix.Tasks.DocsTest do
127141
source_url: "https://github.com/elixir-lang/ex_doc"
128142
]}
129143
] =
130-
run([],
144+
run(context, [],
131145
app: :ex_doc,
132146
name: "ExDoc",
133147
source_url: "https://github.com/elixir-lang/ex_doc",
134148
homepage_url: "https://elixir-lang.org",
135149
version: "1.2.3-dev"
136150
)
137151

138-
assert [{"ex_doc", "dev", _}, {"ex_doc", "dev", _}] = run([], app: :ex_doc)
152+
assert [{"ex_doc", "dev", _}, {"ex_doc", "dev", _}] = run(context, [], app: :ex_doc)
139153
end
140154

141-
test "supports umbrella project" do
155+
test "supports umbrella project", context do
142156
Mix.Project.in_project(:umbrella, "test/fixtures/umbrella", fn _mod ->
143157
[
144158
{"umbrella", "dev",
@@ -155,11 +169,11 @@ defmodule Mix.Tasks.DocsTest do
155169
apps: [:bar, :foo],
156170
source_beam: _
157171
]}
158-
] = run([], app: :umbrella, apps_path: "apps/", docs: [])
172+
] = run(context, [], app: :umbrella, apps_path: "apps/", docs: [])
159173
end)
160174
end
161175

162-
test "supports umbrella project with ignore_apps" do
176+
test "supports umbrella project with ignore_apps", context do
163177
Mix.Project.in_project(:umbrella, "test/fixtures/umbrella", fn _mod ->
164178
[
165179
{"umbrella", "dev",
@@ -178,7 +192,7 @@ defmodule Mix.Tasks.DocsTest do
178192
source_beam: _,
179193
ignore_apps: [:foo]
180194
]}
181-
] = run([], app: :umbrella, apps_path: "apps/", docs: [ignore_apps: [:foo]])
195+
] = run(context, [], app: :umbrella, apps_path: "apps/", docs: [ignore_apps: [:foo]])
182196
end)
183197
end
184198
end

0 commit comments

Comments
 (0)