123456789_123456789_123456789_123456789_123456789_

Module: SimpleCov::Configuration

Overview

Bundles the configuration options used for ::SimpleCov. All methods defined here are usable from ::SimpleCov directly. Please check out ::SimpleCov documentation for further info.

Constant Summary

Instance Attribute Summary

Instance Method Summary

Instance Attribute Details

#active_session?Boolean (readonly)

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).

[ GitHub ]

  
# File 'lib/simplecov/configuration.rb', line 110

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

#branch_coverage?Boolean (readonly)

[ GitHub ]

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

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

#branch_coverage_supported?Boolean (readonly)

[ GitHub ]

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

def branch_coverage_supported?
  coverage_criterion_supported?(:branches)
end

#coverage_for_eval_enabled?Boolean (readonly)

simplecov:enable

[ GitHub ]

  
# 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 (readonly)

[ GitHub ]

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

def coverage_for_eval_supported?
  coverage_criterion_supported?(:eval)
end

#enabled_for_subprocesses?Boolean (readonly)

This method is for internal use only.

whether to install the fork hook.

[ GitHub ]

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

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

#filters (rw)

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

[ GitHub ]

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

def filters
  @filters ||= []
end

#filters=(value) (rw)

[ GitHub ]

  
# File 'lib/simplecov/configuration/filters.rb', line 9

attr_writer :filters, :groups

#formatter(formatter = :__no_arg__) (rw)

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.

[ GitHub ]

  
# 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

#formatter=(value) (rw)

[ GitHub ]

  
# File 'lib/simplecov/configuration/formatting.rb', line 9

attr_writer :formatter, :print_error_status

#groups (rw)

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

[ GitHub ]

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

def groups
  @groups ||= {}
end

#groups=(value) (rw)

[ GitHub ]

  
# File 'lib/simplecov/configuration/filters.rb', line 9

attr_writer :filters, :groups

#method_coverage?Boolean (readonly)

[ GitHub ]

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

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

#method_coverage_supported?Boolean (readonly)

[ GitHub ]

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

def method_coverage_supported?
  coverage_criterion_supported?(:methods)
end

Instance Method Details

#add_filter(filter_argument = nil, &block)

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

[ GitHub ]

  
# File 'lib/simplecov/configuration/filters.rb', line 103

def add_filter(filter_argument = nil, &block)
  example = block ? "`SimpleCov.skip { ... }`" : "`SimpleCov.skip #{filter_argument.inspect}`"
  warn "#{Kernel.caller.first}: [DEPRECATION] `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)

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

[ GitHub ]

  
# 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
  warn "#{Kernel.caller.first}: [DEPRECATION] `SimpleCov.add_group` is deprecated. " \
       "Replace with `SimpleCov.group` (same arguments, same behavior). Example: #{example}."
  group(group_name, filter_argument, &block)
end

#apply_threshold_options(configurator, options) (private)

Forward the one-liner threshold keywords (coverage <code>:branch</code>, minimum: 80) to the matching Configuration::CoverageCriterion verbs, rejecting anything that isn't a recognized threshold option.

[ GitHub ]

  
# File 'lib/simplecov/configuration/coverage.rb', line 59

def apply_threshold_options(configurator, options)
  options.each do |verb, value|
    unless COVERAGE_THRESHOLD_OPTIONS.include?(verb)
      raise SimpleCov::ConfigurationError,
            "Unknown `coverage` option #{verb.inspect}. " \
            "Supported options are #{COVERAGE_THRESHOLD_OPTIONS.inspect}."
    end

    configurator.public_send(verb, value)
  end
end

#at_exit(&block)

Gets or sets the behavior to process coverage results. By default, it calls SimpleCov.result.format!

[ GitHub ]

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

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

  @at_exit = proc { SimpleCov.result.format! }
end

#at_fork(&block)

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

[ GitHub ]

  
# File 'lib/simplecov/configuration.rb', line 119

