Module: SimpleCov
- Extended by:
- Configuration, RunIdentity::Accessors, TestTracker::Accessors, SingleForwardable
- Defined in:
- lib/simplecov/production.rb,
lib/simplecov.rb,
lib/simplecov/cli.rb,
lib/simplecov/color.rb,
lib/simplecov/filter.rb,
lib/simplecov/result.rb,
lib/simplecov/cli/git.rb,
lib/simplecov/cli/run.rb,
lib/simplecov/combine.rb,
lib/simplecov/history.rb,
lib/simplecov/process.rb,
lib/simplecov/version.rb,
lib/simplecov/baseline.rb,
lib/simplecov/cli/diff.rb,
lib/simplecov/cli/open.rb,
lib/simplecov/cli/show.rb,
lib/simplecov/last_run.rb,
lib/simplecov/profiles.rb,
lib/simplecov/cli/badge.rb,
lib/simplecov/cli/clean.rb,
lib/simplecov/cli/merge.rb,
lib/simplecov/cli/patch.rb,
lib/simplecov/cli/serve.rb,
lib/simplecov/cli/tests.rb,
lib/simplecov/cli/usage.rb,
lib/simplecov/cli/watch.rb,
lib/simplecov/directive.rb,
lib/simplecov/file_list.rb,
lib/simplecov/formatter.rb,
lib/simplecov/cli/report.rb,
lib/simplecov/cli/status.rb,
lib/simplecov/exit_codes.rb,
lib/simplecov/atomic_file.rb,
lib/simplecov/cli/dotfile.rb,
lib/simplecov/cli/history.rb,
lib/simplecov/cli/ratchet.rb,
lib/simplecov/context_map.rb,
lib/simplecov/current_run.rb,
lib/simplecov/deprecation.rb,
lib/simplecov/group_names.rb,
lib/simplecov/source_file.rb,
lib/simplecov/cli/affected.rb,
lib/simplecov/cli/coverage.rb,
lib/simplecov/report_stamp.rb,
lib/simplecov/run_identity.rb,
lib/simplecov/test_tracker.rb,
lib/simplecov/cli/badge/svg.rb,
lib/simplecov/cli/dead_code.rb,
lib/simplecov/cli/uncovered.rb,
lib/simplecov/configuration.rb,
lib/simplecov/coverage_json.rb,
lib/simplecov/directive/erb.rb,
lib/simplecov/exit_handling.rb,
lib/simplecov/result_merger.rb,
lib/simplecov/view_coverage.rb,
lib/simplecov/cli/show/sweep.rb,
lib/simplecov/directive/haml.rb,
lib/simplecov/directive/slim.rb,
lib/simplecov/formatter/base.rb,
lib/simplecov/result_adapter.rb,
lib/simplecov/baseline/parser.rb,
lib/simplecov/cli/annotations.rb,
lib/simplecov/cli/completions.rb,
lib/simplecov/cli/diff/output.rb,
lib/simplecov/command_guesser.rb,
lib/simplecov/report_deferral.rb,
lib/simplecov/cli/patch/output.rb,
lib/simplecov/cli/status/facts.rb,
lib/simplecov/cli/watch/poller.rb,
lib/simplecov/exit_codes/check.rb,
lib/simplecov/lines_classifier.rb,
lib/simplecov/production/error.rb,
lib/simplecov/source_file/line.rb,
lib/simplecov/cli/coverage_file.rb,
lib/simplecov/cli/watch/session.rb,
lib/simplecov/context_map/union.rb,
lib/simplecov/parallel_adapters.rb,
lib/simplecov/result_processing.rb,
lib/simplecov/simulate_coverage.rb,
lib/simplecov/cli/history/output.rb,
lib/simplecov/cli/ratchet/output.rb,
lib/simplecov/cli/show/annotator.rb,
lib/simplecov/cli/watch/narrator.rb,
lib/simplecov/directive/template.rb,
lib/simplecov/source_file/branch.rb,
lib/simplecov/source_file/method.rb,
lib/simplecov/test_tracker/delta.rb,
lib/simplecov/cli/command_helpers.rb,
lib/simplecov/cli/watch/test_plan.rb,
lib/simplecov/configuration_error.rb,
lib/simplecov/coverage_statistics.rb,
lib/simplecov/coverage_violations.rb,
lib/simplecov/cli/dead_code/output.rb,
lib/simplecov/cli/tests/redundancy.rb,
lib/simplecov/cli/uncovered/misses.rb,
lib/simplecov/configuration/groups.rb,
lib/simplecov/production/file_sink.rb,
lib/simplecov/result/filter_config.rb,
lib/simplecov/result/serialization.rb,
lib/simplecov/cli/watch/live_report.rb,
lib/simplecov/configuration/filters.rb,
lib/simplecov/configuration/history.rb,
lib/simplecov/configuration/merging.rb,
lib/simplecov/parallel_coordination.rb,
lib/simplecov/cli/affected/selection.rb,
lib/simplecov/combine/lines_combiner.rb,
lib/simplecov/configuration/baseline.rb,
lib/simplecov/configuration/coverage.rb,
lib/simplecov/parallel_adapters/base.rb,
lib/simplecov/parallel_result_merger.rb,
lib/simplecov/result_merger/contexts.rb,
lib/simplecov/source_file/statistics.rb,
lib/simplecov/test_tracker/accessors.rb,
lib/simplecov/unloaded_file_injector.rb,
lib/simplecov/cli/completions/scripts.rb,
lib/simplecov/cli/patch/changed_lines.rb,
lib/simplecov/combine/interned_counts.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/production.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/cli/serve/report_preparer.rb,
lib/simplecov/combine/branches_combiner.rb,
lib/simplecov/combine/identity_interner.rb,
lib/simplecov/configuration/missed_caps.rb,
lib/simplecov/exit_codes/baseline_check.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/cli/affected/changed_files.rb,
lib/simplecov/configuration/deprecations.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/configuration/eval_coverage.rb,
lib/simplecov/configuration/test_tracking.rb,
lib/simplecov/configuration/view_coverage.rb,
lib/simplecov/directive/indented_template.rb,
lib/simplecov/source_file/builder_context.rb,
lib/simplecov/test_tracker/constant_watch.rb,
lib/simplecov/combine/coverage_accumulator.rb,
lib/simplecov/formatter/baseline_formatter.rb,
lib/simplecov/result_merger/resultset_file.rb,
lib/simplecov/result_merger/unloaded_files.rb,
lib/simplecov/source_file/ruby_data_parser.rb,
lib/simplecov/test_tracker/framework_hooks.rb,
lib/simplecov/cli/serve/static_file_handler.rb,
lib/simplecov/configuration/ignored_entries.rb,
lib/simplecov/exit_codes/exit_code_handling.rb,
lib/simplecov/result_merger/resultset_store.rb,
lib/simplecov/formatter/coverage_json_writer.rb,
lib/simplecov/configuration/coverage_criteria.rb,
lib/simplecov/exit_codes/maximum_missed_check.rb,
lib/simplecov/view_coverage/template_compiler.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/result_merger/resultset_run_identity.rb,
lib/simplecov/parallel_result_merger/worker_payload.rb,
lib/simplecov/exit_codes/maximum_coverage_drop_check.rb,
lib/simplecov/static_coverage_extractor/prism_compat.rb,
lib/simplecov/exit_codes/maximum_missed_per_file_check.rb,
lib/simplecov/static_coverage_extractor/value_position.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/static_coverage_extractor/condition_folding.rb,
lib/simplecov/formatter/html_formatter/viewer_data_validator.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,
lib/simplecov/formatter/json_formatter/production_section_formatter.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,
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
simplecov:disable Methods below only fire under a parallel test runner; not reachable from a single-process rspec run. Cucumber's test_projects exercise the parallel_tests integration end-to-end in subprocesses, but those subprocesses don't merge their Coverage data back into the parent this dogfood report measures.
Defined Under Namespace
Modules: AtomicFile, CLI, Color, Combine, CommandGuesser, Configuration, CoverageJSON, CoverageViolations, Deprecation, ExitCodes, Formatter, GroupNames, History, LastRun, ParallelAdapters, ParallelResultMerger, ProcessForkHook, Production, ReportStamp, ResultMerger, RunIdentity, SimulateCoverage, StaticCoverageExtractor, UnloadedFileInjector, UselessResultsRemover, ViewCoverage Classes: ArrayFilter, Baseline, BlockFilter, ConfigurationError, ContextMap, CoverageLimits, CoverageStatistics, CurrentRun, Directive, FileList, Filter, GlobFilter, LinesClassifier, Profiles, RegexFilter, Result, ResultAdapter, SourceFile, StringFilter, TestTracker
Constant Summary collapse
- CRITERION_TO_RUBY_COVERAGE =
At module scope rather than inside
class << selfso it can be declared in the RBS signatures; lexical scoping keeps references inside the singleton class working. { branch: :branches, line: :lines, method: :methods, oneshot_line: :oneshot_lines }.freeze
- VERSION =
"1.3.0"
Constants included from Configuration
Configuration::BUILT_IN_FORMATS, Configuration::COVERAGE_THRESHOLD_OPTIONS, Configuration::DEFAULT_COVERAGE_CRITERION, Configuration::DEFAULT_VIEW_GLOBS, Configuration::DEPRECATION_MODES, Configuration::DROP_BASELINES, Configuration::IGNORABLE_BRANCH_TYPES, Configuration::IGNORABLE_METHOD_TYPES, Configuration::LAZY_FORMAT_REQUIRES, Configuration::LINE_COVERAGE_ALTERNATIVES, Configuration::ONESHOT_LINE_COVERAGE_CRITERION, Configuration::SUPPORTED_COVERAGE_CRITERIA, Configuration::TRACK_TESTS_GRANULARITIES
Class Attribute Summary collapse
- .current_run ⇒ CurrentRun
-
.external_at_exit ⇒ Boolean?
Returns the value of attribute external_at_exit.
-
.pid ⇒ Integer?
Returns the value of attribute pid.
-
.process_start_time ⇒ Time?
Returns the value of attribute process_start_time.
Attributes included from Configuration
#filters, #formatter, #groups, #print_error_status
Class Method Summary collapse
- .at_exit_behavior ⇒ Object
- .clear_result ⇒ void
-
.collate(result_filenames, profile = nil, processes: ENV["SIMPLECOV_CONCURRENCY"].to_i, ignore_timeout: true) ⇒ void
By default
collateignores the merge_timeout so all results in all files specified will be merged. - .collating_result? ⇒ boolish
-
.collect_own_coverage(standalone:) ⇒ void
standaloneis true when no merge step follows, which makes this the final result: the one that reports dropped source files and injects unloaded files. -
.coverage_statistics_key(criterion) ⇒ criterion
:oneshot_linedata is folded into the:linebucket ofcoverage_statisticsbyResultAdapter. - .current_parallel_worker_count ⇒ Object
- .defer_to_existing_report? ⇒ Boolean
-
.existing_report_newer_than_us? ⇒ Boolean
.last_run.jsononly exists after fully successful runs, so alone it left the backstop inert when the child run failed, the case where clobbering its report hurts most. - .exit_status_from_exception ⇒ Object private
-
.external_at_exit? ⇒ Boolean
Coerced so rspec-mocks 4's predicate matcher accepts the result.
- .filtered(files) ⇒ FileList
- .final_result_process? ⇒ Boolean private
- .forked_subprocess? ⇒ Boolean
-
.grouped(files, groups: default_groups) ⇒ Hash[String, FileList]
Files matched by no group fall into the implicit "Ungrouped" bucket.
-
.inject_unloaded_files(result, candidate_paths, synthesize: nil, lines: nil) ⇒ [Hash[String, untyped], Set[String]]
only because the merge runs in another object, on behalf of processes whose configuration it may not share, so it supplies the paths itself.
- .install_at_exit_hook ⇒ void
- .load_profile(name) ⇒ void
- .mark_forked_subprocess! ⇒ void
- .merge_own_slice ⇒ Object
- .monotonic_time ⇒ Object
- .next_subprocess_serial! ⇒ Integer
-
.parallel_results_complete? ⇒ Boolean
wait deadline.
-
.parallel_wait_timed_out?(deadline, expected, seen) ⇒ Boolean
total is partial.
-
.previous_error?(error_exit_status) ⇒ Boolean
accepts it.
-
.process_result(result) ⇒ Object
condition
.last_run.jsonuses, so a run that failed its thresholds becomes neither the drop baseline nor a data point in the trend. -
.ready_to_process_results? ⇒ Boolean
that reports against thresholds, and only when its
wait_for_other_processesconfirmed every sibling reported. -
.report_previous_error ⇒ Object
caller's to answer with.
-
.report_processing_failure(exit_status) ⇒ Object
it is a coverage failure worth explaining.
-
.reset_inherited_at_exit_state! ⇒ void
Forked children inherit at_exit state that is wrong for them: before forking (Minitest autorun runs the suite inside the parent's at_exit), and external_at_exit may point at a Minitest.after_run deferral that is pid-pinned to the parent.
- .result ⇒ Result?
- .result? ⇒ Result, ...
- .result_exit_status(result) ⇒ Object
-
.resultset_count_settled?(tracker, count) ⇒ Boolean
trackercarries the last count and the time it last changed across poll iterations. - .round_coverage(coverage) ⇒ Numeric
-
.run_exit_tasks(error_exit_status = exit_status_from_exception) ⇒ Object
exit status the process should end with rather than performed as an exit.
-
.run_exit_tasks!(error_exit_status = exit_status_from_exception) ⇒ Object
at_exit block (which pre-captures the status, see there) and by
collate. - .run_id ⇒ String
- .start(profile = nil) ⇒ void
- .start_test_tracking ⇒ void
- .start_tracking ⇒ void
-
.started_in_this_process? ⇒ Boolean
mutant:disable -- a pid is an Integer, and Integers answer ==, eql? and equal? alike for the same value.
- .subprocess_serial ⇒ Integer
-
.successful?(status) ⇒ Boolean
Asked as a predicate rather than compared against
ExitCodes::SUCCESS, because two equal Integers are equal through every spelling of the comparison. - .test_tracker ⇒ TestTracker?
- .track_test ⇒ void
- .wait_for_other_processes ⇒ Object private
-
.wait_for_parallel_results(expected, native_wait: false) ⇒ Object
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
- .worker_id ⇒ String
- .write_last_run(result) ⇒ void
Methods included from Configuration
__send__, active_session?, add_coverage_criterion, add_filter, add_group, apply_threshold_options, at_exit, at_fork, baseline, baseline_file, baseline_file=, branch_coverage?, branch_coverage_supported?, build_cover_filter, clear_coverage_criteria, clear_filters, collating_result?, collect_cover_globs, color, color=, combined_formatter, command_name, command_name=, configure, cover, cover_filters, cover_globs, cover_views, coverage, coverage_criteria, coverage_criterion_enabled?, coverage_criterion_supported?, coverage_dir, coverage_dir=, coverage_for_eval_enabled?, coverage_for_eval_supported?, coverage_path, coverage_path=, coverage_running?, current_nocov_token, default_groups, default_primary_coverage, deprecations, disable_coverage, disable_eval_coverage, drop_baseline, enable_coverage, enable_coverage_criterion, enable_coverage_for_eval, enable_eval_coverage, enable_for_subprocesses, enabled_for_subprocesses?, env_merge_timeout, expected_coverage, explicit_coverage_destination?, explicit_custom_coverage_destination?, final_result_process?, finalize_merge, finalize_merge=, finalize_merge?, formats, formatters, formatters=, group, history_limit, history_limit=, ignore_branches, ignore_methods, ignored_branch?, ignored_branches, ignored_method?, ignored_methods, inferred_finalize_merge?, inferred_finalize_merge_warning, line_coverage?, load_coverage, maximum_coverage, maximum_coverage_drop, maximum_missed, maximum_missed_per_file, maximum_missed_per_file_overrides, merge_finalization_owner?, merge_subprocesses, merge_subprocesses=, merge_timeout, merge_timeout=, merging, 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, missed_per_file_replacement, no_default_skips, nocov_token, normalized_missed_caps, normalized_threshold, parallel_tests, parallel_tests=, parallel_wait_timeout, parallel_wait_timeout=, parallel_worker_environment?, parse_filter, partition_per_file_thresholds, per_file_coverage_replacement, per_group_coverage_replacement, primary_coverage, primary_coverage=, print_errors, print_errors=, production_coverage, production_coverage=, 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, raise_on_invalid_missed_cap, refuse_coverage_drop, remove_filter, render_coverage_blocks, require_html_formatter, resolve_criterion_variant, resolve_format, root, root=, skip, source_in_json, source_in_json=, store_ignored_branches, store_ignored_methods, store_maximum_missed_per_file, store_minimum_per_file, store_minimum_per_group, store_missed_cap, store_overall_threshold, track_files, track_files_replacement_hint, track_tests, track_tests?, track_tests_granularity, tracked_files, use_merging, validate_coverage_criteria!, validate_per_file_key, validate_test_tracking!, view_coverage?, view_globs, warn_about_inferred_finalize_merge
Methods included from TestTracker::Accessors
start_test_tracking, test_tracker, track_test
Methods included from RunIdentity::Accessors
Class Attribute Details
.current_run ⇒ CurrentRun
29 30 31 |
# File 'lib/simplecov.rb', line 29 def current_run @current_run ||= CurrentRun.new end |
.external_at_exit ⇒ Boolean?
Returns the value of attribute external_at_exit.
36 37 38 |
# File 'lib/simplecov.rb', line 36 def external_at_exit @external_at_exit end |
.pid ⇒ Integer?
Returns the value of attribute pid.
36 37 38 |
# File 'sig/simplecov.rbs', line 36 def pid @pid end |
.process_start_time ⇒ Time?
Returns the value of attribute process_start_time.
38 39 40 |
# File 'sig/simplecov.rbs', line 38 def process_start_time @process_start_time end |
Class Method Details
.at_exit_behavior ⇒ Object
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/simplecov/exit_handling.rb', line 26 def at_exit_behavior # A different process than the one that called start; don't interfere. return unless started_in_this_process? # Coverage is no longer running (someone stopped it manually, or a test # consumed the result), so don't run exit tasks. return unless Coverage.running? # Captured BEFORE the deferral probe: its freshness check rescues # filesystem errors, and completing any rescue inside an at_exit handler # resets $ERROR_INFO to nil. error_exit_status = exit_status_from_exception # Stand down when we'd only clobber a fresher report (#581). return if defer_to_existing_report? run_exit_tasks!(error_exit_status) end |
.clear_result ⇒ void
This method returns an undefined value.
83 84 85 |
# File 'lib/simplecov/result_processing.rb', line 83 def clear_result current_run.result = nil end |
.collate(result_filenames, profile = nil, processes: ENV["SIMPLECOV_CONCURRENCY"].to_i, ignore_timeout: true) ⇒ void
This method returns an undefined value.
By default collate ignores the merge_timeout so all results in all
files specified will be merged. Pass ignore_timeout: false to honor it.
processes: above 1 fans the merge out across that many forked workers.
The report is identical either way, not merely equivalent. The count is
deliberately not clamped to the machine's core count nor gated on a
minimum number of resultsets: what a collate job can afford is the
caller's call. Anything below 1 is taken as 1, so an unset
SIMPLECOV_CONCURRENCY needs no default of its own.
14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/simplecov/result_processing.rb', line 14 def collate(result_filenames, profile = nil, processes: ENV["SIMPLECOV_CONCURRENCY"].to_i, ignore_timeout: true, &) raise ArgumentError, "There are no reports to be merged" if result_filenames.empty? initial_setup(profile, &) current_run.result = ParallelResultMerger.merge_and_store(*result_filenames, processes: [1, processes].max, ignore_timeout: ignore_timeout) current_run.collating_result = true run_exit_tasks! ensure current_run.collating_result = false end |
.collating_result? ⇒ boolish
104 |
# File 'sig/simplecov.rbs', line 104
def self.collating_result?: () -> boolish
|
.collect_own_coverage(standalone:) ⇒ void
This method returns an undefined value.
standalone is true when no merge step follows, which makes this the
final result: the one that reports dropped source files and injects
unloaded files. When a merge does follow, both jobs belong to the merge.
49 50 51 52 53 |
# File 'lib/simplecov/result_processing.rb', line 49 def collect_own_coverage(standalone:) return unless defined?(Coverage) && Coverage.running? process_coverage_result(report: standalone, inject_unloaded: standalone) end |
.coverage_statistics_key(criterion) ⇒ criterion
:oneshot_line data is folded into the :line bucket of
coverage_statistics by ResultAdapter. The cast is steep's: it narrows
a union on == but not on equal?.
41 42 43 |
# File 'lib/simplecov.rb', line 41 def coverage_statistics_key(criterion) criterion.equal?(:oneshot_line) ? :line : _ = criterion end |
.current_parallel_worker_count ⇒ Object
78 79 80 81 |
# File 'lib/simplecov/parallel_coordination.rb', line 78 def current_parallel_worker_count resultset = ResultMerger.read_resultset ResultMerger.worker_identities_for_run(resultset, run_id, process_start_time).size end |
.defer_to_existing_report? ⇒ Boolean
10 11 12 13 14 15 16 17 |
# File 'lib/simplecov/report_deferral.rb', line 10 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
.last_run.json only exists after fully successful runs, so alone it left
the backstop inert when the child run failed, the case where clobbering its
report hurts most. The report stamp is touched by every formatting process
regardless of exit status. The rescue covers a file vanishing mid-at_exit.
23 24 25 26 27 28 29 30 31 |
# File 'lib/simplecov/report_deferral.rb', line 23 def existing_report_newer_than_us? return false unless process_start_time [LastRun.last_run_path, ReportStamp.path].any? do |path| File.mtime(path) > process_start_time rescue SystemCallError false end end |
.exit_status_from_exception ⇒ 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.
72 73 74 75 76 77 78 79 80 81 |
# File 'lib/simplecov/exit_handling.rb', line 72 def exit_status_from_exception @exit_exception = $ERROR_INFO return nil unless @exit_exception if @exit_exception.is_a?(SystemExit) @exit_exception.status else ExitCodes::EXCEPTION end end |
.external_at_exit? ⇒ Boolean
Coerced so rspec-mocks 4's predicate matcher accepts the result.
46 47 48 |
# File 'lib/simplecov.rb', line 46 def external_at_exit? !!@external_at_exit end |
.filtered(files) ⇒ FileList
55 56 57 58 59 60 61 |
# File 'lib/simplecov/result_processing.rb', line 55 def filtered(files) result = files.to_a filters.each do |filter| result = result.reject { |source_file| filter.matches?(source_file) } end 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 |
# File 'lib/simplecov/parallel_coordination.rb', line 12 def final_result_process? adapter = ParallelAdapters.current # 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 (Minitest's `parallelize`) have every worker produce # the final report and its warnings (#1171). return !forked_subprocess? unless adapter adapter.first_worker? end |
.forked_subprocess? ⇒ Boolean
58 |
# File 'sig/simplecov.rbs', line 58
def self.forked_subprocess?: () -> bool
|
.grouped(files, groups: default_groups) ⇒ Hash[String, FileList]
Files matched by no group fall into the implicit "Ungrouped" bucket. Any group left empty, Ungrouped included, is dropped so a profile's unused groups (#1293) don't pad the report as 100% covered.
66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/simplecov/result_processing.rb', line 66 def grouped(files, groups: default_groups) return {} if GroupNames.validate!(groups.keys).empty? grouped = groups.transform_values do |filter| FileList.new(files.select { |source_file| filter.matches?(source_file) }) end in_group = grouped_file_set(grouped) grouped[GroupNames::UNGROUPED] = FileList.new(files.reject { |source_file| in_group.include?(source_file) }) grouped.reject { |_name, group_files| group_files.empty? } end |
.inject_unloaded_files(result, candidate_paths, synthesize: nil, lines: nil) ⇒ [Hash[String, untyped], Set[String]]
only because the merge runs in another object, on behalf of processes whose configuration it may not share, so it supplies the paths itself.
102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/simplecov/result_processing.rb', line 102 def inject_unloaded_files(result, candidate_paths, synthesize: nil, lines: nil) return [result, Set.new] if candidate_paths.empty? # Synthesizing branch and method tuples means parsing every tracked file # that wasn't loaded, about half the cost of simulating one, and nothing # reads those tuples when neither criterion is enabled. The same goes for # line data, which a branch-only or method-only run neither reports nor # receives from `Coverage` for the files it loaded (#1250). UnloadedFileInjector.call( result, candidate_paths, synthesize: synthesize.nil? ? branch_coverage? || method_coverage? : synthesize, lines: lines.nil? ? line_coverage? : lines ) end |
.install_at_exit_hook ⇒ void
This method returns an undefined value.
80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/simplecov.rb', line 80 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 (#1227). defer_to_minitest_after_run if minitest_autorun_pending? && !forked_subprocess? Kernel.at_exit do next if external_at_exit? at_exit_behavior end end |
.load_profile(name) ⇒ void
This method returns an undefined value.
79 80 81 |
# File 'lib/simplecov/result_processing.rb', line 79 def load_profile(name) profiles.load(name) end |
.mark_forked_subprocess! ⇒ void
This method returns an undefined value.
60 |
# File 'sig/simplecov.rbs', line 60
def self.mark_forked_subprocess!: () -> void
|
.merge_own_slice ⇒ Object
38 39 40 41 42 43 44 |
# File 'lib/simplecov/result_processing.rb', line 38 def merge_own_slice ResultMerger.store_result(result) if result? return unless merge_finalization_owner? wait_for_other_processes current_run.result = ResultMerger.merged_result end |
.monotonic_time ⇒ Object
97 98 99 |
# File 'lib/simplecov/parallel_coordination.rb', line 97 def monotonic_time Process.clock_gettime(Process::CLOCK_MONOTONIC) end |
.next_subprocess_serial! ⇒ Integer
56 |
# File 'sig/simplecov.rbs', line 56
def self.next_subprocess_serial!: () -> Integer
|
.parallel_results_complete? ⇒ Boolean
wait deadline. Defaults to true outside a parallel run.
44 45 46 |
# File 'lib/simplecov/parallel_coordination.rb', line 44 def parallel_results_complete? instance_variable_defined?(:@parallel_results_complete) ? @parallel_results_complete : true end |
.parallel_wait_timed_out?(deadline, expected, seen) ⇒ Boolean
total is partial.
103 104 105 106 107 108 |
# File 'lib/simplecov/parallel_coordination.rb', line 103 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".
86 87 88 89 90 |
# File 'lib/simplecov/exit_handling.rb', line 86 def previous_error?(error_exit_status) return false unless error_exit_status !successful?(error_exit_status) end |
.process_result(result) ⇒ Object
condition .last_run.json uses, so a run that failed its thresholds
becomes neither the drop baseline nor a data point in the trend.
127 128 129 130 131 132 133 134 |
# File 'lib/simplecov/exit_handling.rb', line 127 def process_result(result) result_exit_status = result_exit_status(result) if successful?(result_exit_status) write_last_run(result) History.record(result) end result_exit_status end |
.ready_to_process_results? ⇒ Boolean
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 the
thresholds would surface a spurious violation about the missing slice.
108 109 110 111 |
# File 'lib/simplecov/exit_handling.rb', line 108 def ready_to_process_results? merge_finalization_owner? && result? && (collating_result? || parallel_results_complete?) end |
.report_previous_error ⇒ Object
caller's to answer with.
94 95 96 97 98 99 100 101 |
# File 'lib/simplecov/exit_handling.rb', line 94 def report_previous_error return unless print_errors ExitCodes.print_error Color.colorize( "Stopped processing SimpleCov as a previous error not related to SimpleCov has been detected", :yellow ) end |
.report_processing_failure(exit_status) ⇒ Object
it is a coverage failure worth explaining.
115 116 117 118 119 120 121 122 |
# File 'lib/simplecov/exit_handling.rb', line 115 def report_processing_failure(exit_status) if exit_status.positive? && print_errors ExitCodes.print_error Color.colorize( "SimpleCov failed with exit #{exit_status} due to a coverage related error", :red ) end exit_status end |
.reset_inherited_at_exit_state! ⇒ void
This method returns an undefined value.
Forked children inherit at_exit state that is wrong for them:
before forking (Minitest autorun runs the suite inside the parent's
at_exit), and external_at_exit may point at a Minitest.after_run deferral
that is pid-pinned to the parent. Resetting both is what lets the at_fork
proc's SimpleCov.start install a hook that actually fires (#1227).
11 12 13 14 |
# File 'lib/simplecov/process.rb', line 11 def reset_inherited_at_exit_state! @at_exit_hook_installed = false self.external_at_exit = false end |
.result ⇒ Result?
29 30 31 32 33 34 35 36 |
# File 'lib/simplecov/result_processing.rb', line 29 def result return current_run.result if result? merge = merging collect_own_coverage(standalone: !merge) merge_own_slice if merge current_run.result end |
.result? ⇒ Result, ...
102 |
# File 'sig/simplecov.rbs', line 102
def self.result?: () -> (Result | false | nil)
|
.result_exit_status(result) ⇒ Object
149 150 151 |
# File 'lib/simplecov/exit_handling.rb', line 149 def result_exit_status(result) ExitCodes::ExitCodeHandling.call(result, coverage_limits: build_coverage_limits) end |
.resultset_count_settled?(tracker, count) ⇒ Boolean
tracker carries the last count and the time it last changed across poll
iterations. Answered through an if/else rather than an early return
because falling through after a climb would read the clock a second time
and answer the same false anyway.
87 88 89 90 91 92 93 94 95 |
# File 'lib/simplecov/parallel_coordination.rb', line 87 def resultset_count_settled?(tracker, count) if count > tracker.fetch(:count) tracker[:count] = count tracker[:since] = monotonic_time false else count.positive? && (monotonic_time - tracker.fetch(:since)) >= PARALLEL_RESULTS_SETTLE end end |
.round_coverage(coverage) ⇒ Numeric
95 96 97 |
# File 'lib/simplecov/result_processing.rb', line 95 def round_coverage(coverage) coverage.floor(2) end |
.run_exit_tasks(error_exit_status = exit_status_from_exception) ⇒ Object
exit status the process should end with rather than performed as an exit. The one side effect left to the caller is ending the process, which is what makes this whole path answerable from inside a test.
49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/simplecov/exit_handling.rb', line 49 def run_exit_tasks(error_exit_status = exit_status_from_exception) at_exit.call if previous_error?(error_exit_status) report_previous_error error_exit_status elsif ready_to_process_results? report_processing_failure(process_result(result)) else ExitCodes::SUCCESS end end |
.run_exit_tasks!(error_exit_status = exit_status_from_exception) ⇒ Object
at_exit block (which pre-captures the status, see there) and by collate.
64 65 66 67 68 69 |
# File 'lib/simplecov/exit_handling.rb', line 64 def run_exit_tasks!(error_exit_status = exit_status_from_exception) status = run_exit_tasks(error_exit_status) # Force exit with stored status (#5). Kernel.exit(status) unless successful?(status) end |
.run_id ⇒ String
40 |
# File 'sig/simplecov.rbs', line 40
def self.run_id: () -> String
|
.start(profile = nil) ⇒ void
This method returns an undefined value.
50 51 52 53 54 55 56 |
# File 'lib/simplecov.rb', line 50 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_test_tracking ⇒ void
This method returns an undefined value.
48 |
# File 'sig/simplecov.rbs', line 48
def self.start_test_tracking: () -> void
|
.start_tracking ⇒ void
This method returns an undefined value.
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/simplecov.rb', line 95 def start_tracking require "coverage" warn_if_jruby_full_trace_disabled validate_coverage_criteria! require_relative "simplecov/process" if enabled_for_subprocesses? && Process.respond_to?(:_fork) # Must happen before any forks. RunIdentity.prepare self.current_run = current_run.successor self.pid = Process.pid self.process_start_time = Time.now start_coverage_measurement end |
.started_in_this_process? ⇒ Boolean
mutant:disable -- a pid is an Integer, and Integers answer ==, eql? and equal? alike for the same value.
138 139 140 |
# File 'lib/simplecov/exit_handling.rb', line 138 def started_in_this_process? SimpleCov.pid == Process.pid end |
.subprocess_serial ⇒ Integer
54 |
# File 'sig/simplecov.rbs', line 54
def self.subprocess_serial: () -> Integer
|
.successful?(status) ⇒ Boolean
Asked as a predicate rather than compared against ExitCodes::SUCCESS,
because two equal Integers are equal through every spelling of the
comparison.
145 146 147 |
# File 'lib/simplecov/exit_handling.rb', line 145 def successful?(status) status.zero? end |
.test_tracker ⇒ TestTracker?
46 |
# File 'sig/simplecov.rbs', line 46
def self.test_tracker: () -> TestTracker?
|
.track_test ⇒ void
This method returns an undefined value.
44 |
# File 'sig/simplecov.rbs', line 44
def self.track_test: [T] (String test_id) { () -> T } -> T
|
.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.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/simplecov/parallel_coordination.rb', line 25 def wait_for_other_processes adapter = ParallelAdapters.current return unless adapter && final_result_process? # Adapters that wrap a runner with a real "wait" primitive implement # this; the rest 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. The outcome is captured so # threshold checks can be suppressed 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
going to get, false on timeout. Single-process runs short-circuit.
Normally we poll until expected workers have reported or
SimpleCov.parallel_wait_timeout elapses. When a native wait already
confirmed every sibling process exited, no further resultset will appear,
so a count below expected just means some workers produced none, and
once the count holds steady for PARALLEL_RESULTS_SETTLE we accept it as
final. Without a native wait we can't tell an idle worker from a slow
one, so we keep waiting the full timeout.
63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/simplecov/parallel_coordination.rb', line 63 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 = current_parallel_worker_count 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
33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/simplecov/report_deferral.rb', line 33 def warn_about_deferred_report return unless print_errors ExitCodes.print_error 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.
111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/simplecov/parallel_coordination.rb', line 111 def warn_about_incomplete_parallel_results(expected, seen) return unless print_errors warn 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.
68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/simplecov.rb', line 68 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.
59 60 61 62 63 64 65 66 |
# File 'lib/simplecov.rb', line 59 def with_dot_simplecov_autoload previous = @autoloading_dot_simplecov # : bool? @autoloading_dot_simplecov = true yield ensure # @type var previous: bool? @autoloading_dot_simplecov = previous end |
.worker_id ⇒ String
42 |
# File 'sig/simplecov.rbs', line 42
def self.worker_id: () -> String
|