module SimpleCov

def adapt_coverage_result

Returns:
  • (Hash) -
def adapt_coverage_result
  @result = SimpleCov::ResultAdapter.call(Coverage.result)
end

def add_not_loaded_files(result)


the line-by-line coverage to zero (if relevant) or nil (comments / whitespace etc).
Finds files that were to be tracked but were not loaded and initializes
def add_not_loaded_files(result)
  if tracked_files
    result = result.dup
    Dir[tracked_files].each do |file|
      absolute_path = File.expand_path(file)
      result[absolute_path] ||= SimulateCoverage.call(absolute_path)
    end
  end
  result
end

def clear_result


Clear out the previously cached .result. Primarily useful in testing
def clear_result
  @result = nil
end

def collate(result_filenames, profile = nil, &block)


information about coverage collation
available config options, or checkout the README for more in-depth
Please check out the RDoc for SimpleCov::Configuration to find about

end
add_filter 'test'
SimpleCov.collate Dir["simplecov-resultset-*/.resultset.json"], 'rails' do
OR
end
add_filter 'test'
SimpleCov.collate Dir["simplecov-resultset-*/.resultset.json"] do
OR
SimpleCov.collate Dir["simplecov-resultset-*/.resultset.json"], 'rails' # using rails profile
OR
SimpleCov.collate Dir["simplecov-resultset-*/.resultset.json"]
You can optionally specify configuration with a block:
Collate a series of SimpleCov result files into a single SimpleCov output.
def collate(result_filenames, profile = nil, &block)
  raise "There's no reports to be merged" if result_filenames.empty?
  initial_setup(profile, &block)
  results = result_filenames.flat_map do |filename|
    # Re-create each included instance of SimpleCov::Result from the stored run data.
    (JSON.parse(File.read(filename)) || {}).map do |command_name, coverage|
      SimpleCov::Result.from_hash(command_name => coverage)
    end
  end
  # Use the ResultMerger to produce a single, merged result, ready to use.
  @result = SimpleCov::ResultMerger.merge_and_store(*results)
  run_exit_tasks!
end

def exit_status_from_exception


Returns the exit status from the exit exception
def exit_status_from_exception
  return SimpleCov::ExitCodes::SUCCESS unless exit_exception
  if exit_exception.is_a?(SystemExit)
    exit_exception.status
  else
    SimpleCov::ExitCodes::EXCEPTION
  end
end

def filtered(files)


Applies the configured filters to the given array of SimpleCov::SourceFile items
def filtered(files)
  result = files.clone
  filters.each do |filter|
    result = result.reject { |source_file| filter.matches?(source_file) }
  end
  SimpleCov::FileList.new result
end

def final_result_process?

Other tags:
    Api: - private
def final_result_process?
  # checking for ENV["TEST_ENV_NUMBER"] to determine if the tess are being run in parallel
  !defined?(ParallelTests) || !ENV["TEST_ENV_NUMBER"] || ParallelTests.number_of_running_processes <= 1
end

def grouped(files)


Applies the configured groups to the given array of SimpleCov::SourceFile items
def grouped(files)
  grouped = {}
  grouped_files = []
  groups.each do |name, filter|
    grouped[name] = SimpleCov::FileList.new(files.select { |source_file| filter.matches?(source_file) })
    grouped_files += grouped[name]
  end
  if !groups.empty? && !(other_files = files.reject { |source_file| grouped_files.include?(source_file) }).empty?
    grouped["Ungrouped"] = SimpleCov::FileList.new(other_files)
  end
  grouped
end

def initial_setup(profile, &block)

def initial_setup(profile, &block)
  load_profile(profile) if profile
  configure(&block) if block_given?
  self.running = true
end

def load_adapter(name)

def load_adapter(name)
  warn "#{Kernel.caller.first}: [DEPRECATION] #load_adapter is deprecated. Use #load_profile instead."
  load_profile(name)
end

def load_profile(name)


Applies the profile of given name on SimpleCov configuration
def load_profile(name)
  profiles.load(name)
end

def lookup_corresponding_ruby_coverage_name(criterion)

def lookup_corresponding_ruby_coverage_name(criterion)
  CRITERION_TO_RUBY_COVERAGE.fetch(criterion)
end

def process_coverage_result

Returns:
  • (Hash) -
def process_coverage_result
  adapt_coverage_result
  remove_useless_results
  result_with_not_loaded_files
end

def process_result(result, exit_status)

Other tags:
    Api: - private
def process_result(result, exit_status)
  return exit_status if exit_status != SimpleCov::ExitCodes::SUCCESS # Existing errors
  covered_percent = result.covered_percent.floor(2)
  result_exit_status = result_exit_status(result, covered_percent)
  write_last_run(covered_percent) if result_exit_status == SimpleCov::ExitCodes::SUCCESS # No result errors
  final_result_process? ? result_exit_status : SimpleCov::ExitCodes::SUCCESS
end

def remove_useless_results

Returns:
  • (Hash) -
def remove_useless_results
  @result = SimpleCov::UselessResultsRemover.call(@result)
end

def result


from cache using SimpleCov::ResultMerger if use_merging is activated (default)
Returns the result for the current coverage run, merging it across test suites
def result
  return @result if result?
  # Collect our coverage result
  process_coverage_result if running
  # If we're using merging of results, store the current result
  # first (if there is one), then merge the results and return those
  if use_merging
    wait_for_other_processes
    SimpleCov::ResultMerger.store_result(@result) if result?
    @result = SimpleCov::ResultMerger.merged_result
  end
  @result
ensure
  self.running = false
end

def result?


Otherwise, returns the result
Returns nil if the result has not been computed
def result?
  defined?(@result) && @result
