Module: SimpleCov
- Extended by:
- Configuration
- Defined in:
- lib/simplecov.rb,
lib/simplecov/cli.rb,
lib/simplecov/color.rb,
lib/simplecov/filter.rb,
lib/simplecov/result.rb,
lib/simplecov/cli/run.rb,
lib/simplecov/combine.rb,
lib/simplecov/process.rb,
lib/simplecov/version.rb,
lib/simplecov/cli/diff.rb,
lib/simplecov/cli/open.rb,
lib/simplecov/last_run.rb,
lib/simplecov/profiles.rb,
lib/simplecov/cli/clean.rb,
lib/simplecov/cli/merge.rb,
lib/simplecov/cli/serve.rb,
lib/simplecov/directive.rb,
lib/simplecov/file_list.rb,
lib/simplecov/formatter.rb,
lib/simplecov/cli/report.rb,
lib/simplecov/exit_codes.rb,
lib/simplecov/cli/dotfile.rb,
lib/simplecov/deprecation.rb,
lib/simplecov/source_file.rb,
lib/simplecov/cli/coverage.rb,
lib/simplecov/cli/uncovered.rb,
lib/simplecov/configuration.rb,
lib/simplecov/exit_handling.rb,
lib/simplecov/result_merger.rb,
lib/simplecov/formatter/base.rb,
lib/simplecov/result_adapter.rb,
lib/simplecov/command_guesser.rb,
lib/simplecov/lines_classifier.rb,
lib/simplecov/source_file/line.rb,
lib/simplecov/parallel_adapters.rb,
lib/simplecov/result_processing.rb,
lib/simplecov/simulate_coverage.rb,
lib/simplecov/source_file/branch.rb,
lib/simplecov/source_file/method.rb,
lib/simplecov/coverage_statistics.rb,
lib/simplecov/coverage_violations.rb,
lib/simplecov/configuration/filters.rb,
lib/simplecov/configuration/merging.rb,
lib/simplecov/parallel_coordination.rb,
lib/simplecov/combine/files_combiner.rb,
lib/simplecov/combine/lines_combiner.rb,
lib/simplecov/configuration/coverage.rb,
lib/simplecov/parallel_adapters/base.rb,
lib/simplecov/source_file/statistics.rb,
lib/simplecov/source_file/skip_chunks.rb,
lib/simplecov/useless_results_remover.rb,
lib/simplecov/combine/methods_combiner.rb,
lib/simplecov/combine/results_combiner.rb,
lib/simplecov/configuration/formatting.rb,
lib/simplecov/configuration/thresholds.rb,
lib/simplecov/formatter/html_formatter.rb,
lib/simplecov/formatter/json_formatter.rb,
lib/simplecov/source_file/line_builder.rb,
lib/simplecov/combine/branches_combiner.rb,
lib/simplecov/formatter/multi_formatter.rb,
lib/simplecov/parallel_adapters/generic.rb,
lib/simplecov/source_file/source_loader.rb,
lib/simplecov/static_coverage_extractor.rb,
lib/simplecov/formatter/simple_formatter.rb,
lib/simplecov/result/source_file_builder.rb,
lib/simplecov/source_file/branch_builder.rb,
lib/simplecov/source_file/method_builder.rb,
lib/simplecov/source_file/builder_context.rb,
lib/simplecov/result_merger/resultset_file.rb,
lib/simplecov/source_file/ruby_data_parser.rb,
lib/simplecov/configuration/ignored_entries.rb,
lib/simplecov/exit_codes/exit_code_handling.rb,
lib/simplecov/result_merger/resultset_store.rb,
lib/simplecov/configuration/coverage_criteria.rb,
lib/simplecov/parallel_adapters/parallel_tests.rb,
lib/simplecov/static_coverage_extractor/visitor.rb,
lib/simplecov/result_merger/legacy_format_adapter.rb,
lib/simplecov/result/missing_source_files_reporter.rb,
lib/simplecov/exit_codes/maximum_coverage_drop_check.rb,
lib/simplecov/exit_codes/maximum_overall_coverage_check.rb,
lib/simplecov/exit_codes/minimum_coverage_by_file_check.rb,
lib/simplecov/exit_codes/minimum_overall_coverage_check.rb,
lib/simplecov/formatter/json_formatter/errors_formatter.rb,
lib/simplecov/exit_codes/minimum_coverage_by_group_check.rb,
lib/simplecov/static_coverage_extractor/method_collector.rb,
lib/simplecov/formatter/json_formatter/result_hash_formatter.rb,
lib/simplecov/formatter/json_formatter/source_file_formatter.rb,
lib/simplecov/static_coverage_extractor/location_conventions.rb,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs,
sig/simplecov.rbs
Overview
Coverage threshold configuration: minimum_coverage,
maximum_coverage, expected_coverage, maximum_coverage_drop,
refuse_coverage_drop, and the deprecated by-file / by-group forms.
Defined Under Namespace
Modules: CLI, Color, Combine, CommandGuesser, Configuration, CoverageViolations, Deprecation, ExitCodes, Formatter, LastRun, ParallelAdapters, ProcessForkHook, ResultMerger, SimulateCoverage, StaticCoverageExtractor, UselessResultsRemover Classes: ArrayFilter, BlockFilter, ConfigurationError, CoverageLimits, CoverageStatistics, Directive, FileList, Filter, GlobFilter, LinesClassifier, Profiles, RegexFilter, Result, ResultAdapter, SourceFile, StringFilter
Constant Summary collapse
- CRITERION_TO_RUBY_COVERAGE =
Maps SimpleCov's criterion names to the keys
Coverage.startexpects. { branch: :branches, line: :lines, method: :methods, oneshot_line: :oneshot_lines }.freeze
- VERSION =
"1.0.1"
Constants included from Configuration
Configuration::COVERAGE_THRESHOLD_OPTIONS, Configuration::DEFAULT_COVERAGE_CRITERION, Configuration::IGNORABLE_BRANCH_TYPES, Configuration::IGNORABLE_METHOD_TYPES, Configuration::ONESHOT_LINE_COVERAGE_CRITERION, Configuration::SUPPORTED_COVERAGE_CRITERIA
Class Attribute Summary collapse
-
.external_at_exit ⇒ Boolean?
Should something external (e.g. the Minitest plugin) own the at_exit behavior instead of SimpleCov's own hook?.
-
.pid ⇒ Integer?
Returns the value of attribute pid.
-
.process_start_time ⇒ Time?
When this process started tracking coverage.
Attributes included from Configuration
#filters, #formatter, #groups, #print_error_status
Class Method Summary collapse
- .at_exit_behavior ⇒ Object
-
.clear_result ⇒ void
Clear the cached result.
-
.collate(result_filenames, profile = nil, ignore_timeout: true) ⇒ void
Collate a series of resultset files into a single merged report.
- .collating_result? ⇒ Boolean
-
.coverage_statistics_key(criterion) ⇒ criterion
:oneshot_linestats are folded into the:linebucket, so use the returned criterion to look upcoverage_statistics. -
.defer_to_existing_report? ⇒ Boolean
Returns true when our process has no coverage data to contribute (after the resultset merge) and a newer report already exists on disk.
- .existing_report_newer_than_us? ⇒ Boolean
- .exit_and_report_previous_error(exit_status) ⇒ Object private
- .exit_status_from_exception ⇒ Object
-
.external_at_exit? ⇒ Boolean
Coerce to a proper boolean so rspec-mocks 4's predicate matcher (
expect(...).not_to be_external_at_exit) accepts the result. -
.filtered(files) ⇒ FileList
Applies the configured filters to the given source files.
- .final_result_process? ⇒ Boolean private
-
.forked_subprocess? ⇒ Boolean
running (set by SimpleCov::ProcessForkHook in the child).
-
.grouped(files, groups: SimpleCov.groups) ⇒ Hash[String, FileList]
Bin the given source files by group filter.
-
.install_at_exit_hook ⇒ void
Install the at_exit hook that formats results and runs exit-code checks.
-
.load_profile(name) ⇒ void
Applies the profile of the given name to the configuration.
- .mark_forked_subprocess! ⇒ void
- .monotonic_time ⇒ Object
-
.next_subprocess_serial! ⇒ Integer
child inherits its own ordinal via copy-on-write.
-
.parallel_results_complete? ⇒ Boolean
before the wait deadline.
-
.parallel_wait_timed_out?(deadline, expected, seen) ⇒ Boolean
the first timeout so the user knows the merged total is partial.
-
.previous_error?(error_exit_status) ⇒ Boolean
accepts it.
- .process_result(result) ⇒ Object
- .process_results_and_report_error ⇒ Object
-
.ready_to_process_results? ⇒ Boolean
only one that reports against thresholds, and only when its
wait_for_other_processesconfirmed every sibling reported. -
.reset_inherited_at_exit_state! ⇒ void
Reset at_exit state a forked child inherits from its parent (a possibly consumed hook and a Minitest deferral pid-pinned to the parent), so the child re-arms a hook that fires at its own exit.
-
.result ⇒ Result?
The result for the current coverage run, merged across test suites when merging is active.
-
.result? ⇒ Result, ...
The memoized result, or false/nil when it has not been computed yet.
- .result_exit_status(result) ⇒ Object
-
.resultset_count_settled?(tracker, count) ⇒ Boolean
Track whether the resultset count has held steady (and positive) for
PARALLEL_RESULTS_SETTLEseconds. -
.round_coverage(coverage) ⇒ Numeric
Round coverage down to two decimals.
- .run_exit_tasks! ⇒ Object
-
.start(profile = nil) ⇒ void
Sets up SimpleCov to run against your project:.
-
.start_tracking ⇒ void
Begin coverage tracking without applying configuration.
-
.subprocess_serial ⇒ Integer
A monotonically increasing serial assigned to each forked subprocess; the default
at_forkbuilds worker command names from it. - .wait_for_other_processes ⇒ Object private
-
.wait_for_parallel_results(expected, native_wait: false) ⇒ Object
resultset it's going to get, false on timeout.
- .warn_about_deferred_report ⇒ Object
- .warn_about_incomplete_parallel_results(expected, seen) ⇒ Object private
- .warn_about_start_in_dot_simplecov ⇒ void
-
.with_dot_simplecov_autoload ⇒ void
private
Mark the duration of a
.simplecovauto-load so anySimpleCov.startcall inside the file can warn about the impending migration to a config-only file. -
.write_last_run(result) ⇒ void
rounded down (see #679) so the next run can compute drift.
Methods included from Configuration
active_session?, add_filter, add_group, apply_threshold_options, at_exit, at_fork, branch_coverage?, branch_coverage_supported?, build_cover_filter, clear_coverage_criteria, clear_filters, collating_result?, collect_cover_globs, color, command_name, configure, cover, cover_filters, cover_globs, coverage, coverage_criteria, coverage_criterion_enabled?, coverage_criterion_supported?, coverage_dir, coverage_for_eval_enabled?, coverage_for_eval_supported?, coverage_path, current_nocov_token, default_primary_coverage, disable_coverage, enable_coverage, enable_coverage_criterion, enable_coverage_for_eval, enable_eval_coverage, enable_eval_coverage_criterion, enable_for_subprocesses, enable_oneshot_line, enabled_for_subprocesses?, expected_coverage, explicit_coverage_destination?, explicit_custom_coverage_destination?, finalize_merge, finalize_merge?, formatters, formatters=, group, ignore_branches, ignore_methods, ignored_branch?, ignored_branches, ignored_method?, ignored_methods, inferred_finalize_merge?, inferred_finalize_merge_warning, maximum_coverage, maximum_coverage_drop, merge_finalization_owner?, merge_subprocesses, merge_timeout, merging, method_coverage?, method_coverage_supported?, minimum_coverage, minimum_coverage_by_file, minimum_coverage_by_file_overrides, minimum_coverage_by_group, minimum_possible_coverage_exceeded, no_default_skips, nocov_token, parallel_tests, parallel_wait_timeout, parallel_worker_environment?, parse_filter, partition_per_file_thresholds, per_file_coverage_replacement, per_group_coverage_replacement, primary_coverage, print_errors, profiles, project_name, raise_if_branch_type_unsupported, raise_if_criterion_disabled, raise_if_criterion_unsupported, raise_if_method_type_unsupported, raise_on_invalid_coverage, refuse_coverage_drop, remove_filter, render_coverage_blocks, restore_ivars, root, skip, source_in_json, store_minimum_per_file, store_minimum_per_group, store_overall_threshold, swap_ivars_from, track_files, track_files_replacement_hint, tracked_files, use_merging, validate_coverage_criteria!, validate_per_file_key, warn_about_inferred_finalize_merge
Class Attribute Details
.external_at_exit ⇒ Boolean?
Should something external (e.g. the Minitest plugin) own the at_exit behavior instead of SimpleCov's own hook?
61 62 63 |
# File 'lib/simplecov.rb', line 61 def external_at_exit @external_at_exit end |
.pid ⇒ Integer?
Returns the value of attribute pid.
23 24 25 |
# File 'lib/simplecov.rb', line 23 def pid @pid end |
.process_start_time ⇒ Time?
When this process started tracking coverage.
27 28 29 |
# File 'lib/simplecov.rb', line 27 def process_start_time @process_start_time end |
Class Method Details
.at_exit_behavior ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/simplecov/exit_handling.rb', line 20 def at_exit_behavior # If we are in a different process than called start, don't interfere. return if SimpleCov.pid != Process.pid # If Coverage is no longer running (e.g. someone manually stopped it # or a test consumed the result) then don't run exit tasks. return unless Coverage.running? # Stand down when we'd only clobber a fresher report. See # `defer_to_existing_report?` and issue #581. return if defer_to_existing_report? SimpleCov.run_exit_tasks! end |
.clear_result ⇒ void
This method returns an undefined value.
Clear the cached result. Primarily useful in testing.
101 102 103 |
# File 'lib/simplecov/result_processing.rb', line 101 def clear_result @result = nil end |
.collate(result_filenames, profile = nil, ignore_timeout: true) ⇒ void
This method returns an undefined value.
Collate a series of resultset files into a single merged report. By
default ignores merge_timeout so every listed resultset merges;
pass ignore_timeout: false to honor it.
16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/simplecov/result_processing.rb', line 16 def collate(result_filenames, profile = nil, ignore_timeout: true, &) raise ArgumentError, "There are no reports to be merged" if result_filenames.empty? initial_setup(profile, &) # Use the ResultMerger to produce a single, merged result, ready to use. @result = ResultMerger.merge_and_store(*result_filenames, ignore_timeout: ignore_timeout) @collating_result = true run_exit_tasks! ensure @collating_result = false end |
.collating_result? ⇒ Boolean
63 64 65 |
# File 'lib/simplecov/result_processing.rb', line 63 def collating_result? defined?(@collating_result) && @collating_result end |
.coverage_statistics_key(criterion) ⇒ criterion
:oneshot_line stats are folded into the :line bucket, so use
the returned criterion to look up coverage_statistics.
66 67 68 |
# File 'lib/simplecov.rb', line 66 def coverage_statistics_key(criterion) criterion == :oneshot_line ? :line : criterion end |
.defer_to_existing_report? ⇒ Boolean
Returns true when our process has no coverage data to contribute
(after the resultset merge) and a newer report already exists on
disk. Typically fires when SimpleCov.start ran in a parent
process — e.g. a Rakefile or Rails' Bundler.require — that
shelled out to the test runner. See issue #581.
40 41 42 43 44 45 46 47 |
# File 'lib/simplecov/exit_handling.rb', line 40 def defer_to_existing_report? return false unless existing_report_newer_than_us? res = result empty = res.nil? || res.files.empty? warn_about_deferred_report if empty empty end |
.existing_report_newer_than_us? ⇒ Boolean
49 50 51 52 53 54 |
# File 'lib/simplecov/exit_handling.rb', line 49 def existing_report_newer_than_us? return false unless process_start_time last_run_path = File.join(coverage_path, ".last_run.json") File.exist?(last_run_path) && File.mtime(last_run_path) > process_start_time 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.
98 99 100 101 102 103 104 105 106 |
# File 'lib/simplecov/exit_handling.rb', line 98 def exit_and_report_previous_error(exit_status) if print_errors ExitCodes.print_error SimpleCov::Color.colorize( "Stopped processing SimpleCov as a previous error not related to SimpleCov has been detected", :yellow ) end Kernel.exit(exit_status) end |
.exit_status_from_exception ⇒ Object
79 80 81 82 83 84 85 86 87 88 |
# File 'lib/simplecov/exit_handling.rb', line 79 def exit_status_from_exception @exit_exception = $ERROR_INFO return nil unless @exit_exception if @exit_exception.is_a?(SystemExit) @exit_exception.status else SimpleCov::ExitCodes::EXCEPTION end end |
.external_at_exit? ⇒ Boolean
Coerce to a proper boolean so rspec-mocks 4's predicate matcher
(expect(...).not_to be_external_at_exit) accepts the result.
72 73 74 |
# File 'lib/simplecov.rb', line 72 def external_at_exit? !!@external_at_exit end |
.filtered(files) ⇒ FileList
Applies the configured filters to the given source files.
68 69 70 71 72 73 74 |
# File 'lib/simplecov/result_processing.rb', line 68 def filtered(files) result = files.to_a.dup 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.
12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/simplecov/parallel_coordination.rb', line 12 def final_result_process? adapter = SimpleCov::ParallelAdapters.current # No recognized parallel-test adapter. A subprocess forked while # coverage was running is never the final reporter — the process that # spawned it merges every slice and produces the report. Without this, # fork-based runners that don't set TEST_ENV_NUMBER (e.g. Minitest's # `parallelize`) have every worker produce the final report and its # warnings. See issue #1171. return !forked_subprocess? unless adapter adapter.first_worker? end |
.forked_subprocess? ⇒ Boolean
running (set by SimpleCov::ProcessForkHook in the child). Such a child
stores its own slice but must not act as the final-result process: the
process that forked it merges every slice and produces the report. Only
consulted when no parallel-test adapter is active, since adapters answer
first_worker? themselves. See issue #1171.
51 52 53 |
# File 'lib/simplecov.rb', line 51 def forked_subprocess? !!(defined?(@forked_subprocess) && @forked_subprocess) end |
.grouped(files, groups: SimpleCov.groups) ⇒ Hash[String, FileList]
Bin the given source files by group filter. Files matched by no group fall into the implicit "Ungrouped" bucket.
81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/simplecov/result_processing.rb', line 81 def grouped(files, groups: SimpleCov.groups) return {} if groups.empty? grouped = groups.transform_values do |filter| SimpleCov::FileList.new(files.select { |source_file| filter.matches?(source_file) }) end in_group = grouped_file_set(grouped) ungrouped = files.reject { |source_file| in_group.include?(source_file) } grouped["Ungrouped"] = SimpleCov::FileList.new(ungrouped) if ungrouped.any? grouped end |
.install_at_exit_hook ⇒ void
This method returns an undefined value.
Install the at_exit hook that formats results and runs exit-code
checks. Idempotent; SimpleCov.start calls this automatically.
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/simplecov.rb', line 129 def install_at_exit_hook return if @at_exit_hook_installed @at_exit_hook_installed = true # Never defer in a forked child: Minitest pins its after_run at_exit # to the pid that armed autorun, so the deferral target can't fire # there and the child's resultset would be silently dropped. See # issue #1227. defer_to_minitest_after_run if minitest_autorun_pending? && !forked_subprocess? Kernel.at_exit do next if SimpleCov.external_at_exit? SimpleCov.at_exit_behavior end end |
.load_profile(name) ⇒ void
This method returns an undefined value.
Applies the profile of the given name to the configuration.
96 97 98 |
# File 'lib/simplecov/result_processing.rb', line 96 def load_profile(name) profiles.load(name) end |
.mark_forked_subprocess! ⇒ void
This method returns an undefined value.
56 57 58 |
# File 'lib/simplecov.rb', line 56 def mark_forked_subprocess! @forked_subprocess = true end |
.monotonic_time ⇒ Object
102 103 104 |
# File 'lib/simplecov/parallel_coordination.rb', line 102 def monotonic_time Process.clock_gettime(Process::CLOCK_MONOTONIC) end |
.next_subprocess_serial! ⇒ Integer
child inherits its own ordinal via copy-on-write.
41 42 43 |
# File 'lib/simplecov.rb', line 41 def next_subprocess_serial! @subprocess_serial = subprocess_serial + 1 end |
.parallel_results_complete? ⇒ Boolean
before the wait deadline. Defaults to true outside a parallel
run (when wait_for_other_processes is a no-op).
49 50 51 |
# File 'lib/simplecov/parallel_coordination.rb', line 49 def parallel_results_complete? defined?(@parallel_results_complete) ? @parallel_results_complete : true end |
.parallel_wait_timed_out?(deadline, expected, seen) ⇒ Boolean
the first timeout so the user knows the merged total is partial.
108 109 110 111 112 113 |
# File 'lib/simplecov/parallel_coordination.rb', line 108 def parallel_wait_timed_out?(deadline, expected, seen) return false unless monotonic_time > deadline warn_about_incomplete_parallel_results(expected, seen) true end |
.previous_error?(error_exit_status) ⇒ Boolean
accepts it. test_unit sets status 0 on success, so SUCCESS must also be treated as "not a previous error".
93 94 95 |
# File 'lib/simplecov/exit_handling.rb', line 93 def previous_error?(error_exit_status) !!(error_exit_status && error_exit_status != SimpleCov::ExitCodes::SUCCESS) end |
.process_result(result) ⇒ Object
135 136 137 138 139 |
# File 'lib/simplecov/exit_handling.rb', line 135 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_error ⇒ Object
120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/simplecov/exit_handling.rb', line 120 def process_results_and_report_error exit_status = process_result(result) # Force exit with stored status (see github issue #5) return unless exit_status.positive? if print_errors ExitCodes.print_error SimpleCov::Color.colorize( "SimpleCov failed with exit #{exit_status} due to a coverage related error", :red ) end Kernel.exit exit_status end |
.ready_to_process_results? ⇒ Boolean
only one that reports against thresholds, and only when its
wait_for_other_processes confirmed every sibling reported.
When the wait times out, the merged total is partial and
comparing it against minimum_coverage / maximum_coverage
would surface a spurious "below minimum" violation about the
missing slice rather than a real shortfall.
115 116 117 118 |
# File 'lib/simplecov/exit_handling.rb', line 115 def ready_to_process_results? merge_finalization_owner? && final_result_process? && result? && (collating_result? || parallel_results_complete?) end |
.reset_inherited_at_exit_state! ⇒ void
This method returns an undefined value.
Reset at_exit state a forked child inherits from its parent (a possibly consumed hook and a Minitest deferral pid-pinned to the parent), so the child re-arms a hook that fires at its own exit. Called by the fork hook; see issue #1227.
24 25 26 27 |
# File 'lib/simplecov/process.rb', line 24 def reset_inherited_at_exit_state! @at_exit_hook_installed = false self.external_at_exit = false end |
.result ⇒ Result?
The result for the current coverage run, merged across test suites when merging is active. nil when no coverage was tracked.
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/simplecov/result_processing.rb', line 34 def result return @result if result? use_merging = merging # Collect our coverage result. When merging is off there is no merge # step, so this per-process result is the final one and reports any # dropped source files; otherwise the merged result does the reporting. process_coverage_result(report: !use_merging) if defined?(Coverage) && Coverage.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 SimpleCov::ResultMerger.store_result(@result) if result? return @result unless finalize_merge? wait_for_other_processes @result = SimpleCov::ResultMerger.merged_result end @result end |
.result? ⇒ Result, ...
The memoized result, or false/nil when it has not been computed yet.
58 59 60 |
# File 'lib/simplecov/result_processing.rb', line 58 def result? defined?(@result) && @result end |
.result_exit_status(result) ⇒ Object
141 142 143 |
# File 'lib/simplecov/exit_handling.rb', line 141 def result_exit_status(result) ExitCodes::ExitCodeHandling.call(result, coverage_limits: build_coverage_limits) end |
.resultset_count_settled?(tracker, count) ⇒ Boolean
Track whether the resultset count has held steady (and positive) for
PARALLEL_RESULTS_SETTLE seconds. tracker carries the last count and
the time it last changed across poll iterations.
92 93 94 95 96 97 98 99 100 |
# File 'lib/simplecov/parallel_coordination.rb', line 92 def resultset_count_settled?(tracker, count) if count > tracker[:count] tracker[:count] = count tracker[:since] = monotonic_time return false end count.positive? && (monotonic_time - tracker[:since]) >= PARALLEL_RESULTS_SETTLE end |
.round_coverage(coverage) ⇒ Numeric
Round coverage down to two decimals.
114 115 116 |
# File 'lib/simplecov/result_processing.rb', line 114 def round_coverage(coverage) coverage.floor(2) end |
.run_exit_tasks! ⇒ Object
69 70 71 72 73 74 75 76 |
# File 'lib/simplecov/exit_handling.rb', line 69 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) ⇒ void
This method returns an undefined value.
Sets up SimpleCov to run against your project:
SimpleCov.start
SimpleCov.start 'rails' # using a profile
SimpleCov.start { skip 'test' } # with a config block
84 85 86 87 88 89 90 |
# File 'lib/simplecov.rb', line 84 def start(profile = nil, &) warn_about_start_in_dot_simplecov if @autoloading_dot_simplecov initial_setup(profile, &) start_tracking install_at_exit_hook end |
.start_tracking ⇒ void
This method returns an undefined value.
Begin coverage tracking without applying configuration. Pairs with
SimpleCov.configure { ... }.
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/simplecov.rb', line 152 def start_tracking require "coverage" warn_if_jruby_full_trace_disabled validate_coverage_criteria! # simplecov:disable — fork-hook is enabled via SimpleCov.enable_for_subprocesses, off by default require_relative "simplecov/process" if SimpleCov.enabled_for_subprocesses? && ::Process.respond_to?(:_fork) # simplecov:enable # Trigger adapter selection now so the (possibly lazy) parallel_tests # gem load happens at start_tracking time rather than mid-suite. # `current` is memoized; subsequent calls are cheap. SimpleCov::ParallelAdapters.current @result = nil self.pid = Process.pid self.process_start_time = Time.now start_coverage_measurement end |
.subprocess_serial ⇒ Integer
A monotonically increasing serial assigned to each forked
subprocess; the default at_fork builds worker command names from it.
35 36 37 |
# File 'lib/simplecov.rb', line 35 def subprocess_serial @subprocess_serial ||= 0 end |
.wait_for_other_processes ⇒ 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.
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/simplecov/parallel_coordination.rb', line 26 def wait_for_other_processes adapter = SimpleCov::ParallelAdapters.current return unless adapter && final_result_process? # Native synchronization first (adapters that wrap a runner with a # real "wait" primitive — parallel_tests' # `wait_for_other_processes_to_finish` — implement this; adapters # without a native API no-op and rely on the polling fallback below). adapter.wait_for_siblings # The native wait can return before sibling at_exit handlers finish # writing resultsets, and adapters without a native wait have # nothing else. Either way, poll the resultset cache until all # expected workers have reported or a timeout is reached. Capture # the outcome so `ready_to_process_results?` can suppress min/max # threshold checks against a partial total. @parallel_results_complete = wait_for_parallel_results(adapter.expected_worker_count, native_wait: adapter.native_wait?) end |
.wait_for_parallel_results(expected, native_wait: false) ⇒ Object
resultset it's going to get, false on timeout. Single-process runs (expected <= 1) short-circuit to true with no waiting.
Normally we poll until expected (= PARALLEL_TEST_GROUPS) workers have
reported or SimpleCov.parallel_wait_timeout elapses; raise that setting
when a slow worker routinely finishes well after the others.
When a native wait already confirmed every sibling PROCESS exited
(native_wait), no further resultset will appear, so a count below
expected just means some workers produced none — e.g. parallel_test
groups that got no spec file on a machine with more cores than files.
Once the count then holds steady for PARALLEL_RESULTS_SETTLE we accept
it as final rather than blocking for the whole timeout. Without a native
wait (GenericAdapter) we can't tell an idle worker from a slow one, so we
keep waiting the full timeout.
74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/simplecov/parallel_coordination.rb', line 74 def wait_for_parallel_results(expected, native_wait: false) return true unless expected > 1 # simplecov:disable branch — only false in real parallel runs deadline = monotonic_time + parallel_wait_timeout tracker = {count: 0, since: monotonic_time} loop do seen = SimpleCov::ResultMerger.read_resultset.size return true if seen >= expected return true if native_wait && resultset_count_settled?(tracker, seen) return false if parallel_wait_timed_out?(deadline, expected, seen) sleep 0.1 end end |
.warn_about_deferred_report ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/simplecov/exit_handling.rb', line 56 def warn_about_deferred_report return unless print_errors ExitCodes.print_error SimpleCov::Color.colorize( "Skipping SimpleCov report — this process tracked no application code and a newer " \ "report already exists at #{coverage_path}. This usually means SimpleCov.start ran in a " \ "parent process (e.g. a Rakefile or Rails' Bundler.require) that shelled out to the test " \ "runner. See https://github.com/simplecov-ruby/simplecov/issues/581.", :yellow ) end |
.warn_about_incomplete_parallel_results(expected, seen) ⇒ 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.
116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/simplecov/parallel_coordination.rb', line 116 def warn_about_incomplete_parallel_results(expected, seen) return unless print_errors warn SimpleCov::Color.colorize( "Only #{seen} of #{expected} parallel-test workers reported within " \ "#{parallel_wait_timeout}s, so coverage totals are partial and minimum / " \ "maximum coverage checks are skipped for this run. Increase " \ "SimpleCov.parallel_wait_timeout if a worker routinely needs longer.", :yellow ) end |
.warn_about_start_in_dot_simplecov ⇒ void
This method returns an undefined value.
110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/simplecov.rb', line 110 def warn_about_start_in_dot_simplecov return if @dot_simplecov_start_warned @dot_simplecov_start_warned = true warn "[DEPRECATION] Calling `SimpleCov.start` from `.simplecov` is deprecated and will " \ "be removed in a future release. `.simplecov` should contain configuration only; " \ "move the `SimpleCov.start` call into your `spec_helper.rb` / `test_helper.rb`. " \ "Coverage tracking still begins for backward compatibility, but a future release " \ "will require the explicit `SimpleCov.start` from a test helper. " \ "See https://github.com/simplecov-ruby/simplecov/issues/581." end |
.with_dot_simplecov_autoload ⇒ void
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.
This method returns an undefined value.
Mark the duration of a .simplecov auto-load so any SimpleCov.start
call inside the file can warn about the impending migration to a
config-only file. Tracking still begins for backward compatibility;
the warning is the cue to move SimpleCov.start into a test helper.
See #581.
99 100 101 102 103 104 105 106 107 108 |
# File 'lib/simplecov.rb', line 99 def with_dot_simplecov_autoload # Read in the ensure clause, where flow analysis cannot see the # assignment above; anchor the type here. previous = @autoloading_dot_simplecov # : bool? @autoloading_dot_simplecov = true yield ensure # @type var previous: bool? @autoloading_dot_simplecov = previous end |
.write_last_run(result) ⇒ void
This method returns an undefined value.
rounded down (see #679) so the next run can compute drift.
107 108 109 110 111 |
# File 'lib/simplecov/result_processing.rb', line 107 def write_last_run(result) SimpleCov::LastRun.write( result: result.coverage_statistics.transform_values { |stats| round_coverage(stats.percent) } ) end |