Module: SimpleCov

Defined in:
lib/simplecov.rb,
lib/simplecov/filter.rb,
lib/simplecov/result.rb,
lib/simplecov/combine.rb,
lib/simplecov/version.rb,
lib/simplecov/last_run.rb,
lib/simplecov/profiles.rb,
lib/simplecov/file_list.rb,
lib/simplecov/formatter.rb,
lib/simplecov/exit_codes.rb,
lib/simplecov/source_file.rb,
lib/simplecov/configuration.rb,
lib/simplecov/result_merger.rb,
lib/simplecov/result_adapter.rb,
lib/simplecov/command_guesser.rb,
lib/simplecov/lines_classifier.rb,
lib/simplecov/source_file/line.rb,
lib/simplecov/simulate_coverage.rb,
lib/simplecov/source_file/branch.rb,
lib/simplecov/coverage_statistics.rb,
lib/simplecov/combine/files_combiner.rb,
lib/simplecov/combine/lines_combiner.rb,
lib/simplecov/useless_results_remover.rb,
lib/simplecov/combine/results_combiner.rb,
lib/simplecov/combine/branches_combiner.rb,
lib/simplecov/formatter/multi_formatter.rb,
lib/simplecov/formatter/simple_formatter.rb,
lib/simplecov/exit_codes/exit_code_handling.rb,
lib/simplecov/exit_codes/maximum_coverage_drop_check.rb,
lib/simplecov/exit_codes/minimum_coverage_by_file_check.rb,
lib/simplecov/exit_codes/minimum_overall_coverage_check.rb

Overview

Code coverage for ruby. Please check out README for a full introduction.

Defined Under Namespace

Modules: Combine, CommandGuesser, Configuration, ExitCodes, Formatter, LastRun, ResultMerger, SimulateCoverage, UselessResultsRemover Classes: ArrayFilter, BlockFilter, CoverageLimits, CoverageStatistics, FileList, Filter, LinesClassifier, Profiles, RegexFilter, Result, ResultAdapter, SourceFile, StringFilter

Constant Summary collapse

VERSION =
"0.19.0"

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.external_at_exitObject Also known as: external_at_exit?

Basically, should we take care of at_exit behavior or something else? Used by the minitest plugin. See lib/minitest/simplecov_plugin.rb


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

def external_at_exit
  @external_at_exit
end

.pidObject

Returns the value of attribute pid


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

def pid
  @pid
end

.runningObject

Returns the value of attribute running


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

def running
  @running
end

Class Method Details

.at_exit_behaviorObject


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

def at_exit_behavior
  # If we are in a different process than called start, don't interfere.
  return if SimpleCov.pid != Process.pid

  # If SimpleCov is no longer running then don't run exit tasks
  SimpleCov.run_exit_tasks! if SimpleCov.running
end

.clear_resultObject

Clear out the previously cached .result. Primarily useful in testing


170
171
172
# File 'lib/simplecov.rb', line 170

def clear_result
  @result = nil
end

.collate(result_filenames, profile = nil, &block) ⇒ Object

Collate a series of SimpleCov result files into a single SimpleCov output. You can optionally specify configuration with a block:

SimpleCov.collate Dir["simplecov-resultset-*/.resultset.json"]
 OR
SimpleCov.collate Dir["simplecov-resultset-*/.resultset.json"], 'rails' # using rails profile
 OR
SimpleCov.collate Dir["simplecov-resultset-*/.resultset.json"] do
  add_filter 'test'
end
 OR
SimpleCov.collate Dir["simplecov-resultset-*/.resultset.json"], 'rails' do
  add_filter 'test'
end

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


81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/simplecov.rb', line 81

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.
    Result.from_hash(JSON.parse(File.read(filename)) || {})
  end

  # Use the ResultMerger to produce a single, merged result, ready to use.
  @result = ResultMerger.merge_and_store(*results)

  run_exit_tasks!
end

.exit_and_report_previous_error(exit_status) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Thinking: Move this behavior earlier so if there was an error we do nothing?


223
224
225
226
# File 'lib/simplecov.rb', line 223

def exit_and_report_previous_error(exit_status)
  warn("Stopped processing SimpleCov as a previous error not related to SimpleCov has been detected") if print_error_status
  Kernel.exit(exit_status)
end

.exit_status_from_exceptionObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the exit status from the exit exception


200
201
202
203
204
205
206
207
208
209
210
# File 'lib/simplecov.rb', line 200

def exit_status_from_exception
  # Capture the current exception if it exists
  @exit_exception = $ERROR_INFO
  return nil unless @exit_exception

  if @exit_exception.is_a?(SystemExit)
    @exit_exception.status
  else
    SimpleCov::ExitCodes::EXCEPTION
  end
end

.filtered(files) ⇒ Object

