kettle-test 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +30 -0
- data/CITATION.cff +20 -0
- data/CODE_OF_CONDUCT.md +134 -0
- data/CONTRIBUTING.md +143 -0
- data/LICENSE.txt +21 -0
- data/README.md +676 -0
- data/REEK +0 -0
- data/RUBOCOP.md +71 -0
- data/SECURITY.md +21 -0
- data/checksums/kettle-test-1.0.0.gem.sha256 +1 -0
- data/checksums/kettle-test-1.0.0.gem.sha512 +1 -0
- data/lib/kettle/test/config/ext/rspec/rspec_stubbed_env.rb +5 -0
- data/lib/kettle/test/config/ext/rspec/silent_stream.rb +5 -0
- data/lib/kettle/test/config/ext/timecop.rb +17 -0
- data/lib/kettle/test/config/int/rspec/rspec_core.rb +37 -0
- data/lib/kettle/test/config/int/rspec/silent_stream.rb +20 -0
- data/lib/kettle/test/config/int/rspec/timecop_rspec.rb +33 -0
- data/lib/kettle/test/config/int/rspec_block_is_expected.rb +6 -0
- data/lib/kettle/test/config/version_gem.rb +6 -0
- data/lib/kettle/test/external.rb +42 -0
- data/lib/kettle/test/internal.rb +23 -0
- data/lib/kettle/test/rspec.rb +7 -0
- data/lib/kettle/test/version.rb +12 -0
- data/lib/kettle/test.rb +60 -0
- data/sig/kettle/test.rbs +27 -0
- data.tar.gz.sig +0 -0
- metadata +342 -0
- metadata.gz.sig +0 -0
data/REEK
ADDED
File without changes
|
data/RUBOCOP.md
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
# RuboCop Usage Guide
|
2
|
+
|
3
|
+
## Overview
|
4
|
+
|
5
|
+
A tale of two RuboCop plugin gems.
|
6
|
+
|
7
|
+
### RuboCop Gradual
|
8
|
+
|
9
|
+
This project uses `rubocop_gradual` instead of vanilla RuboCop for code style checking. The `rubocop_gradual` tool allows for gradual adoption of RuboCop rules by tracking violations in a lock file.
|
10
|
+
|
11
|
+
### RuboCop LTS
|
12
|
+
|
13
|
+
This project uses `rubocop-lts` to ensure, on a best-effort basis, compatibility with Ruby >= 1.9.2.
|
14
|
+
RuboCop rules are meticulously configured by the `rubocop-lts` family of gems to ensure that a project is compatible with a specific version of Ruby. See: https://rubocop-lts.gitlab.io for more.
|
15
|
+
|
16
|
+
## Checking RuboCop Violations
|
17
|
+
|
18
|
+
To check for RuboCop violations in this project, always use:
|
19
|
+
|
20
|
+
```bash
|
21
|
+
bundle exec rake rubocop_gradual:check
|
22
|
+
```
|
23
|
+
|
24
|
+
**Do not use** the standard RuboCop commands like:
|
25
|
+
- `bundle exec rubocop`
|
26
|
+
- `rubocop`
|
27
|
+
|
28
|
+
## Understanding the Lock File
|
29
|
+
|
30
|
+
The `.rubocop_gradual.lock` file tracks all current RuboCop violations in the project. This allows the team to:
|
31
|
+
|
32
|
+
1. Prevent new violations while gradually fixing existing ones
|
33
|
+
2. Track progress on code style improvements
|
34
|
+
3. Ensure CI builds don't fail due to pre-existing violations
|
35
|
+
|
36
|
+
## Common Commands
|
37
|
+
|
38
|
+
- **Check violations**
|
39
|
+
- `bundle exec rake rubocop_gradual`
|
40
|
+
- `bundle exec rake rubocop_gradual:check`
|
41
|
+
- **(Safe) Autocorrect violations, and update lockfile if no new violations**
|
42
|
+
- `bundle exec rake rubocop_gradual:autocorrect`
|
43
|
+
- **Force update the lock file (w/o autocorrect) to match violations present in code**
|
44
|
+
- `bundle exec rake rubocop_gradual:force_update`
|
45
|
+
|
46
|
+
## Workflow
|
47
|
+
|
48
|
+
1. Before submitting a PR, run `bundle exec rake rubocop_gradual:autocorrect`
|
49
|
+
a. or just the default `bundle exec rake`, as autocorrection is a pre-requisite of the default task.
|
50
|
+
2. If there are new violations, either:
|
51
|
+
- Fix them in your code
|
52
|
+
- Run `bundle exec rake rubocop_gradual:force_update` to update the lock file (only for violations you can't fix immediately)
|
53
|
+
3. Commit the updated `.rubocop_gradual.lock` file along with your changes
|
54
|
+
|
55
|
+
## Never add inline RuboCop disables
|
56
|
+
|
57
|
+
Do not add inline `rubocop:disable` / `rubocop:enable` comments anywhere in the codebase (including specs, except when following the few existing `rubocop:disable` patterns for a rule already being disabled elsewhere in the code). We handle exceptions in two supported ways:
|
58
|
+
|
59
|
+
- Permanent/structural exceptions: prefer adjusting the RuboCop configuration (e.g., in `.rubocop.yml`) to exclude a rule for a path or file pattern when it makes sense project-wide.
|
60
|
+
- Temporary exceptions while improving code: record the current violations in `.rubocop_gradual.lock` via the gradual workflow:
|
61
|
+
- `bundle exec rake rubocop_gradual:autocorrect` (preferred; will autocorrect what it can and update the lock only if no new violations were introduced)
|
62
|
+
- If needed, `bundle exec rake rubocop_gradual:force_update` (as a last resort when you cannot fix the newly reported violations immediately)
|
63
|
+
|
64
|
+
In general, treat the rules as guidance to follow; fix violations rather than ignore them. For example, RSpec conventions in this project expect `described_class` to be used in specs that target a specific class under test.
|
65
|
+
|
66
|
+
## Benefits of rubocop_gradual
|
67
|
+
|
68
|
+
- Allows incremental adoption of code style rules
|
69
|
+
- Prevents CI failures due to pre-existing violations
|
70
|
+
- Provides a clear record of code style debt
|
71
|
+
- Enables focused efforts on improving code quality over time
|
data/SECURITY.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# Security Policy
|
2
|
+
|
3
|
+
## Supported Versions
|
4
|
+
|
5
|
+
| Version | Supported |
|
6
|
+
|----------|-----------|
|
7
|
+
| 1.latest | ✅ |
|
8
|
+
|
9
|
+
## Security contact information
|
10
|
+
|
11
|
+
To report a security vulnerability, please use the
|
12
|
+
[Tidelift security contact](https://tidelift.com/security).
|
13
|
+
Tidelift will coordinate the fix and disclosure.
|
14
|
+
|
15
|
+
## Additional Support
|
16
|
+
|
17
|
+
If you are interested in support for versions older than the latest release,
|
18
|
+
please consider sponsoring the project / maintainer @ https://liberapay.com/pboling/donate,
|
19
|
+
or find other sponsorship links in the [README].
|
20
|
+
|
21
|
+
[README]: README.md
|
@@ -0,0 +1 @@
|
|
1
|
+
9e529e9db55bdb257b7e16929e09a2704c7453cc3ed4811ed48aa6a681b3a634
|
@@ -0,0 +1 @@
|
|
1
|
+
8968cc13a3547f3a36a24ff8e307a66b4bc6f6c317db9e9677f4a8f0f5f22648ae7d563f4eb5617580987f45817c2efa96e253dc55e38c1dde20a90f4377e9fc
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "timecop"
|
2
|
+
|
3
|
+
# NOTE: Instead of using Timecop directly, prefer to use the utilities provided by Timecop::Rspec.
|
4
|
+
# See spec/support/config/timecop_rspec.rb
|
5
|
+
# We will only use Timecop directly when we need to travel inside a single example.
|
6
|
+
#
|
7
|
+
# Run Tests with a specific time.
|
8
|
+
#
|
9
|
+
# Example:
|
10
|
+
# back_to_the_future = Time.local(2224, 12, 12, 12, 12, 12)
|
11
|
+
# Timecop.freeze(back_to_the_future) do
|
12
|
+
# expect("something").to eq("something")
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
|
16
|
+
# turn on safe mode
|
17
|
+
Timecop.safe_mode = true
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.configure do |config|
|
4
|
+
# Settings that only exist in RSpec v3+ are unavailable during transpec's RSpec syntax upgrade.
|
5
|
+
# Other settings may be easier to upgrade to modern defaults after the uograde,
|
6
|
+
# so we leave them alone during transpec.
|
7
|
+
# :nocov:
|
8
|
+
if Kettle::Test::TRANSPEC
|
9
|
+
config.expect_with(:rspec) do |c|
|
10
|
+
c.syntax = [:expect, :should]
|
11
|
+
end
|
12
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
13
|
+
else
|
14
|
+
config.expect_with(:rspec) do |c|
|
15
|
+
c.syntax = :expect
|
16
|
+
end
|
17
|
+
|
18
|
+
# Enable flags like --only-failures and --next-failure
|
19
|
+
config.example_status_persistence_file_path = ".rspec_status"
|
20
|
+
|
21
|
+
# Disable RSpec exposing methods globally on `Module` and `main`
|
22
|
+
config.disable_monkey_patching!
|
23
|
+
|
24
|
+
# Optionally turn on full backtrace
|
25
|
+
config.full_backtrace = Kettle::Test::FULL_BACKTRACE
|
26
|
+
|
27
|
+
# Profile Slowest Specs?
|
28
|
+
config.profile_examples = Kettle::Test::RSPEC_PROFILE_EXAMPLES_NUM if Kettle::Test::RSPEC_PROFILE_EXAMPLES
|
29
|
+
|
30
|
+
# Exclude examples/groups tagged with :skip_ci when running on CI
|
31
|
+
# Usage: add `:skip_ci` to any example or group you want to skip on CI
|
32
|
+
if Kettle::Test::IS_CI
|
33
|
+
config.filter_run_excluding(skip_ci: true)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
# :nocov:
|
37
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.configure do |config|
|
4
|
+
# RSpec ships with a standard solution.
|
5
|
+
# See: https://www.rubydoc.info/gems/rspec-expectations/RSpec%2FMatchers:output
|
6
|
+
# But it has limitations, so the old non-threadsafe approach of SilentStream is still useful.
|
7
|
+
config.include(SilentStream)
|
8
|
+
|
9
|
+
config.around do |example|
|
10
|
+
# Allow tests to run normally when debugging or tagged with check_output
|
11
|
+
if Kettle::Test::DEBUG || example.metadata[:check_output]
|
12
|
+
example.run
|
13
|
+
# Make tests run silently, with shunted STDOUT & STDERR, if ENV var KETTLE_TEST_SILENT == "true"
|
14
|
+
else
|
15
|
+
silence_all(Kettle::Test::SILENT) do
|
16
|
+
example.run
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "timecop/rspec"
|
2
|
+
|
3
|
+
# Ensure a consistent time for all tests
|
4
|
+
#
|
5
|
+
# Integrates timecop-rspec and provides metadata-based time travel/freeze.
|
6
|
+
# Global baseline time derives from Kettle::Test::GLOBAL_DATE via
|
7
|
+
# ENV["GLOBAL_TIME_TRAVEL_TIME"]. See README for sequential mode behaviors.
|
8
|
+
#
|
9
|
+
# Timecop.travel/freeze any RSpec (describe|context|example) with `:travel` or `:freeze` metadata.
|
10
|
+
#
|
11
|
+
# ```ruby
|
12
|
+
# # Timecop.travel
|
13
|
+
# it "some description", :travel => Time.new(2014, 11, 15) do
|
14
|
+
# Time.now # 2014-11-15 00:00:00
|
15
|
+
# sleep 6
|
16
|
+
# Time.now # 2014-11-15 00:00:06 (6 seconds later)
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# # Timecop.freeze
|
20
|
+
# it "some description", :freeze => Time.new(2014, 11, 15) do
|
21
|
+
# Time.now # 2014-11-15 00:00:00
|
22
|
+
# sleep 6
|
23
|
+
# Time.now # 2014-11-15 00:00:00 (Ruby's time hasn't advanced)
|
24
|
+
# end
|
25
|
+
# ```
|
26
|
+
# If the ENV variable isn't set it will default to today
|
27
|
+
ENV["GLOBAL_TIME_TRAVEL_TIME"] ||= Kettle::Test::GLOBAL_DATE
|
28
|
+
|
29
|
+
RSpec.configure do |config|
|
30
|
+
config.around do |example|
|
31
|
+
Timecop::Rspec.time_machine(sequential: Kettle::Test::TIME_MACHINE_SEQUENTIAL).run(example)
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# External-no-config-needed gems
|
2
|
+
#
|
3
|
+
# Provides external helpers used by specs, including:
|
4
|
+
# - rspec/stubbed_env: safe ENV stubbing
|
5
|
+
# - rspec/block_is_expected: block expectations helper
|
6
|
+
# - rspec_junit_formatter: JUnit XML formatter
|
7
|
+
# - silent_stream: output silencing helpers
|
8
|
+
#
|
9
|
+
# Files in config/ext may not depend on this library's internals.
|
10
|
+
# They are auto-required to wire up RSpec configuration.
|
11
|
+
# Usage:
|
12
|
+
# describe 'my stubbed test' do
|
13
|
+
# before do
|
14
|
+
# stub_env('FOO' => 'is bar')
|
15
|
+
# end
|
16
|
+
# it 'has a value' do
|
17
|
+
# expect(ENV['FOO']).to eq('is bar')
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
require "rspec/mocks"
|
21
|
+
require "rspec/stubbed_env"
|
22
|
+
require "rspec/block_is_expected" # Usage: see https://github.com/galtzo-floss/rspec-block_is_expected#example
|
23
|
+
require "rspec_junit_formatter"
|
24
|
+
require "silent_stream"
|
25
|
+
|
26
|
+
# Configs of external libraries
|
27
|
+
require_relative "config/version_gem"
|
28
|
+
|
29
|
+
# Automatically load any config added to subdirectories of config/ext
|
30
|
+
# These are **not** allowed to depend on this library's internals.
|
31
|
+
path = File.expand_path(__dir__)
|
32
|
+
|
33
|
+
# NOTE: Remove #sort when dropping Ruby v2 support; Ruby v3 Dir.globs are pre-sorted
|
34
|
+
# Load non-rspec library configs
|
35
|
+
Dir.glob("#{path}/config/ext/*.rb")
|
36
|
+
.sort
|
37
|
+
.each { |f| require f }
|
38
|
+
|
39
|
+
# NOTE: Remove #sort when dropping Ruby v2 support; Ruby v3 Dir.globs are pre-sorted
|
40
|
+
Dir.glob("#{path}/config/ext/{rspec,filters,helpers,matchers}/**/*.rb")
|
41
|
+
.sort
|
42
|
+
.each { |f| require f }
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Configs of external libraries that depend on this library's internals
|
2
|
+
#
|
3
|
+
# Auto-loads internal RSpec configuration and any additional integrations under
|
4
|
+
# config/int and its subfolders.
|
5
|
+
# Files in config/ext may depend on this library's internals.
|
6
|
+
require_relative "config/int/rspec_block_is_expected"
|
7
|
+
require_relative "config/int/rspec/rspec_core"
|
8
|
+
require_relative "config/int/rspec/silent_stream"
|
9
|
+
|
10
|
+
# Automatically load any config added to subdirectories of config/int
|
11
|
+
# These are allowed to depend on this library's internals.
|
12
|
+
path = File.expand_path(__dir__)
|
13
|
+
|
14
|
+
# NOTE: Remove #sort when dropping Ruby v2 support; Ruby v3 Dir.globs are pre-sorted
|
15
|
+
# Load non-rspec library configs
|
16
|
+
Dir.glob("#{path}/config/int/*.rb")
|
17
|
+
.sort
|
18
|
+
.each { |f| require f }
|
19
|
+
|
20
|
+
# NOTE: Remove #sort when dropping Ruby v2 support; Ruby v3 Dir.globs are pre-sorted
|
21
|
+
Dir.glob("#{path}/config/int/{rspec,filters,helpers,matchers}/**/*.rb")
|
22
|
+
.sort
|
23
|
+
.each { |f| require f }
|
data/lib/kettle/test.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "test/version"
|
4
|
+
|
5
|
+
module Kettle
|
6
|
+
# Test support and RSpec integration for kettle-rb ecosystem.
|
7
|
+
#
|
8
|
+
# Exposes environment-controlled constants and helpers that tune RSpec behavior
|
9
|
+
# (profiling, backtraces, output silencing, CI filters) and provides a minimal
|
10
|
+
# API for detecting parallel test execution.
|
11
|
+
#
|
12
|
+
# See README for configuration and usage examples.
|
13
|
+
module Test
|
14
|
+
# Base error class for kettle-test specific failures.
|
15
|
+
class Error < StandardError; end
|
16
|
+
|
17
|
+
# String#casecmp? was added in Ruby 2.4, so fallback to String#casecmp
|
18
|
+
# @return [Boolean] whether debug mode is enabled (disables silencing)
|
19
|
+
DEBUG = ENV.fetch("KETTLE_TEST_DEBUG", ENV.fetch("DEBUG", "false")).casecmp("true").zero?
|
20
|
+
# @return [Boolean] whether running in a CI environment (CI=true)
|
21
|
+
IS_CI = ENV.fetch("CI", "").casecmp("true").zero?
|
22
|
+
# @return [Boolean] when true, enables full backtraces in RSpec
|
23
|
+
FULL_BACKTRACE = ENV.fetch("KETTLE_TEST_FULL_BACKTRACE", "false").casecmp("true").zero?
|
24
|
+
# @return [Integer] number of examples to profile (0 disables profiling)
|
25
|
+
RSPEC_PROFILE_EXAMPLES_NUM = ENV.fetch("KETTLE_TEST_RSPEC_PROFILE_EXAMPLES", "0").to_i
|
26
|
+
# @return [Boolean] whether profiling is enabled
|
27
|
+
RSPEC_PROFILE_EXAMPLES = RSPEC_PROFILE_EXAMPLES_NUM > 0
|
28
|
+
# If RSpec's version is < 3, enable `transpec` to facilitate the upgrade.
|
29
|
+
# @return [Gem::Version] active RSpec version
|
30
|
+
RSPEC_VERSION = ::Gem::Version.new(RSpec::Core::Version::STRING)
|
31
|
+
# @return [Boolean] when true, STDOUT/STDERR are silenced during specs (unless :check_output or DEBUG)
|
32
|
+
SILENT = ENV.fetch("KETTLE_TEST_SILENT", IS_CI.to_s).casecmp("true").zero?
|
33
|
+
# @return [Boolean] whether transpec compatibility mode should be enabled
|
34
|
+
TRANSPEC = ::Gem::Version.new("3.0") > RSPEC_VERSION
|
35
|
+
# @return [Boolean] whether the environment signals a parallel test run
|
36
|
+
TREAT_AS_PARALLEL = ENV.fetch("PARALLEL_TEST_FIRST_IS_1", "").casecmp("true").zero?
|
37
|
+
# @return [Boolean] reserved for verbose logging toggles
|
38
|
+
VERBOSE = ENV.fetch("KETTLE_TEST_VERBOSE", "false").casecmp("true").zero?
|
39
|
+
# time starts at midnight on GLOBAL_DATE
|
40
|
+
# @return [String] global travel time or date used as a baseline for timecop
|
41
|
+
GLOBAL_DATE = ENV.fetch("GLOBAL_TIME_TRAVEL_TIME", ENV.fetch("GLOBAL_TIME_TRAVEL_DATE", Date.today.to_s))
|
42
|
+
# @return [Boolean] when true, use sequential time machine mode for timecop-rspec
|
43
|
+
TIME_MACHINE_SEQUENTIAL = ENV.fetch("KETTLE_TEST_TM_SEQUENTIAL", "true").casecmp("true").zero?
|
44
|
+
|
45
|
+
class << self
|
46
|
+
# Detects whether tests are running in parallel.
|
47
|
+
#
|
48
|
+
# Many parallel test runners set PARALLEL_TEST_FIRST_IS_1=true and provide
|
49
|
+
# TEST_ENV_NUMBER for each worker. This helper checks those signals.
|
50
|
+
# @return [Boolean]
|
51
|
+
def is_parallel_test?
|
52
|
+
TREAT_AS_PARALLEL && !ENV.fetch("TEST_ENV_NUMBER", "").empty?
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
Kettle::Test::Version.class_eval do
|
59
|
+
extend VersionGem::Basic
|
60
|
+
end
|
data/sig/kettle/test.rbs
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
module Kettle
|
2
|
+
module Test
|
3
|
+
class Error < StandardError
|
4
|
+
end
|
5
|
+
|
6
|
+
# Environment-driven constants
|
7
|
+
DEBUG: bool
|
8
|
+
IS_CI: bool
|
9
|
+
FULL_BACKTRACE: bool
|
10
|
+
RSPEC_PROFILE_EXAMPLES_NUM: untyped
|
11
|
+
RSPEC_PROFILE_EXAMPLES: bool
|
12
|
+
RSPEC_VERSION: untyped
|
13
|
+
SILENT: bool
|
14
|
+
TRANSPEC: bool
|
15
|
+
TREAT_AS_PARALLEL: bool
|
16
|
+
VERBOSE: bool
|
17
|
+
GLOBAL_DATE: untyped
|
18
|
+
TIME_MACHINE_SEQUENTIAL: bool
|
19
|
+
|
20
|
+
# Class methods
|
21
|
+
def self.is_parallel_test?: () -> bool
|
22
|
+
|
23
|
+
module Version
|
24
|
+
VERSION: untyped
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data.tar.gz.sig
ADDED
Binary file
|