simplecov 0.22.0 → 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 +81 -1
- data/LICENSE +1 -1
- data/README.md +1009 -511
- 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 -405
- 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 -232
- 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 +131 -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
data/lib/simplecov.rb
CHANGED
|
@@ -1,452 +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
|
|
204
|
-
|
|
205
|
-
if @exit_exception.is_a?(SystemExit)
|
|
206
|
-
@exit_exception.status
|
|
207
|
-
else
|
|
208
|
-
SimpleCov::ExitCodes::EXCEPTION
|
|
209
|
-
end
|
|
210
|
-
end
|
|
72
|
+
def warn_about_start_in_dot_simplecov
|
|
73
|
+
return if @dot_simplecov_start_warned
|
|
211
74
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
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 unless Coverage.running?
|
|
139
|
+
start_arguments = coverage_criteria.to_h do |criterion|
|
|
140
|
+
[CRITERION_TO_RUBY_COVERAGE.fetch(criterion), true]
|
|
346
141
|
end
|
|
347
|
-
end
|
|
348
|
-
|
|
349
|
-
def start_coverage_with_criteria
|
|
350
|
-
start_arguments = coverage_criteria.map do |criterion|
|
|
351
|
-
[lookup_corresponding_ruby_coverage_name(criterion), true]
|
|
352
|
-
end.to_h
|
|
353
142
|
|
|
354
143
|
start_arguments[:eval] = true if coverage_for_eval_enabled?
|
|
355
144
|
|
|
356
145
|
Coverage.start(start_arguments) unless Coverage.running?
|
|
357
146
|
end
|
|
358
147
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
# the line-by-line coverage to zero (if relevant) or nil (comments / whitespace etc).
|
|
370
|
-
#
|
|
371
|
-
def add_not_loaded_files(result)
|
|
372
|
-
if tracked_files
|
|
373
|
-
result = result.dup
|
|
374
|
-
Dir[tracked_files].each do |file|
|
|
375
|
-
absolute_path = File.expand_path(file)
|
|
376
|
-
result[absolute_path] ||= SimulateCoverage.call(absolute_path)
|
|
377
|
-
end
|
|
378
|
-
end
|
|
379
|
-
|
|
380
|
-
result
|
|
381
|
-
end
|
|
382
|
-
|
|
383
|
-
#
|
|
384
|
-
# Call steps that handle process coverage result
|
|
385
|
-
#
|
|
386
|
-
# @return [Hash]
|
|
387
|
-
#
|
|
388
|
-
def process_coverage_result
|
|
389
|
-
adapt_coverage_result
|
|
390
|
-
remove_useless_results
|
|
391
|
-
result_with_not_loaded_files
|
|
392
|
-
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)
|
|
393
158
|
|
|
394
|
-
|
|
395
|
-
# Unite the result so it wouldn't matter what coverage type was called
|
|
396
|
-
#
|
|
397
|
-
# @return [Hash]
|
|
398
|
-
#
|
|
399
|
-
def adapt_coverage_result
|
|
400
|
-
@result = SimpleCov::ResultAdapter.call(Coverage.result)
|
|
159
|
+
Minitest.class_variable_get(:@@installed_at_exit)
|
|
401
160
|
end
|
|
402
161
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
# are not related to the project like loaded gems coverage.
|
|
407
|
-
#
|
|
408
|
-
# @return [Hash]
|
|
409
|
-
#
|
|
410
|
-
def remove_useless_results
|
|
411
|
-
@result = SimpleCov::UselessResultsRemover.call(@result)
|
|
412
|
-
end
|
|
413
|
-
|
|
414
|
-
#
|
|
415
|
-
# Initialize result with files that are not included by coverage
|
|
416
|
-
# and added inside the config block
|
|
417
|
-
#
|
|
418
|
-
# @return [Hash]
|
|
419
|
-
#
|
|
420
|
-
def result_with_not_loaded_files
|
|
421
|
-
@result = SimpleCov::Result.new(add_not_loaded_files(@result))
|
|
162
|
+
def defer_to_minitest_after_run
|
|
163
|
+
self.external_at_exit = true
|
|
164
|
+
Minitest.after_run { SimpleCov.at_exit_behavior }
|
|
422
165
|
end
|
|
423
166
|
|
|
424
|
-
#
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
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
|
|
428
173
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
warn("SimpleCov guessed you were running inside parallel tests but couldn't load it. Please file a bug report with us!")
|
|
432
|
-
end
|
|
174
|
+
# simplecov:disable — JRuby-only branches; unreachable from CRuby
|
|
175
|
+
return if org.jruby.RubyInstanceConfig.FULL_TRACE_ENABLED
|
|
433
176
|
|
|
434
|
-
|
|
435
|
-
|
|
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
|
|
436
181
|
end
|
|
437
182
|
end
|
|
438
183
|
end
|
|
439
184
|
|
|
440
|
-
# requires are down here
|
|
185
|
+
# requires are down here for a load order reason I'm not sure what it is about
|
|
441
186
|
require "set"
|
|
442
187
|
require "forwardable"
|
|
188
|
+
require_relative "simplecov/color"
|
|
443
189
|
require_relative "simplecov/configuration"
|
|
444
190
|
SimpleCov.extend SimpleCov::Configuration
|
|
445
191
|
require_relative "simplecov/coverage_statistics"
|
|
192
|
+
require_relative "simplecov/coverage_violations"
|
|
446
193
|
require_relative "simplecov/exit_codes"
|
|
447
194
|
require_relative "simplecov/profiles"
|
|
448
195
|
require_relative "simplecov/source_file/line"
|
|
449
196
|
require_relative "simplecov/source_file/branch"
|
|
197
|
+
require_relative "simplecov/source_file/method"
|
|
450
198
|
require_relative "simplecov/source_file"
|
|
451
199
|
require_relative "simplecov/file_list"
|
|
452
200
|
require_relative "simplecov/result"
|
|
@@ -455,16 +203,22 @@ require_relative "simplecov/formatter"
|
|
|
455
203
|
require_relative "simplecov/last_run"
|
|
456
204
|
require_relative "simplecov/lines_classifier"
|
|
457
205
|
require_relative "simplecov/result_merger"
|
|
206
|
+
require_relative "simplecov/parallel_adapters"
|
|
458
207
|
require_relative "simplecov/command_guesser"
|
|
459
208
|
require_relative "simplecov/version"
|
|
460
209
|
require_relative "simplecov/result_adapter"
|
|
461
210
|
require_relative "simplecov/combine"
|
|
462
211
|
require_relative "simplecov/combine/branches_combiner"
|
|
212
|
+
require_relative "simplecov/combine/methods_combiner"
|
|
463
213
|
require_relative "simplecov/combine/files_combiner"
|
|
464
214
|
require_relative "simplecov/combine/lines_combiner"
|
|
465
215
|
require_relative "simplecov/combine/results_combiner"
|
|
466
216
|
require_relative "simplecov/useless_results_remover"
|
|
467
217
|
require_relative "simplecov/simulate_coverage"
|
|
218
|
+
require_relative "simplecov/result_processing"
|
|
219
|
+
require_relative "simplecov/exit_handling"
|
|
220
|
+
require_relative "simplecov/parallel_coordination"
|
|
468
221
|
|
|
469
222
|
# Load default config
|
|
223
|
+
# simplecov:disable — env-var only set by aruba feature tests
|
|
470
224
|
require_relative "simplecov/defaults" unless ENV["SIMPLECOV_NO_DEFAULTS"]
|