simplecov 0.22.0 → 1.3.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.
Files changed (210) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/README.md +173 -875
  4. data/exe/simplecov +8 -0
  5. data/lib/minitest/simplecov_plugin.rb +18 -7
  6. data/lib/simplecov/atomic_file.rb +67 -0
  7. data/lib/simplecov/autostart.rb +9 -0
  8. data/lib/simplecov/baseline/parser.rb +58 -0
  9. data/lib/simplecov/baseline.rb +170 -0
  10. data/lib/simplecov/cli/affected/changed_files.rb +57 -0
  11. data/lib/simplecov/cli/affected/selection.rb +117 -0
  12. data/lib/simplecov/cli/affected.rb +148 -0
  13. data/lib/simplecov/cli/annotations.rb +166 -0
  14. data/lib/simplecov/cli/badge/svg.rb +70 -0
  15. data/lib/simplecov/cli/badge.rb +62 -0
  16. data/lib/simplecov/cli/clean.rb +86 -0
  17. data/lib/simplecov/cli/command_helpers.rb +91 -0
  18. data/lib/simplecov/cli/completions/scripts.rb +114 -0
  19. data/lib/simplecov/cli/completions.rb +83 -0
  20. data/lib/simplecov/cli/coverage.rb +83 -0
  21. data/lib/simplecov/cli/coverage_file.rb +109 -0
  22. data/lib/simplecov/cli/dead_code/output.rb +100 -0
  23. data/lib/simplecov/cli/dead_code.rb +139 -0
  24. data/lib/simplecov/cli/diff/output.rb +45 -0
  25. data/lib/simplecov/cli/diff.rb +115 -0
  26. data/lib/simplecov/cli/dotfile.rb +156 -0
  27. data/lib/simplecov/cli/git.rb +41 -0
  28. data/lib/simplecov/cli/history/output.rb +135 -0
  29. data/lib/simplecov/cli/history.rb +67 -0
  30. data/lib/simplecov/cli/merge.rb +115 -0
  31. data/lib/simplecov/cli/open.rb +45 -0
  32. data/lib/simplecov/cli/patch/changed_lines.rb +149 -0
  33. data/lib/simplecov/cli/patch/output.rb +151 -0
  34. data/lib/simplecov/cli/patch.rb +175 -0
  35. data/lib/simplecov/cli/ratchet/output.rb +44 -0
  36. data/lib/simplecov/cli/ratchet.rb +83 -0
  37. data/lib/simplecov/cli/report.rb +91 -0
  38. data/lib/simplecov/cli/run.rb +35 -0
  39. data/lib/simplecov/cli/serve/report_preparer.rb +30 -0
  40. data/lib/simplecov/cli/serve/static_file_handler.rb +128 -0
  41. data/lib/simplecov/cli/serve.rb +88 -0
  42. data/lib/simplecov/cli/show/annotator.rb +87 -0
  43. data/lib/simplecov/cli/show/sweep.rb +36 -0
  44. data/lib/simplecov/cli/show.rb +133 -0
  45. data/lib/simplecov/cli/status/facts.rb +87 -0
  46. data/lib/simplecov/cli/status.rb +93 -0
  47. data/lib/simplecov/cli/tests/redundancy.rb +78 -0
  48. data/lib/simplecov/cli/tests.rb +148 -0
  49. data/lib/simplecov/cli/uncovered/misses.rb +33 -0
  50. data/lib/simplecov/cli/uncovered.rb +127 -0
  51. data/lib/simplecov/cli/usage.rb +153 -0
  52. data/lib/simplecov/cli/watch/live_report.rb +73 -0
  53. data/lib/simplecov/cli/watch/narrator.rb +55 -0
  54. data/lib/simplecov/cli/watch/poller.rb +45 -0
  55. data/lib/simplecov/cli/watch/session.rb +134 -0
  56. data/lib/simplecov/cli/watch/test_plan.rb +43 -0
  57. data/lib/simplecov/cli/watch.rb +85 -0
  58. data/lib/simplecov/cli.rb +114 -0
  59. data/lib/simplecov/color.rb +65 -0
  60. data/lib/simplecov/combine/branches_combiner.rb +44 -21
  61. data/lib/simplecov/combine/coverage_accumulator.rb +175 -0
  62. data/lib/simplecov/combine/identity_interner.rb +27 -0
  63. data/lib/simplecov/combine/interned_counts.rb +28 -0
  64. data/lib/simplecov/combine/lines_combiner.rb +35 -29
  65. data/lib/simplecov/combine/methods_combiner.rb +48 -0
  66. data/lib/simplecov/combine/results_combiner.rb +9 -49
  67. data/lib/simplecov/combine.rb +0 -24
  68. data/lib/simplecov/command_guesser.rb +99 -42
  69. data/lib/simplecov/configuration/baseline.rb +31 -0
  70. data/lib/simplecov/configuration/coverage.rb +184 -0
  71. data/lib/simplecov/configuration/coverage_criteria.rb +143 -0
  72. data/lib/simplecov/configuration/deprecations.rb +21 -0
  73. data/lib/simplecov/configuration/eval_coverage.rb +37 -0
  74. data/lib/simplecov/configuration/filters.rb +131 -0
  75. data/lib/simplecov/configuration/formatting.rb +129 -0
  76. data/lib/simplecov/configuration/groups.rb +48 -0
  77. data/lib/simplecov/configuration/history.rb +44 -0
  78. data/lib/simplecov/configuration/ignored_entries.rb +72 -0
  79. data/lib/simplecov/configuration/merging.rb +197 -0
  80. data/lib/simplecov/configuration/missed_caps.rb +51 -0
  81. data/lib/simplecov/configuration/production.rb +23 -0
  82. data/lib/simplecov/configuration/test_tracking.rb +48 -0
  83. data/lib/simplecov/configuration/thresholds.rb +150 -0
  84. data/lib/simplecov/configuration/view_coverage.rb +37 -0
  85. data/lib/simplecov/configuration.rb +100 -443
  86. data/lib/simplecov/configuration_error.rb +5 -0
  87. data/lib/simplecov/context_map/union.rb +81 -0
  88. data/lib/simplecov/context_map.rb +187 -0
  89. data/lib/simplecov/coverage_json.rb +21 -0
  90. data/lib/simplecov/coverage_statistics.rb +24 -28
  91. data/lib/simplecov/coverage_violations.rb +254 -0
  92. data/lib/simplecov/current_run.rb +61 -0
  93. data/lib/simplecov/defaults.rb +20 -28
  94. data/lib/simplecov/deprecation.rb +63 -0
  95. data/lib/simplecov/directive/erb.rb +44 -0
  96. data/lib/simplecov/directive/haml.rb +33 -0
  97. data/lib/simplecov/directive/indented_template.rb +37 -0
  98. data/lib/simplecov/directive/slim.rb +35 -0
  99. data/lib/simplecov/directive/template.rb +29 -0
  100. data/lib/simplecov/directive.rb +152 -0
  101. data/lib/simplecov/exit_codes/baseline_check.rb +46 -0
  102. data/lib/simplecov/exit_codes/check.rb +39 -0
  103. data/lib/simplecov/exit_codes/exit_code_handling.rb +24 -5
  104. data/lib/simplecov/exit_codes/maximum_coverage_drop_check.rb +17 -67
  105. data/lib/simplecov/exit_codes/maximum_missed_check.rb +26 -0
  106. data/lib/simplecov/exit_codes/maximum_missed_per_file_check.rb +34 -0
  107. data/lib/simplecov/exit_codes/maximum_overall_coverage_check.rb +27 -0
  108. data/lib/simplecov/exit_codes/minimum_coverage_by_file_check.rb +20 -38
  109. data/lib/simplecov/exit_codes/minimum_coverage_by_group_check.rb +28 -0
  110. data/lib/simplecov/exit_codes/minimum_overall_coverage_check.rb +37 -34
  111. data/lib/simplecov/exit_codes.rb +26 -0
  112. data/lib/simplecov/exit_handling.rb +163 -0
  113. data/lib/simplecov/file_list.rb +63 -48
  114. data/lib/simplecov/filter.rb +98 -42
  115. data/lib/simplecov/formatter/base.rb +100 -0
  116. data/lib/simplecov/formatter/baseline_formatter.rb +98 -0
  117. data/lib/simplecov/formatter/coverage_json_writer.rb +95 -0
  118. data/lib/simplecov/formatter/html_formatter/public/index.html +93 -0
  119. data/lib/simplecov/formatter/html_formatter/viewer_data_validator.rb +153 -0
  120. data/lib/simplecov/formatter/html_formatter.rb +88 -0
  121. data/lib/simplecov/formatter/json_formatter/errors_formatter.rb +122 -0
  122. data/lib/simplecov/formatter/json_formatter/production_section_formatter.rb +48 -0
  123. data/lib/simplecov/formatter/json_formatter/result_hash_formatter.rb +132 -0
  124. data/lib/simplecov/formatter/json_formatter/source_file_formatter.rb +97 -0
  125. data/lib/simplecov/formatter/json_formatter.rb +40 -0
  126. data/lib/simplecov/formatter/multi_formatter.rb +8 -10
  127. data/lib/simplecov/formatter/simple_formatter.rb +12 -15
  128. data/lib/simplecov/formatter.rb +21 -1
  129. data/lib/simplecov/group_names.rb +33 -0
  130. data/lib/simplecov/history.rb +115 -0
  131. data/lib/simplecov/last_run.rb +16 -5
  132. data/lib/simplecov/lines_classifier.rb +67 -19
  133. data/lib/simplecov/load_global_config.rb +12 -4
  134. data/lib/simplecov/parallel_adapters/base.rb +50 -0
  135. data/lib/simplecov/parallel_adapters/generic.rb +33 -0
  136. data/lib/simplecov/parallel_adapters/parallel_tests.rb +72 -0
  137. data/lib/simplecov/parallel_adapters.rb +54 -0
  138. data/lib/simplecov/parallel_coordination.rb +124 -0
  139. data/lib/simplecov/parallel_result_merger/worker_payload.rb +33 -0
  140. data/lib/simplecov/parallel_result_merger.rb +171 -0
  141. data/lib/simplecov/process.rb +34 -12
  142. data/lib/simplecov/production/error.rb +11 -0
  143. data/lib/simplecov/production/file_sink.rb +130 -0
  144. data/lib/simplecov/production.rb +249 -0
  145. data/lib/simplecov/profiles/bundler_filter.rb +1 -1
  146. data/lib/simplecov/profiles/hidden_filter.rb +1 -1
  147. data/lib/simplecov/profiles/rails.rb +13 -10
  148. data/lib/simplecov/profiles/root_filter.rb +2 -5
  149. data/lib/simplecov/profiles/strict.rb +22 -0
  150. data/lib/simplecov/profiles/test_frameworks.rb +1 -4
  151. data/lib/simplecov/profiles.rb +26 -19
  152. data/lib/simplecov/report_deferral.rb +45 -0
  153. data/lib/simplecov/report_stamp.rb +25 -0
  154. data/lib/simplecov/result/filter_config.rb +19 -0
  155. data/lib/simplecov/result/missing_source_files_reporter.rb +48 -0
  156. data/lib/simplecov/result/serialization.rb +43 -0
  157. data/lib/simplecov/result/source_file_builder.rb +46 -0
  158. data/lib/simplecov/result.rb +123 -47
  159. data/lib/simplecov/result_adapter.rb +130 -11
  160. data/lib/simplecov/result_merger/contexts.rb +22 -0
  161. data/lib/simplecov/result_merger/legacy_format_adapter.rb +24 -0
  162. data/lib/simplecov/result_merger/resultset_file.rb +67 -0
  163. data/lib/simplecov/result_merger/resultset_run_identity.rb +65 -0
  164. data/lib/simplecov/result_merger/resultset_store.rb +62 -0
  165. data/lib/simplecov/result_merger/unloaded_files.rb +95 -0
  166. data/lib/simplecov/result_merger.rb +120 -124
  167. data/lib/simplecov/result_processing.rb +188 -0
  168. data/lib/simplecov/run_identity.rb +75 -0
  169. data/lib/simplecov/simulate_coverage.rb +72 -17
  170. data/lib/simplecov/source_file/branch.rb +8 -35
  171. data/lib/simplecov/source_file/branch_builder.rb +95 -0
  172. data/lib/simplecov/source_file/builder_context.rb +28 -0
  173. data/lib/simplecov/source_file/line.rb +17 -32
  174. data/lib/simplecov/source_file/line_builder.rb +37 -0
  175. data/lib/simplecov/source_file/method.rb +54 -0
  176. data/lib/simplecov/source_file/method_builder.rb +51 -0
  177. data/lib/simplecov/source_file/ruby_data_parser.rb +103 -0
  178. data/lib/simplecov/source_file/skip_chunks.rb +72 -0
  179. data/lib/simplecov/source_file/source_loader.rb +89 -0
  180. data/lib/simplecov/source_file/statistics.rb +76 -0
  181. data/lib/simplecov/source_file.rb +64 -260
  182. data/lib/simplecov/static_coverage_extractor/condition_folding.rb +155 -0
  183. data/lib/simplecov/static_coverage_extractor/location_conventions.rb +191 -0
  184. data/lib/simplecov/static_coverage_extractor/method_collector.rb +45 -0
  185. data/lib/simplecov/static_coverage_extractor/prism_compat.rb +46 -0
  186. data/lib/simplecov/static_coverage_extractor/value_position.rb +61 -0
  187. data/lib/simplecov/static_coverage_extractor/visitor.rb +163 -0
  188. data/lib/simplecov/static_coverage_extractor.rb +78 -0
  189. data/lib/simplecov/test_tracker/accessors.rb +34 -0
  190. data/lib/simplecov/test_tracker/constant_watch.rb +49 -0
  191. data/lib/simplecov/test_tracker/delta.rb +69 -0
  192. data/lib/simplecov/test_tracker/framework_hooks.rb +130 -0
  193. data/lib/simplecov/test_tracker.rb +162 -0
  194. data/lib/simplecov/unloaded_file_injector.rb +62 -0
  195. data/lib/simplecov/useless_results_remover.rb +17 -7
  196. data/lib/simplecov/version.rb +1 -1
  197. data/lib/simplecov/view_coverage/template_compiler.rb +83 -0
  198. data/lib/simplecov/view_coverage.rb +55 -0
  199. data/lib/simplecov-html.rb +5 -0
  200. data/lib/simplecov.rb +143 -394
  201. data/lib/simplecov_json_formatter.rb +5 -0
  202. data/man/simplecov.1 +354 -0
  203. data/sig/simplecov.rbs +1710 -0
  204. metadata +183 -61
  205. data/CHANGELOG.md +0 -191
  206. data/doc/alternate-formatters.md +0 -71
  207. data/doc/commercial-services.md +0 -25
  208. data/doc/editor-integration.md +0 -18
  209. data/lib/simplecov/combine/files_combiner.rb +0 -24
  210. data/lib/simplecov/default_formatter.rb +0 -20
