Module: SimpleCov::Configuration

Included in:
SimpleCov
Defined in:
lib/simplecov/configuration.rb,
lib/simplecov/configuration/filters.rb,
lib/simplecov/configuration/merging.rb,
lib/simplecov/configuration/coverage.rb,
lib/simplecov/configuration/formatting.rb,
lib/simplecov/configuration/thresholds.rb,
lib/simplecov/configuration/ignored_entries.rb,
lib/simplecov/configuration/coverage_criteria.rb

Overview

Selection and validation of the coverage criteria Ruby's Coverage library should track. Supports :line (the historical default), :branch, :method, and :oneshot_line, plus the standalone :eval toggle for instrumenting eval'd code.

Defined Under Namespace

Classes: CoverageCriterion

Constant Summary collapse

COVERAGE_THRESHOLD_OPTIONS =

One-liner keyword options coverage accepts, each forwarding to the CoverageCriterion verb of the same name. minimum_per_group is omitted because it needs an only: target, so it's block-only.

%i[minimum maximum exact maximum_drop minimum_per_file].freeze
IGNORABLE_BRANCH_TYPES =

Branch types accepted by ignore_branches.

%i[implicit_else eval_generated].freeze
IGNORABLE_METHOD_TYPES =

Method types accepted by ignore_methods.

%i[eval_generated].freeze
SUPPORTED_COVERAGE_CRITERIA =
%i[line branch method oneshot_line].freeze
DEFAULT_COVERAGE_CRITERION =
:line
ONESHOT_LINE_COVERAGE_CRITERION =
:oneshot_line

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#filtersObject

Returns the list of configured exclusion filters added via skip (or the deprecated add_filter).



88
89
90
# File 'lib/simplecov/configuration/filters.rb', line 88

def filters
  @filters ||= []
end

#formatter(formatter = :__no_arg__) ⇒ Object

