MixAffected.TestMap.Builder (MixAffected v0.1.0)

Copy Markdown View Source

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.

  1. ExUnit.start(autorun: false), then each test path's test_helper.exs is required (a failing helper is reported and skipped: tracing only needs the test modules to compile)
  2. every test file is required in parallel with MixAffected.TestMap.Tracer registered as a compiler tracer
  3. files that did not finish (an error, or the parallel compiler stopping on someone else's error) are retried one at a time
  4. a file that still fails gets its references from its AST (MixAffected.TestMap.Ast, mode :ast); one that does not parse either is :always
  5. 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)
  6. an affected_by glob MixAffected.Config.validate_glob/2 rejects (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

Functions

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.

Every test file of the project, absolute, sorted (as mix test finds them).

Types

stats()

@type stats() :: %{
  tracer: non_neg_integer(),
  ast: non_neg_integer(),
  always: non_neg_integer(),
  helper_errors: [String.t()],
  glob_warnings: [String.t()]
}

Functions

build(root, config, opts \\ [])

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.

test_files(root, config)

@spec test_files(Path.t(), MixAffected.Config.t()) :: [Path.t()]

Every test file of the project, absolute, sorted (as mix test finds them).