From eb3945e171ad6cd3cd8da765a7915a978f381379 Mon Sep 17 00:00:00 2001 From: Laszlo Bacsi Date: Wed, 1 Aug 2018 23:07:48 +0200 Subject: [PATCH 1/2] Format codebase and check formatting on CI --- .formatter.exs | 3 + .travis.yml | 5 +- lib/ex_doc.ex | 2 +- lib/ex_doc/cli.ex | 24 +++--- lib/ex_doc/formatter/epub.ex | 73 +++++++++------- lib/ex_doc/formatter/html.ex | 62 ++++++++------ lib/ex_doc/formatter/html/templates.ex | 77 ++++++++++------- lib/ex_doc/group_matcher.ex | 8 +- lib/ex_doc/markdown.ex | 13 +-- lib/ex_doc/markdown/earmark.ex | 17 ++-- mix.exs | 17 ++-- test/ex_doc/cli_test.exs | 87 ++++++++++---------- test/ex_doc/formatter/html/autolink_test.exs | 57 +++++++------ test/ex_doc/group_matcher_test.exs | 33 ++++---- test/ex_doc/markdown/cmark_test.exs | 3 +- test/ex_doc/markdown/earmark_test.exs | 3 +- test/ex_doc/retriever_test.exs | 8 +- test/ex_doc_test.exs | 48 +++++++---- test/fixtures/behaviour.ex | 2 +- test/fixtures/callbacks_no_docs.ex | 4 +- test/fixtures/types_and_specs.ex | 6 +- test/fixtures/umbrella/apps/bar/mix.exs | 6 +- test/fixtures/umbrella/apps/foo/mix.exs | 6 +- test/fixtures/umbrella/mix.exs | 6 +- test/test_helper.exs | 44 ++++++---- 25 files changed, 355 insertions(+), 259 deletions(-) create mode 100644 .formatter.exs diff --git a/.formatter.exs b/.formatter.exs new file mode 100644 index 000000000..682fc6c6b --- /dev/null +++ b/.formatter.exs @@ -0,0 +1,3 @@ +[ + inputs: ["{mix,.formatter}.exs", "{lib,test}/**/*.{ex,exs}"] +] diff --git a/.travis.yml b/.travis.yml index f5b922f41..a86237aaf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,11 +8,12 @@ notifications: before_script: - export DISPLAY=:99.0 - sh -e /etc/init.d/xvfb start + - mix local.hex --force + - mix deps.get env: - MIX_ENV=test script: - - mix do local.hex --force - - mix deps.get + - mix format --check-formatted - mix test - mix coveralls.travis - bash test/prerelease.sh diff --git a/lib/ex_doc.ex b/lib/ex_doc.ex index 1fbacf0fb..855ec4dc8 100644 --- a/lib/ex_doc.ex +++ b/lib/ex_doc.ex @@ -66,7 +66,7 @@ defmodule ExDoc do if Code.ensure_loaded?(modname) do modname else - raise "formatter module #{inspect argname} not found" + raise "formatter module #{inspect(argname)} not found" end end diff --git a/lib/ex_doc/cli.ex b/lib/ex_doc/cli.ex index 17ba53ba5..28a059e06 100644 --- a/lib/ex_doc/cli.ex +++ b/lib/ex_doc/cli.ex @@ -21,15 +21,14 @@ defmodule ExDoc.CLI do o: :output, r: :source_root, u: :source_url, - v: :version, + v: :version ], - switches: [ debug: :boolean, extra: :keep, language: :string, source_ref: :string, - version: :boolean, + version: :boolean ] ) @@ -41,18 +40,20 @@ defmodule ExDoc.CLI do end defp print_version do - IO.puts "ExDoc v#{ExDoc.version}" + IO.puts("ExDoc v#{ExDoc.version()}") end defp generate(args, opts, generator) do [project, version, source_beam] = parse_args(args) Code.prepend_path(source_beam) + opts = opts |> Keyword.put(:source_beam, source_beam) |> extra_files_options() |> merge_config() + generator.(project, version, opts) end @@ -62,6 +63,7 @@ defmodule ExDoc.CLI do opts |> Keyword.delete(:config) |> Keyword.merge(read_config(config)) + _ -> opts end @@ -80,7 +82,7 @@ defmodule ExDoc.CLI do {result, _} = Code.eval_string(config) unless is_list(result) do - raise "expected a keyword list from config file: #{inspect path}" + raise "expected a keyword list from config file: #{inspect(path)}" end result @@ -89,19 +91,19 @@ defmodule ExDoc.CLI do defp parse_args([_project, _version, _source_beam] = args), do: args defp parse_args([_, _, _ | _]) do - IO.puts "Too many arguments.\n" + IO.puts("Too many arguments.\n") print_usage() - exit {:shutdown, 1} + exit({:shutdown, 1}) end defp parse_args(_) do - IO.puts "Too few arguments.\n" + IO.puts("Too few arguments.\n") print_usage() - exit {:shutdown, 1} + exit({:shutdown, 1}) end defp print_usage do - IO.puts ~S""" + IO.puts(~S""" Usage: ex_doc PROJECT VERSION BEAMS [OPTIONS] @@ -158,6 +160,6 @@ defmodule ExDoc.CLI do https://github.com/elixir-lang/ecto/blob/v1.0/%{path}#L%{line} - """ + """) end end diff --git a/lib/ex_doc/formatter/epub.ex b/lib/ex_doc/formatter/epub.ex index e9c2da2fe..c2c6adc96 100644 --- a/lib/ex_doc/formatter/epub.ex +++ b/lib/ex_doc/formatter/epub.ex @@ -10,7 +10,7 @@ defmodule ExDoc.Formatter.EPUB do @doc """ Generate EPUB documentation for the given modules. """ - @spec run(list, ExDoc.Config.t) :: String.t + @spec run(list, ExDoc.Config.t()) :: String.t() def run(project_nodes, config) when is_map(config) do config = normalize_config(config) File.rm_rf!(config.output) @@ -53,6 +53,7 @@ defmodule ExDoc.Formatter.EPUB do config.output |> Path.expand() |> Path.join("#{config.project}") + %{config | output: output} end @@ -61,9 +62,11 @@ defmodule ExDoc.Formatter.EPUB do Enum.each(extras, fn %{id: id, title: title, content: content} -> output = "#{config.output}/OEBPS/#{id}.xhtml" html = Templates.extra_template(config, title, content) - if File.regular? output do - IO.puts :stderr, "warning: file #{Path.relative_to_cwd output} already exists" + + if File.regular?(output) do + IO.puts(:stderr, "warning: file #{Path.relative_to_cwd(output)} already exists") end + File.write!(output, html) end) end @@ -72,8 +75,8 @@ defmodule ExDoc.Formatter.EPUB do defp generate_content(config, nodes, uuid, datetime, static_files) do static_files = static_files - |> Enum.filter(fn(name) -> - String.contains?(name, "OEBPS") and config.output |> Path.join(name) |> File.regular?() + |> Enum.filter(fn name -> + String.contains?(name, "OEBPS") and config.output |> Path.join(name) |> File.regular?() end) |> Enum.map(&Path.relative_to(&1, "OEBPS")) @@ -90,17 +93,17 @@ defmodule ExDoc.Formatter.EPUB do {extras_by_group, groups} = extras |> Enum.with_index() - |> Enum.reduce({%{}, %{}}, fn({x, index}, {extras_by_group, groups}) -> - group = if x.group != "", do: x.group, else: "Extras" - extras_by_group = Map.update(extras_by_group, group, [x], &([x | &1])) - groups = Map.put_new(groups, group, index) - {extras_by_group, groups} - end) + |> Enum.reduce({%{}, %{}}, fn {x, index}, {extras_by_group, groups} -> + group = if x.group != "", do: x.group, else: "Extras" + extras_by_group = Map.update(extras_by_group, group, [x], &[x | &1]) + groups = Map.put_new(groups, group, index) + {extras_by_group, groups} + end) groups |> Map.to_list() |> List.keysort(1) - |> Enum.map(fn({k, _}) -> {k, Enum.reverse(Map.get(extras_by_group, k))} end) + |> Enum.map(fn {k, _} -> {k, Enum.reverse(Map.get(extras_by_group, k))} end) end defp generate_title(config) do @@ -115,43 +118,48 @@ defmodule ExDoc.Formatter.EPUB do end defp generate_epub(output) do - :zip.create(String.to_charlist("#{output}.epub"), - [{'mimetype', @mimetype} | files_to_add(output)], - compress: ['.css', '.xhtml', '.html', '.ncx', '.js', - '.opf', '.jpg', '.png', '.xml']) + :zip.create( + String.to_charlist("#{output}.epub"), + [{'mimetype', @mimetype} | files_to_add(output)], + compress: ['.css', '.xhtml', '.html', '.ncx', '.js', '.opf', '.jpg', '.png', '.xml'] + ) end ## Helpers defp default_assets do - [{Assets.dist(), "OEBPS/dist"}, - {Assets.metainfo(), "META-INF"}, - # Implementation Note: - # -------------------- - # In the EPUB format, extra files such as CSS and Javascript must - # be included inside the OEBPS directory. - # The file "OEBPS/file.ext" will be referenced inside pages as "file.ext". - # This means that as long as the assets are included with the "OEBPS" prefix, - # they will be accessible as if it were an HTML document. - # This allows us to reuse pretty much all logic between the `:epub` and the `:html` formats. - {Assets.markdown_processor_assets(), "OEBPS"}] + [ + {Assets.dist(), "OEBPS/dist"}, + {Assets.metainfo(), "META-INF"}, + # Implementation Note: + # -------------------- + # In the EPUB format, extra files such as CSS and Javascript must + # be included inside the OEBPS directory. + # The file "OEBPS/file.ext" will be referenced inside pages as "file.ext". + # This means that as long as the assets are included with the "OEBPS" prefix, + # they will be accessible as if it were an HTML document. + # This allows us to reuse pretty much all logic between the `:epub` and the `:html` formats. + {Assets.markdown_processor_assets(), "OEBPS"} + ] end defp files_to_add(path) do - Enum.reduce Path.wildcard(Path.join(path, "**/*")), [], fn file, acc -> + Enum.reduce(Path.wildcard(Path.join(path, "**/*")), [], fn file, acc -> case File.read(file) do {:ok, bin} -> [{file |> Path.relative_to(path) |> String.to_charlist(), bin} | acc] + {:error, _} -> acc end - end + end) end # Helper to format Erlang datetime tuple defp format_datetime do {{year, month, day}, {hour, min, sec}} = :calendar.universal_time() list = [year, month, day, hour, min, sec] + "~4..0B-~2..0B-~2..0BT~2..0B:~2..0B:~2..0BZ" |> :io_lib.format(list) |> IO.iodata_to_binary() @@ -169,7 +177,10 @@ defmodule ExDoc.Formatter.EPUB do bin = <> <> = bin - Enum.map_join([<>, <>, <>, <>, <>], <<45>>, - &(Base.encode16(&1, case: :lower))) + Enum.map_join( + [<>, <>, <>, <>, <>], + <<45>>, + &Base.encode16(&1, case: :lower) + ) end end diff --git a/lib/ex_doc/formatter/html.ex b/lib/ex_doc/formatter/html.ex index 0586243e1..153740429 100644 --- a/lib/ex_doc/formatter/html.ex +++ b/lib/ex_doc/formatter/html.ex @@ -11,7 +11,7 @@ defmodule ExDoc.Formatter.HTML do @doc """ Generate HTML documentation for the given modules. """ - @spec run(list, ExDoc.Config.t) :: String.t + @spec run(list, ExDoc.Config.t()) :: String.t() def run(project_nodes, config) when is_map(config) do config = normalize_config(config) config = %{config | output: Path.expand(config.output)} @@ -28,46 +28,49 @@ defmodule ExDoc.Formatter.HTML do tasks: filter_list(:task, linked) } - extras = - [build_api_reference(nodes_map, config) | - build_extras(config, autolink)] + extras = [ + build_api_reference(nodes_map, config) + | build_extras(config, autolink) + ] assets_dir = "assets" static_files = generate_assets(config, assets_dir, default_assets(config)) generated_files = generate_sidebar_items(nodes_map, extras, config) ++ - generate_extras(nodes_map, extras, config) ++ - generate_logo(assets_dir, config) ++ - generate_search(nodes_map, config) ++ - generate_not_found(nodes_map, config) ++ - generate_list(nodes_map.modules, nodes_map, config) ++ - generate_list(nodes_map.exceptions, nodes_map, config) ++ - generate_list(nodes_map.tasks, nodes_map, config) ++ - generate_index(config) + generate_extras(nodes_map, extras, config) ++ + generate_logo(assets_dir, config) ++ + generate_search(nodes_map, config) ++ + generate_not_found(nodes_map, config) ++ + generate_list(nodes_map.modules, nodes_map, config) ++ + generate_list(nodes_map.exceptions, nodes_map, config) ++ + generate_list(nodes_map.tasks, nodes_map, config) ++ generate_index(config) generate_build(static_files ++ generated_files, build) config.output |> Path.join("index.html") |> Path.relative_to_cwd() end defp normalize_config(%{main: "index"}) do - raise ArgumentError, message: ~S("main" cannot be set to "index", otherwise it will recursively link to itself) + raise ArgumentError, + message: ~S("main" cannot be set to "index", otherwise it will recursively link to itself) end + defp normalize_config(%{main: main} = config) do %{config | main: main || @main} end defp output_setup(build, config) do - if File.exists? build do + if File.exists?(build) do build - |> File.read! + |> File.read!() |> String.split("\n", trim: true) |> Enum.map(&Path.join(config.output, &1)) |> Enum.each(&File.rm/1) - File.rm build + + File.rm(build) else - File.rm_rf! config.output - File.mkdir_p! config.output + File.rm_rf!(config.output) + File.mkdir_p!(config.output) end end @@ -104,7 +107,7 @@ defmodule ExDoc.Formatter.HTML do digest = content - |> :erlang.md5 + |> :erlang.md5() |> Base.encode16(case: :lower) |> binary_part(0, 10) @@ -121,8 +124,9 @@ defmodule ExDoc.Formatter.HTML do html = Templates.extra_template(config, title, nodes_map, content) if File.regular?(output) do - IO.puts :stderr, "warning: file #{Path.relative_to_cwd output} already exists" + IO.puts(:stderr, "warning: file #{Path.relative_to_cwd(output)} already exists") end + File.write!(output, html) filename end) @@ -154,6 +158,7 @@ defmodule ExDoc.Formatter.HTML do Enum.flat_map(sources, fn {files, dir} -> target_dir = Path.join(config.output, dir) File.mkdir(target_dir) + Enum.map(files, fn {name, content} -> target = Path.join(target_dir, name) File.write(target, content) @@ -164,9 +169,12 @@ defmodule ExDoc.Formatter.HTML do defp default_assets(config) do debug = if config.debug, do: [{Assets.debug(), "dist"}], else: [] - [{Assets.dist(), "dist"}, - {Assets.fonts(), "fonts"}, - {Assets.markdown_processor_assets(), ""} | debug] + + [ + {Assets.dist(), "dist"}, + {Assets.fonts(), "fonts"}, + {Assets.markdown_processor_assets(), ""} | debug + ] end defp build_api_reference(nodes_map, config) do @@ -204,7 +212,7 @@ defmodule ExDoc.Formatter.HTML do |> File.read!() |> Autolink.project_doc(autolink) - group = GroupMatcher.match_extra groups, input + group = GroupMatcher.match_extra(groups, input) html_content = Markdown.to_html(content, file: input, line: 1) title = title || extract_title(html_content) || input_to_title(input) @@ -262,6 +270,7 @@ defmodule ExDoc.Formatter.HTML do def generate_logo(_dir, %{logo: nil}) do [] end + def generate_logo(dir, %{output: output, logo: logo}) do extname = logo @@ -281,14 +290,15 @@ defmodule ExDoc.Formatter.HTML do defp generate_redirect(filename, config, redirect_to) do unless File.regular?("#{config.output}/#{redirect_to}") do - IO.puts :stderr, "warning: #{filename} redirects to #{redirect_to}, which does not exist" + IO.puts(:stderr, "warning: #{filename} redirects to #{redirect_to}, which does not exist") end + content = Templates.redirect_template(config, redirect_to) File.write!("#{config.output}/#{filename}", content) end def filter_list(:module, nodes) do - Enum.filter(nodes, ¬(&1.type in [:exception, :impl, :task])) + Enum.filter(nodes, &(not (&1.type in [:exception, :impl, :task]))) end def filter_list(type, nodes) do diff --git a/lib/ex_doc/formatter/html/templates.ex b/lib/ex_doc/formatter/html/templates.ex index 80afb1482..2505f7333 100644 --- a/lib/ex_doc/formatter/html/templates.ex +++ b/lib/ex_doc/formatter/html/templates.ex @@ -16,9 +16,11 @@ defmodule ExDoc.Formatter.HTML.Templates do def get_specs(%ExDoc.TypeNode{spec: spec}) do [spec] end + def get_specs(%ExDoc.FunctionNode{specs: specs}) when is_list(specs) do - presence specs + presence(specs) end + def get_specs(_node) do nil end @@ -29,6 +31,7 @@ defmodule ExDoc.Formatter.HTML.Templates do def get_defaults(%{defaults: defaults}) do defaults end + def get_defaults(_) do [] end @@ -39,6 +42,7 @@ defmodule ExDoc.Formatter.HTML.Templates do def to_html(nil, %{source_path: _, doc_line: _}) do nil end + def to_html(doc, %{source_path: file, doc_line: line}) when is_binary(doc) do ExDoc.Markdown.to_html(doc, file: file, line: line + 1) end @@ -54,13 +58,14 @@ defmodule ExDoc.Formatter.HTML.Templates do Generate a link id """ def link_id(module_node), do: link_id(module_node.id, module_node.type) + def link_id(id, type) do case type do :macrocallback -> "c:#{id}" - :callback -> "c:#{id}" - :type -> "t:#{id}" - :opaque -> "t:#{id}" - _ -> "#{id}" + :callback -> "c:#{id}" + :type -> "t:#{id}" + :opaque -> "t:#{id}" + _ -> "#{id}" end end @@ -69,8 +74,10 @@ defmodule ExDoc.Formatter.HTML.Templates do """ def module_title(%{type: :task, title: title}), do: "mix " <> title + def module_title(%{type: :module, title: title}), do: title + def module_title(%{type: type, title: title}), do: title <> " #{type}" @@ -80,11 +87,12 @@ defmodule ExDoc.Formatter.HTML.Templates do If `doc` is `nil`, it returns `nil`. """ - @spec synopsis(String.t) :: String.t + @spec synopsis(String.t()) :: String.t() @spec synopsis(nil) :: nil def synopsis(nil), do: nil - def synopsis(""), do: "" + def synopsis(""), do: "" + def synopsis(doc) when is_binary(doc) do doc |> String.split(~r/\n\s*\n/) @@ -94,15 +102,16 @@ defmodule ExDoc.Formatter.HTML.Templates do |> String.trim_trailing() end - defp presence([]), do: nil + defp presence([]), do: nil defp presence(other), do: other @doc false def h(binary) do escape_map = [{"&", "&"}, {"<", "<"}, {">", ">"}, {~S("), """}] - Enum.reduce escape_map, binary, fn({pattern, escape}, acc) -> + + Enum.reduce(escape_map, binary, fn {pattern, escape}, acc -> String.replace(acc, pattern, escape) - end + end) end @doc false @@ -120,8 +129,7 @@ defmodule ExDoc.Formatter.HTML.Templates do Create a JS object which holds all the items displayed in the sidebar area """ def create_sidebar_items(nodes_map, extras) do - nodes_map = - [sidebar_items_extras(extras) | Enum.map(nodes_map, &sidebar_items_keys/1)] + nodes_map = [sidebar_items_extras(extras) | Enum.map(nodes_map, &sidebar_items_keys/1)] "sidebarNodes={#{Enum.join(nodes_map, ",")}}" end @@ -130,6 +138,7 @@ defmodule ExDoc.Formatter.HTML.Templates do extras |> Enum.map(&sidebar_items_extra/1) |> Enum.join(",") + ~s/"extras":[#{keys}]/ end @@ -138,6 +147,7 @@ defmodule ExDoc.Formatter.HTML.Templates do value |> Enum.map(&sidebar_items_node/1) |> Enum.join(",") + ~s/"#{id}":[#{keys}]/ end @@ -146,6 +156,7 @@ defmodule ExDoc.Formatter.HTML.Templates do content |> extract_headers |> Enum.map_join(",", fn {header, anchor} -> sidebar_items_object(header, anchor) end) + ~s/{"id":"#{id}","title":"#{title}","group":"#{group}","headers":[#{headers}]}/ end @@ -156,7 +167,7 @@ defmodule ExDoc.Formatter.HTML.Templates do |> Regex.scan(content, capture: :all_but_first) |> List.flatten() |> Enum.filter(&(&1 != "")) - |> Enum.map(&(String.replace(&1, @clean_html_regex, ""))) + |> Enum.map(&String.replace(&1, @clean_html_regex, "")) |> Enum.map(&{&1, header_to_id(&1)}) end @@ -168,16 +179,20 @@ defmodule ExDoc.Formatter.HTML.Templates do |> Enum.map_join(",", &sidebar_items_by_type/1) if items == "" do - ~s/{"id":#{inspect(module_node.id)},"title":#{inspect(module_node.title)},"group":"#{module_node.group}"}/ + ~s/{"id":#{inspect(module_node.id)},"title":#{inspect(module_node.title)}/ <> + ~s/,"group":"#{module_node.group}"}/ else - ~s/{"id":#{inspect(module_node.id)},"title":#{inspect(module_node.title)},"group":"#{module_node.group}",#{items}}/ + ~s/{"id":#{inspect(module_node.id)},"title":#{inspect(module_node.title)}/ <> + ~s/,"group":"#{module_node.group}",#{items}}/ end end defp sidebar_items_by_type({type, docs}) do - objects = Enum.map_join(docs, ",", fn doc -> - sidebar_items_object(doc.id, link_id(doc)) - end) + objects = + Enum.map_join(docs, ",", fn doc -> + sidebar_items_object(doc.id, link_id(doc)) + end) + ~s/"#{type}":[#{objects}]/ end @@ -187,9 +202,9 @@ defmodule ExDoc.Formatter.HTML.Templates do def module_summary(module_node) do %{ - callbacks: Enum.filter(module_node.docs, & &1.type in [:callback, :macrocallback]), - functions: Enum.filter(module_node.docs, & &1.type in [:function, :macro]), - guards: Enum.filter(module_node.docs, & &1.type in [:guard]), + callbacks: Enum.filter(module_node.docs, &(&1.type in [:callback, :macrocallback])), + functions: Enum.filter(module_node.docs, &(&1.type in [:function, :macro])), + guards: Enum.filter(module_node.docs, &(&1.type in [:guard])), types: module_node.typespecs } end @@ -214,13 +229,15 @@ defmodule ExDoc.Formatter.HTML.Templates do |> relative_asset(output, pattern) end - defp relative_asset([], output, pattern), do: raise "could not find matching #{output}/#{pattern}" - defp relative_asset([h|_], output, _pattern), do: Path.relative_to(h, output) + defp relative_asset([], output, pattern), + do: raise("could not find matching #{output}/#{pattern}") + + defp relative_asset([h | _], output, _pattern), do: Path.relative_to(h, output) @doc """ Extract a linkable ID from a heading """ - @spec header_to_id(String.t) :: String.t + @spec header_to_id(String.t()) :: String.t() def header_to_id(header) do header |> String.replace(@clean_html_regex, "") @@ -236,9 +253,10 @@ defmodule ExDoc.Formatter.HTML.Templates do prefixed with `prefix`. """ @heading_regex ~r/<(h[23]).*?>(.*?)<\/\1>/m - @spec link_headings(String.t, Regex.t, String.t) :: String.t + @spec link_headings(String.t(), Regex.t(), String.t()) :: String.t() def link_headings(content, regex \\ @heading_regex, prefix \\ "") def link_headings(nil, _, _), do: nil + def link_headings(content, regex, prefix) do Regex.replace(regex, content, fn match, tag, title -> link_heading(match, tag, title, header_to_id(title), prefix) @@ -246,6 +264,7 @@ defmodule ExDoc.Formatter.HTML.Templates do end defp link_heading(match, _tag, _title, "", _prefix), do: match + defp link_heading(_match, tag, title, id, prefix) do """ <#{tag} id="#{prefix}#{id}" class="section-heading"> @@ -276,12 +295,12 @@ defmodule ExDoc.Formatter.HTML.Templates do sidebar_template: [:config, :nodes_map], summary_template: [:name, :nodes], summary_entry_template: [:module_node], - redirect_template: [:config, :redirect_to], + redirect_template: [:config, :redirect_to] ] - Enum.each templates, fn({name, args}) -> + Enum.each(templates, fn {name, args} -> filename = Path.expand("templates/#{name}.eex", __DIR__) @doc false - EEx.function_from_file :def, name, filename, args, trim: true - end + EEx.function_from_file(:def, name, filename, args, trim: true) + end) end diff --git a/lib/ex_doc/group_matcher.ex b/lib/ex_doc/group_matcher.ex index 10ca93ea6..ec04908ae 100644 --- a/lib/ex_doc/group_matcher.ex +++ b/lib/ex_doc/group_matcher.ex @@ -1,7 +1,7 @@ defmodule ExDoc.GroupMatcher do @moduledoc false - @type pattern :: Regex.t | module() | String.t + @type pattern :: Regex.t() | module() | String.t() @type patterns :: pattern | [pattern] @type group_patterns :: keyword(patterns) @@ -15,7 +15,7 @@ defmodule ExDoc.GroupMatcher do @doc """ Finds a matching group for the given module name or id. """ - @spec match_module(group_patterns, module(), String.t) :: atom() | nil + @spec match_module(group_patterns, module(), String.t()) :: atom() | nil def match_module(group_patterns, module, id) do match_group_patterns(group_patterns, fn pattern -> case pattern do @@ -29,7 +29,7 @@ defmodule ExDoc.GroupMatcher do @doc """ Finds a matching group for the given extra filename """ - @spec match_extra(group_patterns, String.t) :: atom() | nil + @spec match_extra(group_patterns, String.t()) :: atom() | nil def match_extra(group_patterns, filename) do match_group_patterns(group_patterns, fn pattern -> case pattern do @@ -41,7 +41,7 @@ defmodule ExDoc.GroupMatcher do defp match_group_patterns(group_patterns, matcher) do Enum.find_value(group_patterns, fn {group, patterns} -> - patterns = List.wrap patterns + patterns = List.wrap(patterns) Enum.any?(patterns, matcher) && group end) end diff --git a/lib/ex_doc/markdown.ex b/lib/ex_doc/markdown.ex index 33ae32c39..99d3640c8 100644 --- a/lib/ex_doc/markdown.ex +++ b/lib/ex_doc/markdown.ex @@ -18,7 +18,7 @@ defmodule ExDoc.Markdown do @doc """ Converts markdown into HTML. """ - @callback to_html(String.t, Keyword.t) :: String.t + @callback to_html(String.t(), Keyword.t()) :: String.t() @doc """ Assets specific to the markdown implementation. @@ -53,7 +53,7 @@ defmodule ExDoc.Markdown do end """ - @callback assets(atom) :: [{String.t, String.t}] + @callback assets(atom) :: [{String.t(), String.t()}] @doc """ Literal content to be written to the file just before the closing head tag. @@ -70,7 +70,7 @@ defmodule ExDoc.Markdown do end """ - @callback before_closing_head_tag(atom) :: String.t + @callback before_closing_head_tag(atom) :: String.t() @doc """ Literal content to be written to the file just before the closing body tag. @@ -87,7 +87,7 @@ defmodule ExDoc.Markdown do end """ - @callback before_closing_body_tag(atom) :: String.t + @callback before_closing_body_tag(atom) :: String.t() @doc """ A function that accepts configuration options and configures the markdown processor. @@ -123,6 +123,7 @@ defmodule ExDoc.Markdown do case Application.fetch_env(:ex_doc, @markdown_processor_key) do {:ok, processor} -> processor + :error -> processor = find_markdown_processor() || raise_no_markdown_processor() put_markdown_processor(processor) @@ -146,9 +147,9 @@ defmodule ExDoc.Markdown do end defp find_markdown_processor do - Enum.find @markdown_processors, fn module -> + Enum.find(@markdown_processors, fn module -> Code.ensure_loaded?(module) && module.available? - end + end) end defp raise_no_markdown_processor do diff --git a/lib/ex_doc/markdown/earmark.ex b/lib/ex_doc/markdown/earmark.ex index b4e1cd7b4..b0a427343 100644 --- a/lib/ex_doc/markdown/earmark.ex +++ b/lib/ex_doc/markdown/earmark.ex @@ -17,8 +17,7 @@ defmodule ExDoc.Markdown.Earmark do Check if the Earmark Markdown parser module is available. """ def available? do - match?({:ok, _}, Application.ensure_all_started(:earmark)) and - Code.ensure_loaded?(Earmark) + match?({:ok, _}, Application.ensure_all_started(:earmark)) and Code.ensure_loaded?(Earmark) end @doc """ @@ -40,12 +39,14 @@ defmodule ExDoc.Markdown.Earmark do def to_html(text, opts) do options = struct(Earmark.Options, - gfm: Keyword.get(opts, :gfm, true), - line: Keyword.get(opts, :line, 1), - file: Keyword.get(opts, :file), - breaks: Keyword.get(opts, :breaks, false), - smartypants: Keyword.get(opts, :smartypants, true), - plugins: Keyword.get(opts, :plugins, %{})) + gfm: Keyword.get(opts, :gfm, true), + line: Keyword.get(opts, :line, 1), + file: Keyword.get(opts, :file), + breaks: Keyword.get(opts, :breaks, false), + smartypants: Keyword.get(opts, :smartypants, true), + plugins: Keyword.get(opts, :plugins, %{}) + ) + text |> Earmark.as_html!(options) |> ExDoc.Highlighter.highlight_code_blocks() diff --git a/mix.exs b/mix.exs index f084dc59b..3acc1644d 100644 --- a/mix.exs +++ b/mix.exs @@ -18,7 +18,7 @@ defmodule ExDoc.Mixfile do description: "ExDoc is a documentation generation tool for Elixir", xref: [exclude: [Cmark]], docs: docs() - ] + ] end def application do @@ -43,9 +43,15 @@ defmodule ExDoc.Mixfile do end defp package do - [ + [ licenses: ["Apache 2.0"], - maintainers: ["José Valim", "Eksperimental", "Milton Mazzarri", "Friedel Ziegelmayer", "Dmitry"], + maintainers: [ + "José Valim", + "Eksperimental", + "Milton Mazzarri", + "Friedel Ziegelmayer", + "Dmitry" + ], files: ["formatters", "lib", "mix.exs", "LICENSE", "CHANGELOG.md", "README.md"], links: %{ "GitHub" => "https://github.com/elixir-lang/ex_doc", @@ -67,12 +73,11 @@ defmodule ExDoc.Mixfile do source_ref: "v#{@version}", source_url: "https://github.com/elixir-lang/ex_doc", groups_for_modules: [ - "Markdown": [ + Markdown: [ ExDoc.Markdown, ExDoc.Markdown.Cmark, ExDoc.Markdown.Earmark ], - "Formatter API": [ ExDoc.Config, ExDoc.Formatter.EPUB, @@ -80,7 +85,7 @@ defmodule ExDoc.Mixfile do ExDoc.Formatter.HTML.Autolink, ExDoc.FunctionNode, ExDoc.ModuleNode, - ExDoc.TypeNode, + ExDoc.TypeNode ] ] ] diff --git a/test/ex_doc/cli_test.exs b/test/ex_doc/cli_test.exs index 2f009edfc..d6c3cd0bc 100644 --- a/test/ex_doc/cli_test.exs +++ b/test/ex_doc/cli_test.exs @@ -19,8 +19,7 @@ defmodule ExDoc.CLITest do assert project == "ExDoc" assert version == "1.2.3" - assert Enum.sort(opts) == - [extra_section: "Guides", extras: ["README.md"], source_beam: "..."] + assert Enum.sort(opts) == [extra_section: "Guides", extras: ["README.md"], source_beam: "..."] after File.rm!("test.config") end @@ -33,22 +32,21 @@ defmodule ExDoc.CLITest do test "config must be a keyword list" do File.write!("test.config", ~s(%{"extras" => "README.md"})) - assert_raise RuntimeError, - ~S(expected a keyword list from config file: "test.config"), fn -> - run(["ExDoc", "1.2.3", "...", "-c", "test.config"]) - end + assert_raise RuntimeError, ~S(expected a keyword list from config file: "test.config"), fn -> + run(["ExDoc", "1.2.3", "...", "-c", "test.config"]) + end after File.rm!("test.config") end test "version" do assert capture_io(fn -> - run(["--version"]) - end) == "ExDoc v#{ExDoc.version}\n" + run(["--version"]) + end) == "ExDoc v#{ExDoc.version()}\n" assert capture_io(fn -> - run(["-v"]) - end) == "ExDoc v#{ExDoc.version}\n" + run(["-v"]) + end) == "ExDoc v#{ExDoc.version()}\n" end test "too many arguments" do @@ -70,44 +68,47 @@ defmodule ExDoc.CLITest do test "arguments that are not aliased" do File.write!("not_aliased.config", ~s([key: "val"])) - args = [ - "ExDoc", "1.2.3", "ebin", - "--config", "not_aliased.config", - "--output", "html", - "--formatter", "html", - "--filter-prefix", "prefix_", - "--source-root", "./", - "--source-url", "http://example.com/username/project", - "--source-ref", "abcdefg", - "--main", "Main", - "--homepage-url", "http://example.com", - "--extra", "README.md", "--extra", "Foo", "--extra", "Bar", - "--extra-section", "Extra", - "--assets", "foo.css", - "--logo", "logo.png", - "--canonical", "http://example.com/project" - ] + args = ~w( + ExDoc 1.2.3 ebin + --config not_aliased.config + --output html + --formatter html + --filter-prefix prefix_ + --source-root ./ + --source-url http://example.com/username/project + --source-ref abcdefg + --main Main + --homepage-url http://example.com + --extra README.md + --extra Foo + --extra Bar + --extra-section Extra + --assets foo.css + --logo logo.png + --canonical http://example.com/project + ) {project, version, opts} = run(args) assert project == "ExDoc" assert version == "1.2.3" + assert Enum.sort(opts) == [ - assets: "foo.css", - canonical: "http://example.com/project", - extra_section: "Extra", - extras: ["README.md", "Foo", "Bar"], - filter_prefix: "prefix_", - formatter: "html", - homepage_url: "http://example.com", - key: "val", - logo: "logo.png", - main: "Main", - output: "html", - source_beam: "ebin", - source_ref: "abcdefg", - source_root: "./", - source_url: "http://example.com/username/project", - ] + assets: "foo.css", + canonical: "http://example.com/project", + extra_section: "Extra", + extras: ["README.md", "Foo", "Bar"], + filter_prefix: "prefix_", + formatter: "html", + homepage_url: "http://example.com", + key: "val", + logo: "logo.png", + main: "Main", + output: "html", + source_beam: "ebin", + source_ref: "abcdefg", + source_root: "./", + source_url: "http://example.com/username/project" + ] after File.rm!("not_aliased.config") end diff --git a/test/ex_doc/formatter/html/autolink_test.exs b/test/ex_doc/formatter/html/autolink_test.exs index 0d418079a..f7633c280 100644 --- a/test/ex_doc/formatter/html/autolink_test.exs +++ b/test/ex_doc/formatter/html/autolink_test.exs @@ -7,17 +7,14 @@ defmodule ExDoc.Formatter.HTML.AutolinkTest do describe "local" do test "autolinks fun/arity in docs" do - assert Autolink.locals("`example/2`", ["example/2"]) == - "[`example/2`](#example/2)" + assert Autolink.locals("`example/2`", ["example/2"]) == "[`example/2`](#example/2)" - assert Autolink.locals("`__ENV__/0`", ["__ENV__/0"]) == - "[`__ENV__/0`](#__ENV__/0)" + assert Autolink.locals("`__ENV__/0`", ["__ENV__/0"]) == "[`__ENV__/0`](#__ENV__/0)" assert Autolink.locals("`example/2` then `example/2`", ["example/2"]) == "[`example/2`](#example/2) then [`example/2`](#example/2)" - assert Autolink.locals("` spaces/0 `", ["spaces/0"]) == - "[`spaces/0`](#spaces/0)" + assert Autolink.locals("` spaces/0 `", ["spaces/0"]) == "[`spaces/0`](#spaces/0)" assert Autolink.locals("`example/1` and `example/2`", ["example/1", "example/2"]) == "[`example/1`](#example/1) and [`example/2`](#example/2)" @@ -95,21 +92,20 @@ defmodule ExDoc.Formatter.HTML.AutolinkTest do assert Autolink.elixir_functions("`MyModule.example/2`", ["MyModule.example/2"]) == "[`MyModule.example/2`](MyModule.html#example/2)" - assert Autolink.elixir_functions("`MyModule.Nested.example/2`", ["MyModule.Nested.example/2"]) == - "[`MyModule.Nested.example/2`](MyModule.Nested.html#example/2)" + assert Autolink.elixir_functions("`MyModule.Nested.example/2`", [ + "MyModule.Nested.example/2" + ]) == "[`MyModule.Nested.example/2`](MyModule.Nested.html#example/2)" - assert Autolink.elixir_functions( - "`Mod.example/2` then `Mod.example/2`", - ["Mod.example/2"] - ) == "[`Mod.example/2`](Mod.html#example/2) then [`Mod.example/2`](Mod.html#example/2)" + assert Autolink.elixir_functions("`Mod.example/2` then `Mod.example/2`", ["Mod.example/2"]) == + "[`Mod.example/2`](Mod.html#example/2) then [`Mod.example/2`](Mod.html#example/2)" assert Autolink.elixir_functions("` MyModule.spaces/0 `", ["MyModule.spaces/0"]) == "[`MyModule.spaces/0`](MyModule.html#spaces/0)" - assert Autolink.elixir_functions( - "`ModA.example/1` and `ModB.example/2`", - ["ModA.example/1", "ModB.example/2"] - ) == + assert Autolink.elixir_functions("`ModA.example/1` and `ModB.example/2`", [ + "ModA.example/1", + "ModB.example/2" + ]) == "[`ModA.example/1`](ModA.html#example/1) and [`ModB.example/2`](ModB.html#example/2)" assert Autolink.elixir_functions( @@ -140,10 +136,17 @@ defmodule ExDoc.Formatter.HTML.AutolinkTest do end test "autolinks special forms" do - assert Autolink.elixir_functions("`Mod.++/2`", ["Mod.++/2"]) === "[`Mod.++/2`](Mod.html#++/2)" + assert Autolink.elixir_functions("`Mod.++/2`", ["Mod.++/2"]) === + "[`Mod.++/2`](Mod.html#++/2)" + assert Autolink.elixir_functions("`Mod.!/1`", ["Mod.!/1"]) === "[`Mod.!/1`](Mod.html#!/1)" - assert Autolink.elixir_functions("`Mod.../2`", ["Mod.../2"]) === "[`Mod.../2`](Mod.html#../2)" - assert Autolink.elixir_functions("`Mod.--/2`", ["Mod.--/2"]) === "[`Mod.--/2`](Mod.html#--/2)" + + assert Autolink.elixir_functions("`Mod.../2`", ["Mod.../2"]) === + "[`Mod.../2`](Mod.html#../2)" + + assert Autolink.elixir_functions("`Mod.--/2`", ["Mod.--/2"]) === + "[`Mod.--/2`](Mod.html#--/2)" + assert Autolink.elixir_functions("`Mod.%/2`", ["Mod.%/2"]) === "[`Mod.%/2`](Mod.html#%25/2)" assert Autolink.elixir_functions("`Mod.<<>>/1`", ["Mod.<<>>/1"]) === @@ -206,7 +209,8 @@ defmodule ExDoc.Formatter.HTML.AutolinkTest do assert Autolink.elixir_functions("[`f`](`Foo.foo/1`), [`f`](`Foo.foo/1`)", ["Foo.foo/1"]) == "[`f`](Foo.html#foo/1), [`f`](Foo.html#foo/1)" - assert Autolink.elixir_functions("[`foo`](`Foo.//2`)", ["Foo.//2"]) == "[`foo`](Foo.html#//2)" + assert Autolink.elixir_functions("[`foo`](`Foo.//2`)", ["Foo.//2"]) == + "[`foo`](Foo.html#//2)" assert Autolink.elixir_functions("[`for`](`Kernel.SpecialForms.for/1`)", []) == "[`for`](#{@elixir_docs}elixir/Kernel.SpecialForms.html#for/1)" @@ -325,7 +329,8 @@ defmodule ExDoc.Formatter.HTML.AutolinkTest do end test "autolinks locals" do - assert Autolink.typespec(quote(do: foo(1)), [foo: 1], []) == ~s[foo(1)] + assert Autolink.typespec(quote(do: foo(1)), [foo: 1], []) == + ~s[foo(1)] assert Autolink.typespec(quote(do: bar(foo(1))), [foo: 1], []) == ~s[bar(foo(1))] @@ -349,8 +354,8 @@ defmodule ExDoc.Formatter.HTML.AutolinkTest do assert Autolink.typespec(quote(do: bar(foo(1)) :: foo(1)), [foo: 1], [], []) == ~s[bar(foo(1)) :: foo(1)] - assert Autolink.typespec(quote(do: (bar(foo(1)) :: foo(1) when bat: foo(1))), [foo: 1], [], []) == - ~s[bar(foo(1)) :: foo(1) when bat: foo(1)] + assert Autolink.typespec(quote(do: (bar(f(1)) :: f(1) when bat: f(1))), [f: 1], [], []) == + ~s[bar(f(1)) :: f(1) when bat: f(1)] assert Autolink.typespec(quote(do: bar(foo :: foo(1)) :: foo(1)), [foo: 1], [], []) == ~s[bar(foo :: foo(1)) :: foo(1)] @@ -393,7 +398,11 @@ defmodule ExDoc.Formatter.HTML.AutolinkTest do end test "autolinks inside parameterized types" do - assert Autolink.typespec(quote(do: parameterized_t(foo())), [parameterized_t: 1, foo: 0], []) == + assert Autolink.typespec( + quote(do: parameterized_t(foo())), + [parameterized_t: 1, foo: 0], + [] + ) == ~s[parameterized_t(foo())] assert Autolink.typespec(quote(do: Parameterized.t(foo())), [foo: 0], [Parameterized]) == diff --git a/test/ex_doc/group_matcher_test.exs b/test/ex_doc/group_matcher_test.exs index 9542ca352..cdbf481e4 100644 --- a/test/ex_doc/group_matcher_test.exs +++ b/test/ex_doc/group_matcher_test.exs @@ -5,28 +5,31 @@ defmodule ExDoc.GroupMatcherTest do describe "module matching" do test "it can match modules by their atom names" do patterns = [ - "Group": [MyApp.SomeModule, :lists] + Group: [MyApp.SomeModule, :lists] ] - assert match_module(patterns, MyApp.SomeModule, "MyApp.SomeModule") == :"Group" - assert match_module(patterns, :lists, ":lists") == :"Group" + + assert match_module(patterns, MyApp.SomeModule, "MyApp.SomeModule") == :Group + assert match_module(patterns, :lists, ":lists") == :Group assert match_module(patterns, MyApp.SomeOtherModule, "MyApp.SomeOtherModule") == nil end test "it can match modules by their string names" do patterns = [ - "Group": ["MyApp.SomeModule", ":lists"] + Group: ["MyApp.SomeModule", ":lists"] ] - assert match_module(patterns, MyApp.SomeModule, "MyApp.SomeModule") == :"Group" - assert match_module(patterns, :lists, ":lists") == :"Group" + + assert match_module(patterns, MyApp.SomeModule, "MyApp.SomeModule") == :Group + assert match_module(patterns, :lists, ":lists") == :Group assert match_module(patterns, MyApp.SomeOtherModule, "MyApp.SomeOtherModule") == nil end test "it can match modules by regular expressions" do patterns = [ - "Group": ~r/MyApp\..?/ + Group: ~r/MyApp\..?/ ] - assert match_module(patterns, MyApp.SomeModule, "MyApp.SomeModule") == :"Group" - assert match_module(patterns, MyApp.SomeOtherModule, "MyApp.SomeOtherModule") == :"Group" + + assert match_module(patterns, MyApp.SomeModule, "MyApp.SomeModule") == :Group + assert match_module(patterns, MyApp.SomeOtherModule, "MyApp.SomeOtherModule") == :Group assert match_module(patterns, MyAppWeb.SomeOtherModule, "MyAppWeb.SomeOtherModule") == nil end end @@ -34,18 +37,20 @@ defmodule ExDoc.GroupMatcherTest do describe "extras matching" do test "it can match extra files by their string names" do patterns = [ - "Group": ["docs/handling/testing.md"] + Group: ["docs/handling/testing.md"] ] - assert match_extra(patterns, "docs/handling/testing.md") == :"Group" + + assert match_extra(patterns, "docs/handling/testing.md") == :Group assert match_extra(patterns, "docs/handling/setup.md") == nil end test "it can match extra files by regular expressions" do patterns = [ - "Group": ~r/docs\/handling?/ + Group: ~r/docs\/handling?/ ] - assert match_extra(patterns, "docs/handling/testing.md") == :"Group" - assert match_extra(patterns, "docs/handling/setup.md") == :"Group" + + assert match_extra(patterns, "docs/handling/testing.md") == :Group + assert match_extra(patterns, "docs/handling/setup.md") == :Group assert match_extra(patterns, "docs/introduction.md") == nil end end diff --git a/test/ex_doc/markdown/cmark_test.exs b/test/ex_doc/markdown/cmark_test.exs index a39bd5300..662f23c19 100644 --- a/test/ex_doc/markdown/cmark_test.exs +++ b/test/ex_doc/markdown/cmark_test.exs @@ -6,8 +6,7 @@ defmodule ExDoc.Markdown.CmarkTest do alias ExDoc.Markdown.Cmark, as: Markdown test "to_html generate the HTML from the markdown" do - assert Markdown.to_html("# Test\n\nHello", []) =~ - ~s(

