Class: Testprune::Configuration

Inherits:
Object
  • Object
show all
Defined in:
lib/testprune/configuration.rb

Overview

Holds run/analysis settings. ‘source_paths` define which files count as the system-under-test — coverage in any other file (test helpers, vendored gems, the bundle) is ignored so footprints stay precise and cheap to diff.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(root: Dir.pwd) ⇒ Configuration

Returns a new instance of Configuration.



27
28
29
30
31
32
33
34
35
36
# File 'lib/testprune/configuration.rb', line 27

def initialize(root: Dir.pwd)
  @root             = File.expand_path(root)
  @source_paths     = %w[app lib]
  @exclude_globs    = %w[**/vendor/** **/node_modules/** **/db/** **/config/**]
  @output_dir       = File.join(@root, 'tmp', '.testprune')
  @overlap_threshold = 0.9 # Jaccard cutoff for LOW-confidence overlap pairs
  # Units executed by >= this fraction of tests are treated as ambient
  # shared-setup noise and subtracted before detection. nil disables it.
  @baseline_fraction = 0.5
end

Instance Attribute Details

#baseline_fractionObject

Returns the value of attribute baseline_fraction.



8
9
10
# File 'lib/testprune/configuration.rb', line 8

def baseline_fraction
  @baseline_fraction
end

#exclude_globsObject

Returns the value of attribute exclude_globs.



8
9
10
# File 'lib/testprune/configuration.rb', line 8

def exclude_globs
  @exclude_globs
end

#output_dirObject

Returns the value of attribute output_dir.



8
9
10
# File 'lib/testprune/configuration.rb', line 8

def output_dir
  @output_dir
end

#overlap_thresholdObject

Returns the value of attribute overlap_threshold.



8
9
10
# File 'lib/testprune/configuration.rb', line 8

def overlap_threshold
  @overlap_threshold
end

#rootObject

Returns the value of attribute root.



8
9
10
# File 'lib/testprune/configuration.rb', line 8

def root
  @root
end

#source_pathsObject

Returns the value of attribute source_paths.



8
9
10
# File 'lib/testprune/configuration.rb', line 8

def source_paths
  @source_paths
end

Class Method Details

.from_env(env = ENV) ⇒ Object

Rebuild config inside the instrumented subprocess from env vars set by Runner.



39
40
41
42
43
44
45
# File 'lib/testprune/configuration.rb', line 39

def self.from_env(env = ENV)
  cfg = new(root: env.fetch('TESTPRUNE_ROOT', Dir.pwd))
  cfg.source_paths  = split_env(env['TESTPRUNE_SOURCE_PATHS']) || cfg.source_paths
  cfg.exclude_globs = split_env(env['TESTPRUNE_EXCLUDE']) || cfg.exclude_globs
  cfg.output_dir    = env['TESTPRUNE_OUTPUT_DIR'] || cfg.output_dir
  cfg
end

.split_env(value) ⇒ Object



47
48
49
50
51
# File 'lib/testprune/configuration.rb', line 47

def self.split_env(value)
  return nil if value.nil? || value.empty?

  value.split(File::PATH_SEPARATOR)
end

Instance Method Details

#patch_fileObject



82
83
84
# File 'lib/testprune/configuration.rb', line 82

def patch_file
  File.join(@output_dir, 'removal.patch')
end

#run_fileObject



78
79
80
# File 'lib/testprune/configuration.rb', line 78

def run_file
  File.join(@output_dir, 'run.json')
end

#source_file?(path) ⇒ Boolean

True when an absolute file path is part of the system-under-test.

Returns:

  • (Boolean)


71
72
73
74
75
76
# File 'lib/testprune/configuration.rb', line 71

def source_file?(path)
  abs = File.expand_path(path)
  return false unless source_roots.any? { |root| abs.start_with?("#{root}/") }

  @exclude_globs.none? { |glob| File.fnmatch?(glob, abs, File::FNM_PATHNAME) }
end

#source_rootsObject

Absolute, existing source roots under which coverage is considered in-scope. Memoized: re-allocating this array on every source_file? call is O(tests * files).



65
66
67
68
# File 'lib/testprune/configuration.rb', line 65

def source_roots
  @source_roots ||= @source_paths.map { |p| File.expand_path(p, @root) }
                                 .select { |p| File.directory?(p) }
end

#to_envObject

Env vars the Runner must export so the subprocess reconstructs this config.



54
55
56
57
58
59
60
61
# File 'lib/testprune/configuration.rb', line 54

def to_env
  {
    'TESTPRUNE_ROOT'         => @root,
    'TESTPRUNE_SOURCE_PATHS' => @source_paths.join(File::PATH_SEPARATOR),
    'TESTPRUNE_EXCLUDE'      => @exclude_globs.join(File::PATH_SEPARATOR),
    'TESTPRUNE_OUTPUT_DIR'   => @output_dir
  }
end