simplecov 1.0.0 → 1.0.1

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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/lib/simplecov/cli/coverage.rb +5 -3
  3. data/lib/simplecov/cli/diff.rb +2 -1
  4. data/lib/simplecov/cli/dotfile.rb +9 -4
  5. data/lib/simplecov/cli/merge.rb +5 -3
  6. data/lib/simplecov/cli/report.rb +11 -6
  7. data/lib/simplecov/cli/run.rb +1 -1
  8. data/lib/simplecov/cli/serve.rb +17 -7
  9. data/lib/simplecov/cli/uncovered.rb +2 -1
  10. data/lib/simplecov/combine/branches_combiner.rb +2 -1
  11. data/lib/simplecov/combine/results_combiner.rb +2 -1
  12. data/lib/simplecov/configuration/coverage.rb +6 -2
  13. data/lib/simplecov/configuration/coverage_criteria.rb +3 -1
  14. data/lib/simplecov/configuration/formatting.rb +17 -7
  15. data/lib/simplecov/configuration/thresholds.rb +13 -9
  16. data/lib/simplecov/configuration.rb +22 -13
  17. data/lib/simplecov/coverage_statistics.rb +4 -1
  18. data/lib/simplecov/coverage_violations.rb +2 -1
  19. data/lib/simplecov/defaults.rb +3 -3
  20. data/lib/simplecov/directive.rb +8 -3
  21. data/lib/simplecov/exit_codes/maximum_coverage_drop_check.rb +1 -1
  22. data/lib/simplecov/exit_codes/maximum_overall_coverage_check.rb +1 -1
  23. data/lib/simplecov/exit_codes/minimum_coverage_by_file_check.rb +1 -1
  24. data/lib/simplecov/exit_codes/minimum_coverage_by_group_check.rb +1 -1
  25. data/lib/simplecov/exit_codes/minimum_overall_coverage_check.rb +3 -3
  26. data/lib/simplecov/exit_codes.rb +12 -0
  27. data/lib/simplecov/exit_handling.rb +3 -3
  28. data/lib/simplecov/file_list.rb +12 -5
  29. data/lib/simplecov/formatter/base.rb +2 -1
  30. data/lib/simplecov/formatter/html_formatter.rb +13 -7
  31. data/lib/simplecov/formatter/json_formatter/errors_formatter.rb +9 -3
  32. data/lib/simplecov/formatter/json_formatter/result_hash_formatter.rb +1 -1
  33. data/lib/simplecov/formatter/json_formatter/source_file_formatter.rb +1 -1
  34. data/lib/simplecov/formatter/json_formatter.rb +4 -2
  35. data/lib/simplecov/formatter/multi_formatter.rb +7 -2
  36. data/lib/simplecov/formatter/simple_formatter.rb +3 -1
  37. data/lib/simplecov/process.rb +22 -0
  38. data/lib/simplecov/result_adapter.rb +2 -1
  39. data/lib/simplecov/result_processing.rb +4 -4
  40. data/lib/simplecov/simulate_coverage.rb +2 -2
  41. data/lib/simplecov/source_file/line.rb +2 -2
  42. data/lib/simplecov/source_file/method.rb +1 -1
  43. data/lib/simplecov/source_file/method_builder.rb +3 -1
  44. data/lib/simplecov/source_file/source_loader.rb +2 -2
  45. data/lib/simplecov/source_file.rb +2 -2
  46. data/lib/simplecov/static_coverage_extractor/location_conventions.rb +158 -0
  47. data/lib/simplecov/static_coverage_extractor/visitor.rb +9 -45
  48. data/lib/simplecov/version.rb +1 -1
  49. data/lib/simplecov.rb +24 -11
  50. data/sig/simplecov.rbs +1638 -0
  51. metadata +5 -3
