simplecov 0.22.0 → 1.0.0
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/LICENSE +1 -1
- data/README.md +1058 -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 +27 -5
- 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 +197 -0
- data/lib/simplecov/configuration/formatting.rb +119 -0
- data/lib/simplecov/configuration/ignored_entries.rb +63 -0
- data/lib/simplecov/configuration/merging.rb +164 -0
- data/lib/simplecov/configuration/thresholds.rb +174 -0
- data/lib/simplecov/configuration.rb +91 -407
- 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/deprecation.rb +45 -0
- 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 +128 -0
- data/lib/simplecov/formatter/json_formatter/source_file_formatter.rb +99 -0
- data/lib/simplecov/formatter/json_formatter.rb +87 -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 +25 -13
- data/lib/simplecov/load_global_config.rb +9 -4
- data/lib/simplecov/parallel_adapters/base.rb +61 -0
- data/lib/simplecov/parallel_adapters/generic.rb +44 -0
- data/lib/simplecov/parallel_adapters/parallel_tests.rb +93 -0
- data/lib/simplecov/parallel_adapters.rb +83 -0
- data/lib/simplecov/parallel_coordination.rb +129 -0
- data/lib/simplecov/process.rb +31 -13
- 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 +108 -19
- data/lib/simplecov/result_adapter.rb +70 -8
- 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 +59 -91
- data/lib/simplecov/result_processing.rb +179 -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 +75 -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/method_collector.rb +55 -0
- data/lib/simplecov/static_coverage_extractor/visitor.rb +171 -0
- data/lib/simplecov/static_coverage_extractor.rb +110 -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 +156 -371
- data/lib/simplecov_json_formatter.rb +4 -0
- data/schemas/coverage-v1.0.schema.json +306 -0
- data/schemas/coverage.schema.json +306 -0
- metadata +90 -57
- data/CHANGELOG.md +0 -191
- data/lib/simplecov/default_formatter.rb +0 -20
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SimpleCov
|
|
4
|
+
# Inclusion / exclusion / grouping methods: `cover`, `skip`, `group`,
|
|
5
|
+
# plus the deprecated `track_files` / `add_filter` / `add_group`
|
|
6
|
+
# aliases. Mutates the same `filters`, `groups`, and `cover_filters`
|
|
7
|
+
# collections the main Configuration module exposes.
|
|
8
|
+
module Configuration
|
|
9
|
+
attr_writer :filters, :groups
|
|
10
|
+
|
|
11
|
+
#
|
|
12
|
+
# Restrict the universe of files in the coverage report to those matching
|
|
13
|
+
# one or more globs, regexps, or block predicates. Multiple calls union;
|
|
14
|
+
# when any `cover` matcher is configured the report drops every file that
|
|
15
|
+
# doesn't match at least one of them.
|
|
16
|
+
#
|
|
17
|
+
# Strings are interpreted as shell globs (e.g. "lib/**/*.rb"), not
|
|
18
|
+
# substring matches — this is a deliberate departure from the legacy
|
|
19
|
+
# `add_filter` semantics and matches the way `track_files` already
|
|
20
|
+
# interprets its argument.
|
|
21
|
+
#
|
|
22
|
+
# When the matcher is a string-glob, `cover` also expands the glob on
|
|
23
|
+
# disk so files that exist but were never required during the run still
|
|
24
|
+
# appear in the report (at 0% coverage). This is the "include unloaded
|
|
25
|
+
# files" half of the legacy `track_files` behavior, rolled into the
|
|
26
|
+
# same call.
|
|
27
|
+
#
|
|
28
|
+
# SimpleCov.start do
|
|
29
|
+
# cover "lib/**/*.rb", "app/**/*.rb"
|
|
30
|
+
# cover(/_helper\.rb\z/)
|
|
31
|
+
# cover { |sf| sf.lines.count > 5 }
|
|
32
|
+
# end
|
|
33
|
+
#
|
|
34
|
+
def cover(*args, &block)
|
|
35
|
+
args.each { |arg| cover_filters << build_cover_filter(arg) }
|
|
36
|
+
cover_filters << SimpleCov::BlockFilter.new(block) if block
|
|
37
|
+
cover_filters
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Returns the list of configured inclusion filters added via `cover`.
|
|
41
|
+
def cover_filters
|
|
42
|
+
@cover_filters ||= []
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Returns the list of string globs passed to `cover` — used by the
|
|
46
|
+
# disk-discovery pass in `SimpleCov.add_not_loaded_files` so files
|
|
47
|
+
# matching a `cover` glob appear in the report even when they were
|
|
48
|
+
# never required during the suite.
|
|
49
|
+
#
|
|
50
|
+
# Walks into `ArrayFilter` entries (built when a caller passes an
|
|
51
|
+
# array to `cover`) so a glob nested inside `cover(["lib/**/*.rb",
|
|
52
|
+
# /helper\.rb\z/])` still drives unloaded-file discovery.
|
|
53
|
+
def cover_globs
|
|
54
|
+
collect_cover_globs(cover_filters)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# DEPRECATED: prefer `cover`, which both includes unloaded files (the
|
|
58
|
+
# historical `track_files` behavior) and restricts the report to the
|
|
59
|
+
# matching set.
|
|
60
|
+
def track_files(glob)
|
|
61
|
+
SimpleCov::Deprecation.warn("`SimpleCov.track_files` is deprecated. " \
|
|
62
|
+
"#{track_files_replacement_hint(glob)}")
|
|
63
|
+
@tracked_files = glob
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# `track_files(nil)` is the documented way to clear a previously-set
|
|
67
|
+
# glob, but `cover(nil)` raises `ConfigurationError`, so don't point
|
|
68
|
+
# users at it. The `cover` API has no direct equivalent for "reset
|
|
69
|
+
# the inclusion list" — point users at the `@cover_filters` reset.
|
|
70
|
+
def track_files_replacement_hint(glob)
|
|
71
|
+
if glob.nil?
|
|
72
|
+
"Replace with `SimpleCov.cover_filters.clear` — clearing the inclusion list."
|
|
73
|
+
else
|
|
74
|
+
"Replace with `SimpleCov.cover #{glob.inspect}` — `cover` includes unloaded files on disk " \
|
|
75
|
+
"(the historical `track_files` behavior) and also restricts the report to the matching set. " \
|
|
76
|
+
"If you want to keep additional files outside #{glob.inspect} in the report, pass every " \
|
|
77
|
+
"directory you care about, e.g. `cover #{glob.inspect}, \"app/**/*.rb\"`."
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Returns the glob used to include files that were not explicitly required.
|
|
82
|
+
def tracked_files
|
|
83
|
+
@tracked_files if defined?(@tracked_files)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Returns the list of configured exclusion filters added via `skip`
|
|
87
|
+
# (or the deprecated `add_filter`).
|
|
88
|
+
def filters
|
|
89
|
+
@filters ||= []
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
#
|
|
93
|
+
# Drop matching files from the coverage report. The inverse of `cover`.
|
|
94
|
+
#
|
|
95
|
+
# See README for the full grammar; `skip` accepts a String (path-segment
|
|
96
|
+
# substring), Regexp, block predicate, or Array of any of those.
|
|
97
|
+
#
|
|
98
|
+
def skip(filter_argument = nil, &)
|
|
99
|
+
filters << parse_filter(filter_argument, &)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# DEPRECATED: alias for `skip`. Same matcher grammar, identical behavior.
|
|
103
|
+
def add_filter(filter_argument = nil, &block)
|
|
104
|
+
example = block ? "`SimpleCov.skip { ... }`" : "`SimpleCov.skip #{filter_argument.inspect}`"
|
|
105
|
+
SimpleCov::Deprecation.warn("`SimpleCov.add_filter` is deprecated. " \
|
|
106
|
+
"Replace with `SimpleCov.skip` (same arguments, same behavior). Example: #{example}.")
|
|
107
|
+
skip(filter_argument, &block)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Remove any filters whose `filter_argument` equals the given value.
|
|
111
|
+
# Returns true when at least one filter was removed, false otherwise.
|
|
112
|
+
def remove_filter(filter_argument) # rubocop:disable Naming/PredicateMethod
|
|
113
|
+
before = filters.size
|
|
114
|
+
filters.reject! { |filter| filter.respond_to?(:filter_argument) && filter.filter_argument == filter_argument }
|
|
115
|
+
filters.size != before
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# Remove every filter from the chain, including the defaults installed
|
|
119
|
+
# by `SimpleCov.start`.
|
|
120
|
+
def clear_filters
|
|
121
|
+
@filters = []
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Returns the configured groups. Add groups using SimpleCov.group.
|
|
125
|
+
def groups
|
|
126
|
+
@groups ||= {}
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Define a display group for files. Same matcher grammar as `skip`,
|
|
130
|
+
# but instead of dropping the matching files it bins them under
|
|
131
|
+
# `group_name` for the formatter. Files matched by no group fall
|
|
132
|
+
# into the implicit "Ungrouped" bucket.
|
|
133
|
+
def group(group_name, filter_argument = nil, &)
|
|
134
|
+
groups[group_name] = parse_filter(filter_argument, &)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# DEPRECATED: alias for `group`. Same arguments, same behavior.
|
|
138
|
+
def add_group(group_name, filter_argument = nil, &block)
|
|
139
|
+
example = if block
|
|
140
|
+
"`SimpleCov.group #{group_name.inspect} { ... }`"
|
|
141
|
+
else
|
|
142
|
+
"`SimpleCov.group #{group_name.inspect}, #{filter_argument.inspect}`"
|
|
143
|
+
end
|
|
144
|
+
SimpleCov::Deprecation.warn(
|
|
145
|
+
"`SimpleCov.add_group` is deprecated. " \
|
|
146
|
+
"Replace with `SimpleCov.group` (same arguments, same behavior). Example: #{example}."
|
|
147
|
+
)
|
|
148
|
+
group(group_name, filter_argument, &block)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# Drop every filter previously installed (defaults plus anything
|
|
152
|
+
# earlier in this block) so subsequent `skip` calls start from a
|
|
153
|
+
# clean slate. Order matters — call this before your own `skip`
|
|
154
|
+
# invocations.
|
|
155
|
+
def no_default_skips
|
|
156
|
+
clear_filters
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
private
|
|
160
|
+
|
|
161
|
+
# The actual filter processor. Not meant for direct use.
|
|
162
|
+
def parse_filter(filter_argument = nil, &filter_proc)
|
|
163
|
+
filter = filter_argument || filter_proc
|
|
164
|
+
|
|
165
|
+
raise ArgumentError, "Please specify either a filter or a block to filter with" unless filter
|
|
166
|
+
|
|
167
|
+
SimpleCov::Filter.build_filter(filter)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# Build a filter for a `cover` argument. Strings are treated as
|
|
171
|
+
# globs (not substrings — that's `skip`/`add_filter`'s semantics).
|
|
172
|
+
def build_cover_filter(arg)
|
|
173
|
+
case arg
|
|
174
|
+
when String then SimpleCov::GlobFilter.new(arg)
|
|
175
|
+
when Regexp then SimpleCov::RegexFilter.new(arg)
|
|
176
|
+
when Proc then SimpleCov::BlockFilter.new(arg)
|
|
177
|
+
when SimpleCov::Filter then arg
|
|
178
|
+
when Array then SimpleCov::ArrayFilter.new(arg.map { |a| build_cover_filter(a) })
|
|
179
|
+
else raise SimpleCov::ConfigurationError, "Unsupported `cover` argument #{arg.inspect}; " \
|
|
180
|
+
"expected a String glob, Regexp, Proc, " \
|
|
181
|
+
"SimpleCov::Filter, or Array of those."
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# Walk a list of cover filters and return the string globs they hold,
|
|
186
|
+
# descending into `ArrayFilter` wrappers built by `cover(["a", "b"])`.
|
|
187
|
+
def collect_cover_globs(filter_list)
|
|
188
|
+
filter_list.flat_map do |filter|
|
|
189
|
+
case filter
|
|
190
|
+
when SimpleCov::GlobFilter then filter.filter_argument
|
|
191
|
+
when SimpleCov::ArrayFilter then collect_cover_globs(filter.filter_argument)
|
|
192
|
+
else []
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../formatter/multi_formatter"
|
|
4
|
+
|
|
5
|
+
module SimpleCov
|
|
6
|
+
# Formatter selection (`formatter` / `formatters`), reporting toggles
|
|
7
|
+
# (`print_errors`), and the deprecated `# :nocov:` token hook.
|
|
8
|
+
module Configuration
|
|
9
|
+
attr_writer :formatter, :print_error_status
|
|
10
|
+
|
|
11
|
+
#
|
|
12
|
+
# Gets or sets the configured formatter. Pass `false` (or `nil`) to
|
|
13
|
+
# opt out of formatting entirely — worker processes in big parallel
|
|
14
|
+
# CI setups (see #964) only need their `.resultset.json` on disk so
|
|
15
|
+
# a final `SimpleCov.collate` job can produce the report; running
|
|
16
|
+
# them without a formatter saves the per-job HTML/multi-formatter
|
|
17
|
+
# overhead.
|
|
18
|
+
#
|
|
19
|
+
def formatter(formatter = :__no_arg__)
|
|
20
|
+
return @formatter if formatter == :__no_arg__
|
|
21
|
+
|
|
22
|
+
@formatter = formatter || nil # normalize `false` to `nil`
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Sets the configured formatters. Pass `[]` to opt out of
|
|
26
|
+
# formatting entirely; see `formatter` for the rationale.
|
|
27
|
+
def formatters(formatters = :__no_arg__)
|
|
28
|
+
return Array(formatter) if formatters == :__no_arg__
|
|
29
|
+
|
|
30
|
+
self.formatters = formatters
|
|
31
|
+
formatters
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Sets the configured formatters. Equivalent to `formatters [...]`.
|
|
35
|
+
def formatters=(formatters)
|
|
36
|
+
@formatter = formatters.empty? ? nil : SimpleCov::Formatter::MultiFormatter.new(formatters)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
#
|
|
40
|
+
# Get or set whether SimpleCov colorizes its stderr diagnostics. Accepts
|
|
41
|
+
# `true` (always on), `false` (always off), or `:auto` (default: defer
|
|
42
|
+
# to `SimpleCov::Color`, which checks `$stderr.tty?` with `NO_COLOR`
|
|
43
|
+
# and `FORCE_COLOR` overrides). An explicit `true`/`false` wins over
|
|
44
|
+
# both auto-detection and the env vars, which is the right escape
|
|
45
|
+
# hatch when stderr is being piped through a wrapper that still
|
|
46
|
+
# renders ANSI in its own terminal (parallel_tests with
|
|
47
|
+
# `--combine-stderr`, log multiplexers, some CI runners). See #1157.
|
|
48
|
+
#
|
|
49
|
+
def color(value = :__no_arg__)
|
|
50
|
+
return defined?(@color) ? @color : :auto if value == :__no_arg__
|
|
51
|
+
|
|
52
|
+
@color = value
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
#
|
|
56
|
+
# Get or set whether SimpleCov prints its own diagnostic warnings to
|
|
57
|
+
# stderr. Covers per-check threshold violations, the trailing
|
|
58
|
+
# "SimpleCov failed with exit ..." summary, and the deferred-report /
|
|
59
|
+
# previous-error notices. Defaults to true. Set to false to silence
|
|
60
|
+
# SimpleCov entirely when parsing tooling output (see issue #1155).
|
|
61
|
+
#
|
|
62
|
+
def print_errors(value = :__no_arg__)
|
|
63
|
+
return defined?(@print_error_status) ? @print_error_status : true if value == :__no_arg__
|
|
64
|
+
|
|
65
|
+
@print_error_status = value
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
#
|
|
69
|
+
# Get or set whether `coverage.json` includes the full source-text
|
|
70
|
+
# array for every file. Defaults to true. Set to false when a
|
|
71
|
+
# downstream tool reads the project's source files directly and
|
|
72
|
+
# only needs the coverage metrics, so `coverage.json` doesn't carry
|
|
73
|
+
# a copy of the source tree (which dominates the payload on larger
|
|
74
|
+
# projects).
|
|
75
|
+
#
|
|
76
|
+
# The HTML viewer's `coverage_data.js` always includes source —
|
|
77
|
+
# the client-side renderer needs it. Only `coverage.json` honors
|
|
78
|
+
# this setting.
|
|
79
|
+
#
|
|
80
|
+
# SimpleCov.start do
|
|
81
|
+
# source_in_json false
|
|
82
|
+
# end
|
|
83
|
+
#
|
|
84
|
+
def source_in_json(value = :__no_arg__)
|
|
85
|
+
return defined?(@source_in_json) ? @source_in_json : true if value == :__no_arg__
|
|
86
|
+
|
|
87
|
+
@source_in_json = value
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# DEPRECATED: alias for `print_errors`. Same value, same behavior.
|
|
91
|
+
def print_error_status
|
|
92
|
+
SimpleCov::Deprecation.warn("`SimpleCov.print_error_status` is deprecated. " \
|
|
93
|
+
"Replace with `SimpleCov.print_errors` (same value).")
|
|
94
|
+
defined?(@print_error_status) ? @print_error_status : true
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
#
|
|
98
|
+
# DEPRECATED: configure `# :nocov:` token override. Prefer
|
|
99
|
+
# `# simplecov:disable` / `# simplecov:enable` block comments (see
|
|
100
|
+
# SimpleCov::Directive). The `# :nocov:` toggle and this hook will
|
|
101
|
+
# be removed in a future release.
|
|
102
|
+
#
|
|
103
|
+
def nocov_token(nocov_token = nil)
|
|
104
|
+
SimpleCov::Deprecation.warn("`SimpleCov.nocov_token` and `SimpleCov.skip_token` are deprecated. " \
|
|
105
|
+
"Replace with `# simplecov:disable` / `# simplecov:enable` block comments.")
|
|
106
|
+
current_nocov_token(nocov_token)
|
|
107
|
+
end
|
|
108
|
+
alias skip_token nocov_token
|
|
109
|
+
|
|
110
|
+
# Internal accessor used by SimpleCov to recognise `# :nocov:`
|
|
111
|
+
# markers without emitting the public-API deprecation warning. Will
|
|
112
|
+
# be removed alongside the deprecated `nocov_token` setter.
|
|
113
|
+
def current_nocov_token(value = nil)
|
|
114
|
+
return @nocov_token if defined?(@nocov_token) && value.nil?
|
|
115
|
+
|
|
116
|
+
@nocov_token = value || "nocov"
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SimpleCov
|
|
4
|
+
# Coverage-entry filters scoped to branch / method criteria. See
|
|
5
|
+
# `ignore_branches` and `ignore_methods`, and #1033 /
|
|
6
|
+
# #1046 for the synthetic-entry detection rationale.
|
|
7
|
+
module Configuration
|
|
8
|
+
# Branch types accepted by `ignore_branches`.
|
|
9
|
+
IGNORABLE_BRANCH_TYPES = %i[implicit_else eval_generated].freeze
|
|
10
|
+
# Method types accepted by `ignore_methods`.
|
|
11
|
+
IGNORABLE_METHOD_TYPES = %i[eval_generated].freeze
|
|
12
|
+
|
|
13
|
+
# Variadic; multiple calls union. Setting is recorded regardless
|
|
14
|
+
# of whether branch coverage is enabled at call time. See #1033, #1046.
|
|
15
|
+
def ignore_branches(*types)
|
|
16
|
+
types.each { |type| raise_if_branch_type_unsupported(type) }
|
|
17
|
+
ignored_branches.concat(types).uniq!
|
|
18
|
+
ignored_branches
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def ignored_branches
|
|
22
|
+
@ignored_branches ||= []
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def ignored_branch?(type)
|
|
26
|
+
ignored_branches.include?(type)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# See `ignore_branches`. The only supported method-type token today
|
|
30
|
+
# is `:eval_generated`; see #1046 for the rationale.
|
|
31
|
+
def ignore_methods(*types)
|
|
32
|
+
types.each { |type| raise_if_method_type_unsupported(type) }
|
|
33
|
+
ignored_methods.concat(types).uniq!
|
|
34
|
+
ignored_methods
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def ignored_methods
|
|
38
|
+
@ignored_methods ||= []
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def ignored_method?(type)
|
|
42
|
+
ignored_methods.include?(type)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def raise_if_branch_type_unsupported(type)
|
|
48
|
+
return if IGNORABLE_BRANCH_TYPES.member?(type)
|
|
49
|
+
|
|
50
|
+
raise SimpleCov::ConfigurationError,
|
|
51
|
+
"Unsupported branch type #{type.inspect} for `ignore_branches`. " \
|
|
52
|
+
"Supported values are #{IGNORABLE_BRANCH_TYPES.inspect}"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def raise_if_method_type_unsupported(type)
|
|
56
|
+
return if IGNORABLE_METHOD_TYPES.member?(type)
|
|
57
|
+
|
|
58
|
+
raise SimpleCov::ConfigurationError,
|
|
59
|
+
"Unsupported method type #{type.inspect} for `ignore_methods`. " \
|
|
60
|
+
"Supported values are #{IGNORABLE_METHOD_TYPES.inspect}"
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SimpleCov
|
|
4
|
+
# Result merging and subprocess / parallel-test coordination:
|
|
5
|
+
# `merging`, `merge_subprocesses`, `merge_timeout`, `parallel_tests`.
|
|
6
|
+
module Configuration
|
|
7
|
+
#
|
|
8
|
+
# Get or set whether SimpleCov should hook `Process._fork` to
|
|
9
|
+
# attach itself to subprocesses. Required when the suite uses
|
|
10
|
+
# parallel test workers (e.g. Rails' `parallelize(workers:)`).
|
|
11
|
+
# Defaults to false.
|
|
12
|
+
#
|
|
13
|
+
def merge_subprocesses(value = nil)
|
|
14
|
+
return @enable_for_subprocesses if defined?(@enable_for_subprocesses) && value.nil?
|
|
15
|
+
|
|
16
|
+
@enable_for_subprocesses = value || false
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @api private — predicate used by `start_tracking` to decide
|
|
20
|
+
# whether to install the fork hook.
|
|
21
|
+
def enabled_for_subprocesses?
|
|
22
|
+
defined?(@enable_for_subprocesses) ? @enable_for_subprocesses : false
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
#
|
|
26
|
+
# Get or set whether SimpleCov should auto-require the
|
|
27
|
+
# `parallel_tests` gem when it sees `TEST_ENV_NUMBER` /
|
|
28
|
+
# `PARALLEL_TEST_GROUPS` in the environment. Defaults to auto-detect
|
|
29
|
+
# (nil). See #1018.
|
|
30
|
+
#
|
|
31
|
+
def parallel_tests(value = :__no_arg__)
|
|
32
|
+
return defined?(@parallel_tests) ? @parallel_tests : nil if value == :__no_arg__
|
|
33
|
+
|
|
34
|
+
@parallel_tests = value
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# DEPRECATED: alias for `merge_subprocesses`. Same value/behavior.
|
|
38
|
+
def enable_for_subprocesses(value = nil)
|
|
39
|
+
SimpleCov::Deprecation.warn("`SimpleCov.enable_for_subprocesses` is deprecated. " \
|
|
40
|
+
"Replace with `SimpleCov.merge_subprocesses` (same value, same behavior).")
|
|
41
|
+
return @enable_for_subprocesses if defined?(@enable_for_subprocesses) && value.nil?
|
|
42
|
+
|
|
43
|
+
@enable_for_subprocesses = value || false
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
#
|
|
47
|
+
# Get or set whether to merge results from multiple test suites
|
|
48
|
+
# (test:units, test:functionals, cucumber, ...) into a single
|
|
49
|
+
# coverage report. Defaults to true.
|
|
50
|
+
#
|
|
51
|
+
def merging(use = nil)
|
|
52
|
+
@use_merging = use unless use.nil?
|
|
53
|
+
@use_merging = true unless defined?(@use_merging) && @use_merging == false
|
|
54
|
+
@use_merging
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
#
|
|
58
|
+
# Get or set whether this process owns final merge processing:
|
|
59
|
+
# waiting for sibling workers, building the merged result, formatting,
|
|
60
|
+
# enforcing thresholds, and writing `.last_run.json`.
|
|
61
|
+
#
|
|
62
|
+
# Defaults to true, except for recognized multi-worker parallel runs
|
|
63
|
+
# that explicitly write to a custom coverage destination while merging
|
|
64
|
+
# is enabled. Those runs are likely using an external `SimpleCov.collate`
|
|
65
|
+
# step to finalize the merge.
|
|
66
|
+
#
|
|
67
|
+
def finalize_merge(value = :__no_arg__)
|
|
68
|
+
unless value == :__no_arg__
|
|
69
|
+
@finalize_merge = value
|
|
70
|
+
@finalize_merge_explicit = true
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
return @finalize_merge if defined?(@finalize_merge_explicit) && @finalize_merge_explicit
|
|
74
|
+
|
|
75
|
+
inferred = inferred_finalize_merge?
|
|
76
|
+
warn_about_inferred_finalize_merge unless inferred
|
|
77
|
+
inferred
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def finalize_merge?
|
|
81
|
+
finalize_merge
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# @api private
|
|
85
|
+
def merge_finalization_owner?
|
|
86
|
+
collating_result? || finalize_merge?
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# DEPRECATED: alias for `merging`. Same value, same behavior.
|
|
90
|
+
def use_merging(use = nil)
|
|
91
|
+
SimpleCov::Deprecation.warn("`SimpleCov.use_merging` is deprecated. " \
|
|
92
|
+
"Replace with `SimpleCov.merging` (same value, same behavior).")
|
|
93
|
+
@use_merging = use unless use.nil?
|
|
94
|
+
@use_merging = true unless defined?(@use_merging) && @use_merging == false
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
#
|
|
98
|
+
# Defines the maximum age (in seconds) of a resultset to still be
|
|
99
|
+
# included in merged results. Default is 600 seconds (10 minutes).
|
|
100
|
+
#
|
|
101
|
+
def merge_timeout(seconds = nil)
|
|
102
|
+
@merge_timeout = seconds if seconds.is_a?(Integer)
|
|
103
|
+
@merge_timeout ||= 600
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
#
|
|
107
|
+
# Defines how long (in seconds) the reporting process waits for the
|
|
108
|
+
# remaining parallel-test workers to write their resultsets before it
|
|
109
|
+
# proceeds with a partial merge. Default is 60 seconds. Raise it when a
|
|
110
|
+
# slow worker routinely finishes well after the others, so its coverage
|
|
111
|
+
# is still included and the minimum / maximum coverage checks aren't
|
|
112
|
+
# skipped against a partial total.
|
|
113
|
+
#
|
|
114
|
+
def parallel_wait_timeout(seconds = nil)
|
|
115
|
+
@parallel_wait_timeout = seconds if seconds.is_a?(Integer)
|
|
116
|
+
@parallel_wait_timeout ||= 60
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
private
|
|
120
|
+
|
|
121
|
+
def inferred_finalize_merge?
|
|
122
|
+
return true unless merging
|
|
123
|
+
|
|
124
|
+
adapter = SimpleCov::ParallelAdapters.current
|
|
125
|
+
return true unless adapter
|
|
126
|
+
return true unless adapter.expected_worker_count > 1
|
|
127
|
+
return true unless parallel_worker_environment?
|
|
128
|
+
return true unless explicit_custom_coverage_destination?
|
|
129
|
+
|
|
130
|
+
false
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def parallel_worker_environment?
|
|
134
|
+
ENV.key?("TEST_ENV_NUMBER") || ENV.key?("PARALLEL_TEST_GROUPS")
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def explicit_custom_coverage_destination?
|
|
138
|
+
return false unless explicit_coverage_destination?
|
|
139
|
+
|
|
140
|
+
coverage_path != File.expand_path("coverage", root)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def explicit_coverage_destination?
|
|
144
|
+
(defined?(@coverage_path_explicit) && @coverage_path_explicit) ||
|
|
145
|
+
(defined?(@coverage_dir_explicit) && @coverage_dir_explicit)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def warn_about_inferred_finalize_merge
|
|
149
|
+
return if defined?(@finalize_merge_inference_warned) && @finalize_merge_inference_warned
|
|
150
|
+
return unless print_errors
|
|
151
|
+
|
|
152
|
+
@finalize_merge_inference_warned = true
|
|
153
|
+
warn SimpleCov::Color.colorize(inferred_finalize_merge_warning, :yellow)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def inferred_finalize_merge_warning
|
|
157
|
+
"SimpleCov inferred `finalize_merge false` because this parallel worker is merging " \
|
|
158
|
+
"into a custom coverage destination. Set `SimpleCov.finalize_merge false` to keep " \
|
|
159
|
+
"external collation ownership, or `SimpleCov.finalize_merge true` if this worker " \
|
|
160
|
+
"should wait, merge, format, enforce thresholds, and write `.last_run.json`. " \
|
|
161
|
+
"See https://github.com/simplecov-ruby/simplecov#merge-finalization-ownership."
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|