From 6e9cc81650e029c4f360e0c094be0faad809fb84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20M=C3=BCller?= Date: Sun, 21 May 2023 15:49:56 -0300 Subject: [PATCH 1/9] Safety check before running File.rm_rf! in doc gen --- lib/ex_doc/formatter/epub.ex | 30 ++++++++++++- lib/ex_doc/formatter/html.ex | 42 ++++++++++++++----- test/ex_doc/formatter/epub_test.exs | 12 ++++++ test/ex_doc/formatter/html/erlang_test.exs | 6 +++ .../formatter/html/search_items_test.exs | 6 +++ test/ex_doc/formatter/html_test.exs | 18 ++++++++ test/test_helper.exs | 4 ++ 7 files changed, 105 insertions(+), 13 deletions(-) diff --git a/lib/ex_doc/formatter/epub.ex b/lib/ex_doc/formatter/epub.ex index 44a8c5175..7e38590ef 100644 --- a/lib/ex_doc/formatter/epub.ex +++ b/lib/ex_doc/formatter/epub.ex @@ -10,9 +10,9 @@ defmodule ExDoc.Formatter.EPUB do """ @spec run(list, ExDoc.Config.t()) :: String.t() def run(project_nodes, config) when is_map(config) do + parent = config.output config = normalize_config(config) - File.rm_rf!(config.output) - File.mkdir_p!(Path.join(config.output, "OEBPS")) + setup_output(config, parent) project_nodes = HTML.render_all(project_nodes, ".xhtml", config, highlight_tag: "samp") @@ -44,6 +44,32 @@ defmodule ExDoc.Formatter.EPUB do Path.relative_to_cwd(epub) end + defp setup_output(config, parent) do + safety_path = Path.join(parent, ".ex_doc") + + cond do + File.exists?(safety_path) -> + File.rm_rf!(config.output) + mkdir_output!(config.output, parent) + + not File.exists?(parent) -> + mkdir_output!(config.output, parent) + + true -> + raise """ + ex_doc cannot output to #{config.output}: + Directory already exists and is not managed by ex_doc. + + Try giving an unexisting directory as `--output`. + """ + end + end + + defp mkdir_output!(path, parent) do + File.mkdir_p!(Path.join(path, "OEBPS")) + File.touch!(Path.join(parent, ".ex_doc")) + end + defp normalize_config(config) do output = config.output diff --git a/lib/ex_doc/formatter/html.ex b/lib/ex_doc/formatter/html.ex index 0e18a7788..05e1086fb 100644 --- a/lib/ex_doc/formatter/html.ex +++ b/lib/ex_doc/formatter/html.ex @@ -147,20 +147,40 @@ defmodule ExDoc.Formatter.HTML do end defp output_setup(build, config) do - if File.exists?(build) do - build - |> File.read!() - |> String.split("\n", trim: true) - |> Enum.map(&Path.join(config.output, &1)) - |> Enum.each(&File.rm/1) - - File.rm(build) - else - File.rm_rf!(config.output) - File.mkdir_p!(config.output) + safety_path = Path.join(config.output, ".ex_doc") + + cond do + File.exists?(build) -> + build + |> File.read!() + |> String.split("\n", trim: true) + |> Enum.map(&Path.join(config.output, &1)) + |> Enum.each(&File.rm/1) + + File.rm(build) + + File.exists?(safety_path) -> + File.rm_rf!(config.output) + mkdir_output!(config.output) + + not File.exists?(config.output) -> + mkdir_output!(config.output) + + true -> + raise """ + ex_doc cannot output to #{config.output}: + Directory already exists and is not managed by ex_doc. + + Try giving an unexisting directory as `--output`. + """ end end + defp mkdir_output!(path) do + File.mkdir_p!(path) + File.touch!(Path.join(path, ".ex_doc")) + end + defp generate_build(files, build) do entries = Enum.map(files, &[&1, "\n"]) File.write!(build, entries) diff --git a/test/ex_doc/formatter/epub_test.exs b/test/ex_doc/formatter/epub_test.exs index c1f02225c..3bf6da333 100644 --- a/test/ex_doc/formatter/epub_test.exs +++ b/test/ex_doc/formatter/epub_test.exs @@ -103,6 +103,18 @@ defmodule ExDoc.Formatter.EPUBTest do assert File.regular?(tmp_dir <> "/epub/another_dir/#{doc_config(context)[:project]}.epub") end + test "fails if trying to write to existing directory", context do + assert_raise RuntimeError, ~r/Directory already exists and is not managed by ex_doc/, fn -> + config = doc_config(context) + + new_output = config[:output] <> "/new-dir" + File.mkdir_p!(new_output) + + new_config = Keyword.put(config, :output, new_output) + generate_docs(new_config) + end + end + test "generates an EPUB file with a standardized structure", %{tmp_dir: tmp_dir} = context do generate_docs_and_unzip(context, doc_config(context)) diff --git a/test/ex_doc/formatter/html/erlang_test.exs b/test/ex_doc/formatter/html/erlang_test.exs index 9ac95267d..341fdb287 100644 --- a/test/ex_doc/formatter/html/erlang_test.exs +++ b/test/ex_doc/formatter/html/erlang_test.exs @@ -5,6 +5,12 @@ defmodule ExDoc.Formatter.HTML.ErlangTest do @moduletag :otp_eep48 @moduletag :tmp_dir + setup %{tmp_dir: tmp_dir} do + output = tmp_dir <> "/doc" + File.mkdir!(output) + File.touch!("#{output}/.ex_doc") + end + test "smoke test", c do erlc(c, :foo, ~S""" %% @doc diff --git a/test/ex_doc/formatter/html/search_items_test.exs b/test/ex_doc/formatter/html/search_items_test.exs index eaa7d83d3..fadf2f242 100644 --- a/test/ex_doc/formatter/html/search_items_test.exs +++ b/test/ex_doc/formatter/html/search_items_test.exs @@ -4,6 +4,12 @@ defmodule ExDoc.Formatter.HTML.SearchItemsTest do @moduletag :tmp_dir + setup %{tmp_dir: tmp_dir} do + output = tmp_dir <> "/doc" + File.mkdir!(output) + File.touch!("#{output}/.ex_doc") + end + test "Elixir module", c do modules = elixirc(c, ~S''' diff --git a/test/ex_doc/formatter/html_test.exs b/test/ex_doc/formatter/html_test.exs index 7f18d44ce..f01979c1c 100644 --- a/test/ex_doc/formatter/html_test.exs +++ b/test/ex_doc/formatter/html_test.exs @@ -6,6 +6,12 @@ defmodule ExDoc.Formatter.HTMLTest do @moduletag :tmp_dir + setup %{tmp_dir: tmp_dir} do + output = tmp_dir <> "/html" + File.mkdir_p!(output) + File.touch!(output <> "/.ex_doc") + end + defp read_wildcard!(path) do [file] = Path.wildcard(path) File.read!(file) @@ -146,6 +152,18 @@ defmodule ExDoc.Formatter.HTMLTest do refute content_module =~ re[:index][:refresh] end + test "fails if trying to write to existing directory", context do + assert_raise RuntimeError, ~r/Directory already exists and is not managed by ex_doc/, fn -> + config = doc_config(context) + + new_output = config[:output] <> "/new-dir" + File.mkdir_p!(new_output) + + new_config = Keyword.put(config, :output, new_output) + generate_docs(new_config) + end + end + test "allows to set the authors of the document", %{tmp_dir: tmp_dir} = context do generate_docs(doc_config(context, authors: ["John Doe", "Jane Doe"])) content_index = File.read!(tmp_dir <> "/html/api-reference.html") diff --git a/test/test_helper.exs b/test/test_helper.exs index 9ce5e3e4b..bf13c7992 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -22,6 +22,10 @@ defmodule TestHelper do def elixirc(context, filename \\ "nofile", code) do dir = context.tmp_dir + output_dir = context.tmp_dir <> "/html" + File.mkdir_p!(output_dir) + File.write!(output_dir <> "/.ex_doc", "") + src_path = Path.join([dir, filename]) src_path |> Path.dirname() |> File.mkdir_p!() File.write!(src_path, code) From 677fbb9ce115b2bb0cb06cb37d468df0236c4a4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20M=C3=BCller?= Date: Sun, 21 May 2023 18:54:39 -0300 Subject: [PATCH 2/9] Use single setup_output function for both html and epub --- lib/ex_doc/formatter/epub.ex | 30 +++++----------------- lib/ex_doc/formatter/html.ex | 50 +++++++++++++++++++++--------------- 2 files changed, 36 insertions(+), 44 deletions(-) diff --git a/lib/ex_doc/formatter/epub.ex b/lib/ex_doc/formatter/epub.ex index 7e38590ef..2e20ce890 100644 --- a/lib/ex_doc/formatter/epub.ex +++ b/lib/ex_doc/formatter/epub.ex @@ -12,7 +12,7 @@ defmodule ExDoc.Formatter.EPUB do def run(project_nodes, config) when is_map(config) do parent = config.output config = normalize_config(config) - setup_output(config, parent) + HTML.setup_output(config, &cleanup_output_dir/2, &create_output_dir/2, parent) project_nodes = HTML.render_all(project_nodes, ".xhtml", config, highlight_tag: "samp") @@ -44,30 +44,14 @@ defmodule ExDoc.Formatter.EPUB do Path.relative_to_cwd(epub) end - defp setup_output(config, parent) do - safety_path = Path.join(parent, ".ex_doc") - - cond do - File.exists?(safety_path) -> - File.rm_rf!(config.output) - mkdir_output!(config.output, parent) - - not File.exists?(parent) -> - mkdir_output!(config.output, parent) - - true -> - raise """ - ex_doc cannot output to #{config.output}: - Directory already exists and is not managed by ex_doc. - - Try giving an unexisting directory as `--output`. - """ - end + defp create_output_dir(root, config) do + File.mkdir_p!(Path.join(config.output, "OEBPS")) + File.touch!(Path.join(root, ".ex_doc")) end - defp mkdir_output!(path, parent) do - File.mkdir_p!(Path.join(path, "OEBPS")) - File.touch!(Path.join(parent, ".ex_doc")) + defp cleanup_output_dir(docs_root, config) do + File.rm_rf!(config.output) + create_output_dir(docs_root, config) end defp normalize_config(config) do diff --git a/lib/ex_doc/formatter/html.ex b/lib/ex_doc/formatter/html.ex index 05e1086fb..23b5c8674 100644 --- a/lib/ex_doc/formatter/html.ex +++ b/lib/ex_doc/formatter/html.ex @@ -16,7 +16,7 @@ defmodule ExDoc.Formatter.HTML do config = %{config | output: Path.expand(config.output)} build = Path.join(config.output, ".build") - output_setup(build, config) + setup_output(config, &cleanup_output_dir/2, &create_output_dir/2) project_nodes = render_all(project_nodes, ".html", config, []) extras = build_extras(config, ".html") @@ -146,29 +146,20 @@ defmodule ExDoc.Formatter.HTML do |> ExDoc.DocAST.highlight(language, opts) end - defp output_setup(build, config) do - safety_path = Path.join(config.output, ".ex_doc") + def setup_output(config, cleanup, create, root \\ nil) do + root = root || config.output + safety_path = Path.join(root, ".ex_doc") cond do - File.exists?(build) -> - build - |> File.read!() - |> String.split("\n", trim: true) - |> Enum.map(&Path.join(config.output, &1)) - |> Enum.each(&File.rm/1) + File.exists?(safety_path) and File.exists?(root) -> + cleanup.(root, config) - File.rm(build) - - File.exists?(safety_path) -> - File.rm_rf!(config.output) - mkdir_output!(config.output) - - not File.exists?(config.output) -> - mkdir_output!(config.output) + not File.exists?(root) -> + create.(root, config) true -> raise """ - ex_doc cannot output to #{config.output}: + ex_doc cannot output to #{root}: Directory already exists and is not managed by ex_doc. Try giving an unexisting directory as `--output`. @@ -176,9 +167,26 @@ defmodule ExDoc.Formatter.HTML do end end - defp mkdir_output!(path) do - File.mkdir_p!(path) - File.touch!(Path.join(path, ".ex_doc")) + defp create_output_dir(root, _config) do + File.mkdir_p!(root) + File.touch!(Path.join(root, ".ex_doc")) + end + + defp cleanup_output_dir(docs_root, config) do + build = Path.join(docs_root, ".build") + + if File.exists?(build) do + build + |> File.read!() + |> String.split("\n", trim: true) + |> Enum.map(&Path.join(docs_root, &1)) + |> Enum.each(&File.rm/1) + + File.rm(build) + else + File.rm_rf!(docs_root) + create_output_dir(docs_root, config) + end end defp generate_build(files, build) do From 6d56e7f522ae38bbdc2aa34c8dd4f15d28f29bd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20M=C3=BCller?= Date: Mon, 22 May 2023 08:41:45 -0300 Subject: [PATCH 3/9] Warn instead of raise and allow usage of empty directories --- lib/ex_doc/formatter/epub.ex | 7 ++++++- lib/ex_doc/formatter/html.ex | 27 +++++++++++++++---------- test/ex_doc/formatter/epub_test.exs | 31 +++++++++++++++++++++-------- test/ex_doc/formatter/html_test.exs | 31 +++++++++++++++++++++-------- 4 files changed, 68 insertions(+), 28 deletions(-) diff --git a/lib/ex_doc/formatter/epub.ex b/lib/ex_doc/formatter/epub.ex index 2e20ce890..d8f05e4a9 100644 --- a/lib/ex_doc/formatter/epub.ex +++ b/lib/ex_doc/formatter/epub.ex @@ -12,7 +12,12 @@ defmodule ExDoc.Formatter.EPUB do def run(project_nodes, config) when is_map(config) do parent = config.output config = normalize_config(config) - HTML.setup_output(config, &cleanup_output_dir/2, &create_output_dir/2, parent) + + HTML.setup_output( + parent, + &cleanup_output_dir(&1, config), + &create_output_dir(&1, config) + ) project_nodes = HTML.render_all(project_nodes, ".xhtml", config, highlight_tag: "samp") diff --git a/lib/ex_doc/formatter/html.ex b/lib/ex_doc/formatter/html.ex index 23b5c8674..9568aec99 100644 --- a/lib/ex_doc/formatter/html.ex +++ b/lib/ex_doc/formatter/html.ex @@ -16,7 +16,7 @@ defmodule ExDoc.Formatter.HTML do config = %{config | output: Path.expand(config.output)} build = Path.join(config.output, ".build") - setup_output(config, &cleanup_output_dir/2, &create_output_dir/2) + setup_output(config.output, &cleanup_output_dir(&1, config), &create_output_dir(&1, config)) project_nodes = render_all(project_nodes, ".html", config, []) extras = build_extras(config, ".html") @@ -146,29 +146,34 @@ defmodule ExDoc.Formatter.HTML do |> ExDoc.DocAST.highlight(language, opts) end - def setup_output(config, cleanup, create, root \\ nil) do - root = root || config.output + def setup_output(root, cleanup, create) do safety_path = Path.join(root, ".ex_doc") cond do File.exists?(safety_path) and File.exists?(root) -> - cleanup.(root, config) + cleanup.(root) not File.exists?(root) -> - create.(root, config) + create.(root) - true -> - raise """ - ex_doc cannot output to #{root}: - Directory already exists and is not managed by ex_doc. + File.ls!(root) == [] -> + add_safety_file(root) + :ok - Try giving an unexisting directory as `--output`. - """ + true -> + IO.warn( + "ExDoc is outputting to an existing directory. " <> + "Beware documentation output may be mixed with other entries" + ) end end defp create_output_dir(root, _config) do File.mkdir_p!(root) + add_safety_file(root) + end + + defp add_safety_file(root) do File.touch!(Path.join(root, ".ex_doc")) end diff --git a/test/ex_doc/formatter/epub_test.exs b/test/ex_doc/formatter/epub_test.exs index 3bf6da333..58c8c330c 100644 --- a/test/ex_doc/formatter/epub_test.exs +++ b/test/ex_doc/formatter/epub_test.exs @@ -103,16 +103,31 @@ defmodule ExDoc.Formatter.EPUBTest do assert File.regular?(tmp_dir <> "/epub/another_dir/#{doc_config(context)[:project]}.epub") end - test "fails if trying to write to existing directory", context do - assert_raise RuntimeError, ~r/Directory already exists and is not managed by ex_doc/, fn -> - config = doc_config(context) + test "succeeds if trying to write into an empty existing directory", context do + config = doc_config(context) - new_output = config[:output] <> "/new-dir" - File.mkdir_p!(new_output) + new_output = config[:output] <> "/new-dir" + File.mkdir_p!(new_output) - new_config = Keyword.put(config, :output, new_output) - generate_docs(new_config) - end + new_config = Keyword.put(config, :output, new_output) + + refute ExUnit.CaptureIO.capture_io(:stderr, fn -> + generate_docs(new_config) + end) =~ "ExDoc is outputting to an existing directory" + end + + test "warns if trying to write into existing directory with files", context do + config = doc_config(context) + new_output = config[:output] <> "/new-dir" + + File.mkdir_p!(new_output) + File.touch!(Path.join(new_output, "dummy-file")) + + new_config = Keyword.put(config, :output, new_output) + + assert ExUnit.CaptureIO.capture_io(:stderr, fn -> + generate_docs(new_config) + end) =~ "ExDoc is outputting to an existing directory" end test "generates an EPUB file with a standardized structure", %{tmp_dir: tmp_dir} = context do diff --git a/test/ex_doc/formatter/html_test.exs b/test/ex_doc/formatter/html_test.exs index f01979c1c..6c5344934 100644 --- a/test/ex_doc/formatter/html_test.exs +++ b/test/ex_doc/formatter/html_test.exs @@ -152,16 +152,31 @@ defmodule ExDoc.Formatter.HTMLTest do refute content_module =~ re[:index][:refresh] end - test "fails if trying to write to existing directory", context do - assert_raise RuntimeError, ~r/Directory already exists and is not managed by ex_doc/, fn -> - config = doc_config(context) + test "succeeds if trying to write into an empty existing directory", context do + config = doc_config(context) - new_output = config[:output] <> "/new-dir" - File.mkdir_p!(new_output) + new_output = config[:output] <> "/new-dir" + File.mkdir_p!(new_output) - new_config = Keyword.put(config, :output, new_output) - generate_docs(new_config) - end + new_config = Keyword.put(config, :output, new_output) + + refute ExUnit.CaptureIO.capture_io(:stderr, fn -> + generate_docs(new_config) + end) =~ "ExDoc is outputting to an existing directory" + end + + test "warns if trying to write into existing directory with files", context do + config = doc_config(context) + new_output = config[:output] <> "/new-dir" + + File.mkdir_p!(new_output) + File.touch!(Path.join(new_output, "dummy-file")) + + new_config = Keyword.put(config, :output, new_output) + + assert ExUnit.CaptureIO.capture_io(:stderr, fn -> + generate_docs(new_config) + end) =~ "ExDoc is outputting to an existing directory" end test "allows to set the authors of the document", %{tmp_dir: tmp_dir} = context do From 445b7e655ea62844c45e59248fdc1f01e8b8ddb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20M=C3=BCller?= Date: Tue, 30 May 2023 23:30:38 -0300 Subject: [PATCH 4/9] Create .exdoc file on existing directory warn --- lib/ex_doc/formatter/html.ex | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/ex_doc/formatter/html.ex b/lib/ex_doc/formatter/html.ex index 2c1ef3cbd..d02a06b38 100644 --- a/lib/ex_doc/formatter/html.ex +++ b/lib/ex_doc/formatter/html.ex @@ -165,6 +165,8 @@ defmodule ExDoc.Formatter.HTML do "ExDoc is outputting to an existing directory. " <> "Beware documentation output may be mixed with other entries" ) + + create.(root) end end From 20605817a3739c957e3ca0356f49dd5fff9f96b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20M=C3=BCller?= Date: Wed, 31 May 2023 11:59:55 -0300 Subject: [PATCH 5/9] Ensure warns only once on existing directory as output --- test/ex_doc/formatter/epub_test.exs | 5 +++++ test/ex_doc/formatter/html_test.exs | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/test/ex_doc/formatter/epub_test.exs b/test/ex_doc/formatter/epub_test.exs index 58c8c330c..859d41a6d 100644 --- a/test/ex_doc/formatter/epub_test.exs +++ b/test/ex_doc/formatter/epub_test.exs @@ -128,6 +128,11 @@ defmodule ExDoc.Formatter.EPUBTest do assert ExUnit.CaptureIO.capture_io(:stderr, fn -> generate_docs(new_config) end) =~ "ExDoc is outputting to an existing directory" + + # Warn only once + refute ExUnit.CaptureIO.capture_io(:stderr, fn -> + generate_docs(new_config) + end) =~ "ExDoc is outputting to an existing directory" end test "generates an EPUB file with a standardized structure", %{tmp_dir: tmp_dir} = context do diff --git a/test/ex_doc/formatter/html_test.exs b/test/ex_doc/formatter/html_test.exs index ee8489c94..98f769393 100644 --- a/test/ex_doc/formatter/html_test.exs +++ b/test/ex_doc/formatter/html_test.exs @@ -205,6 +205,11 @@ defmodule ExDoc.Formatter.HTMLTest do assert ExUnit.CaptureIO.capture_io(:stderr, fn -> generate_docs(new_config) end) =~ "ExDoc is outputting to an existing directory" + + # Warn only once + refute ExUnit.CaptureIO.capture_io(:stderr, fn -> + generate_docs(new_config) + end) =~ "ExDoc is outputting to an existing directory" end test "allows to set the authors of the document", %{tmp_dir: tmp_dir} = context do From 489dfaa99a27e6d12bdda7c85791b2b7db14dffe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20M=C3=BCller?= Date: Wed, 31 May 2023 12:27:32 -0300 Subject: [PATCH 6/9] Move formatter tests that deal with IO to new module --- test/ex_doc/formatter/epub_io_test.exs | 55 +++++++++++++++++++++++++ test/ex_doc/formatter/epub_test.exs | 32 --------------- test/ex_doc/formatter/html_io_test.exs | 57 ++++++++++++++++++++++++++ test/ex_doc/formatter/html_test.exs | 32 --------------- 4 files changed, 112 insertions(+), 64 deletions(-) create mode 100644 test/ex_doc/formatter/epub_io_test.exs create mode 100644 test/ex_doc/formatter/html_io_test.exs diff --git a/test/ex_doc/formatter/epub_io_test.exs b/test/ex_doc/formatter/epub_io_test.exs new file mode 100644 index 000000000..496389019 --- /dev/null +++ b/test/ex_doc/formatter/epub_io_test.exs @@ -0,0 +1,55 @@ +defmodule ExDoc.Formatter.EPUBIOTest do + use ExUnit.Case, async: false + + @moduletag :tmp_dir + + test "succeeds if trying to write into an empty existing directory", context do + config = doc_config(context) + + new_output = config[:output] <> "/new-dir" + File.mkdir_p!(new_output) + + new_config = Keyword.put(config, :output, new_output) + + refute ExUnit.CaptureIO.capture_io(:stderr, fn -> + generate_docs(new_config) + end) =~ "ExDoc is outputting to an existing directory" + end + + test "warns if trying to write into existing directory with files", context do + config = doc_config(context) + new_output = config[:output] <> "/new-dir" + + File.mkdir_p!(new_output) + File.touch!(Path.join(new_output, "dummy-file")) + + new_config = Keyword.put(config, :output, new_output) + + assert ExUnit.CaptureIO.capture_io(:stderr, fn -> + generate_docs(new_config) + end) =~ "ExDoc is outputting to an existing directory" + + # Warn only once + refute ExUnit.CaptureIO.capture_io(:stderr, fn -> + generate_docs(new_config) + end) =~ "ExDoc is outputting to an existing directory" + end + + defp generate_docs(config) do + config = Keyword.put_new(config, :skip_undefined_reference_warnings_on, ["Warnings"]) + ExDoc.generate_docs(config[:project], config[:version], config) + end + + defp doc_config(%{tmp_dir: tmp_dir} = _context) do + [ + app: :elixir, + project: "Elixir", + version: "1.0.1", + formatter: "epub", + output: tmp_dir <> "/epub", + source_beam: "test/tmp/beam", + extras: ["test/fixtures/README.md"], + skip_undefined_reference_warnings_on: ["Warnings"] + ] + end +end diff --git a/test/ex_doc/formatter/epub_test.exs b/test/ex_doc/formatter/epub_test.exs index 859d41a6d..c1f02225c 100644 --- a/test/ex_doc/formatter/epub_test.exs +++ b/test/ex_doc/formatter/epub_test.exs @@ -103,38 +103,6 @@ defmodule ExDoc.Formatter.EPUBTest do assert File.regular?(tmp_dir <> "/epub/another_dir/#{doc_config(context)[:project]}.epub") end - test "succeeds if trying to write into an empty existing directory", context do - config = doc_config(context) - - new_output = config[:output] <> "/new-dir" - File.mkdir_p!(new_output) - - new_config = Keyword.put(config, :output, new_output) - - refute ExUnit.CaptureIO.capture_io(:stderr, fn -> - generate_docs(new_config) - end) =~ "ExDoc is outputting to an existing directory" - end - - test "warns if trying to write into existing directory with files", context do - config = doc_config(context) - new_output = config[:output] <> "/new-dir" - - File.mkdir_p!(new_output) - File.touch!(Path.join(new_output, "dummy-file")) - - new_config = Keyword.put(config, :output, new_output) - - assert ExUnit.CaptureIO.capture_io(:stderr, fn -> - generate_docs(new_config) - end) =~ "ExDoc is outputting to an existing directory" - - # Warn only once - refute ExUnit.CaptureIO.capture_io(:stderr, fn -> - generate_docs(new_config) - end) =~ "ExDoc is outputting to an existing directory" - end - test "generates an EPUB file with a standardized structure", %{tmp_dir: tmp_dir} = context do generate_docs_and_unzip(context, doc_config(context)) diff --git a/test/ex_doc/formatter/html_io_test.exs b/test/ex_doc/formatter/html_io_test.exs new file mode 100644 index 000000000..06aa3fc2a --- /dev/null +++ b/test/ex_doc/formatter/html_io_test.exs @@ -0,0 +1,57 @@ +defmodule ExDoc.Formatter.HtmlIOTest do + use ExUnit.Case, async: false + + @moduletag :tmp_dir + + test "succeeds if trying to write into an empty existing directory", context do + config = doc_config(context) + + new_output = config[:output] <> "/new-dir" + File.mkdir_p!(new_output) + + new_config = Keyword.put(config, :output, new_output) + + refute ExUnit.CaptureIO.capture_io(:stderr, fn -> + generate_docs(new_config) + end) =~ "ExDoc is outputting to an existing directory" + end + + test "warns if trying to write into existing directory with files", context do + config = doc_config(context) + new_output = config[:output] <> "/new-dir" + + File.mkdir_p!(new_output) + File.touch!(Path.join(new_output, "dummy-file")) + + new_config = Keyword.put(config, :output, new_output) + + assert ExUnit.CaptureIO.capture_io(:stderr, fn -> + generate_docs(new_config) + end) =~ "ExDoc is outputting to an existing directory" + + # Warn only once + refute ExUnit.CaptureIO.capture_io(:stderr, fn -> + generate_docs(new_config) + end) =~ "ExDoc is outputting to an existing directory" + end + + defp generate_docs(config) do + config = Keyword.put_new(config, :skip_undefined_reference_warnings_on, ["Warnings"]) + ExDoc.generate_docs(config[:project], config[:version], config) + end + + defp doc_config(%{tmp_dir: tmp_dir} = _context) do + [ + apps: [:elixir], + project: "Elixir", + version: "1.0.1", + formatter: "html", + assets: "test/tmp/html_assets", + output: tmp_dir <> "/html", + source_beam: "test/tmp/beam", + source_url: "https://github.com/elixir-lang/elixir", + logo: "test/fixtures/elixir.png", + extras: [] + ] + end +end diff --git a/test/ex_doc/formatter/html_test.exs b/test/ex_doc/formatter/html_test.exs index 98f769393..9cde053da 100644 --- a/test/ex_doc/formatter/html_test.exs +++ b/test/ex_doc/formatter/html_test.exs @@ -180,38 +180,6 @@ defmodule ExDoc.Formatter.HTMLTest do refute content_module =~ re[:index][:refresh] end - test "succeeds if trying to write into an empty existing directory", context do - config = doc_config(context) - - new_output = config[:output] <> "/new-dir" - File.mkdir_p!(new_output) - - new_config = Keyword.put(config, :output, new_output) - - refute ExUnit.CaptureIO.capture_io(:stderr, fn -> - generate_docs(new_config) - end) =~ "ExDoc is outputting to an existing directory" - end - - test "warns if trying to write into existing directory with files", context do - config = doc_config(context) - new_output = config[:output] <> "/new-dir" - - File.mkdir_p!(new_output) - File.touch!(Path.join(new_output, "dummy-file")) - - new_config = Keyword.put(config, :output, new_output) - - assert ExUnit.CaptureIO.capture_io(:stderr, fn -> - generate_docs(new_config) - end) =~ "ExDoc is outputting to an existing directory" - - # Warn only once - refute ExUnit.CaptureIO.capture_io(:stderr, fn -> - generate_docs(new_config) - end) =~ "ExDoc is outputting to an existing directory" - end - test "allows to set the authors of the document", %{tmp_dir: tmp_dir} = context do generate_docs(doc_config(context, authors: ["John Doe", "Jane Doe"])) content_index = File.read!(tmp_dir <> "/html/api-reference.html") From 229c1636a94290805a8280af8944d84e39b7bbfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20M=C3=BCller?= Date: Thu, 1 Jun 2023 10:11:46 -0300 Subject: [PATCH 7/9] Simplify IO test modules --- test/ex_doc/formatter/epub_io_test.exs | 55 +++++++++---------------- test/ex_doc/formatter/html_io_test.exs | 57 +++++++++----------------- 2 files changed, 38 insertions(+), 74 deletions(-) diff --git a/test/ex_doc/formatter/epub_io_test.exs b/test/ex_doc/formatter/epub_io_test.exs index 496389019..9bca8bc88 100644 --- a/test/ex_doc/formatter/epub_io_test.exs +++ b/test/ex_doc/formatter/epub_io_test.exs @@ -3,53 +3,36 @@ defmodule ExDoc.Formatter.EPUBIOTest do @moduletag :tmp_dir - test "succeeds if trying to write into an empty existing directory", context do - config = doc_config(context) + test "succeeds if trying to write into an empty existing directory", %{tmp_dir: tmp_dir} do + File.mkdir!("#{tmp_dir}/doc") - new_output = config[:output] <> "/new-dir" - File.mkdir_p!(new_output) - - new_config = Keyword.put(config, :output, new_output) - - refute ExUnit.CaptureIO.capture_io(:stderr, fn -> - generate_docs(new_config) - end) =~ "ExDoc is outputting to an existing directory" + assert ExUnit.CaptureIO.capture_io(:stderr, fn -> + generate_docs(tmp_dir) + end) =~ "" end - test "warns if trying to write into existing directory with files", context do - config = doc_config(context) - new_output = config[:output] <> "/new-dir" - - File.mkdir_p!(new_output) - File.touch!(Path.join(new_output, "dummy-file")) - - new_config = Keyword.put(config, :output, new_output) + test "warns if trying to write into existing directory with files", %{tmp_dir: tmp_dir} do + File.mkdir!("#{tmp_dir}/doc") + File.touch!("#{tmp_dir}/doc/foo.txt") assert ExUnit.CaptureIO.capture_io(:stderr, fn -> - generate_docs(new_config) + generate_docs(tmp_dir) end) =~ "ExDoc is outputting to an existing directory" # Warn only once - refute ExUnit.CaptureIO.capture_io(:stderr, fn -> - generate_docs(new_config) - end) =~ "ExDoc is outputting to an existing directory" - end - - defp generate_docs(config) do - config = Keyword.put_new(config, :skip_undefined_reference_warnings_on, ["Warnings"]) - ExDoc.generate_docs(config[:project], config[:version], config) + assert ExUnit.CaptureIO.capture_io(:stderr, fn -> + generate_docs(tmp_dir) + end) =~ "" end - defp doc_config(%{tmp_dir: tmp_dir} = _context) do - [ - app: :elixir, - project: "Elixir", - version: "1.0.1", + defp generate_docs(tmp_dir) do + config = [ + app: :foo, formatter: "epub", - output: tmp_dir <> "/epub", - source_beam: "test/tmp/beam", - extras: ["test/fixtures/README.md"], - skip_undefined_reference_warnings_on: ["Warnings"] + output: "#{tmp_dir}/doc", + source_beam: "#{tmp_dir}/ebin", ] + + ExDoc.generate_docs("Foo", "1.0.0", config) end end diff --git a/test/ex_doc/formatter/html_io_test.exs b/test/ex_doc/formatter/html_io_test.exs index 06aa3fc2a..c7d224c12 100644 --- a/test/ex_doc/formatter/html_io_test.exs +++ b/test/ex_doc/formatter/html_io_test.exs @@ -3,55 +3,36 @@ defmodule ExDoc.Formatter.HtmlIOTest do @moduletag :tmp_dir - test "succeeds if trying to write into an empty existing directory", context do - config = doc_config(context) + test "succeeds if trying to write into an empty existing directory", %{tmp_dir: tmp_dir} do + File.mkdir!("#{tmp_dir}/doc") - new_output = config[:output] <> "/new-dir" - File.mkdir_p!(new_output) - - new_config = Keyword.put(config, :output, new_output) - - refute ExUnit.CaptureIO.capture_io(:stderr, fn -> - generate_docs(new_config) - end) =~ "ExDoc is outputting to an existing directory" + assert ExUnit.CaptureIO.capture_io(:stderr, fn -> + generate_docs(tmp_dir) + end) =~ "" end - test "warns if trying to write into existing directory with files", context do - config = doc_config(context) - new_output = config[:output] <> "/new-dir" - - File.mkdir_p!(new_output) - File.touch!(Path.join(new_output, "dummy-file")) - - new_config = Keyword.put(config, :output, new_output) + test "warns if trying to write into existing directory with files", %{tmp_dir: tmp_dir} do + File.mkdir!("#{tmp_dir}/doc") + File.touch!("#{tmp_dir}/doc/foo.txt") assert ExUnit.CaptureIO.capture_io(:stderr, fn -> - generate_docs(new_config) + generate_docs(tmp_dir) end) =~ "ExDoc is outputting to an existing directory" # Warn only once - refute ExUnit.CaptureIO.capture_io(:stderr, fn -> - generate_docs(new_config) - end) =~ "ExDoc is outputting to an existing directory" - end - - defp generate_docs(config) do - config = Keyword.put_new(config, :skip_undefined_reference_warnings_on, ["Warnings"]) - ExDoc.generate_docs(config[:project], config[:version], config) + assert ExUnit.CaptureIO.capture_io(:stderr, fn -> + generate_docs(tmp_dir) + end) =~ "" end - defp doc_config(%{tmp_dir: tmp_dir} = _context) do - [ - apps: [:elixir], - project: "Elixir", - version: "1.0.1", + defp generate_docs(tmp_dir) do + config = [ + app: :foo, formatter: "html", - assets: "test/tmp/html_assets", - output: tmp_dir <> "/html", - source_beam: "test/tmp/beam", - source_url: "https://github.com/elixir-lang/elixir", - logo: "test/fixtures/elixir.png", - extras: [] + output: "#{tmp_dir}/doc", + source_beam: "#{tmp_dir}/ebin", ] + + ExDoc.generate_docs("Foo", "1.0.0", config) end end From 85aa54b8e07f81f634d80ed8a03604483479ea95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20M=C3=BCller?= Date: Thu, 1 Jun 2023 10:12:36 -0300 Subject: [PATCH 8/9] Mix format --- test/ex_doc/formatter/epub_io_test.exs | 2 +- test/ex_doc/formatter/html_io_test.exs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/ex_doc/formatter/epub_io_test.exs b/test/ex_doc/formatter/epub_io_test.exs index 9bca8bc88..081866d71 100644 --- a/test/ex_doc/formatter/epub_io_test.exs +++ b/test/ex_doc/formatter/epub_io_test.exs @@ -30,7 +30,7 @@ defmodule ExDoc.Formatter.EPUBIOTest do app: :foo, formatter: "epub", output: "#{tmp_dir}/doc", - source_beam: "#{tmp_dir}/ebin", + source_beam: "#{tmp_dir}/ebin" ] ExDoc.generate_docs("Foo", "1.0.0", config) diff --git a/test/ex_doc/formatter/html_io_test.exs b/test/ex_doc/formatter/html_io_test.exs index c7d224c12..32eb07624 100644 --- a/test/ex_doc/formatter/html_io_test.exs +++ b/test/ex_doc/formatter/html_io_test.exs @@ -30,7 +30,7 @@ defmodule ExDoc.Formatter.HtmlIOTest do app: :foo, formatter: "html", output: "#{tmp_dir}/doc", - source_beam: "#{tmp_dir}/ebin", + source_beam: "#{tmp_dir}/ebin" ] ExDoc.generate_docs("Foo", "1.0.0", config) From b2b7a8aa70135bb8a2eeb78dc4b5cb6ecf03b668 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20M=C3=BCller?= Date: Thu, 1 Jun 2023 10:23:38 -0300 Subject: [PATCH 9/9] Use == instead of =~ in assertions --- test/ex_doc/formatter/epub_io_test.exs | 4 ++-- test/ex_doc/formatter/html_io_test.exs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/ex_doc/formatter/epub_io_test.exs b/test/ex_doc/formatter/epub_io_test.exs index 081866d71..086374790 100644 --- a/test/ex_doc/formatter/epub_io_test.exs +++ b/test/ex_doc/formatter/epub_io_test.exs @@ -8,7 +8,7 @@ defmodule ExDoc.Formatter.EPUBIOTest do assert ExUnit.CaptureIO.capture_io(:stderr, fn -> generate_docs(tmp_dir) - end) =~ "" + end) == "" end test "warns if trying to write into existing directory with files", %{tmp_dir: tmp_dir} do @@ -22,7 +22,7 @@ defmodule ExDoc.Formatter.EPUBIOTest do # Warn only once assert ExUnit.CaptureIO.capture_io(:stderr, fn -> generate_docs(tmp_dir) - end) =~ "" + end) == "" end defp generate_docs(tmp_dir) do diff --git a/test/ex_doc/formatter/html_io_test.exs b/test/ex_doc/formatter/html_io_test.exs index 32eb07624..8da38c2b2 100644 --- a/test/ex_doc/formatter/html_io_test.exs +++ b/test/ex_doc/formatter/html_io_test.exs @@ -8,7 +8,7 @@ defmodule ExDoc.Formatter.HtmlIOTest do assert ExUnit.CaptureIO.capture_io(:stderr, fn -> generate_docs(tmp_dir) - end) =~ "" + end) == "" end test "warns if trying to write into existing directory with files", %{tmp_dir: tmp_dir} do @@ -22,7 +22,7 @@ defmodule ExDoc.Formatter.HtmlIOTest do # Warn only once assert ExUnit.CaptureIO.capture_io(:stderr, fn -> generate_docs(tmp_dir) - end) =~ "" + end) == "" end defp generate_docs(tmp_dir) do