def at_fork(&block)
  @at_fork = block if block
  @at_fork ||= lambda { |pid|
    # This needs a unique name so it won't be overwritten
    SimpleCov.command_name "#{SimpleCov.command_name} (subprocess: #{pid})"
    # 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

#build_cover_filter(arg) (private)

Build a filter for a #cover argument. Strings are treated as globs (not substrings — that's #skip/add_filter's semantics).

[ GitHub ]

  
# File 'lib/simplecov/configuration/filters.rb', line 170

def build_cover_filter(arg)
  case arg
  when String            then SimpleCov::GlobFilter.new(arg)
  when Regexp            then SimpleCov::RegexFilter.new(arg)
  when Proc              then SimpleCov::BlockFilter.new(arg)
  when SimpleCov::Filter then arg
  when Array             then SimpleCov::ArrayFilter.new(arg.map { |a| build_cover_filter(a) })
  else raise SimpleCov::ConfigurationError, "Unsupported `cover` argument #{arg.inspect}; " \
                                            "expected a String glob, Regexp, Proc, " \
                                            "SimpleCov::Filter, or Array of those."
  end
end

#clear_coverage_criteria

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

[ GitHub ]

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

def clear_coverage_criteria
  @coverage_criteria = nil
  @primary_coverage = nil
end

#clear_filters

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

[ GitHub ]

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

def clear_filters
  @filters = []
end

#collect_cover_globs(filter_list) (private)

Walk a list of cover filters and return the string globs they hold, descending into ArrayFilter wrappers built by cover(["a", "b"]).

[ GitHub ]

  
# File 'lib/simplecov/configuration/filters.rb', line 185

def collect_cover_globs(filter_list)
  filter_list.flat_map do |filter|
    case filter
    when SimpleCov::GlobFilter  then filter.filter_argument
    when SimpleCov::ArrayFilter then collect_cover_globs(filter.filter_argument)
    else []
    end
  end
end

#color(value = :__no_arg__)

Get or set whether ::SimpleCov colorizes its stderr diagnostics. Accepts true (always on), false (always off), or :auto (default: defer to 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.

[ GitHub ]

  
# 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)

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").

[ GitHub ]

  
# File 'lib/simplecov/configuration.rb', line 66

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

#configure(&block)

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

[ GitHub ]

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

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)

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
[ GitHub ]

  
# 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_filters

Returns the list of configured inclusion filters added via #cover.

[ GitHub ]

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

def cover_filters
  @cover_filters ||= []
end

#cover_globs

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.

[ GitHub ]

  
# 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)

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.

[ GitHub ]

  
# 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_criteria

[ GitHub ]

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

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

#coverage_criterion_enabled?(criterion) ⇒ Boolean

[ GitHub ]

  
# 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

[ GitHub ]

  
# 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)

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

Configure with SimpleCov.coverage_dir('cov')

[ GitHub ]

  
# 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 = dir || "coverage"
end

#coverage_path(path = nil)

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.

[ GitHub ]

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

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)

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.

[ GitHub ]

  
# 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

#default_primary_coverage (private)

If :line is enabled, it's the default primary; otherwise fall back to whichever criterion the user actually enabled (in insertion order). Returning :line even when disabled would propagate broken state into minimum_coverage 90.

[ GitHub ]

  
# File 'lib/simplecov/configuration/coverage_criteria.rb', line 134

def default_primary_coverage
  return DEFAULT_COVERAGE_CRITERION if coverage_criterion_enabled?(DEFAULT_COVERAGE_CRITERION)

  coverage_criteria.first
end

#disable_coverage(criterion)

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

[ GitHub ]

  
# 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)

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

[ GitHub ]

  
# 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_criterion(criterion, enabled:, oneshot:) (private)

Enable the criterion (or its oneshot / eval variant) and return the criterion symbol that thresholds should be stored under.

[ GitHub ]

  
# File 'lib/simplecov/configuration/coverage.rb', line 73

def enable_coverage_criterion(criterion, enabled:, oneshot:)
  return enable_oneshot_line(criterion) if oneshot
  return enable_eval_coverage_criterion if criterion == :eval

  enabled ? enable_coverage(criterion) : disable_coverage(criterion)
  criterion
end

#enable_coverage_for_eval

DEPRECATED: prefer enable_coverage :eval.

[ GitHub ]

  
# File 'lib/simplecov/configuration/coverage_criteria.rb', line 112

def enable_coverage_for_eval
  warn "#{Kernel.caller.first}: [DEPRECATION] `SimpleCov.enable_coverage_for_eval` is deprecated. " \
       "Replace with `SimpleCov.enable_coverage :eval`."
  enable_eval_coverage
end

#enable_eval_coverage (private)

Shared implementation backing both enable_coverage :eval and the deprecated #enable_coverage_for_eval.

[ GitHub ]

  
# File 'lib/simplecov/configuration/coverage_criteria.rb', line 122

