class SimpleCov::Result
library generates (Coverage.result).
A simplecov code coverage result, initialized from the Hash Ruby’s built-in coverage
def self.from_hash(hash)
def self.from_hash(hash) hash.map do |command_name, data| new(data.fetch("coverage"), command_name: command_name, created_at: Time.at(data["timestamp"])) end end
def apply_cover_filters!(cover_filters)
this is a no-op, preserving the historical "everything required, then
files matching at least one of them. With no cover matchers configured
When any `cover` matcher is configured, restrict `@files` to source
def apply_cover_filters!(cover_filters) return if cover_filters.empty? @files = SimpleCov::FileList.new( @files.select { |source_file| cover_filters.any? { |filter| filter.matches?(source_file) } } ) end
def apply_filters!(filters)
Applies the given filter chain to `@files`, dropping each source
def apply_filters!(filters) filters.each do |filter| @files = SimpleCov::FileList.new(@files.reject { |source_file| filter.matches?(source_file) }) end end
def command_name
The command name that launched this result.
def command_name @command_name ||= SimpleCov.command_name end
def coverage
def coverage original_result.slice(*filenames) end
def coverage_for(path)
given file path, or nil if no matching source file is in this
Returns the {line:/branch:/method:} coverage_statistics hash for the
def coverage_for(path) source_file_for(path)&.coverage_statistics end
def created_at
def created_at @created_at ||= Time.now end
def filenames
def filenames files.map(&:filename) end
def format!
processes in a parallel CI run, which only need their
/ `SimpleCov.formatters []`) — the cheap path for non-final
nil if formatting has been opted out of (`SimpleCov.formatter false`
Applies the configured SimpleCov.formatter on this result. Returns
def format! formatter = SimpleCov.formatter return nil if formatter.nil? Formatter.instance_for(formatter).format(self) end
def groups
def groups @groups ||= SimpleCov.grouped(files, groups: @groups_config) end
def initialize(original_result, command_name: nil, created_at: nil, not_loaded_files: Set.new,
FilterConfig to opt out — useful for tests that build synthetic Results
configuration so existing call sites are unchanged. Pass a custom
`filter_config` defaults to the SimpleCov singleton's filter / group
coverage data).
Initialize a new SimpleCov::Result from given Coverage.result (a Hash of filenames each containing an array of
def initialize(original_result, command_name: nil, created_at: nil, not_loaded_files: Set.new, report: false, filter_config: FilterConfig.new) @original_result = original_result.freeze @command_name = command_name @created_at = created_at @groups_config = filter_config.groups builder = SourceFileBuilder.new(original_result, not_loaded_files: not_loaded_files) @files = builder.call warn_about_missing_source_files(builder.missing_source_files, original_result.size) if report apply_cover_filters!(filter_config.cover_filters) apply_filters!(filter_config.filters) end
def source_file_for(path)
SimpleCov.root, so callers can pass either an absolute path or a
matching file is in this result. The path is resolved against
Returns the SimpleCov::SourceFile for the given path, or nil if no
def source_file_for(path) target = File.expand_path(path, SimpleCov.root) files.find { |file| file.filename == target } end
def to_hash
def to_hash { command_name => { "coverage" => coverage, "timestamp" => created_at.to_i } } end
def warn_about_missing_source_files(missing, input_size)
def warn_about_missing_source_files(missing, input_size) return if missing.empty? # Emit only from the process that writes the final report. The merged # result is rebuilt in every parallel worker (each one stores its own # slice), so without this gate the warning prints once per worker — this # is the same signal SimpleCov uses to pick the process that runs the # report and threshold checks. It's intentionally not gated on # print_errors: the default at_fork sets print_errors false on workers, # and in many parallel runners the final-report process is itself a # worker, so a print_errors gate would suppress the one warning we want. # See issues #980 and #1171. return unless SimpleCov.final_result_process? MissingSourceFilesReporter.new( missing, input_size: input_size, every_entry_dropped: @files.empty? && missing.size == input_size ).warn! end