single_cov 1.10.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8d35277b97cbcabd001c11de169153d1eda320dfcfbd7ad516406ee811e623eb
4
- data.tar.gz: c5d9fb7c34b7cb1a67a772a8ce870dbfc40cc6b1ae9ee859a951bbc3cbf93120
3
+ metadata.gz: e47ea219fd0ed2b3d8911ca9679c4de43988ba900072e7a3efe349275d230f8b
4
+ data.tar.gz: 24410aaf39a37f4301723bc53b76cbccfeb596ceed364a4ebe4dfbdde54a3556
5
5
  SHA512:
6
- metadata.gz: 64b8de808afd738fae4817c0701c12905882a4122ac50b53cc3e13694f78a831bcbaa433a7e45115682ef3ea2beefd7b59d2442872ad2ce11a82999007e3c6c7
7
- data.tar.gz: 7637465f16cadc6a8beec088abd9fff899a3d9052617dd9c89d786ee24e565cb6fa8a8508a69407d63c013088aa11a3b765ac152198fc395460a490536525295
6
+ metadata.gz: 0dd92b86bfa607cfb908cfaa7fc2a5b8e74da99a92d6a116cc88dbf2b241cc27664c027814989cb6e7d180bed5d7dff65e181c76cb71181340e0d947d7a0d183
7
+ data.tar.gz: c42f4b53dfc9e16cb72b57e8180cf81c9cad57dbf1be0f549ceb480e16dd31d7030130dfca58e731dc3398ff61a82d05eeafb9b5fa2a7b905dd43ca6ab60bfa4
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module SingleCov
3
- VERSION = "1.10.0"
3
+ VERSION = "2.0.0"
4
4
  end
data/lib/single_cov.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  module SingleCov
3
3
  COVERAGES = []
4
- MAX_OUTPUT = 40
4
+ MAX_OUTPUT = Integer(ENV["SINGLE_COV_MAX_OUTPUT"] || "40")
5
5
  RAILS_APP_FOLDERS = ["models", "serializers", "helpers", "controllers", "mailers", "views", "jobs", "channels"]
6
6
  UNCOVERED_COMMENT_MARKER = /#.*uncovered/
7
7
  PREFIXES_TO_IGNORE = [] # things to not prefix with lib/ etc
@@ -32,7 +32,7 @@ module SingleCov
32
32
 
33
33
  def all_covered?(result)
34
34
  errors = COVERAGES.flat_map do |file, expected_uncovered|
35
- next no_coverage_error(file) unless coverage = result["#{root}/#{file}"]
35
+ next no_coverage_error(file) unless (coverage = result["#{root}/#{file}"])
36
36
 
37
37
  uncovered = uncovered(coverage)
38
38
  next if uncovered.size == expected_uncovered
@@ -50,7 +50,9 @@ module SingleCov
50
50
 
51
51
  return true if errors.empty?
52
52
 
53
- errors[MAX_OUTPUT..-1] = "... coverage output truncated" if errors.size >= MAX_OUTPUT
53
+ if errors.size >= MAX_OUTPUT
54
+ errors[MAX_OUTPUT..-1] = "... coverage output truncated (use SINGLE_COV_MAX_OUTPUT=999 to expand)"
55
+ end
54
56
  @error_logger.puts errors
55
57
 
56
58
  errors.all? { |l| warning?(l) }
@@ -117,8 +119,7 @@ module SingleCov
117
119
 
118
120
  case framework
119
121
  when :minitest
120
- minitest_should_not_be_running!
121
- return if minitest_running_subset_of_tests?
122
+ return if minitest_running_subset_of_tests?(ARGV)
122
123
  when :rspec
123
124
  return if rspec_running_subset_of_tests?
124
125
  else
@@ -127,15 +128,35 @@ module SingleCov
127
128
 
128
129
  start_coverage_recording
129
130
 