data/lib/simplecov.rb CHANGED
@@ -1,470 +1,219 @@
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
3
+ require "forwardable"
4
+ require_relative "simplecov/configuration_error"
5
+ require_relative "simplecov/current_run"
18
6
 
19
- #
20
- # Code coverage for ruby. Please check out README for a full introduction.
21
- #
22
7
  module SimpleCov
23
- class << self
24
- attr_accessor :running, :pid
25
-
26
- # Basically, should we take care of at_exit behavior or something else?
27
- # Used by the minitest plugin. See lib/minitest/simplecov_plugin.rb
28
- 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
8
+ # At module scope rather than inside `class << self` so it can be declared in
9
+ # the RBS signatures; lexical scoping keeps references inside the singleton
10
+ # class working.
11
+ CRITERION_TO_RUBY_COVERAGE = {
12
+ branch: :branches,
13
+ line: :lines,
14
+ method: :methods,
15
+ oneshot_line: :oneshot_lines
16
+ }.freeze
17
+
18
+ # `SingleForwardable` rather than `Forwardable` on the singleton class,
19
+ # because RBS has no way to speak about the singleton class's own ancestors.
20
+ extend SingleForwardable
21
+
22
+ def_delegators :current_run,
23
+ :pid, :pid=, :process_start_time, :process_start_time=,
24
+ :subprocess_serial, :next_subprocess_serial!,
25
+ :forked_subprocess?, :mark_forked_subprocess!,
26
+ :result?, :collating_result?
55
27
 
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
-
104
- # Collect our coverage result
105
- process_coverage_result if running
106
-
107
- # If we're using merging of results, store the current result
108
- # first (if there is one), then merge the results and return those
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
118
- end
119
-
120
- #
121
- # Returns nil if the result has not been computed
122
- # Otherwise, returns the result
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
153
- end
154
-
155
- #
156
- # Applies the profile of given name on SimpleCov configuration
157
- #
158
- def load_profile(name)
159
- profiles.load(name)
160
- end
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
169
- #
170
- def clear_result
171
- @result = nil
172
- end
173
-
174
- def at_exit_behavior
175
- # If we are in a different process than called start, don't interfere.
176
- return if SimpleCov.pid != Process.pid
177
-
178
- # If SimpleCov is no longer running then don't run exit tasks
179
- SimpleCov.run_exit_tasks! if SimpleCov.running
28
+ class << self
29
+ def current_run
30
+ @current_run ||= CurrentRun.new
180
31
  end