def enable_eval_coverage
  if coverage_for_eval_supported?
    @coverage_for_eval_enabled = true
  else
    warn "Coverage for eval is not available; Use Ruby 3.2.0 or later"
  end
end

#enable_eval_coverage_criterion (private)

[ GitHub ]

  
# File 'lib/simplecov/configuration/coverage.rb', line 90

def enable_eval_coverage_criterion
  enable_coverage(:eval)
  :eval
end

#enable_for_subprocesses(value = nil)

DEPRECATED: alias for #merge_subprocesses. Same value/behavior.

[ GitHub ]

  
# File 'lib/simplecov/configuration/merging.rb', line 38

def enable_for_subprocesses(value = nil)
  warn "#{Kernel.caller.first}: [DEPRECATION] `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

#enable_oneshot_line(criterion) (private)

[ GitHub ]

  
# File 'lib/simplecov/configuration/coverage.rb', line 81

def enable_oneshot_line(criterion)
  unless criterion == :line
    raise SimpleCov::ConfigurationError, "`oneshot: true` is only valid for `coverage :line`"
  end

  enable_coverage(ONESHOT_LINE_COVERAGE_CRITERION)
  ONESHOT_LINE_COVERAGE_CRITERION
end

#expected_coverage(coverage = nil)

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

[ GitHub ]

  
# 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

#formatters(formatters = :__no_arg__)

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

[ GitHub ]

  
# 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)

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

[ GitHub ]

  
# 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)

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.

[ GitHub ]

  
# 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)

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

[ GitHub ]

  
# 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)

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

[ GitHub ]

  
# 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

[ GitHub ]

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

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

#ignored_branches

[ GitHub ]

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

def ignored_branches
  @ignored_branches ||= []
end

#ignored_method?(type) ⇒ Boolean

[ GitHub ]

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

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

#ignored_methods

[ GitHub ]

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

def ignored_methods
  @ignored_methods ||= []
end

#maximum_coverage(coverage = nil)

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.

[ GitHub ]

  
# 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)

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

[ GitHub ]

  
# 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_subprocesses(value = nil)

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.

[ GitHub ]

  
# 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)

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

[ GitHub ]

  
# File 'lib/simplecov/configuration/merging.rb', line 69

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

#merging(use = nil)

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

[ GitHub ]

  
# 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

#minimum_coverage(coverage = nil)

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).

[ GitHub ]

  
# 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)

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.

[ GitHub ]

  
# 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)

  warn "#{Kernel.caller.first}: [DEPRECATION] `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_overrides

Returns the per-path overrides set via #minimum_coverage_by_file.

[ GitHub ]

  
# 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)

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

[ GitHub ]

  
# File 'lib/simplecov/configuration/thresholds.rb', line 98

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

  warn "#{Kernel.caller.first}: [DEPRECATION] `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

#minimum_possible_coverage_exceeded(coverage_option) (private)

[ GitHub ]

  
# File 'lib/simplecov/configuration/thresholds.rb', line 138

def minimum_possible_coverage_exceeded(coverage_option)
  warn "The coverage you set for #{coverage_option} is greater than 100%"
end

#no_default_skips

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.

[ GitHub ]

  
# File 'lib/simplecov/configuration/filters.rb', line 153

def no_default_skips
  clear_filters
end

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

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

[ GitHub ]

  
# File 'lib/simplecov/configuration/formatting.rb', line 103

def nocov_token(nocov_token = nil)
  warn "#{Kernel.caller.first}: [DEPRECATION] `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__)

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.

[ GitHub ]

  
# 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

#parse_filter(filter_argument = nil, &filter_proc) (private)

The actual filter processor. Not meant for direct use.

Raises:

  • (ArgumentError)
[ GitHub ]

  
# File 'lib/simplecov/configuration/filters.rb', line 160

def parse_filter(filter_argument = nil, &filter_proc)
  filter = filter_argument || filter_proc

  raise ArgumentError, "Please specify either a filter or a block to filter with" unless filter

  SimpleCov::Filter.build_filter(filter)
end

#partition_per_file_thresholds(coverage) (private)

Split a #minimum_coverage_by_file argument into Symbol-keyed criterion defaults and String/Regexp-keyed per-path overrides; normalize Numeric override values to {primary_coverage => N} so downstream code only has one shape to handle.

[ GitHub ]

  
# File 'lib/simplecov/configuration/thresholds.rb', line 124

