Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid race conditions in tests #1569

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 6 additions & 4 deletions test/ex_doc_test.exs
@@ -1,6 +1,8 @@
defmodule ExDocTest do
use ExUnit.Case, async: true

@moduletag :tmp_dir

# Simple retriever that returns whatever is passed into it
defmodule IdentityRetriever do
def docs_from_dir(source, config) do
Expand All @@ -15,15 +17,15 @@ defmodule ExDocTest do
end
end

test "uses custom markdown processor" do
test "uses custom markdown processor", %{tmp_dir: tmp_dir} do
project = "Elixir"
version = "1"

options = [
apps: [:test_app],
formatter: IdentityFormatter,
markdown_processor: Sample,
output: "test/tmp/ex_doc",
output: tmp_dir <> "/ex_doc",
retriever: IdentityRetriever,
source_beam: "beam_dir"
]
Expand All @@ -34,15 +36,15 @@ defmodule ExDocTest do
Application.delete_env(:ex_doc, :markdown_processor)
end

test "uses custom markdown processor with custom options" do
test "uses custom markdown processor with custom options", %{tmp_dir: tmp_dir} do
project = "Elixir"
version = "1"

options = [
apps: [:test_app],
formatter: IdentityFormatter,
markdown_processor: {Sample, [foo: :bar]},
output: "test/tmp/ex_doc",
output: tmp_dir <> "/ex_doc",
retriever: IdentityRetriever,
source_beam: "beam_dir"
]
Expand Down
92 changes: 53 additions & 39 deletions test/mix/tasks/docs_test.exs
Expand Up @@ -3,109 +3,123 @@ Mix.shell(Mix.Shell.Process)

defmodule Mix.Tasks.DocsTest do
# Cannot run concurrently due to Mix compile/deps calls
use ExUnit.Case
use ExUnit.Case, async: false

def run(args, opts) do
@moduletag :tmp_dir

def run(context, args, opts) do
opts = Keyword.put_new(opts, :output, context[:tmp_dir])
Mix.Tasks.Docs.run(args, opts, &{&1, &2, &3})
end

test "inflects values from app and version" do
test "inflects values from app and version", context do
assert [
{"ex_doc", "0.1.0", [formatter: "html", deps: _, apps: _, source_beam: _]},
{"ex_doc", "0.1.0", [formatter: "epub", deps: _, apps: _, source_beam: _]}
] = run([], app: :ex_doc, version: "0.1.0")
] = run(context, [], app: :ex_doc, version: "0.1.0")
end

test "accepts multiple formatters from CLI" do
test "accepts multiple formatters from CLI", context do
assert [
{"ex_doc", "0.1.0", [formatter: "html", deps: _, apps: _, source_beam: _]},
{"ex_doc", "0.1.0", [formatter: "epub", deps: _, apps: _, source_beam: _]}
] = run(["-f", "html", "-f", "epub"], app: :ex_doc, version: "0.1.0")
] = run(context, ["-f", "html", "-f", "epub"], app: :ex_doc, version: "0.1.0")
end

test "accepts multiple formatters from config" do
test "accepts multiple formatters from config", context do
assert [
{"ex_doc", "0.1.0",
[formatter: "html", deps: _, apps: _, source_beam: _, formatters: _]},
{"ex_doc", "0.1.0",
[formatter: "epub", deps: _, apps: _, source_beam: _, formatters: _]}
] = run([], app: :ex_doc, version: "0.1.0", docs: [formatters: ["html", "epub"]])
] =
run(context, [], app: :ex_doc, version: "0.1.0", docs: [formatters: ["html", "epub"]])
end

test "uses the given name" do
test "uses the given name", context do
assert [
{"ExDoc", "0.1.0", [formatter: "html", deps: _, apps: _, source_beam: _]},
{"ExDoc", "0.1.0", [formatter: "epub", deps: _, apps: _, source_beam: _]}
] = run([], app: :ex_doc, version: "0.1.0", name: "ExDoc")
] = run(context, [], app: :ex_doc, version: "0.1.0", name: "ExDoc")
end

test "accepts modules in :main" do
test "accepts modules in :main", context do
assert [
{"ex_doc", "dev",
[formatter: "html", deps: _, main: "Sample", apps: _, source_beam: _]},
{"ex_doc", "dev",
[formatter: "epub", deps: _, main: "Sample", apps: _, source_beam: _]}
] = run([], app: :ex_doc, docs: [main: Sample])
] = run(context, [], app: :ex_doc, docs: [main: Sample])
end

test "accepts files in :main" do
test "accepts files in :main", context do
assert [
{"ex_doc", "dev",
[formatter: "html", deps: _, apps: _, source_beam: _, main: "another"]},
{"ex_doc", "dev",
[formatter: "epub", deps: _, apps: _, source_beam: _, main: "another"]}
] = run([], app: :ex_doc, docs: [main: "another"])
] = run(context, [], app: :ex_doc, docs: [main: "another"])
end

test "accepts output in :output" do
test "accepts output in :output", %{tmp_dir: tmp_dir} = context do
[{_, _, html_options}, {_, _, epub_options}] =
run_results = run(context, [], app: :ex_doc, docs: [output: tmp_dir <> "/hello"])