130
- override_at_exit do |status, _exception|
131
- if enabled? && main_process? && status == 0
132
- results = coverage_results
133
- generate_report results
134
- exit 1 unless SingleCov.all_covered?(results)
131
+ # minitest overrides at_exit, so we need to get into it to execute after it finishes
132
+ # so when using the `minitest` executable or loading minitest before SingleCov the first branch is used
133
+ if defined?(Minitest)
134
+ (class << Minitest; self; end).prepend(Module.new do
135
+ def run(args = [])
136
+ original_args = args.dup # minitest modified them
137
+ result = super
138
+ if result && !SingleCov.send(:minitest_running_subset_of_tests?, original_args)
139
+ return SingleCov.report_at_exit
140
+ end
141
+ result
142
+ end
143
+ end)
144
+ else
145
+ override_at_exit do |status, _exception|
146
+ if main_process? && status == 0 && !report_at_exit
147
+ exit 1
148
+ end
135
149
  end
136
150
  end
137
151
  end
138
152
 
153
+ def report_at_exit
154
+ return unless enabled?
155
+ results = coverage_results
156
+ generate_report results
157
+ SingleCov.all_covered?(results)
158
+ end
159
+
139
160
  # use this in forks when using rspec to silence duplicated output
140
161
  def disable
141
162
  @disabled = true
@@ -157,7 +178,7 @@ module SingleCov
157
178
  end
158
179
 
159
180
  def enabled?
160
- (!defined?(@disabled) || !@disabled)
181
+ !defined?(@disabled) || !@disabled
161
182
  end
162
183
 
163
184
  # assuming that the main process will load all the files, we store it's pid
@@ -166,7 +187,7 @@ module SingleCov
166
187
  end
167
188
 
168
189
  def main_process?
169
- (!defined?(@main_process_pid) || @main_process_pid == Process.pid)
190
+ !defined?(@main_process_pid) || @main_process_pid == Process.pid
170
191
  end
171
192
 
172
193
  # {[branch_id] => {[branch_part] => coverage}} --> uncovered location
@@ -228,56 +249,26 @@ module SingleCov
228
249
  COVERAGES.size == 1
229
250
  end
230
251
 
231
- # we cannot insert our hooks when minitest is already running
232
- def minitest_should_not_be_running!
233
- return unless defined?(Minitest)
234
- return unless Minitest.class_variable_defined?(:@@installed_at_exit)
235
- return unless Minitest.class_variable_get(:@@installed_at_exit)
236
-
237
- # untested
238
- # https://github.com/rails/rails/pull/26515 rails loads autorun before test
239
- # but it works out for some reason
240
- return if Minitest.extensions.include?('rails')
241
-
242
- # untested
243
- # forking test runner does some hacky acrobatics to fake minitest status
244
- # and the resets it ... works out ok in the end ...
245
- return if faked_by_forking_test_runner?
246
-
247
- # ... but only if it's used with `--merge-coverage` otherwise the coverage reporting is useless
248
- if $0.end_with?("/forking-test-runner")
249
- raise "forking-test-runner only work with single_cov when using --merge-coverage"
250
- end
251
-
252
- raise "Load minitest after setting up SingleCov"
253
- end
254
-
255
- # ForkingTestRunner fakes an initialized minitest to avoid multiple hooks being installed
256
- # so hooks still get added in order https://github.com/grosser/forking_test_runner/pull/4
257
- def faked_by_forking_test_runner?
258
- defined?(Coverage) && Coverage.respond_to?(:capture_coverage!)
259
- end
260
-
261
252
  # do not record or verify when only running selected tests since it would be missing data
262
- def minitest_running_subset_of_tests?
253
+ def minitest_running_subset_of_tests?(argv)
263
254
  # via direct option (ruby test.rb -n /foo/)
264
- (ARGV.map { |a| a.split('=', 2).first } & ['-n', '--name', '-l', '--line']).any? ||
255
+ # or `minitest foo.rb:123` which is translated to -n
256
+ argv.map { |a| a.split('=', 2).first }.intersect?(['-n', '--name', '-l', '--line']) ||
265
257
 
