Class: Evilution::Config

Inherits:
Object
  • Object
show all
Defined in:
lib/evilution/config.rb

Constant Summary collapse

CONFIG_FILES =
%w[.evilution.yml config/evilution.yml].freeze
DEFAULTS =
{
  timeout: 30,
  format: :text,
  target: nil,
  min_score: 0.0,
  integration: :rspec,
  verbose: false,
  quiet: false,
  jobs: 1,
  fail_fast: nil,
  baseline: true,
  isolation: :auto,
  incremental: false,
  suggest_tests: false,
  progress: true,
  save_session: false,
  line_ranges: {},
  spec_files: [],
  ignore_patterns: [],
  show_disabled: false,
  baseline_session: nil,
  skip_heredoc_literals: false,
  related_specs_heuristic: false,
  fallback_to_full_suite: false,
  preload: nil,
  spec_mappings: {},
  spec_pattern: nil,
  example_targeting: true,
  example_targeting_fallback: :full_file,
  example_targeting_cache: { max_files: 50, max_blocks: 10_000 }
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(**options) ⇒ Config

Returns a new instance of Config.



55
56
57
58
59
60
61
# File 'lib/evilution/config.rb', line 55

def initialize(**options)
  file_options = options.delete(:skip_config_file) ? {} : load_config_file
  env_options = load_env_options
  merged = DEFAULTS.merge(file_options).merge(env_options).merge(options)
  assign_attributes(merged)
  freeze
end

Instance Attribute Details

#baselineObject (readonly)

Returns the value of attribute baseline.



45
46
47
# File 'lib/evilution/config.rb', line 45

def baseline
  @baseline
end

#baseline_sessionObject (readonly)

Returns the value of attribute baseline_session.



45
46
47
# File 'lib/evilution/config.rb', line 45

def baseline_session
  @baseline_session
end

#example_targetingObject (readonly)

Returns the value of attribute example_targeting.



45
46
47
# File 'lib/evilution/config.rb', line 45

def example_targeting
  @example_targeting
end

#example_targeting_cacheObject (readonly)

Returns the value of attribute example_targeting_cache.



45
46
47
# File 'lib/evilution/config.rb', line 45

def example_targeting_cache
  @example_targeting_cache
end

#example_targeting_fallbackObject (readonly)

Returns the value of attribute example_targeting_fallback.



45
46
47
# File 'lib/evilution/config.rb', line 45

def example_targeting_fallback
  @example_targeting_fallback
end

#fail_fastObject (readonly)

Returns the value of attribute fail_fast.



45
46
47
# File 'lib/evilution/config.rb', line 45

def fail_fast
  @fail_fast
end

#fallback_to_full_suiteObject (readonly)

Returns the value of attribute fallback_to_full_suite.



45
46
47
# File 'lib/evilution/config.rb', line 45

def fallback_to_full_suite
  @fallback_to_full_suite
end

#formatObject (readonly)

Returns the value of attribute format.



45
46
47
# File 'lib/evilution/config.rb', line 45

def format
  @format
end

#hooksObject (readonly)

Returns the value of attribute hooks.



45
46
47
# File 'lib/evilution/config.rb', line 45

def hooks
  @hooks
end

#ignore_patternsObject (readonly)

Returns the value of attribute ignore_patterns.



45
46
47
# File 'lib/evilution/config.rb', line 45

def ignore_patterns
  @ignore_patterns
end

#incrementalObject (readonly)

Returns the value of attribute incremental.



45
46
47
# File 'lib/evilution/config.rb', line 45

def incremental
  @incremental
end

#integrationObject (readonly)

Returns the value of attribute integration.



45
46
47
# File 'lib/evilution/config.rb', line 45

def integration
  @integration
end

#isolationObject (readonly)

Returns the value of attribute isolation.



45
46
47
# File 'lib/evilution/config.rb', line 45

def isolation
  @isolation
end

#jobsObject (readonly)

Returns the value of attribute jobs.



45
46
47
# File 'lib/evilution/config.rb', line 45

def jobs
  @jobs
end

#line_rangesObject (readonly)

Returns the value of attribute line_ranges.



45
46
47
# File 'lib/evilution/config.rb', line 45

def line_ranges
  @line_ranges
end

#min_scoreObject (readonly)

Returns the value of attribute min_score.



45
46
47
# File 'lib/evilution/config.rb', line 45

def min_score
  @min_score
end

#preloadObject (readonly)

Returns the value of attribute preload.



45
46
47
# File 'lib/evilution/config.rb', line 45

def preload
  @preload
end

#progressObject (readonly)

Returns the value of attribute progress.



45
46
47
# File 'lib/evilution/config.rb', line 45

def progress
  @progress
end

#quietObject (readonly)

Returns the value of attribute quiet.



45
46
47
# File 'lib/evilution/config.rb', line 45

def quiet
  @quiet
end

Returns the value of attribute related_specs_heuristic.



45
46
47
# File 'lib/evilution/config.rb', line 45

def related_specs_heuristic
  @related_specs_heuristic
end

#save_sessionObject (readonly)

Returns the value of attribute save_session.



45
46
47
# File 'lib/evilution/config.rb', line 45

def save_session
  @save_session
end

#show_disabledObject (readonly)

Returns the value of attribute show_disabled.



45
46
47
# File 'lib/evilution/config.rb', line 45

def show_disabled
  @show_disabled
end

#skip_heredoc_literalsObject (readonly)

Returns the value of attribute skip_heredoc_literals.



45
46
47
# File 'lib/evilution/config.rb', line 45

def skip_heredoc_literals
  @skip_heredoc_literals
end

#spec_filesObject (readonly)

Returns the value of attribute spec_files.



45
46
47
# File 'lib/evilution/config.rb', line 45

def spec_files
  @spec_files
end

#spec_mappingsObject (readonly)

Returns the value of attribute spec_mappings.



45
46
47
# File 'lib/evilution/config.rb', line 45

def spec_mappings
  @spec_mappings
end

#spec_patternObject (readonly)

Returns the value of attribute spec_pattern.



45
46
47
# File 'lib/evilution/config.rb', line 45

def spec_pattern
  @spec_pattern
end

#spec_selectorObject (readonly)

Returns the value of attribute spec_selector.



45
46
47
# File 'lib/evilution/config.rb', line 45

def spec_selector
  @spec_selector
end

#suggest_testsObject (readonly)

Returns the value of attribute suggest_tests.



45
46
47
# File 'lib/evilution/config.rb', line 45

def suggest_tests
  @suggest_tests
end

#targetObject (readonly)

Returns the value of attribute target.



45
46
47
# File 'lib/evilution/config.rb', line 45

def target
  @target
end

#target_filesObject (readonly)

Returns the value of attribute target_files.



45
46
47
# File 'lib/evilution/config.rb', line 45

def target_files
  @target_files
end

#timeoutObject (readonly)

Returns the value of attribute timeout.



45
46
47
# File 'lib/evilution/config.rb', line 45

def timeout
  @timeout
end

#verboseObject (readonly)

Returns the value of attribute verbose.



45
46
47
# File 'lib/evilution/config.rb', line 45

def verbose
  @verbose
end

Class Method Details

.default_templateObject

Generates a default config file template.



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# File 'lib/evilution/config.rb', line 143

def self.default_template
  <<~YAML
    # Evilution configuration
    # See: https://github.com/marinazzio/evilution

    # Per-mutation timeout in seconds (default: 30)
    # timeout: 30

    # Output format: text or json (default: text)
    # format: text

    # Minimum mutation score to pass (0.0 to 1.0, default: 0.0)
    # min_score: 0.0

    # Test integration: rspec, minitest (default: rspec)
    # integration: rspec

    # Number of parallel workers (default: 1)
    # jobs: 1

    # Stop after N surviving mutants (default: disabled)
    # fail_fast: 1

    # Generate concrete test code in suggestions, matching integration (default: false)
    # suggest_tests: false

    # Skip all string literal mutations inside heredocs (default: false).
    # Useful for Rails apps where heredoc content (SQL, templates, fixtures)
    # rarely has meaningful test coverage and produces noisy survivors.
    # skip_heredoc_literals: true

    # Opt into the RelatedSpecHeuristic, which appends request/integration/
    # feature/system specs for mutations that touch `.includes(...)` calls
    # (default: false). Off by default because the fan-out can be heavy and
    # push runs over the per-mutation timeout. Enable if you need coverage
    # of N+1 regressions that only surface in higher-level specs.
    # related_specs_heuristic: true

    # When no matching spec resolves for a mutation's source file, the
    # default is to skip that mutation and mark it :unresolved in the
    # report (a coverage gap signal). Set to true to fall back to running
    # the entire test suite for such mutations instead (slow, high memory).
    # fallback_to_full_suite: false

    # Preload file required in the parent process before forking workers.
    # For Rails projects, spec/rails_helper.rb or test/test_helper.rb is
    # auto-detected when isolation resolves to :fork. Set to false to disable.
    # preload: spec/rails_helper.rb # or test/test_helper.rb

    # Hooks: Ruby files returning a Proc, keyed by lifecycle event
    # hooks:
    #   worker_process_start: config/evilution_hooks/worker_start.rb
    #   mutation_insert_pre: config/evilution_hooks/mutation_pre.rb

    # Per-mutation example targeting (default: true). When enabled, Evilution
    # parses resolved spec files and restricts each mutation run to examples
    # whose bodies reference the mutated method/class token. Set to false
    # to run every example in the resolved spec files. You can also disable
    # without editing the file by exporting EV_DISABLE_EXAMPLE_TARGETING=1.
    # example_targeting: true

    # Behavior when targeting finds no matching example (default: full_file).
    # full_file  - run every example in the resolved spec files
    # unresolved - mark the mutation :unresolved and skip
    # example_targeting_fallback: full_file

    # LRU cache bounds for the spec AST parser that powers example targeting.
    # example_targeting_cache:
    #   max_files: 50
    #   max_blocks: 10000

    # AST patterns to skip during mutation generation (default: [])
    # See docs/ast_pattern_syntax.md for pattern syntax
    # ignore_patterns:
    #   - "call{name=info, receiver=call{name=logger}}"
    #   - "call{name=debug|warn}"
  YAML
end

.file_optionsObject



127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/evilution/config.rb', line 127

def self.file_options
  CONFIG_FILES.each do |path|
    next unless File.exist?(path)

    data = YAML.safe_load_file(path, symbolize_names: true)
    return data.is_a?(Hash) ? data : {}
  rescue Psych::SyntaxError, Psych::DisallowedClass => e
    raise Evilution::ConfigError.new("failed to parse config file #{path}: #{e.message}", file: path)
  rescue SystemCallError => e
    raise Evilution::ConfigError.new("cannot read config file #{path}: #{e.message}", file: path)
  end

  {}
end

Instance Method Details

#baseline?Boolean

Returns:

  • (Boolean)


87
88
89
# File 'lib/evilution/config.rb', line 87

def baseline?
  baseline
end

#example_targeting?Boolean

Returns:

  • (Boolean)


119
120
121
# File 'lib/evilution/config.rb', line 119

def example_targeting?
  example_targeting
end

#fail_fast?Boolean

Returns:

  • (Boolean)


83
84
85
# File 'lib/evilution/config.rb', line 83

def fail_fast?
  !fail_fast.nil?
end

#fallback_to_full_suite?Boolean

Returns:

  • (Boolean)


123
124
125
# File 'lib/evilution/config.rb', line 123

def fallback_to_full_suite?
  fallback_to_full_suite
end

#html?Boolean

Returns:

  • (Boolean)


71
72
73
# File 'lib/evilution/config.rb', line 71

def html?
  format == :html
end

#incremental?Boolean

Returns:

  • (Boolean)


91
92
93
# File 'lib/evilution/config.rb', line 91

def incremental?
  incremental
end

#json?Boolean

Returns:

  • (Boolean)


63
64
65
# File 'lib/evilution/config.rb', line 63

def json?
  format == :json
end

#line_ranges?Boolean

Returns:

  • (Boolean)


75
76
77
# File 'lib/evilution/config.rb', line 75

def line_ranges?
  !line_ranges.empty?
end

#progress?Boolean

Returns:

  • (Boolean)


99
100
101
# File 'lib/evilution/config.rb', line 99

def progress?
  progress
end

Returns:

  • (Boolean)


115
116
117
# File 'lib/evilution/config.rb', line 115

def related_specs_heuristic?
  related_specs_heuristic
end

#save_session?Boolean

Returns:

  • (Boolean)


103
104
105
# File 'lib/evilution/config.rb', line 103

def save_session?
  save_session
end

#show_disabled?Boolean

Returns:

  • (Boolean)


107
108
109
# File 'lib/evilution/config.rb', line 107

def show_disabled?
  show_disabled
end

#skip_heredoc_literals?Boolean

Returns:

  • (Boolean)


111
112
113
# File 'lib/evilution/config.rb', line 111

def skip_heredoc_literals?
  skip_heredoc_literals
end

#suggest_tests?Boolean

Returns:

  • (Boolean)


95
96
97
# File 'lib/evilution/config.rb', line 95

def suggest_tests?
  suggest_tests
end

#target?Boolean

Returns:

  • (Boolean)


79
80
81
# File 'lib/evilution/config.rb', line 79

def target?
  !target.nil?
end

#text?Boolean

Returns:

  • (Boolean)


67
68
69
# File 'lib/evilution/config.rb', line 67

def text?
  format == :text
end