181
32
 
182
33
  # @api private
183
- #
184
- # Called from at_exit block
185
- #
186
- def run_exit_tasks!
187
- error_exit_status = exit_status_from_exception
34
+ attr_writer :current_run
188
35
 
189
- at_exit.call
36
+ attr_accessor :external_at_exit
190
37
 
191
- exit_and_report_previous_error(error_exit_status) if previous_error?(error_exit_status)
192
- process_results_and_report_error if ready_to_process_results?
38
+ # `:oneshot_line` data is folded into the `:line` bucket of
39
+ # `coverage_statistics` by `ResultAdapter`. The cast is steep's: it narrows
40
+ # a union on `==` but not on `equal?`.
41
+ def coverage_statistics_key(criterion)
42
+ criterion.equal?(:oneshot_line) ? :line : _ = criterion
193
43
  end
194
44
 
195
- #
196
- # @api private
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
45
+ # Coerced so rspec-mocks 4's predicate matcher accepts the result.
46
+ def external_at_exit?
47
+ !!@external_at_exit
210
48
  end
211
49
 
212
- # @api private
213
- def previous_error?(error_exit_status)
214
- # Normally it'd be enough to check for previous error but when running test_unit
215
- # status is 0
216
- error_exit_status && error_exit_status != SimpleCov::ExitCodes::SUCCESS
217
- end
50
+ def start(profile = nil, &)
51
+ warn_about_start_in_dot_simplecov if @autoloading_dot_simplecov
218
52
 
