Module: Evilution::Integration::Loading::TestLoadPath
- Defined in:
- lib/evilution/integration/loading/test_load_path.rb
Overview
Mirrors ‘ruby -Itest` / `-Ispec` for in-process test loading.
evilution loads resolved test files with Kernel#load instead of shelling out, so the ‘-Itest` shown in the displayed command string is never actually applied to $LOAD_PATH. Minitest and Test::Unit suites near-universally `require “test_helper”` (which the suite’s own runner satisfies via -Itest); without the test root on $LOAD_PATH that bare require raises LoadError and every mutation errors with score 0.0 (EV-52hf / GH #1326).
Anchors against Evilution.project_base_dir, which resolves to PROJECT_ROOT inside an isolated worker (EV-wqxu / GH #1278) and Dir.pwd otherwise, so the same call works on both the baseline (parent) and mutation (child) paths.
Constant Summary collapse
- ROOT_NAMES =
%w[test spec].freeze
Class Method Summary collapse
-
.add!(files, base: Evilution.project_base_dir) ⇒ Object
Prepend every relevant test directory to $LOAD_PATH (idempotently).
- .conventional_roots(base) ⇒ Object
-
.dirs_for(files, base) ⇒ Object
The directories to put on $LOAD_PATH for the given resolved test files: the conventional test/ and spec/ roots under base, each file’s own directory, and the topmost test/spec ancestor of each file (covers nested layouts like test/unit, spec/lib, spec/unit).
-
.root_ancestor(dir, base) ⇒ Object
Walk from ‘dir` up to `base`, returning the highest ancestor whose basename is a conventional test root (test/spec).
- .within?(dir, base) ⇒ Boolean
Class Method Details
.add!(files, base: Evilution.project_base_dir) ⇒ Object
Prepend every relevant test directory to $LOAD_PATH (idempotently). Iterate in reverse so the first entry from #dirs_for ends up frontmost, preserving its order (mirrors how ‘ruby -Ia -Ib` lands a before b).
25 26 27 28 29 |
# File 'lib/evilution/integration/loading/test_load_path.rb', line 25 def add!(files, base: Evilution.project_base_dir) dirs_for(files, base).reverse_each do |dir| $LOAD_PATH.unshift(dir) unless $LOAD_PATH.include?(dir) end end |
.conventional_roots(base) ⇒ Object
54 55 56 |
# File 'lib/evilution/integration/loading/test_load_path.rb', line 54 def conventional_roots(base) ROOT_NAMES.map { |name| File.join(base, name) } end |
.dirs_for(files, base) ⇒ Object
The directories to put on $LOAD_PATH for the given resolved test files: the conventional test/ and spec/ roots under base, each file’s own directory, and the topmost test/spec ancestor of each file (covers nested layouts like test/unit, spec/lib, spec/unit). Existing directories only, and only those inside the project base – never a broad outside-project dir (e.g. a /tmp test file), which would over-widen $LOAD_PATH for the whole process (the baseline runs in the long-lived parent).
38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/evilution/integration/loading/test_load_path.rb', line 38 def dirs_for(files, base) base = File.(base) dirs = conventional_roots(base) Array(files).each do |file| file_dir = File.dirname(File.(file, base)) dirs << file_dir root = root_ancestor(file_dir, base) dirs << root if root end dirs.uniq.select { |dir| File.directory?(dir) && within?(dir, base) } end |
.root_ancestor(dir, base) ⇒ Object
Walk from ‘dir` up to `base`, returning the highest ancestor whose basename is a conventional test root (test/spec). Highest, so test/unit/foo_test.rb yields `test` (matching -Itest), not the intermediate test/unit.
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/evilution/integration/loading/test_load_path.rb', line 61 def root_ancestor(dir, base) base = File.(base) found = nil current = File.(dir) loop do found = current if ROOT_NAMES.include?(File.basename(current)) break if current == base parent = File.dirname(current) break if parent == current current = parent end found end |
.within?(dir, base) ⇒ Boolean
50 51 52 |
# File 'lib/evilution/integration/loading/test_load_path.rb', line 50 def within?(dir, base) dir == base || dir.start_with?("#{base}/") end |