simplecov 0.21.2 → 1.0.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +90 -0
- data/LICENSE +1 -1
- data/README.md +1018 -508
- data/doc/alternate-formatters.md +0 -5
- data/doc/commercial-services.md +5 -5
- data/exe/simplecov +11 -0
- data/lib/minitest/simplecov_plugin.rb +13 -5
- data/lib/simplecov/autostart.rb +11 -0
- data/lib/simplecov/cli/clean.rb +47 -0
- data/lib/simplecov/cli/coverage.rb +91 -0
- data/lib/simplecov/cli/diff.rb +151 -0
- data/lib/simplecov/cli/dotfile.rb +100 -0
- data/lib/simplecov/cli/merge.rb +116 -0
- data/lib/simplecov/cli/open.rb +50 -0
- data/lib/simplecov/cli/report.rb +84 -0
- data/lib/simplecov/cli/run.rb +36 -0
- data/lib/simplecov/cli/serve.rb +139 -0
- data/lib/simplecov/cli/uncovered.rb +107 -0
- data/lib/simplecov/cli.rb +150 -0
- data/lib/simplecov/color.rb +74 -0
- data/lib/simplecov/combine/branches_combiner.rb +3 -2
- data/lib/simplecov/combine/files_combiner.rb +7 -1
- data/lib/simplecov/combine/lines_combiner.rb +19 -17
- data/lib/simplecov/combine/methods_combiner.rb +26 -0
- data/lib/simplecov/combine/results_combiner.rb +5 -4
- data/lib/simplecov/command_guesser.rb +46 -32
- data/lib/simplecov/configuration/coverage.rb +171 -0
- data/lib/simplecov/configuration/coverage_criteria.rb +156 -0
- data/lib/simplecov/configuration/filters.rb +195 -0
- data/lib/simplecov/configuration/formatting.rb +119 -0
- data/lib/simplecov/configuration/ignored_entries.rb +63 -0
- data/lib/simplecov/configuration/merging.rb +74 -0
- data/lib/simplecov/configuration/thresholds.rb +174 -0
- data/lib/simplecov/configuration.rb +79 -386
- data/lib/simplecov/coverage_statistics.rb +12 -9
- data/lib/simplecov/coverage_violations.rb +148 -0
- data/lib/simplecov/defaults.rb +27 -20
- data/lib/simplecov/directive.rb +162 -0
- data/lib/simplecov/exit_codes/exit_code_handling.rb +8 -2
- data/lib/simplecov/exit_codes/maximum_coverage_drop_check.rb +19 -57
- data/lib/simplecov/exit_codes/maximum_overall_coverage_check.rb +45 -0
- data/lib/simplecov/exit_codes/minimum_coverage_by_file_check.rb +17 -27
- data/lib/simplecov/exit_codes/minimum_coverage_by_group_check.rb +41 -0
- data/lib/simplecov/exit_codes/minimum_overall_coverage_check.rb +38 -21
- data/lib/simplecov/exit_codes.rb +3 -0
- data/lib/simplecov/exit_handling.rb +158 -0
- data/lib/simplecov/file_list.rb +61 -17
- data/lib/simplecov/filter.rb +69 -24
- data/lib/simplecov/formatter/base.rb +101 -0
- data/lib/simplecov/formatter/html_formatter/public/application.css +1 -0
- data/lib/simplecov/formatter/html_formatter/public/application.js +18 -0
- data/lib/simplecov/formatter/html_formatter/public/favicon_green.png +0 -0
- data/lib/simplecov/formatter/html_formatter/public/favicon_red.png +0 -0
- data/lib/simplecov/formatter/html_formatter/public/favicon_yellow.png +0 -0
- data/lib/simplecov/formatter/html_formatter/public/index.html +56 -0
- data/lib/simplecov/formatter/html_formatter.rb +79 -0
- data/lib/simplecov/formatter/json_formatter/errors_formatter.rb +84 -0
- data/lib/simplecov/formatter/json_formatter/result_hash_formatter.rb +127 -0
- data/lib/simplecov/formatter/json_formatter/source_file_formatter.rb +99 -0
- data/lib/simplecov/formatter/json_formatter.rb +77 -0
- data/lib/simplecov/formatter/multi_formatter.rb +4 -5
- data/lib/simplecov/formatter/simple_formatter.rb +9 -11
- data/lib/simplecov/formatter.rb +4 -0
- data/lib/simplecov/last_run.rb +10 -3
- data/lib/simplecov/lines_classifier.rb +26 -13
- data/lib/simplecov/load_global_config.rb +9 -4
- data/lib/simplecov/parallel_adapters/base.rb +51 -0
- data/lib/simplecov/parallel_adapters/generic.rb +42 -0
- data/lib/simplecov/parallel_adapters/parallel_tests.rb +77 -0
- data/lib/simplecov/parallel_adapters.rb +83 -0
- data/lib/simplecov/parallel_coordination.rb +95 -0
- data/lib/simplecov/process.rb +20 -14
- data/lib/simplecov/profiles/bundler_filter.rb +1 -1
- data/lib/simplecov/profiles/hidden_filter.rb +1 -1
- data/lib/simplecov/profiles/rails.rb +24 -10
- data/lib/simplecov/profiles/root_filter.rb +6 -5
- data/lib/simplecov/profiles/strict.rb +32 -0
- data/lib/simplecov/profiles/test_frameworks.rb +1 -4
- data/lib/simplecov/profiles.rb +32 -3
- data/lib/simplecov/result/missing_source_files_reporter.rb +49 -0
- data/lib/simplecov/result/source_file_builder.rb +51 -0
- data/lib/simplecov/result.rb +97 -19
- data/lib/simplecov/result_adapter.rb +68 -6
- data/lib/simplecov/result_merger/legacy_format_adapter.rb +28 -0
- data/lib/simplecov/result_merger/resultset_file.rb +38 -0
- data/lib/simplecov/result_merger/resultset_store.rb +50 -0
- data/lib/simplecov/result_merger.rb +46 -90
- data/lib/simplecov/result_processing.rb +162 -0
- data/lib/simplecov/simulate_coverage.rb +54 -8
- data/lib/simplecov/source_file/branch.rb +1 -3
- data/lib/simplecov/source_file/branch_builder.rb +114 -0
- data/lib/simplecov/source_file/builder_context.rb +28 -0
- data/lib/simplecov/source_file/line.rb +7 -2
- data/lib/simplecov/source_file/line_builder.rb +43 -0
- data/lib/simplecov/source_file/method.rb +52 -0
- data/lib/simplecov/source_file/method_builder.rb +58 -0
- data/lib/simplecov/source_file/ruby_data_parser.rb +88 -0
- data/lib/simplecov/source_file/skip_chunks.rb +77 -0
- data/lib/simplecov/source_file/source_loader.rb +63 -0
- data/lib/simplecov/source_file/statistics.rb +57 -0
- data/lib/simplecov/source_file.rb +66 -226
- data/lib/simplecov/static_coverage_extractor/visitor.rb +193 -0
- data/lib/simplecov/static_coverage_extractor.rb +111 -0
- data/lib/simplecov/useless_results_remover.rb +16 -7
- data/lib/simplecov/version.rb +1 -1
- data/lib/simplecov-html.rb +4 -0
- data/lib/simplecov.rb +133 -377
- data/lib/simplecov_json_formatter.rb +4 -0
- data/schemas/coverage-v1.0.schema.json +300 -0
- data/schemas/coverage.schema.json +300 -0
- metadata +88 -56
- data/lib/simplecov/default_formatter.rb +0 -20
|
@@ -1,18 +1,27 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module SimpleCov
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
4
|
+
# Drop coverage entries whose paths live outside `SimpleCov.root` so the
|
|
5
|
+
# report only reflects the project's own source. Vendored gems, stdlib
|
|
6
|
+
# files, and anything else that happens to have been touched during the
|
|
7
|
+
# run never make it into the formatted result.
|
|
7
8
|
module UselessResultsRemover
|
|
8
9
|
def self.call(coverage_result)
|
|
9
|
-
coverage_result.select
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
coverage_result.select { |path, _coverage| path.match?(root_regex) }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# The `/i` flag covers case-insensitive matches on Windows / macOS-HFS+
|
|
14
|
+
# where the on-disk path's case can differ from `SimpleCov.root`'s.
|
|
15
|
+
def self.root_regex
|
|
16
|
+
root = SimpleCov.root
|
|
17
|
+
return @root_regex if root == @root_regex_root
|
|
18
|
+
|
|
19
|
+
@root_regex_root = root
|
|
20
|
+
@root_regex = /\A#{Regexp.escape(root.chomp(File::SEPARATOR) + File::SEPARATOR)}/i
|
|
12
21
|
end
|
|
13
22
|
|
|
14
23
|
def self.root_regx
|
|
15
|
-
|
|
24
|
+
root_regex
|
|
16
25
|
end
|
|
17
26
|
end
|
|
18
27
|
end
|
data/lib/simplecov/version.rb
CHANGED
data/lib/simplecov.rb
CHANGED
|
@@ -1,450 +1,200 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "English"
|
|
4
|
-
|
|
5
|
-
# Coverage may be inaccurate under JRUBY.
|
|
6
|
-
if defined?(JRUBY_VERSION) && defined?(JRuby) && !org.jruby.RubyInstanceConfig.FULL_TRACE_ENABLED
|
|
7
|
-
|
|
8
|
-
# @see https://github.com/jruby/jruby/issues/1196
|
|
9
|
-
# @see https://github.com/metricfu/metric_fu/pull/226
|
|
10
|
-
# @see https://github.com/simplecov-ruby/simplecov/issues/420
|
|
11
|
-
# @see https://github.com/simplecov-ruby/simplecov/issues/86
|
|
12
|
-
# @see https://jira.codehaus.org/browse/JRUBY-6106
|
|
13
|
-
|
|
14
|
-
warn 'Coverage may be inaccurate; set the "--debug" command line option,' \
|
|
15
|
-
' or do JRUBY_OPTS="--debug"' \
|
|
16
|
-
' or set the "debug.fullTrace=true" option in your .jrubyrc'
|
|
17
|
-
end
|
|
18
|
-
|
|
19
3
|
#
|
|
20
4
|
# Code coverage for ruby. Please check out README for a full introduction.
|
|
21
5
|
#
|
|
22
6
|
module SimpleCov
|
|
7
|
+
# Raised when a user's configuration is internally inconsistent — e.g.
|
|
8
|
+
# every coverage criterion has been disabled.
|
|
9
|
+
class ConfigurationError < StandardError; end
|
|
10
|
+
|
|
23
11
|
class << self
|
|
24
|
-
|
|
12
|
+
CRITERION_TO_RUBY_COVERAGE = {
|
|
13
|
+
branch: :branches,
|
|
14
|
+
line: :lines,
|
|
15
|
+
method: :methods,
|
|
16
|
+
oneshot_line: :oneshot_lines
|
|
17
|
+
}.freeze
|
|
25
18
|
|
|
26
|
-
|
|
27
|
-
#
|
|
19
|
+
attr_accessor :pid
|
|
20
|
+
# When this process started tracking coverage. Captured by SimpleCov.start
|
|
21
|
+
# so JSONFormatter can detect when an existing coverage.json was written
|
|
22
|
+
# by a sibling process running concurrently.
|
|
23
|
+
attr_accessor :process_start_time
|
|
24
|
+
# Should we take care of at_exit behavior or something else? Used by the
|
|
25
|
+
# minitest plugin. See lib/minitest/simplecov_plugin.rb.
|
|
28
26
|
attr_accessor :external_at_exit
|
|
29
|
-
alias external_at_exit? external_at_exit
|
|
30
|
-
|
|
31
|
-
#
|
|
32
|
-
# Sets up SimpleCov to run against your project.
|
|
33
|
-
# You can optionally specify a profile to use as well as configuration with a block:
|
|
34
|
-
# SimpleCov.start
|
|
35
|
-
# OR
|
|
36
|
-
# SimpleCov.start 'rails' # using rails profile
|
|
37
|
-
# OR
|
|
38
|
-
# SimpleCov.start do
|
|
39
|
-
# add_filter 'test'
|
|
40
|
-
# end
|
|
41
|
-
# OR
|
|
42
|
-
# SimpleCov.start 'rails' do
|
|
43
|
-
# add_filter 'test'
|
|
44
|
-
# end
|
|
45
|
-
#
|
|
46
|
-
# Please check out the RDoc for SimpleCov::Configuration to find about available config options
|
|
47
|
-
#
|
|
48
|
-
def start(profile = nil, &block)
|
|
49
|
-
require "coverage"
|
|
50
|
-
initial_setup(profile, &block)
|
|
51
|
-
require_relative "./simplecov/process" if SimpleCov.enabled_for_subprocesses? &&
|
|
52
|
-
::Process.respond_to?(:fork)
|
|
53
|
-
|
|
54
|
-
make_parallel_tests_available
|
|
55
|
-
|
|
56
|
-
@result = nil
|
|
57
|
-
self.pid = Process.pid
|
|
58
|
-
|
|
59
|
-
start_coverage_measurement
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
#
|
|
63
|
-
# Collate a series of SimpleCov result files into a single SimpleCov output.
|
|
64
|
-
#
|
|
65
|
-
# You can optionally specify configuration with a block:
|
|
66
|
-
# SimpleCov.collate Dir["simplecov-resultset-*/.resultset.json"]
|
|
67
|
-
# OR
|
|
68
|
-
# SimpleCov.collate Dir["simplecov-resultset-*/.resultset.json"], 'rails' # using rails profile
|
|
69
|
-
# OR
|
|
70
|
-
# SimpleCov.collate Dir["simplecov-resultset-*/.resultset.json"] do
|
|
71
|
-
# add_filter 'test'
|
|
72
|
-
# end
|
|
73
|
-
# OR
|
|
74
|
-
# SimpleCov.collate Dir["simplecov-resultset-*/.resultset.json"], 'rails' do
|
|
75
|
-
# add_filter 'test'
|
|
76
|
-
# end
|
|
77
|
-
#
|
|
78
|
-
# Please check out the RDoc for SimpleCov::Configuration to find about
|
|
79
|
-
# available config options, or checkout the README for more in-depth
|
|
80
|
-
# information about coverage collation
|
|
81
|
-
#
|
|
82
|
-
# By default `collate` ignores the merge_timeout so all results of all files specified will be
|
|
83
|
-
# merged together. If you want to honor the merge_timeout then provide the keyword argument
|
|
84
|
-
# `ignore_timeout: false`.
|
|
85
|
-
#
|
|
86
|
-
def collate(result_filenames, profile = nil, ignore_timeout: true, &block)
|
|
87
|
-
raise "There are no reports to be merged" if result_filenames.empty?
|
|
88
|
-
|
|
89
|
-
initial_setup(profile, &block)
|
|
90
|
-
|
|
91
|
-
# Use the ResultMerger to produce a single, merged result, ready to use.
|
|
92
|
-
@result = ResultMerger.merge_and_store(*result_filenames, ignore_timeout: ignore_timeout)
|
|
93
|
-
|
|
94
|
-
run_exit_tasks!
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
#
|
|
98
|
-
# Returns the result for the current coverage run, merging it across test suites
|
|
99
|
-
# from cache using SimpleCov::ResultMerger if use_merging is activated (default)
|
|
100
|
-
#
|
|
101
|
-
def result
|
|
102
|
-
return @result if result?
|
|
103
27
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
if use_merging
|
|
110
|
-
wait_for_other_processes
|
|
111
|
-
SimpleCov::ResultMerger.store_result(@result) if result?
|
|
112
|
-
@result = SimpleCov::ResultMerger.merged_result
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
@result
|
|
116
|
-
ensure
|
|
117
|
-
self.running = false
|
|
28
|
+
# `:oneshot_line` data is folded into the `:line` bucket of
|
|
29
|
+
# `coverage_statistics` by `ResultAdapter`, so use `:line` to look
|
|
30
|
+
# up stats for either criterion.
|
|
31
|
+
def coverage_statistics_key(criterion)
|
|
32
|
+
criterion == :oneshot_line ? :line : criterion
|
|
118
33
|
end
|
|
119
34
|
|
|
120
|
-
#
|
|
121
|
-
#
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
def result?
|
|
125
|
-
defined?(@result) && @result
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
#
|
|
129
|
-
# Applies the configured filters to the given array of SimpleCov::SourceFile items
|
|
130
|
-
#
|
|
131
|
-
def filtered(files)
|
|
132
|
-
result = files.clone
|
|
133
|
-
filters.each do |filter|
|
|
134
|
-
result = result.reject { |source_file| filter.matches?(source_file) }
|
|
135
|
-
end
|
|
136
|
-
SimpleCov::FileList.new result
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
#
|
|
140
|
-
# Applies the configured groups to the given array of SimpleCov::SourceFile items
|
|
141
|
-
#
|
|
142
|
-
def grouped(files)
|
|
143
|
-
grouped = {}
|
|
144
|
-
grouped_files = []
|
|
145
|
-
groups.each do |name, filter|
|
|
146
|
-
grouped[name] = SimpleCov::FileList.new(files.select { |source_file| filter.matches?(source_file) })
|
|
147
|
-
grouped_files += grouped[name]
|
|
148
|
-
end
|
|
149
|
-
if !groups.empty? && !(other_files = files.reject { |source_file| grouped_files.include?(source_file) }).empty?
|
|
150
|
-
grouped["Ungrouped"] = SimpleCov::FileList.new(other_files)
|
|
151
|
-
end
|
|
152
|
-
grouped
|
|
35
|
+
# Coerce to a proper boolean so rspec-mocks 4's predicate matcher
|
|
36
|
+
# (`expect(...).not_to be_external_at_exit`) accepts the result.
|
|
37
|
+
def external_at_exit?
|
|
38
|
+
!!@external_at_exit
|
|
153
39
|
end
|
|
154
40
|
|
|
155
41
|
#
|
|
156
|
-
#
|
|
42
|
+
# Sets up SimpleCov to run against your project. See README for
|
|
43
|
+
# the full DSL, or:
|
|
157
44
|
#
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
def load_adapter(name)
|
|
163
|
-
warn "#{Kernel.caller.first}: [DEPRECATION] #load_adapter is deprecated. Use #load_profile instead."
|
|
164
|
-
load_profile(name)
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
#
|
|
168
|
-
# Clear out the previously cached .result. Primarily useful in testing
|
|
45
|
+
# SimpleCov.start
|
|
46
|
+
# SimpleCov.start 'rails' # using a profile
|
|
47
|
+
# SimpleCov.start { add_filter 'test' } # with a config block
|
|
169
48
|
#
|
|
170
|
-
def
|
|
171
|
-
|
|
172
|
-
end
|
|
49
|
+
def start(profile = nil, &)
|
|
50
|
+
warn_about_start_in_dot_simplecov if @autoloading_dot_simplecov
|
|
173
51
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
# If SimpleCov is no longer running then don't run exit tasks
|
|
179
|
-
SimpleCov.run_exit_tasks! if SimpleCov.running
|
|
52
|
+
initial_setup(profile, &)
|
|
53
|
+
start_tracking
|
|
54
|
+
install_at_exit_hook
|
|
180
55
|
end
|
|
181
56
|
|
|
182
57
|
# @api private
|
|
183
58
|
#
|
|
184
|
-
#
|
|
185
|
-
#
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
59
|
+
# Mark the duration of a `.simplecov` auto-load so any `SimpleCov.start`
|
|
60
|
+
# call inside the file can warn about the impending migration to a
|
|
61
|
+
# config-only file. Tracking still begins for backward compatibility;
|
|
62
|
+
# the warning is the cue to move `SimpleCov.start` into a test helper.
|
|
63
|
+
# See #581.
|
|
64
|
+
def with_dot_simplecov_autoload
|
|
65
|
+
previous = @autoloading_dot_simplecov
|
|
66
|
+
@autoloading_dot_simplecov = true
|
|
67
|
+
yield
|
|
68
|
+
ensure
|
|
69
|
+
@autoloading_dot_simplecov = previous
|
|
193
70
|
end
|
|
194
71
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
#
|
|
198
|
-
# Returns the exit status from the exit exception
|
|
199
|
-
#
|
|
200
|
-
def exit_status_from_exception
|
|
201
|
-
# Capture the current exception if it exists
|
|
202
|
-
@exit_exception = $ERROR_INFO
|
|
203
|
-
return nil unless @exit_exception
|
|
72
|
+
def warn_about_start_in_dot_simplecov
|
|
73
|
+
return if @dot_simplecov_start_warned
|
|
204
74
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
# @api private
|
|
213
|
-
def previous_error?(error_exit_status)
|
|
214
|
-
# Normally it'd be enough to check for previous error but when running test_unit
|
|
215
|
-
# status is 0
|
|
216
|
-
error_exit_status && error_exit_status != SimpleCov::ExitCodes::SUCCESS
|
|
75
|
+
@dot_simplecov_start_warned = true
|
|
76
|
+
warn "[DEPRECATION] Calling `SimpleCov.start` from `.simplecov` is deprecated and will " \
|
|
77
|
+
"be removed in a future release. `.simplecov` should contain configuration only; " \
|
|
78
|
+
"move the `SimpleCov.start` call into your `spec_helper.rb` / `test_helper.rb`. " \
|
|
79
|
+
"Coverage tracking still begins for backward compatibility, but a future release " \
|
|
80
|
+
"will require the explicit `SimpleCov.start` from a test helper. " \
|
|
81
|
+
"See https://github.com/simplecov-ruby/simplecov/issues/581."
|
|
217
82
|
end
|
|
218
83
|
|
|
219
84
|
#
|
|
220
|
-
#
|
|
85
|
+
# Install the at_exit hook that formats results and runs exit-code
|
|
86
|
+
# checks. `SimpleCov.start` calls this automatically. Idempotent —
|
|
87
|
+
# safe to call multiple times. Callers that drive the formatting
|
|
88
|
+
# pipeline themselves (e.g., dogfood test setups) can skip it by
|
|
89
|
+
# using `start_tracking` directly instead of `start`.
|
|
221
90
|
#
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
warn("Stopped processing SimpleCov as a previous error not related to SimpleCov has been detected") if print_error_status
|
|
225
|
-
Kernel.exit(exit_status)
|
|
226
|
-
end
|
|
91
|
+
def install_at_exit_hook
|
|
92
|
+
return if @at_exit_hook_installed
|
|
227
93
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
94
|
+
@at_exit_hook_installed = true
|
|
95
|
+
defer_to_minitest_after_run if minitest_autorun_pending?
|
|
96
|
+
Kernel.at_exit do
|
|
97
|
+
next if SimpleCov.external_at_exit?
|
|
232
98
|
|
|
233
|
-
|
|
234
|
-
exit_status = process_result(result)
|
|
235
|
-
|
|
236
|
-
# Force exit with stored status (see github issue #5)
|
|
237
|
-
if exit_status.positive?
|
|
238
|
-
warn("SimpleCov failed with exit #{exit_status} due to a coverage related error") if print_error_status
|
|
239
|
-
Kernel.exit exit_status
|
|
99
|
+
SimpleCov.at_exit_behavior
|
|
240
100
|
end
|
|
241
101
|
end
|
|
242
102
|
|
|
243
|
-
# @api private
|
|
244
|
-
#
|
|
245
|
-
# Usage:
|
|
246
|
-
# exit_status = SimpleCov.process_result(SimpleCov.result, exit_status)
|
|
247
|
-
#
|
|
248
|
-
def process_result(result)
|
|
249
|
-
result_exit_status = result_exit_status(result)
|
|
250
|
-
write_last_run(result) if result_exit_status == SimpleCov::ExitCodes::SUCCESS
|
|
251
|
-
result_exit_status
|
|
252
|
-
end
|
|
253
|
-
|
|
254
|
-
# @api private
|
|
255
|
-
CoverageLimits = Struct.new(:minimum_coverage, :minimum_coverage_by_file, :maximum_coverage_drop, keyword_init: true)
|
|
256
|
-
def result_exit_status(result)
|
|
257
|
-
coverage_limits = CoverageLimits.new(
|
|
258
|
-
minimum_coverage: minimum_coverage, minimum_coverage_by_file: minimum_coverage_by_file,
|
|
259
|
-
maximum_coverage_drop: maximum_coverage_drop
|
|
260
|
-
)
|
|
261
|
-
|
|
262
|
-
ExitCodes::ExitCodeHandling.call(result, coverage_limits: coverage_limits)
|
|
263
|
-
end
|
|
264
|
-
|
|
265
103
|
#
|
|
266
|
-
#
|
|
104
|
+
# Begin coverage tracking without applying configuration. Pairs with
|
|
105
|
+
# `SimpleCov.configure { ... }` for callers that want to separate
|
|
106
|
+
# the two — for example a dogfood test that has already started
|
|
107
|
+
# `Coverage` itself before requiring simplecov, but still wants the
|
|
108
|
+
# process_start_time / pid / fork-hook bookkeeping.
|
|
267
109
|
#
|
|
268
|
-
def
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
110
|
+
def start_tracking
|
|
111
|
+
require "coverage"
|
|
112
|
+
warn_if_jruby_full_trace_disabled
|
|
113
|
+
validate_coverage_criteria!
|
|
114
|
+
# simplecov:disable — fork-hook is enabled via SimpleCov.enable_for_subprocesses, off by default
|
|
115
|
+
require_relative "simplecov/process" if SimpleCov.enabled_for_subprocesses? &&
|
|
116
|
+
::Process.respond_to?(:_fork)
|
|
117
|
+
# simplecov:enable
|
|
118
|
+
|
|
119
|
+
# Trigger adapter selection now so the (possibly lazy) parallel_tests
|
|
120
|
+
# gem load happens at start_tracking time rather than mid-suite.
|
|
121
|
+
# `current` is memoized; subsequent calls are cheap.
|
|
122
|
+
SimpleCov::ParallelAdapters.current
|
|
281
123
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
def write_last_run(result)
|
|
286
|
-
SimpleCov::LastRun.write(result:
|
|
287
|
-
result.coverage_statistics.transform_values do |stats|
|
|
288
|
-
round_coverage(stats.percent)
|
|
289
|
-
end)
|
|
290
|
-
end
|
|
124
|
+
@result = nil
|
|
125
|
+
self.pid = Process.pid
|
|
126
|
+
self.process_start_time = Time.now
|
|
291
127
|
|
|
292
|
-
|
|
293
|
-
# @api private
|
|
294
|
-
#
|
|
295
|
-
# Rounding down to be extra strict, see #679
|
|
296
|
-
def round_coverage(coverage)
|
|
297
|
-
coverage.floor(2)
|
|
128
|
+
start_coverage_measurement
|
|
298
129
|
end
|
|
299
130
|
|
|
300
131
|
private
|
|
301
132
|
|
|
302
|
-
def initial_setup(profile, &block)
|
|
303
|
-
load_profile(profile) if profile
|
|
304
|
-
configure(&block) if block_given?
|
|
305
|
-
self.running = true
|
|
306
|
-
end
|
|
307
|
-
|
|
308
|
-
#
|
|
309
|
-
# Trigger Coverage.start depends on given config coverage_criterion
|
|
310
133
|
#
|
|
311
|
-
#
|
|
312
|
-
#
|
|
134
|
+
# Trigger Coverage.start with the configured criteria. Every supported
|
|
135
|
+
# runtime (CRuby >= 3.1, JRuby >= 9.4, TruffleRuby >= 22) accepts the
|
|
136
|
+
# criteria-hash form, so no compatibility fallback is needed.
|
|
313
137
|
#
|
|
314
138
|
def start_coverage_measurement
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
# There is also a nice writeup of the different coverage criteria made in this
|
|
318
|
-
# comment https://github.com/simplecov-ruby/simplecov/pull/692#discussion_r281836176 :
|
|
319
|
-
# Ruby < 2.5:
|
|
320
|
-
# https://github.com/ruby/ruby/blob/v1_9_3_374/ext/coverage/coverage.c
|
|
321
|
-
# traditional mode (Array)
|
|
322
|
-
#
|
|
323
|
-
# Ruby 2.5:
|
|
324
|
-
# https://bugs.ruby-lang.org/issues/13901
|
|
325
|
-
# https://github.com/ruby/ruby/blob/v2_5_3/ext/coverage/coverage.c
|
|
326
|
-
# default: traditional/compatible mode (Array)
|
|
327
|
-
# :lines - like traditional mode but using Hash
|
|
328
|
-
# :branches
|
|
329
|
-
# :methods
|
|
330
|
-
# :all - same as lines + branches + methods
|
|
331
|
-
#
|
|
332
|
-
# Ruby >= 2.6:
|
|
333
|
-
# https://bugs.ruby-lang.org/issues/15022
|
|
334
|
-
# https://github.com/ruby/ruby/blob/v2_6_3/ext/coverage/coverage.c
|
|
335
|
-
# default: traditional/compatible mode (Array)
|
|
336
|
-
# :lines - like traditional mode but using Hash
|
|
337
|
-
# :branches
|
|
338
|
-
# :methods
|
|
339
|
-
# :oneshot_lines - can not be combined with lines
|
|
340
|
-
# :all - same as lines + branches + methods
|
|
341
|
-
#
|
|
342
|
-
if coverage_start_arguments_supported?
|
|
343
|
-
start_coverage_with_criteria
|
|
344
|
-
else
|
|
345
|
-
Coverage.start
|
|
139
|
+
start_arguments = coverage_criteria.to_h do |criterion|
|
|
140
|
+
[CRITERION_TO_RUBY_COVERAGE.fetch(criterion), true]
|
|
346
141
|
end
|
|
347
|
-
end
|
|
348
142
|
|
|
349
|
-
|
|
350
|
-
start_arguments = coverage_criteria.map do |criterion|
|
|
351
|
-
[lookup_corresponding_ruby_coverage_name(criterion), true]
|
|
352
|
-
end.to_h
|
|
143
|
+
start_arguments[:eval] = true if coverage_for_eval_enabled?
|
|
353
144
|
|
|
354
|
-
Coverage.start(start_arguments)
|
|
145
|
+
Coverage.start(start_arguments) unless Coverage.running?
|
|
355
146
|
end
|
|
356
147
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
# the line-by-line coverage to zero (if relevant) or nil (comments / whitespace etc).
|
|
368
|
-
#
|
|
369
|
-
def add_not_loaded_files(result)
|
|
370
|
-
if tracked_files
|
|
371
|
-
result = result.dup
|
|
372
|
-
Dir[tracked_files].each do |file|
|
|
373
|
-
absolute_path = File.expand_path(file)
|
|
374
|
-
result[absolute_path] ||= SimulateCoverage.call(absolute_path)
|
|
375
|
-
end
|
|
376
|
-
end
|
|
148
|
+
# `Rake::TestTask` runs `ruby -e 'require "minitest/autorun"; ...'`,
|
|
149
|
+
# which means Minitest's at_exit registers before SimpleCov's. Since
|
|
150
|
+
# at_exit fires LIFO, SimpleCov's hook would otherwise run *before*
|
|
151
|
+
# Minitest gets a chance to invoke the tests — and format an empty
|
|
152
|
+
# resultset. When we can see that Minitest is loaded and its autorun
|
|
153
|
+
# is armed, route the report through `Minitest.after_run` instead,
|
|
154
|
+
# which fires after the suite completes. See issues #1099 and #1112.
|
|
155
|
+
def minitest_autorun_pending?
|
|
156
|
+
return false unless defined?(Minitest) && Minitest.respond_to?(:after_run)
|
|
157
|
+
return false unless Minitest.class_variable_defined?(:@@installed_at_exit)
|
|
377
158
|
|
|
378
|
-
|
|
159
|
+
Minitest.class_variable_get(:@@installed_at_exit)
|
|
379
160
|
end
|
|
380
161
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
# @return [Hash]
|
|
385
|
-
#
|
|
386
|
-
def process_coverage_result
|
|
387
|
-
adapt_coverage_result
|
|
388
|
-
remove_useless_results
|
|
389
|
-
result_with_not_loaded_files
|
|
162
|
+
def defer_to_minitest_after_run
|
|
163
|
+
self.external_at_exit = true
|
|
164
|
+
Minitest.after_run { SimpleCov.at_exit_behavior }
|
|
390
165
|
end
|
|
391
166
|
|
|
392
|
-
#
|
|
393
|
-
#
|
|
394
|
-
#
|
|
395
|
-
# @
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
@result = SimpleCov::ResultAdapter.call(Coverage.result)
|
|
399
|
-
end
|
|
400
|
-
|
|
401
|
-
#
|
|
402
|
-
# Filter coverage result
|
|
403
|
-
# The result before filter also has result of coverage for files
|
|
404
|
-
# are not related to the project like loaded gems coverage.
|
|
405
|
-
#
|
|
406
|
-
# @return [Hash]
|
|
407
|
-
#
|
|
408
|
-
def remove_useless_results
|
|
409
|
-
@result = SimpleCov::UselessResultsRemover.call(@result)
|
|
410
|
-
end
|
|
411
|
-
|
|
412
|
-
#
|
|
413
|
-
# Initialize result with files that are not included by coverage
|
|
414
|
-
# and added inside the config block
|
|
415
|
-
#
|
|
416
|
-
# @return [Hash]
|
|
417
|
-
#
|
|
418
|
-
def result_with_not_loaded_files
|
|
419
|
-
@result = SimpleCov::Result.new(add_not_loaded_files(@result))
|
|
420
|
-
end
|
|
167
|
+
# JRuby coverage data is unreliable unless full-trace mode is enabled.
|
|
168
|
+
# @see https://github.com/jruby/jruby/issues/1196
|
|
169
|
+
# @see https://github.com/simplecov-ruby/simplecov/issues/420
|
|
170
|
+
# @see https://github.com/simplecov-ruby/simplecov/issues/86
|
|
171
|
+
def warn_if_jruby_full_trace_disabled
|
|
172
|
+
return unless defined?(JRUBY_VERSION) && defined?(JRuby) # simplecov:disable — JRuby-only branch
|
|
421
173
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
return if defined?(ParallelTests)
|
|
425
|
-
return unless probably_running_parallel_tests?
|
|
426
|
-
|
|
427
|
-
require "parallel_tests"
|
|
428
|
-
rescue LoadError
|
|
429
|
-
warn("SimpleCov guessed you were running inside parallel tests but couldn't load it. Please file a bug report with us!")
|
|
430
|
-
end
|
|
174
|
+
# simplecov:disable — JRuby-only branches; unreachable from CRuby
|
|
175
|
+
return if org.jruby.RubyInstanceConfig.FULL_TRACE_ENABLED
|
|
431
176
|
|
|
432
|
-
|
|
433
|
-
|
|
177
|
+
warn 'Coverage may be inaccurate; set the "--debug" command line option, ' \
|
|
178
|
+
'or do JRUBY_OPTS="--debug" ' \
|
|
179
|
+
'or set the "debug.fullTrace=true" option in your .jrubyrc'
|
|
180
|
+
# simplecov:enable
|
|
434
181
|
end
|
|
435
182
|
end
|
|
436
183
|
end
|
|
437
184
|
|
|
438
|
-
# requires are down here
|
|
185
|
+
# requires are down here for a load order reason I'm not sure what it is about
|
|
439
186
|
require "set"
|
|
440
187
|
require "forwardable"
|
|
188
|
+
require_relative "simplecov/color"
|
|
441
189
|
require_relative "simplecov/configuration"
|
|
442
190
|
SimpleCov.extend SimpleCov::Configuration
|
|
443
191
|
require_relative "simplecov/coverage_statistics"
|
|
192
|
+
require_relative "simplecov/coverage_violations"
|
|
444
193
|
require_relative "simplecov/exit_codes"
|
|
445
194
|
require_relative "simplecov/profiles"
|
|
446
195
|
require_relative "simplecov/source_file/line"
|
|
447
196
|
require_relative "simplecov/source_file/branch"
|
|
197
|
+
require_relative "simplecov/source_file/method"
|
|
448
198
|
require_relative "simplecov/source_file"
|
|
449
199
|
require_relative "simplecov/file_list"
|
|
450
200
|
require_relative "simplecov/result"
|
|
@@ -453,16 +203,22 @@ require_relative "simplecov/formatter"
|
|
|
453
203
|
require_relative "simplecov/last_run"
|
|
454
204
|
require_relative "simplecov/lines_classifier"
|
|
455
205
|
require_relative "simplecov/result_merger"
|
|
206
|
+
require_relative "simplecov/parallel_adapters"
|
|
456
207
|
require_relative "simplecov/command_guesser"
|
|
457
208
|
require_relative "simplecov/version"
|
|
458
209
|
require_relative "simplecov/result_adapter"
|
|
459
210
|
require_relative "simplecov/combine"
|
|
460
211
|
require_relative "simplecov/combine/branches_combiner"
|
|
212
|
+
require_relative "simplecov/combine/methods_combiner"
|
|
461
213
|
require_relative "simplecov/combine/files_combiner"
|
|
462
214
|
require_relative "simplecov/combine/lines_combiner"
|
|
463
215
|
require_relative "simplecov/combine/results_combiner"
|
|
464
216
|
require_relative "simplecov/useless_results_remover"
|
|
465
217
|
require_relative "simplecov/simulate_coverage"
|
|
218
|
+
require_relative "simplecov/result_processing"
|
|
219
|
+
require_relative "simplecov/exit_handling"
|
|
220
|
+
require_relative "simplecov/parallel_coordination"
|
|
466
221
|
|
|
467
222
|
# Load default config
|
|
223
|
+
# simplecov:disable — env-var only set by aruba feature tests
|
|
468
224
|
require_relative "simplecov/defaults" unless ENV["SIMPLECOV_NO_DEFAULTS"]
|