219
- #
220
- # @api private
221
- #
222
- # Thinking: Move this behavior earlier so if there was an error we do nothing?
223
- def exit_and_report_previous_error(exit_status)
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)
53
+ initial_setup(profile, &)
54
+ start_tracking
55
+ install_at_exit_hook
226
56
  end
227
57
 
228
58
  # @api private
229
- def ready_to_process_results?
230
- final_result_process? && result?
59
+ def with_dot_simplecov_autoload
60
+ previous = @autoloading_dot_simplecov # : bool?
61
+ @autoloading_dot_simplecov = true
62
+ yield
63
+ ensure
64
+ # @type var previous: bool?
65
+ @autoloading_dot_simplecov = previous
231
66
  end
232
67
 
233
- def process_results_and_report_error
234
- exit_status = process_result(result)
68
+ def warn_about_start_in_dot_simplecov
69
+ return if @dot_simplecov_start_warned
235
70
 
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
240
- end
71
+ @dot_simplecov_start_warned = true
72
+ warn "[DEPRECATION] Calling `SimpleCov.start` from `.simplecov` is deprecated and will " \
73
+ "be removed in a future release. `.simplecov` should contain configuration only; " \
74
+ "move the `SimpleCov.start` call into your `spec_helper.rb` / `test_helper.rb`. " \
75
+ "Coverage tracking still begins for backward compatibility, but a future release " \
76
+ "will require the explicit `SimpleCov.start` from a test helper. " \
77
+ "See https://github.com/simplecov-ruby/simplecov/issues/581."
241
78
  end
