Class: SimpleCov::Result

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

Overview

A code coverage result, initialized from the Hash Ruby's built-in coverage library generates.

Defined Under Namespace

Modules: Serialization, _SerializableResult Classes: FilterConfig, MissingSourceFilesReporter, SourceFileBuilder

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Serialization

#append_contexts, #context_filenames, #coverage, #to_hash

Constructor Details

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

filter_config defaults to the SimpleCov singleton's filter / group configuration. Pass a custom FilterConfig to opt out, which is useful for tests that build synthetic Results.

tracked_files accepts any collection that answers to_a (the merge passes a Set), and nil for a run that tracked nothing.

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)
  • tracked_files: (_ToA[String], nil) (defaults to: nil)
  • run_id: (String, nil) (defaults to: nil)
  • worker_id: (String, nil) (defaults to: nil)
  • contexts: (ContextMap, nil) (defaults to: nil)
  • report: (Boolean) (defaults to: false)
  • filter_config: (FilterConfig) (defaults to: FilterConfig.new)


52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/simplecov/result.rb', line 52

def initialize(original_result, command_name: nil, created_at: nil, not_loaded_files: Set.new,
  tracked_files: nil, run_id: nil, worker_id: nil, contexts: nil, report: false,
  filter_config: FilterConfig.new)
  @original_result = original_result.freeze
  @command_name = command_name
  @created_at = created_at
  (tracked_files, run_id, worker_id, contexts)
  @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) if report
  apply_cover_filters!(filter_config.cover_filters)
  apply_filters!(filter_config.filters)
end

Instance Attribute Details

#command_nameString

Returns:

  • (String)


113
114
115
# File 'lib/simplecov/result.rb', line 113

def command_name
  @command_name ||= SimpleCov.command_name
end

#command_namesArray[String]

Returns:

  • (Array[String])


117
118
119
# File 'lib/simplecov/result.rb', line 117

def command_names
  @command_names ||= [command_name]
end

#contextsContextMap? (readonly)

The ContextMap recorded under track_tests, or nil when this result carries none: tracking was off, or a merge dropped the map because not every merged result recorded one.

Returns:



31
32
33
# File 'lib/simplecov/result.rb', line 31

def contexts
  @contexts
end

#created_atTime

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 the value of attribute files.

Returns:



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

def files
  @files
end

#original_resultHash[String, untyped] (readonly)

Returns the value of attribute original_result.

Returns:

  • (Hash[String, untyped])


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

def original_result
  @original_result
end

#run_idString? (readonly)

Used only for parallel-result coordination. They do not change which fresh suites are merged.

Returns:

  • (String, nil)


26
27
28
# File 'lib/simplecov/result.rb', line 26

def run_id
  @run_id
end

#tracked_filesArray[String] (readonly)

Every path the producing process was told to track, loaded or not. Carried into the resultset so a merge elsewhere can inject the ones nobody loaded without needing that process's config (#1250).

Returns:

  • (Array[String])


23
24
25
# File 'lib/simplecov/result.rb', line 23

def tracked_files
  @tracked_files
end

#worker_idString? (readonly)

Used only for parallel-result coordination. They do not change which fresh suites are merged.

Returns:

  • (String, nil)


26
27
28
# File 'lib/simplecov/result.rb', line 26

def worker_id
  @worker_id
end

Class Method Details

.from_hash(hash) ⇒ Array[Result]

Parameters:

  • hash (Hash[String, untyped])

Returns:



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

def self.from_hash(hash)
  hash.map do |command_name, data|
    new(data.fetch("coverage"), command_name: command_name, created_at: Time.at(data.fetch("timestamp")),
      tracked_files: data["tracked_files"], run_id: data["run_id"],
      worker_id: data["worker_id"], contexts: ContextMap.from_hash(data["contexts"]))
  end
end

Instance Method Details

#apply_cover_filters!(cover_filters) ⇒ void

This method returns an undefined value.

With no cover matchers configured this is a no-op, preserving the historical "everything required, then filtered" universe.

Parameters:

  • cover_filters (Array[Filter[untyped]])


162
163
164
165
166
167
168
# File 'lib/simplecov/result.rb', line 162

def apply_cover_filters!(cover_filters)
  return if cover_filters.empty?

  @files = 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.

Parameters:

  • filters (Array[Filter[untyped]])


154
155
156
157
158
# File 'lib/simplecov/result.rb', line 154

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

