kettle-soup-cover 3.0.1 → 3.0.2
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
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +33 -1
- data/README.md +133 -199
- data/lib/kettle/soup/cover/constants.rb +4 -3
- data/lib/kettle/soup/cover/rakelib/coverage.rake +12 -7
- data/lib/kettle/soup/cover/rakelib/turbo_tests.rake +10 -2
- data/lib/kettle/soup/cover/version.rb +1 -1
- data/lib/kettle/soup/cover.rb +0 -22
- data/sig/kettle/soup/cover.rbs +5 -7
- data.tar.gz.sig +0 -0
- metadata +37 -36
- metadata.gz.sig +0 -0
- data/AGPL-3.0-only.md +0 -235
- data/CITATION.cff +0 -20
- data/CODE_OF_CONDUCT.md +0 -134
- data/CONTRIBUTING.md +0 -275
- data/FUNDING.md +0 -70
- data/RUBOCOP.md +0 -71
- data/SECURITY.md +0 -21
- data/certs/pboling.pem +0 -27
- data/lib/kettle/change.rb +0 -39
- data/sig/kettle/soup/cover/version.rbs +0 -10
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8cf644580911fd001cb0626a8d4ccefd16990c3c95006794240ed861e7c4c76c
|
|
4
|
+
data.tar.gz: 61c130cdf6018f5a2076bf8e6d47767b31853a94ba844c828aa5be167286c34f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ad5ff5fc02467a62d6216a42f39d988ecd1e1573e20cb76e080c81b49972a5c8a03e1af365c0b6e87349b501306e6ad38cea7f32d60754f5316c5745338930ff
|
|
7
|
+
data.tar.gz: 553cc07f992ae3f9786b134de937fb89c318722359898f92a71dc8c588145301bedbe522bcb574978e4af9ab0390fd5c6467d764d1f08904f7c8c6517587f4d1
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/CHANGELOG.md
CHANGED
|
@@ -30,6 +30,36 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
30
30
|
|
|
31
31
|
### Security
|
|
32
32
|
|
|
33
|
+
## [3.0.2] - 2026-07-19
|
|
34
|
+
|
|
35
|
+
- TAG: [v3.0.2][3.0.2t]
|
|
36
|
+
- COVERAGE: 100.00% -- 243/243 lines in 12 files
|
|
37
|
+
- BRANCH COVERAGE: 94.12% -- 64/68 branches in 12 files
|
|
38
|
+
- 16.18% documented
|
|
39
|
+
|
|
40
|
+
### Added
|
|
41
|
+
|
|
42
|
+
- Added `Kettle::Soup::Cover::Constants::WASHED_CONSTANTS` as the contract used
|
|
43
|
+
by the spec harness to validate constant reload behavior.
|
|
44
|
+
|
|
45
|
+
### Changed
|
|
46
|
+
|
|
47
|
+
- `kettle-wash` is now a development dependency used by the test harness instead
|
|
48
|
+
of a runtime dependency loaded during coverage bootstrap.
|
|
49
|
+
|
|
50
|
+
- kettle-jem-template-20260716-001 - Shim gemspec manifests now include
|
|
51
|
+
`LICENSE.md` instead of nonexistent `LICENSE.txt`.
|
|
52
|
+
- kettle-jem-template-20260716-002 - Generated gemspec manifests now ship fewer
|
|
53
|
+
repository-only files by default to reduce downstream distro packaging churn.
|
|
54
|
+
|
|
55
|
+
- Updated the README coverage setup, environment variable reference, and
|
|
56
|
+
turbo_tests2 usage notes to match the current implementation.
|
|
57
|
+
|
|
58
|
+
### Fixed
|
|
59
|
+
|
|
60
|
+
- Specs now reset coverage constants through `kettle-wash` instead of the old
|
|
61
|
+
`Kettle::Soup::Cover.reset_const` helper.
|
|
62
|
+
|
|
33
63
|
## [3.0.1] - 2026-07-18
|
|
34
64
|
|
|
35
65
|
- TAG: [v3.0.1][3.0.1t]
|
|
@@ -534,7 +564,9 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
534
564
|
|
|
535
565
|
- Initial release
|
|
536
566
|
|
|
537
|
-
[Unreleased]: https://github.com/kettle-dev/kettle-soup-cover/compare/v3.0.
|
|
567
|
+
[Unreleased]: https://github.com/kettle-dev/kettle-soup-cover/compare/v3.0.2...HEAD
|
|
568
|
+
[3.0.2]: https://github.com/kettle-dev/kettle-soup-cover/compare/v3.0.1...v3.0.2
|
|
569
|
+
[3.0.2t]: https://github.com/kettle-dev/kettle-soup-cover/releases/tag/v3.0.2
|
|
538
570
|
[3.0.1]: https://github.com/kettle-dev/kettle-soup-cover/compare/v3.0.0...v3.0.1
|
|
539
571
|
[3.0.1t]: https://github.com/kettle-dev/kettle-soup-cover/releases/tag/v3.0.1
|
|
540
572
|
[3.0.0]: https://github.com/kettle-dev/kettle-soup-cover/compare/v3.0.0.rc6...v3.0.0
|
data/README.md
CHANGED
|
@@ -21,56 +21,33 @@ I've summarized my thoughts in [this blog post](https://dev.to/galtzo/hostile-ta
|
|
|
21
21
|
|
|
22
22
|
## 🌻 Synopsis <a href="https://discord.gg/3qme4XHNKN"><img alt="Galtzo FLOSS Logo by Aboling0, CC BY-SA 4.0" src="https://logos.galtzo.com/assets/images/galtzo-floss/avatar-128px.svg" width="8%" align="right"/></a> <a href="https://ruby-toolbox.com"><img alt="ruby-lang Logo, Yukihiro Matsumoto, Ruby Visual Identity Team, CC BY-SA 2.5" src="https://logos.galtzo.com/assets/images/ruby-lang/avatar-128px.svg" width="8%" align="right"/></a>
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
`kettle-soup-cover` is a 12-factor SimpleCov harness for Ruby projects. It keeps
|
|
25
|
+
coverage policy in environment variables, configures branch coverage, loads a
|
|
26
|
+
curated formatter stack, isolates `turbo_tests2` worker reports, and can collate
|
|
27
|
+
parallel worker output into one final report.
|
|
25
28
|
|
|
26
|
-
|
|
27
|
-
For apps and libraries. Any test framework. Many code coverage related GitHub Actions (example configs [1](#marocchinosticky-pull-request-comment), [2](#irongutcodecoveragesummary)).
|
|
29
|
+
The normal setup is intentionally small:
|
|
28
30
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
1. Add the gem to your `:development, :test` bundle with `require: false`.
|
|
32
|
+
2. Require `kettle-soup-cover` before loading the app or library under test.
|
|
33
|
+
3. Require `simplecov` and call `SimpleCov.start` only when
|
|
34
|
+
`Kettle::Soup::Cover::DO_COV` is true.
|
|
35
|
+
4. Require `kettle/soup/cover/config` after `simplecov` and before
|
|
36
|
+
`SimpleCov.start`.
|
|
33
37
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
That configuration works for RSpec, Minitest, and other Ruby test runners. In CI,
|
|
39
|
+
coverage is enabled by default from `CI=true`; locally it stays off unless
|
|
40
|
+
`K_SOUP_COV_DO=true` is set. When `turbo_tests2` sets `TEST_ENV_NUMBER`, worker
|
|
41
|
+
coverage is written under `coverage/turbo_tests/<worker>` and hard minimum
|
|
42
|
+
enforcement is deferred until the parent collation step.
|
|
38
43
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
This library's local dev / testing / CI dependency structure serves as an example of a "modular gemfile" pattern
|
|
42
|
-
enabling a discrete gemfile for each CI workflow.
|
|
43
|
-
|
|
44
|
-
<details>
|
|
45
|
-
<summary>What is a modular gemfile?</summary>
|
|
46
|
-
|
|
47
|
-
This modular pattern has the following benefits:
|
|
48
|
-
|
|
49
|
-
- All dependencies are DRY, never repeated.
|
|
50
|
-
- All modular gemfiles are shared between the main `Gemfile`, and the workflow `gemfiles/*.gemfile`s that need them.
|
|
51
|
-
- All gemfiles source from the `gemspec`.
|
|
52
|
-
|
|
53
|
-
If you like this idea, there is an even better alternative.
|
|
54
|
-
|
|
55
|
-
I've codified it for reuse in my [appraisal2](https://github.com/appraisal-rb/appraisal2/) gem,
|
|
56
|
-
which is a hard fork of the venerable `appraisal` gem due to that gem's lack of support for modular gemfiles.
|
|
57
|
-
|
|
58
|
-
</details>
|
|
59
|
-
|
|
60
|
-
📔 ME TOO! 📔
|
|
61
|
-
|
|
62
|
-
### 12-factor
|
|
63
|
-
|
|
64
|
-
One of the major benefits of using this library is not having to figure
|
|
65
|
-
out how to get multiple coverage output formats working. I did that for you,
|
|
66
|
-
and I got all of them working, at the same time together, or al la carte. Kum-ba-ya.
|
|
67
|
-
|
|
68
|
-
A quick shot of 12-factor coverage power, straight to your brain:
|
|
44
|
+
A quick shot of 12-factor coverage power:
|
|
69
45
|
|
|
70
46
|
```console
|
|
71
47
|
export K_SOUP_COV_COMMAND_NAME="RSpec (COVERAGE)" # Display name for the coverage run
|
|
48
|
+
export K_SOUP_COV_CLEAN_RESULTSET=true # Delete stale .resultset.json before SimpleCov.start
|
|
72
49
|
export K_SOUP_COV_DEBUG=false # Enable debug output for configuration (true/false)
|
|
73
|
-
export K_SOUP_COV_DIR=coverage #
|
|
50
|
+
export K_SOUP_COV_DIR=coverage # Root directory where coverage reports are written
|
|
74
51
|
export K_SOUP_COV_DO=true # Enable coverage collection (true/false)
|
|
75
52
|
export K_SOUP_COV_FILTER_DIRS="bin,docs,vendor" # Comma-separated dirs to filter out of coverage
|
|
76
53
|
export K_SOUP_COV_FORMATTERS="html,tty" # Comma-separated list: html,xml,rcov,lcov,json,tty
|
|
@@ -81,7 +58,9 @@ export K_SOUP_COV_MIN_LINE=69 # Minimum required line coverage percentage (integ
|
|
|
81
58
|
export K_SOUP_COV_MULTI_FORMATTERS=true # Enable multiple SimpleCov formatters (true/false)
|
|
82
59
|
export K_SOUP_COV_PREFIX="K_SOUP_COV_" # Prefix used for the envvars (useful for namespacing)
|
|
83
60
|
export K_SOUP_COV_OPEN_BIN=xdg-open # Command to open HTML report in `coverage` rake task (or empty to disable)
|
|
84
|
-
export
|
|
61
|
+
export K_SOUP_COV_TURBO_TESTS=true # Isolate turbo_tests2 worker coverage when TEST_ENV_NUMBER is set
|
|
62
|
+
export K_SOUP_COV_TURBO_TESTS_DIR=turbo_tests # Worker coverage subdirectory below K_SOUP_COV_DIR
|
|
63
|
+
export K_SOUP_COV_USE_MERGING=true # Enable merging of results for parallel/test matrix runs (true/false)
|
|
85
64
|
export K_SOUP_COV_VERBOSE=false # Enable verbose logging (true/false)
|
|
86
65
|
export MAX_ROWS=5 # simplecov-console setting: limits tty output to the worst N rows of uncovered files
|
|
87
66
|
```
|
|
@@ -196,169 +175,136 @@ gem install kettle-soup-cover
|
|
|
196
175
|
|
|
197
176
|
## ⚙️ Configuration
|
|
198
177
|
|
|
199
|
-
|
|
178
|
+
Configure this gem with environment variables. Variable names use
|
|
179
|
+
`K_SOUP_COV_PREFIX`, which defaults to `K_SOUP_COV_`; for example the `DIR`
|
|
180
|
+
setting is read from `K_SOUP_COV_DIR`.
|
|
181
|
+
|
|
182
|
+
| Variable | Default | Purpose |
|
|
183
|
+
|----------|---------|---------|
|
|
184
|
+
| `CI` | `false` | Standard CI flag. Used as the default for `DO` and `MIN_HARD`. |
|
|
185
|
+
| `K_SOUP_COV_CLEAN_RESULTSET` | `true` locally, `false` on CI and in turbo workers | Deletes stale `.resultset.json` before `SimpleCov.start`. Set `false` for spawned subprocess coverage so one process does not wipe another process' resultset. |
|
|
186
|
+
| `K_SOUP_COV_COMMAND_NAME` | `RSpec (COVERAGE)` | SimpleCov command name. Workers become `COMMAND_NAME (turbo_tests2 worker N)`. |
|
|
187
|
+
| `K_SOUP_COV_DEBUG` | `false` | Enables debug-oriented constants. |
|
|
188
|
+
| `K_SOUP_COV_DIR` | `coverage` | Root coverage directory. Workers use `DIR/TURBO_TESTS_DIR/TEST_ENV_NUMBER`. |
|
|
189
|
+
| `K_SOUP_COV_DO` | `CI` | Enables the caller's `require "simplecov"` / `SimpleCov.start` block. |
|
|
190
|
+
| `K_SOUP_COV_FILTER_DIRS` | `bin,certs,checksums,config,coverage,docs,features,gemfiles,pkg,results,sig,spec,src,test,test-results,vendor` | Comma-separated root directories skipped by SimpleCov. |
|
|
191
|
+
| `K_SOUP_COV_FORMATTERS` | `html,xml,rcov,lcov,json,tty` on CI; `html,tty` locally | Formatter list. Supported values are `html`, `xml`, `rcov`, `lcov`, `json`, and `tty`. |
|
|
192
|
+
| `K_SOUP_COV_MERGE_TIMEOUT` | `3600` | SimpleCov merge timeout in seconds when merging is enabled. |
|
|
193
|
+
| `K_SOUP_COV_MIN_BRANCH` | `80` | Branch coverage minimum. |
|
|
194
|
+
| `K_SOUP_COV_MIN_HARD` | `CI` | Fails the run when minimums are missed. Worker processes always defer hard enforcement to collation. |
|
|
195
|
+
| `K_SOUP_COV_MIN_LINE` | `80` | Line coverage minimum. |
|
|
196
|
+
| `K_SOUP_COV_MULTI_FORMATTERS` | `true` on CI; otherwise `true` when any formatter is configured | Uses SimpleCov's multi-formatter support. |
|
|
197
|
+
| `K_SOUP_COV_OPEN_BIN` | `open` on macOS, `xdg-open` elsewhere | Browser-opening command for `rake coverage`. Set empty to only print the report path. |
|
|
198
|
+
| `K_SOUP_COV_PREFIX` | `K_SOUP_COV_` | Alternate namespace for all `K_SOUP_COV_*` variables. |
|
|
199
|
+
| `K_SOUP_COV_TURBO_TESTS` | `true` | Enables turbo_tests2 worker coverage isolation when `TEST_ENV_NUMBER` is present. |
|
|
200
|
+
| `K_SOUP_COV_TURBO_TESTS_DIR` | `turbo_tests` | Subdirectory for worker coverage under `K_SOUP_COV_DIR`. |
|
|
201
|
+
| `K_SOUP_COV_USE_MERGING` | `true` | Enables SimpleCov result merging. |
|
|
202
|
+
| `K_SOUP_COV_VERBOSE` | `false` | Enables verbose-oriented constants. |
|
|
203
|
+
| `MAX_ROWS` | formatter-defined | Passed through to `simplecov-console`; `MAX_ROWS=0` removes the `tty` formatter. |
|
|
204
|
+
| `TEST_ENV_NUMBER` | empty | Set by parallel test tools. Non-empty values mark a turbo_tests2 worker. |
|
|
200
205
|
|
|
201
|
-
|
|
206
|
+
## 🔧 Basic Usage
|
|
207
|
+
|
|
208
|
+
### Gemfile
|
|
209
|
+
|
|
210
|
+
Use `require: false` so coverage starts exactly where your test helper starts it.
|
|
211
|
+
Keep the gem in both `:development` and `:test` if you want the bundled
|
|
212
|
+
`coverage` rake task locally.
|
|
202
213
|
|
|
203
214
|
```ruby
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
# then run remaining specs. This ensures FFI tests get a clean environment
|
|
207
|
-
# while still validating that BackendConflict protection works.
|
|
208
|
-
#
|
|
209
|
-
# For coverage aggregation with SimpleCov merging:
|
|
210
|
-
# - Each task uses a unique K_SOUP_COV_COMMAND_NAME so SimpleCov tracks them separately
|
|
211
|
-
# - K_SOUP_COV_USE_MERGING=true must be set in .envrc for results to merge
|
|
212
|
-
# - K_SOUP_COV_MERGE_TIMEOUT should be set long enough for all tasks to complete
|
|
213
|
-
begin
|
|
214
|
-
require "rspec/core/rake_task"
|
|
215
|
-
|
|
216
|
-
# FFI specs run first in a clean environment
|
|
217
|
-
desc("Run FFI backend specs first (before MRI loads)")
|
|
218
|
-
RSpec::Core::RakeTask.new(:ffi_specs) do |t|
|
|
219
|
-
t.pattern = "./spec/**/*_spec.rb"
|
|
220
|
-
t.rspec_opts = "--tag ffi"
|
|
221
|
-
end
|
|
222
|
-
# Set unique command name at execution time for SimpleCov merging
|
|
223
|
-
desc("Set SimpleCov command name for FFI specs")
|
|
224
|
-
task(:set_ffi_command_name) do
|
|
225
|
-
ENV["K_SOUP_COV_COMMAND_NAME"] = "FFI Specs"
|
|
226
|
-
end
|
|
227
|
-
Rake::Task[:ffi_specs].enhance([:set_ffi_command_name])
|
|
228
|
-
|
|
229
|
-
# Matrix checks will run in between FFI and MRI
|
|
230
|
-
desc("Run Backend Matrix Specs")
|
|
231
|
-
RSpec::Core::RakeTask.new(:backend_matrix_specs) do |t|
|
|
232
|
-
t.pattern = "./spec_matrix/**/*_spec.rb"
|
|
233
|
-
end
|
|
234
|
-
desc("Set SimpleCov command name for backend matrix specs")
|
|
235
|
-
task(:set_matrix_command_name) do
|
|
236
|
-
ENV["K_SOUP_COV_COMMAND_NAME"] = "Backend Matrix Specs"
|
|
237
|
-
end
|
|
238
|
-
Rake::Task[:backend_matrix_specs].enhance([:set_matrix_command_name])
|
|
239
|
-
|
|
240
|
-
# All other specs run after FFI specs
|
|
241
|
-
desc("Run non-FFI specs (after FFI specs have run)")
|
|
242
|
-
RSpec::Core::RakeTask.new(:remaining_specs) do |t|
|
|
243
|
-
t.pattern = "./spec/**/*_spec.rb"
|
|
244
|
-
t.rspec_opts = "--tag ~ffi"
|
|
245
|
-
end
|
|
246
|
-
desc("Set SimpleCov command name for remaining specs")
|
|
247
|
-
task(:set_remaining_command_name) do
|
|
248
|
-
ENV["K_SOUP_COV_COMMAND_NAME"] = "Remaining Specs"
|
|
249
|
-
end
|
|
250
|
-
Rake::Task[:remaining_specs].enhance([:set_remaining_command_name])
|
|
251
|
-
|
|
252
|
-
# Final task to run all specs (for spec task, runs in single process for final coverage merge)
|
|
253
|
-
desc("Run all specs in one process (no FFI isolation)")
|
|
254
|
-
RSpec::Core::RakeTask.new(:all_specs) do |t|
|
|
255
|
-
t.pattern = "spec/**{,/*/**}/*_spec.rb"
|
|
256
|
-
end
|
|
257
|
-
desc("Set SimpleCov command name for all specs")
|
|
258
|
-
task(:set_all_command_name) do
|
|
259
|
-
ENV["K_SOUP_COV_COMMAND_NAME"] = "All Specs"
|
|
260
|
-
end
|
|
261
|
-
Rake::Task[:all_specs].enhance([:set_all_command_name])
|
|
262
|
-
|
|
263
|
-
# Override the default spec task to run in sequence
|
|
264
|
-
# NOTE: We do NOT include :all_specs here because ffi_specs + remaining_specs already
|
|
265
|
-
# cover all specs. Including all_specs would cause duplicated test runs.
|
|
266
|
-
Rake::Task[:spec].clear if Rake::Task.task_defined?(:spec)
|
|
267
|
-
desc("Run specs with FFI tests first, then backend matrix, then remaining tests")
|
|
268
|
-
task(spec: [:ffi_specs, :backend_matrix_specs, :remaining_specs]) # rubocop:disable Rake/DuplicateTask
|
|
269
|
-
rescue LoadError
|
|
270
|
-
desc("(stub) spec is unavailable")
|
|
271
|
-
task(:spec) do # rubocop:disable Rake/DuplicateTask
|
|
272
|
-
warn("NOTE: rspec isn't installed, or is disabled for #{RUBY_VERSION} in the current environment")
|
|
273
|
-
end
|
|
215
|
+
group :development, :test do
|
|
216
|
+
gem "kettle-soup-cover", "~> 3.0", require: false
|
|
274
217
|
end
|
|
275
218
|
```
|
|
276
219
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
### RSpec or MiniTest
|
|
220
|
+
### RSpec, Minitest, or another Ruby test runner
|
|
280
221
|
|
|
281
|
-
In your
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
222
|
+
In your test helper, require `kettle-soup-cover` before loading the library or
|
|
223
|
+
application under test. Start SimpleCov only when `DO_COV` is true. Requiring
|
|
224
|
+
`simplecov` loads the project-local `.simplecov`, so limit that file to
|
|
225
|
+
project-local `SimpleCov.configure` rules and load `kettle/soup/cover/config`
|
|
226
|
+
in the helper:
|
|
285
227
|
|
|
286
228
|
```ruby
|
|
287
229
|
require "kettle-soup-cover"
|
|
230
|
+
|
|
288
231
|
if Kettle::Soup::Cover::DO_COV
|
|
289
232
|
require "simplecov"
|
|
290
|
-
|
|
291
|
-
#
|
|
233
|
+
require "kettle/soup/cover/config"
|
|
234
|
+
# Minitest users that rely on SimpleCov's external at_exit handling should set:
|
|
292
235
|
# SimpleCov.external_at_exit = true
|
|
236
|
+
SimpleCov.start
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
# Now load your app or library under test.
|
|
240
|
+
require "my_gem"
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Use `.simplecov` only for project-local SimpleCov rules, such as the files this
|
|
244
|
+
project should cover:
|
|
245
|
+
|
|
246
|
+
```ruby
|
|
247
|
+
SimpleCov.configure do
|
|
248
|
+
cover "lib/**/*.rb", "lib/**/*.rake", "exe/*.rb"
|
|
293
249
|
end
|
|
294
250
|
```
|
|
295
251
|
|
|
296
|
-
|
|
252
|
+
### Rails and RSpec
|
|
297
253
|
|
|
298
|
-
In
|
|
254
|
+
In Rails, start coverage after `spec_helper` is loaded and before Rails boots:
|
|
299
255
|
|
|
300
256
|
```ruby
|
|
301
|
-
# External gems
|
|
302
257
|
require "kettle-soup-cover"
|
|
303
|
-
|
|
304
|
-
# This file is copied to spec/ when you run 'rails generate rspec:install'
|
|
305
|
-
# We provide a preconfigured version compatible with Rails 8
|
|
306
258
|
require "spec_helper"
|
|
259
|
+
|
|
307
260
|
ENV["RAILS_ENV"] ||= "test"
|
|
308
261
|
|
|
309
|
-
# Last thing before loading the app-under-test is code coverage.
|
|
310
262
|
if Kettle::Soup::Cover::DO_COV
|
|
311
263
|
require "simplecov"
|
|
264
|
+
require "kettle/soup/cover/config"
|
|
312
265
|
SimpleCov.start
|
|
313
266
|
end
|
|
267
|
+
|
|
314
268
|
require File.expand_path("../config/environment", __dir__)
|
|
315
269
|
```
|
|
316
270
|
|
|
317
|
-
|
|
318
|
-
|
|
271
|
+
### Rake tasks
|
|
272
|
+
|
|
273
|
+
Define a `test` task, then install this gem's local `coverage` task:
|
|
319
274
|
|
|
320
275
|
```ruby
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
276
|
+
require "kettle-soup-cover"
|
|
277
|
+
Kettle::Soup::Cover.install_tasks
|
|
278
|
+
|
|
279
|
+
desc "Run specs through the test task expected by kettle-soup-cover"
|
|
280
|
+
task test: :spec
|
|
324
281
|
```
|
|
325
282
|
|
|
326
|
-
|
|
283
|
+
`rake coverage` forces coverage on, resets coverage constants through
|
|
284
|
+
`kettle-wash`, invokes `test`, and opens `K_SOUP_COV_DIR/index.html` unless
|
|
285
|
+
`K_SOUP_COV_OPEN_BIN` is empty.
|
|
327
286
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
require "kettle-soup-cover"
|
|
333
|
-
|
|
334
|
-
if Kettle::Soup::Cover::DO_COV
|
|
335
|
-
require "simplecov"
|
|
336
|
-
SimpleCov.start
|
|
337
|
-
|
|
338
|
-
# IMPORTANT: If you are using MiniTest instead of RSpec, also do this (and not in .simplecov):
|
|
339
|
-
# SimpleCov.external_at_exit = true
|
|
340
|
-
end
|
|
341
|
-
rescue LoadError => error
|
|
342
|
-
# check the error message, if you are so inclined, and re-raise if not what is expected
|
|
343
|
-
raise error unless error.message.include?("kettle")
|
|
344
|
-
end
|
|
345
|
-
```
|
|
287
|
+
### turbo_tests2 coverage
|
|
288
|
+
|
|
289
|
+
When `K_SOUP_COV_TURBO_TESTS=true` and `TEST_ENV_NUMBER` is non-empty,
|
|
290
|
+
`kettle-soup-cover` treats the process as a worker:
|
|
346
291
|
|
|
347
|
-
|
|
292
|
+
- `K_SOUP_COV_DIR` remains the root coverage directory.
|
|
293
|
+
- worker output goes to `K_SOUP_COV_DIR/K_SOUP_COV_TURBO_TESTS_DIR/TEST_ENV_NUMBER`;
|
|
294
|
+
- worker command names include the worker number;
|
|
295
|
+
- `SimpleCov.finalize_merge(false)` is applied in workers;
|
|
296
|
+
- hard coverage minimums are disabled in workers and enforced during parent collation.
|
|
348
297
|
|
|
349
|
-
|
|
298
|
+
The installed tasks provide both `turbo_tests:*` and `turbo_tests2:*` names:
|
|
350
299
|
|
|
351
300
|
```ruby
|
|
352
|
-
|
|
301
|
+
Kettle::Soup::Cover.install_tasks
|
|
353
302
|
```
|
|
354
303
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
which is configured by default on CI. To replicate that locally you could:
|
|
304
|
+
Use `turbo_tests:setup` before workers and `turbo_tests:cleanup` after workers
|
|
305
|
+
when your runner does not invoke those hooks automatically.
|
|
358
306
|
|
|
359
|
-
|
|
360
|
-
CI=true bundle exec rake test # or whatever command you run for tests.
|
|
361
|
-
```
|
|
307
|
+
### Coverage JSON analyzer
|
|
362
308
|
|
|
363
309
|
To inspect the current local coverage report, use the bundled analyzer:
|
|
364
310
|
|
|
@@ -375,31 +321,6 @@ pass it explicitly:
|
|
|
375
321
|
bin/kettle-soup-cover -p coverage/coverage.json
|
|
376
322
|
```
|
|
377
323
|
|
|
378
|
-
That's it!
|
|
379
|
-
|
|
380
|
-
### Rakefile
|
|
381
|
-
|
|
382
|
-
You'll need to have your `test` task defined.
|
|
383
|
-
If you use `spec` instead, you can make it a pre-requisite of the `test` task with:
|
|
384
|
-
|
|
385
|
-
```ruby
|
|
386
|
-
desc "run spec task with test task"
|
|
387
|
-
task test: :spec
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
This gem provides a `coverage` task.
|
|
391
|
-
It runs the `test` task (see just above about that),
|
|
392
|
-
and opens the coverage results in a browser.
|
|
393
|
-
|
|
394
|
-
```ruby
|
|
395
|
-
require "kettle-soup-cover"
|
|
396
|
-
Kettle::Soup::Cover.install_tasks
|
|
397
|
-
```
|
|
398
|
-
|
|
399
|
-
### kettle-soup-cover (exe/kettle-soup-cover)
|
|
400
|
-
|
|
401
|
-
This gem ships a small helper binary `kettle-soup-cover` under `exe/kettle-soup-cover`. It consumes a SimpleCov JSON output (coverage/coverage.json) and prints a readable, summarized report of lines and branches. The script will, by default, look for `coverage/coverage.json` in the directory configured by `K_SOUP_COV_DIR` (defaults to `coverage`).
|
|
402
|
-
|
|
403
324
|
Usage examples:
|
|
404
325
|
|
|
405
326
|
```
|
|
@@ -418,7 +339,8 @@ Notes:
|
|
|
418
339
|
|
|
419
340
|
### Filters
|
|
420
341
|
|
|
421
|
-
There are two built-in SimpleCov filters which can be loaded via
|
|
342
|
+
There are two built-in SimpleCov filters which can be loaded via
|
|
343
|
+
`Kettle::Soup::Cover.load_filters`.
|
|
422
344
|
|
|
423
345
|
You could use them like this:
|
|
424
346
|
|
|
@@ -429,7 +351,7 @@ SimpleCov.add_group("Too Long", Kettle::Soup::Cover::Filters::GtLineFilter.new(1
|
|
|
429
351
|
### Advanced Usage
|
|
430
352
|
|
|
431
353
|
There are a number of ENV variables that control things within this gem.
|
|
432
|
-
All of them can be found, along with their default values, in [lib/kettle/soup/cover.rb][env-constants].
|
|
354
|
+
All of them can be found, along with their default values, in [lib/kettle/soup/cover/constants.rb][env-constants].
|
|
433
355
|
|
|
434
356
|
#### Handy List of ENV Variables
|
|
435
357
|
|
|
@@ -454,7 +376,7 @@ Below is a reference for the environment variables used by this gem. Each sectio
|
|
|
454
376
|
#### K_SOUP_COV_DIR
|
|
455
377
|
|
|
456
378
|
- Default: `coverage`
|
|
457
|
-
- What it controls:
|
|
379
|
+
- What it controls: Root directory where SimpleCov writes coverage reports. Turbo worker processes write under `K_SOUP_COV_DIR/K_SOUP_COV_TURBO_TESTS_DIR/TEST_ENV_NUMBER`. The `exe/kettle-soup-cover` script and rake tasks look here for artifacts like `coverage.json` or `index.html`.
|
|
458
380
|
- Example: `export K_SOUP_COV_DIR=my-coverage`
|
|
459
381
|
|
|
460
382
|
#### K_SOUP_COV_DO
|
|
@@ -479,7 +401,7 @@ Note: the `exe/kettle-soup-cover` script requires that the `json` formatter be e
|
|
|
479
401
|
|
|
480
402
|
#### K_SOUP_COV_CLEAN_RESULTSET
|
|
481
403
|
|
|
482
|
-
- Default: `false` on CI; `true` locally.
|
|
404
|
+
- Default: `false` on CI and in turbo worker processes; `true` locally.
|
|
483
405
|
- What it controls: When true, deletes `coverage/.resultset.json` before SimpleCov starts. This prevents stale entries from prior runs (e.g., after a refactor that shifts line/branch numbers) from polluting the current run's coverage report. In CI each job starts from a clean workspace so this is unnecessary; locally developers re-run tests frequently and stale entries accumulate.
|
|
484
406
|
- Example: `export K_SOUP_COV_CLEAN_RESULTSET=false`
|
|
485
407
|
|
|
@@ -487,7 +409,7 @@ Note: the `exe/kettle-soup-cover` script requires that the `json` formatter be e
|
|
|
487
409
|
|
|
488
410
|
#### K_SOUP_COV_MERGE_TIMEOUT
|
|
489
411
|
|
|
490
|
-
- Default: `
|
|
412
|
+
- Default: `3600`
|
|
491
413
|
- What it controls: When using merging (`K_SOUP_COV_USE_MERGING=true`), this sets a numeric timeout in seconds for the merge operation.
|
|
492
414
|
- Example: `export K_SOUP_COV_MERGE_TIMEOUT=3600`
|
|
493
415
|
|
|
@@ -499,8 +421,8 @@ Note: the `exe/kettle-soup-cover` script requires that the `json` formatter be e
|
|
|
499
421
|
|
|
500
422
|
#### K_SOUP_COV_MIN_HARD
|
|
501
423
|
|
|
502
|
-
- Default: Uses `CI` if unset (`CI=false` default).
|
|
503
|
-
- What it controls: Whether failing coverage thresholds should fail the run (hard failure) or only warn.
|
|
424
|
+
- Default: Uses `CI` if unset (`CI=false` default). Worker processes always use `false`.
|
|
425
|
+
- What it controls: Whether failing coverage thresholds should fail the run (hard failure) or only warn. In turbo_tests2 worker processes, hard enforcement is deferred to the parent collation process.
|
|
504
426
|
- Example: `export K_SOUP_COV_MIN_HARD=true`
|
|
505
427
|
|
|
506
428
|
#### K_SOUP_COV_MIN_LINE
|
|
@@ -527,9 +449,21 @@ Note: the `exe/kettle-soup-cover` script requires that the `json` formatter be e
|
|
|
527
449
|
- What it controls: Command used by the Rake `coverage` task to open the HTML report. Set to an empty value to disable auto-opening and just print report locations.
|
|
528
450
|
- Example: `export K_SOUP_COV_OPEN_BIN=xdg-open` or `export K_SOUP_COV_OPEN_BIN=` (to only print the path)
|
|
529
451
|
|
|
452
|
+
#### K_SOUP_COV_TURBO_TESTS
|
|
453
|
+
|
|
454
|
+
- Default: `true`
|
|
455
|
+
- What it controls: Enables turbo_tests2 worker isolation when `TEST_ENV_NUMBER` is non-empty.
|
|
456
|
+
- Example: `export K_SOUP_COV_TURBO_TESTS=true`
|
|
457
|
+
|
|
458
|
+
#### K_SOUP_COV_TURBO_TESTS_DIR
|
|
459
|
+
|
|
460
|
+
- Default: `turbo_tests`
|
|
461
|
+
- What it controls: Subdirectory under `K_SOUP_COV_DIR` for worker coverage output.
|
|
462
|
+
- Example: `export K_SOUP_COV_TURBO_TESTS_DIR=parallel`
|
|
463
|
+
|
|
530
464
|
#### K_SOUP_COV_USE_MERGING
|
|
531
465
|
|
|
532
|
-
- Default: `
|
|
466
|
+
- Default: `true`
|
|
533
467
|
- What it controls: When true, enables result merging semantics for multiple test runs (works with merge timeout and other behaviors).
|
|
534
468
|
- Example: `export K_SOUP_COV_USE_MERGING=true`
|
|
535
469
|
|
|
@@ -544,7 +478,7 @@ Note: Some third-party formatters may also read their own environment variables.
|
|
|
544
478
|
Additionally, some of the included gems, like [`simplecov-console`][simplecov-console],
|
|
545
479
|
have their own complete suite of ENV variables you can configure.
|
|
546
480
|
|
|
547
|
-
[env-constants]: /lib/kettle/soup/cover.rb
|
|
481
|
+
[env-constants]: /lib/kettle/soup/cover/constants.rb
|
|
548
482
|
[simplecov-console]: https://github.com/chetan/simplecov-console#options
|
|
549
483
|
|
|
550
484
|
#### Compatible with GitHub Actions for Code Coverage feedback in pull requests
|
|
@@ -878,7 +812,7 @@ Thanks for RTFM. ☺️
|
|
|
878
812
|
[📌gitmoji]: https://gitmoji.dev
|
|
879
813
|
[📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
|
|
880
814
|
[🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
|
881
|
-
[🧮kloc-img]: https://img.shields.io/badge/KLOC-0.
|
|
815
|
+
[🧮kloc-img]: https://img.shields.io/badge/KLOC-0.243-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
|
|
882
816
|
[🔐security]: https://github.com/kettle-dev/kettle-soup-cover/blob/main/SECURITY.md
|
|
883
817
|
[🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
|
|
884
818
|
[📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
|
|
@@ -127,7 +127,7 @@ module Kettle
|
|
|
127
127
|
MERGE_TIMEOUT = ENV_GET.call("MERGE_TIMEOUT", "3600").to_i
|
|
128
128
|
VERBOSE = ENV_GET.call("VERBOSE", Constants::FALSE).casecmp?(Constants::TRUE)
|
|
129
129
|
|
|
130
|
-
|
|
130
|
+
WASHED_CONSTANTS = {
|
|
131
131
|
constants: %w[
|
|
132
132
|
CI
|
|
133
133
|
CLEAN_RESULTSET
|
|
@@ -160,9 +160,10 @@ module Kettle
|
|
|
160
160
|
TURBO_TESTS_WORKER
|
|
161
161
|
USE_MERGING
|
|
162
162
|
VERBOSE
|
|
163
|
+
WASHED_CONSTANTS
|
|
163
164
|
],
|
|
164
|
-
path:
|
|
165
|
-
|
|
165
|
+
path: File.expand_path(__FILE__)
|
|
166
|
+
}.freeze
|
|
166
167
|
end
|
|
167
168
|
end
|
|
168
169
|
end
|
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
# NOTE: This is not for CI, only for local development.
|
|
2
|
+
require "kettle/wash"
|
|
2
3
|
require "shellwords"
|
|
3
4
|
|
|
5
|
+
constants_path = File.expand_path("../constants.rb", __dir__)
|
|
6
|
+
load constants_path unless Kettle::Soup::Cover::Constants.const_defined?(:WASHED_CONSTANTS, false)
|
|
7
|
+
washed_constants = Kettle::Soup::Cover::Constants::WASHED_CONSTANTS
|
|
8
|
+
|
|
4
9
|
desc "Run specs w/ coverage and open results in browser"
|
|
5
10
|
task :coverage do
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
ENV["K_SOUP_COV_PREFIX"] = "K_SOUP_COV_"
|
|
12
|
+
ENV["K_SOUP_COV_DO"] = "true"
|
|
13
|
+
ENV["K_SOUP_COV_MULTI_FORMATTERS"] = "true"
|
|
14
|
+
ENV["K_SOUP_COV_FORMATTERS"] ||= "html"
|
|
15
|
+
ENV["K_SOUP_COV_DIR"] ||= "coverage"
|
|
16
|
+
Kettle::Wash.reset_constants(owner: Kettle::Soup::Cover::Constants, **washed_constants)
|
|
17
|
+
|
|
13
18
|
Rake::Task["test"].invoke
|
|
14
19
|
html_report = "#{Kettle::Soup::Cover::COVERAGE_DIR}/index.html"
|
|
15
20
|
if Kettle::Soup::Cover::OPEN_BIN.empty?
|
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
restore_cover_modules = lambda do
|
|
4
|
+
load File.expand_path("../constants.rb", __dir__) unless Kettle::Soup::Cover.const_defined?(:Constants, false)
|
|
5
|
+
Kettle::Soup::Cover.include(Kettle::Soup::Cover::Constants) unless Kettle::Soup::Cover.ancestors.include?(Kettle::Soup::Cover::Constants)
|
|
6
|
+
|
|
7
|
+
load File.expand_path("../loaders.rb", __dir__) unless Kettle::Soup::Cover.const_defined?(:Loaders, false)
|
|
8
|
+
Kettle::Soup::Cover.extend(Kettle::Soup::Cover::Loaders)
|
|
9
|
+
end
|
|
10
|
+
|
|
3
11
|
namespace :turbo_tests do
|
|
4
12
|
desc "Prepare shared SimpleCov coverage output for turbo_tests2 workers"
|
|
5
13
|
task :setup do
|
|
6
|
-
|
|
14
|
+
restore_cover_modules.call
|
|
7
15
|
if Kettle::Soup::Cover.turbo_tests_coverage?
|
|
8
16
|
Kettle::Soup::Cover.clear_coverage_dir!
|
|
9
17
|
end
|
|
@@ -11,7 +19,7 @@ namespace :turbo_tests do
|
|
|
11
19
|
|
|
12
20
|
desc "Collate turbo_tests2 worker coverage reports"
|
|
13
21
|
task :cleanup do
|
|
14
|
-
|
|
22
|
+
restore_cover_modules.call
|
|
15
23
|
Kettle::Soup::Cover.collate_turbo_tests_coverage!
|
|
16
24
|
end
|
|
17
25
|
end
|