defmodule ESpec.Output.Html do @moduledoc """ Generates html output. """ alias ESpec.Example @doc "Format the final result." def format_result(examples, times, _opts) do tree = context_tree(examples) html = make_html(tree, true) summary = format_summary(examples, times) string = EEx.eval_file(template_path, [examples: html, summary: summary]) String.replace(string, "\n", "") end @doc "Formats an example result." def format_example(_example, _opts), do: "" defp template_path, do: Path.join(Path.dirname(__ENV__.file), "templates/html.html.eex") defp context_tree(examples) do examples |> Enum.reduce({Map.new, []}, fn(ex, acc) -> contexts = Enum.filter(ex.context, &(&1.__struct__ == ESpec.Context)) put_deep(acc, contexts, ex) end) end defp put_deep({dict, values}, [el | tl], value) when length(tl) > 0 do d = case Map.get(dict, el) do {inner, vals} -> put_deep({inner, vals}, tl, value) nil -> put_deep({Map.new, []}, tl, value) end {Map.put(dict, el, d), values} end defp put_deep({dict, values}, [el], value) do new_dict = case Map.get(dict, el) do {inner, vals} -> Map.put(dict, el, {inner, [value | vals]}) nil -> Map.put(dict, el, {Map.new, [value]}) end {new_dict, values} end defp put_deep({dict, values}, [], value) do {dict, [value | values]} end defp make_html({dict, values}, top? \\ false, firstli? \\ false) do lis = Enum.reduce(values, "", fn(ex, acc) -> acc <> "