simplecov 0.22.0 → 1.0.0.rc2
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 +89 -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 +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 +74 -0
- data/lib/simplecov/configuration/thresholds.rb +174 -0
- data/lib/simplecov/configuration.rb +86 -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 +47 -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 +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 +26 -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 +54 -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 +148 -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 +89 -56
- data/lib/simplecov/default_formatter.rb +0 -20
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "set"
|
|
4
|
+
|
|
5
|
+
begin
|
|
6
|
+
require "prism"
|
|
7
|
+
rescue LoadError
|
|
8
|
+
# Prism isn't available on this Ruby (older than 3.3 without the gem).
|
|
9
|
+
# `StaticCoverageExtractor.available?` will return false and callers
|
|
10
|
+
# fall back to the previous "empty hashes" behavior.
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
module SimpleCov
|
|
14
|
+
# Static enumeration of the branches and methods Ruby's `Coverage` library
|
|
15
|
+
# WOULD have reported if a file had been loaded with `branches: true` /
|
|
16
|
+
# `methods: true`. Used by `SimulateCoverage` to backfill data for files
|
|
17
|
+
# added via `cover` / `track_files` that were never `require`'d during the
|
|
18
|
+
# run — so unloaded files contribute to the branch/method denominators
|
|
19
|
+
# symmetrically with their line coverage, instead of vanishing from the
|
|
20
|
+
# totals (see #1059).
|
|
21
|
+
#
|
|
22
|
+
# Implementation uses Prism (stdlib in Ruby 3.3+, gem on older Rubies).
|
|
23
|
+
# When Prism isn't available, `available?` returns false and SimulateCoverage
|
|
24
|
+
# falls back to the previous behavior — older Rubies keep working, just
|
|
25
|
+
# without the synthesized data.
|
|
26
|
+
#
|
|
27
|
+
# The emitted shape mirrors `Coverage.result[path]` for the same file:
|
|
28
|
+
# branches are nested as `{condition_tuple => {arm_tuple => 0, ...}}` and
|
|
29
|
+
# methods as `{["ClassName", :name, lines/cols] => 0}`. Position info
|
|
30
|
+
# comes from Prism's reported source locations; it doesn't always match
|
|
31
|
+
# `Coverage`'s byte-for-byte (the two parsers report slightly different
|
|
32
|
+
# column conventions for some constructs), but lines are reliable and
|
|
33
|
+
# downstream consumers that key off line numbers (the HTML formatter,
|
|
34
|
+
# SonarQube, etc.) see the data they expect.
|
|
35
|
+
module StaticCoverageExtractor
|
|
36
|
+
module_function
|
|
37
|
+
|
|
38
|
+
# simplecov:disable branch
|
|
39
|
+
# The Prism-unavailable arm of this ternary is unreachable when Prism
|
|
40
|
+
# itself IS loadable — i.e., on every engine that exercises the dogfood
|
|
41
|
+
# report. Asserted-on by callers; tested indirectly via the
|
|
42
|
+
# `available?`-returns-false fallback path in SimulateCoverage's spec.
|
|
43
|
+
def available?
|
|
44
|
+
defined?(::Prism) ? true : false
|
|
45
|
+
end
|
|
46
|
+
# simplecov:enable branch
|
|
47
|
+
|
|
48
|
+
# Parse `source` (a string of Ruby) and return a hash of the form
|
|
49
|
+
# `{"branches" => {...}, "methods" => {...}}` matching the shape that
|
|
50
|
+
# `Coverage.result[path]` produces. Returns nil on parse failure or
|
|
51
|
+
# when Prism isn't available; callers should treat that as "couldn't
|
|
52
|
+
# extract — fall back to empty hashes."
|
|
53
|
+
def call(source)
|
|
54
|
+
# simplecov:disable branch — `then` arm unreachable when Prism IS loadable
|
|
55
|
+
return nil unless available?
|
|
56
|
+
|
|
57
|
+
# simplecov:enable branch
|
|
58
|
+
|
|
59
|
+
result = ::Prism.parse(source)
|
|
60
|
+
return nil if result.failure?
|
|
61
|
+
|
|
62
|
+
visitor = Visitor.new
|
|
63
|
+
visitor.visit(result.value)
|
|
64
|
+
{"branches" => visitor.branches, "methods" => visitor.methods}
|
|
65
|
+
rescue StandardError
|
|
66
|
+
# simplecov:disable line
|
|
67
|
+
# Parser errors beyond the .failure? check, unsupported AST shapes,
|
|
68
|
+
# or anything else: fall back to empty hashes rather than crashing
|
|
69
|
+
# the whole report. Defensive; hard to trigger from a real source
|
|
70
|
+
# input that Prism accepts at parse time.
|
|
71
|
+
nil
|
|
72
|
+
# simplecov:enable line
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Summarize a source file's REAL branch and method positions, for the
|
|
76
|
+
# `:eval_generated` filter (SimpleCov.ignore_branches /
|
|
77
|
+
# SimpleCov.ignore_methods, #1046). Returns a hash:
|
|
78
|
+
#
|
|
79
|
+
# {
|
|
80
|
+
# branches: Set[start_line, ...], # e.g., [3, 12, 20]
|
|
81
|
+
# methods: Set[[name, start_line], ...] # e.g., [[:foo, 7], [:bar, 13]]
|
|
82
|
+
# }
|
|
83
|
+
#
|
|
84
|
+
# Branch matching is start_line-only because Coverage's condition type
|
|
85
|
+
# vocabulary (`:if`, `:unless`, `:case`, `:while`, `:until`) does not
|
|
86
|
+
# always match Prism's emitted type (the existing visitor reports
|
|
87
|
+
# `:if` for `unless` and ternary). Coincidental line-sharing between
|
|
88
|
+
# a real branch and an eval-generated one will keep both, which is
|
|
89
|
+
# an acceptable false-negative for an opt-in filter. Method matching
|
|
90
|
+
# uses (name, start_line) since a method name is unique at any line.
|
|
91
|
+
#
|
|
92
|
+
# Returns nil when Prism is unavailable or parsing fails, signaling
|
|
93
|
+
# callers to keep every Coverage entry (no false drops).
|
|
94
|
+
def real_source_positions(source)
|
|
95
|
+
extracted = call(source)
|
|
96
|
+
return nil unless extracted
|
|
97
|
+
|
|
98
|
+
{
|
|
99
|
+
branches: extracted["branches"].keys.to_set { |tuple| tuple[2] },
|
|
100
|
+
methods: extracted["methods"].keys.to_set { |tuple| [tuple[1], tuple[2]] }
|
|
101
|
+
}
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# simplecov:disable branch
|
|
107
|
+
# The `else` arm (Prism missing) is unreachable on engines where the
|
|
108
|
+
# dogfood report runs; the Visitor class only matters when Prism is
|
|
109
|
+
# loadable.
|
|
110
|
+
require_relative "static_coverage_extractor/visitor" if SimpleCov::StaticCoverageExtractor.available?
|
|
111
|
+
# simplecov:enable branch
|
|
@@ -1,18 +1,27 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module SimpleCov
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
4
|
+
# Drop coverage entries whose paths live outside `SimpleCov.root` so the
|
|
5
|
+
# report only reflects the project's own source. Vendored gems, stdlib
|
|
6
|
+
# files, and anything else that happens to have been touched during the
|
|
7
|
+
# run never make it into the formatted result.
|
|
7
8
|
module UselessResultsRemover
|
|
8
9
|
def self.call(coverage_result)
|
|
9
|
-
coverage_result.select
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
coverage_result.select { |path, _coverage| path.match?(root_regex) }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# The `/i` flag covers case-insensitive matches on Windows / macOS-HFS+
|
|
14
|
+
# where the on-disk path's case can differ from `SimpleCov.root`'s.
|
|
15
|
+
def self.root_regex
|
|
16
|
+
root = SimpleCov.root
|
|
17
|
+
return @root_regex if root == @root_regex_root
|
|
18
|
+
|
|
19
|
+
@root_regex_root = root
|
|
20
|
+
@root_regex = /\A#{Regexp.escape(root.chomp(File::SEPARATOR) + File::SEPARATOR)}/i
|
|
12
21
|
end
|
|
13
22
|
|
|
14
23
|
def self.root_regx
|
|
15
|
-
|
|
24
|
+
root_regex
|
|
16
25
|
end
|
|
17
26
|
end
|
|
18
27
|
end
|
data/lib/simplecov/version.rb
CHANGED