MixAffected.Selection (MixAffected v0.1.0)

Copy Markdown View Source

Picks the test files to run from the seeds of a change (changed sources the graph knows, plus changed test files) and the test map.

It walks one graph whose edges point from a file to whatever it may change:

  • source -> source: MixAffected.Graph reverse edges (any kind)
  • file -> test: the test references a module defined in the file (the file may itself be a test file that defines helper modules)
  • file -> test: one of the test's affected_by globs (tag or attribute) matches the file
  • file -> test: a config mapping's source glob matches the file and one of its test globs matches the test
  • any seed -> test: the test references a module that resolves to nothing (the changed or deleted file, source or test, may have defined it)
  • seed -> test: one of the test's reads globs (files it reads from the repo, such as a guard scanning lib/**) matches the seed. Only a seed's content changed, so a file the walk merely reaches does not count.

read_only files (changed files the config ignores) select only the tests whose reads match them, and tests the map does not know (which may read anything); they seed nothing else.

Every test file it reaches is selected, and so is every test file a selected test needs loaded: one defining a module the selected test references (otherwise mix test <files> would fail on it). Tests the map marks :always or :ast (the AST fallback misses use-injected references), and test files the map does not know at all, are selected whenever there is any seed (MixAffected.Run turns selecting an unknown or stale entry into a full run). The walk is breadth-first in sorted order, so each selected test's explain chain is one shortest path changed file -> ... -> test.

Summary

Functions

test_files are the test files that exist now; map entries for other files are ignored. graph may be nil when every seed is a test file.

Types

path()

@type path() :: MixAffected.Graph.path()

result()

@type result() :: %{tests: [path()], explain: %{optional(path()) => [path()]}}

Functions

select(graph, seeds, test_files, test_map, config, read_only \\ [])

@spec select(
  MixAffected.Graph.t() | nil,
  [path()],
  [path()],
  MixAffected.TestMap.t(),
  MixAffected.Config.t(),
  [path()]
) :: result()

test_files are the test files that exist now; map entries for other files are ignored. graph may be nil when every seed is a test file.