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.
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,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.configure do |config|
4
+ config.include_context("with stubbed env")
5
+ end
@@ -0,0 +1,5 @@
1
+ require "silent_stream"
2
+
3
+ RSpec.configure do |config|
4
+ config.include(SilentStream)
5
+ end
@@ -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,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Support RSpec v2 => transpec => v3 syntax
4
+ # :nocov:
5
+ require "rspec/block_is_expected/matchers/not" unless Kettle::Test::TRANSPEC
6
+ # :nocov:
@@ -0,0 +1,6 @@
1
+ require "version_gem/rspec"
2
+
3
+ # External RSpec Matchers
4
+ require "version_gem/rspec"
5
+ # Handy Helpers for querying the Ruby version
6
+ require "version_gem/ruby"
@@ -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 }
@@ -0,0 +1,7 @@
1
+ require_relative "external"
2
+
3
+ # Entry point for RSpec integrations provided by kettle-test.
4
+ # Requires external helpers, this library, then wires internal configuration.
5
+ require "kettle/test"
6
+
7
+ require_relative "internal"
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kettle
4
+ module Test
5
+ # Version namespace
6
+ module Version
7
+ # The current version of kettle-test.
8
+ # @return [String]
9
+ VERSION = "1.0.0"
10
+ end
11
+ end
12
+ end
@@ -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
@@ -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