simplecov 0.18.5 → 0.21.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +75 -520
- data/README.md +112 -29
- data/doc/alternate-formatters.md +12 -2
- data/doc/commercial-services.md +5 -0
- data/lib/minitest/simplecov_plugin.rb +1 -1
- data/lib/simplecov.rb +126 -137
- data/lib/simplecov/configuration.rb +90 -15
- data/lib/simplecov/default_formatter.rb +20 -0
- data/lib/simplecov/defaults.rb +11 -8
- data/lib/simplecov/exit_codes.rb +5 -0
- data/lib/simplecov/exit_codes/exit_code_handling.rb +29 -0
- data/lib/simplecov/exit_codes/maximum_coverage_drop_check.rb +73 -0
- data/lib/simplecov/exit_codes/minimum_coverage_by_file_check.rb +54 -0
- data/lib/simplecov/exit_codes/minimum_overall_coverage_check.rb +53 -0
- data/lib/simplecov/file_list.rb +12 -6
- data/lib/simplecov/filter.rb +7 -5
- data/lib/simplecov/formatter.rb +2 -2
- data/lib/simplecov/formatter/multi_formatter.rb +5 -7
- data/lib/simplecov/lines_classifier.rb +3 -3
- data/lib/simplecov/no_defaults.rb +1 -1
- data/lib/simplecov/process.rb +19 -0
- data/lib/simplecov/result.rb +8 -35
- data/lib/simplecov/result_merger.rb +121 -57
- data/lib/simplecov/source_file/line.rb +1 -1
- data/lib/simplecov/useless_results_remover.rb +5 -3
- data/lib/simplecov/version.rb +1 -1
- metadata +31 -12
- data/CODE_OF_CONDUCT.md +0 -76
- data/CONTRIBUTING.md +0 -51
- data/ISSUE_TEMPLATE.md +0 -23
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.*
|
@@ -73,9 +73,10 @@ Getting started
|
|
73
73
|
analysis to happen on. When testing a server process (e.g. a JSON API
|
74
74
|
endpoint) via a separate test process (e.g. when using Selenium) where you
|
75
75
|
want to see all code executed by the `rails server`, and not just code
|
76
|
-
executed in your actual test files, you
|
76
|
+
executed in your actual test files, you need to require SimpleCov in the
|
77
|
+
server process. For rails for instance, you'll want to add something like this
|
77
78
|
to the top of `bin/rails`, but below the "shebang" line (`#! /usr/bin/env
|
78
|
-
ruby`):
|
79
|
+
ruby`) and after config/boot is required:
|
79
80
|
|
80
81
|
```ruby
|
81
82
|
if ENV['RAILS_ENV'] == 'test'
|
@@ -167,8 +168,8 @@ to use SimpleCov with them. Here's an overview of the known ones:
|
|
167
168
|
race conditions occur when results are merged.
|
168
169
|
</td>
|
169
170
|
<td>
|
170
|
-
<a href="https://github.com/
|
171
|
-
<a href="https://github.com/
|
171
|
+
<a href="https://github.com/simplecov-ruby/simplecov/issues/64">#64</a> &
|
172
|
+
<a href="https://github.com/simplecov-ruby/simplecov/pull/185">#185</a>
|
172
173
|
</td>
|
173
174
|
</tr>
|
174
175
|
<tr>
|
@@ -192,7 +193,7 @@ to use SimpleCov with them. Here's an overview of the known ones:
|
|
192
193
|
to explicitly set the output root using `SimpleCov.root('foo/bar/baz')`
|
193
194
|
</td>
|
194
195
|
<td>
|
195
|
-
<a href="https://github.com/
|
196
|
+
<a href="https://github.com/simplecov-ruby/simplecov/issues/95">#95</a>
|
196
197
|
</td>
|
197
198
|
</tr>
|
198
199
|
<tr>
|
@@ -203,11 +204,11 @@ to use SimpleCov with them. Here's an overview of the known ones:
|
|
203
204
|
Because of how Spork works internally (using preforking), there used to
|
204
205
|
be trouble when using SimpleCov with it, but that has apparently been
|
205
206
|
resolved with a specific configuration strategy. See <a
|
206
|
-
href="https://github.com/
|
207
|
+
href="https://github.com/simplecov-ruby/simplecov/issues/42#issuecomment-4440284">this</a>
|
207
208
|
comment.
|
208
209
|
</td>
|
209
210
|
<td>
|
210
|
-
<a href="https://github.com/
|
211
|
+
<a href="https://github.com/simplecov-ruby/simplecov/issues/42#issuecomment-4440284">#42</a>
|
211
212
|
</td>
|
212
213
|
</tr>
|
213
214
|
<tr>
|
@@ -218,7 +219,7 @@ to use SimpleCov with them. Here's an overview of the known ones:
|
|
218
219
|
<a href="#want-to-use-spring-with-simplecov">See section below.</a>
|
219
220
|
</td>
|
220
221
|
<td>
|
221
|
-
<a href="https://github.com/
|
222
|
+
<a href="https://github.com/simplecov-ruby/simplecov/issues/381">#381</a>
|
222
223
|
</td>
|
223
224
|
</tr>
|
224
225
|
<tr>
|
@@ -231,7 +232,7 @@ to use SimpleCov with them. Here's an overview of the known ones:
|
|
231
232
|
(Dec 11th, 2011) should have this problem resolved.
|
232
233
|
</td>
|
233
234
|
<td>
|
234
|
-
<a href="https://github.com/
|
235
|
+
<a href="https://github.com/simplecov-ruby/simplecov/issues/45">#45</a> &
|
235
236
|
<a href="https://github.com/test-unit/test-unit/pull/12">test-unit/test-unit#12</a>
|
236
237
|
</td>
|
237
238
|
</tr>
|
@@ -294,7 +295,6 @@ information to be lost.
|
|
294
295
|
Add branch coverage measurement statistics to your results. Supported in CRuby versions 2.5+.
|
295
296
|
|
296
297
|
```ruby
|
297
|
-
# or in configure or just SimpleCov.enable_coverage :branch
|
298
298
|
SimpleCov.start do
|
299
299
|
enable_coverage :branch
|
300
300
|
end
|
@@ -340,6 +340,22 @@ Hence, we recommend looking at both metrics together. Branch coverage might also
|
|
340
340
|
overall metric to look at - while you might be missing only 10% of your lines that might
|
341
341
|
account for 50% of your branches for instance.
|
342
342
|
|
343
|
+
## Primary Coverage
|
344
|
+
|
345
|
+
By default, the primary coverage type is `line`. To set the primary coverage to something else, use the following:
|
346
|
+
|
347
|
+
```ruby
|
348
|
+
# or in configure SimpleCov.primary_coverage :branch
|
349
|
+
SimpleCov.start do
|
350
|
+
enable_coverage :branch
|
351
|
+
primary_coverage :branch
|
352
|
+
end
|
353
|
+
```
|
354
|
+
|
355
|
+
Primary coverage determines what will come in first all output, and the type of coverage to check if you don't specify the type of coverage when customizing exit behavior (`SimpleCov.minimum_coverage 90`).
|
356
|
+
|
357
|
+
Note that coverage must first be enabled for non-default coverage types.
|
358
|
+
|
343
359
|
## Filters
|
344
360
|
|
345
361
|
Filters can be used to remove selected files from your coverage data. By default, a filter is applied that removes all
|
@@ -429,7 +445,7 @@ end
|
|
429
445
|
# :nocov:
|
430
446
|
```
|
431
447
|
|
432
|
-
The name of the token can be changed to your liking. [Learn more about the nocov feature.]( https://github.com/
|
448
|
+
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
449
|
|
434
450
|
**Note:** You shouldn't have to use the nocov token to skip private methods that are being included in your coverage. If
|
435
451
|
you appropriately test the public interface of your classes and objects you should automatically get full coverage of
|
@@ -440,7 +456,7 @@ your private methods.
|
|
440
456
|
By default, SimpleCov filters everything outside of the `SimpleCov.root` directory. However, sometimes you may want
|
441
457
|
to include coverage reports for things you include as a gem, for example a Rails Engine.
|
442
458
|
|
443
|
-
Here's an example by [@lsaffie](https://github.com/lsaffie) from [#221](https://github.com/
|
459
|
+
Here's an example by [@lsaffie](https://github.com/lsaffie) from [#221](https://github.com/simplecov-ruby/simplecov/issues/221)
|
444
460
|
that shows how you can achieve just that:
|
445
461
|
|
446
462
|
```ruby
|
@@ -614,6 +630,53 @@ namespace :coverage do
|
|
614
630
|
end
|
615
631
|
```
|
616
632
|
|
633
|
+
## Running simplecov against subprocesses
|
634
|
+
|
635
|
+
`SimpleCov.enable_for_subprocesses` will allow SimpleCov to observe subprocesses starting using `Process.fork`.
|
636
|
+
This modifies ruby's core Process.fork method so that SimpleCov can see into it, appending `" (subprocess #{pid})"`
|
637
|
+
to the `SimpleCov.command_name`, with results that can be merged together using SimpleCov's merging feature.
|
638
|
+
|
639
|
+
To configure this, use `.at_fork`.
|
640
|
+
|
641
|
+
```ruby
|
642
|
+
SimpleCov.enable_for_subprocesses true
|
643
|
+
SimpleCov.at_fork do |pid|
|
644
|
+
# This needs a unique name so it won't be ovewritten
|
645
|
+
SimpleCov.command_name "#{SimpleCov.command_name} (subprocess: #{pid})"
|
646
|
+
# be quiet, the parent process will be in charge of output and checking coverage totals
|
647
|
+
SimpleCov.print_error_status = false
|
648
|
+
SimpleCov.formatter SimpleCov::Formatter::SimpleFormatter
|
649
|
+
SimpleCov.minimum_coverage 0
|
650
|
+
# start
|
651
|
+
SimpleCov.start
|
652
|
+
end
|
653
|
+
```
|
654
|
+
|
655
|
+
NOTE: SimpleCov must have already been started before `Process.fork` was called.
|
656
|
+
|
657
|
+
### Running simplecov against spawned subprocesses
|
658
|
+
|
659
|
+
Perhaps you're testing a ruby script with `PTY.spawn` or `Open3.popen`, or `Process.spawn` or etc.
|
660
|
+
SimpleCov can cover this too.
|
661
|
+
|
662
|
+
Add a .simplecov_spawn.rb file to your project root
|
663
|
+
```ruby
|
664
|
+
# .simplecov_spawn.rb
|
665
|
+
require 'simplecov' # this will also pick up whatever config is in .simplecov
|
666
|
+
# so ensure it just contains configuration, and doesn't call SimpleCov.start.
|
667
|
+
SimpleCov.command_name 'spawn' # As this is not for a test runner directly, script doesn't have a pre-defined base command_name
|
668
|
+
SimpleCov.at_fork.call(Process.pid) # Use the per-process setup described previously
|
669
|
+
SimpleCov.start # only now can we start.
|
670
|
+
```
|
671
|
+
Then, instead of calling your script directly, like:
|
672
|
+
```ruby
|
673
|
+
PTY.spawn('my_script.rb') do # ...
|
674
|
+
```
|
675
|
+
Use bin/ruby to require the new .simplecov_spawn file, then your script
|
676
|
+
```ruby
|
677
|
+
PTY.spawn('ruby -r./.simplecov_spawn my_script.rb') do # ...
|
678
|
+
```
|
679
|
+
|
617
680
|
## Running coverage only on demand
|
618
681
|
|
619
682
|
The Ruby STDLIB Coverage library that SimpleCov builds upon is *very* fast (on a ~10 min Rails test suite, the speed
|
@@ -739,30 +802,36 @@ to help ensure coverage is relatively consistent, rather than being skewed by pa
|
|
739
802
|
|
740
803
|
```ruby
|
741
804
|
SimpleCov.minimum_coverage_by_file 80
|
805
|
+
# same as above (the default is to check line coverage by file)
|
806
|
+
SimpleCov.minimum_coverage_by_file line: 80
|
807
|
+
# check for a minimum line coverage by file of 90% and minimum 80% branch coverage
|
808
|
+
SimpleCov.minimum_coverage_by_file line: 90, branch: 80
|
742
809
|
```
|
743
810
|
|
744
|
-
(not yet supported for branch coverage)
|
745
|
-
|
746
811
|
### Maximum coverage drop
|
747
812
|
|
748
813
|
You can define the maximum coverage drop percentage at once. SimpleCov will return non-zero if exceeded.
|
749
814
|
|
750
815
|
```ruby
|
751
816
|
SimpleCov.maximum_coverage_drop 5
|
817
|
+
# same as above (the default is to check line drop)
|
818
|
+
SimpleCov.maximum_coverage_drop line: 5
|
819
|
+
# check for a maximum line drop of 5% and maximum 10% branch drop
|
820
|
+
SimpleCov.maximum_coverage_drop line: 5, branch: 10
|
752
821
|
```
|
753
822
|
|
754
|
-
(not yet supported for branch coverage)
|
755
|
-
|
756
823
|
### Refuse dropping coverage
|
757
824
|
|
758
825
|
You can also entirely refuse dropping coverage between test runs:
|
759
826
|
|
760
827
|
```ruby
|
761
828
|
SimpleCov.refuse_coverage_drop
|
829
|
+
# same as above (the default is to only refuse line drop)
|
830
|
+
SimpleCov.refuse_coverage_drop :line
|
831
|
+
# refuse drop for line and branch
|
832
|
+
SimpleCov.refuse_coverage_drop :line, :branch
|
762
833
|
```
|
763
834
|
|
764
|
-
(not yet supported for branch coverage)
|
765
|
-
|
766
835
|
## Using your own formatter
|
767
836
|
|
768
837
|
You can use your own formatter with:
|
@@ -786,6 +855,20 @@ SimpleCov.formatters = SimpleCov::Formatter::MultiFormatter.new([
|
|
786
855
|
])
|
787
856
|
```
|
788
857
|
|
858
|
+
## JSON formatter
|
859
|
+
|
860
|
+
SimpleCov is packaged with a separate gem called [simplecov_json_formatter](https://github.com/codeclimate-community/simplecov_json_formatter) that provides you with a JSON formatter, this formatter could be useful for different use cases, such as for CI consumption or for reporting to external services.
|
861
|
+
|
862
|
+
In order to use it you will need to manually load the installed gem like so:
|
863
|
+
|
864
|
+
```ruby
|
865
|
+
require "simplecov_json_formatter"
|
866
|
+
SimpleCov.formatter = SimpleCov::Formatter::JSONFormatter
|
867
|
+
```
|
868
|
+
|
869
|
+
> _Note:_ In case you plan to report your coverage results to CodeClimate services, know that SimpleCov will automatically use the
|
870
|
+
> JSON formatter along with the HTML formatter when the `CC_TEST_REPORTER_ID` variable is present in the environment.
|
871
|
+
|
789
872
|
## Available formatters, editor integrations and hosted services
|
790
873
|
|
791
874
|
* [Open Source formatter and integration plugins for SimpleCov](doc/alternate-formatters.md)
|
@@ -794,7 +877,7 @@ SimpleCov.formatters = SimpleCov::Formatter::MultiFormatter.new([
|
|
794
877
|
|
795
878
|
## Ruby version compatibility
|
796
879
|
|
797
|
-
SimpleCov is built in [Continuous Integration] on Ruby 2.
|
880
|
+
SimpleCov is built in [Continuous Integration] on Ruby 2.5+ as well as JRuby 9.2+.
|
798
881
|
|
799
882
|
Note for JRuby => You need to pass JRUBY_OPTS="--debug" or create .jrubyrc and add debug.fullTrace=true
|
800
883
|
|
@@ -809,7 +892,7 @@ with them, you'll find that it often misreports coverage with the default config
|
|
809
892
|
issue. Don't despair!
|
810
893
|
|
811
894
|
One solution is to [explicitly call eager
|
812
|
-
load](https://github.com/
|
895
|
+
load](https://github.com/simplecov-ruby/simplecov/issues/381#issuecomment-347651728)
|
813
896
|
in your `test_helper.rb` / `spec_helper.rb` after calling `SimpleCov.start`.
|
814
897
|
|
815
898
|
```ruby
|
@@ -868,7 +951,7 @@ Everyone participating in this project's development, issue trackers and other c
|
|
868
951
|
|
869
952
|
## Contributing
|
870
953
|
|
871
|
-
See the [contributing guide](https://github.com/
|
954
|
+
See the [contributing guide](https://github.com/simplecov-ruby/simplecov/blob/main/CONTRIBUTING.md).
|
872
955
|
|
873
956
|
## Kudos
|
874
957
|
|
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,12 @@ 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-
|
63
|
+
#### [simplecov-tailwindcss](https://github.com/chiefpansancolt/simplecov-tailwindcss)
|
64
|
+
*by [Chiefpansancolt](https://github.com/chiefpansancolt)*
|
65
|
+
|
66
|
+
A TailwindCSS & TailwindUI Designed HTML formatter with clean and easy search of files with a tabular left Navigation.
|
67
|
+
|
68
|
+
#### [simplecov-material](https://github.com/chiefpansancolt/simplecov-material)
|
59
69
|
*by [Chiefpansancolt](https://github.com/chiefpansancolt)*
|
60
70
|
|
61
71
|
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
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# How minitest plugins. See https://github.com/
|
3
|
+
# How minitest plugins. See https://github.com/simplecov-ruby/simplecov/pull/756 for why we need this.
|
4
4
|
# https://github.com/seattlerb/minitest#writing-extensions
|
5
5
|
module Minitest
|
6
6
|
def self.plugin_simplecov_init(_options)
|
data/lib/simplecov.rb
CHANGED
@@ -3,19 +3,17 @@
|
|
3
3
|
require "English"
|
4
4
|
|
5
5
|
# Coverage may be inaccurate under JRUBY.
|
6
|
-
if defined?(JRUBY_VERSION) && defined?(JRuby)
|
6
|
+
if defined?(JRUBY_VERSION) && defined?(JRuby) && !org.jruby.RubyInstanceConfig.FULL_TRACE_ENABLED
|
7
7
|
|
8
8
|
# @see https://github.com/jruby/jruby/issues/1196
|
9
9
|
# @see https://github.com/metricfu/metric_fu/pull/226
|
10
|
-
# @see https://github.com/
|
11
|
-
# @see https://github.com/
|
10
|
+
# @see https://github.com/simplecov-ruby/simplecov/issues/420
|
11
|
+
# @see https://github.com/simplecov-ruby/simplecov/issues/86
|
12
12
|
# @see https://jira.codehaus.org/browse/JRUBY-6106
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
' or set the "debug.fullTrace=true" option in your .jrubyrc'
|
18
|
-
end
|
14
|
+
warn 'Coverage may be inaccurate; set the "--debug" command line option,' \
|
15
|
+
' or do JRUBY_OPTS="--debug"' \
|
16
|
+
' or set the "debug.fullTrace=true" option in your .jrubyrc'
|
19
17
|
end
|
20
18
|
|
21
19
|
#
|
@@ -23,9 +21,7 @@ end
|
|
23
21
|
#
|
24
22
|
module SimpleCov
|
25
23
|
class << self
|
26
|
-
attr_accessor :running
|
27
|
-
attr_accessor :pid
|
28
|
-
attr_reader :exit_exception
|
24
|
+
attr_accessor :running, :pid
|
29
25
|
|
30
26
|
# Basically, should we take care of at_exit behavior or something else?
|
31
27
|
# Used by the minitest plugin. See lib/minitest/simplecov_plugin.rb
|
@@ -52,6 +48,11 @@ module SimpleCov
|
|
52
48
|
def start(profile = nil, &block)
|
53
49
|
require "coverage"
|
54
50
|
initial_setup(profile, &block)
|
51
|
+
require_relative "./simplecov/process" if SimpleCov.enabled_for_subprocesses? &&
|
52
|
+
::Process.respond_to?(:fork)
|
53
|
+
|
54
|
+
make_parallel_tests_available
|
55
|
+
|
55
56
|
@result = nil
|
56
57
|
self.pid = Process.pid
|
57
58
|
|
@@ -60,6 +61,7 @@ module SimpleCov
|
|
60
61
|
|
61
62
|
#
|
62
63
|
# Collate a series of SimpleCov result files into a single SimpleCov output.
|
64
|
+
#
|
63
65
|
# You can optionally specify configuration with a block:
|
64
66
|
# SimpleCov.collate Dir["simplecov-resultset-*/.resultset.json"]
|
65
67
|
# OR
|
@@ -77,20 +79,17 @@ module SimpleCov
|
|
77
79
|
# available config options, or checkout the README for more in-depth
|
78
80
|
# information about coverage collation
|
79
81
|
#
|
80
|
-
|
81
|
-
|
82
|
+
# By default `collate` ignores the merge_timeout so all results of all files specified will be
|
83
|
+
# merged together. If you want to honor the merge_timeout then provide the keyword argument
|
84
|
+
# `ignore_timeout: false`.
|
85
|
+
#
|
86
|
+
def collate(result_filenames, profile = nil, ignore_timeout: true, &block)
|
87
|
+
raise "There are no reports to be merged" if result_filenames.empty?
|
82
88
|
|
83
89
|
initial_setup(profile, &block)
|
84
90
|
|
85
|
-
results = result_filenames.flat_map do |filename|
|
86
|
-
# Re-create each included instance of SimpleCov::Result from the stored run data.
|
87
|
-
(JSON.parse(File.read(filename)) || {}).map do |command_name, coverage|
|
88
|
-
SimpleCov::Result.from_hash(command_name => coverage)
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
91
|
# Use the ResultMerger to produce a single, merged result, ready to use.
|
93
|
-
@result =
|
92
|
+
@result = ResultMerger.merge_and_store(*result_filenames, ignore_timeout: ignore_timeout)
|
94
93
|
|
95
94
|
run_exit_tasks!
|
96
95
|
end
|
@@ -103,7 +102,6 @@ module SimpleCov
|
|
103
102
|
return @result if result?
|
104
103
|
|
105
104
|
# Collect our coverage result
|
106
|
-
|
107
105
|
process_coverage_result if running
|
108
106
|
|
109
107
|
# If we're using merging of results, store the current result
|
@@ -173,54 +171,71 @@ module SimpleCov
|
|
173
171
|
@result = nil
|
174
172
|
end
|
175
173
|
|
174
|
+
def at_exit_behavior
|
175
|
+
# If we are in a different process than called start, don't interfere.
|
176
|
+
return if SimpleCov.pid != Process.pid
|
177
|
+
|
178
|
+
# If SimpleCov is no longer running then don't run exit tasks
|
179
|
+
SimpleCov.run_exit_tasks! if SimpleCov.running
|
180
|
+
end
|
181
|
+
|
182
|
+
# @api private
|
176
183
|
#
|
177
|
-
#
|
178
|
-
# This will get called inside the at_exit block
|
184
|
+
# Called from at_exit block
|
179
185
|
#
|
180
|
-
def
|
181
|
-
|
186
|
+
def run_exit_tasks!
|
187
|
+
error_exit_status = exit_status_from_exception
|
188
|
+
|
189
|
+
at_exit.call
|
190
|
+
|
191
|
+
exit_and_report_previous_error(error_exit_status) if previous_error?(error_exit_status)
|
192
|
+
process_results_and_report_error if ready_to_process_results?
|
182
193
|
end
|
183
194
|
|
195
|
+
#
|
196
|
+
# @api private
|
184
197
|
#
|
185
198
|
# Returns the exit status from the exit exception
|
186
199
|
#
|
187
200
|
def exit_status_from_exception
|
188
|
-
|
201
|
+
# Capture the current exception if it exists
|
202
|
+
@exit_exception = $ERROR_INFO
|
203
|
+
return nil unless @exit_exception
|
189
204
|
|
190
|
-
if exit_exception.is_a?(SystemExit)
|
191
|
-
exit_exception.status
|
205
|
+
if @exit_exception.is_a?(SystemExit)
|
206
|
+
@exit_exception.status
|
192
207
|
else
|
193
208
|
SimpleCov::ExitCodes::EXCEPTION
|
194
209
|
end
|
195
210
|
end
|
196
211
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
SimpleCov.run_exit_tasks! if SimpleCov.running
|
212
|
+
# @api private
|
213
|
+
def previous_error?(error_exit_status)
|
214
|
+
# Normally it'd be enough to check for previous error but when running test_unit
|
215
|
+
# status is 0
|
216
|
+
error_exit_status && error_exit_status != SimpleCov::ExitCodes::SUCCESS
|
203
217
|
end
|
204
218
|
|
205
|
-
# @api private
|
206
219
|
#
|
207
|
-
#
|
220
|
+
# @api private
|
208
221
|
#
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
exit_status
|
222
|
+
# Thinking: Move this behavior earlier so if there was an error we do nothing?
|
223
|
+
def exit_and_report_previous_error(exit_status)
|
224
|
+
warn("Stopped processing SimpleCov as a previous error not related to SimpleCov has been detected") if print_error_status
|
225
|
+
Kernel.exit(exit_status)
|
226
|
+
end
|
213
227
|
|
214
|
-
|
228
|
+
# @api private
|
229
|
+
def ready_to_process_results?
|
230
|
+
final_result_process? && result?
|
231
|
+
end
|
215
232
|
|
216
|
-
|
217
|
-
|
218
|
-
exit_status = SimpleCov.process_result(SimpleCov.result, exit_status) if SimpleCov.result?
|
233
|
+
def process_results_and_report_error
|
234
|
+
exit_status = process_result(result)
|
219
235
|
|
220
236
|
# Force exit with stored status (see github issue #5)
|
221
|
-
|
222
|
-
|
223
|
-
$stderr.printf("SimpleCov failed with exit %<exit_status>d\n", exit_status: exit_status) if print_error_status
|
237
|
+
if exit_status.positive?
|
238
|
+
warn("SimpleCov failed with exit #{exit_status} due to a coverage related error") if print_error_status
|
224
239
|
Kernel.exit exit_status
|
225
240
|
end
|
226
241
|
end
|
@@ -230,55 +245,29 @@ module SimpleCov
|
|
230
245
|
# Usage:
|
231
246
|
# exit_status = SimpleCov.process_result(SimpleCov.result, exit_status)
|
232
247
|
#
|
233
|
-
def process_result(result
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
result_exit_status = result_exit_status(result, covered_percent)
|
238
|
-
write_last_run(covered_percent) if result_exit_status == SimpleCov::ExitCodes::SUCCESS # No result errors
|
239
|
-
final_result_process? ? result_exit_status : SimpleCov::ExitCodes::SUCCESS
|
248
|
+
def process_result(result)
|
249
|
+
result_exit_status = result_exit_status(result)
|
250
|
+
write_last_run(result) if result_exit_status == SimpleCov::ExitCodes::SUCCESS
|
251
|
+
result_exit_status
|
240
252
|
end
|
241
253
|
|
242
254
|
# @api private
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
$stderr.printf(
|
252
|
-
"File (%<file>s) is only (%<least_covered_percentage>.2f%%) covered. This is below the expected minimum coverage per file of (%<min_coverage>.2f%%).\n",
|
253
|
-
file: result.least_covered_file,
|
254
|
-
least_covered_percentage: covered_percentages.min,
|
255
|
-
min_coverage: SimpleCov.minimum_coverage_by_file
|
256
|
-
)
|
257
|
-
SimpleCov::ExitCodes::MINIMUM_COVERAGE
|
258
|
-
elsif (last_run = SimpleCov::LastRun.read)
|
259
|
-
coverage_diff = last_run[:result][:covered_percent] - covered_percent
|
260
|
-
if coverage_diff > SimpleCov.maximum_coverage_drop
|
261
|
-
$stderr.printf(
|
262
|
-
"Coverage has dropped by %<drop_percent>.2f%% since the last time (maximum allowed: %<max_drop>.2f%%).\n",
|
263
|
-
drop_percent: coverage_diff,
|
264
|
-
max_drop: SimpleCov.maximum_coverage_drop
|
265
|
-
)
|
266
|
-
SimpleCov::ExitCodes::MAXIMUM_COVERAGE_DROP
|
267
|
-
else
|
268
|
-
SimpleCov::ExitCodes::SUCCESS
|
269
|
-
end
|
270
|
-
else
|
271
|
-
SimpleCov::ExitCodes::SUCCESS
|
272
|
-
end
|
255
|
+
CoverageLimits = Struct.new(:minimum_coverage, :minimum_coverage_by_file, :maximum_coverage_drop, keyword_init: true)
|
256
|
+
def result_exit_status(result)
|
257
|
+
coverage_limits = CoverageLimits.new(
|
258
|
+
minimum_coverage: minimum_coverage, minimum_coverage_by_file: minimum_coverage_by_file,
|
259
|
+
maximum_coverage_drop: maximum_coverage_drop
|
260
|
+
)
|
261
|
+
|
262
|
+
ExitCodes::ExitCodeHandling.call(result, coverage_limits: coverage_limits)
|
273
263
|
end
|
274
|
-
# rubocop:enable Metrics/MethodLength
|
275
264
|
|
276
265
|
#
|
277
266
|
# @api private
|
278
267
|
#
|
279
268
|
def final_result_process?
|
280
|
-
# checking for ENV["TEST_ENV_NUMBER"] to determine if the
|
281
|
-
!defined?(ParallelTests) || !ENV["TEST_ENV_NUMBER"] || ParallelTests.
|
269
|
+
# checking for ENV["TEST_ENV_NUMBER"] to determine if the tests are being run in parallel
|
270
|
+
!defined?(ParallelTests) || !ENV["TEST_ENV_NUMBER"] || ParallelTests.last_process?
|
282
271
|
end
|
283
272
|
|
284
273
|
#
|
@@ -293,8 +282,19 @@ module SimpleCov
|
|
293
282
|
#
|
294
283
|
# @api private
|
295
284
|
#
|
296
|
-
def write_last_run(
|
297
|
-
SimpleCov::LastRun.write(result:
|
285
|
+
def write_last_run(result)
|
286
|
+
SimpleCov::LastRun.write(result:
|
287
|
+
result.coverage_statistics.transform_values do |stats|
|
288
|
+
round_coverage(stats.percent)
|
289
|
+
end)
|
290
|
+
end
|
291
|
+
|
292
|
+
#
|
293
|
+
# @api private
|
294
|
+
#
|
295
|
+
# Rounding down to be extra strict, see #679
|
296
|
+
def round_coverage(coverage)
|
297
|
+
coverage.floor(2)
|
298
298
|
end
|
299
299
|
|
300
300
|
private
|
@@ -315,7 +315,7 @@ module SimpleCov
|
|
315
315
|
# This blog post gives a good run down of the coverage criterias introduced
|
316
316
|
# in Ruby 2.5: https://blog.bigbinary.com/2018/04/11/ruby-2-5-supports-measuring-branch-and-method-coverages.html
|
317
317
|
# There is also a nice writeup of the different coverage criteria made in this
|
318
|
-
# comment https://github.com/
|
318
|
+
# comment https://github.com/simplecov-ruby/simplecov/pull/692#discussion_r281836176 :
|
319
319
|
# Ruby < 2.5:
|
320
320
|
# https://github.com/ruby/ruby/blob/v1_9_3_374/ext/coverage/coverage.c
|
321
321
|
# traditional mode (Array)
|
@@ -419,61 +419,50 @@ module SimpleCov
|
|
419
419
|
@result = SimpleCov::Result.new(add_not_loaded_files(@result))
|
420
420
|
end
|
421
421
|
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
minimum_expected: percent,
|
427
|
-
actual: result.coverage_statistics[criterion].percent
|
428
|
-
}
|
429
|
-
end
|
422
|
+
# parallel_tests isn't always available, see: https://github.com/grosser/parallel_tests/issues/772
|
423
|
+
def make_parallel_tests_available
|
424
|
+
return if defined?(ParallelTests)
|
425
|
+
return unless probably_running_parallel_tests?
|
430
426
|
|
431
|
-
|
432
|
-
|
433
|
-
|
427
|
+
require "parallel_tests"
|
428
|
+
rescue LoadError
|
429
|
+
warn("SimpleCov guessed you were running inside parallel tests but couldn't load it. Please file a bug report with us!")
|
434
430
|
end
|
435
431
|
|
436
|
-
def
|
437
|
-
|
438
|
-
$stderr.printf(
|
439
|
-
"%<criterion>s coverage (%<covered>.2f%%) is below the expected minimum coverage (%<minimum_coverage>.2f%%).\n",
|
440
|
-
covered: violation.fetch(:actual).floor(2),
|
441
|
-
minimum_coverage: violation.fetch(:minimum_expected),
|
442
|
-
criterion: violation.fetch(:criterion).capitalize
|
443
|
-
)
|
444
|
-
end
|
432
|
+
def probably_running_parallel_tests?
|
433
|
+
ENV["TEST_ENV_NUMBER"] && ENV["PARALLEL_TEST_GROUPS"]
|
445
434
|
end
|
446
435
|
end
|
447
436
|
end
|
448
437
|
|
449
|
-
|
438
|
+
# requires are down here here for a load order reason I'm not sure what it is about
|
450
439
|
require "set"
|
451
440
|
require "forwardable"
|
452
|
-
|
441
|
+
require_relative "simplecov/configuration"
|
453
442
|
SimpleCov.extend SimpleCov::Configuration
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
443
|
+
require_relative "simplecov/coverage_statistics"
|
444
|
+
require_relative "simplecov/exit_codes"
|
445
|
+
require_relative "simplecov/profiles"
|
446
|
+
require_relative "simplecov/source_file/line"
|
447
|
+
require_relative "simplecov/source_file/branch"
|
448
|
+
require_relative "simplecov/source_file"
|
449
|
+
require_relative "simplecov/file_list"
|
450
|
+
require_relative "simplecov/result"
|
451
|
+
require_relative "simplecov/filter"
|
452
|
+
require_relative "simplecov/formatter"
|
453
|
+
require_relative "simplecov/last_run"
|
454
|
+
require_relative "simplecov/lines_classifier"
|
455
|
+
require_relative "simplecov/result_merger"
|
456
|
+
require_relative "simplecov/command_guesser"
|
457
|
+
require_relative "simplecov/version"
|
458
|
+
require_relative "simplecov/result_adapter"
|
459
|
+
require_relative "simplecov/combine"
|
460
|
+
require_relative "simplecov/combine/branches_combiner"
|
461
|
+
require_relative "simplecov/combine/files_combiner"
|
462
|
+
require_relative "simplecov/combine/lines_combiner"
|
463
|
+
require_relative "simplecov/combine/results_combiner"
|
464
|
+
require_relative "simplecov/useless_results_remover"
|
465
|
+
require_relative "simplecov/simulate_coverage"
|
477
466
|
|
478
467
|
# Load default config
|
479
|
-
|
468
|
+
require_relative "simplecov/defaults" unless ENV["SIMPLECOV_NO_DEFAULTS"]
|