Packages
excoveralls
0.3.11
0.18.5
0.18.4
0.18.3
0.18.2
0.18.1
0.18.0
0.17.1
0.17.0
0.16.1
0.16.0
0.15.3
0.15.2
0.15.1
0.15.0
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.13.4
0.13.3
0.13.2
0.13.1
0.13.0
0.12.3
0.12.2
0.12.1
0.12.0
0.11.2
0.11.1
0.11.0
0.10.6
0.10.5
0.10.4
0.10.3
0.10.2
0.10.1
0.10.0
0.9.2
0.9.1
0.9.0
0.8.2
0.8.1
0.8.0
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.11
0.3.10
0.3.9
0.3.8
0.3.7
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
Coverage report tool for Elixir with coveralls.io integration.
Current section
Files
Jump to
Current section
Files
lib/excoveralls/local.ex
defmodule ExCoveralls.Local do
@moduledoc """
Locally displays the result to screen.
"""
@doc """
Stores count information for calculating coverage values.
"""
defmodule Count do
defstruct lines: 0, relevant: 0, covered: 0
end
@doc """
Provides an entry point for the module.
"""
def execute(stats, options \\ []) do
IO.puts "----------------"
IO.puts print_string("~-6s ~-40s ~8s ~8s ~8s", ["COV", "FILE", "LINES", "RELEVANT", "MISSED"])
coverage(stats) |> IO.puts
IO.puts "----------------"
if options[:detail] == true do
source(stats, options[:filter]) |> IO.puts
end
end
@doc """
Format the source code with color for the files that matches with
the specified patterns.
"""
def source(stats, _patterns = nil), do: source(stats)
def source(stats, _patterns = []), do: source(stats)
def source(stats, patterns) do
Enum.filter(stats, fn(stat) -> String.contains?(stat[:name], patterns) end) |> source
end
def source(stats) do
stats |> Enum.map(&format_source/1)
|> Enum.join("\n")
end
defp format_source(stat) do
"\n\e[33m--------#{stat[:name]}--------\e[m\n" <> colorize(stat)
end
defp colorize([{:name, _name}, {:source, source}, {:coverage, coverage}]) do
lines = String.split(source, "\n")
Enum.zip(lines, coverage)
|> Enum.map(&do_colorize/1)
|> Enum.join("\n")
end
defp do_colorize({line, coverage}) do
case coverage do
nil -> line
0 -> "\e[31m#{line}\e[m"
_ -> "\e[32m#{line}\e[m"
end
end
@doc """
Format the source coverage stats into string.
"""
def coverage(stats) do
stats = Enum.sort(stats, fn(x, y) -> x[:name] <= y[:name] end)
count_info = Enum.map(stats, fn(stat) -> [stat, calculate_count(stat[:coverage])] end)
Enum.join(format_body(count_info), "\n") <> "\n" <> format_total(count_info)
end
defp format_body(info) do
Enum.map(info, &format_info/1)
end
defp format_info([stat, count]) do
coverage = get_coverage(count)
print_string("~5.1f% ~-40s ~8w ~8w ~8w",
[coverage, stat[:name], count.lines, count.relevant, count.relevant - count.covered])
end
defp format_total(info) do
totals = Enum.reduce(info, %Count{}, fn([_, count], acc) -> append(count, acc) end)
coverage = get_coverage(totals)
print_string("[TOTAL] ~5.1f%", [coverage])
end
defp append(a, b) do
%Count{
lines: a.lines + b.lines,
relevant: a.relevant + b.relevant,
covered: a.covered + b.covered
}
end
defp get_coverage(count) do
case count.relevant do
0 -> default_coverage_value
_ -> (count.covered / count.relevant) * 100
end
end
defp default_coverage_value do
options = ExCoveralls.Settings.get_coverage_options
case Dict.fetch(options, "treat_no_relevant_lines_as_covered") do
{:ok, true} -> 100.0
_ -> 0.0
end
end
@doc """
Calucate count information from thhe coverage stats.
"""
def calculate_count(coverage) do
do_calculate_count(coverage, 0, 0, 0)
end
defp do_calculate_count([], lines, relevant, covered) do
%Count{lines: lines, relevant: relevant, covered: covered}
end
defp do_calculate_count([h|t], lines, relevant, covered) do
case h do
nil -> do_calculate_count(t, lines + 1, relevant, covered)
0 -> do_calculate_count(t, lines + 1, relevant + 1, covered)
n when is_number(n)
-> do_calculate_count(t, lines + 1, relevant + 1, covered + 1)
_ -> raise "Invalid data - #{h}"
end
end
defp print_string(format, params) do
char_list = :io_lib.format(format, params)
List.to_string(char_list)
end
end