242
79
 
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
80
+ def install_at_exit_hook
81
+ return if @at_exit_hook_installed
253
82
 
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
83
+ @at_exit_hook_installed = true
84
+ # Never defer in a forked child: Minitest pins its after_run at_exit to
85
+ # the pid that armed autorun, so the deferral target can't fire there and
86
+ # the child's resultset would be silently dropped (#1227).
87
+ defer_to_minitest_after_run if minitest_autorun_pending? && !forked_subprocess?
88
+ Kernel.at_exit do
89
+ next if external_at_exit?
264
90
 
265
- #
266
- # @api private
267
- #
268
- def final_result_process?
269
- # checking for ENV["TEST_ENV_NUMBER"] to determine if the tests are being run in parallel
270
- !defined?(ParallelTests) || !ENV["TEST_ENV_NUMBER"] || ParallelTests.last_process?
91
+ at_exit_behavior
92
+ end
271
93
  end
272
94
 
273
- #
274
- # @api private
275
- #
276
- def wait_for_other_processes
277
- return unless defined?(ParallelTests) && final_result_process?
95
+ def start_tracking
96
+ require "coverage"
97
+ warn_if_jruby_full_trace_disabled
98
+ validate_coverage_criteria!
99
+ require_relative "simplecov/process" if enabled_for_subprocesses? && Process.respond_to?(:_fork)
278
100
 