def partition_per_file_thresholds(coverage)
  coverage.each_key { |key| validate_per_file_key(key) }
  defaults, raw = coverage.partition { |key, _| key.is_a?(Symbol) }.map(&:to_h)
  overrides = raw.transform_values { |value| value.is_a?(Numeric) ? {primary_coverage => value} : value }
  [defaults, overrides]
end

#per_file_coverage_replacement(defaults, overrides) (private)

Render the #coverage configuration equivalent to a (deprecated) #minimum_coverage_by_file argument so the deprecation warning can be copy-pasted verbatim into the user's config.

[ GitHub ]

  
# File 'lib/simplecov/configuration/thresholds.rb', line 145

def per_file_coverage_replacement(defaults, overrides)
  by_criterion = Hash.new { |hash, criterion| hash[criterion] = [] }
  defaults.each { |criterion, percent| by_criterion[criterion] << "minimum_per_file #{percent}" }
  overrides.each do |target, criteria|
    criteria.each do |criterion, percent|
      by_criterion[criterion] << "minimum_per_file #{percent}, only: #{target.inspect}"
    end
  end
  render_coverage_blocks(by_criterion)
end

#per_group_coverage_replacement(coverage) (private)

Same, for a (deprecated) #minimum_coverage_by_group argument.

[ GitHub ]

  
# File 'lib/simplecov/configuration/thresholds.rb', line 157

def per_group_coverage_replacement(coverage)
  by_criterion = Hash.new { |hash, criterion| hash[criterion] = [] }
  coverage.each do |group_name, group_coverage|
    group_coverage = {primary_coverage => group_coverage} if group_coverage.is_a?(Numeric)
    group_coverage.each do |criterion, percent|
      by_criterion[criterion] << "minimum_per_group #{percent}, only: #{group_name.inspect}"
    end
  end
  render_coverage_blocks(by_criterion)
end

#primary_coverage(criterion = nil)

[ GitHub ]

  
# 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

#profiles

Returns the hash of available profiles

[ GitHub ]

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

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

#project_name(new_name = nil)

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

[ GitHub ]

  
# File 'lib/simplecov/configuration.rb', line 136

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_if_branch_type_unsupported(type) (private)

[ GitHub ]

  
# File 'lib/simplecov/configuration/ignored_entries.rb', line 47

def raise_if_branch_type_unsupported(type)
  return if IGNORABLE_BRANCH_TYPES.member?(type)

  raise SimpleCov::ConfigurationError,
        "Unsupported branch type #{type.inspect} for `ignore_branches`. " \
        "Supported values are #{IGNORABLE_BRANCH_TYPES.inspect}"
end

#raise_if_criterion_disabled(criterion) (private)

[ GitHub ]

  
# File 'lib/simplecov/configuration/coverage_criteria.rb', line 140

def raise_if_criterion_disabled(criterion)
  raise_if_criterion_unsupported(criterion)
  return if coverage_criterion_enabled?(criterion)

  raise SimpleCov::ConfigurationError,
        "Coverage criterion #{criterion}, is disabled! " \
        "Please enable it first through enable_coverage #{criterion} (if supported)"
end

#raise_if_criterion_unsupported(criterion) (private)

[ GitHub ]

  
# File 'lib/simplecov/configuration/coverage_criteria.rb', line 149

def raise_if_criterion_unsupported(criterion)
  return if SUPPORTED_COVERAGE_CRITERIA.member?(criterion)

  raise SimpleCov::ConfigurationError,
        "Unsupported coverage criterion #{criterion}, supported values are #{SUPPORTED_COVERAGE_CRITERIA}"
end

#raise_if_method_type_unsupported(type) (private)

[ GitHub ]

  
# File 'lib/simplecov/configuration/ignored_entries.rb', line 55

def raise_if_method_type_unsupported(type)
  return if IGNORABLE_METHOD_TYPES.member?(type)

  raise SimpleCov::ConfigurationError,
        "Unsupported method type #{type.inspect} for `ignore_methods`. " \
        "Supported values are #{IGNORABLE_METHOD_TYPES.inspect}"
end

#raise_on_invalid_coverage(coverage, coverage_setting)

[ GitHub ]

  
# 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)

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

[ GitHub ]

  
# 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)

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

[ GitHub ]

  
# 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

#render_coverage_blocks(by_criterion) (private)

[ GitHub ]

  
# File 'lib/simplecov/configuration/thresholds.rb', line 168