Applies the configured filters to the given array of SimpleCov::SourceFile items


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

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

.final_result_process?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)

268
269
270
271
# File 'lib/simplecov.rb', line 268

def final_result_process?
  # checking for ENV["TEST_ENV_NUMBER"] to determine if the tests are being run in parallel
  !defined?(ParallelTests) || !ENV["TEST_ENV_NUMBER"] || ParallelTests.last_process?
end

.grouped(files) ⇒ Object

Applies the configured groups to the given array of SimpleCov::SourceFile items


142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/simplecov.rb', line 142

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

.load_adapter(name) ⇒ Object


162
163
164
165
# File 'lib/simplecov.rb', line 162

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

.load_profile(name) ⇒ Object

Applies the profile of given name on SimpleCov configuration


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

def load_profile(name)
  profiles.load(name)
end

.previous_error?(error_exit_status) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)

213
214
215
216
217
# File 'lib/simplecov.rb', line 213

def previous_error?(error_exit_status)
  # Normally it'd be enough to check for previous error but when running test_unit
  # status is 0
  error_exit_status && error_exit_status != SimpleCov::ExitCodes::SUCCESS
end

.process_result(result) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Usage:

exit_status = SimpleCov.process_result(SimpleCov.result, exit_status)

248
249
250
251
252
# File 'lib/simplecov.rb', line 248

def process_result(result)
  result_exit_status = result_exit_status(result)
  write_last_run(result) if result_exit_status == SimpleCov::ExitCodes::SUCCESS
  result_exit_status
end

.process_results_and_report_errorObject


233
234
235
236
237
238
239
240
241
# File 'lib/simplecov.rb', line 233

def process_results_and_report_error
  exit_status = process_result(result)

  # Force exit with stored status (see github issue #5)
  if exit_status.positive?
    warn("SimpleCov failed with exit #{exit_status} due to a coverage related error") if print_error_status
    Kernel.exit exit_status
  end
end

.ready_to_process_results?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)

229
230
231
# File 'lib/simplecov.rb', line 229

def ready_to_process_results?
  final_result_process? && result?
end

.resultObject

Returns the result for the current coverage run, merging it across test suites from cache using SimpleCov::ResultMerger if use_merging is activated (default)


101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/simplecov.rb', line 101

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

.result?Boolean

Returns nil if the result has not been computed Otherwise, returns the result

Returns:

  • (Boolean)

124
125
126
# File 'lib/simplecov.rb', line 124

def result?
  defined?(@result) && @result
end

.result_exit_status(result) ⇒ Object


256
257
258
259
260
261
262
263
# File 'lib/simplecov.rb', line 256

def result_exit_status(result)
  coverage_limits = CoverageLimits.new(
    minimum_coverage: minimum_coverage, minimum_coverage_by_file: minimum_coverage_by_file,
    maximum_coverage_drop: maximum_coverage_drop
  )

  ExitCodes::ExitCodeHandling.call(result, coverage_limits: coverage_limits)
end

.round_coverage(coverage) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Rounding down to be extra strict, see #679


293
294
295
# File 'lib/simplecov.rb', line 293

def round_coverage(coverage)
  coverage.floor(2)
end

.run_exit_tasks!Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Called from at_exit block


186
187
188
189
190
191
192
193
# File 'lib/simplecov.rb', line 186

def run_exit_tasks!
  error_exit_status = exit_status_from_exception

  at_exit.call

  exit_and_report_previous_error(error_exit_status) if previous_error?(error_exit_status)
  process_results_and_report_error if ready_to_process_results?
end

.start(profile = nil, &block) ⇒ Object

Sets up SimpleCov to run against your project. You can optionally specify a profile to use as well as configuration with a block:

SimpleCov.start
 OR
SimpleCov.start 'rails' # using rails profile
 OR
SimpleCov.start do
  add_filter 'test'
end
  OR
SimpleCov.start 'rails' do
  add_filter 'test'
end

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


50
51
52
53
54
55
56
57
58
59
60
# File 'lib/simplecov.rb', line 50

def start(profile = nil, &block)
  require "coverage"
  initial_setup(profile, &block)
  require_relative "./simplecov/process" if SimpleCov.enabled_for_subprocesses?
  make_parallel_tests_available

  @result = nil
  self.pid = Process.pid

  start_coverage_measurement
end

.wait_for_other_processesObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.


276
277
278
279
280
# File 'lib/simplecov.rb', line 276

def wait_for_other_processes
  return unless defined?(ParallelTests) && final_result_process?

  ParallelTests.wait_for_other_processes_to_finish
end

.write_last_run(result) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.


285
286
287
# File 'lib/simplecov.rb', line 285

def write_last_run(result)
  SimpleCov::LastRun.write(result: {covered_percent: round_coverage(result.covered_percent)})
end