Class: SimpleCov::Result

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/simplecov/result.rb,
lib/simplecov/result/source_file_builder.rb,
lib/simplecov/result/missing_source_files_reporter.rb,
sig/simplecov.rbs

Overview

A coverage result built from the Hash Ruby's Coverage library produces: filename => per-criterion coverage data.

Defined Under Namespace

Classes: FilterConfig, MissingSourceFilesReporter, SourceFileBuilder

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(original_result, command_name: nil, created_at: nil, not_loaded_files: Set.new, report: false, filter_config: FilterConfig.new) ⇒ Result

Initialize a new SimpleCov::Result from given Coverage.result (a Hash of filenames each containing an array of coverage data).

filter_config defaults to the SimpleCov singleton's filter / group configuration so existing call sites are unchanged. Pass a custom FilterConfig to opt out — useful for tests that build synthetic Results and don't want the project's filters or groups applied.

Parameters:

  • original_result (Hash[String, untyped])
  • command_name: (String, nil) (defaults to: nil)
  • created_at: (Time, nil) (defaults to: nil)
  • not_loaded_files: (Set[String]) (defaults to: Set.new)
  • report: (Boolean) (defaults to: false)
  • filter_config: (FilterConfig) (defaults to: FilterConfig.new)


57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/simplecov/result.rb', line 57

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

Instance Attribute Details

#command_nameString

The command name that launched this result. Delegated to SimpleCov.command_name if not set manually

Returns:

  • (String)


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

def command_name
  @command_name ||= SimpleCov.command_name
end

#created_atTime

Defines when this result has been created. Defaults to Time.now

Returns:

  • (Time)


109
110
111
# File 'lib/simplecov/result.rb', line 109

def created_at
  @created_at ||= Time.now
end

#filesFileList (readonly) Also known as: source_files

Returns all files that are applicable to this result (sans filters!) as instances of SimpleCov::SourceFile. Aliased as :source_files

Returns:



20
21
22
# File 'lib/simplecov/result.rb', line 20

def files
  @files
end

#original_resultHash[String, untyped] (readonly)

Returns the original Coverage.result used for this instance of SimpleCov::Result

Returns:

  • (Hash[String, untyped])


17
18
19
# File 'lib/simplecov/result.rb', line 17

def original_result
  @original_result
end

Class Method Details

.from_hash(hash) ⇒ Array[Result]

Loads a SimpleCov::Result#to_hash dump

Parameters:

  • hash (Hash[String, untyped])

Returns:



130
131
132
133
134
# File 'lib/simplecov/result.rb', line 130

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

Instance Method Details

#apply_cover_filters!(cover_filters) ⇒ void

This method returns an undefined value.

When any cover matcher is configured, restrict @files to source files matching at least one of them. With no cover matchers configured this is a no-op, preserving the historical "everything required, then filtered" universe.

Parameters:

  • cover_filters (Array[Filter[untyped]])


175
176
177
178
179
180
181
# File 'lib/simplecov/result.rb', line 175

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

#apply_filters!(filters) ⇒ void

This method returns an undefined value.

Applies the given filter chain to @files, dropping each source file that any filter matches.

Parameters:

  • filters (Array[Filter[untyped]])


165
166
167
168
169
# File 'lib/simplecov/result.rb', line 165

def apply_filters!(filters)
  filters.each do |filter|
    @files = SimpleCov::FileList.new(@files.reject { |source_file| filter.matches?(source_file) })
  end
end

#coverageHash[String, untyped]

Returns:

  • (Hash[String, untyped])


159
160
161
# File 'lib/simplecov/result.rb', line 159

def coverage
  original_result.slice(*filenames)
end

#coverage_for(path) ⇒ Hash[criterion, CoverageStatistics]?

Returns the line:/branch:/method: coverage_statistics hash for the given file path, or nil if no matching source file is in this result. See SimpleCov::Result#source_file_for for path resolution.

Parameters:

  • path (String)

Returns:



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

def coverage_for(path)
  source_file_for(path)&.coverage_statistics
end

#coverage_statisticsHash[criterion, CoverageStatistics] #coverage_statistics(arg0) ⇒ CoverageStatistics?

Overloads:



787
788
# File 'sig/simplecov.rbs', line 787

def coverage_statistics: () -> Hash[criterion, CoverageStatistics]
| (criterion) -> CoverageStatistics?