data/sig/simplecov.rbs ADDED
@@ -0,0 +1,1638 @@
1
+ # Code coverage for Ruby. See the README for a full introduction.
2
+ module SimpleCov
3
+ # A coverage criterion that can be enabled, measured, and reported.
4
+ type criterion = :line | :branch | :method
5
+
6
+ # Anything accepted by `skip` / `group` (and the deprecated
7
+ # `add_filter` / `add_group`): a path-segment substring, a Regexp, a
8
+ # prebuilt Filter, a predicate on the SourceFile, or an Array of those.
9
+ type filter_arg = String | Regexp | Filter[untyped] | ^(SourceFile source_file) -> boolish | Array[filter_arg]
10
+
11
+ # Anything accepted by `cover`: a shell-glob String, Regexp, Proc,
12
+ # prebuilt Filter, or an Array of those.
13
+ type cover_arg = String | Regexp | ^(SourceFile source_file) -> boolish | Filter[untyped] | Array[cover_arg]
14
+
15
+ # Raised when a user's configuration is internally inconsistent — e.g.
16
+ # every coverage criterion has been disabled.
17
+ class ConfigurationError < StandardError
18
+ end
19
+
20
+ # Maps SimpleCov's criterion names to the keys `Coverage.start` expects.
21
+ CRITERION_TO_RUBY_COVERAGE: Hash[Symbol, Symbol]
22
+
23
+ extend Configuration
24
+
25
+ self.@subprocess_serial: Integer?
26
+ self.@forked_subprocess: bool?
27
+ self.@autoloading_dot_simplecov: bool?
28
+ self.@dot_simplecov_start_warned: bool?
29
+ self.@at_exit_hook_installed: bool?
30
+
31
+ attr_accessor self.pid: Integer?
32
+
33
+ # When this process started tracking coverage.
34
+ attr_accessor self.process_start_time: Time?
35
+
36
+ # Should something external (e.g. the Minitest plugin) own the
37
+ # at_exit behavior instead of SimpleCov's own hook?
38
+ attr_accessor self.external_at_exit: bool?
39
+
40
+ def self.external_at_exit?: () -> bool
41
+
42
+ # A monotonically increasing serial assigned to each forked
43
+ # subprocess; the default `at_fork` builds worker command names from it.
44
+ def self.subprocess_serial: () -> Integer
45
+
46
+ def self.next_subprocess_serial!: () -> Integer
47
+
48
+ def self.forked_subprocess?: () -> bool
49
+
50
+ def self.mark_forked_subprocess!: () -> void
51
+
52
+ # `:oneshot_line` stats are folded into the `:line` bucket, so use
53
+ # the returned criterion to look up `coverage_statistics`.
54
+ def self.coverage_statistics_key: ((criterion | :oneshot_line) criterion) -> criterion
55
+
56
+ # Sets up SimpleCov to run against your project:
57
+ #
58
+ # SimpleCov.start
59
+ # SimpleCov.start 'rails' # using a profile
60
+ # SimpleCov.start { skip 'test' } # with a config block
61
+ #
62
+ def self.start: (?(String | Symbol)? profile) ?{ () [self: singleton(SimpleCov)] -> void } -> void
63
+
64
+ def self.with_dot_simplecov_autoload: [T] () { () -> T } -> T
65
+
66
+ def self.warn_about_start_in_dot_simplecov: () -> void
67
+
68
+ # Install the at_exit hook that formats results and runs exit-code
69
+ # checks. Idempotent; `SimpleCov.start` calls this automatically.
70
+ def self.install_at_exit_hook: () -> void
71
+
72
+ # Reset at_exit state a forked child inherits from its parent (a
73
+ # possibly consumed hook and a Minitest deferral pid-pinned to the
74
+ # parent), so the child re-arms a hook that fires at its own exit.
75
+ # Called by the fork hook; see issue #1227.
76
+ def self.reset_inherited_at_exit_state!: () -> void
77
+
78
+ # Begin coverage tracking without applying configuration. Pairs with
79
+ # `SimpleCov.configure { ... }`.
80
+ def self.start_tracking: () -> void
81
+
82
+ # Implementation details of `start` / `start_tracking` (private in Ruby;
83
+ # RBS cannot mark singleton methods private).
84
+ def self.start_coverage_measurement: () -> void
85
+
86
+ def self.minitest_autorun_pending?: () -> bool
87
+
88
+ def self.defer_to_minitest_after_run: () -> void
89
+
90
+ def self.warn_if_jruby_full_trace_disabled: () -> void
91
+ end
92
+
93
+ # ----- version -----
94
+
95
+ module SimpleCov
96
+ VERSION: String
97
+ end
98
+
99
+ # ----- result_processing -----
100
+
101
+ # Result-building façade: turns the raw `Coverage.result` hash into a
102
+ # `SimpleCov::Result`, applies filters and groups, drives merging, and
103
+ # exposes the `collate` entry point.
104
+ module SimpleCov
105
+ self.@result: Result?
106
+ self.@collating_result: bool?
107
+
108
+ # Collate a series of resultset files into a single merged report. By
109
+ # default ignores `merge_timeout` so every listed resultset merges;
110
+ # pass `ignore_timeout: false` to honor it.
111
+ def self.collate: (Array[String] result_filenames, ?(String | Symbol)? profile, ?ignore_timeout: bool) ?{ () [self: singleton(SimpleCov)] -> void } -> void
112
+
113
+ # The result for the current coverage run, merged across test suites
114
+ # when merging is active. nil when no coverage was tracked.
115
+ def self.result: () -> Result?
116
+
117
+ # The memoized result, or false/nil when it has not been computed yet.
118
+ def self.result?: () -> (Result | false | nil)
119
+
120
+ def self.collating_result?: () -> boolish
121
+
122
+ # Applies the configured filters to the given source files.
123
+ def self.filtered: ((Array[SourceFile] | FileList) files) -> FileList
124
+
125
+ # Bin the given source files by group filter. Files matched by no
126
+ # group fall into the implicit "Ungrouped" bucket.
127
+ def self.grouped: ((Array[SourceFile] | FileList) files, ?groups: Hash[String, Filter[untyped]]) -> Hash[String, FileList]
128
+
129
+ # Applies the profile of the given name to the configuration.
130
+ def self.load_profile: ((String | Symbol) name) -> void
131
+
132
+ # Clear the cached result. Primarily useful in testing.
133
+ def self.clear_result: () -> void
134
+
135
+ def self.write_last_run: (Result result) -> void
136
+
137
+ # Round coverage down to two decimals.
138
+ def self.round_coverage: (Numeric coverage) -> Numeric
139
+
140
+ # Implementation details of `collate` / `result` (private in Ruby;
141
+ # RBS cannot mark singleton methods private).
142
+ def self.initial_setup: ((String | Symbol)? profile) ?{ () [self: singleton(SimpleCov)] -> void } -> void
143
+
144
+ def self.grouped_file_set: (Hash[String, FileList] grouped) -> Set[SourceFile]
145
+
146
+ def self.add_not_loaded_files: (Hash[String, untyped] result) -> [Hash[String, untyped], Set[String]]
147
+
148
+ def self.unloaded_file_discovery_globs: () -> Array[String]
149
+
150
+ def self.discover_unloaded_paths: (Array[String] globs) -> Array[String]
151
+
152
+ def self.inject_unloaded_files: (Hash[String, untyped] result, Array[String] candidate_paths) -> [Hash[String, untyped], Set[String]]
153
+
154
+ def self.process_coverage_result: (report: bool) -> void
155
+ end
156
+
157
+ # ----- configuration -----
158
+
159
+ # Bundles the configuration options used for SimpleCov. All methods
160
+ # defined here are usable from SimpleCov directly.
161
+ module SimpleCov
162
+ module Configuration
163
+ @root: String
164
+ @coverage_dir: String
165
+ @coverage_dir_explicit: bool?
166
+ @coverage_path: String?
167
+ @coverage_path_explicit: bool?
168
+ @command_name: String?
169
+ @profiles: Profiles?
170
+ @at_exit: Proc?
171
+ @at_fork: Proc?
172
+ @project_name: String?
173
+
174
+ # The root for the project, defaulting to the current working
175
+ # directory. Get, or set with `SimpleCov.root('/my/project/path')`.
176
+ def root: (?String? root) -> String
177
+
178
+ # The name of the output and cache directory. Defaults to "coverage".
179
+ def coverage_dir: (?String? dir) -> String
180
+
181
+ # The full path to the output directory. By default `root` +
182
+ # `coverage_dir`; assign an absolute path to pin the destination
183
+ # regardless of later `root` / `coverage_dir` changes (see #716).
184
+ def coverage_path: (?String? path) -> String
185
+
186
+ # The name of the command (a.k.a. test suite) currently running.
187
+ # Auto-detected when not set explicitly.
188
+ def command_name: (?String? name) -> String
189
+
190
+ # The hash of available profiles.
191
+ def profiles: () -> Profiles
192
+
193
+ # Configure SimpleCov in a block, evaluated with `self` bound to
194
+ # the configuration target (usually the SimpleCov module itself):
195
+ #
196
+ # SimpleCov.configure { skip "test" }
197
+ #
198
+ def configure: () { () [self: self] -> void } -> void
199
+
200
+ # Gets or sets the behavior that processes coverage results at
201
+ # process exit. The default stores/merges the current result and
202
+ # formats only from the final reporting process.
203
+ def at_exit: () ?{ () -> void } -> Proc
204
+
205
+ # Whether SimpleCov has anything to do at exit: coverage is being
206
+ # tracked, or a result has already been assembled (e.g. by collate).
207
+ def active_session?: () -> boolish
208
+
209
+ # Gets or sets the behavior run in a newly forked process. The
210
+ # block receives the child pid. The default renames the command
211
+ # from the fork serial, silences errors, and restarts SimpleCov.
212
+ def at_fork: () ?{ (Integer pid) -> void } -> Proc
213
+
214
+ # The project name — defaults to the last dirname in `root`,
215
+ # capitalized, with underscores replaced by spaces.
216
+ def project_name: (?String? new_name) -> String
217
+
218
+ private
219
+
220
+ # Copy instance variables from block_context into self, saving any
221
+ # of ours that would be clobbered.
222
+ def swap_ivars_from: (untyped block_context) -> Hash[Symbol, untyped]
223
+
224
+ # Copy instance variables back to block_context and restore ours.
225
+ def restore_ivars: (untyped block_context, Hash[Symbol, untyped] saved) -> void
226
+ end
227
+ end
228
+
229
+ # ----- configuration/coverage_criteria -----
230
+
231
+ # Selection and validation of the coverage criteria Ruby's `Coverage`
232
+ # library should track: `:line` (default), `:branch`, `:method`, and
233
+ # `:oneshot_line`, plus the standalone `:eval` toggle.
234
+ module SimpleCov
235
+ module Configuration
236
+ # Members are line, branch, method, and oneshot_line (%i[] literals
237
+ # infer as Array[Symbol]).
238
+ SUPPORTED_COVERAGE_CRITERIA: Array[Symbol]
239
+
240
+ DEFAULT_COVERAGE_CRITERION: :line
241
+
242
+ ONESHOT_LINE_COVERAGE_CRITERION: :oneshot_line
243
+
244
+ @primary_coverage: (criterion | :oneshot_line)?
245
+ @coverage_criteria: Set[criterion | :oneshot_line]?
246
+ @coverage_for_eval_enabled: bool?
247
+
248
+ # Enable one or more coverage criteria. `:eval` is accepted as a
249
+ # shorthand for the standalone eval-coverage toggle;
250
+ # `:oneshot_line` replaces `:line`.
251
+ def enable_coverage: (*(criterion | :oneshot_line | :eval) criteria) -> void
252
+
253
+ # Remove `criterion` from the set of enabled coverage criteria.
254
+ # Disabling every criterion raises at `start_tracking`, not here.
255
+ def disable_coverage: ((criterion | :oneshot_line) criterion) -> void
256
+
257
+ # Gets the report's leading criterion, or sets it. The setter
258
+ # validates at runtime that the criterion is enabled; the parameter
259
+ # type also rejects unknown criteria statically.
260
+ def primary_coverage: (?(criterion | :oneshot_line)? criterion) -> (criterion | :oneshot_line)
261
+
262
+ # The currently enabled criteria. Defaults to `Set[:line]`.
263
+ def coverage_criteria: () -> Set[criterion | :oneshot_line]
264
+
265
+ # Any Symbol is accepted: asking whether an unknown criterion is
266
+ # enabled is a legitimate question (the answer is false), and the
267
+ # private validators rely on it.
268
+ def coverage_criterion_enabled?: (Symbol criterion) -> bool
269
+
270
+ # Reset the criteria back to the lazy default (`Set[:line]`).
271
+ def clear_coverage_criteria: () -> void
272
+
273
+ def validate_coverage_criteria!: () -> void
274
+
275
+ def branch_coverage?: () -> bool
276
+
277
+ def branch_coverage_supported?: () -> bool
278
+
279
+ def method_coverage?: () -> bool
280
+
281
+ def method_coverage_supported?: () -> bool
282
+
283
+ def coverage_for_eval_supported?: () -> bool
284
+
285
+ # Whether the running Ruby's Coverage library supports the given
286
+ # criterion, named in Coverage's own plural vocabulary
287
+ # (`:lines`, `:branches`, `:methods`, `:oneshot_lines`, `:eval`).
288
+ def coverage_criterion_supported?: (Symbol criterion) -> bool
289
+
290
+ def coverage_for_eval_enabled?: () -> bool
291
+
292
+ # DEPRECATED: use `enable_coverage :eval` instead.
293
+ def enable_coverage_for_eval: () -> void
294
+
295
+ private
296
+
297
+ def enable_eval_coverage: () -> void
298
+
299
+ def default_primary_coverage: () -> (criterion | :oneshot_line)
300
+
301
+ # Validators: any Symbol is accepted at the type level; the whole
302
+ # point of these is raising ConfigurationError on bad input.
303
+ def raise_if_criterion_disabled: (Symbol criterion) -> void
304
+
305
+ def raise_if_criterion_unsupported: (Symbol criterion) -> void
306
+ end
307
+ end
308
+
309
+ # ----- configuration/coverage -----
310
+
311
+ # The criterion-first `coverage` configuration method: naming a
312
+ # criterion enables it, and every threshold is declared with the same
313
+ # syntax regardless of criterion.
314
+ #
315
+ # SimpleCov.start do
316
+ # coverage :line do
317
+ # minimum 90
318
+ # minimum_per_file 80
319
+ # minimum_per_file 100, only: "app/mailers/request_mailer.rb"
320
+ # maximum_drop 5
321
+ # end
322
+ #
323
+ # coverage :branch, minimum: 80
324
+ # end
325
+ module SimpleCov
326
+ module Configuration
327
+ # Members are minimum, maximum, exact, maximum_drop, and
328
+ # minimum_per_file (%i[] literals infer as Array[Symbol]).
329
+ COVERAGE_THRESHOLD_OPTIONS: Array[Symbol]
330
+
331
+ # Configure (and, unless `enabled: false`, enable) a coverage
332
+ # criterion. `primary: true` makes it the report's leading
333
+ # criterion; `oneshot: true` (only for `:line`) selects
334
+ # oneshot-lines mode; `:eval` is enable-only. Threshold keywords
335
+ # mirror the block verbs for one-liner use. Returns the criterion
336
+ # symbol the thresholds were stored under.
337
+ # The threshold keywords (minimum:, maximum:, exact:, maximum_drop:,
338
+ # minimum_per_file:) arrive via **thresholds in the implementation, so
339
+ # they are typed as a Numeric kwarg splat. The block runs under
340
+ # instance_eval, which also yields the receiver as an optional argument.
341
+ def coverage: ((criterion | :eval) criterion, ?primary: bool, ?enabled: bool, ?oneshot: bool, **Numeric thresholds) ?{ (?CoverageCriterion) [self: CoverageCriterion] -> void } -> (criterion | :oneshot_line | :eval)
342
+
343
+ private
344
+
345
+ def apply_threshold_options: (CoverageCriterion configurator, Hash[Symbol, Numeric] options) -> void
346
+
347
+ def enable_coverage_criterion: ((criterion | :eval) criterion, enabled: bool, oneshot: bool) -> (criterion | :oneshot_line | :eval)
348
+
349
+ def enable_oneshot_line: ((criterion | :eval) criterion) -> :oneshot_line
350
+
351
+ def enable_eval_coverage_criterion: () -> :eval
352
+
353
+ # Threshold-store writers used by CoverageCriterion via `send`.
354
+ # They accept any criterion Symbol; `raise_on_invalid_coverage`
355
+ # rejects invalid ones (including `:eval`) at runtime.
356
+ def store_overall_threshold: (Symbol setting, Symbol criterion, Numeric percent) -> void
357
+
358
+ def store_minimum_per_file: (Symbol criterion, Numeric percent, (String | Regexp)? target) -> void
359
+
360
+ def store_minimum_per_group: (Symbol criterion, Numeric percent, String group_name) -> void
361
+
362
+ public
363
+
364
+ # Receiver for a `coverage <criterion> do ... end` block. Each verb
365
+ # writes a threshold for the single criterion the block configures,
366
+ # so values are always plain percentages.
367
+ class CoverageCriterion
368
+ @config: Configuration
369
+ @criterion: Symbol
370
+
371
+ def initialize: (Configuration config, Symbol criterion) -> void
372
+
373
+ # Overall (suite-wide) minimum for this criterion.
374
+ def minimum: (Numeric percent) -> void
375
+
376
+ # Overall maximum: fails the build if coverage rises above it.
377
+ def maximum: (Numeric percent) -> void
378
+
379
+ # Pin coverage to an exact figure (sets both minimum and maximum).
380
+ def exact: (Numeric percent) -> void
381
+
382
+ # Maximum allowed drop between runs (0 refuses any drop).
383
+ def maximum_drop: (Numeric percent) -> void
384
+
385
+ # Per-file minimum. With no `only:`, the default for every file;
386
+ # with `only:` (String path or Regexp), an override for matches.
387
+ def minimum_per_file: (Numeric percent, ?only: (String | Regexp)?) -> void
388
+
389
+ # Per-group minimum for the named group (defined via `group`).
390
+ def minimum_per_group: (Numeric percent, only: String) -> void
391
+
392
+ # Make this criterion the report's primary (leading) criterion.
393
+ def primary: () -> void
394
+ end
395
+ end
396
+ end
397
+
398
+ # ----- configuration/filters -----
399
+
400
+ # Inclusion / exclusion / grouping methods: `cover`, `skip`, `group`,
401
+ # plus the deprecated `track_files` / `add_filter` / `add_group` aliases.
402
+ module SimpleCov
403
+ module Configuration
404
+ attr_writer filters: Array[Filter[untyped]]
405
+
406
+ attr_writer groups: Hash[String, Filter[untyped]]
407
+
408
+ @cover_filters: Array[Filter[untyped]]?
409
+ @tracked_files: String?
410
+
411
+ # Restrict the report to files matching one or more shell globs,
412
+ # regexps, or block predicates. Multiple calls union. String globs
413
+ # are also expanded on disk so unloaded files appear at 0% coverage.
414
+ def cover: (*cover_arg args) ?{ (SourceFile source_file) -> boolish } -> Array[Filter[untyped]]
415
+
416
+ # The configured inclusion filters added via `cover`.
417
+ def cover_filters: () -> Array[Filter[untyped]]
418
+
419
+ # The string globs passed to `cover`, driving unloaded-file discovery.
420
+ def cover_globs: () -> Array[String]
421
+
422
+ # DEPRECATED: use `cover` instead.
423
+ def track_files: (String? glob) -> String?
424
+
425
+ def track_files_replacement_hint: (String? glob) -> String
426
+
427
+ # The glob used to include files that were not explicitly required.
428
+ def tracked_files: () -> String?
429
+
430
+ # The configured exclusion filters added via `skip` (or the
431
+ # deprecated `add_filter`).
432
+ def filters: () -> Array[Filter[untyped]]
433
+
434
+ # Drop matching files from the coverage report. The inverse of
435
+ # `cover`. Strings match at path-segment boundaries.
436
+ def skip: (?filter_arg? filter_argument) ?{ (SourceFile source_file) -> boolish } -> Array[Filter[untyped]]
437
+
438
+ # DEPRECATED: use `skip` instead (same arguments, same behavior).
439
+ def add_filter: (?filter_arg? filter_argument) ?{ (SourceFile source_file) -> boolish } -> Array[Filter[untyped]]
440
+
441
+ # Remove any filters whose `filter_argument` equals the given
442
+ # value. Returns true when at least one filter was removed.
443
+ def remove_filter: (untyped filter_argument) -> bool
444
+
445
+ # Remove every filter from the chain, including the defaults
446
+ # installed by `SimpleCov.start`.
447
+ def clear_filters: () -> Array[Filter[untyped]]
448
+
449
+ # The configured groups. Add groups using `group`.
450
+ def groups: () -> Hash[String, Filter[untyped]]
451
+
452
+ # Define a display group for files. Same matcher grammar as `skip`,
453
+ # but bins matches under `group_name` instead of dropping them.
454
+ def group: (String group_name, ?filter_arg? filter_argument) ?{ (SourceFile source_file) -> boolish } -> Filter[untyped]
455
+
456
+ # DEPRECATED: use `group` instead (same arguments, same behavior).
457
+ def add_group: (String group_name, ?filter_arg? filter_argument) ?{ (SourceFile source_file) -> boolish } -> Filter[untyped]
458
+
459
+ # Drop every previously installed filter (defaults included) so
460
+ # subsequent `skip` calls start from a clean slate.
461
+ def no_default_skips: () -> Array[Filter[untyped]]
462
+
463
+ private
464
+
465
+ def parse_filter: (?filter_arg? filter_argument) ?{ (SourceFile source_file) -> boolish } -> Filter[untyped]
466
+
467
+ def build_cover_filter: (cover_arg arg) -> Filter[untyped]
468
+
469
+ def collect_cover_globs: (Array[Filter[untyped]] filter_list) -> Array[String]
470
+ end
471
+ end
472
+
473
+ # ----- configuration/formatting -----
474
+
475
+ # Formatter selection (`formatter` / `formatters`), reporting toggles
476
+ # (`print_errors`, `color`, `source_in_json`), and the deprecated
477
+ # `# :nocov:` token hook.
478
+ module SimpleCov
479
+ module Configuration
480
+ # A formatter is a Class whose instances respond to `format(result)`
481
+ # (including the anonymous Class built by `MultiFormatter.new`).
482
+ attr_writer formatter: Class?
483
+
484
+ attr_writer print_error_status: bool
485
+
486
+ @color: bool | :auto
487
+ @source_in_json: bool
488
+ @nocov_token: String
489
+
490
+ # Gets or sets the configured formatter. Pass `false` (or `nil`) to
491
+ # opt out of formatting entirely (see #964).
492
+ def formatter: (?(Class | false | :__no_arg__)? formatter) -> Class?
493
+
494
+ # Gets the formatter chain, or sets it. Accepts an Array, a single
495
+ # formatter, or nil / `[]` to opt out of formatting entirely.
496
+ # Returns the passed value when setting.
497
+ def formatters: (?(Array[Class] | Class | :__no_arg__)? formatters) -> (Array[Class] | Class | nil)
498
+
499
+ # Sets the configured formatters (single formatters are wrapped;
500
+ # nil / `[]` opts out of formatting entirely).
501
+ def formatters=: ((Array[Class] | Class)? formatters) -> void
502
+
503
+ # Whether stderr diagnostics are colorized: `true`, `false`, or
504
+ # `:auto` (default — respects TTY, NO_COLOR, and FORCE_COLOR).
505
+ def color: (?(bool | :auto | :__no_arg__) value) -> (bool | :auto)
506
+
507
+ # Whether SimpleCov prints its own diagnostic warnings to stderr.
508
+ # Defaults to true.
509
+ def print_errors: (?(bool | :__no_arg__) value) -> bool
510
+
511
+ # Whether `coverage.json` embeds the full source text of every
512
+ # file. Defaults to true.
513
+ def source_in_json: (?(bool | :__no_arg__) value) -> bool
514
+
515
+ # DEPRECATED: use `print_errors` instead (same value).
516
+ def print_error_status: () -> bool
517
+
518
+ # DEPRECATED: use `# simplecov:disable` / `# simplecov:enable`
519
+ # directive comments instead of `# :nocov:` toggles.
520
+ def nocov_token: (?String? nocov_token) -> String
521
+
522
+ # DEPRECATED: alias for `nocov_token`.
523
+ alias skip_token nocov_token
524
+
525
+ def current_nocov_token: (?String? value) -> String
526
+ end
527
+ end
528
+
529
+ # ----- configuration/ignored_entries -----
530
+
531
+ # Coverage-entry filters scoped to branch / method criteria. See
532
+ # `ignore_branches` / `ignore_methods` and #1033 / #1046.
533
+ module SimpleCov
534
+ module Configuration
535
+ # Branch types accepted by `ignore_branches`: implicit_else and
536
+ # eval_generated (%i[] literals infer as Array[Symbol]).
537
+ IGNORABLE_BRANCH_TYPES: Array[Symbol]
538
+
539
+ # Method types accepted by `ignore_methods`: eval_generated (%i[]
540
+ # literals infer as Array[Symbol]).
541
+ IGNORABLE_METHOD_TYPES: Array[Symbol]
542
+
543
+ @ignored_branches: Array[Symbol]?
544
+ @ignored_methods: Array[Symbol]?
545
+
546
+ # Opt out of synthetic branch entries. Variadic; multiple calls
547
+ # union. Recorded even when branch coverage is not (yet) enabled.
548
+ def ignore_branches: (*(:implicit_else | :eval_generated) types) -> Array[Symbol]
549
+
550
+ def ignored_branches: () -> Array[Symbol]
551
+
552
+ def ignored_branch?: (Symbol type) -> bool
553
+
554
+ # Opt out of synthetic method entries (currently `:eval_generated` only).
555
+ def ignore_methods: (*:eval_generated types) -> Array[Symbol]
556
+
557
+ def ignored_methods: () -> Array[Symbol]
558
+
559
+ def ignored_method?: (Symbol type) -> bool
560
+
561
+ private
562
+
563
+ def raise_if_branch_type_unsupported: (Symbol type) -> void
564
+
565
+ def raise_if_method_type_unsupported: (Symbol type) -> void
566
+ end
567
+ end
568
+
569
+ # ----- configuration/merging -----
570
+
571
+ # Result merging and subprocess / parallel-test coordination:
572
+ # `merging`, `merge_subprocesses`, `merge_timeout`, `finalize_merge`,
573
+ # `parallel_tests`, `parallel_wait_timeout`.
574
+ module SimpleCov
575
+ module Configuration
576
+ # `defined?`-guarded module state. Declared non-nil where every
577
+ # read is guarded, so readers don't have to refute a nil that
578
+ # cannot be observed.
579
+ @enable_for_subprocesses: bool
580
+ @parallel_tests: bool?
581
+ @use_merging: bool
582
+ @finalize_merge: bool
583
+ @finalize_merge_explicit: bool
584
+ @finalize_merge_inference_warned: bool
585
+ @merge_timeout: Integer?
586
+ @parallel_wait_timeout: Integer?
587
+
588
+ # Get or set whether SimpleCov hooks `Process._fork` to attach
589
+ # itself to subprocesses (e.g. Rails' `parallelize(workers:)`).
590
+ # Defaults to false.
591
+ def merge_subprocesses: (?bool? value) -> bool
592
+
593
+ def enabled_for_subprocesses?: () -> bool
594
+
595
+ # Get or set whether SimpleCov auto-requires the `parallel_tests`
596
+ # gem when it sees its environment variables. nil (the default)
597
+ # means auto-detect. See #1018.
598
+ def parallel_tests: (?(:__no_arg__ | bool)? value) -> bool?
599
+
600
+ # DEPRECATED: use `merge_subprocesses` instead (same value).
601
+ def enable_for_subprocesses: (?bool? value) -> bool
602
+
603
+ # Get or set whether to merge results from multiple test suites
604
+ # into a single coverage report. Defaults to true.
605
+ def merging: (?bool? use) -> bool
606
+
607
+ # Get or set whether this process owns final merge processing:
608
+ # waiting for sibling workers, merging, formatting, enforcing
609
+ # thresholds, and writing `.last_run.json`. Defaults to true except
610
+ # for recognized multi-worker parallel runs writing to a custom
611
+ # coverage destination (those likely finalize via an external
612
+ # `SimpleCov.collate` step). See #1215.
613
+ def finalize_merge: (?(:__no_arg__ | bool) value) -> bool
614
+
615
+ def finalize_merge?: () -> bool
616
+
617
+ def merge_finalization_owner?: () -> boolish
618
+
619
+ # DEPRECATED: use `merging` instead (same value, same behavior).
620
+ # Returns nil when merging had already been disabled.
621
+ def use_merging: (?bool? use) -> bool?
622
+
623
+ # The maximum age (in seconds) of a resultset to still be included
624
+ # in merged results. Defaults to 600.
625
+ def merge_timeout: (?Integer? seconds) -> Integer
626
+
627
+ # How long (in seconds) the reporting process waits for remaining
628
+ # parallel-test workers to write their resultsets before it
629
+ # proceeds with a partial merge. Defaults to 60. See #1171.
630
+ def parallel_wait_timeout: (?Integer? seconds) -> Integer
631
+
632
+ private
633
+
634
+ def inferred_finalize_merge?: () -> bool
635
+
636
+ def parallel_worker_environment?: () -> bool
637
+
638
+ def explicit_custom_coverage_destination?: () -> bool
639
+
640
+ def explicit_coverage_destination?: () -> boolish
641
+
642
+ def warn_about_inferred_finalize_merge: () -> void
643
+
644
+ def inferred_finalize_merge_warning: () -> String
645
+
646
+ # Host contract: defined on SimpleCov itself (result_processing.rb).
647
+ # This module is only ever extended onto SimpleCov, where the
648
+ # method is available to `merge_finalization_owner?`.
649
+ def collating_result?: () -> boolish
650
+ end
651
+ end
652
+
653
+ # ----- configuration/thresholds -----
654
+
655
+ # Coverage threshold configuration: `minimum_coverage`,
656
+ # `maximum_coverage`, `expected_coverage`, `maximum_coverage_drop`,
657
+ # `refuse_coverage_drop`, and the deprecated by-file / by-group forms.
658
+ module SimpleCov
659
+ module Configuration
660
+ # Thresholds are stored per criterion; a bare Numeric argument is
661
+ # normalized to `{primary_coverage => value}`. Keys are criterion
662
+ # symbols — Symbol rather than the `criterion` alias because the
663
+ # stores also carry `:oneshot_line`, and the validating setters are
664
+ # the layer that rejects unknown symbols (with ConfigurationError).
665
+ type coverage_thresholds = Hash[Symbol, Numeric]
666
+
667
+ @minimum_coverage: coverage_thresholds?
668
+ @maximum_coverage: coverage_thresholds?
669
+ @maximum_coverage_drop: coverage_thresholds?
670
+ @minimum_coverage_by_file: coverage_thresholds?
671
+ @minimum_coverage_by_file_overrides: Hash[String | Regexp, coverage_thresholds]?
672
+ @minimum_coverage_by_group: Hash[String, coverage_thresholds]?
673
+
674
+ # The minimum overall coverage required for the suite to pass.
675
+ # Default: none (0%, disabled).
676
+ def minimum_coverage: (?(Numeric | coverage_thresholds)? coverage) -> coverage_thresholds
677
+
678
+ def raise_on_invalid_coverage: (coverage_thresholds coverage, String coverage_setting) -> void
679
+
680
+ # The maximum overall coverage allowed — an unexpected jump above
681
+ # it fails the build. Pair with `minimum_coverage` (or use
682
+ # `expected_coverage`) to pin coverage. See #187.
683
+ def maximum_coverage: (?(Numeric | coverage_thresholds)? coverage) -> coverage_thresholds
684
+
685
+ # Pin the suite to an exact figure: sets both `minimum_coverage`
686
+ # and `maximum_coverage`. See #187.
687
+ def expected_coverage: (?(Numeric | coverage_thresholds)? coverage) -> coverage_thresholds
688
+
689
+ # The maximum coverage drop between runs allowed for the suite to
690
+ # pass. Default: none (100%, disabled).
691
+ def maximum_coverage_drop: (?(Numeric | coverage_thresholds)? coverage_drop) -> coverage_thresholds
692
+
693
+ # DEPRECATED: use `coverage(criterion) { minimum_per_file ... }`.
694
+ # Symbol keys declare per-criterion defaults; String / Regexp keys
695
+ # declare per-path overrides.
696
+ def minimum_coverage_by_file: () -> coverage_thresholds
697
+ | ((Numeric | Hash[Symbol | String | Regexp, Numeric | coverage_thresholds]) coverage) -> Hash[String | Regexp, coverage_thresholds]
698
+
699
+ # The per-path overrides set via `minimum_coverage_by_file` (or
700
+ # `coverage(criterion) { minimum_per_file N, only: ... }`).
701
+ def minimum_coverage_by_file_overrides: () -> Hash[String | Regexp, coverage_thresholds]
702
+
703
+ # DEPRECATED: use `coverage(criterion) { minimum_per_group ... }`.
704
+ def minimum_coverage_by_group: () -> Hash[String, coverage_thresholds]
705
+ | (Hash[String, Numeric | coverage_thresholds] coverage) -> Hash[String, coverage_thresholds]
706
+
707
+ # Refuse any coverage drop for the given criteria (all enabled
708
+ # criteria when none are given). Coverage may only increase.
709
+ def refuse_coverage_drop: (*(criterion | :oneshot_line) criteria) -> coverage_thresholds
710
+
711
+ private
712
+
713
+ def partition_per_file_thresholds: (Hash[Symbol | String | Regexp, Numeric | coverage_thresholds] coverage) -> [coverage_thresholds, Hash[String | Regexp, coverage_thresholds]]
714
+
715
+ def validate_per_file_key: ((Symbol | String | Regexp) key) -> void
716
+
717
+ def minimum_possible_coverage_exceeded: (String coverage_option) -> void
718
+
719
+ def per_file_coverage_replacement: (coverage_thresholds defaults, Hash[String | Regexp, coverage_thresholds] overrides) -> String
720
+
721
+ def per_group_coverage_replacement: (Hash[String, Numeric | coverage_thresholds] coverage) -> String
722
+
723
+ def render_coverage_blocks: (Hash[Symbol, Array[String]] by_criterion) -> String
724
+ end
725
+ end
726
+
727
+ # ----- result -----
728
+
729
+ module SimpleCov
730
+ # A coverage result built from the Hash Ruby's Coverage library
731
+ # produces: filename => per-criterion coverage data.
732
+ class Result
733
+ extend Forwardable
734
+
735
+ attr_reader original_result: Hash[String, untyped]
736
+ attr_reader files: FileList
737
+ alias source_files files
738
+ # The writers accept the strict types; the ivars stay nilable because
739
+ # both default to nil and are lazily backfilled by the readers.
740
+ attr_writer created_at (): Time
741
+ attr_writer command_name (): String
742
+
743
+ @created_at: Time?
744
+ @command_name: String?
745
+ @groups_config: Hash[String, Filter[untyped]]
746
+ @groups: Hash[String, FileList]?
747
+
748
+ # Bundles filter and grouping configuration. Every field defaults to
749
+ # the SimpleCov singleton's configuration; tests pass a custom
750
+ # instance (e.g. `filters: []`) to opt out.
751
+ class FilterConfig
752
+ attr_reader filters: Array[Filter[untyped]]
753
+ attr_reader cover_filters: Array[Filter[untyped]]
754
+ attr_reader groups: Hash[String, Filter[untyped]]
755
+
756
+ def initialize: (?filters: Array[Filter[untyped]], ?cover_filters: Array[Filter[untyped]], ?groups: Hash[String, Filter[untyped]]) -> void
757
+ end
758
+
759
+ def initialize: (Hash[String, untyped] original_result, ?command_name: String?, ?created_at: Time?, ?not_loaded_files: Set[String], ?report: bool, ?filter_config: FilterConfig) -> void
760
+
761
+ def filenames: () -> Array[String]
762
+ # Accepts an absolute or project-relative path (resolved against SimpleCov.root).
763
+ def source_file_for: (String path) -> SourceFile?
764
+ def coverage_for: (String path) -> Hash[criterion, CoverageStatistics]?
765
+ def groups: () -> Hash[String, FileList]
766
+ # Returns nil when formatting is opted out of (`formatter false` /
767
+ # `formatters []`); otherwise whatever the configured formatter returns.
768
+ def format!: () -> untyped
769
+ def created_at: () -> Time
770
+ def command_name: () -> String
771
+ def to_hash: () -> Hash[String, { "coverage" => Hash[String, untyped], "timestamp" => Integer }]
772
+ def self.from_hash: (Hash[String, untyped] hash) -> Array[Result]
773
+
774
+ # Delegated to #files (see FileList).
775
+ def covered_percent: (?criterion) -> Float?
776
+ def covered_percentages: () -> Array[Float?]
777
+ def least_covered_file: () -> String
778
+ def covered_strength: (?criterion) -> Float?
779
+ def covered_lines: () -> Integer?
780
+ def missed_lines: () -> Integer?
781
+ def total_branches: () -> Integer?
782
+ def covered_branches: () -> Integer?
783
+ def missed_branches: () -> Integer?
784
+ def total_methods: () -> Integer?
785
+ def covered_methods: () -> Integer?
786
+ def missed_methods: () -> Integer?
787
+ def coverage_statistics: () -> Hash[criterion, CoverageStatistics]
788
+ | (criterion) -> CoverageStatistics?
789
+ def coverage_statistics_by_file: () -> Hash[criterion, Array[CoverageStatistics]]
790
+ def total_lines: () -> Integer?
791
+
792
+ private
793
+
794
+ def warn_about_missing_source_files: (Array[String] missing, Integer input_size) -> void
795
+ def coverage: () -> Hash[String, untyped]
796
+ def apply_filters!: (Array[Filter[untyped]] filters) -> void
797
+ def apply_cover_filters!: (Array[Filter[untyped]] cover_filters) -> void
798
+ end
799
+ end
800
+
801
+ # ----- file_list -----
802
+
803
+ module SimpleCov
804
+ # An Enumerable of SourceFile instances with aggregate coverage
805
+ # helpers. Aggregate readers return nil when the corresponding
806
+ # criterion was not enabled for the run.
807
+ class FileList
808
+ include Enumerable[SimpleCov::SourceFile]
809
+ extend Forwardable
810
+
811
+ def initialize: (Array[SourceFile] files) -> void
812
+
813
+ @files: Array[SourceFile]
814
+ @coverage_statistics: Hash[criterion, CoverageStatistics]?
815
+ @coverage_statistics_by_file: Hash[criterion, Array[CoverageStatistics]]?
816
+
817
+ # Delegated to the underlying Array.
818
+ def each: () { (SourceFile) -> void } -> void
819
+ | () -> Enumerator[SourceFile, untyped]
820
+ def size: () -> Integer
821
+ def length: () -> Integer
822
+ def map: [U] () { (SourceFile) -> U } -> Array[U]
823
+ def count: () -> Integer
824
+ | (untyped) -> Integer
825
+ | () { (SourceFile) -> boolish } -> Integer
826
+ def empty?: () -> bool
827
+ def to_a: () -> Array[SourceFile]
828
+ def to_ary: () -> Array[SourceFile]
829
+
830
+ def coverage_statistics: () -> Hash[criterion, CoverageStatistics]
831
+ | (criterion) -> CoverageStatistics?
832
+ def coverage_statistics_by_file: () -> Hash[criterion, Array[CoverageStatistics]]
833
+
834
+ def covered_lines: () -> Integer?
835
+ def missed_lines: () -> Integer?
836
+ # 0.0 when the list is empty, an Integer sum otherwise.
837
+ def never_lines: () -> (Integer | Float)
838
+ def skipped_lines: () -> (Integer | Float)
839
+ def covered_percentages: () -> Array[Float?]
840
+ def least_covered_file: () -> String
841
+ def lines_of_code: () -> Integer?
842
+ def covered_percent: (?criterion) -> Float?
843
+ def covered_strength: (?criterion) -> Float?
844
+
845
+ def total_branches: () -> Integer?
846
+ def covered_branches: () -> Integer?
847
+ def missed_branches: () -> Integer?
848
+ def branch_covered_percent: () -> Float?
849
+
850
+ def total_methods: () -> Integer?
851
+ def covered_methods: () -> Integer?
852
+ def missed_methods: () -> Integer?
853
+ def method_covered_percent: () -> Float?
854
+
855
+ private
856
+
857
+ def compute_coverage_statistics_by_file: () -> Hash[criterion, Array[CoverageStatistics]]
858
+ def compute_coverage_statistics: () -> Hash[criterion, CoverageStatistics]
859
+ def enabled_criteria_for_reporting: () -> Array[criterion]
860
+ end
861
+ end
862
+
863
+ # ----- source_file -----
864
+
865
+ module SimpleCov
866
+ # A source file with its coverage data, source lines, and helpers to
867
+ # interpret that data.
868
+ class SourceFile
869
+ include BuilderContext
870
+
871
+ # Full absolute path to the file.
872
+ attr_reader filename: String
873
+ # Coverage.result-shaped data for this file, e.g.
874
+ # {"lines" => [...], "branches" => {...}, "methods" => {...}}.
875
+ attr_reader coverage_data: Hash[String, untyped]
876
+
877
+ def initialize: (String filename, Hash[String, untyped] coverage_data, ?loaded: bool) -> void
878
+
879
+ # Memoization backing for the lazy readers below.
880
+ @loaded: bool
881
+ @src: Array[String]?
882
+ @coverage_statistics: Hash[criterion, CoverageStatistics]?
883
+ @lines: Array[Line]?
884
+ @covered_lines: Array[Line]?
885
+ @missed_lines: Array[Line]?
886
+ @never_lines: Array[Line]?
887
+ @skipped_lines: Array[Line]?
888
+ @branches: Array[Branch]?
889
+ @total_branches: Array[Branch]?
890
+ @branches_report: Hash[Integer, Array[[ Symbol, Integer ]]]?
891
+ @covered_branches: Array[Branch]?
892
+ @missed_branches: Array[Branch]?
893
+ @methods: Array[Method]?
894
+ @covered_methods: Array[Method]?
895
+ @missed_methods: Array[Method]?
896
+
897
+ # Project-relative path with no leading separator (e.g. "lib/foo.rb").
898
+ def project_filename: () -> String
899
+ # Source lines, read lazily.
900
+ def src: () -> Array[String]
901
+ alias source src
902
+
903
+ # With no argument returns a Hash keyed by every supported criterion
904
+ # (disabled criteria collapse to 0/0/0); pass a criterion to get that
905
+ # one CoverageStatistics.
906
+ def coverage_statistics: () -> Hash[criterion, CoverageStatistics]
907
+ | (criterion) -> CoverageStatistics?
908
+
909
+ def lines: () -> Array[Line]
910
+ alias source_lines lines
911
+ def covered_lines: () -> Array[Line]
912
+ def missed_lines: () -> Array[Line]
913
+ def never_lines: () -> Array[Line]
914
+ def skipped_lines: () -> Array[Line]
915
+ def lines_of_code: () -> Integer
916
+ # 1-based line lookup.
917
+ def line: (Integer number) -> Line?
918
+ def covered_percent: (?criterion) -> Float?
919
+ def covered_strength: (?criterion) -> Float?
920
+ def no_lines?: () -> bool
921
+ def relevant_lines: () -> Integer
922
+
923
+ def branches: () -> Array[Branch]
924
+ def no_branches?: () -> bool
925
+ # DEPRECATED: use `covered_percent(:branch)`.
926
+ def branches_coverage_percent: () -> Float?
927
+ # All relevant (covered + missed) branches, not a count.
928
+ def total_branches: () -> Array[Branch]
929
+ # line number => Array of [branch type, hit count] pairs.
930
+ def branches_report: () -> Hash[Integer, Array[[ Symbol, Integer ]]]
931
+ def covered_branches: () -> Array[Branch]
932
+ def missed_branches: () -> Array[Branch]
933
+ def branches_for_line: (Integer line_number) -> Array[[ Symbol, Integer ]]
934
+ def line_with_missed_branch?: (Integer line_number) -> bool
935
+
936
+ def methods: () -> Array[Method]
937
+ def covered_methods: () -> Array[Method]
938
+ def missed_methods: () -> Array[Method]
939
+ # DEPRECATED: use `covered_percent(:method)`.
940
+ def methods_coverage_percent: () -> Float?
941
+
942
+ # Whether this file was added via `cover` / `track_files` but never
943
+ # loaded during the run.
944
+ def not_loaded?: () -> bool
945
+ end
946
+ end
947
+
948
+ # ----- source_file/line -----
949
+
950
+ module SimpleCov
951
+ class SourceFile
952
+ # A single source line with its coverage: nil (not relevant, e.g. a
953
+ # comment), 0 (missed), or >= 1 (times executed).
954
+ class Line
955
+ attr_reader src: String
956
+ attr_reader line_number: Integer
957
+ attr_reader coverage: Integer?
958
+ attr_reader skipped: bool
959
+
960
+ alias source src
961
+ alias line line_number
962
+ alias number line_number
963
+
964
+ # Raises ArgumentError unless src is a String, line_number an
965
+ # Integer, and coverage an Integer or nil.
966
+ def initialize: (String src, Integer line_number, Integer? coverage) -> void
967
+
968
+ def missed?: () -> bool
969
+ def covered?: () -> bool
970
+ def never?: () -> bool
971
+ def skipped!: () -> void
972
+ def skipped?: () -> bool
973
+ # "covered", "missed", "skipped", or "never" — useful e.g. as a css class.
974
+ def status: () -> String?
975
+ end
976
+ end
977
+ end
978
+
979
+ # ----- source_file/branch -----
980
+
981
+ module SimpleCov
982
+ class SourceFile
983
+ # A single branch detected in the coverage data.
984
+ class Branch
985
+ attr_reader start_line: Integer
986
+ attr_reader end_line: Integer
987
+ attr_reader coverage: Integer
988
+ # Branch arm type as reported by Coverage (:then, :else, :when, ...).
989
+ attr_reader type: Symbol
990
+
991
+ @inline: bool
992
+ @skipped: bool
993
+
994
+ def initialize: (start_line: Integer, end_line: Integer, coverage: Integer, inline: bool, type: Symbol) -> void
995
+
996
+ def inline?: () -> bool
997
+ def covered?: () -> bool
998
+ def missed?: () -> bool
999
+ # The line the branch is reported on: its own start line when
1000
+ # inline, otherwise the line above (the if/else itself).
1001
+ def report_line: () -> Integer
1002
+ def skipped!: () -> void
1003
+ def skipped?: () -> bool
1004
+ def overlaps_with?: (Range[Integer] line_range) -> bool
1005
+ # [branch type, hit count]
1006
+ def report: () -> [ Symbol, Integer ]
1007
+ end
1008
+ end
1009
+ end
1010
+
1011
+ # ----- source_file/method -----
1012
+
1013
+ module SimpleCov
1014
+ class SourceFile
1015
+ # A single method detected in the coverage data.
1016
+ class Method
1017
+ attr_reader source_file: SourceFile
1018
+ attr_reader coverage: Integer
1019
+ # A Module when the data comes straight from Coverage, a String
1020
+ # after a JSON round-trip through a resultset.
1021
+ attr_reader class_name: Module | String
1022
+ attr_reader method_name: Symbol | String
1023
+ attr_reader start_line: Integer?
1024
+ attr_reader start_col: Integer?
1025
+ attr_reader end_line: Integer?
1026
+ attr_reader end_col: Integer?
1027
+
1028
+ @skipped: bool
1029
+ @lines: Array[Line]?
1030
+
1031
+ # info is the Coverage method key minus its class entry:
1032
+ # [class_name, method_name, start_line, start_col, end_line, end_col].
1033
+ def initialize: (SourceFile source_file, [ Module | String, Symbol | String, Integer?, Integer?, Integer?, Integer? ] info, Integer coverage) -> void
1034
+
1035
+ def covered?: () -> bool
1036
+ def skipped?: () -> bool
1037
+ def skipped!: () -> void
1038
+ def missed?: () -> bool
1039
+ # The source lines spanned by this method ([] when the location is unknown).
1040
+ def lines: () -> Array[Line]
1041
+ def overlaps_with?: (Range[Integer] line_range) -> bool
1042
+ def to_s: () -> String
1043
+ end
1044
+ end
1045
+ end
1046
+
1047
+ # ----- source_file/statistics -----
1048
+
1049
+ module SimpleCov
1050
+ class SourceFile
1051
+ # Builds the CoverageStatistics triple (:line/:branch/:method) for a
1052
+ # SourceFile; disabled or empty criteria collapse to 0/0/0.
1053
+ class Statistics
1054
+ @source_file: SourceFile
1055
+
1056
+ def initialize: (SourceFile source_file) -> void
1057
+
1058
+ def call: () -> Hash[criterion, CoverageStatistics]
1059
+
1060
+ private
1061
+
1062
+ def line_statistics: () -> Hash[criterion, CoverageStatistics]
1063
+
1064
+ def branch_statistics: () -> Hash[criterion, CoverageStatistics]
1065
+
1066
+ def method_statistics: () -> Hash[criterion, CoverageStatistics]
1067
+ end
1068
+ end
1069
+ end
1070
+
1071
+ # ----- source_file/builder_context -----
1072
+
1073
+ module SimpleCov
1074
+ class SourceFile
1075
+ # Helpers shared by the per-criterion builders (LineBuilder /
1076
+ # BranchBuilder / MethodBuilder). Mixed into SourceFile so each
1077
+ # builder can ask the file for its skip-chunk ranges and Prism-derived
1078
+ # real source positions without duplicating the memoization.
1079
+ module BuilderContext
1080
+ # Positions extracted from the parsed source: branch start lines,
1081
+ # and [method name, line] pairs. Method names are Symbols from
1082
+ # runtime data and Strings after a JSON round-trip.
1083
+ type real_positions = { branches: Set[Integer], methods: Set[[untyped, Integer]] }
1084
+
1085
+ @skip_chunks: SkipChunks?
1086
+ @real_source_positions: real_positions?
1087
+
1088
+ # Skip-chunk lookup for the named criterion (`:line`, `:branch`,
1089
+ # `:method`).
1090
+ def skip_chunks_for: (criterion) -> Array[Range[Integer]]
1091
+
1092
+ # Memoized set of real source positions extracted via Prism. Returns
1093
+ # nil when Prism is unavailable or parsing fails, signaling callers
1094
+ # to keep every Coverage entry (no false drops). The `defined?`
1095
+ # guard preserves a nil memoization across calls.
1096
+ def real_source_positions: () -> real_positions?
1097
+
1098
+ # Provided by the including class (SourceFile).
1099
+ def filename: () -> String
1100
+ def src: () -> Array[String]
1101
+ end
1102
+ end
1103
+ end
1104
+
1105
+ # ----- coverage_statistics -----
1106
+
1107
+ module SimpleCov
1108
+ # Uniform per-criterion coverage statistics. Counts are Integers;
1109
+ # percent and strength are Floats. `percent` is 100.0 whenever nothing
1110
+ # was missed, including the 0-of-0 case; `strength` is 0.0 when there
1111
+ # is nothing to cover.
1112
+ class CoverageStatistics
1113
+ # Seed for the reduce in .from: covered, missed, omitted, strength.
1114
+ ZERO_STATS: [Integer, Integer, Integer, Float]
1115
+
1116
+ attr_reader total: Integer
1117
+ attr_reader covered: Integer
1118
+ attr_reader missed: Integer
1119
+ attr_reader omitted: Integer
1120
+ attr_reader strength: Float
1121
+ attr_reader percent: Float
1122
+
1123
+ def self.from: (Array[CoverageStatistics] coverage_statistics) -> CoverageStatistics
1124
+
1125
+ # `percent:` overrides the computed percentage (used to report 0%
1126
+ # for tracked-but-never-loaded files).
1127
+ def initialize: (covered: Integer, missed: Integer, ?omitted: Integer, ?total_strength: Integer | Float, ?percent: Float?) -> void
1128
+
1129
+ private
1130
+
1131
+ def compute_percent: (Integer covered, Integer missed, Integer total) -> Float
1132
+ def compute_strength: (Integer | Float total_strength, Integer total) -> Float
1133
+ end
1134
+ end
1135
+
1136
+ # ----- last_run -----
1137
+
1138
+ module SimpleCov
1139
+ # Reads and writes coverage/.last_run.json — the previous run's
1140
+ # coverage percentages used by MaximumCoverageDropCheck.
1141
+ module LastRun
1142
+ def self.last_run_path: () -> String
1143
+
1144
+ # nil when the file does not exist or is blank. Keys are symbolized.
1145
+ def self.read: () -> Hash[Symbol, untyped]?
1146
+
1147
+ def self.write: (Hash[Symbol, untyped] json) -> void
1148
+ end
1149
+ end
1150
+
1151
+ # ----- filter -----
1152
+
1153
+ module SimpleCov
1154
+ # Base filter class. Inherit and override `matches?` to create custom
1155
+ # filters. `T` is the type of the configured filter argument.
1156
+ class Filter[T]
1157
+ attr_reader filter_argument: T
1158
+
1159
+ def initialize: (T filter_argument) -> void
1160
+
1161
+ # The base implementation raises NotImplementedError.
1162
+ def matches?: (SourceFile source_file) -> boolish
1163
+
1164
+ def self.build_filter: (filter_arg filter_argument) -> Filter[untyped]
1165
+
1166
+ def self.class_for_argument: (filter_arg filter_argument) -> singleton(Filter)
1167
+
1168
+ # Maps raw filter-argument classes (String, Regexp, Array, Proc) to
1169
+ # the Filter subclass that handles them. Private class method.
1170
+ self.@filter_classes_by_argument_type: Hash[Class, singleton(Filter)]?
1171
+
1172
+ def self.filter_classes_by_argument_type: () -> Hash[Class, singleton(Filter)]
1173
+ end
1174
+
1175
+ # Matches when the project path contains the configured string at a
1176
+ # path-segment boundary ("lib" matches "lib/foo.rb" but not "library/").
1177
+ class StringFilter < Filter[String]
1178
+ def matches?: (SourceFile source_file) -> bool
1179
+
1180
+ private
1181
+
1182
+ @segment_pattern: Regexp?
1183
+
1184
+ def segment_pattern: () -> Regexp
1185
+
1186
+ def compute_segment_pattern: () -> Regexp
1187
+ end
1188
+
1189
+ # Matches when the project path matches the configured Regexp.
1190
+ class RegexFilter < Filter[Regexp]
1191
+ def matches?: (SourceFile source_file) -> bool
1192
+ end
1193
+
1194
+ # Matches when the configured block returns truthy for the source file.
1195
+ class BlockFilter < Filter[^(SourceFile) -> boolish]
1196
+ def matches?: (SourceFile source_file) -> boolish
1197
+ end
1198
+
1199
+ # Matches when the project path matches the configured shell glob
1200
+ # (e.g. "lib/**/*.rb").
1201
+ class GlobFilter < Filter[String]
1202
+ def matches?: (SourceFile source_file) -> bool
1203
+ end
1204
+
1205
+ # Matches when any of the component filters built from the array's
1206
+ # elements match. Note: `filter_argument` holds the built Filter
1207
+ # objects, not the raw array passed to `new`.
1208
+ class ArrayFilter < Filter[Array[Filter[untyped]]]
1209
+ def initialize: (Array[filter_arg] filter_argument) -> void
1210
+
1211
+ def matches?: (SourceFile source_file) -> boolish
1212
+ end
1213
+ end
1214
+
1215
+ # ----- formatter -----
1216
+
1217
+ module SimpleCov
1218
+ # Namespace for result formatters. A formatter is any class whose
1219
+ # instances respond to `#format(result)` and that can be instantiated
1220
+ # with no arguments; wire one up via `SimpleCov.formatter=` or
1221
+ # `SimpleCov.formatters=`.
1222
+ module Formatter
1223
+ # Structural interface for custom formatter instances.
1224
+ interface _Formatter
1225
+ def format: (SimpleCov::Result result) -> untyped
1226
+ end
1227
+ end
1228
+ end
1229
+
1230
+ # ----- formatter/base -----
1231
+
1232
+ module SimpleCov
1233
+ module Formatter
1234
+ # @api private — shared scaffolding for formatters that write a
1235
+ # report to an output directory and emit the "Coverage report
1236
+ # generated for X to Y" status line on stderr. Subclasses implement
1237
+ # `format`.
1238
+ class Base
1239
+ @silent: bool
1240
+ @output_dir: String?
1241
+
1242
+ # `output_dir` defaults to `SimpleCov.coverage_path` when nil.
1243
+ def initialize: (?silent: bool, ?output_dir: String?) -> void
1244
+
1245
+ private
1246
+
1247
+ # Subclasses prepend a marker (e.g. "JSON ") to the summary line.
1248
+ def message_prefix: () -> String
1249
+
1250
+ def output_path: () -> String
1251
+
1252
+ # Directory (relative to cwd when inside it) plus the subclass's
1253
+ # `entry_point_filename`, for the status line. See issue #197.
1254
+ def displayable_output_path: () -> String
1255
+
1256
+ def relative_or_absolute_output_path: () -> String
1257
+
1258
+ # Subclasses name the report's entry-point file (`index.html`,
1259
+ # `coverage.json`); nil leaves the bare directory in the status line.
1260
+ def entry_point_filename: () -> String?
1261
+
1262
+ def output_message: (SimpleCov::Result result) -> String
1263
+
1264
+ # nil for branch/method criteria with nothing to measure, so the
1265
+ # summary doesn't print "Branch coverage: 0 / 0 (100.00%)" noise.
1266
+ def stats_line: (Symbol criterion, SimpleCov::CoverageStatistics stat) -> String?
1267
+ end
1268
+ end
1269
+ end
1270
+
1271
+ # ----- formatter/simple_formatter -----
1272
+
1273
+ module SimpleCov
1274
+ module Formatter
1275
+ # Renders the result as a plain-text string, one section per group.
1276
+ # Returns the string; does not write anything to disk.
1277
+ class SimpleFormatter
1278
+ def format: (SimpleCov::Result result) -> String
1279
+
1280
+ private
1281
+
1282
+ def format_group: (String name, SimpleCov::FileList files) -> String
1283
+ end
1284
+ end
1285
+ end
1286
+
1287
+ # ----- formatter/multi_formatter -----
1288
+
1289
+ module SimpleCov
1290
+ module Formatter
1291
+ # Wraps multiple formatters so one configured formatter can drive
1292
+ # several output formats (HTML + JSON, etc.) in a single run.
1293
+ class MultiFormatter
1294
+ # Shared `#format` implementation, included into the anonymous
1295
+ # classes that `MultiFormatter.new` builds. Formatter errors are
1296
+ # rescued and mapped to nil, so the result array can hold nils.
1297
+ module InstanceMethods
1298
+ def format: (SimpleCov::Result result) -> Array[untyped]
1299
+
1300
+ # Defined via `define_method` on each class `MultiFormatter.new`
1301
+ # builds; declared here so users of those classes type-check.
1302
+ def formatters: () -> Array[untyped]
1303
+ end
1304
+
1305
+ # Returns a newly built Class (not a MultiFormatter instance) whose
1306
+ # instances respond to `#format` and `#formatters`. The argument is
1307
+ # normalized with `Array()`: a single formatter, an array of
1308
+ # formatters, or nil are all accepted.
1309
+ def self.new: (?untyped formatters) -> Class
1310
+ end
1311
+ end
1312
+ end
1313
+
1314
+ # ----- formatter/html_formatter -----
1315
+
1316
+ module SimpleCov
1317
+ module Formatter
1318
+ # Writes the HTML report: coverage_data.js plus pre-compiled static
1319
+ # assets, and coverage.json as a side artifact (shared serialization
1320
+ # via JSONFormatter.build_hash).
1321
+ class HTMLFormatter < Base
1322
+ DATA_FILENAME: "coverage_data.js"
1323
+
1324
+ def format: (SimpleCov::Result result) -> void
1325
+
1326
+ # Generate HTML from a pre-existing coverage.json file without a
1327
+ # live SimpleCov::Result or a running test suite.
1328
+ def format_from_json: (String json_path, String output_dir) -> void
1329
+
1330
+ private
1331
+
1332
+ def entry_point_filename: () -> String
1333
+
1334
+ def copy_static_assets: (?String dest_dir) -> void
1335
+
1336
+ # Write via temp file + File.rename so parallel writers can't race
1337
+ # and read-only existing assets are replaced without EACCES.
1338
+ def atomic_write: (String dest, String content) -> void
1339
+
1340
+ def public_dir: () -> String
1341
+ end
1342
+ end
1343
+ end
1344
+
1345
+ # ----- formatter/json_formatter -----
1346
+
1347
+ module SimpleCov
1348
+ module Formatter
1349
+ # Writes coverage results as JSON to coverage/coverage.json.
1350
+ class JSONFormatter < Base
1351
+ FILENAME: "coverage.json"
1352
+
1353
+ # The hash serialized to coverage.json ($schema, meta, total,
1354
+ # coverage, groups, errors). `include_source:` defaults to
1355
+ # `SimpleCov.source_in_json`; pass true to force the per-file
1356
+ # source arrays regardless of the global setting.
1357
+ def self.build_hash: (SimpleCov::Result result, ?include_source: bool) -> Hash[Symbol, untyped]
1358
+
1359
+ def format: (SimpleCov::Result result) -> void
1360
+
1361
+ private
1362
+
1363
+ def message_prefix: () -> String
1364
+
1365
+ def entry_point_filename: () -> String
1366
+
1367
+ # Warns when an existing coverage.json is newer than this process's
1368
+ # start time (a concurrent sibling writer). See issue #1171.
1369
+ def warn_if_concurrent_overwrite: (String path, SimpleCov::Result result) -> void
1370
+
1371
+ # timestamp stays untyped (not Time) so the comparison sites don't
1372
+ # require the stdlib `time` extension sigs; the value is produced by
1373
+ # Time.iso8601 at runtime.
1374
+ def existing_meta: (String path) -> ({ timestamp: untyped, command_name: untyped })?
1375
+ end
1376
+ end
1377
+ end
1378
+
1379
+ # ----- exit_codes -----
1380
+
1381
+ module SimpleCov
1382
+ # Exit codes SimpleCov uses when a coverage check fails.
1383
+ module ExitCodes
1384
+ SUCCESS: 0
1385
+
1386
+ EXCEPTION: 1
1387
+
1388
+ MINIMUM_COVERAGE: 2
1389
+
1390
+ MAXIMUM_COVERAGE_DROP: 3
1391
+
1392
+ MAXIMUM_COVERAGE: 4
1393
+
1394
+ # Threshold-violation reports and exit-status notices: enforcement
1395
+ # output on stderr, deliberately not routed through Kernel#warn.
1396
+ def self.print_error: (String message) -> void
1397
+ end
1398
+ end
1399
+
1400
+ # ----- exit_codes/exit_code_handling -----
1401
+
1402
+ module SimpleCov
1403
+ module ExitCodes
1404
+ # The threshold-limit readers ExitCodeHandling consults. Satisfied by
1405
+ # SimpleCov's own configuration, or by any object exposing the same
1406
+ # readers (see the dogfood check in spec/helper.rb for an example
1407
+ # built from a plain Data class).
1408
+ interface _CoverageLimits
1409
+ def minimum_coverage: () -> Hash[Symbol, Numeric]
1410
+
1411
+ def minimum_coverage_by_file: () -> Hash[Symbol, Numeric]
1412
+
1413
+ def minimum_coverage_by_file_overrides: () -> untyped
1414
+
1415
+ def minimum_coverage_by_group: () -> untyped
1416
+
1417
+ def maximum_coverage: () -> Hash[Symbol, Numeric]
1418
+
1419
+ def maximum_coverage_drop: () -> Hash[Symbol, Numeric]
1420
+ end
1421
+
1422
+ # Runs every coverage check against the result and returns the exit
1423
+ # code of the first failing one, or SUCCESS when all pass.
1424
+ module ExitCodeHandling
1425
+ def self?.call: (SimpleCov::Result result, coverage_limits: _CoverageLimits) -> Integer
1426
+
1427
+ def self?.coverage_checks: (SimpleCov::Result result, _CoverageLimits coverage_limits) -> Array[untyped]
1428
+ end
1429
+ end
1430
+ end
1431
+
1432
+ # ----- profiles -----
1433
+
1434
+ module SimpleCov
1435
+ # Registry of named configuration procs, loadable via
1436
+ # `SimpleCov.start :rails` and definable via
1437
+ # `SimpleCov.profiles.define(:foo) { ... }`. The stored blocks are
1438
+ # evaluated through `SimpleCov.configure`, so they self-bind to the
1439
+ # configuration DSL.
1440
+ # A stored profile block. The self-type is untyped because the block
1441
+ # is written against the configuration DSL but stored as a plain Proc;
1442
+ # it self-binds when SimpleCov.configure evaluates it.
1443
+ type profile_proc = ^() [self: untyped] -> void
1444
+
1445
+ class Profiles < Hash[Symbol, profile_proc]
1446
+ # Raises SimpleCov::ConfigurationError when the name is taken.
1447
+ # The block runs via instance_exec against the SimpleCov module itself
1448
+ # (which extends Configuration), not a Configuration instance.
1449
+ def define: (Symbol | String name) { () [self: singleton(SimpleCov)] -> void } -> profile_proc
1450
+
1451
+ # Applies the named profile via SimpleCov.configure.
1452
+ def load: (Symbol | String name) -> void
1453
+
1454
+ # Returns the proc for the given profile name, autoloading bundled
1455
+ # ("simplecov/profiles/<name>") or plugin-gem
1456
+ # ("simplecov-profile-<name>") profiles on first lookup. Raises
1457
+ # SimpleCov::ConfigurationError when none is found.
1458
+ def fetch_proc: (Symbol | String name) -> profile_proc
1459
+
1460
+ private
1461
+
1462
+ # Tries `require "simplecov/profiles/<name>"`, then
1463
+ # `require "simplecov-profile-<name>"`; swallows LoadError so
1464
+ # fetch_proc raises the user-facing error.
1465
+ def autoload_profile: (Symbol name) -> void
1466
+ end
1467
+ end
1468
+
1469
+ # ----- parallel_adapters -----
1470
+
1471
+ module SimpleCov
1472
+ # Registry + selection for parallel-test-runner adapters. An adapter is
1473
+ # a class (used as a singleton, never instantiated) answering the
1474
+ # `_Adapter` contract; subclass `ParallelAdapters::Base` to inherit
1475
+ # no-op defaults. Register custom adapters via
1476
+ # `SimpleCov::ParallelAdapters.register MyRunnerAdapter`.
1477
+ module ParallelAdapters
1478
+ # The class-level contract an adapter must answer. `singleton(Base)`
1479
+ # and its subclasses satisfy this structurally.
1480
+ interface _Adapter
1481
+ def active?: () -> boolish
1482
+
1483
+ def first_worker?: () -> bool
1484
+
1485
+ def wait_for_siblings: () -> void
1486
+
1487
+ def native_wait?: () -> boolish
1488
+
1489
+ def expected_worker_count: () -> Integer
1490
+ end
1491
+
1492
+ # Registry state. Declared on both the instance and singleton sides
1493
+ # because `module_function` bodies type-check as instance methods
1494
+ # while runtime state lives on the module itself.
1495
+ @adapters: Array[_Adapter]?
1496
+
1497
+ self.@adapters: Array[_Adapter]?
1498
+
1499
+ # Memoized current adapter. Distinguishes "not yet computed" (ivar
1500
+ # undefined) from "computed, no adapter active" (nil), hence the
1501
+ # `defined?` guard in the implementation.
1502
+ @current: _Adapter?
1503
+
1504
+ self.@current: _Adapter?
1505
+
1506
+ # Adapters in selection order: user-registered adapters first, then
1507
+ # ParallelTestsAdapter, then GenericAdapter.
1508
+ def self?.adapters: () -> Array[_Adapter]
1509
+
1510
+ # Registers a custom adapter at the front of the selection list and
1511
+ # returns it. Clears the memoized `current` selection.
1512
+ def self?.register: (_Adapter adapter) -> _Adapter
1513
+
1514
+ # The first registered adapter whose `active?` returns true, or nil
1515
+ # when no recognized parallel runner is active (single-worker run).
1516
+ def self?.current: () -> _Adapter?
1517
+
1518
+ # Clears the memoized `current` selection (primarily for tests that
1519
+ # mutate env vars between examples).
1520
+ def self?.reset_current!: () -> void
1521
+ end
1522
+ end
1523
+
1524
+ # ----- parallel_adapters/base -----
1525
+
1526
+ module SimpleCov
1527
+ module ParallelAdapters
1528
+ # No-op defaults for a parallel-test-runner adapter: behave like a
1529
+ # single-process run. Real adapters subclass and override what they
1530
+ # need. The contract methods are class methods; adapters are never
1531
+ # instantiated.
1532
+ class Base
1533
+ # Should this adapter be selected for the current process? The
1534
+ # first registered adapter whose `active?` returns truthy wins.
1535
+ def self.active?: () -> boolish
1536
+
1537
+ # Should THIS worker do the final-result work (wait for siblings,
1538
+ # merge resultsets, run threshold checks, format the report)?
1539
+ # Defaults to true for the single-process case.
1540
+ def self.first_worker?: () -> bool
1541
+
1542
+ # Optional: block until sibling workers have finished writing
1543
+ # their resultsets. The no-op default leaves synchronization to
1544
+ # SimpleCov's resultset polling fallback.
1545
+ def self.wait_for_siblings: () -> void
1546
+
1547
+ # Does `wait_for_siblings` block until every sibling process has
1548
+ # exited? When true, a settled resultset count below
1549
+ # `expected_worker_count` is accepted as final.
1550
+ def self.native_wait?: () -> boolish
1551
+
1552
+ # How many parallel workers participate in this run. Defaults to 1.
1553
+ def self.expected_worker_count: () -> Integer
1554
+ end
1555
+ end
1556
+ end
1557
+
1558
+ # ----- parallel_adapters/generic -----
1559
+
1560
+ module SimpleCov
1561
+ module ParallelAdapters
1562
+ # Catch-all adapter for runners that follow the `TEST_ENV_NUMBER` /
1563
+ # `PARALLEL_TEST_GROUPS` env-var convention without shipping a Ruby
1564
+ # API (parallel_rspec, knapsack-style splitters, custom CI sharding).
1565
+ # Activates when `TEST_ENV_NUMBER` is set, unless
1566
+ # `SimpleCov.parallel_tests false` opted out.
1567
+ class GenericAdapter < Base
1568
+ def self.active?: () -> bool
1569
+
1570
+ # First worker is TEST_ENV_NUMBER "" (parallel_tests convention)
1571
+ # or "1" (runners that number from 1).
1572
+ def self.first_worker?: () -> bool
1573
+
1574
+ def self.expected_worker_count: () -> Integer
1575
+ end
1576
+ end
1577
+ end
1578
+
1579
+ # ----- parallel_adapters/parallel_tests -----
1580
+
1581
+ module SimpleCov
1582
+ module ParallelAdapters
1583
+ # Adapter for grosser/parallel_tests. Requires the full native
1584
+ # coordination contract (ParallelTests constant loaded,
1585
+ # TEST_ENV_NUMBER and PARALLEL_PID_FILE set); env-var-only setups
1586
+ # fall through to GenericAdapter.
1587
+ class ParallelTestsAdapter < Base
1588
+ def self.active?: () -> bool
1589
+
1590
+ # Delegates to ParallelTests.first_process? (the first started
1591
+ # process does the final-result work; see issue #922).
1592
+ def self.first_worker?: () -> bool
1593
+
1594
+ # Uses ParallelTests.wait_for_other_processes_to_finish when the
1595
+ # pid-file contract is present.
1596
+ def self.wait_for_siblings: () -> void
1597
+
1598
+ def self.native_wait?: () -> bool
1599
+
1600
+ def self.expected_worker_count: () -> Integer
1601
+
1602
+ # Auto-requires parallel_tests when installed and the env vars it
1603
+ # sets are present; a missing gem is treated as "not using
1604
+ # parallel_tests" (see issue #1018).
1605
+ def self.ensure_loaded: () -> void
1606
+
1607
+ def self.env_suggests_parallel_tests?: () -> bool
1608
+
1609
+ def self.native_parallel_tests_environment?: () -> bool
1610
+ end
1611
+ end
1612
+ end
1613
+
1614
+ # ----- deprecation -----
1615
+
1616
+ module SimpleCov
1617
+ # Emits legacy-API deprecation warnings, deduplicated by the source
1618
+ # location that triggered them (see issue #1204).
1619
+ module Deprecation
1620
+ # Warns about a deprecated API at most once per call-site location.
1621
+ # `message` is the notice without the `[DEPRECATION]` tag or location
1622
+ # prefix; `location` defaults to the caller of the deprecated method.
1623
+ def self?.warn: (String message, ?location: String?) -> void
1624
+
1625
+ # Dedup keys (locations, or messages when no backtrace is available)
1626
+ # already emitted by this process. Declared on both the instance and
1627
+ # singleton sides because `module_function` bodies type-check as
1628
+ # instance methods while runtime state lives on the module itself.
1629
+ @emitted: Set[String]?
1630
+
1631
+ self.@emitted: Set[String]?
1632
+
1633
+ def self?.emitted: () -> Set[String]
1634
+
1635
+ # @api private — reset emitted state between tests.
1636
+ def self?.reset!: () -> void
1637
+ end
1638
+ end