def render_coverage_blocks(by_criterion)
  by_criterion.map do |criterion, statements|
    "  coverage(#{criterion.inspect}) { #{statements.join('; ')} }"
  end.join("\n")
end

#restore_ivars(block_context, saved) (private)

Copy instance variables back to block_context and restore our saved values.

[ GitHub ]

  
# File 'lib/simplecov/configuration.rb', line 159

def restore_ivars(block_context, saved)
  block_context.instance_variables.each do |ivar|
    block_context.instance_variable_set(ivar, instance_variable_get(ivar))
  end
  saved.each { |ivar, value| instance_variable_set(ivar, value) }
end

#root(root = nil)

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

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

[ GitHub ]

  
# 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)

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.

[ GitHub ]

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

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

#skip_token(nocov_token = nil)

Alias for #nocov_token.

[ GitHub ]

  
# File 'lib/simplecov/configuration/formatting.rb', line 108

alias skip_token nocov_token

#source_in_json(value = :__no_arg__)

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
[ GitHub ]

  
# 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

#store_minimum_per_file(criterion, percent, target) (private)

[ GitHub ]

  
# File 'lib/simplecov/configuration/coverage.rb', line 103

def store_minimum_per_file(criterion, percent, target)
  raise_on_invalid_coverage({criterion => percent}, "minimum_coverage_by_file")
  return minimum_coverage_by_file[criterion] = percent if target.nil?

  unless target.is_a?(String) || target.is_a?(Regexp)
    raise SimpleCov::ConfigurationError, "`only:` must be a String path or Regexp, got #{target.inspect}"
  end

  (minimum_coverage_by_file_overrides[target] ||= {})[criterion] = percent
end

#store_minimum_per_group(criterion, percent, group_name) (private)

[ GitHub ]

  
# File 'lib/simplecov/configuration/coverage.rb', line 114

def store_minimum_per_group(criterion, percent, group_name)
  raise_on_invalid_coverage({criterion => percent}, "minimum_coverage_by_group")
  (minimum_coverage_by_group[group_name] ||= {})[criterion] = percent
end

#store_overall_threshold(setting, criterion, percent) (private)

This method is for internal use only.

write the same @minimum_coverage / @maximum_coverage / ... hashes the flat threshold methods populate, so the exit-code checks are unchanged.

[ GitHub ]

  
# File 'lib/simplecov/configuration/coverage.rb', line 98

def store_overall_threshold(setting, criterion, percent)
  raise_on_invalid_coverage({criterion => percent}, setting.to_s)
  public_send(setting)[criterion] = percent
end

#swap_ivars_from(block_context) (private)

Copy instance variables from block_context into self, saving any of ours that would be clobbered. Returns the saved values for later restoration.

[ GitHub ]

  
# File 'lib/simplecov/configuration.rb', line 148

def swap_ivars_from(block_context)
  saved = {}
  our_ivars = instance_variables
  block_context.instance_variables.each do |ivar|
    saved[ivar] = instance_variable_get(ivar) if our_ivars.include?(ivar)
    instance_variable_set(ivar, block_context.instance_variable_get(ivar))
  end
  saved
end

#track_files(glob)

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

[ GitHub ]

  
# File 'lib/simplecov/configuration/filters.rb', line 60

def track_files(glob)
  warn "#{Kernel.caller.first}: [DEPRECATION] `SimpleCov.track_files` is deprecated. " \
       "#{track_files_replacement_hint(glob)}"
  @tracked_files = glob
end

#track_files_replacement_hint(glob)

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.

[ GitHub ]

  
# 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_files

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

[ GitHub ]

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

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

#use_merging(use = nil)

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

[ GitHub ]

  
# File 'lib/simplecov/configuration/merging.rb', line 58

def use_merging(use = nil)
  warn "#{Kernel.caller.first}: [DEPRECATION] `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!

This method is for internal use only.

fast when the user has disabled every coverage criterion.

[ GitHub ]

  
# 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

#validate_per_file_key(key) (private)

[ GitHub ]

  
# File 'lib/simplecov/configuration/thresholds.rb', line 131

def validate_per_file_key(key)
  return if key.is_a?(Symbol) || key.is_a?(String) || key.is_a?(Regexp)

  raise SimpleCov::ConfigurationError,
        "minimum_coverage_by_file keys must be Symbol (criterion), String, or Regexp; got #{key.inspect}"
end