Test

\n

Hello

) + assert Markdown.to_html("# Test\n\nHello", []) =~ ~s(

Test

\n

Hello

) end test "to_html handles empty input" do diff --git a/test/ex_doc/markdown/earmark_test.exs b/test/ex_doc/markdown/earmark_test.exs index 0094b0357..0dfd43a0c 100644 --- a/test/ex_doc/markdown/earmark_test.exs +++ b/test/ex_doc/markdown/earmark_test.exs @@ -6,8 +6,7 @@ defmodule ExDoc.Markdown.EarmarkTest do @moduletag :earmark test "to_html generate the HTML from the markdown" do - assert Markdown.to_html("# Test\n\nHello", []) =~ - ~s(

Test

\n

Hello

) + assert Markdown.to_html("# Test\n\nHello", []) =~ ~s(

Test

\n

Hello

) end test "to_html handles empty input" do diff --git a/test/ex_doc/retriever_test.exs b/test/ex_doc/retriever_test.exs index b9015f6a9..da6fc16f4 100644 --- a/test/ex_doc/retriever_test.exs +++ b/test/ex_doc/retriever_test.exs @@ -35,8 +35,7 @@ defmodule ExDoc.RetrieverTest do assert module_node.title == "CompiledWithDocs" assert module_node.module == CompiledWithDocs - assert module_node.source_url == - "http://example.com/test/fixtures/compiled_with_docs.ex#L1" + assert module_node.source_url == "http://example.com/test/fixtures/compiled_with_docs.ex#L1" assert module_node.doc == """ moduledoc @@ -69,6 +68,7 @@ defmodule ExDoc.RetrieverTest do test "returns the function nodes for each module" do [module_node] = docs_from_files(["CompiledWithDocs"]) + [struct, example, example_1, _example_with_h3, example_without_docs, is_zero] = module_node.docs @@ -93,12 +93,14 @@ defmodule ExDoc.RetrieverTest do assert example_without_docs.id == "example_without_docs/0" assert example_without_docs.doc == nil assert example_without_docs.defaults == [] + assert example_without_docs.source_url == "http://example.com/test/fixtures/compiled_with_docs.ex\#L34" assert is_zero.id == "is_zero/1" assert is_zero.doc == "A simple guard" - assert is_zero.type in [:guard, :macro] # TODO: Remove :macro when ~> 1.8 + # TODO: Remove :macro when ~> 1.8 + assert is_zero.type in [:guard, :macro] assert is_zero.defaults == [] end diff --git a/test/ex_doc_test.exs b/test/ex_doc_test.exs index 801b89393..4302a8ed6 100644 --- a/test/ex_doc_test.exs +++ b/test/ex_doc_test.exs @@ -18,33 +18,37 @@ defmodule ExDocTest do test "build_config & normalize_options" do project = "Elixir" version = "1" - options = [ - formatter: IdentityFormatter, - retriever: IdentityRetriever, - source_root: "root_dir", - source_beam: "beam_dir", - ] - {_, config} = ExDoc.generate_docs project, version, Keyword.merge(options, [output: "test/tmp/ex_doc"]) + opts_with_output = + &[ + formatter: IdentityFormatter, + retriever: IdentityRetriever, + source_root: "root_dir", + source_beam: "beam_dir", + output: &1 + ] + + {_, config} = ExDoc.generate_docs(project, version, opts_with_output.("test/tmp/ex_doc")) assert config.output == "test/tmp/ex_doc" - {_, config} = ExDoc.generate_docs project, version, Keyword.merge(options, [output: "test/tmp/ex_doc/"]) + {_, config} = ExDoc.generate_docs(project, version, opts_with_output.("test/tmp/ex_doc/")) assert config.output == "test/tmp/ex_doc" - {_, config} = ExDoc.generate_docs project, version, Keyword.merge(options, [output: "test/tmp/ex_doc//"]) + {_, config} = ExDoc.generate_docs(project, version, opts_with_output.("test/tmp/ex_doc//")) assert config.output == "test/tmp/ex_doc" end test "uses custom markdown processor" do project = "Elixir" version = "1" + options = [ formatter: IdentityFormatter, markdown_processor: Sample, output: "test/tmp/ex_doc", retriever: IdentityRetriever, source_root: "root_dir", - source_beam: "beam_dir", + source_beam: "beam_dir" ] ExDoc.generate_docs(project, version, options) @@ -54,24 +58,34 @@ defmodule ExDocTest do end test "source_beam sets source dir" do - options = [formatter: IdentityFormatter, retriever: IdentityRetriever, - source_root: "root_dir", source_beam: "beam_dir"] - {{source_dir, _retr_config}, _config} = ExDoc.generate_docs "Elixir", "1", options + options = [ + formatter: IdentityFormatter, + retriever: IdentityRetriever, + source_root: "root_dir", + source_beam: "beam_dir" + ] + + {{source_dir, _retr_config}, _config} = ExDoc.generate_docs("Elixir", "1", options) assert source_dir == options[:source_beam] end test "formatter module not found" do project = "Elixir" version = "1" - options = [formatter: "pdf", retriever: IdentityRetriever, - source_root: "root_dir", source_beam: "beam_dir"] + + options = [ + formatter: "pdf", + retriever: IdentityRetriever, + source_root: "root_dir", + source_beam: "beam_dir" + ] assert_raise RuntimeError, "formatter module \"pdf\" not found", - fn -> ExDoc.generate_docs project, version, options end + fn -> ExDoc.generate_docs(project, version, options) end end test "version" do - assert ExDoc.version =~ ~r{\d+\.\d+\.\d+} + assert ExDoc.version() =~ ~r{\d+\.\d+\.\d+} end end diff --git a/test/fixtures/behaviour.ex b/test/fixtures/behaviour.ex index 99d5be208..9a4bba422 100644 --- a/test/fixtures/behaviour.ex +++ b/test/fixtures/behaviour.ex @@ -6,7 +6,7 @@ defmodule CustomBehaviourOne do This is a sample callback. """ @callback hello(integer) :: integer - @callback greet(integer | String.t) :: integer + @callback greet(integer | String.t()) :: integer end defmodule CustomBehaviourTwo do diff --git a/test/fixtures/callbacks_no_docs.ex b/test/fixtures/callbacks_no_docs.ex index 7b2994b73..27cf1e236 100644 --- a/test/fixtures/callbacks_no_docs.ex +++ b/test/fixtures/callbacks_no_docs.ex @@ -1,8 +1,8 @@ defmodule CallbacksNoDocs do - @callback connect(params :: map, String.t) :: {:ok, String.t} | :error + @callback connect(params :: map, String.t()) :: {:ok, String.t()} | :error @doc deprecated: "Use another id", since: "1.3.0" - @callback id(String.t) :: String.t | nil + @callback id(String.t()) :: String.t() | nil @optional_callbacks id: 1 end diff --git a/test/fixtures/types_and_specs.ex b/test/fixtures/types_and_specs.ex index 1bb2613a4..46ae69f56 100644 --- a/test/fixtures/types_and_specs.ex +++ b/test/fixtures/types_and_specs.ex @@ -11,10 +11,10 @@ defmodule TypesAndSpecs do """ @typedoc "A public type" - @type public(t) :: {t, String.t, Sub.t, opaque, :ok | :error} + @type public(t) :: {t, String.t(), Sub.t(), opaque, :ok | :error} @typep private :: any - @opaque opaque :: {Dict.t} - @type ref :: {:binary.part, public(any)} + @opaque opaque :: {Dict.t()} + @type ref :: {:binary.part(), public(any)} @typedoc false @type internal :: any diff --git a/test/fixtures/umbrella/apps/bar/mix.exs b/test/fixtures/umbrella/apps/bar/mix.exs index e0b40724c..2b3bb6d58 100644 --- a/test/fixtures/umbrella/apps/bar/mix.exs +++ b/test/fixtures/umbrella/apps/bar/mix.exs @@ -2,7 +2,9 @@ defmodule Bar.Mixfile do use Mix.Project def project do - [app: :bar, - version: "0.1.0"] + [ + app: :bar, + version: "0.1.0" + ] end end diff --git a/test/fixtures/umbrella/apps/foo/mix.exs b/test/fixtures/umbrella/apps/foo/mix.exs index 3a8791823..bc13dafb6 100644 --- a/test/fixtures/umbrella/apps/foo/mix.exs +++ b/test/fixtures/umbrella/apps/foo/mix.exs @@ -2,7 +2,9 @@ defmodule Foo.Mixfile do use Mix.Project def project do - [app: :foo, - version: "0.1.0"] + [ + app: :foo, + version: "0.1.0" + ] end end diff --git a/test/fixtures/umbrella/mix.exs b/test/fixtures/umbrella/mix.exs index ef42b3ab4..6bac6068b 100644 --- a/test/fixtures/umbrella/mix.exs +++ b/test/fixtures/umbrella/mix.exs @@ -2,8 +2,10 @@ defmodule Umbrella.Mixfile do use Mix.Project def project do - [apps_path: "apps", - deps: deps()] + [ + apps_path: "apps", + deps: deps() + ] end defp deps do diff --git a/test/test_helper.exs b/test/test_helper.exs index 76531bb1b..7f4eeb7bb 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -1,6 +1,6 @@ exclude = [ - cmark: !ExDoc.Markdown.Cmark.available?, - earmark: !ExDoc.Markdown.Earmark.available? + cmark: !ExDoc.Markdown.Cmark.available?(), + earmark: !ExDoc.Markdown.Earmark.available?() ] ExUnit.start(exclude: Enum.filter(exclude, &elem(&1, 1))) @@ -19,28 +19,36 @@ defmodule ExDoc.Markdown.DummyProcessor do @moduledoc false @behaviour ExDoc.Markdown - def to_html(text, opts), - do: ExDoc.Markdown.Earmark.to_html(text, opts) + def to_html(text, opts), do: ExDoc.Markdown.Earmark.to_html(text, opts) - def assets(:html), do: [ - {"html_assets.css", "HTML assets - CSS"}, - {"html_assets.js", "HTML assets - Javascript"}] + def assets(:html) do + [{"html_assets.css", "HTML assets - CSS"}, {"html_assets.js", "HTML assets - Javascript"}] + end - def assets(:epub), do: [ - {"epub_assets-css.css", "EPUB assets - CSS"}, - {"epub_assets-js.js", "EPUB assets - Javascript"}] + def assets(:epub) do + [ + {"epub_assets-css.css", "EPUB assets - CSS"}, + {"epub_assets-js.js", "EPUB assets - Javascript"} + ] + end def available?(), do: true def configure(_), do: :ok - def before_closing_head_tag(:html), - do: "UNIQUE:©MARKDOWN-PROCESSOR-BEFORE-CLOSING-HEAD-TAG-HTML" - def before_closing_head_tag(:epub), - do: "UNIQUE:©MARKDOWN-PROCESSOR-BEFORE-CLOSING-HEAD-TAG-EPUB" + def before_closing_head_tag(:html) do + "UNIQUE:©MARKDOWN-PROCESSOR-BEFORE-CLOSING-HEAD-TAG-HTML" + end - def before_closing_body_tag(:html), - do: "UNIQUE:©MARKDOWN-PROCESSOR-BEFORE-CLOSING-BODY-TAG-HTML" - def before_closing_body_tag(:epub), - do: "UNIQUE:©MARKDOWN-PROCESSOR-BEFORE-CLOSING-BODY-TAG-EPUB" + def before_closing_head_tag(:epub) do + "UNIQUE:©MARKDOWN-PROCESSOR-BEFORE-CLOSING-HEAD-TAG-EPUB" + end + + def before_closing_body_tag(:html) do + "UNIQUE:©MARKDOWN-PROCESSOR-BEFORE-CLOSING-BODY-TAG-HTML" + end + + def before_closing_body_tag(:epub) do + "UNIQUE:©MARKDOWN-PROCESSOR-BEFORE-CLOSING-BODY-TAG-EPUB" + end end From 68dc3e514f8debdd8d3a9023353cf87bf3d81931 Mon Sep 17 00:00:00 2001 From: Laszlo Bacsi Date: Thu, 2 Aug 2018 00:07:05 +0200 Subject: [PATCH 2/2] fixup! eb3945e --- test/ex_doc/formatter/html/autolink_test.exs | 39 +++++++------------- 1 file changed, 14 insertions(+), 25 deletions(-) diff --git a/test/ex_doc/formatter/html/autolink_test.exs b/test/ex_doc/formatter/html/autolink_test.exs index f7633c280..2eaba1a21 100644 --- a/test/ex_doc/formatter/html/autolink_test.exs +++ b/test/ex_doc/formatter/html/autolink_test.exs @@ -92,9 +92,10 @@ defmodule ExDoc.Formatter.HTML.AutolinkTest do assert Autolink.elixir_functions("`MyModule.example/2`", ["MyModule.example/2"]) == "[`MyModule.example/2`](MyModule.html#example/2)" - assert Autolink.elixir_functions("`MyModule.Nested.example/2`", [ - "MyModule.Nested.example/2" - ]) == "[`MyModule.Nested.example/2`](MyModule.Nested.html#example/2)" + assert Autolink.elixir_functions( + "`MyModule.Nested.example/2`", + ["MyModule.Nested.example/2"] + ) == "[`MyModule.Nested.example/2`](MyModule.Nested.html#example/2)" assert Autolink.elixir_functions("`Mod.example/2` then `Mod.example/2`", ["Mod.example/2"]) == "[`Mod.example/2`](Mod.html#example/2) then [`Mod.example/2`](Mod.html#example/2)" @@ -102,10 +103,10 @@ defmodule ExDoc.Formatter.HTML.AutolinkTest do assert Autolink.elixir_functions("` MyModule.spaces/0 `", ["MyModule.spaces/0"]) == "[`MyModule.spaces/0`](MyModule.html#spaces/0)" - assert Autolink.elixir_functions("`ModA.example/1` and `ModB.example/2`", [ - "ModA.example/1", - "ModB.example/2" - ]) == + assert Autolink.elixir_functions( + "`ModA.example/1` and `ModB.example/2`", + ["ModA.example/1", "ModB.example/2"] + ) == "[`ModA.example/1`](ModA.html#example/1) and [`ModB.example/2`](ModB.html#example/2)" assert Autolink.elixir_functions( @@ -398,12 +399,8 @@ defmodule ExDoc.Formatter.HTML.AutolinkTest do end test "autolinks inside parameterized types" do - assert Autolink.typespec( - quote(do: parameterized_t(foo())), - [parameterized_t: 1, foo: 0], - [] - ) == - ~s[parameterized_t(foo())] + assert Autolink.typespec(quote(do: t(foo())), [t: 1, foo: 0], []) == + ~s[t(foo())] assert Autolink.typespec(quote(do: Parameterized.t(foo())), [foo: 0], [Parameterized]) == ~s[Parameterized.t(foo())] @@ -414,19 +411,11 @@ defmodule ExDoc.Formatter.HTML.AutolinkTest do assert Autolink.typespec(quote(do: Parameterized.t(Foo.t())), [], [Parameterized, Foo]) == ~s[Parameterized.t(Foo.t())] - assert Autolink.typespec( - quote(do: parameterized_t(foo() | bar())), - [parameterized_t: 1, foo: 0, bar: 0], - [] - ) == - ~s[parameterized_t(foo() | bar())] + assert Autolink.typespec(quote(do: t(foo() | bar())), [t: 1, foo: 0, bar: 0], []) == + ~s[t(foo() | bar())] - assert Autolink.typespec( - quote(do: parameterized_t(parameterized_t(foo()))), - [parameterized_t: 1, foo: 0], - [] - ) == - ~s[parameterized_t(parameterized_t(foo()))] + assert Autolink.typespec(quote(do: t(t(foo()))), [t: 1, foo: 0], []) == + ~s[t(t(foo()))] assert Autolink.typespec(quote(do: parameterized_t(foo())), [foo: 0], []) == ~s[parameterized_t(foo())]