279
- ParallelTests.wait_for_other_processes_to_finish
280
- end
101
+ # Must happen before any forks.
102
+ RunIdentity.prepare
281
103
 
282
- #
283
- # @api private
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
104
+ self.current_run = current_run.successor
105
+ self.pid = Process.pid
106
+ self.process_start_time = Time.now
291
107
 
292
- #
293
- # @api private
294
- #
295
- # Rounding down to be extra strict, see #679
296
- def round_coverage(coverage)
297
- coverage.floor(2)
108
+ start_coverage_measurement
298
109
  end
299
110
 
300
- private
301
-
302
- def initial_setup(profile, &block)
303
- load_profile(profile) if profile
304
- configure(&block) if block_given?
305
- self.running = true
306
- end
111
+ private
307
112
 
308
- #
309
- # Trigger Coverage.start depends on given config coverage_criterion
310
- #
311
- # With Positive branch it supports all coverage measurement types
312
- # With Negative branch it supports only line coverage measurement type
313
- #
314
113
  def start_coverage_measurement
315
- # This blog post gives a good run down of the coverage criterias introduced
316
- # in Ruby 2.5: https://blog.bigbinary.com/2018/04/11/ruby-2-5-supports-measuring-branch-and-method-coverages.html
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?
114
+ start_arguments = coverage_criteria.to_h do |criterion|
115
+ [CRITERION_TO_RUBY_COVERAGE.fetch(criterion), true]
346
116
  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