#coverage_statistics_by_fileHash[criterion, Array[CoverageStatistics]]

Returns:



789
# File 'sig/simplecov.rbs', line 789

def coverage_statistics_by_file: () -> Hash[criterion, Array[CoverageStatistics]]

#covered_branchesInteger?

Returns:

  • (Integer, nil)


782
# File 'sig/simplecov.rbs', line 782

def covered_branches: () -> Integer?

#covered_linesInteger?

Returns:

  • (Integer, nil)


779
# File 'sig/simplecov.rbs', line 779

def covered_lines: () -> Integer?

#covered_methodsInteger?

Returns:

  • (Integer, nil)


785
# File 'sig/simplecov.rbs', line 785

def covered_methods: () -> Integer?

#covered_percentFloat?

Delegated to #files (see FileList).

Parameters:

  • (criterion)

Returns:

  • (Float, nil)


775
# File 'sig/simplecov.rbs', line 775

def covered_percent: (?criterion) -> Float?

#covered_percentagesArray[Float?]

Returns:

  • (Array[Float?])


776
# File 'sig/simplecov.rbs', line 776

def covered_percentages: () -> Array[Float?]

#covered_strengthFloat?

Parameters:

  • (criterion)

Returns:

  • (Float, nil)


778
# File 'sig/simplecov.rbs', line 778

def covered_strength: (?criterion) -> Float?

#filenamesArray[String]

Returns all filenames for source files contained in this result

Returns:

  • (Array[String])


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

def filenames
  files.map(&:filename)
end

#format!Object

Returns nil when formatting is opted out of (formatter false / formatters []); otherwise whatever the configured formatter returns.

Returns:

  • (Object)


101
102
103
104
105
106
# File 'lib/simplecov/result.rb', line 101

def format!
  formatter = SimpleCov.formatter
  return nil if formatter.nil?

  formatter.new.format(self)
end

#groupsHash[String, FileList]

Returns a Hash of groups for this result. Define groups using SimpleCov.group 'Models', 'app/models'

Returns:



92
93
94
# File 'lib/simplecov/result.rb', line 92

def groups
  @groups ||= SimpleCov.grouped(files, groups: @groups_config)
end

#least_covered_fileString

Returns:

  • (String)


777
# File 'sig/simplecov.rbs', line 777

def least_covered_file: () -> String

#missed_branchesInteger?

Returns:

  • (Integer, nil)


783
# File 'sig/simplecov.rbs', line 783

def missed_branches: () -> Integer?

#missed_linesInteger?

Returns:

  • (Integer, nil)


780
# File 'sig/simplecov.rbs', line 780

def missed_lines: () -> Integer?

#missed_methodsInteger?

Returns:

  • (Integer, nil)


786
# File 'sig/simplecov.rbs', line 786

def missed_methods: () -> Integer?

#source_file_for(path) ⇒ SourceFile?

Accepts an absolute or project-relative path (resolved against SimpleCov.root).

Parameters:

  • path (String)

Returns:



79
80
81
82
# File 'lib/simplecov/result.rb', line 79

def source_file_for(path)
  target = File.expand_path(path, SimpleCov.root)
  files.find { |file| file.filename == target }
end

#to_hashHash[String, { "coverage" => Hash[String, untyped], "timestamp" => Integer }]

Returns a hash representation of this Result that can be used for marshalling it into JSON

Returns:

  • (Hash[String, { "coverage" => Hash[String, untyped], "timestamp" => Integer }])


120
121
122
123
124
125
126
127
# File 'lib/simplecov/result.rb', line 120

def to_hash
  {
    command_name => {
      "coverage" => coverage,
      "timestamp" => created_at.to_i
    }
  }
end

#total_branchesInteger?

Returns:

  • (Integer, nil)


781
# File 'sig/simplecov.rbs', line 781

def total_branches: () -> Integer?

#total_linesInteger?

Returns:

  • (Integer, nil)


790
# File 'sig/simplecov.rbs', line 790

def total_lines: () -> Integer?

#total_methodsInteger?

Returns:

  • (Integer, nil)


784
# File 'sig/simplecov.rbs', line 784

def total_methods: () -> Integer?

#warn_about_missing_source_files(missing, input_size) ⇒ void

This method returns an undefined value.

Parameters:

  • missing (Array[String])
  • input_size (Integer)


138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/simplecov/result.rb', line 138

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