end

def result_exit_status(result, covered_percent)

Other tags:
    Api: - private
def result_exit_status(result, covered_percent)
  covered_percentages = result.covered_percentages.map { |percentage| percentage.floor(2) }
  if covered_percent < SimpleCov.minimum_coverage
    $stderr.printf(
      "Coverage (%<covered>.2f%%) is below the expected minimum coverage (%<minimum_coverage>.2f%%).\n",
      covered: covered_percent,
      minimum_coverage: SimpleCov.minimum_coverage
    )
    SimpleCov::ExitCodes::MINIMUM_COVERAGE
  elsif covered_percentages.any? { |p| p < SimpleCov.minimum_coverage_by_file }
    $stderr.printf(
      "File (%<file>s) is only (%<least_covered_percentage>.2f%%) covered. This is below the expected minimum coverage per file of (%<min_coverage>.2f%%).\n",
      file: result.least_covered_file,
      least_covered_percentage: covered_percentages.min,
      min_coverage: SimpleCov.minimum_coverage_by_file
    )
    SimpleCov::ExitCodes::MINIMUM_COVERAGE
  elsif (last_run = SimpleCov::LastRun.read)
    coverage_diff = last_run[:result][:covered_percent] - covered_percent
    if coverage_diff > SimpleCov.maximum_coverage_drop
      $stderr.printf(
        "Coverage has dropped by %<drop_percent>.2f%% since the last time (maximum allowed: %<max_drop>.2f%%).\n",
        drop_percent: coverage_diff,
        max_drop: SimpleCov.maximum_coverage_drop
      )
      SimpleCov::ExitCodes::MAXIMUM_COVERAGE_DROP
    else
      SimpleCov::ExitCodes::SUCCESS
    end
  else
    SimpleCov::ExitCodes::SUCCESS
  end
end

def result_with_not_loaded_files

Returns:
  • (Hash) -
def result_with_not_loaded_files
  @result = SimpleCov::Result.new(add_not_loaded_files(@result))
end

def run_exit_tasks!

Other tags:
    Api: - private
def run_exit_tasks!
  set_exit_exception
  exit_status = SimpleCov.exit_status_from_exception
  SimpleCov.at_exit.call
  # Don't modify the exit status unless the result has already been
  # computed
  exit_status = SimpleCov.process_result(SimpleCov.result, exit_status) if SimpleCov.result?
  # Force exit with stored status (see github issue #5)
  # unless it's nil or 0 (see github issue #281)
  if exit_status&.positive?
    $stderr.printf("SimpleCov failed with exit %<exit_status>d\n", exit_status: exit_status) if print_error_status
    Kernel.exit exit_status
  end
end

def set_exit_exception


This will get called inside the at_exit block
Capture the current exception if it exists
def set_exit_exception
  @exit_exception = $ERROR_INFO
end

def start(profile = nil, &block)


Please check out the RDoc for SimpleCov::Configuration to find about available config options

end
add_filter 'test'
SimpleCov.start 'rails' do
OR
end
add_filter 'test'
SimpleCov.start do
OR
SimpleCov.start 'rails' # using rails profile
OR
SimpleCov.start
You can optionally specify a profile to use as well as configuration with a block:
Sets up SimpleCov to run against your project.
def start(profile = nil, &block)
  require "coverage"
  initial_setup(profile, &block)
  @result = nil
  self.pid = Process.pid
  start_coverage_measurement
end

def start_coverage_measurement


With Negative branch it supports only line coverage measurement type
With Positive branch it supports all coverage measurement types

Trigger Coverage.start depends on given config coverage_criterion
def start_coverage_measurement
  # This blog post gives a good run down of the coverage criterias introduced
  # in Ruby 2.5: https://blog.bigbinary.com/2018/04/11/ruby-2-5-supports-measuring-branch-and-method-coverages.html
  # There is also a nice writeup of the different coverage criteria made in this
  # comment  https://github.com/colszowka/simplecov/pull/692#discussion_r281836176 :
  # Ruby < 2.5:
  # https://github.com/ruby/ruby/blob/v1_9_3_374/ext/coverage/coverage.c
  # traditional mode (Array)
  #
  # Ruby 2.5:
  # https://bugs.ruby-lang.org/issues/13901
  # https://github.com/ruby/ruby/blob/v2_5_3/ext/coverage/coverage.c
  # default: traditional/compatible mode (Array)
  # :lines - like traditional mode but using Hash
  # :branches
  # :methods
  # :all - same as lines + branches + methods
  #
  # Ruby >= 2.6:
  # https://bugs.ruby-lang.org/issues/15022
  # https://github.com/ruby/ruby/blob/v2_6_3/ext/coverage/coverage.c
  # default: traditional/compatible mode (Array)
  # :lines - like traditional mode but using Hash
  # :branches
  # :methods
  # :oneshot_lines - can not be combined with lines
  # :all - same as lines + branches + methods
  #
  if coverage_start_arguments_supported?
    start_coverage_with_criteria
  else
    Coverage.start
  end
end

def start_coverage_with_criteria

def start_coverage_with_criteria
  start_arguments = coverage_criteria.map do |criterion|
    [lookup_corresponding_ruby_coverage_name(criterion), true]
  end.to_h
  Coverage.start(start_arguments)
end

def wait_for_other_processes

Other tags:
    Api: - private
def wait_for_other_processes
  return unless defined?(ParallelTests) && final_result_process?
  ParallelTests.wait_for_other_processes_to_finish
end

def write_last_run(covered_percent)

Other tags:
    Api: - private
def write_last_run(covered_percent)
  SimpleCov::LastRun.write(result: {covered_percent: covered_percent})
end