266
- # via testrbl or mtest or rails with direct line number (mtest test.rb:123)
267
- (ARGV.first =~ /:\d+\Z/) ||
258
+ # via testrbl, mtest, or rails with direct line number (mtest test.rb:123)
259
+ (argv.first =~ /:\d+\Z/) ||
268
260
 
269
261
  # via rails test which preloads mintest, removes ARGV and fills options
270
262
  (
271
- defined?(Minitest) &&
272
263
  defined?(Minitest.reporter) &&
273
264
  Minitest.reporter &&
274
265
  (reporter = Minitest.reporter.reporters.first) &&
275
- reporter.options[:filter]
266
+ (reporter.options[:filter] || reporter.options[:include]) # MT 5 vs MT 6
276
267
  )
277
268
  end
278
269
 
279
270
  def rspec_running_subset_of_tests?
280
- (ARGV & ['-t', '--tag', '-e', '--example']).any? || ARGV.any? { |a| a =~ /:\d+$|\[[\d:]+\]$/ }
271
+ ARGV.intersect?(['-t', '--tag', '-e', '--example']) || ARGV.any? { |a| a =~ /:\d+$|\[[\d:]+\]$/ }
281
272
  end
282
273
 
283
274
  # code stolen from SimpleCov
@@ -398,7 +389,7 @@ module SingleCov
398
389
  end
399
390
 
400
391
  # remove test extension
401
- if !file_part.sub!(/_(?:test|spec)\.rb\b.*/, '.rb') && !file_part.sub!(/\/test_/, "/")
392
+ if !file_part.sub!(/_(?:test|spec)\.rb\b.*/, '.rb') && !file_part.sub!('/test_', "/")
402
393
  raise "Unable to remove test extension from #{file} ... /test_, _test.rb and _spec.rb are supported"
403
394
  end
404
395
  end
@@ -416,14 +407,14 @@ module SingleCov
416
407
  end
417
408
 
418
409
  def generate_report(results)
419
- return unless report = coverage_report
410
+ return unless (report = coverage_report)
420
411
 
421
412
  # not a hard dependency for the whole library
422
413
  require "json"
423
414
  require "fileutils"
424
415
 
425
416
  used = COVERAGES.map { |f, _| "#{root}/#{f}" }
426
- covered = results.select { |k, _| used.include?(k) }
417
+ covered = results.slice(*used)
427
418
 
428
419
  if coverage_report_lines
429
420
  covered = covered.transform_values { |v| v.is_a?(Hash) ? v.fetch(:lines) : v }
metadata CHANGED
@@ -1,16 +1,98 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: single_cov
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.10.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Grosser
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2023-05-20 00:00:00.000000000 Z
12
- dependencies: []
13
- description:
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: bump
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0'
19
+ type: :development
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: minitest
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: rake
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: rspec
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: rubocop
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ - !ruby/object:Gem::Dependency
83
+ name: simplecov
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
14
96
  email: michael@grosser.it
15
97
  executables: []
16
98
  extensions: []
@@ -23,7 +105,6 @@ homepage: https://github.com/grosser/single_cov
23
105
  licenses:
24
106
  - MIT
25
107
  metadata: {}
26
- post_install_message:
27
108
  rdoc_options: []
28
109
  require_paths:
29
110
  - lib
@@ -31,15 +112,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
31
112
  requirements:
32
113
  - - ">="
33
114
  - !ruby/object:Gem::Version
34
- version: 2.7.0
115
+ version: 3.2.0
35
116
  required_rubygems_version: !ruby/object:Gem::Requirement
36
117
  requirements:
37
118
  - - ">="
38
119
  - !ruby/object:Gem::Version
39
120
  version: '0'
40
121
  requirements: []
41
- rubygems_version: 3.3.3
42
- signing_key:
122
+ rubygems_version: 3.6.9
43
123
  specification_version: 4
44
124
  summary: Actionable code coverage.
45
125
  test_files: []