Muex. Coverage
(Muex v0.8.1)
View Source
A line-level coverage index: which test files execute which source lines.
Used to run, for each mutant, only the tests that actually exercise the
mutated line — and to skip mutants on lines no test covers (:no_coverage)
rather than wasting a full test run on a mutant nothing can catch.
The index is a plain map (%{file => %{line => MapSet of test files}}); build
it with new/0 + put/4 and query it with tests_for/3 / covered?/3.
Summary
Functions
Builds a coverage index by running each test file under :cover and recording
which source lines it executes.
Whether any test covers file:line.
Extracts the executed line numbers from a :cover.analyse(_, :calls, :line)
result, i.e. the lines with a non-zero call count.
Returns an empty index.
Records that test_file executes line of file.
Records that line of file is executable (even if no test runs it).
Records that test_file executes every line in lines of file.
Returns the coverage status of file:line
Types
@type t() :: %{required(Path.t()) => %{required(pos_integer()) => MapSet.t(Path.t())}}
Functions
Builds a coverage index by running each test file under :cover and recording
which source lines it executes.
For every file in test_files, runs mix test <file> --cover --export-coverage
in a subprocess, then analyses each module in file_to_module and attributes
its executed lines to that test file. Returns a t() index.
Options: :cd (project root, default File.cwd!/0).
@spec covered?(t(), Path.t(), pos_integer()) :: boolean()
Whether any test covers file:line.
@spec covered_lines([{{module(), pos_integer()}, non_neg_integer()}]) :: [ pos_integer() ]
Extracts the executed line numbers from a :cover.analyse(_, :calls, :line)
result, i.e. the lines with a non-zero call count.
@spec new() :: t()
Returns an empty index.
@spec put(t(), Path.t(), pos_integer(), Path.t()) :: t()
Records that test_file executes line of file.
@spec put_executable(t(), Path.t(), pos_integer()) :: t()
Records that line of file is executable (even if no test runs it).
@spec put_lines(t(), Path.t(), [pos_integer()], Path.t()) :: t()
Records that test_file executes every line in lines of file.
@spec tests_for(t(), Path.t(), pos_integer()) :: {:covered, [Path.t()]} | :no_coverage | :unknown
Returns the coverage status of file:line:
{:covered, sorted_test_files}— at least one test executes the line;:no_coverage— the line is executable but no test runs it;:unknown— there is no coverage data for the line (e.g. it is not an executable line, like adefmodule/defheader), so coverage can't decide and the caller should run the mutant normally.