simplecov 0.18.2 → 0.19.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.
data/CONTRIBUTING.md CHANGED
@@ -1,6 +1,6 @@
1
1
  ## Reporting Issues
2
2
 
3
- You can report issues at https://github.com/colszowka/simplecov/issues
3
+ You can report issues at https://github.com/simplecov-ruby/simplecov/issues
4
4
 
5
5
  Before you go ahead please search existing issues for your problem, chances are someone else already reported it.
6
6
 
@@ -10,7 +10,7 @@ To make sure that we can help you quickly please include and check the following
10
10
  - please ensure you are requiring and starting SimpleCov before requiring any application code.
11
11
  - If running via rake, please ensure you are requiring SimpleCov at the top of your Rakefile
12
12
  For example, if running via RSpec, this would be at the top of your spec_helper.
13
- - Have you tried using a [`.simplecov` file](https://github.com/colszowka/simplecov#using-simplecov-for-centralized-config)?
13
+ - Have you tried using a [`.simplecov` file](https://github.com/simplecov-ruby/simplecov#using-simplecov-for-centralized-config)?
14
14
  * Include the SimpleCov version you are running in your report.
15
15
  * If you are not running the latest version (please check), and you cannot update it,
16
16
  please specify in your report why you can't update to the latest version.
@@ -28,7 +28,7 @@ Thanks!
28
28
 
29
29
  To fetch & test the library for development, do:
30
30
 
31
- $ git clone https://github.com/colszowka/simplecov.git
31
+ $ git clone https://github.com/simplecov-ruby/simplecov.git
32
32
  $ cd simplecov
33
33
  $ bundle
34
34
  $ bundle exec rake
data/ISSUE_TEMPLATE.md CHANGED
@@ -8,7 +8,7 @@ To make sure that we can help you quickly please include and check the following
8
8
  - please ensure you are requiring and starting SimpleCov before requiring any application code.
9
9
  - If running via rake, please ensure you are requiring SimpleCov at the top of your Rakefile
10
10
  For example, if running via RSpec, this would be at the top of your spec_helper.
11
- - Have you tried using a [`.simplecov` file](https://github.com/colszowka/simplecov#using-simplecov-for-centralized-config)?
11
+ - Have you tried using a [`.simplecov` file](https://github.com/simplecov-ruby/simplecov#using-simplecov-for-centralized-config)?
12
12
  * Include the SimpleCov version you are running in your report.
13
13
  * If you are not running the latest version (please check), and you cannot update it,
14
14
  please specify in your report why you can't update to the latest version.
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- SimpleCov [![Gem Version](https://badge.fury.io/rb/simplecov.svg)](https://badge.fury.io/rb/simplecov) [![Build Status](https://github.com/colszowka/simplecov/workflows/stable/badge.svg?branch=master)][Continuous Integration] [![Code Climate](https://codeclimate.com/github/colszowka/simplecov.svg)](https://codeclimate.com/github/colszowka/simplecov) [![Inline docs](http://inch-ci.org/github/colszowka/simplecov.svg)](http://inch-ci.org/github/colszowka/simplecov)
1
+ SimpleCov [![Gem Version](https://badge.fury.io/rb/simplecov.svg)](https://badge.fury.io/rb/simplecov) [![Build Status](https://github.com/simplecov-ruby/simplecov/workflows/stable/badge.svg?branch=main)][Continuous Integration] [![Maintainability](https://api.codeclimate.com/v1/badges/c071d197d61953a7e482/maintainability)](https://codeclimate.com/github/simplecov-ruby/simplecov/maintainability) [![Inline docs](http://inch-ci.org/github/simplecov-ruby/simplecov.svg?branch=main)](http://inch-ci.org/github/simplecov-ruby/simplecov)
2
2
  =========
3
3
 
4
4
  **Code coverage for Ruby**
@@ -10,14 +10,14 @@ SimpleCov [![Gem Version](https://badge.fury.io/rb/simplecov.svg)](https://badge
10
10
  * [Continuous Integration]
11
11
 
12
12
  [Coverage]: https://ruby-doc.org/stdlib/libdoc/coverage/rdoc/Coverage.html "API doc for Ruby's Coverage library"
13
- [Source Code]: https://github.com/colszowka/simplecov "Source Code @ GitHub"
13
+ [Source Code]: https://github.com/simplecov-ruby/simplecov "Source Code @ GitHub"
14
14
  [API documentation]: http://rubydoc.info/gems/simplecov/frames "RDoc API Documentation at Rubydoc.info"
15
15
  [Configuration]: http://rubydoc.info/gems/simplecov/SimpleCov/Configuration "Configuration options API documentation"
16
- [Changelog]: https://github.com/colszowka/simplecov/blob/master/CHANGELOG.md "Project Changelog"
16
+ [Changelog]: https://github.com/simplecov-ruby/simplecov/blob/main/CHANGELOG.md "Project Changelog"
17
17
  [Rubygem]: http://rubygems.org/gems/simplecov "SimpleCov @ rubygems.org"
18
- [Continuous Integration]: https://github.com/colszowka/simplecov/actions?query=workflow%3Astable "SimpleCov is built around the clock by github.com"
19
- [Dependencies]: https://gemnasium.com/colszowka/simplecov "SimpleCov dependencies on Gemnasium"
20
- [simplecov-html]: https://github.com/colszowka/simplecov-html "SimpleCov HTML Formatter Source Code @ GitHub"
18
+ [Continuous Integration]: https://github.com/simplecov-ruby/simplecov/actions?query=workflow%3Astable "SimpleCov is built around the clock by github.com"
19
+ [Dependencies]: https://gemnasium.com/simplecov-ruby/simplecov "SimpleCov dependencies on Gemnasium"
20
+ [simplecov-html]: https://github.com/simplecov-ruby/simplecov-html "SimpleCov HTML Formatter Source Code @ GitHub"
21
21
 
22
22
  SimpleCov is a code coverage analysis tool for Ruby. It uses [Ruby's built-in Coverage][Coverage] library to gather code
23
23
  coverage data, but makes processing its results much easier by providing a clean API to filter, group, merge, format,
@@ -37,8 +37,8 @@ configured automatically when you launch SimpleCov. If you're curious, you can f
37
37
 
38
38
  *Code and Bug Reports*
39
39
 
40
- * [Issue Tracker](https://github.com/colszowka/simplecov/issues)
41
- * See [CONTRIBUTING](https://github.com/colszowka/simplecov/blob/master/CONTRIBUTING.md) for how to contribute along
40
+ * [Issue Tracker](https://github.com/simplecov-ruby/simplecov/issues)
41
+ * See [CONTRIBUTING](https://github.com/simplecov-ruby/simplecov/blob/main/CONTRIBUTING.md) for how to contribute along
42
42
  with some common problems to check out before creating an issue.
43
43
 
44
44
  *Questions, Problems, Suggestions, etc.*
@@ -167,8 +167,8 @@ to use SimpleCov with them. Here's an overview of the known ones:
167
167
  race conditions occur when results are merged.
168
168
  </td>
169
169
  <td>
170
- <a href="https://github.com/colszowka/simplecov/issues/64">#64</a> &amp;
171
- <a href="https://github.com/colszowka/simplecov/pull/185">#185</a>
170
+ <a href="https://github.com/simplecov-ruby/simplecov/issues/64">#64</a> &amp;
171
+ <a href="https://github.com/simplecov-ruby/simplecov/pull/185">#185</a>
172
172
  </td>
173
173
  </tr>
174
174
  <tr>
@@ -192,7 +192,7 @@ to use SimpleCov with them. Here's an overview of the known ones:
192
192
  to explicitly set the output root using `SimpleCov.root('foo/bar/baz')`
193
193
  </td>
194
194
  <td>
195
- <a href="https://github.com/colszowka/simplecov/issues/95">#95</a>
195
+ <a href="https://github.com/simplecov-ruby/simplecov/issues/95">#95</a>
196
196
  </td>
197
197
  </tr>
198
198
  <tr>
@@ -203,11 +203,11 @@ to use SimpleCov with them. Here's an overview of the known ones:
203
203
  Because of how Spork works internally (using preforking), there used to
204
204
  be trouble when using SimpleCov with it, but that has apparently been
205
205
  resolved with a specific configuration strategy. See <a
206
- href="https://github.com/colszowka/simplecov/issues/42#issuecomment-4440284">this</a>
206
+ href="https://github.com/simplecov-ruby/simplecov/issues/42#issuecomment-4440284">this</a>
207
207
  comment.
208
208
  </td>
209
209
  <td>
210
- <a href="https://github.com/colszowka/simplecov/issues/42#issuecomment-4440284">#42</a>
210
+ <a href="https://github.com/simplecov-ruby/simplecov/issues/42#issuecomment-4440284">#42</a>
211
211
  </td>
212
212
  </tr>
213
213
  <tr>
@@ -218,7 +218,7 @@ to use SimpleCov with them. Here's an overview of the known ones:
218
218
  <a href="#want-to-use-spring-with-simplecov">See section below.</a>
219
219
  </td>
220
220
  <td>
221
- <a href="https://github.com/colszowka/simplecov/issues/381">#381</a>
221
+ <a href="https://github.com/simplecov-ruby/simplecov/issues/381">#381</a>
222
222
  </td>
223
223
  </tr>
224
224
  <tr>
@@ -231,7 +231,7 @@ to use SimpleCov with them. Here's an overview of the known ones:
231
231
  (Dec 11th, 2011) should have this problem resolved.
232
232
  </td>
233
233
  <td>
234
- <a href="https://github.com/colszowka/simplecov/issues/45">#45</a> &amp;
234
+ <a href="https://github.com/simplecov-ruby/simplecov/issues/45">#45</a> &amp;
235
235
  <a href="https://github.com/test-unit/test-unit/pull/12">test-unit/test-unit#12</a>
236
236
  </td>
237
237
  </tr>
@@ -429,7 +429,7 @@ end
429
429
  # :nocov:
430
430
  ```
431
431
 
432
- The name of the token can be changed to your liking. [Learn more about the nocov feature.]( https://github.com/colszowka/simplecov/blob/master/features/config_nocov_token.feature)
432
+ The name of the token can be changed to your liking. [Learn more about the nocov feature.]( https://github.com/simplecov-ruby/simplecov/blob/main/features/config_nocov_token.feature)
433
433
 
434
434
  **Note:** You shouldn't have to use the nocov token to skip private methods that are being included in your coverage. If
435
435
  you appropriately test the public interface of your classes and objects you should automatically get full coverage of
@@ -440,7 +440,7 @@ your private methods.
440
440
  By default, SimpleCov filters everything outside of the `SimpleCov.root` directory. However, sometimes you may want
441
441
  to include coverage reports for things you include as a gem, for example a Rails Engine.
442
442
 
443
- Here's an example by [@lsaffie](https://github.com/lsaffie) from [#221](https://github.com/colszowka/simplecov/issues/221)
443
+ Here's an example by [@lsaffie](https://github.com/lsaffie) from [#221](https://github.com/simplecov-ruby/simplecov/issues/221)
444
444
  that shows how you can achieve just that:
445
445
 
446
446
  ```ruby
@@ -614,6 +614,53 @@ namespace :coverage do
614
614
  end
615
615
  ```
616
616
 
617
+ ## Running simplecov against subprocesses
618
+
619
+ `SimpleCov.enable_for_subprocesses` will allow SimpleCov to observe subprocesses starting using `Process.fork`.
620
+ This modifies ruby's core Process.fork method so that SimpleCov can see into it, appending `" (subprocess #{pid})"`
621
+ to the `SimpleCov.command_name`, with results that can be merged together using SimpleCov's merging feature.
622
+
623
+ To configure this, use `.at_fork`.
624
+
625
+ ```ruby
626
+ SimpleCov.enable_for_subprocesses true
627
+ SimpleCov.at_fork do |pid|
628
+ # This needs a unique name so it won't be ovewritten
629
+ SimpleCov.command_name "#{SimpleCov.command_name} (subprocess: #{pid})"
630
+ # be quiet, the parent process will be in charge of output and checking coverage totals
631
+ SimpleCov.print_error_status = false
632
+ SimpleCov.formatter SimpleCov::Formatter::SimpleFormatter
633
+ SimpleCov.minimum_coverage 0
634
+ # start
635
+ SimpleCov.start
636
+ end
637
+ ```
638
+
639
+ NOTE: SimpleCov must have already been started before `Process.fork` was called.
640
+
641
+ ### Running simplecov against spawned subprocesses
642
+
643
+ Perhaps you're testing a ruby script with `PTY.spawn` or `Open3.popen`, or `Process.spawn` or etc.
644
+ SimpleCov can cover this too.
645
+
646
+ Add a .simplecov_spawn.rb file to your project root
647
+ ```ruby
648
+ # .simplecov_spawn.rb
649
+ require 'simplecov' # this will also pick up whatever config is in .simplecov
650
+ # so ensure it just contains configuration, and doesn't call SimpleCov.start.
651
+ SimpleCov.command_name 'spawn' # As this is not for a test runner directly, script doesn't have a pre-defined base command_name
652
+ SimpleCov.at_fork.call(Process.pid) # Use the per-process setup described previously
653
+ SimpleCov.start # only now can we start.
654
+ ```
655
+ Then, instead of calling your script directly, like:
656
+ ```ruby
657
+ PTY.spawn('my_script.rb') do # ...
658
+ ```
659
+ Use bin/ruby to require the new .simplecov_spawn file, then your script
660
+ ```ruby
661
+ PTY.spawn('ruby -r./.simplecov_spawn my_script.rb') do # ...
662
+ ```
663
+
617
664
  ## Running coverage only on demand
618
665
 
619
666
  The Ruby STDLIB Coverage library that SimpleCov builds upon is *very* fast (on a ~10 min Rails test suite, the speed
@@ -794,7 +841,7 @@ SimpleCov.formatters = SimpleCov::Formatter::MultiFormatter.new([
794
841
 
795
842
  ## Ruby version compatibility
796
843
 
797
- SimpleCov is built in [Continuous Integration] on Ruby 2.4+ as well as JRuby 9.2+.
844
+ SimpleCov is built in [Continuous Integration] on Ruby 2.5+ as well as JRuby 9.2+.
798
845
 
799
846
  Note for JRuby => You need to pass JRUBY_OPTS="--debug" or create .jrubyrc and add debug.fullTrace=true
800
847
 
@@ -809,7 +856,7 @@ with them, you'll find that it often misreports coverage with the default config
809
856
  issue. Don't despair!
810
857
 
811
858
  One solution is to [explicitly call eager
812
- load](https://github.com/colszowka/simplecov/issues/381#issuecomment-347651728)
859
+ load](https://github.com/simplecov-ruby/simplecov/issues/381#issuecomment-347651728)
813
860
  in your `test_helper.rb` / `spec_helper.rb` after calling `SimpleCov.start`.
814
861
 
815
862
  ```ruby
@@ -868,7 +915,7 @@ Everyone participating in this project's development, issue trackers and other c
868
915
 
869
916
  ## Contributing
870
917
 
871
- See the [contributing guide](https://github.com/colszowka/simplecov/blob/master/CONTRIBUTING.md).
918
+ See the [contributing guide](https://github.com/simplecov-ruby/simplecov/blob/main/CONTRIBUTING.md).
872
919
 
873
920
  ## Kudos
874
921
 
@@ -1,7 +1,7 @@
1
1
  ## Alternate coverage report formatters
2
2
 
3
3
  The community around simplecov provides a whole bunch of alternate formatters beyond the official
4
- [simplecov-html](https://github.com/colszowka/simplecov-html) gem.
4
+ [simplecov-html](https://github.com/simplecov-ruby/simplecov-html) gem.
5
5
 
6
6
  If you have built or found one that is missing here, please send a Pull Request for this document!
7
7
 
@@ -15,6 +15,11 @@ A formatter that generates a coverage badge for use in your project's readme usi
15
15
 
16
16
  A formatter that generates a small coverage badge for use in your project's readme using the SVG.
17
17
 
18
+ #### [simplecov_badger](https://github.com/traels-it/simplecov_badger)
19
+ *by traels.it*
20
+
21
+ A formatter that uploads your coverage to a server, that will then host a SVG badge of the score. No need to have the badge stored in repository.
22
+
18
23
  #### [simplecov-cobertura](https://github.com/dashingrocket/simplecov-cobertura)
19
24
  *by Jesse Bowes*
20
25
 
@@ -55,7 +60,7 @@ A formatter that prints the coverage of the file under test when you run a singl
55
60
 
56
61
  t_wada AA formatter for SimpleCov
57
62
 
58
- #### [simplecov-material(https://github.com/chiefpansancolt/simplecov-material)
63
+ #### [simplecov-material](https://github.com/chiefpansancolt/simplecov-material)
59
64
  *by [Chiefpansancolt](https://github.com/chiefpansancolt)*
60
65
 
61
66
  A Material Designed HTML formatter with clean and easy search of files with a tabular left Navigation.
@@ -4,6 +4,11 @@ There is a bunch of services that offer integration with your existing CI pipeli
4
4
  reports. Please note these are not associated with the SimpleCov project itself, so please report problems with
5
5
  these integrations with their respective owners.
6
6
 
7
+ #### [Codacy](https://github.com/codacy/codacy-coverage-reporter)
8
+ *by [Codacy](https://www.codacy.com/)*
9
+
10
+ Upload coverage reports to [codacy.com](https://www.codacy.com/), a hosted (or self-hosted) software quality analysis platform that also includes coverage reporting.
11
+
7
12
  #### [codeclimate](https://github.com/codeclimate/ruby-test-reporter)
8
13
  *by [Code Climate](https://codeclimate.com/)*
9
14
 
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ # How minitest plugins. See https://github.com/simplecov-ruby/simplecov/pull/756 for why we need this.
4
+ # https://github.com/seattlerb/minitest#writing-extensions
5
+ module Minitest
6
+ def self.plugin_simplecov_init(_options)
7
+ if defined?(SimpleCov)
8
+ SimpleCov.external_at_exit = true
9
+
10
+ Minitest.after_run do
11
+ SimpleCov.at_exit_behavior
12
+ end
13
+ end
14
+ end
15
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "fileutils"
4
4
  require "docile"
5
- require "simplecov/formatter/multi_formatter"
5
+ require_relative "formatter/multi_formatter"
6
6
 
7
7
  module SimpleCov
8
8
  #
@@ -196,6 +196,52 @@ module SimpleCov
196
196
  @at_exit ||= proc { SimpleCov.result.format! }
197
197
  end
198
198
 
199
+ # gets or sets the enabled_for_subprocess configuration
200
+ # when true, this will inject SimpleCov code into Process.fork
201
+ def enable_for_subprocesses(value = nil)
202
+ @enable_for_subprocesses = value unless value.nil?
203
+ @enable_for_subprocesses || false
204
+ end
205
+
206
+ # gets the enabled_for_subprocess configuration
207
+ def enabled_for_subprocesses?
208
+ enable_for_subprocesses
209
+ end
210
+
211
+ #
212
+ # Gets or sets the behavior to start a new forked Process.
213
+ #
214
+ # By default, it will add " (Process #{pid})" to the command_name, and start SimpleCov in quiet mode
215
+ #
216
+ # Configure with:
217
+ #
218
+ # SimpleCov.at_fork do |pid|
219
+ # SimpleCov.start do
220
+ # # This needs a unique name so it won't be ovewritten
221
+ # SimpleCov.command_name "#{SimpleCov.command_name} (subprocess: #{pid})"
222
+ # # be quiet, the parent process will be in charge of using the regular formatter and checking coverage totals
223
+ # SimpleCov.print_error_status = false
224
+ # SimpleCov.formatter SimpleCov::Formatter::SimpleFormatter
225
+ # SimpleCov.minimum_coverage 0
226
+ # # start
227
+ # SimpleCov.start
228
+ # end
229
+ # end
230
+ #
231
+ def at_fork(&block)
232
+ @at_fork = block if block_given?
233
+ @at_fork ||= lambda { |pid|
234
+ # This needs a unique name so it won't be ovewritten
235
+ SimpleCov.command_name "#{SimpleCov.command_name} (subprocess: #{pid})"
236
+ # be quiet, the parent process will be in charge of using the regular formatter and checking coverage totals
237
+ SimpleCov.print_error_status = false
238
+ SimpleCov.formatter SimpleCov::Formatter::SimpleFormatter
239
+ SimpleCov.minimum_coverage 0
240
+ # start
241
+ SimpleCov.start
242
+ }
243
+ end
244
+
199
245
  #
200
246
  # Returns the project name - currently assuming the last dirname in
201
247
  # the SimpleCov.root is this.
@@ -239,17 +285,20 @@ module SimpleCov
239
285
  #
240
286
  # Default is 0% (disabled)
241
287
  #
288
+
289
+ # rubocop:disable Metrics/CyclomaticComplexity
242
290
  def minimum_coverage(coverage = nil)
243
291
  return @minimum_coverage ||= {} unless coverage
244
292
 
245
293
  coverage = {DEFAULT_COVERAGE_CRITERION => coverage} if coverage.is_a?(Numeric)
246
- coverage.keys.each { |criterion| raise_if_criterion_disabled(criterion) }
247
- coverage.values.each do |percent|
294
+ coverage.each_key { |criterion| raise_if_criterion_disabled(criterion) }
295
+ coverage.each_value do |percent|
248
296
  minimum_possible_coverage_exceeded("minimum_coverage") if percent && percent > 100
249
297
  end
250
298
 
251
299
  @minimum_coverage = coverage
252
300
  end
301
+ # rubocop:enable Metrics/CyclomaticComplexity
253
302
 
254
303
  #
255
304
  # Defines the maximum coverage drop at once allowed for the testsuite to pass.
@@ -3,11 +3,11 @@
3
3
  # Load default formatter gem
4
4
  require "simplecov-html"
5
5
  require "pathname"
6
- require "simplecov/profiles/root_filter"
7
- require "simplecov/profiles/test_frameworks"
8
- require "simplecov/profiles/bundler_filter"
9
- require "simplecov/profiles/hidden_filter"
10
- require "simplecov/profiles/rails"
6
+ require_relative "profiles/root_filter"
7
+ require_relative "profiles/test_frameworks"
8
+ require_relative "profiles/bundler_filter"
9
+ require_relative "profiles/hidden_filter"
10
+ require_relative "profiles/rails"
11
11
 
12
12
  # Default configuration
13
13
  SimpleCov.configure do
@@ -22,17 +22,13 @@ end
22
22
  SimpleCov::CommandGuesser.original_run_command = "#{$PROGRAM_NAME} #{ARGV.join(' ')}"
23
23
 
24
24
  at_exit do
25
- # If we are in a different process than called start, don't interfere.
26
- next if SimpleCov.pid != Process.pid
25
+ next if SimpleCov.external_at_exit?
27
26
 
28
- # If SimpleCov is no longer running then don't run exit tasks
29
- next unless SimpleCov.running
30
-
31
- SimpleCov.run_exit_tasks!
27
+ SimpleCov.at_exit_behavior
32
28
  end
33
29
 
34
30
  # Autoload config from ~/.simplecov if present
35
- require "simplecov/load_global_config"
31
+ require_relative "load_global_config"
36
32
 
37
33
  # Autoload config from .simplecov if present
38
34
  # Recurse upwards until we find .simplecov or reach the root directory
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SimpleCov
4
+ module ExitCodes
5
+ module ExitCodeHandling
6
+ module_function
7
+
8
+ def call(result, coverage_limits:)
9
+ checks = coverage_checks(result, coverage_limits)
10
+
11
+ failing_check = checks.find(&:failing?)
12
+ if failing_check
13
+ failing_check.report
14
+ failing_check.exit_code
15
+ else
16
+ SimpleCov::ExitCodes::SUCCESS
17
+ end
18
+ end
19
+
20
+ def coverage_checks(result, coverage_limits)
21
+ [
22
+ MinimumOverallCoverageCheck.new(result, coverage_limits.minimum_coverage),
23
+ MinimumCoverageByFileCheck.new(result, coverage_limits.minimum_coverage_by_file),
24
+ MaximumCoverageDropCheck.new(result, coverage_limits.maximum_coverage_drop)
25
+ ]
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SimpleCov
4
+ module ExitCodes
5
+ class MaximumCoverageDropCheck
6
+ def initialize(result, maximum_coverage_drop)
7
+ @result = result
8
+ @maximum_coverage_drop = maximum_coverage_drop
9
+ end
10
+
11
+ def failing?
12
+ return false unless maximum_coverage_drop && last_run
13
+
14
+ coverage_diff > maximum_coverage_drop
15
+ end
16
+
17
+ def report
18
+ $stderr.printf(
19
+ "Coverage has dropped by %<drop_percent>.2f%% since the last time (maximum allowed: %<max_drop>.2f%%).\n",
20
+ drop_percent: coverage_diff,
21
+ max_drop: maximum_coverage_drop
22
+ )
23
+ end
24
+
25
+ def exit_code
26
+ SimpleCov::ExitCodes::MAXIMUM_COVERAGE_DROP
27
+ end
28
+
29
+ private
30
+
31
+ attr_reader :result, :maximum_coverage_drop
32
+
33
+ def last_run
34
+ return @last_run if defined?(@last_run)
35
+
36
+ @last_run = SimpleCov::LastRun.read
37
+ end
38
+
39
+ def coverage_diff
40
+ raise "Trying to access coverage_diff although there is no last run" unless last_run
41
+
42
+ @coverage_diff ||= last_run[:result][:covered_percent] - covered_percent
43
+ end
44
+
45
+ def covered_percent
46
+ SimpleCov.round_coverage(result.covered_percent)
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SimpleCov
4
+ module ExitCodes
5
+ class MinimumCoverageByFileCheck
6
+ def initialize(result, minimum_coverage_by_file)
7
+ @result = result
8
+ @minimum_coverage_by_file = minimum_coverage_by_file
9
+ end
10
+
11
+ def failing?
12
+ covered_percentages.any? { |p| p < minimum_coverage_by_file }
13
+ end
14
+
15
+ def report
16
+ $stderr.printf(
17
+ "File (%<file>s) is only (%<least_covered_percentage>.2f%%) covered. This is below the expected minimum coverage per file of (%<min_coverage>.2f%%).\n",
18
+ file: result.least_covered_file,
19
+ least_covered_percentage: covered_percentages.min,
20
+ min_coverage: minimum_coverage_by_file
21
+ )
22
+ end
23
+
24
+ def exit_code
25
+ SimpleCov::ExitCodes::MINIMUM_COVERAGE
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :result, :minimum_coverage_by_file
31
+
32
+ def covered_percentages
33
+ @covered_percentages ||=
34
+ result.covered_percentages.map { |percentage| SimpleCov.round_coverage(percentage) }
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SimpleCov
4
+ module ExitCodes
5
+ class MinimumOverallCoverageCheck
6
+ def initialize(result, minimum_coverage)
7
+ @result = result
8
+ @minimum_coverage = minimum_coverage
9
+ end
10
+
11
+ def failing?
12
+ minimum_violations.any?
13
+ end
14
+
15
+ def report
16
+ minimum_violations.each do |violation|
17
+ $stderr.printf(
18
+ "%<criterion>s coverage (%<covered>.2f%%) is below the expected minimum coverage (%<minimum_coverage>.2f%%).\n",
19
+ covered: SimpleCov.round_coverage(violation.fetch(:actual)),
20
+ minimum_coverage: violation.fetch(:minimum_expected),
21
+ criterion: violation.fetch(:criterion).capitalize
22
+ )
23
+ end
24
+ end
25
+
26
+ def exit_code
27
+ SimpleCov::ExitCodes::MINIMUM_COVERAGE
28
+ end
29
+
30
+ private
31
+
32
+ attr_reader :result, :minimum_coverage
33
+
34
+ def minimum_violations
35
+ @minimum_violations ||= calculate_minimum_violations
36
+ end
37
+
38
+ def calculate_minimum_violations
39
+ coverage_achieved = minimum_coverage.map do |criterion, percent|
40
+ {
41
+ criterion: criterion,
42
+ minimum_expected: percent,
43
+ actual: result.coverage_statistics.fetch(criterion).percent
44
+ }
45
+ end
46
+
47
+ coverage_achieved.select do |achieved|
48
+ achieved.fetch(:actual) < achieved.fetch(:minimum_expected)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -8,3 +8,8 @@ module SimpleCov
8
8
  MAXIMUM_COVERAGE_DROP = 3
9
9
  end
10
10
  end
11
+
12
+ require_relative "exit_codes/exit_code_handling"
13
+ require_relative "exit_codes/maximum_coverage_drop_check"
14
+ require_relative "exit_codes/minimum_coverage_by_file_check"
15
+ require_relative "exit_codes/minimum_overall_coverage_check"
@@ -14,6 +14,7 @@ module SimpleCov
14
14
  #
15
15
  class Filter
16
16
  attr_reader :filter_argument
17
+
17
18
  def initialize(filter_argument)
18
19
  @filter_argument = filter_argument
19
20
  end
@@ -34,13 +35,14 @@ module SimpleCov
34
35
  end
35
36
 
36
37
  def self.class_for_argument(filter_argument)
37
- if filter_argument.is_a?(String)
38
+ case filter_argument
39
+ when String
38
40
  SimpleCov::StringFilter
39
- elsif filter_argument.is_a?(Regexp)
41
+ when Regexp
40
42
  SimpleCov::RegexFilter
41
- elsif filter_argument.is_a?(Array)
43
+ when Array
42
44
  SimpleCov::ArrayFilter
43
- elsif filter_argument.is_a?(Proc)
45
+ when Proc
44
46
  SimpleCov::BlockFilter
45
47
  else
46
48
  raise ArgumentError, "You have provided an unrecognized filter type"
@@ -50,7 +52,7 @@ module SimpleCov
50
52
 
51
53
  class StringFilter < SimpleCov::Filter
52
54
  # Returns true when the given source file's filename matches the
53
- # string configured when initializing this Filter with StringFilter.new('somestring)
55
+ # string configured when initializing this Filter with StringFilter.new('somestring')
54
56
  def matches?(source_file)
55
57
  source_file.project_filename.include?(filter_argument)
56
58
  end
@@ -6,12 +6,10 @@ module SimpleCov
6
6
  module InstanceMethods
7
7
  def format(result)
8
8
  formatters.map do |formatter|
9
- begin
10
- formatter.new.format(result)
11
- rescue StandardError => e
12
- warn("Formatter #{formatter} failed with #{e.class}: #{e.message} (#{e.backtrace.first})")
13
- nil
14
- end
9
+ formatter.new.format(result)
10
+ rescue StandardError => e
11
+ warn("Formatter #{formatter} failed with #{e.class}: #{e.message} (#{e.backtrace.first})")
12
+ nil
15
13
  end
16
14
  end
17
15
  end
@@ -27,7 +25,7 @@ module SimpleCov
27
25
 
28
26
  def self.[](*args)
29
27
  warn "#{Kernel.caller.first}: [DEPRECATION] ::[] is deprecated. Use ::new instead."
30
- new(Array([*args]))
28
+ new(Array(args))
31
29
  end
32
30
  end
33
31
  end
@@ -6,5 +6,5 @@ module SimpleCov
6
6
  end
7
7
  end
8
8
 
9
- require "simplecov/formatter/simple_formatter"
10
- require "simplecov/formatter/multi_formatter"
9
+ require_relative "formatter/simple_formatter"
10
+ require_relative "formatter/multi_formatter"