Reads a test file's source without compiling it: the modules it names
(the fallback when requiring the file fails) and its affected_by globs.
Alias resolution is file-wide, not lexical: alias A.B anywhere makes
every B... reference resolve to A.B..., and the unaliased reading is
kept too. Over-matching only selects more tests; it never drops one.
Summary
Functions
The globs of every literal @moduletag affected_by: ["glob", ...] (also
among other tags in the same keyword list) and @affected_by ["glob", ...]
in the source; [] if none or unparseable.
Whether the source defines a protocol impl (defimpl); true if it does not parse.
The root-relative globs of the files a test reads from the repo itself
(a source-scanning guard reading lib/**, a doc test reading
guides/*.md, a Dockerfile test), found without compiling it: [] when
the source calls no file-reading or -listing function (File.read!/1,
Path.wildcard/1, ... or @external_resource), else a glob per path
literal anywhere in the file whose first segment is one of top_level
(the entries of the project root). A literal names a file or a directory,
so "lib/app" reads lib/app and lib/app/**; literal globs are kept.
Every module the source names through an alias (Foo.Bar), resolving
alias, alias ..., as: and alias Foo.{A, B}. :error if it does not parse.
Functions
The globs of every literal @moduletag affected_by: ["glob", ...] (also
among other tags in the same keyword list) and @affected_by ["glob", ...]
in the source; [] if none or unparseable.
Whether the source defines a protocol impl (defimpl); true if it does not parse.
The root-relative globs of the files a test reads from the repo itself
(a source-scanning guard reading lib/**, a doc test reading
guides/*.md, a Dockerfile test), found without compiling it: [] when
the source calls no file-reading or -listing function (File.read!/1,
Path.wildcard/1, ... or @external_resource), else a glob per path
literal anywhere in the file whose first segment is one of top_level
(the entries of the project root). A literal names a file or a directory,
so "lib/app" reads lib/app and lib/app/**; literal globs are kept.
Path.join/1,2 of leading literals reads the joined path, Path.expand/2
and Path.join/2 from __DIR__ resolve against test_file's directory,
:code.priv_dir/1 is priv, ~w words and the literal parts of an
interpolation ("#{File.cwd!()}/guides/x.md") count as literals, other
sigils (regexes) do not.
["**"] (reads everything) when the reads cannot be pinned to the repo:
the source does not parse, it reads but no literal names a repo path, a
reading call's literal argument is not anchored at the root (".",
"**/*.ex", a relative "fixtures/x.json"), it lists the working
directory (File.ls!/0, File.cwd!()), a __DIR__ path leaves the root,
or a literal glob does not compile (MixAffected.Glob.compile/1) or uses
a [...] character class MixAffected.Glob does not implement, so
selection never matches against it.
Every module the source names through an alias (Foo.Bar), resolving
alias, alias ..., as: and alias Foo.{A, B}. :error if it does not parse.