#configured_group?(group_name) ⇒ Boolean

True for a group the configuration defines, whether or not any file matched it; groups omits the ones that matched nothing.

Parameters:

  • group_name (String)

Returns:

  • (Boolean)


89
90
91
# File 'lib/simplecov/result.rb', line 89

def configured_group?(group_name)
  @groups_config.key?(group_name)
end

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

Path resolution as in source_file_for.

Parameters:

  • path (String)

Returns:



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

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

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

Overloads:



693
694
# File 'sig/simplecov.rbs', line 693

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

#coverage_statistics_by_fileHash[criterion, Array[CoverageStatistics]]

Returns:



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

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

#covered_branchesInteger?

Returns:

  • (Integer, nil)


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

def covered_branches: () -> Integer?

#covered_linesInteger?

Returns:

  • (Integer, nil)


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

def covered_lines: () -> Integer?

#covered_methodsInteger?

Returns:

  • (Integer, nil)


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

def covered_methods: () -> Integer?

#covered_percentFloat?

Parameters:

  • (criterion)

Returns:

  • (Float, nil)


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

def covered_percent: (?criterion) -> Float?

#covered_percentagesArray[Float?]

Returns:

  • (Array[Float?])


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

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

#covered_strengthFloat?

Parameters:

  • (criterion)

Returns:

  • (Float, nil)


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

def covered_strength: (?criterion) -> Float?

#filenamesArray[String]

Returns:

  • (Array[String])


67
68
69
# File 'lib/simplecov/result.rb', line 67

def filenames
  files.map(&:filename)
end

#format!Object

Returns nil if formatting has been opted out of (SimpleCov.formatter false / SimpleCov.formatters []), the cheap path for non-final processes in a parallel CI run, which only need their .resultset.json on disk (#964).

Returns:

  • (Object)


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

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

  formatted = Formatter.format(formatter, self)
  # Recorded regardless of how the run ends, so a parent process's
  # clobber-prevention backstop can tell a report was produced even when
  # this run's checks or tests failed, unlike .last_run.json.
  ReportStamp.touch
  formatted
end

#groupsHash[String, FileList]

Returns:



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

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

#initialize_resultset_metadata(tracked_files, run_id, worker_id, contexts) ⇒ void

This method returns an undefined value.

Parameters:

  • tracked_files (_ToA[String], nil)
  • run_id (String, nil)
  • worker_id (String, nil)
  • contexts (ContextMap, nil)


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

def (tracked_files, run_id, worker_id, contexts)
  @tracked_files = tracked_files.to_a
  @run_id = run_id
  @worker_id = worker_id
  @contexts = contexts
end

#least_covered_fileString?

Returns:

  • (String, nil)


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

def least_covered_file: () -> String?

#missed_branchesInteger?

Returns:

  • (Integer, nil)


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

def missed_branches: () -> Integer?

#missed_linesInteger?

Returns:

  • (Integer, nil)


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

def missed_lines: () -> Integer?

#missed_methodsInteger?

Returns:

  • (Integer, nil)


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

def missed_methods: () -> Integer?

#source_file_for(path) ⇒ SourceFile?

The path is resolved against SimpleCov.root, so callers can pass either an absolute path or a project-relative one.

Parameters:

  • path (String)

Returns:



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

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

#total_branchesInteger?

Returns:

  • (Integer, nil)


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

def total_branches: () -> Integer?

#total_linesInteger?

Returns:

  • (Integer, nil)


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

def total_lines: () -> Integer?

#total_methodsInteger?

Returns:

  • (Integer, nil)


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

def total_methods: () -> Integer?

#warn_about_missing_source_files(missing) ⇒ void

This method returns an undefined value.

Parameters:

  • missing (Array[String])


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

def warn_about_missing_source_files(missing)
  return if missing.empty?

  # Emit only from the process that writes the final report: the merged
  # result is rebuilt in every parallel worker, so without this gate the
  # warning prints once per worker. Intentionally not gated on
  # print_errors, because the default at_fork sets print_errors false on
  # workers and in many parallel runners the final-report process is itself
  # a worker (#980, #1171).
  return unless SimpleCov.final_result_process?

  # Every built file survives (only the missing ones are dropped), so an
  # empty file list is exactly the "nothing was found" case.
  MissingSourceFilesReporter.new(missing, every_entry_dropped: @files.empty?).warn!
end