assert [
{"ex_doc", "dev",
[formatter: "html", deps: _, apps: _, source_beam: _, output: "hello"]},
{"ex_doc", "dev",
[formatter: "epub", deps: _, apps: _, source_beam: _, output: "hello"]}
] = run([], app: :ex_doc, docs: [output: "hello"])
{"ex_doc", "dev", [formatter: "html", deps: _, apps: _, source_beam: _, output: _]},
{"ex_doc", "dev", [formatter: "epub", deps: _, apps: _, source_beam: _, output: _]}
] = run_results

assert html_options[:output] == "#{tmp_dir}/hello"
assert epub_options[:output] == "#{tmp_dir}/hello"
end

test "parses output with lower preference than options" do
test "parses output with lower preference than options", %{tmp_dir: tmp_dir} = context do
output = tmp_dir <> "/world"

[{_, _, html_options}, {_, _, epub_options}] =
run_results = run(context, ["-o", "#{output}"], app: :ex_doc, docs: [output: output])

assert [
{"ex_doc", "dev",
[formatter: "html", deps: _, apps: _, source_beam: _, output: "world"]},
{"ex_doc", "dev",
[formatter: "epub", deps: _, apps: _, source_beam: _, output: "world"]}
] = run(~w(-o world), app: :ex_doc, docs: [output: "world"])
{"ex_doc", "dev", [formatter: "html", deps: _, apps: _, source_beam: _, output: _]},
{"ex_doc", "dev", [formatter: "epub", deps: _, apps: _, source_beam: _, output: _]}
] = run_results

assert html_options[:output] == "#{tmp_dir}/world"
assert epub_options[:output] == "#{tmp_dir}/world"
end

test "includes dependencies" do
test "includes dependencies", context do
assert [
{"ex_doc", "dev", [formatter: "html", deps: deps, apps: _, source_beam: _]},
{"ex_doc", "dev", [formatter: "epub", deps: deps, apps: _, source_beam: _]}
] = run([], app: :ex_doc, docs: [])
] = run(context, [], app: :ex_doc, docs: [])

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

test "allows custom dependency paths" do
test "allows custom dependency paths", context do
assert [
{"ex_doc", "dev", [formatter: "html", deps: deps, apps: _, source_beam: _]},
{"ex_doc", "dev", [formatter: "epub", deps: deps, apps: _, source_beam: _]}
] = run([], app: :ex_doc, docs: [deps: [earmark_parser: "foo"]])
] = run(context, [], app: :ex_doc, docs: [deps: [earmark_parser: "foo"]])

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

test "accepts lazy docs" do
test "accepts lazy docs", context do
assert [
{"ex_doc", "dev",
[formatter: "html", deps: _, apps: _, source_beam: _, main: "another"]},
{"ex_doc", "dev",
[formatter: "epub", deps: _, apps: _, source_beam: _, main: "another"]}
] = run([], app: :ex_doc, docs: fn -> [main: "another"] end)
] = run(context, [], app: :ex_doc, docs: fn -> [main: "another"] end)
end

test "accepts options from root" do
test "accepts options from root", context do
# accepted options are: `app`, `name`, `source_url`, `homepage_url`, `version`
assert [
{"ExDoc", "1.2.3-dev",
Expand All @@ -127,18 +141,18 @@ defmodule Mix.Tasks.DocsTest do
source_url: "https://github.com/elixir-lang/ex_doc"
]}
] =
run([],
run(context, [],
app: :ex_doc,
name: "ExDoc",
source_url: "https://github.com/elixir-lang/ex_doc",
homepage_url: "https://elixir-lang.org",
version: "1.2.3-dev"
)

assert [{"ex_doc", "dev", _}, {"ex_doc", "dev", _}] = run([], app: :ex_doc)
assert [{"ex_doc", "dev", _}, {"ex_doc", "dev", _}] = run(context, [], app: :ex_doc)
end

test "supports umbrella project" do
test "supports umbrella project", context do
Mix.Project.in_project(:umbrella, "test/fixtures/umbrella", fn _mod ->
[
{"umbrella", "dev",
Expand All @@ -155,11 +169,11 @@ defmodule Mix.Tasks.DocsTest do
apps: [:bar, :foo],
source_beam: _
]}
] = run([], app: :umbrella, apps_path: "apps/", docs: [])
] = run(context, [], app: :umbrella, apps_path: "apps/", docs: [])
end)
end

test "supports umbrella project with ignore_apps" do
test "supports umbrella project with ignore_apps", context do
Mix.Project.in_project(:umbrella, "test/fixtures/umbrella", fn _mod ->
[
{"umbrella", "dev",
Expand All @@ -178,7 +192,7 @@ defmodule Mix.Tasks.DocsTest do
source_beam: _,
ignore_apps: [:foo]
]}
] = run([], app: :umbrella, apps_path: "apps/", docs: [ignore_apps: [:foo]])
] = run(context, [], app: :umbrella, apps_path: "apps/", docs: [ignore_apps: [:foo]])
end)
end
end