Gets or sets the configured formatter. Pass false (or nil) to opt out of formatting entirely — worker processes in big parallel CI setups (see #964) only need their .resultset.json on disk so a final SimpleCov.collate job can produce the report; running them without a formatter saves the per-job HTML/multi-formatter overhead.



19
20
21
22
23
# File 'lib/simplecov/configuration/formatting.rb', line 19

def formatter(formatter = :__no_arg__)
  return @formatter if formatter == :__no_arg__

  @formatter = formatter || nil # normalize `false` to `nil`
end

#groupsObject

Returns the configured groups. Add groups using SimpleCov.group.



125
126
127
# File 'lib/simplecov/configuration/filters.rb', line 125

def groups
  @groups ||= {}
end

DEPRECATED: alias for print_errors. Same value, same behavior.



91
92
93
94
95
# File 'lib/simplecov/configuration/formatting.rb', line 91

def print_error_status
  SimpleCov::Deprecation.warn("`SimpleCov.print_error_status` is deprecated. " \
                              "Replace with `SimpleCov.print_errors` (same value).")
  defined?(@print_error_status) ? @print_error_status : true
end

Instance Method Details

#active_session?Boolean

Whether SimpleCov has anything to do at exit: the Coverage module is actively tracking, or a @result has already been assembled (e.g. by SimpleCov.collate, which never starts Coverage).

Returns:

  • (Boolean)


115
116
117
# File 'lib/simplecov/configuration.rb', line 115

def active_session?
  SimpleCov.result? || (defined?(Coverage) && Coverage.running?)
end

#add_filter(filter_argument = nil, &block) ⇒ Object

DEPRECATED: alias for skip. Same matcher grammar, identical behavior.



103
104
105
106
107
108
# File 'lib/simplecov/configuration/filters.rb', line 103

def add_filter(filter_argument = nil, &block)
  example = block ? "`SimpleCov.skip { ... }`" : "`SimpleCov.skip #{filter_argument.inspect}`"
  SimpleCov::Deprecation.warn("`SimpleCov.add_filter` is deprecated. " \
                              "Replace with `SimpleCov.skip` (same arguments, same behavior). Example: #{example}.")
  skip(filter_argument, &block)
end

#add_group(group_name, filter_argument = nil, &block) ⇒ Object

DEPRECATED: alias for group. Same arguments, same behavior.



138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/simplecov/configuration/filters.rb', line 138

def add_group(group_name, filter_argument = nil, &block)
  example = if block
              "`SimpleCov.group #{group_name.inspect} { ... }`"
            else
              "`SimpleCov.group #{group_name.inspect}, #{filter_argument.inspect}`"
            end
  SimpleCov::Deprecation.warn(
    "`SimpleCov.add_group` is deprecated. " \
    "Replace with `SimpleCov.group` (same arguments, same behavior). Example: #{example}."
  )
  group(group_name, filter_argument, &block)
end

#at_exit(&block) ⇒ Object

Gets or sets the behavior to process coverage results. By default, it stores/merges the current result and formats only from the final reporting process.



101
102
103
104
105
106
107
108
109
110
# File 'lib/simplecov/configuration.rb', line 101

def at_exit(&block)
  @at_exit = block if block
  return @at_exit if @at_exit
  return proc {} unless active_session?

  @at_exit = proc do
    result = SimpleCov.result
    result.format! if result && SimpleCov.merge_finalization_owner? && SimpleCov.final_result_process?
  end
end

#at_fork(&block) ⇒ Object

Gets or sets the behavior to start a new forked Process. Defaults to adding " (subprocess: #serial)" to command_name and starting SimpleCov in quiet mode.



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/simplecov/configuration.rb', line 124

def at_fork(&block)
  @at_fork = block if block
  @at_fork ||= lambda { |_pid|
    # Needs a name that's unique per worker within a run yet identical
    # across runs. Build it from SimpleCov's stable fork serial rather
    # than the OS pid: with the pid, every run produced uniquely-named
    # results that never overwrote the previous run's, so they piled up
    # in .resultset.json until merge_timeout and the merged report's
    # file set drifted from run to run. See issue #1171.
    SimpleCov.command_name "#{SimpleCov.command_name} (subprocess: #{SimpleCov.subprocess_serial})"
    # be quiet, the parent process will use the regular formatter
    SimpleCov.print_errors false
    SimpleCov.formatter SimpleCov::Formatter::SimpleFormatter
    SimpleCov.minimum_coverage 0
    SimpleCov.start
  }
end

#branch_coverage?Boolean

Returns:

  • (Boolean)


71
72
73
# File 'lib/simplecov/configuration/coverage_criteria.rb', line 71

def branch_coverage?
  branch_coverage_supported? && coverage_criterion_enabled?(:branch)
end

#branch_coverage_supported?Boolean

Returns:

  • (Boolean)


75
76
77
# File 'lib/simplecov/configuration/coverage_criteria.rb', line 75

def branch_coverage_supported?
  coverage_criterion_supported?(:branches)
end

#clear_coverage_criteriaObject

Reset the criteria back to the lazy default (Set[:line]).



56
57
58
59
# File 'lib/simplecov/configuration/coverage_criteria.rb', line 56

def clear_coverage_criteria
  @coverage_criteria = nil
  @primary_coverage = nil
end

#clear_filtersObject

Remove every filter from the chain, including the defaults installed by SimpleCov.start.



120
121
122
# File 'lib/simplecov/configuration/filters.rb', line 120

def clear_filters
  @filters = []
end

#color(value = :__no_arg__) ⇒ Object

Get or set whether SimpleCov colorizes its stderr diagnostics. Accepts true (always on), false (always off), or :auto (default: defer to SimpleCov::Color, which checks $stderr.tty? with NO_COLOR and FORCE_COLOR overrides). An explicit true/false wins over both auto-detection and the env vars, which is the right escape hatch when stderr is being piped through a wrapper that still renders ANSI in its own terminal (parallel_tests with --combine-stderr, log multiplexers, some CI runners). See #1157.



49
50
51
52
53
# File 'lib/simplecov/configuration/formatting.rb', line 49

def color(value = :__no_arg__)
  return defined?(@color) ? @color : :auto if value == :__no_arg__

  @color = value
end

#command_name(name = nil) ⇒ Object

The name of the command (a.k.a. Test Suite) currently running. Used for result merging and caching. Auto-detected; set explicitly with SimpleCov.command_name("test:units").



67
68
69
70
71
# File 'lib/simplecov/configuration.rb', line 67

def command_name(name = nil)
  @name = name unless name.nil?
  @name ||= SimpleCov::CommandGuesser.guess
  @name
end

#configure(&block) ⇒ Object

Allows you to configure simplecov in a block instead of prepending SimpleCov to each config method.



82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/simplecov/configuration.rb', line 82

def configure(&block)
  block_context = block.binding.receiver

  # If the block was defined in our own context, instance_exec is sufficient
  return instance_exec(&block) if equal?(block_context)

  # Copy the caller's instance variables in so that references like @filter
  # inside the block resolve to the caller's values, not ours.
  saved = swap_ivars_from(block_context)
  instance_exec(&block)
ensure
  restore_ivars(block_context, saved) if defined?(saved) && saved
end

#cover(*args, &block) ⇒ Object

Restrict the universe of files in the coverage report to those matching one or more globs, regexps, or block predicates. Multiple calls union; when any cover matcher is configured the report drops every file that doesn't match at least one of them.

Strings are interpreted as shell globs (e.g. "lib/**/*.rb"), not substring matches — this is a deliberate departure from the legacy add_filter semantics and matches the way track_files already interprets its argument.

When the matcher is a string-glob, cover also expands the glob on disk so files that exist but were never required during the run still appear in the report (at 0% coverage). This is the "include unloaded files" half of the legacy track_files behavior, rolled into the same call.

SimpleCov.start do
  cover "lib/**/*.rb", "app/**/*.rb"
  cover(/_helper\.rb\z/)
  cover { |sf| sf.lines.count > 5 }
end


34
35
36
37
38
# File 'lib/simplecov/configuration/filters.rb', line 34

def cover(*args, &block)
  args.each { |arg| cover_filters << build_cover_filter(arg) }
  cover_filters << SimpleCov::BlockFilter.new(block) if block
  cover_filters
end

#cover_filtersObject

Returns the list of configured inclusion filters added via cover.



41
42
43
# File 'lib/simplecov/configuration/filters.rb', line 41

def cover_filters
  @cover_filters ||= []
end

#cover_globsObject

Returns the list of string globs passed to cover — used by the disk-discovery pass in SimpleCov.add_not_loaded_files so files matching a cover glob appear in the report even when they were never required during the suite.

Walks into ArrayFilter entries (built when a caller passes an array to cover) so a glob nested inside cover(["lib/**/*.rb", /helper\.rb\z/]) still drives unloaded-file discovery.



53
54
55
# File 'lib/simplecov/configuration/filters.rb', line 53

def cover_globs
  collect_cover_globs(cover_filters)
end

#coverage(criterion, primary: false, enabled: true, oneshot: false, **thresholds, &block) ⇒ Object

Configure (and, unless enabled: false, enable) a coverage criterion.

Threshold options mirror the block verbs for one-liner use:

coverage :branch, minimum: 80, maximum_drop: 5

primary: true makes this the report's leading criterion (and the one a bare minimum_coverage 90 targets). oneshot: true (valid only for :line) selects the faster oneshot-lines mode. :eval is enable-only.



43
44
45
46
47
48
49
50
51
52
# File 'lib/simplecov/configuration/coverage.rb', line 43

def coverage(criterion, primary: false, enabled: true, oneshot: false, **thresholds, &block)
  criterion = enable_coverage_criterion(criterion, enabled: enabled, oneshot: oneshot)
  primary_coverage(criterion) if primary

  configurator = CoverageCriterion.new(self, criterion)
  apply_threshold_options(configurator, thresholds)
  configurator.instance_eval(&block) if block

  criterion
end

#coverage_criteriaObject



47
48
49
# File 'lib/simplecov/configuration/coverage_criteria.rb', line 47

def coverage_criteria
  @coverage_criteria ||= Set[DEFAULT_COVERAGE_CRITERION]
end

#coverage_criterion_enabled?(criterion) ⇒ Boolean

Returns:

  • (Boolean)


51
52
53
# File 'lib/simplecov/configuration/coverage_criteria.rb', line 51

def coverage_criterion_enabled?(criterion)
  coverage_criteria.member?(criterion)
end

#coverage_criterion_supported?(criterion) ⇒ Boolean

Ask the Coverage runtime itself whether a criterion is supported (Ruby >= 3.2). Older Rubies don't expose Coverage.supported?, so fall back to the historical engine check that line/branch/method were unavailable on JRuby. :eval was added later, so on older Rubies its fallback is "always unsupported" rather than the JRuby-only one above. The fallback arm is unreachable from the dogfood report, which runs on a newer Ruby. simplecov:disable

Returns:

  • (Boolean)


99
100
101
102
103
104
# File 'lib/simplecov/configuration/coverage_criteria.rb', line 99

def coverage_criterion_supported?(criterion)
  require "coverage"
  return Coverage.supported?(criterion) if Coverage.respond_to?(:supported?)

  criterion != :eval && RUBY_ENGINE != "jruby"
end

#coverage_dir(dir = nil) ⇒ Object

The name of the output and cache directory. Defaults to 'coverage'

Configure with SimpleCov.coverage_dir('cov')



30
31
32
33
34
35
36
# File 'lib/simplecov/configuration.rb', line 30

def coverage_dir(dir = nil)
  return @coverage_dir if defined?(@coverage_dir) && dir.nil?

  @coverage_path = nil unless @coverage_path_explicit # invalidate cache
  @coverage_dir_explicit = true unless dir.nil?
  @coverage_dir = dir || "coverage"
end

#coverage_for_eval_enabled?Boolean

simplecov:enable

Returns:

  • (Boolean)


107
108
109
# File 'lib/simplecov/configuration/coverage_criteria.rb', line 107

def coverage_for_eval_enabled?
  @coverage_for_eval_enabled ||= false
end

#coverage_for_eval_supported?Boolean

Returns:

  • (Boolean)


87
88
89
# File 'lib/simplecov/configuration/coverage_criteria.rb', line 87

def coverage_for_eval_supported?
  coverage_criterion_supported?(:eval)
end

#coverage_path(path = nil) ⇒ Object

Returns the full path to the output directory. By default constructed from SimpleCov.root + SimpleCov.coverage_dir, but callers can override with an arbitrary absolute path — handy for out-of-tree build directories. See #716.

Reading is pure: the directory is only created when a path is explicitly assigned (the user has signaled they intend to write there). The codepaths that actually write into the directory (formatters, LastRun, ResultsetStore) ensure existence themselves, so read-only CLI subcommands that interpolate the path into status text don't materialize a stray coverage/ directory.



52
53
54
55
56
57
58
59
60
# File 'lib/simplecov/configuration.rb', line 52

def coverage_path(path = nil)
  if path
    @coverage_path = File.expand_path(path)
    @coverage_path_explicit = true
    FileUtils.mkdir_p @coverage_path
  end

  @coverage_path ||= File.expand_path(coverage_dir, root)
end

#current_nocov_token(value = nil) ⇒ Object

Internal accessor used by SimpleCov to recognise # :nocov: markers without emitting the public-API deprecation warning. Will be removed alongside the deprecated nocov_token setter.



113
114
115
116
117
# File 'lib/simplecov/configuration/formatting.rb', line 113

def current_nocov_token(value = nil)
  return @nocov_token if defined?(@nocov_token) && value.nil?

  @nocov_token = value || "nocov"
end

#disable_coverage(criterion) ⇒ Object

Remove criterion from the set of enabled coverage criteria. Disabling every criterion raises at start_tracking (not here), so config files that toggle criteria in arbitrary order don't have to worry about transient empty states.



32
33
34
35
36
# File 'lib/simplecov/configuration/coverage_criteria.rb', line 32

def disable_coverage(criterion)
  raise_if_criterion_unsupported(criterion)
  coverage_criteria.delete(criterion)
  @primary_coverage = nil if @primary_coverage == criterion
end

#enable_coverage(*criteria) ⇒ Object

Enable one or more coverage criteria. :eval is accepted as a shorthand for the standalone eval-coverage toggle.



15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/simplecov/configuration/coverage_criteria.rb', line 15

def enable_coverage(*criteria)
  criteria.each do |criterion|
    if criterion == :eval
      enable_eval_coverage
    else
      raise_if_criterion_unsupported(criterion)
      # :oneshot_lines can not be combined with :lines
      coverage_criteria.delete(DEFAULT_COVERAGE_CRITERION) if criterion == ONESHOT_LINE_COVERAGE_CRITERION
      coverage_criteria << criterion
    end
  end
end

#enable_coverage_for_evalObject

DEPRECATED: prefer enable_coverage :eval.



112
113
114
115
116
# File 'lib/simplecov/configuration/coverage_criteria.rb', line 112

def enable_coverage_for_eval
  SimpleCov::Deprecation.warn("`SimpleCov.enable_coverage_for_eval` is deprecated. " \
                              "Replace with `SimpleCov.enable_coverage :eval`.")
  enable_eval_coverage
end

#enable_for_subprocesses(value = nil) ⇒ Object

DEPRECATED: alias for merge_subprocesses. Same value/behavior.



38
39
40
41
42
43
44
# File 'lib/simplecov/configuration/merging.rb', line 38

def enable_for_subprocesses(value = nil)
  SimpleCov::Deprecation.warn("`SimpleCov.enable_for_subprocesses` is deprecated. " \
                              "Replace with `SimpleCov.merge_subprocesses` (same value, same behavior).")
  return @enable_for_subprocesses if defined?(@enable_for_subprocesses) && value.nil?

  @enable_for_subprocesses = value || false
end

#enabled_for_subprocesses?Boolean

whether to install the fork hook.

Returns:

  • (Boolean)


21
22
23
# File 'lib/simplecov/configuration/merging.rb', line 21

def enabled_for_subprocesses?
  defined?(@enable_for_subprocesses) ? @enable_for_subprocesses : false
end

#expected_coverage(coverage = nil) ⇒ Object

Pins the suite to an exact coverage figure by setting both minimum_coverage and maximum_coverage. See #187.



47
48
49
50
51
52
# File 'lib/simplecov/configuration/thresholds.rb', line 47

def expected_coverage(coverage = nil)
  return minimum_coverage if coverage.nil?

  minimum_coverage(coverage)
  maximum_coverage(coverage)
end

#finalize_merge(value = :__no_arg__) ⇒ Object

Get or set whether this process owns final merge processing: waiting for sibling workers, building the merged result, formatting, enforcing thresholds, and writing .last_run.json.

Defaults to true, except for recognized multi-worker parallel runs that explicitly write to a custom coverage destination while merging is enabled. Those runs are likely using an external SimpleCov.collate step to finalize the merge.



67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/simplecov/configuration/merging.rb', line 67

def finalize_merge(value = :__no_arg__)
  unless value == :__no_arg__
    @finalize_merge = value
    @finalize_merge_explicit = true
  end

  return @finalize_merge if defined?(@finalize_merge_explicit) && @finalize_merge_explicit

  inferred = inferred_finalize_merge?
  warn_about_inferred_finalize_merge unless inferred
  inferred
end

#finalize_merge?Boolean

Returns:

  • (Boolean)


80
81
82
# File 'lib/simplecov/configuration/merging.rb', line 80

def finalize_merge?
  finalize_merge
end

#formatters(formatters = :__no_arg__) ⇒ Object

Sets the configured formatters. Pass [] to opt out of formatting entirely; see formatter for the rationale.



27
28
29
30
31
32
# File 'lib/simplecov/configuration/formatting.rb', line 27

def formatters(formatters = :__no_arg__)
  return Array(formatter) if formatters == :__no_arg__

  self.formatters = formatters
  formatters
end

#formatters=(formatters) ⇒ Object

Sets the configured formatters. Equivalent to formatters [...].



35
36
37
# File 'lib/simplecov/configuration/formatting.rb', line 35

def formatters=(formatters)
  @formatter = formatters.empty? ? nil : SimpleCov::Formatter::MultiFormatter.new(formatters)
end

#group(group_name, filter_argument = nil) ⇒ Object

Define a display group for files. Same matcher grammar as skip, but instead of dropping the matching files it bins them under group_name for the formatter. Files matched by no group fall into the implicit "Ungrouped" bucket.



133
134
135
# File 'lib/simplecov/configuration/filters.rb', line 133

def group(group_name, filter_argument = nil, &)
  groups[group_name] = parse_filter(filter_argument, &)
end

#ignore_branches(*types) ⇒ Object

Variadic; multiple calls union. Setting is recorded regardless of whether branch coverage is enabled at call time. See #1033, #1046.



15
16
17
18
19
# File 'lib/simplecov/configuration/ignored_entries.rb', line 15

def ignore_branches(*types)
  types.each { |type| raise_if_branch_type_unsupported(type) }
  ignored_branches.concat(types).uniq!
  ignored_branches
end

#ignore_methods(*types) ⇒ Object

See ignore_branches. The only supported method-type token today is :eval_generated; see #1046 for the rationale.



31
32
33
34
35
# File 'lib/simplecov/configuration/ignored_entries.rb', line 31

def ignore_methods(*types)
  types.each { |type| raise_if_method_type_unsupported(type) }
  ignored_methods.concat(types).uniq!
  ignored_methods
end

#ignored_branch?(type) ⇒ Boolean

Returns:

  • (Boolean)


25
26
27
# File 'lib/simplecov/configuration/ignored_entries.rb', line 25

def ignored_branch?(type)
  ignored_branches.include?(type)
end

#ignored_branchesObject



21
22
23
# File 'lib/simplecov/configuration/ignored_entries.rb', line 21

def ignored_branches
  @ignored_branches ||= []
end

#ignored_method?(type) ⇒ Boolean

Returns:

  • (Boolean)


41
42
43
# File 'lib/simplecov/configuration/ignored_entries.rb', line 41

def ignored_method?(type)
  ignored_methods.include?(type)
end

#ignored_methodsObject



37
38
39
# File 'lib/simplecov/configuration/ignored_entries.rb', line 37

def ignored_methods
  @ignored_methods ||= []
end

#maximum_coverage(coverage = nil) ⇒ Object

Defines the maximum overall coverage allowed for the testsuite to pass. Useful paired with minimum_coverage (or via expected_coverage) to pin coverage to an exact value, so an unexpected jump up fails the build. See #187.



35
36
37
38
39
40
41
# File 'lib/simplecov/configuration/thresholds.rb', line 35

def maximum_coverage(coverage = nil)
  return @maximum_coverage ||= {} unless coverage

  coverage = {primary_coverage => coverage} if coverage.is_a?(Numeric)
  raise_on_invalid_coverage(coverage, "maximum_coverage")
  @maximum_coverage = coverage
end

#maximum_coverage_drop(coverage_drop = nil) ⇒ Object

Defines the maximum coverage drop at once allowed for the testsuite to pass. Default is 100% (disabled).



58
59
60
61
62
63
64
# File 'lib/simplecov/configuration/thresholds.rb', line 58

def maximum_coverage_drop(coverage_drop = nil)
  return @maximum_coverage_drop ||= {} unless coverage_drop

  coverage_drop = {primary_coverage => coverage_drop} if coverage_drop.is_a?(Numeric)
  raise_on_invalid_coverage(coverage_drop, "maximum_coverage_drop")
  @maximum_coverage_drop = coverage_drop
end

#merge_finalization_owner?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)


85
86
87
# File 'lib/simplecov/configuration/merging.rb', line 85

def merge_finalization_owner?
  collating_result? || finalize_merge?
end

#merge_subprocesses(value = nil) ⇒ Object

Get or set whether SimpleCov should hook Process._fork to attach itself to subprocesses. Required when the suite uses parallel test workers (e.g. Rails' parallelize(workers:)). Defaults to false.



13
14
15
16
17
# File 'lib/simplecov/configuration/merging.rb', line 13

def merge_subprocesses(value = nil)
  return @enable_for_subprocesses if defined?(@enable_for_subprocesses) && value.nil?

  @enable_for_subprocesses = value || false
end

#merge_timeout(seconds = nil) ⇒ Object

Defines the maximum age (in seconds) of a resultset to still be included in merged results. Default is 600 seconds (10 minutes).



101
102
103
104
# File 'lib/simplecov/configuration/merging.rb', line 101

def merge_timeout(seconds = nil)
  @merge_timeout = seconds if seconds.is_a?(Integer)
  @merge_timeout ||= 600
end

#merging(use = nil) ⇒ Object

Get or set whether to merge results from multiple test suites (test:units, test:functionals, cucumber, ...) into a single coverage report. Defaults to true.



51
52
53
54
55
# File 'lib/simplecov/configuration/merging.rb', line 51

def merging(use = nil)
  @use_merging = use unless use.nil?
  @use_merging = true unless defined?(@use_merging) && @use_merging == false
  @use_merging
end

#method_coverage?Boolean

Returns:

  • (Boolean)


79
80
81
# File 'lib/simplecov/configuration/coverage_criteria.rb', line 79

def method_coverage?
  method_coverage_supported? && coverage_criterion_enabled?(:method)
end

#method_coverage_supported?Boolean

Returns:

  • (Boolean)


83
84
85
# File 'lib/simplecov/configuration/coverage_criteria.rb', line 83

def method_coverage_supported?
  coverage_criterion_supported?(:methods)
end

#minimum_coverage(coverage = nil) ⇒ Object

Defines the minimum overall coverage required for the testsuite to pass. Returns non-zero if the current coverage is below this threshold. Default is 0% (disabled).



14
15
16
17
18
19
20
# File 'lib/simplecov/configuration/thresholds.rb', line 14

def minimum_coverage(coverage = nil)
  return @minimum_coverage ||= {} unless coverage

  coverage = {primary_coverage => coverage} if coverage.is_a?(Numeric)
  raise_on_invalid_coverage(coverage, "minimum_coverage")
  @minimum_coverage = coverage
end

#minimum_coverage_by_file(coverage = nil) ⇒ Object

Defines the minimum coverage per file required for the testsuite to pass. Accepts a Numeric (global threshold on the primary criterion), a Symbol-keyed Hash (per-criterion globals), or a Hash mixing Symbol keys with String / Regexp keys to declare per-path overrides. See README and #575.



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/simplecov/configuration/thresholds.rb', line 73

def minimum_coverage_by_file(coverage = nil)
  return @minimum_coverage_by_file ||= {} unless coverage

  coverage = {primary_coverage => coverage} if coverage.is_a?(Numeric)
  defaults, overrides = partition_per_file_thresholds(coverage)

  SimpleCov::Deprecation.warn("`SimpleCov.minimum_coverage_by_file` is deprecated. " \
                              "Replace it with:\n#{per_file_coverage_replacement(defaults, overrides)}")

  raise_on_invalid_coverage(defaults, "minimum_coverage_by_file")
  overrides.each_value { |criteria| raise_on_invalid_coverage(criteria, "minimum_coverage_by_file") }

  @minimum_coverage_by_file = defaults
  @minimum_coverage_by_file_overrides = overrides
end

#minimum_coverage_by_file_overridesObject

Returns the per-path overrides set via minimum_coverage_by_file.



90
91
92
# File 'lib/simplecov/configuration/thresholds.rb', line 90

def minimum_coverage_by_file_overrides
  @minimum_coverage_by_file_overrides ||= {}
end

#minimum_coverage_by_group(coverage = nil) ⇒ Object

Defines the minimum coverage per group required for the testsuite to pass. Default is 0% (disabled).



98
99
100
101
102
103
104
105
106
107
108
# File 'lib/simplecov/configuration/thresholds.rb', line 98

def minimum_coverage_by_group(coverage = nil)
  return @minimum_coverage_by_group ||= {} unless coverage

  SimpleCov::Deprecation.warn("`SimpleCov.minimum_coverage_by_group` is deprecated. " \
                              "Replace it with:\n#{per_group_coverage_replacement(coverage)}")
  @minimum_coverage_by_group = coverage.dup.transform_values do |group_coverage|
    group_coverage = {primary_coverage => group_coverage} if group_coverage.is_a?(Numeric)
    raise_on_invalid_coverage(group_coverage, "minimum_coverage_by_group")
    group_coverage
  end
end

#no_default_skipsObject

Drop every filter previously installed (defaults plus anything earlier in this block) so subsequent skip calls start from a clean slate. Order matters — call this before your own skip invocations.



155
156
157
# File 'lib/simplecov/configuration/filters.rb', line 155

def no_default_skips
  clear_filters
end

#nocov_token(nocov_token = nil) ⇒ Object Also known as: skip_token

DEPRECATED: configure # :nocov: token override. Prefer # simplecov:disable / # simplecov:enable block comments (see SimpleCov::Directive). The # :nocov: toggle and this hook will be removed in a future release.



103
104
105
106
107
# File 'lib/simplecov/configuration/formatting.rb', line 103

def nocov_token(nocov_token = nil)
  SimpleCov::Deprecation.warn("`SimpleCov.nocov_token` and `SimpleCov.skip_token` are deprecated. " \
                              "Replace with `# simplecov:disable` / `# simplecov:enable` block comments.")
  current_nocov_token(nocov_token)
end

#parallel_tests(value = :__no_arg__) ⇒ Object

Get or set whether SimpleCov should auto-require the parallel_tests gem when it sees TEST_ENV_NUMBER / PARALLEL_TEST_GROUPS in the environment. Defaults to auto-detect (nil). See #1018.



31
32
33
34
35
# File 'lib/simplecov/configuration/merging.rb', line 31

def parallel_tests(value = :__no_arg__)
  return defined?(@parallel_tests) ? @parallel_tests : nil if value == :__no_arg__

  @parallel_tests = value
end

#parallel_wait_timeout(seconds = nil) ⇒ Object

Defines how long (in seconds) the reporting process waits for the remaining parallel-test workers to write their resultsets before it proceeds with a partial merge. Default is 60 seconds. Raise it when a slow worker routinely finishes well after the others, so its coverage is still included and the minimum / maximum coverage checks aren't skipped against a partial total.



114
115
116
117
# File 'lib/simplecov/configuration/merging.rb', line 114

def parallel_wait_timeout(seconds = nil)
  @parallel_wait_timeout = seconds if seconds.is_a?(Integer)
  @parallel_wait_timeout ||= 60
end

#primary_coverage(criterion = nil) ⇒ Object



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

def primary_coverage(criterion = nil)
  if criterion.nil?
    @primary_coverage ||= default_primary_coverage
  else
    raise_if_criterion_disabled(criterion)
    @primary_coverage = criterion
  end
end

Get or set whether SimpleCov prints its own diagnostic warnings to stderr. Covers per-check threshold violations, the trailing "SimpleCov failed with exit ..." summary, and the deferred-report / previous-error notices. Defaults to true. Set to false to silence SimpleCov entirely when parsing tooling output (see issue #1155).



62
63
64
65
66
# File 'lib/simplecov/configuration/formatting.rb', line 62

def print_errors(value = :__no_arg__)
  return defined?(@print_error_status) ? @print_error_status : true if value == :__no_arg__

  @print_error_status = value
end

#profilesObject

Returns the hash of available profiles



74
75
76
# File 'lib/simplecov/configuration.rb', line 74

def profiles
  @profiles ||= SimpleCov::Profiles.new
end

#project_name(new_name = nil) ⇒ Object

Returns the project name — defaults to the last dirname in SimpleCov.root, capitalized with underscores → spaces.



146
147
148
149
150
151
# File 'lib/simplecov/configuration.rb', line 146

def project_name(new_name = nil)
  return @project_name if defined?(@project_name) && @project_name && new_name.nil?

  @project_name = new_name if new_name.is_a?(String)
  @project_name ||= File.basename(root).capitalize.tr("_", " ")
end

#raise_on_invalid_coverage(coverage, coverage_setting) ⇒ Object



22
23
24
25
26
27
# File 'lib/simplecov/configuration/thresholds.rb', line 22

def raise_on_invalid_coverage(coverage, coverage_setting)
  coverage.each_key { |criterion| raise_if_criterion_disabled(criterion) }
  coverage.each_value do |percent|
    minimum_possible_coverage_exceeded(coverage_setting) if percent && percent > 100
  end
end

#refuse_coverage_drop(*criteria) ⇒ Object

Refuses any coverage drop. Coverage is only allowed to increase.



113
114
115
116
# File 'lib/simplecov/configuration/thresholds.rb', line 113

def refuse_coverage_drop(*criteria)
  criteria = coverage_criteria if criteria.empty?
  maximum_coverage_drop(criteria.to_h { |c| [c, 0] })
end

#remove_filter(filter_argument) ⇒ Object

Remove any filters whose filter_argument equals the given value. Returns true when at least one filter was removed, false otherwise.



112
113
114
115
116
# File 'lib/simplecov/configuration/filters.rb', line 112

def remove_filter(filter_argument) # rubocop:disable Naming/PredicateMethod
  before = filters.size
  filters.reject! { |filter| filter.respond_to?(:filter_argument) && filter.filter_argument == filter_argument }
  filters.size != before
end

#root(root = nil) ⇒ Object

The root for the project. This defaults to the current working directory.

Configure with SimpleCov.root('/my/project/path')



18
19
20
21
22
23
# File 'lib/simplecov/configuration.rb', line 18

def root(root = nil)
  return @root if defined?(@root) && root.nil?

  @coverage_path = nil unless @coverage_path_explicit # invalidate cache
  @root = File.expand_path(root || Dir.getwd)
end

#skip(filter_argument = nil) ⇒ Object

Drop matching files from the coverage report. The inverse of cover.

See README for the full grammar; skip accepts a String (path-segment substring), Regexp, block predicate, or Array of any of those.



98
99
100
# File 'lib/simplecov/configuration/filters.rb', line 98

def skip(filter_argument = nil, &)
  filters << parse_filter(filter_argument, &)
end

#source_in_json(value = :__no_arg__) ⇒ Object

Get or set whether coverage.json includes the full source-text array for every file. Defaults to true. Set to false when a downstream tool reads the project's source files directly and only needs the coverage metrics, so coverage.json doesn't carry a copy of the source tree (which dominates the payload on larger projects).

The HTML viewer's coverage_data.js always includes source — the client-side renderer needs it. Only coverage.json honors this setting.

SimpleCov.start do
  source_in_json false
end


84
85
86
87
88
# File 'lib/simplecov/configuration/formatting.rb', line 84

def source_in_json(value = :__no_arg__)
  return defined?(@source_in_json) ? @source_in_json : true if value == :__no_arg__

  @source_in_json = value
end

#track_files(glob) ⇒ Object

DEPRECATED: prefer cover, which both includes unloaded files (the historical track_files behavior) and restricts the report to the matching set.



60
61
62
63
64
# File 'lib/simplecov/configuration/filters.rb', line 60

def track_files(glob)
  SimpleCov::Deprecation.warn("`SimpleCov.track_files` is deprecated. " \
                              "#{track_files_replacement_hint(glob)}")
  @tracked_files = glob
end

#track_files_replacement_hint(glob) ⇒ Object

track_files(nil) is the documented way to clear a previously-set glob, but cover(nil) raises ConfigurationError, so don't point users at it. The cover API has no direct equivalent for "reset the inclusion list" — point users at the @cover_filters reset.



70
71
72
73
74
75
76
77
78
79
# File 'lib/simplecov/configuration/filters.rb', line 70

def track_files_replacement_hint(glob)
  if glob.nil?
    "Replace with `SimpleCov.cover_filters.clear` — clearing the inclusion list."
  else
    "Replace with `SimpleCov.cover #{glob.inspect}` — `cover` includes unloaded files on disk " \
      "(the historical `track_files` behavior) and also restricts the report to the matching set. " \
      "If you want to keep additional files outside #{glob.inspect} in the report, pass every " \
      "directory you care about, e.g. `cover #{glob.inspect}, \"app/**/*.rb\"`."
  end
end

#tracked_filesObject

Returns the glob used to include files that were not explicitly required.



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

def tracked_files
  @tracked_files if defined?(@tracked_files)
end

#use_merging(use = nil) ⇒ Object

DEPRECATED: alias for merging. Same value, same behavior.



90
91
92
93
94
95
# File 'lib/simplecov/configuration/merging.rb', line 90

def use_merging(use = nil)
  SimpleCov::Deprecation.warn("`SimpleCov.use_merging` is deprecated. " \
                              "Replace with `SimpleCov.merging` (same value, same behavior).")
  @use_merging = use unless use.nil?
  @use_merging = true unless defined?(@use_merging) && @use_merging == false
end

#validate_coverage_criteria!Object

fast when the user has disabled every coverage criterion.



63
64
65
66
67
68
69
# File 'lib/simplecov/configuration/coverage_criteria.rb', line 63

def validate_coverage_criteria!
  return unless coverage_criteria.empty?

  raise SimpleCov::ConfigurationError,
        "At least one coverage criterion must be enabled. " \
        "Re-enable one with `enable_coverage :line`, `:branch`, or `:method`."
end