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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +216 -170
- data/CONTRIBUTING.md +3 -3
- data/ISSUE_TEMPLATE.md +1 -1
- data/README.md +67 -20
- data/doc/alternate-formatters.md +7 -2
- data/doc/commercial-services.md +5 -0
- data/lib/minitest/simplecov_plugin.rb +15 -0
- data/lib/simplecov/configuration.rb +52 -3
- data/lib/simplecov/defaults.rb +8 -12
- data/lib/simplecov/exit_codes/exit_code_handling.rb +29 -0
- data/lib/simplecov/exit_codes/maximum_coverage_drop_check.rb +50 -0
- data/lib/simplecov/exit_codes/minimum_coverage_by_file_check.rb +38 -0
- data/lib/simplecov/exit_codes/minimum_overall_coverage_check.rb +53 -0
- data/lib/simplecov/exit_codes.rb +5 -0
- data/lib/simplecov/filter.rb +7 -5
- data/lib/simplecov/formatter/multi_formatter.rb +5 -7
- data/lib/simplecov/formatter.rb +2 -2
- data/lib/simplecov/lines_classifier.rb +1 -1
- data/lib/simplecov/no_defaults.rb +1 -1
- data/lib/simplecov/process.rb +19 -0
- data/lib/simplecov/result.rb +14 -12
- data/lib/simplecov/result_merger.rb +2 -7
- data/lib/simplecov/source_file.rb +46 -1
- data/lib/simplecov/useless_results_remover.rb +5 -3
- data/lib/simplecov/version.rb +1 -1
- data/lib/simplecov.rb +117 -118
- metadata +16 -8
data/CONTRIBUTING.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
## Reporting Issues
|
|
2
2
|
|
|
3
|
-
You can report issues at https://github.com/
|
|
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/
|
|
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/
|
|
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/
|
|
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 [](https://badge.fury.io/rb/simplecov) [](https://badge.fury.io/rb/simplecov) [][Continuous Integration] [](https://codeclimate.com/github/simplecov-ruby/simplecov/maintainability) [](http://inch-ci.org/github/simplecov-ruby/simplecov)
|
|
2
2
|
=========
|
|
3
3
|
|
|
4
4
|
**Code coverage for Ruby**
|
|
@@ -10,14 +10,14 @@ SimpleCov [](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/
|
|
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/
|
|
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/
|
|
19
|
-
[Dependencies]: https://gemnasium.com/
|
|
20
|
-
[simplecov-html]: https://github.com/
|
|
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/
|
|
41
|
-
* See [CONTRIBUTING](https://github.com/
|
|
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/
|
|
171
|
-
<a href="https://github.com/
|
|
170
|
+
<a href="https://github.com/simplecov-ruby/simplecov/issues/64">#64</a> &
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
234
|
+
<a href="https://github.com/simplecov-ruby/simplecov/issues/45">#45</a> &
|
|
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/
|
|
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/
|
|
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.
|
|
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/
|
|
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/
|
|
918
|
+
See the [contributing guide](https://github.com/simplecov-ruby/simplecov/blob/main/CONTRIBUTING.md).
|
|
872
919
|
|
|
873
920
|
## Kudos
|
|
874
921
|
|
data/doc/alternate-formatters.md
CHANGED
|
@@ -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/
|
|
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.
|
data/doc/commercial-services.md
CHANGED
|
@@ -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
|
-
|
|
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.
|
|
247
|
-
coverage.
|
|
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.
|
data/lib/simplecov/defaults.rb
CHANGED
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
# Load default formatter gem
|
|
4
4
|
require "simplecov-html"
|
|
5
5
|
require "pathname"
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
-
|
|
26
|
-
next if SimpleCov.pid != Process.pid
|
|
25
|
+
next if SimpleCov.external_at_exit?
|
|
27
26
|
|
|
28
|
-
|
|
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
|
-
|
|
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
|
data/lib/simplecov/exit_codes.rb
CHANGED
|
@@ -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"
|
data/lib/simplecov/filter.rb
CHANGED
|
@@ -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
|
-
|
|
38
|
+
case filter_argument
|
|
39
|
+
when String
|
|
38
40
|
SimpleCov::StringFilter
|
|
39
|
-
|
|
41
|
+
when Regexp
|
|
40
42
|
SimpleCov::RegexFilter
|
|
41
|
-
|
|
43
|
+
when Array
|
|
42
44
|
SimpleCov::ArrayFilter
|
|
43
|
-
|
|
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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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(
|
|
28
|
+
new(Array(args))
|
|
31
29
|
end
|
|
32
30
|
end
|
|
33
31
|
end
|
data/lib/simplecov/formatter.rb
CHANGED