Builds a MixAffected.TestMap inside the consuming project's VM, the way
mix test loads tests but without running any: the project must already
be compiled (and its apps started, as mix test does) by the caller.
ExUnit.start(autorun: false), then each test path'stest_helper.exsis required (a failing helper is reported and skipped: tracing only needs the test modules to compile)- every test file is required in parallel with
MixAffected.TestMap.Tracerregistered as a compiler tracer - files that did not finish (an error, or the parallel compiler stopping on someone else's error) are retried one at a time
- a file that still fails gets its references from its AST
(
MixAffected.TestMap.Ast, mode:ast); one that does not parse either is:always - every file's
:reads(repo files it reads itself) come from its AST, anchored at the entries of the root (MixAffected.TestMap.Ast.reads/3) - an
affected_byglobMixAffected.Config.validate_glob/2rejects (malformed, not in normal form, or naming a directory) is dropped and its file is:always, with a warning in the stats: the edge it declared cannot be honoured, so the test runs whenever anything is affected
Referenced modules are mapped to their source file: the test file that
defined them, else module_info(:compile)[:source]. Sources outside the
root, or under an :exclude dir (deps, _build), are dropped.
A referenced Mox mock (a loaded module exporting __mock_for__/0) also
references the behaviours it mocks; mocks are defined by test_helper.exs,
which is required before the test files are traced.
Protocol impls among the project's :modules are recorded with the file
of the type they are for (nil when that type is not a project module).
Summary
Types
@type stats() :: %{ tracer: non_neg_integer(), ast: non_neg_integer(), always: non_neg_integer(), helper_errors: [String.t()], glob_warnings: [String.t()] }
Functions
@spec build(Path.t(), MixAffected.Config.t(), keyword()) :: {MixAffected.TestMap.t(), stats()}
Options: :exclude - absolute dirs whose sources are never refs;
:modules - the project's compiled modules, searched for protocol impls
(TestMap :impls). root is the absolute project root.
@spec test_files(Path.t(), MixAffected.Config.t()) :: [Path.t()]
Every test file of the project, absolute, sorted (as mix test finds them).