117
 
354
118
  start_arguments[:eval] = true if coverage_for_eval_enabled?
355
119
 
356
- Coverage.start(start_arguments) unless Coverage.running?
120
+ Coverage.start(**start_arguments) unless Coverage.running?
121
+ start_test_tracking
357
122
  end
358
123
 
359
- CRITERION_TO_RUBY_COVERAGE = {
360
- branch: :branches,
361
- line: :lines
362
- }.freeze
363
- def lookup_corresponding_ruby_coverage_name(criterion)
364
- CRITERION_TO_RUBY_COVERAGE.fetch(criterion)
365
- end
366
-
367
- #
368
- # Finds files that were to be tracked but were not loaded and initializes
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
124
+ # `Rake::TestTask` runs `ruby -e 'require "minitest/autorun"; ...'`, so
125
+ # Minitest's at_exit registers before SimpleCov's and, at_exit being LIFO,
126
+ # SimpleCov's would format an empty resultset before the tests ever run.
127
+ # Routing through `Minitest.after_run` instead fires after the suite
128
+ # completes (#1099, #1112).
129
+ def minitest_autorun_pending?
130
+ return false unless defined?(Minitest) && Minitest.respond_to?(:after_run)
131
+ return false unless Minitest.class_variable_defined?(:@@installed_at_exit)
379
132
 
380
- result
133
+ Minitest.class_variable_get(:@@installed_at_exit)
381
134
  end
382
135
 
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
136
+ def defer_to_minitest_after_run
137
+ self.external_at_exit = true
138
+ Minitest.after_run { at_exit_behavior }
392
139
  end
393
140
 
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)
401
- end
402
-
403
- #
404
- # Filter coverage result
405
- # The result before filter also has result of coverage for files
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))
422
- end
141
+ # JRuby coverage data is unreliable unless full-trace mode is enabled.
142
+ # @see https://github.com/jruby/jruby/issues/1196
143
+ # @see https://github.com/simplecov-ruby/simplecov/issues/420
144
+ # @see https://github.com/simplecov-ruby/simplecov/issues/86
145
+ # mutant:disable — every line below the guard is JRuby-only, and no
146
+ # example running on the engine this suite runs on can reach one.
147
+ def warn_if_jruby_full_trace_disabled
148
+ return unless defined?(JRUBY_VERSION) && defined?(JRuby) # simplecov:disable — JRuby-only branch
423
149
 
424
- # parallel_tests isn't always available, see: https://github.com/grosser/parallel_tests/issues/772
425
- def make_parallel_tests_available
426
- return if defined?(ParallelTests)
427
- return unless probably_running_parallel_tests?
150
+ # simplecov:disable — JRuby-only branches; unreachable from CRuby
151
+ # `org` is JRuby's Java-package entry point, absent on CRuby, so no RBS
152
+ # declaration can be truthful here.
153
+ return if org.jruby.RubyInstanceConfig.FULL_TRACE_ENABLED # steep:ignore NoMethod
428
154
 
429
- require "parallel_tests"
430
- rescue LoadError
431
- warn("SimpleCov guessed you were running inside parallel tests but couldn't load it. Please file a bug report with us!")
432
- end
433
-
434
- def probably_running_parallel_tests?
435
- ENV["TEST_ENV_NUMBER"] && ENV["PARALLEL_TEST_GROUPS"]
155
+ warn 'Coverage may be inaccurate; set the "--debug" command line option, ' \
156
+ 'or do JRUBY_OPTS="--debug" ' \
157
+ 'or set the "debug.fullTrace=true" option in your .jrubyrc'
158
+ # simplecov:enable
436
159
  end
