simplecov 1.1.1 → 1.2.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/README.md +148 -5
- data/exe/simplecov +0 -3
- data/lib/minitest/simplecov_plugin.rb +12 -9
- data/lib/simplecov/atomic_file.rb +16 -19
- data/lib/simplecov/autostart.rb +5 -7
- data/lib/simplecov/baseline/parser.rb +58 -0
- data/lib/simplecov/baseline.rb +170 -0
- data/lib/simplecov/cli/affected/changed_files.rb +57 -0
- data/lib/simplecov/cli/affected/selection.rb +117 -0
- data/lib/simplecov/cli/affected.rb +148 -0
- data/lib/simplecov/cli/badge/svg.rb +70 -0
- data/lib/simplecov/cli/badge.rb +62 -0
- data/lib/simplecov/cli/clean.rb +23 -24
- data/lib/simplecov/cli/command_helpers.rb +55 -19
- data/lib/simplecov/cli/completions/scripts.rb +114 -0
- data/lib/simplecov/cli/completions.rb +83 -0
- data/lib/simplecov/cli/coverage.rb +25 -28
- data/lib/simplecov/cli/coverage_file.rb +58 -14
- data/lib/simplecov/cli/dead_code/output.rb +100 -0
- data/lib/simplecov/cli/dead_code.rb +139 -0
- data/lib/simplecov/cli/diff/output.rb +45 -0
- data/lib/simplecov/cli/diff.rb +35 -67
- data/lib/simplecov/cli/dotfile.rb +83 -38
- data/lib/simplecov/cli/git.rb +41 -0
- data/lib/simplecov/cli/history/output.rb +135 -0
- data/lib/simplecov/cli/history.rb +67 -0
- data/lib/simplecov/cli/merge.rb +34 -39
- data/lib/simplecov/cli/open.rb +12 -15
- data/lib/simplecov/cli/patch/changed_lines.rb +149 -0
- data/lib/simplecov/cli/patch/output.rb +135 -0
- data/lib/simplecov/cli/patch.rb +169 -0
- data/lib/simplecov/cli/ratchet/output.rb +44 -0
- data/lib/simplecov/cli/ratchet.rb +83 -0
- data/lib/simplecov/cli/report.rb +18 -24
- data/lib/simplecov/cli/run.rb +8 -9
- data/lib/simplecov/cli/serve/report_preparer.rb +7 -6
- data/lib/simplecov/cli/serve/static_file_handler.rb +62 -56
- data/lib/simplecov/cli/serve.rb +27 -24
- data/lib/simplecov/cli/show/annotator.rb +87 -0
- data/lib/simplecov/cli/show/sweep.rb +36 -0
- data/lib/simplecov/cli/show.rb +133 -0
- data/lib/simplecov/cli/status/facts.rb +87 -0
- data/lib/simplecov/cli/status.rb +93 -0
- data/lib/simplecov/cli/tests/redundancy.rb +78 -0
- data/lib/simplecov/cli/tests.rb +148 -0
- data/lib/simplecov/cli/uncovered/misses.rb +37 -0
- data/lib/simplecov/cli/uncovered.rb +70 -32
- data/lib/simplecov/cli/usage.rb +152 -0
- data/lib/simplecov/cli/watch/live_report.rb +73 -0
- data/lib/simplecov/cli/watch/narrator.rb +55 -0
- data/lib/simplecov/cli/watch/poller.rb +45 -0
- data/lib/simplecov/cli/watch/session.rb +134 -0
- data/lib/simplecov/cli/watch/test_plan.rb +43 -0
- data/lib/simplecov/cli/watch.rb +85 -0
- data/lib/simplecov/cli.rb +43 -92
- data/lib/simplecov/color.rb +19 -37
- data/lib/simplecov/combine/branches_combiner.rb +7 -31
- data/lib/simplecov/combine/coverage_accumulator.rb +49 -142
- data/lib/simplecov/combine/identity_interner.rb +10 -13
- data/lib/simplecov/combine/interned_counts.rb +7 -9
- data/lib/simplecov/combine/lines_combiner.rb +20 -44
- data/lib/simplecov/combine/methods_combiner.rb +9 -35
- data/lib/simplecov/combine/results_combiner.rb +4 -21
- data/lib/simplecov/combine.rb +0 -6
- data/lib/simplecov/command_guesser.rb +20 -34
- data/lib/simplecov/configuration/baseline.rb +31 -0
- data/lib/simplecov/configuration/coverage.rb +91 -79
- data/lib/simplecov/configuration/coverage_criteria.rb +43 -54
- data/lib/simplecov/configuration/deprecations.rb +21 -0
- data/lib/simplecov/configuration/eval_coverage.rb +6 -10
- data/lib/simplecov/configuration/filters.rb +40 -73
- data/lib/simplecov/configuration/formatting.rb +74 -83
- data/lib/simplecov/configuration/groups.rb +19 -13
- data/lib/simplecov/configuration/history.rb +44 -0
- data/lib/simplecov/configuration/ignored_entries.rb +31 -22
- data/lib/simplecov/configuration/merging.rb +94 -62
- data/lib/simplecov/configuration/missed_caps.rb +51 -0
- data/lib/simplecov/configuration/production.rb +23 -0
- data/lib/simplecov/configuration/test_tracking.rb +48 -0
- data/lib/simplecov/configuration/thresholds.rb +33 -62
- data/lib/simplecov/configuration/view_coverage.rb +38 -0
- data/lib/simplecov/configuration.rb +70 -76
- data/lib/simplecov/configuration_error.rb +5 -0
- data/lib/simplecov/context_map/union.rb +81 -0
- data/lib/simplecov/context_map.rb +187 -0
- data/lib/simplecov/coverage_json.rb +2 -5
- data/lib/simplecov/coverage_statistics.rb +14 -24
- data/lib/simplecov/coverage_violations.rb +157 -64
- data/lib/simplecov/current_run.rb +61 -0
- data/lib/simplecov/defaults.rb +4 -23
- data/lib/simplecov/deprecation.rb +45 -27
- data/lib/simplecov/directive.rb +46 -62
- data/lib/simplecov/exit_codes/baseline_check.rb +46 -0
- data/lib/simplecov/exit_codes/check.rb +17 -11
- data/lib/simplecov/exit_codes/exit_code_handling.rb +21 -8
- data/lib/simplecov/exit_codes/maximum_coverage_drop_check.rb +7 -10
- data/lib/simplecov/exit_codes/maximum_missed_check.rb +26 -0
- data/lib/simplecov/exit_codes/maximum_missed_per_file_check.rb +34 -0
- data/lib/simplecov/exit_codes/maximum_overall_coverage_check.rb +7 -12
- data/lib/simplecov/exit_codes/minimum_coverage_by_file_check.rb +11 -10
- data/lib/simplecov/exit_codes/minimum_coverage_by_group_check.rb +7 -9
- data/lib/simplecov/exit_codes/minimum_overall_coverage_check.rb +16 -17
- data/lib/simplecov/exit_codes.rb +16 -10
- data/lib/simplecov/exit_handling.rb +94 -59
- data/lib/simplecov/file_list.rb +20 -51
- data/lib/simplecov/filter.rb +43 -66
- data/lib/simplecov/formatter/base.rb +37 -55
- data/lib/simplecov/formatter/baseline_formatter.rb +98 -0
- data/lib/simplecov/formatter/coverage_json_writer.rb +29 -31
- data/lib/simplecov/formatter/html_formatter/public/index.html +15 -9
- data/lib/simplecov/formatter/html_formatter/viewer_data_validator.rb +74 -17
- data/lib/simplecov/formatter/html_formatter.rb +24 -41
- data/lib/simplecov/formatter/json_formatter/errors_formatter.rb +50 -16
- data/lib/simplecov/formatter/json_formatter/production_section_formatter.rb +48 -0
- data/lib/simplecov/formatter/json_formatter/result_hash_formatter.rb +43 -29
- data/lib/simplecov/formatter/json_formatter/source_file_formatter.rb +14 -10
- data/lib/simplecov/formatter/json_formatter.rb +7 -13
- data/lib/simplecov/formatter/multi_formatter.rb +5 -11
- data/lib/simplecov/formatter/simple_formatter.rb +2 -8
- data/lib/simplecov/formatter.rb +14 -10
- data/lib/simplecov/group_names.rb +13 -12
- data/lib/simplecov/history.rb +115 -0
- data/lib/simplecov/last_run.rb +6 -9
- data/lib/simplecov/lines_classifier.rb +31 -16
- data/lib/simplecov/load_global_config.rb +7 -7
- data/lib/simplecov/parallel_adapters/base.rb +13 -41
- data/lib/simplecov/parallel_adapters/generic.rb +7 -19
- data/lib/simplecov/parallel_adapters/parallel_tests.rb +21 -42
- data/lib/simplecov/parallel_adapters.rb +24 -55
- data/lib/simplecov/parallel_coordination.rb +39 -49
- data/lib/simplecov/parallel_result_merger/worker_payload.rb +33 -0
- data/lib/simplecov/parallel_result_merger.rb +67 -126
- data/lib/simplecov/process.rb +14 -32
- data/lib/simplecov/production/error.rb +11 -0
- data/lib/simplecov/production/file_sink.rb +130 -0
- data/lib/simplecov/production.rb +249 -0
- data/lib/simplecov/profiles/rails.rb +1 -12
- data/lib/simplecov/profiles/root_filter.rb +0 -4
- data/lib/simplecov/profiles/strict.rb +9 -19
- data/lib/simplecov/profiles.rb +11 -33
- data/lib/simplecov/report_deferral.rb +11 -15
- data/lib/simplecov/report_stamp.rb +6 -9
- data/lib/simplecov/result/filter_config.rb +19 -0
- data/lib/simplecov/result/missing_source_files_reporter.rb +8 -9
- data/lib/simplecov/result/serialization.rb +43 -0
- data/lib/simplecov/result/source_file_builder.rb +7 -12
- data/lib/simplecov/result.rb +68 -117
- data/lib/simplecov/result_adapter.rb +56 -68
- data/lib/simplecov/result_merger/contexts.rb +22 -0
- data/lib/simplecov/result_merger/legacy_format_adapter.rb +4 -8
- data/lib/simplecov/result_merger/resultset_file.rb +20 -27
- data/lib/simplecov/result_merger/resultset_run_identity.rb +23 -25
- data/lib/simplecov/result_merger/resultset_store.rb +23 -14
- data/lib/simplecov/result_merger/unloaded_files.rb +24 -32
- data/lib/simplecov/result_merger.rb +59 -58
- data/lib/simplecov/result_processing.rb +74 -119
- data/lib/simplecov/run_identity.rb +16 -18
- data/lib/simplecov/simulate_coverage.rb +34 -50
- data/lib/simplecov/source_file/branch.rb +8 -33
- data/lib/simplecov/source_file/branch_builder.rb +28 -47
- data/lib/simplecov/source_file/builder_context.rb +6 -13
- data/lib/simplecov/source_file/line.rb +13 -33
- data/lib/simplecov/source_file/line_builder.rb +9 -15
- data/lib/simplecov/source_file/method.rb +3 -7
- data/lib/simplecov/source_file/method_builder.rb +6 -15
- data/lib/simplecov/source_file/ruby_data_parser.rb +59 -66
- data/lib/simplecov/source_file/skip_chunks.rb +19 -28
- data/lib/simplecov/source_file/source_loader.rb +45 -35
- data/lib/simplecov/source_file/statistics.rb +10 -9
- data/lib/simplecov/source_file.rb +21 -51
- data/lib/simplecov/static_coverage_extractor/condition_folding.rb +63 -114
- data/lib/simplecov/static_coverage_extractor/location_conventions.rb +76 -121
- data/lib/simplecov/static_coverage_extractor/method_collector.rb +11 -24
- data/lib/simplecov/static_coverage_extractor/prism_compat.rb +15 -24
- data/lib/simplecov/static_coverage_extractor/value_position.rb +25 -38
- data/lib/simplecov/static_coverage_extractor/visitor.rb +47 -64
- data/lib/simplecov/static_coverage_extractor.rb +46 -62
- data/lib/simplecov/test_tracker/accessors.rb +34 -0
- data/lib/simplecov/test_tracker/constant_watch.rb +49 -0
- data/lib/simplecov/test_tracker/delta.rb +69 -0
- data/lib/simplecov/test_tracker/framework_hooks.rb +130 -0
- data/lib/simplecov/test_tracker.rb +162 -0
- data/lib/simplecov/unloaded_file_injector.rb +18 -31
- data/lib/simplecov/useless_results_remover.rb +7 -6
- data/lib/simplecov/version.rb +1 -1
- data/lib/simplecov/view_coverage/template_compiler.rb +83 -0
- data/lib/simplecov/view_coverage.rb +55 -0
- data/lib/simplecov-html.rb +1 -0
- data/lib/simplecov.rb +57 -113
- data/lib/simplecov_json_formatter.rb +1 -0
- data/man/simplecov.1 +349 -0
- data/sig/simplecov.rbs +523 -595
- metadata +72 -5
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module SimpleCov
|
|
4
|
-
# Inclusion and exclusion methods: `cover` and `skip`, plus the deprecated
|
|
5
|
-
# `track_files` and `add_filter` aliases.
|
|
6
4
|
module Configuration
|
|
7
5
|
attr_writer :filters
|
|
8
6
|
|
|
@@ -12,59 +10,38 @@ module SimpleCov
|
|
|
12
10
|
# when any `cover` matcher is configured the report drops every file that
|
|
13
11
|
# doesn't match at least one of them.
|
|
14
12
|
#
|
|
15
|
-
# Strings are interpreted as shell globs
|
|
16
|
-
#
|
|
17
|
-
# `add_filter` semantics and matches the way `track_files` already
|
|
18
|
-
# interprets its argument.
|
|
13
|
+
# Strings are interpreted as shell globs, not substring matches, a
|
|
14
|
+
# deliberate departure from the legacy `add_filter` semantics.
|
|
19
15
|
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
# files" half of the legacy `track_files` behavior, rolled into the
|
|
24
|
-
# same call.
|
|
25
|
-
#
|
|
26
|
-
# SimpleCov.start do
|
|
27
|
-
# cover "lib/**/*.rb", "app/**/*.rb"
|
|
28
|
-
# cover(/_helper\.rb\z/)
|
|
29
|
-
# cover { |sf| sf.lines.count > 5 }
|
|
30
|
-
# end
|
|
16
|
+
# A string glob is also expanded on disk, so files that exist but were
|
|
17
|
+
# never required during the run still appear in the report at 0%. This is
|
|
18
|
+
# the "include unloaded files" half of the legacy `track_files` behavior.
|
|
31
19
|
#
|
|
32
20
|
def cover(*args, &block)
|
|
33
21
|
args.each { |arg| cover_filters << build_cover_filter(arg) }
|
|
34
|
-
cover_filters <<
|
|
22
|
+
cover_filters << BlockFilter.new(block) if block
|
|
35
23
|
cover_filters
|
|
36
24
|
end
|
|
37
25
|
|
|
38
|
-
# Returns the list of configured inclusion filters added via `cover`.
|
|
39
26
|
def cover_filters
|
|
40
27
|
@cover_filters ||= []
|
|
41
28
|
end
|
|
42
29
|
|
|
43
|
-
#
|
|
44
|
-
#
|
|
45
|
-
#
|
|
46
|
-
# never required during the suite.
|
|
47
|
-
#
|
|
48
|
-
# Walks into `ArrayFilter` entries (built when a caller passes an
|
|
49
|
-
# array to `cover`) so a glob nested inside `cover(["lib/**/*.rb",
|
|
50
|
-
# /helper\.rb\z/])` still drives unloaded-file discovery.
|
|
30
|
+
# The string globs passed to `cover`, used by the disk-discovery pass in
|
|
31
|
+
# `SimpleCov.tracked_file_paths` so files matching a `cover` glob appear in
|
|
32
|
+
# the report even when they were never required during the suite.
|
|
51
33
|
def cover_globs
|
|
52
34
|
collect_cover_globs(cover_filters)
|
|
53
35
|
end
|
|
54
36
|
|
|
55
|
-
# DEPRECATED: prefer `cover`, which both includes unloaded files (the
|
|
56
|
-
# historical `track_files` behavior) and restricts the report to the
|
|
57
|
-
# matching set.
|
|
58
37
|
def track_files(glob)
|
|
59
|
-
|
|
60
|
-
|
|
38
|
+
Deprecation.warn("`SimpleCov.track_files` is deprecated. " \
|
|
39
|
+
"#{track_files_replacement_hint(glob)}")
|
|
61
40
|
@tracked_files = glob
|
|
62
41
|
end
|
|
63
42
|
|
|
64
|
-
# `track_files(nil)` is the documented way to clear a previously-set
|
|
65
|
-
#
|
|
66
|
-
# users at it. The `cover` API has no direct equivalent for "reset
|
|
67
|
-
# the inclusion list" — point users at the `@cover_filters` reset.
|
|
43
|
+
# `track_files(nil)` is the documented way to clear a previously-set glob,
|
|
44
|
+
# but `cover(nil)` raises `ConfigurationError`, so don't point users at it.
|
|
68
45
|
def track_files_replacement_hint(glob)
|
|
69
46
|
if glob.nil?
|
|
70
47
|
"Replace with `SimpleCov.cover_filters.clear` — clearing the inclusion list."
|
|
@@ -76,86 +53,76 @@ module SimpleCov
|
|
|
76
53
|
end
|
|
77
54
|
end
|
|
78
55
|
|
|
79
|
-
#
|
|
56
|
+
# Nil until `cover` names a glob: an unset ivar reads as nil, so the absence
|
|
57
|
+
# needs no guard of its own.
|
|
80
58
|
def tracked_files
|
|
81
|
-
@tracked_files
|
|
59
|
+
@tracked_files
|
|
82
60
|
end
|
|
83
61
|
|
|
84
|
-
# Returns the list of configured exclusion filters added via `skip`
|
|
85
|
-
# (or the deprecated `add_filter`).
|
|
86
62
|
def filters
|
|
87
63
|
@filters ||= []
|
|
88
64
|
end
|
|
89
65
|
|
|
90
66
|
#
|
|
91
67
|
# Drop matching files from the coverage report. The inverse of `cover`.
|
|
92
|
-
#
|
|
93
|
-
#
|
|
94
|
-
# substring), Regexp, block predicate, or Array of any of those.
|
|
68
|
+
# Accepts a String (path-segment substring), Regexp, block predicate, or
|
|
69
|
+
# Array of any of those.
|
|
95
70
|
#
|
|
96
71
|
def skip(filter_argument = nil, &)
|
|
97
72
|
filters << parse_filter(filter_argument, &)
|
|
98
73
|
end
|
|
99
74
|
|
|
100
|
-
# DEPRECATED: alias for `skip`. Same matcher grammar, identical behavior.
|
|
101
75
|
def add_filter(filter_argument = nil, &block)
|
|
102
76
|
example = block ? "`SimpleCov.skip { ... }`" : "`SimpleCov.skip #{filter_argument.inspect}`"
|
|
103
|
-
|
|
104
|
-
|
|
77
|
+
Deprecation.warn("`SimpleCov.add_filter` is deprecated. " \
|
|
78
|
+
"Replace with `SimpleCov.skip` (same arguments, same behavior). Example: #{example}.")
|
|
105
79
|
skip(filter_argument, &block)
|
|
106
80
|
end
|
|
107
81
|
|
|
108
|
-
#
|
|
109
|
-
#
|
|
110
|
-
def remove_filter(filter_argument)
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
82
|
+
# `reject!` answers nil when it rejected nothing, which is the whole of
|
|
83
|
+
# "was anything removed".
|
|
84
|
+
def remove_filter(filter_argument)
|
|
85
|
+
rejected = filters.reject! do |filter|
|
|
86
|
+
filter.respond_to?(:filter_argument) && filter.filter_argument.eql?(filter_argument)
|
|
87
|
+
end
|
|
88
|
+
!rejected.nil?
|
|
114
89
|
end
|
|
115
90
|
|
|
116
|
-
# Remove every filter from the chain, including the defaults installed
|
|
117
|
-
# by `SimpleCov.start`.
|
|
118
91
|
def clear_filters
|
|
119
92
|
@filters = []
|
|
120
93
|
end
|
|
121
94
|
|
|
122
|
-
#
|
|
123
|
-
# earlier in this block) so subsequent `skip` calls start from a
|
|
124
|
-
# clean slate. Order matters — call this before your own `skip`
|
|
125
|
-
# invocations.
|
|
95
|
+
# Order matters: call this before your own `skip` invocations.
|
|
126
96
|
def no_default_skips
|
|
127
97
|
clear_filters
|
|
128
98
|
end
|
|
129
99
|
|
|
130
|
-
|
|
100
|
+
private
|
|
131
101
|
|
|
132
|
-
# The actual filter processor. Not meant for direct use.
|
|
133
102
|
def parse_filter(filter_argument = nil, &filter_proc)
|
|
134
103
|
filter = filter_argument || filter_proc
|
|
135
104
|
|
|
136
105
|
raise ArgumentError, "Please specify either a filter or a block to filter with" unless filter
|
|
137
106
|
|
|
138
|
-
|
|
107
|
+
Filter.build_filter(filter)
|
|
139
108
|
end
|
|
140
109
|
|
|
141
|
-
#
|
|
142
|
-
#
|
|
143
|
-
# everything else dispatches exactly like `add_filter`.
|
|
110
|
+
# Strings are treated as globs, not substrings (that's `skip`'s
|
|
111
|
+
# semantics); everything else dispatches exactly like `add_filter`.
|
|
144
112
|
def build_cover_filter(arg)
|
|
145
|
-
|
|
146
|
-
rescue
|
|
147
|
-
raise
|
|
148
|
-
|
|
149
|
-
|
|
113
|
+
Filter.build_filter(arg, string_filter: GlobFilter)
|
|
114
|
+
rescue ConfigurationError
|
|
115
|
+
raise ConfigurationError, "Unsupported `cover` argument #{arg.inspect}; " \
|
|
116
|
+
"expected a String glob, Regexp, Proc, " \
|
|
117
|
+
"SimpleCov::Filter, or Array of those."
|
|
150
118
|
end
|
|
151
119
|
|
|
152
|
-
#
|
|
153
|
-
# descending into `ArrayFilter` wrappers built by `cover(["a", "b"])`.
|
|
120
|
+
# Descends into `ArrayFilter` wrappers built by `cover(["a", "b"])`.
|
|
154
121
|
def collect_cover_globs(filter_list)
|
|
155
122
|
filter_list.flat_map do |filter|
|
|
156
123
|
case filter
|
|
157
|
-
when
|
|
158
|
-
when
|
|
124
|
+
when GlobFilter then filter.filter_argument
|
|
125
|
+
when ArrayFilter then collect_cover_globs(filter.filter_argument)
|
|
159
126
|
else []
|
|
160
127
|
end
|
|
161
128
|
end
|
|
@@ -3,35 +3,33 @@
|
|
|
3
3
|
require_relative "../formatter/multi_formatter"
|
|
4
4
|
|
|
5
5
|
module SimpleCov
|
|
6
|
-
# Formatter selection (`formatter` / `formatters`), reporting toggles
|
|
7
|
-
# (`print_errors`), and the deprecated `# :nocov:` token hook.
|
|
8
6
|
module Configuration
|
|
9
7
|
attr_writer :formatter, :print_error_status
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
9
|
+
BUILT_IN_FORMATS = {
|
|
10
|
+
html: :HTMLFormatter, json: :JSONFormatter, simple: :SimpleFormatter, baseline: :BaselineFormatter
|
|
11
|
+
}.freeze
|
|
12
|
+
private_constant :BUILT_IN_FORMATS
|
|
13
|
+
|
|
14
|
+
LAZY_FORMAT_REQUIRES = {html: "../../simplecov-html"}.freeze
|
|
15
|
+
private_constant :LAZY_FORMAT_REQUIRES
|
|
16
|
+
|
|
17
|
+
def formats(*names)
|
|
18
|
+
return formatters if names.empty?
|
|
19
|
+
|
|
20
|
+
self.formatters = names.map { |name| resolve_format(name) }
|
|
21
|
+
formatters
|
|
22
|
+
end
|
|
23
|
+
|
|
24
24
|
def formatter(formatter = :__no_arg__)
|
|
25
25
|
case formatter
|
|
26
26
|
when :__no_arg__
|
|
27
27
|
@formatter
|
|
28
28
|
else
|
|
29
|
-
@formatter = formatter || nil
|
|
29
|
+
@formatter = formatter || nil
|
|
30
30
|
end
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
-
# Sets the configured formatters. Pass `[]` to opt out of
|
|
34
|
-
# formatting entirely; see `formatter` for the rationale.
|
|
35
33
|
def formatters(formatters = :__no_arg__)
|
|
36
34
|
case formatters
|
|
37
35
|
when :__no_arg__
|
|
@@ -39,100 +37,93 @@ module SimpleCov
|
|
|
39
37
|
configured ? [configured] : []
|
|
40
38
|
else
|
|
41
39
|
self.formatters = formatters
|
|
42
|
-
formatters
|
|
43
40
|
end
|
|
44
41
|
end
|
|
45
42
|
|
|
46
|
-
#
|
|
47
|
-
#
|
|
48
|
-
#
|
|
49
|
-
# formatter classes or ready-built instances; see `formatter`.
|
|
50
|
-
# `nil`, `false`, and `[]` all opt out of formatting entirely —
|
|
51
|
-
# `false` normalized like `formatter false` does, since `Array(false)`
|
|
52
|
-
# would otherwise smuggle it in as a "formatter" that can only fail.
|
|
43
|
+
# `nil`, `false`, and `[]` all opt out of formatting entirely. `false` is
|
|
44
|
+
# normalized first, since `Array(false)` would otherwise smuggle it in as a
|
|
45
|
+
# "formatter" that can only fail.
|
|
53
46
|
def formatters=(formatters)
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
#
|
|
59
|
-
# Get or set whether SimpleCov colorizes its stderr diagnostics. Accepts
|
|
60
|
-
# `true` (always on), `false` (always off), or `:auto` (default: defer
|
|
61
|
-
# to `SimpleCov::Color`, which checks `$stderr.tty?` with `NO_COLOR`
|
|
62
|
-
# and `FORCE_COLOR` overrides). An explicit `true`/`false` wins over
|
|
63
|
-
# both auto-detection and the env vars, which is the right escape
|
|
64
|
-
# hatch when stderr is being piped through a wrapper that still
|
|
65
|
-
# renders ANSI in its own terminal (parallel_tests with
|
|
66
|
-
# `--combine-stderr`, log multiplexers, some CI runners). See #1157.
|
|
67
|
-
#
|
|
47
|
+
@formatter = combined_formatter(Array(formatters || nil))
|
|
48
|
+
end
|
|
49
|
+
|
|
68
50
|
def color(value = :__no_arg__)
|
|
69
|
-
return
|
|
51
|
+
return instance_variable_defined?(:@color) ? @color : :auto if value.eql?(:__no_arg__)
|
|
52
|
+
|
|
53
|
+
self.color = _ = value
|
|
54
|
+
end
|
|
70
55
|
|
|
56
|
+
def color=(value)
|
|
71
57
|
@color = value
|
|
72
58
|
end
|
|
73
59
|
|
|
74
|
-
#
|
|
75
|
-
# Get or set whether SimpleCov prints its own diagnostic warnings to
|
|
76
|
-
# stderr. Covers per-check threshold violations, the trailing
|
|
77
|
-
# "SimpleCov failed with exit ..." summary, and the deferred-report /
|
|
78
|
-
# previous-error notices. Defaults to true. Set to false to silence
|
|
79
|
-
# SimpleCov entirely when parsing tooling output (see issue #1155).
|
|
80
|
-
#
|
|
81
60
|
def print_errors(value = :__no_arg__)
|
|
82
|
-
return
|
|
61
|
+
return instance_variable_defined?(:@print_error_status) ? @print_error_status : true if value.eql?(:__no_arg__)
|
|
83
62
|
|
|
63
|
+
self.print_errors = _ = value
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def print_errors=(value)
|
|
84
67
|
@print_error_status = value
|
|
85
68
|
end
|
|
86
69
|
|
|
87
|
-
#
|
|
88
|
-
# Get or set whether `coverage.json` includes the full source-text
|
|
89
|
-
# array for every file. Defaults to true. Set to false when a
|
|
90
|
-
# downstream tool reads the project's source files directly and
|
|
91
|
-
# only needs the coverage metrics, so `coverage.json` doesn't carry
|
|
92
|
-
# a copy of the source tree (which dominates the payload on larger
|
|
93
|
-
# projects).
|
|
94
|
-
#
|
|
95
|
-
# The HTML report's embedded data always includes source — the
|
|
96
|
-
# client-side renderer needs it. Only `coverage.json` honors
|
|
97
|
-
# this setting.
|
|
98
|
-
#
|
|
99
|
-
# SimpleCov.start do
|
|
100
|
-
# source_in_json false
|
|
101
|
-
# end
|
|
102
|
-
#
|
|
103
70
|
def source_in_json(value = :__no_arg__)
|
|
104
|
-
return
|
|
71
|
+
return instance_variable_defined?(:@source_in_json) ? @source_in_json : true if value.eql?(:__no_arg__)
|
|
72
|
+
|
|
73
|
+
self.source_in_json = _ = value
|
|
74
|
+
end
|
|
105
75
|
|
|
76
|
+
def source_in_json=(value)
|
|
106
77
|
@source_in_json = value
|
|
107
78
|
end
|
|
108
79
|
|
|
109
|
-
# DEPRECATED: alias for `print_errors`. Same value, same behavior.
|
|
110
80
|
def print_error_status
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
81
|
+
Deprecation.warn("`SimpleCov.print_error_status` is deprecated. " \
|
|
82
|
+
"Replace with `SimpleCov.print_errors` (same value).")
|
|
83
|
+
instance_variable_defined?(:@print_error_status) ? @print_error_status : true
|
|
114
84
|
end
|
|
115
85
|
|
|
116
|
-
#
|
|
117
|
-
# DEPRECATED: configure `# :nocov:` token override. Prefer
|
|
118
|
-
# `# simplecov:disable` / `# simplecov:enable` block comments (see
|
|
119
|
-
# SimpleCov::Directive). The `# :nocov:` toggle and this hook will
|
|
120
|
-
# be removed in a future release.
|
|
121
|
-
#
|
|
122
86
|
def nocov_token(nocov_token = nil)
|
|
123
|
-
|
|
124
|
-
|
|
87
|
+
Deprecation.warn("`SimpleCov.nocov_token` and `SimpleCov.skip_token` are deprecated. " \
|
|
88
|
+
"Replace with `# simplecov:disable` / `# simplecov:enable` block comments.")
|
|
125
89
|
current_nocov_token(nocov_token)
|
|
126
90
|
end
|
|
127
|
-
|
|
91
|
+
alias_method :skip_token, :nocov_token
|
|
128
92
|
|
|
129
|
-
# Internal accessor used by SimpleCov to recognise `# :nocov:`
|
|
130
|
-
# markers without emitting the public-API deprecation warning. Will
|
|
131
|
-
# be removed alongside the deprecated `nocov_token` setter.
|
|
132
93
|
def current_nocov_token(value = nil)
|
|
133
|
-
return @nocov_token if
|
|
94
|
+
return @nocov_token if instance_variable_defined?(:@nocov_token) && value.nil?
|
|
134
95
|
|
|
135
96
|
@nocov_token = value || "nocov"
|
|
136
97
|
end
|
|
98
|
+
|
|
99
|
+
private
|
|
100
|
+
|
|
101
|
+
# An empty list is how a project opts out of formatting.
|
|
102
|
+
def combined_formatter(formatters)
|
|
103
|
+
return if formatters.empty?
|
|
104
|
+
|
|
105
|
+
Formatter::MultiFormatter.new(formatters)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def resolve_format(name)
|
|
109
|
+
return name unless name.instance_of?(Symbol)
|
|
110
|
+
|
|
111
|
+
constant = BUILT_IN_FORMATS[name]
|
|
112
|
+
unless constant
|
|
113
|
+
raise ConfigurationError,
|
|
114
|
+
"Unknown format #{name.inspect}. Built-in formats are :html, :json, :simple, and :baseline; " \
|
|
115
|
+
"pass a formatter class or instance for anything else."
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
require_html_formatter(name)
|
|
119
|
+
Formatter.const_get(constant)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# `formats :html` has to work in a process that never required the HTML
|
|
123
|
+
# formatter, which under SIMPLECOV_NO_DEFAULTS nothing else has.
|
|
124
|
+
def require_html_formatter(name)
|
|
125
|
+
path = LAZY_FORMAT_REQUIRES[name]
|
|
126
|
+
require_relative(path) if path
|
|
127
|
+
end
|
|
137
128
|
end
|
|
138
129
|
end
|
|
@@ -1,38 +1,44 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module SimpleCov
|
|
4
|
-
# Group configuration is kept separate from inclusion and exclusion filters,
|
|
5
|
-
# while sharing their matcher parser through the main Configuration module.
|
|
6
4
|
module Configuration
|
|
7
|
-
# Returns the configured groups. Add groups using SimpleCov.group.
|
|
8
5
|
def groups
|
|
9
6
|
@groups ||= {}
|
|
10
7
|
end
|
|
11
8
|
|
|
9
|
+
# The group set `SimpleCov.grouped` bins against when its caller names none.
|
|
10
|
+
# It reads through a method of its own because the keyword it defaults
|
|
11
|
+
# shadows `groups`, so the default has to name a receiver, and every
|
|
12
|
+
# spelling of that receiver is the same call.
|
|
13
|
+
#
|
|
14
|
+
# mutant:disable — for that reason: `SimpleCov.groups`, `self.groups` and
|
|
15
|
+
# `groups()` cannot be told apart.
|
|
16
|
+
def default_groups
|
|
17
|
+
groups
|
|
18
|
+
end
|
|
19
|
+
|
|
12
20
|
def groups=(new_groups)
|
|
13
21
|
new_groups = new_groups.to_h { |name, filter| [GroupNames.normalize(name), filter] }
|
|
14
22
|
GroupNames.validate!(new_groups.keys)
|
|
15
23
|
@groups = new_groups
|
|
16
24
|
end
|
|
17
25
|
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
# into the implicit "Ungrouped" bucket.
|
|
26
|
+
# Same matcher grammar as `skip`, but instead of dropping the matching files
|
|
27
|
+
# it bins them under `group_name` for the formatter. Files matched by no
|
|
28
|
+
# group fall into the implicit "Ungrouped" bucket.
|
|
22
29
|
def group(group_name, filter_argument = nil, &)
|
|
23
30
|
group_name = GroupNames.normalize(group_name)
|
|
24
31
|
GroupNames.validate!([group_name])
|
|
25
32
|
groups[group_name] = parse_filter(filter_argument, &)
|
|
26
33
|
end
|
|
27
34
|
|
|
28
|
-
# DEPRECATED: alias for `group`. Same arguments, same behavior.
|
|
29
35
|
def add_group(group_name, filter_argument = nil, &block)
|
|
30
36
|
example = if block
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
37
|
+
"`SimpleCov.group #{group_name.inspect} { ... }`"
|
|
38
|
+
else
|
|
39
|
+
"`SimpleCov.group #{group_name.inspect}, #{filter_argument.inspect}`"
|
|
40
|
+
end
|
|
41
|
+
Deprecation.warn(
|
|
36
42
|
"`SimpleCov.add_group` is deprecated. " \
|
|
37
43
|
"Replace with `SimpleCov.group` (same arguments, same behavior). Example: #{example}."
|
|
38
44
|
)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SimpleCov
|
|
4
|
+
module Configuration
|
|
5
|
+
DROP_BASELINES = %i[last_run median branch].freeze
|
|
6
|
+
|
|
7
|
+
# How many runs coverage/.history.json keeps, newest kept. 0 disables
|
|
8
|
+
# recording entirely, and anything but a count of runs is refused.
|
|
9
|
+
def history_limit(limit = nil)
|
|
10
|
+
return @history_limit ||= 100 if limit.nil?
|
|
11
|
+
|
|
12
|
+
self.history_limit = limit
|
|
13
|
+
_ = @history_limit
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def history_limit=(limit)
|
|
17
|
+
unless limit.instance_of?(Integer) && limit >= 0
|
|
18
|
+
raise ConfigurationError, "history_limit takes a non-negative integer, got #{limit.inspect}"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
@history_limit = limit
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# What `maximum_coverage_drop` measures the drop against: `:last_run` (the
|
|
25
|
+
# default) the previous run whatever it was, `:median` the median of the
|
|
26
|
+
# recorded history so one run that dipped for an unrelated reason cannot
|
|
27
|
+
# quietly become the baseline, and `:branch` the newest recorded run on the
|
|
28
|
+
# current git branch so a feature branch is compared with itself.
|
|
29
|
+
#
|
|
30
|
+
# The latter two read coverage/.history.json and find nothing to compare
|
|
31
|
+
# against while it is empty, which counts as "no previous run" the way a
|
|
32
|
+
# missing .last_run.json does.
|
|
33
|
+
def drop_baseline(mode = nil)
|
|
34
|
+
return @drop_baseline ||= :last_run if mode.nil?
|
|
35
|
+
|
|
36
|
+
unless DROP_BASELINES.include?(mode)
|
|
37
|
+
raise ConfigurationError,
|
|
38
|
+
"drop_baseline takes one of #{DROP_BASELINES}, got #{mode.inspect}"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
@drop_baseline = mode
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
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
4
|
module Configuration
|
|
8
|
-
# Branch types accepted by `ignore_branches`.
|
|
9
5
|
IGNORABLE_BRANCH_TYPES = %i[implicit_else eval_generated].freeze
|
|
10
|
-
# Method types accepted by `ignore_methods`.
|
|
11
6
|
IGNORABLE_METHOD_TYPES = %i[eval_generated].freeze
|
|
12
7
|
|
|
13
|
-
#
|
|
14
|
-
#
|
|
8
|
+
# Deprecated in favour of `coverage(:branch) { ignore :implicit_else }`,
|
|
9
|
+
# which fixes the criterion by context the way the threshold verbs do. One
|
|
10
|
+
# difference rides out the deprecation period: the coverage block enables the
|
|
11
|
+
# criterion it names, while this legacy setter records without enabling.
|
|
15
12
|
def ignore_branches(*types)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
Deprecation.warn("`SimpleCov.ignore_branches` is deprecated. " \
|
|
14
|
+
"Replace with `coverage(:branch) { ignore #{types.map(&:inspect).join(", ")} }`.")
|
|
15
|
+
store_ignored_branches(types)
|
|
19
16
|
end
|
|
20
17
|
|
|
21
18
|
def ignored_branches
|
|
@@ -26,12 +23,10 @@ module SimpleCov
|
|
|
26
23
|
ignored_branches.include?(type)
|
|
27
24
|
end
|
|
28
25
|
|
|
29
|
-
# See `ignore_branches`. The only supported method-type token today
|
|
30
|
-
# is `:eval_generated`; see #1046 for the rationale.
|
|
31
26
|
def ignore_methods(*types)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
27
|
+
Deprecation.warn("`SimpleCov.ignore_methods` is deprecated. " \
|
|
28
|
+
"Replace with `coverage(:method) { ignore #{types.map(&:inspect).join(", ")} }`.")
|
|
29
|
+
store_ignored_methods(types)
|
|
35
30
|
end
|
|
36
31
|
|
|
37
32
|
def ignored_methods
|
|
@@ -42,22 +37,36 @@ module SimpleCov
|
|
|
42
37
|
ignored_methods.include?(type)
|
|
43
38
|
end
|
|
44
39
|
|
|
45
|
-
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
# Variadic semantics: multiple calls union, duplicates are no-ops, unknown
|
|
43
|
+
# tokens raise.
|
|
44
|
+
def store_ignored_branches(types)
|
|
45
|
+
types.each { |type| raise_if_branch_type_unsupported(type) }
|
|
46
|
+
ignored_branches.concat(types).uniq!
|
|
47
|
+
ignored_branches
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def store_ignored_methods(types)
|
|
51
|
+
types.each { |type| raise_if_method_type_unsupported(type) }
|
|
52
|
+
ignored_methods.concat(types).uniq!
|
|
53
|
+
ignored_methods
|
|
54
|
+
end
|
|
46
55
|
|
|
47
56
|
def raise_if_branch_type_unsupported(type)
|
|
48
57
|
return if IGNORABLE_BRANCH_TYPES.member?(type)
|
|
49
58
|
|
|
50
|
-
raise
|
|
51
|
-
|
|
52
|
-
|
|
59
|
+
raise ConfigurationError,
|
|
60
|
+
"Unsupported branch type #{type.inspect} for `ignore_branches`. " \
|
|
61
|
+
"Supported values are #{IGNORABLE_BRANCH_TYPES.inspect}"
|
|
53
62
|
end
|
|
54
63
|
|
|
55
64
|
def raise_if_method_type_unsupported(type)
|
|
56
65
|
return if IGNORABLE_METHOD_TYPES.member?(type)
|
|
57
66
|
|
|
58
|
-
raise
|
|
59
|
-
|
|
60
|
-
|
|
67
|
+
raise ConfigurationError,
|
|
68
|
+
"Unsupported method type #{type.inspect} for `ignore_methods`. " \
|
|
69
|
+
"Supported values are #{IGNORABLE_METHOD_TYPES.inspect}"
|
|
61
70
|
end
|
|
62
71
|
end
|
|
63
72
|
end
|