437
160
  end
438
161
  end
439
162
 
440
- # requires are down here here for a load order reason I'm not sure what it is about
441
- require "set"
442
- require "forwardable"
163
+ require_relative "simplecov/color"
164
+ require_relative "simplecov/deprecation"
165
+ require_relative "simplecov/group_names"
443
166
  require_relative "simplecov/configuration"
444
167
  SimpleCov.extend SimpleCov::Configuration
445
168
  require_relative "simplecov/coverage_statistics"
169
+ require_relative "simplecov/coverage_violations"
446
170
  require_relative "simplecov/exit_codes"
447
171
  require_relative "simplecov/profiles"
448
172
  require_relative "simplecov/source_file/line"
449
173
  require_relative "simplecov/source_file/branch"
174
+ require_relative "simplecov/source_file/method"
450
175
  require_relative "simplecov/source_file"
451
176
  require_relative "simplecov/file_list"
452
177
  require_relative "simplecov/result"
453
178
  require_relative "simplecov/filter"
454
179
  require_relative "simplecov/formatter"
455
180
  require_relative "simplecov/last_run"
181
+ require_relative "simplecov/history"
182
+ require_relative "simplecov/report_stamp"
183
+ require_relative "simplecov/baseline"
456
184
  require_relative "simplecov/lines_classifier"
185
+ require_relative "simplecov/context_map"
186
+ require_relative "simplecov/context_map/union"
187
+ require_relative "simplecov/test_tracker/constant_watch"
188
+ require_relative "simplecov/test_tracker/delta"
189
+ require_relative "simplecov/test_tracker"
190
+ require_relative "simplecov/test_tracker/framework_hooks"
191
+ require_relative "simplecov/test_tracker/accessors"
192
+ SimpleCov.extend SimpleCov::TestTracker::Accessors
457
193
  require_relative "simplecov/result_merger"
194
+ require_relative "simplecov/parallel_result_merger"
195
+ require_relative "simplecov/parallel_adapters"
196
+ require_relative "simplecov/run_identity"
197
+ SimpleCov.extend SimpleCov::RunIdentity::Accessors
458
198
  require_relative "simplecov/command_guesser"
459
199
  require_relative "simplecov/version"
460
200
  require_relative "simplecov/result_adapter"
461
201
  require_relative "simplecov/combine"
202
+ require_relative "simplecov/combine/identity_interner"
462
203
  require_relative "simplecov/combine/branches_combiner"
463
- require_relative "simplecov/combine/files_combiner"
204
+ require_relative "simplecov/combine/methods_combiner"
464
205
  require_relative "simplecov/combine/lines_combiner"
206
+ require_relative "simplecov/combine/coverage_accumulator"
465
207
  require_relative "simplecov/combine/results_combiner"
466
208
  require_relative "simplecov/useless_results_remover"
467
209
  require_relative "simplecov/simulate_coverage"
468
-
469
- # Load default config
210
+ require_relative "simplecov/unloaded_file_injector"
211
+ require_relative "simplecov/view_coverage"
212
+ require_relative "simplecov/result_processing"
213
+ require_relative "simplecov/exit_handling"
214
+ require_relative "simplecov/report_deferral"
215
+ require_relative "simplecov/parallel_coordination"
216
+
217
+ # simplecov:disable — env-var never set in the dogfooded test process
218
+ # (sandbox fixture subprocesses set it via simplecov/no_defaults)
470
219
  require_relative "simplecov/defaults" unless ENV["SIMPLECOV_NO_DEFAULTS"]
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Backward-compatibility shim: simplecov_json_formatter is now part of simplecov.
4
+
5
+ require_relative "simplecov/formatter/json_formatter"