kettle-dev Logo by GitHub # 🍲 Kettle::Test [![Version][👽versioni]][👽version] [![Ruby Users Forum][✉️ruby-forum-top-img]][✉️ruby-forum] [![GitHub tag (latest SemVer)][⛳️tag-img]][⛳️tag] [![License: AGPL-3.0-only OR PolyForm-Small-Business-1.0.0][📄license-img]][📄license] [![Total downloads][👽dl-ranki]][👽dl-rank] [![CodeCov Test Coverage][🏀codecovi]][🏀codecov] [![Coveralls Test Coverage][🏀coveralls-img]][🏀coveralls] [![QLTY Test Coverage][🏀qlty-covi]][🏀qlty-cov] [![QLTY Maintainability][🏀qlty-mnti]][🏀qlty-mnt] [![CI Heads][🚎3-hd-wfi]][🚎3-hd-wf] [![CI Runtime Dependencies @ HEAD][🚎12-crh-wfi]][🚎12-crh-wf] [![CI Current][🚎11-c-wfi]][🚎11-c-wf] [![CI Truffle Ruby][🚎9-t-wfi]][🚎9-t-wf] [![CI JRuby][🚎10-j-wfi]][🚎10-j-wf] [![Deps Locked][🚎13-🔒️-wfi]][🚎13-🔒️-wf] [![Deps Unlocked][🚎14-🔓️-wfi]][🚎14-🔓️-wf] [![CI Test Coverage][🚎2-cov-wfi]][🚎2-cov-wf] [![CI Style][🚎5-st-wfi]][🚎5-st-wf] `if ci_badges.map(&:color).detect { it != "green"}` ☝️ [let me know on Discord][✉️discord-invite] or [RubyForum][✉️ruby-forum], as I may have missed the notification. --- `if ci_badges.map(&:color).all? { it == "green"}` 👇️ send money so I can do more of this. FLOSS maintenance is now my full-time job. [![OpenCollective Backers][🖇osc-backers-i]][🖇osc-backers] [![OpenCollective Sponsors][🖇osc-sponsors-i]][🖇osc-sponsors] [![Sponsor Me on Github][🖇sponsor-img]][🖇sponsor] [![Liberapay Goal Progress][⛳liberapay-img]][⛳liberapay] [![Donate on PayPal][🖇paypal-img]][🖇paypal] [![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate at ko-fi.com][🖇kofi-img]][🖇kofi]
👣 How will this project approach the September 2025 hostile takeover of RubyGems? 🚑️ I've summarized my thoughts in [this blog post](https://dev.to/galtzo/hostile-takeover-of-rubygems-my-thoughts-5hlo).
## 🌻 Synopsis Galtzo FLOSS Logo by Aboling0, CC BY-SA 4.0 ruby-lang Logo, Yukihiro Matsumoto, Ruby Visual Identity Team, CC BY-SA 2.5 Add to your `spec/spec_helper.rb`: ```ruby require "kettle/test/rspec" # ... any other config you need to do. # NOTE: Gemfiles for older rubies (< 2.7) won't have kettle-soup-cover. # The rescue LoadError handles that scenario. begin require "kettle-soup-cover" require "simplecov" if Kettle::Soup::Cover::DO_COV # `.simplecov` is run here! rescue LoadError => error # check the error message, and re-raise if not what is expected raise error unless error.message.include?("kettle") end # This gem (or app) require "gem-under-test" ``` Now you have many powerful testing tools at your disposal, all fully [documented](#-configuration) and tested. I expect the current release of this gem to be compatible with Ruby 2.4+, and concordant releases of JRuby, and TruffleRuby. | 🚚 _Amazing_ test matrix was brought to you by | 🔎 appraisal2 🔎 | |------------------------------------------------|-------------------------------------------------------------------------------------| | 👟 Check it out! | ✨ [github.com/appraisal-rb/appraisal2][💎appraisal2] ✨ | ## 💡 Info you can shake a stick at | Tokens to Remember | [![Gem name][⛳️name-img]][⛳️gem-name] [![Gem namespace][⛳️namespace-img]][⛳️gem-namespace] | |-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Works with JRuby | [![JRuby 9.2 Compat][💎jruby-9.2i]][🚎jruby-9.2-wf] [![JRuby 9.3 Compat][💎jruby-9.3i]][🚎jruby-9.3-wf]
[![JRuby 9.4 Compat][💎jruby-9.4i]][🚎jruby-9.4-wf] [![JRuby 10.0 Compat][💎jruby-10.0i]][🚎jruby-10.0-wf] [![JRuby current Compat][💎jruby-c-i]][🚎10-j-wf] [![JRuby HEAD Compat][💎jruby-headi]][🚎3-hd-wf]| | Works with Truffle Ruby | [![Truffle Ruby 22.3 Compat][💎truby-22.3i]][🚎truby-22.3-wf] [![Truffle Ruby 23.0 Compat][💎truby-23.0i]][🚎truby-23.0-wf] [![Truffle Ruby 23.1 Compat][💎truby-23.1i]][🚎truby-23.1-wf]
[![Truffle Ruby 24.2 Compat][💎truby-24.2i]][🚎truby-24.2-wf] [![Truffle Ruby 25.0 Compat][💎truby-25.0i]][🚎truby-25.0-wf] [![Truffle Ruby 33.0 Compat][💎truby-33.0i]][🚎truby-33.0-wf] [![Truffle Ruby current Compat][💎truby-c-i]][🚎9-t-wf] [![Truffle Ruby HEAD Compat][💎truby-headi]][🚎3-hd-wf]| | Works with MRI Ruby 4 | [![Ruby current Compat][💎ruby-c-i]][🚎11-c-wf] [![Ruby HEAD Compat][💎ruby-headi]][🚎3-hd-wf]| | Works with MRI Ruby 3 | [![Ruby 3.0 Compat][💎ruby-3.0i]][🚎ruby-3.0-wf] [![Ruby 3.1 Compat][💎ruby-3.1i]][🚎ruby-3.1-wf] [![Ruby 3.2 Compat][💎ruby-3.2i]][🚎ruby-3.2-wf] [![Ruby 3.3 Compat][💎ruby-3.3i]][🚎ruby-3.3-wf] [![Ruby 3.4 Compat][💎ruby-3.4i]][🚎ruby-3.4-wf]| | Works with MRI Ruby 2 | [![Ruby 2.4 Compat][💎ruby-2.4i]][🚎ruby-2.4-wf] [![Ruby 2.5 Compat][💎ruby-2.5i]][🚎ruby-2.5-wf] [![Ruby 2.6 Compat][💎ruby-2.6i]][🚎ruby-2.6-wf] [![Ruby 2.7 Compat][💎ruby-2.7i]][🚎ruby-2.7-wf]| | Support & Community | [![Join Me on Daily.dev's RubyFriends][✉️ruby-friends-img]][✉️ruby-friends] [![Get help from RubyForum][✉️ruby-forum-img]][✉️ruby-forum] [![Live Chat on Discord][✉️discord-invite-img-ftb]][✉️discord-invite] [![Get help from me on Upwork][👨🏼‍🏫expsup-upwork-img]][👨🏼‍🏫expsup-upwork] [![Get help from me on Codementor][👨🏼‍🏫expsup-codementor-img]][👨🏼‍🏫expsup-codementor] | | Source | [![Source on GitLab.com][📜src-gl-img]][📜src-gl] [![Source on CodeBerg.org][📜src-cb-img]][📜src-cb] [![Source on GitHub.com][📜src-gh-img]][📜src-gh] [![The best SHA: dQw4w9WgXcQ!][🧮kloc-img]][🧮kloc] | | Documentation | [![Current release on RubyDoc.info][📜docs-cr-rd-img]][🚎yard-current] [![YARD on Galtzo.com][📜docs-head-rd-img]][🚎yard-head] [![Maintainer Blog][🚂maint-blog-img]][🚂maint-blog] [![GitLab Wiki][📜gl-wiki-img]][📜gl-wiki] [![GitHub Wiki][📜gh-wiki-img]][📜gh-wiki] | | Compliance | [![License: AGPL-3.0-only OR PolyForm-Small-Business-1.0.0][📄license-img]][📄license] [![Apache license compatibility: Category X][📄license-compat-img]][📄license-compat] [![📄ilo-declaration-img]][📄ilo-declaration] [![Security Policy][🔐security-img]][🔐security] [![Contributor Covenant 2.1][🪇conduct-img]][🪇conduct] [![SemVer 2.0.0][📌semver-img]][📌semver] | | Style | [![Enforced Code Style Linter][💎rlts-img]][💎rlts] [![Keep-A-Changelog 1.0.0][📗keep-changelog-img]][📗keep-changelog] [![Gitmoji Commits][📌gitmoji-img]][📌gitmoji] [![Compatibility appraised by: appraisal2][💎appraisal2-img]][💎appraisal2] | | Maintainer 🎖️ | [![Follow Me on LinkedIn][💖🖇linkedin-img]][💖🖇linkedin] [![Follow Me on Ruby.Social][💖🐘ruby-mast-img]][💖🐘ruby-mast] [![Follow Me on Bluesky][💖🦋bluesky-img]][💖🦋bluesky] [![Contact Maintainer][🚂maint-contact-img]][🚂maint-contact] [![My technical writing][💖💁🏼‍♂️devto-img]][💖💁🏼‍♂️devto] | | `...` 💖 | [![Find Me on WellFound:][💖✌️wellfound-img]][💖✌️wellfound] [![Find Me on CrunchBase][💖💲crunchbase-img]][💖💲crunchbase] [![My LinkTree][💖🌳linktree-img]][💖🌳linktree] [![More About Me][💖💁🏼‍♂️aboutme-img]][💖💁🏼‍♂️aboutme] [🧊][💖🧊berg] [🐙][💖🐙hub] [🛖][💖🛖hut] [🧪][💖🧪lab] | ### Compatibility Compatible with MRI Ruby 2.4.0+, and concordant releases of JRuby, and TruffleRuby. CI workflows and Appraisals are generated for MRI Ruby 2.4+. This test floor is configured by `ruby.test_minimum` in `.kettle-jem.yml` and may be higher than the gem's runtime compatibility floor when legacy Rubies are not practical for the current toolchain. kettle-dev Logo by Aboling0, CC BY-SA 4.0 The _amazing_ test matrix is powered by the kettle-dev stack.
How kettle-dev manages complexity in tests | Gem | Source | Role | Total downloads | |-----|--------|------|---------------------| | [appraisal2](https://clickgems.clickhouse.com/dashboard/appraisal2) | [GitHub](https://github.com/appraisal-rb/appraisal2) | multi-dependency Appraisal matrix generation | [![Total downloads for appraisal2](https://img.shields.io/gem/dt/appraisal2.svg?style=flat-square)](https://clickgems.clickhouse.com/dashboard/appraisal2) | | [appraisal2-rubocop](https://clickgems.clickhouse.com/dashboard/appraisal2-rubocop) | [GitHub](https://github.com/appraisal-rb/appraisal2-rubocop) | RuboCop Appraisal generator integration | [![Total downloads for appraisal2-rubocop](https://img.shields.io/gem/dt/appraisal2-rubocop.svg?style=flat-square)](https://clickgems.clickhouse.com/dashboard/appraisal2-rubocop) | | [kettle-dev](https://clickgems.clickhouse.com/dashboard/kettle-dev) | [GitHub](https://github.com/kettle-dev/kettle-dev) | development, release, and CI workflow tooling | [![Total downloads for kettle-dev](https://img.shields.io/gem/dt/kettle-dev.svg?style=flat-square)](https://clickgems.clickhouse.com/dashboard/kettle-dev) | | [kettle-jem](https://clickgems.clickhouse.com/dashboard/kettle-jem) | [GitHub](https://github.com/kettle-dev/kettle-jem) | Appraisals & CI workflow templates | [![Total downloads for kettle-jem](https://img.shields.io/gem/dt/kettle-jem.svg?style=flat-square)](https://clickgems.clickhouse.com/dashboard/kettle-jem) | | [kettle-soup-cover](https://clickgems.clickhouse.com/dashboard/kettle-soup-cover) | [GitHub](https://github.com/kettle-dev/kettle-soup-cover) | SimpleCov coverage policy and reporting | [![Total downloads for kettle-soup-cover](https://img.shields.io/gem/dt/kettle-soup-cover.svg?style=flat-square)](https://clickgems.clickhouse.com/dashboard/kettle-soup-cover) | | [rubocop-lts](https://clickgems.clickhouse.com/dashboard/rubocop-lts) | [GitHub](https://github.com/rubocop-lts/rubocop-lts) | Ruby-version-aware linting | [![Total downloads for rubocop-lts](https://img.shields.io/gem/dt/rubocop-lts.svg?style=flat-square)](https://clickgems.clickhouse.com/dashboard/rubocop-lts) | | [turbo_tests2](https://clickgems.clickhouse.com/dashboard/turbo_tests2) | [GitHub](https://github.com/galtzo-floss/turbo_tests2) | parallel test execution | [![Total downloads for turbo_tests2](https://img.shields.io/gem/dt/turbo_tests2.svg?style=flat-square)](https://clickgems.clickhouse.com/dashboard/turbo_tests2) |
### Federated DVCS
Find this repo on federated forges (Coming soon!) | Federated [DVCS][💎d-in-dvcs] Repository | Status | Issues | PRs | Wiki | CI | |-------------------------------------------------|-------------------------------------------|-------------------|------------------|-----------------|----------------| | 🧪 [kettle-dev/kettle-test on GitLab][📜src-gl] | The Truth | [💚][🤝gl-issues] | [💚][🤝gl-pulls] | [💚][📜gl-wiki] | 🐭 Tiny Matrix | | 🧊 [kettle-dev/kettle-test on CodeBerg][📜src-cb] | An Ethical Mirror ([Donate][🤝cb-donate]) | [💚][🤝cb-issues] | [💚][🤝cb-pulls] | ➖ | ⭕️ No Matrix | | 🐙 [kettle-dev/kettle-test on GitHub][📜src-gh] | Another Mirror | [💚][🤝gh-issues] | [💚][🤝gh-pulls] | [💚][📜gh-wiki] | 💯 Full Matrix |
### Enterprise Support [![Tidelift](https://tidelift.com/badges/package/rubygems/kettle-test)](https://tidelift.com/subscription/pkg/rubygems-kettle-test?utm_source=rubygems-kettle-test&utm_medium=referral&utm_campaign=readme) Available as part of the Tidelift Subscription.
Need enterprise-level guarantees? The maintainers of this and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use. [![Get help from me on Tidelift][🏙️entsup-tidelift-img]][🏙️entsup-tidelift] - 💡Subscribe for support guarantees covering _all_ your FLOSS dependencies - 💡Tidelift is part of [Sonar][🏙️entsup-tidelift-sonar] - 💡Tidelift pays maintainers to maintain the software you depend on!
📊`@`Pointy Haired Boss: An [enterprise support][🏙️entsup-tidelift] subscription is "[never gonna let you down][🧮kloc]", and *supports* open source maintainers Alternatively: - [![Ruby Users Forum][✉️ruby-forum-img]][✉️ruby-forum] - [![Live Chat on Discord][✉️discord-invite-img-ftb]][✉️discord-invite] - [![Get help from me on Upwork][👨🏼‍🏫expsup-upwork-img]][👨🏼‍🏫expsup-upwork] - [![Get help from me on Codementor][👨🏼‍🏫expsup-codementor-img]][👨🏼‍🏫expsup-codementor]
## ✨ Installation Install the gem and add to the application's Gemfile by executing: ```console bundle add kettle-test ``` If bundler is not being used to manage dependencies, install the gem by executing: ```console gem install kettle-test ``` ## ⚙️ Configuration Add to your `spec/spec_helper.rb`: ```ruby require "kettle/test/rspec" # ... any other config you need to do. # NOTE: Gemfiles for older rubies (< 2.7) won't have kettle-soup-cover. # The rescue LoadError handles that scenario. begin require "kettle-soup-cover" require "simplecov" if Kettle::Soup::Cover::DO_COV # `.simplecov` is run here! rescue LoadError => error # check the error message, and re-raise if not what is expected raise error unless error.message.include?("kettle") end # This gem (or app) require "gem-under-test" ``` That's it! Additional customizations can be done by setting environment variables. ### Environment Variables Below are the environment variables recognized by kettle-test. Unless otherwise specified, set values to the string "true" to enable a boolean feature, or provide the noted type. - DEBUG (String: "true"/"false") - Overrides default silencing for the entire run; when true, STDOUT/STDERR are not silenced by this library. - Default: "false". If KETTLE_TEST_DEBUG is not set, DEBUG is used. - GLOBAL_TIME_TRAVEL_TIME (String: Date/Time) - Global start time for Timecop across examples when using time travel. - Example: "2014-11-15" or "2014-11-15 13:45:00". - Default: falls back to GLOBAL_TIME_TRAVEL_DATE if set, else today. - GLOBAL_TIME_TRAVEL_DATE (String: Date) - Alternate way to set a global date used when GLOBAL_TIME_TRAVEL_TIME is not provided. - Default: today (Date.today.to_s). - KETTLE_TEST_DEBUG (String: "true"/"false") - Same as DEBUG but namespaced for this gem. Takes precedence over DEBUG. - Default: "false". - CI (String: "true"/"false") - Signals a CI environment. When true, examples tagged :skip_ci are excluded. - Also used as the default for KETTLE_TEST_SILENT when not set. - Default: unset/empty → treated as false. - KETTLE_TEST_SILENT (String: "true"/"false") - Controls silencing of STDOUT/STDERR during specs (unless :check_output is used or DEBUG is true). - When true with the default turbo_tests2 runner, sets TURBO_TESTS2_WORKER_OUTPUT=quiet unless already set. - Default: value of CI (true on CI, false locally unless CI=true). - TURBO_TESTS2_WORKER_OUTPUT (String) - Explicit turbo_tests2 worker output mode. When set, kettle-test preserves it. - Default: quiet when KETTLE_TEST_SILENT is true; otherwise turbo_tests2's own default. - KETTLE_TEST_VERBOSE (String: "true"/"false") - Reserved for future verbose logging toggles. Default: "false". - KETTLE_TEST_FULL_BACKTRACE (String: "true"/"false") - When true, enables RSpec full backtraces. - Default: "false". - KETTLE_TEST_RSPEC_PROFILE_EXAMPLES (Integer as String) - When > 0, RSpec will profile the slowest N examples or example groups. - Example: KETTLE_TEST_RSPEC_PROFILE_EXAMPLES=10 - Default: "0" (disabled). - KETTLE_TEST_TM_SEQUENTIAL (String: "true"/"false") - Controls Timecop sequential time machine mode for RSpec examples (see below). - Default: "true". - PARALLEL_TEST_FIRST_IS_1 (String: "true"/"false") and TEST_ENV_NUMBER (String) - Used to detect parallel test runs via Kettle::Test.is_parallel_test?. Not generally required to set manually. - Default: unset (treated as non-parallel unless provided by your parallel test runner). ### TimeCop-RSpec #### Global Time Travel Using global time travel will `Timecop.travel` any example that isn't already time traveling. I.e. example level timecop metadata will take precedence. ```sh GLOBAL_TIME_TRAVEL_TIME=2014-11-15 bundle exec rspec spec/some_directory/ ``` The global time travel can also be skipped. You may want to skip time travel when testing with some external service, such as redis, where you can't modify time the same way as within ruby. ```ruby it "some example that can't time travel", :skip_global_travel do # Time.now will be real time end ``` #### Regular Time Machine ```ruby ENV["KETTLE_TEST_TM_SEQUENTIAL"] = "false" ``` The regular time machine will run each example at the time specified by the RSpec metadata, or the global travel time. #### Sequential Time Machine ```ruby ENV["KETTLE_TEST_TM_SEQUENTIAL"] = "true" ``` The sequential time machine is almost the same as the regular time machine, except that it will sometimes resume time travel. Global travel will always resume from when the previous global traveled example ended. E.g. ```ruby # GLOBAL_TIME_TRAVEL_TIME=2014-11-15 bundle exec rspec some_spec.rb it "example 1" do Time.now # => 2014-11-15 00:00:00 sleep 6 end it "example 2" do Time.now # => 2014-11-15 00:00:06 (resumed from end of previous example) end ``` ## 🔧 Basic Usage ### Shared Context "with rake" Make sure to require "rake" before you require "kettle/test" (or "kettle/dev" since it will require this library). If you do the shared context will be available to use in your specs automatically. ```ruby include_context "with rake", "demo" do let(:tmp_rakelib) do Dir.mktmpdir("with_rake_spec_") end let(:task_dir) { tmp_rakelib } let(:rakelib) { tmp_rakelib } # Provide args for the rake task invocation let(:task_args) { ["Bob"] } end ``` See the spec for a more complete example: [with_rake_spec.rb](spec/kettle/text/support/shared_contexts/with_rake_spec.rb) ### RSpec Time Machine Tags :freeze and :travel Timecop.travel/freeze any RSpec (describe|context|example) with `:travel` or `:freeze` metadata. ```ruby # Timecop.travel it "some description", travel: Time.new(2014, 11, 15) do Time.now # 2014-11-15 00:00:00 sleep 6 Time.now # 2014-11-15 00:00:06 (6 seconds later) end # Timecop.freeze it "some description", freeze: Time.new(2014, 11, 15) do Time.now # 2014-11-15 00:00:00 sleep 6 Time.now # 2014-11-15 00:00:00 (Ruby's time hasn't advanced) end ``` Following spec's local travel will resume when specified time is the same as the previous examples specified time. If the time is different, it will start from the current examples specified time. ```ruby describe SomeUnit, travel: Time.new(2014, 11, 15) do it "example 1" do Time.now # => 2014-11-15 00:00:00 sleep 6 end it "example 2" do Time.now # => 2014-11-15 00:00:06 (resumed from end of previous example) end it "example 3", travel: Time.new(1982, 6, 16) do Time.now # => 1982-06-16 00:00:00 end end ``` ### Stubbed ENV in examples Use rspec-stubbed_env to safely set and restore environment variables in specs. ```ruby RSpec.describe("stubbed env") do # kettle-test includes these globally, so they are always available # include_context "with stubbed env" # include_context "with hidden env" before do stub_env("FOO" => "is bar") hide_env("PATH") end it "uses the stubbed value" do expect(ENV["FOO"]).to(eq("is bar")) end it "has no path" do expect(ENV["PATH"]).to(be_nil) end end ``` ### Silencing output and checking output STDOUT/STDERR are silenced by default when KETTLE_TEST_SILENT is true (defaults to true on CI). With the default turbo_tests2 runner, worker output summaries are also quiet by default in silent mode. To assert output from the code under test, tag examples/groups with :check_output, or run with DEBUG=true to disable silencing globally. ```ruby RSpec.describe("output", :check_output) do it "prints" do puts "This will be visible in test output" expect(true).to(be(true)) end end ``` Or run: ```sh DEBUG=true bundle exec rspec ``` ### Version-based pending and skipping Use rspec-pending_for to conditionally pending or skip examples based on Ruby version and engine. The `pending_for` and `skip_for` macros support flexible version specifications: **Supported version forms:** - String: exact or partial match to RUBY_VERSION (e.g., "3.2.4", "3.2", or "3") - Array of strings: any matching entry triggers pending/skip - Range of Gem::Version: inclusive/exclusive endpoints respected - Range of Integer: compares major version only (e.g., 2..3 for Ruby 2.x and 3.x) **Supported engines:** :ruby (MRI), :jruby, :truffleruby **Specifying versions:** ```ruby RSpec.describe("version-specific behavior") do # Exact version string it "pends only on Ruby 3.2.4" do pending_for(engine: :ruby, versions: "3.2.4") # ... end # Multiple exact versions it "pends on a set of MRI versions" do pending_for(engine: :ruby, versions: %w[2.7.10 3.0.7 3.1.6]) end # Match any engine by version (no :engine) it "skips on any engine if version equals 2.7.8" do skip_for(versions: "2.7.8", reason: "Known upstream incompatibility") end # Range of Gem::Version (inclusive) it "pends for MRI >= 2.6.0 and <= 3.0.0" do pending_for( engine: :ruby, versions: (Gem::Version.new("2.6.0")..Gem::Version.new("3.0.0")) ) end # Range of Gem::Version (exclusive end) it "skips for MRI >= 3.1.0 and < 3.3.0" do skip_for( engine: :ruby, versions: (Gem::Version.new("3.1.0")...Gem::Version.new("3.3.0")) ) end # Range of Integer (major versions) it "pends on all Ruby 2.x and 3.x" do pending_for(versions: (2..3), reason: "Major series currently affected") end it "skips on Ruby 2.x but not 3.x" do skip_for(versions: (2...3)) # 2 <= version < 3 end end ``` **Using with RSpec tags:** ```ruby RSpec.configure do |config| # Auto-skip examples requiring specific Ruby versions via tags config.before(:each, :requires_ruby_32) do skip_for( reason: "Requires Ruby >= 3.2", versions: %w[2.7 3.0 3.1] ) end end RSpec.describe("something") do it "runs only on Ruby 3.2+", :requires_ruby_32 do # ... your example code ... end end ``` **Notes:** - Omit :engine to match any Ruby engine (MRI, JRuby, TruffleRuby) - Omit :versions with :engine to match all versions of that engine - JRuby and TruffleRuby are matched using their RUBY_VERSION compatibility - String matching supports partial versions ("3.1" matches "3.1.x" but not "3.0.x") - Provide :reason to override the default message in reports ### CI-only filtering Examples or groups tagged with :skip_ci are excluded on CI (CI=true). ```ruby RSpec.describe("flaky external call", :skip_ci) do it "runs locally but is skipped on CI" do # ... end end ``` ### Profile slowest examples Set KETTLE_TEST_RSPEC_PROFILE_EXAMPLES to a positive integer to enable RSpec profiling. ```sh KETTLE_TEST_RSPEC_PROFILE_EXAMPLES=10 bundle exec rspec ``` ### Full backtraces Enable full backtraces from RSpec to aid debugging. ```sh KETTLE_TEST_FULL_BACKTRACE=true bundle exec rspec ``` ## 🔐 Security See [SECURITY.md][🔐security]. ## 🤝 Contributing If you need some ideas of where to help, you could work on adding more code coverage, or if it is already 💯 (see [below](#code-coverage)) check [issues][🤝gh-issues] or [PRs][🤝gh-pulls], or use the gem and think about how it could be better. We [![Keep A Changelog][📗keep-changelog-img]][📗keep-changelog] so if you make changes, remember to update it. See [CONTRIBUTING.md][🤝contributing] for more detailed instructions. ### 🚀 Release Instructions See [CONTRIBUTING.md][🤝contributing]. ### Code Coverage
Coverage service badges [![Coverage Graph][🏀codecov-g]][🏀codecov] [![Coveralls Test Coverage][🏀coveralls-img]][🏀coveralls] [![QLTY Test Coverage][🏀qlty-covi]][🏀qlty-cov]
### 🪇 Code of Conduct Everyone interacting with this project's codebases, issue trackers, chat rooms and mailing lists agrees to follow the [![Contributor Covenant 2.1][🪇conduct-img]][🪇conduct]. ## 🌈 Contributors [![Contributors][🖐contributors-img]][🖐contributors] Made with [contributors-img][🖐contrib-rocks]. Also see GitLab Contributors: [https://gitlab.com/kettle-dev/kettle-test/-/graphs/main][🚎contributors-gl]
⭐️ Star History Star History Chart
## 📌 Versioning This library follows [![Semantic Versioning 2.0.0][📌semver-img]][📌semver] for its public API where practical. For most applications, prefer the [Pessimistic Version Constraint][📌pvc] with two digits of precision. For example: ```ruby spec.add_dependency("kettle-test", "~> 2.0") ```
📌 Is "Platform Support" part of the public API? More details inside. Dropping support for a platform can be a breaking change for affected users. If a release changes supported platforms, it should be called out clearly in the changelog and versioned with that impact in mind. To get a better understanding of how SemVer is intended to work over a project's lifetime, read this article from the creator of SemVer: - ["Major Version Numbers are Not Sacred"][📌major-versions-not-sacred]
See [CHANGELOG.md][📌changelog] for a list of releases. ## 📄 License The gem is available under the following licenses: [AGPL-3.0-only](https://github.com/kettle-dev/kettle-test/blob/main/AGPL-3.0-only.md), [PolyForm-Small-Business-1.0.0](https://github.com/kettle-dev/kettle-test/blob/main/PolyForm-Small-Business-1.0.0.md). See [LICENSE.md][📄license] for details. If none of the available licenses suit your use case, please [contact us](mailto:floss@galtzo.com) to discuss a custom commercial license. ### © Copyright See [LICENSE.md][📄license] for the official copyright notice.
Copyright holders - Required Notice: Copyright (c) 2023, 2025-2026 Peter H. Boling
## 🤑 A request for help Maintainers have teeth and need to pay their dentists. After getting laid off in an RIF in March, and encountering difficulty finding a new one, I began spending most of my time building open source tools. I'm hoping to be able to pay for my kids' health insurance this month, so if you value the work I am doing, I need your support. Please consider sponsoring me or the project. To join the community or get help, use the RubyForum or Discord. [![Ruby Users Forum][✉️ruby-forum-img]][✉️ruby-forum] [![Live Chat on Discord][✉️discord-invite-img-ftb]][✉️discord-invite] To say "thanks!" ☝️ Join the community or 👇️ send money. [![Sponsor kettle-dev/kettle-test on Open Source Collective][🖇osc-all-bottom-img]][🖇osc] 💌 [![Sponsor me on GitHub Sponsors][🖇sponsor-bottom-img]][🖇sponsor] 💌 [![Sponsor me on Liberapay][⛳liberapay-bottom-img]][⛳liberapay] 💌 [![Donate on PayPal][🖇paypal-bottom-img]][🖇paypal] ### Please give the project a star ⭐ ♥. Many parts of this project are actively managed by a [kettle-jem](https://github.com/structuredmerge/structuredmerge-ruby/tree/main/gems/kettle-jem) smart template utilizing [StructuredMerge.org](https://structuredmerge.org) merge contracts. Thanks for RTFM. ☺️ [⛳liberapay-img]: https://img.shields.io/liberapay/goal/pboling.svg?logo=liberapay&color=a51611&style=flat [⛳liberapay-bottom-img]: https://img.shields.io/liberapay/goal/pboling.svg?style=for-the-badge&logo=liberapay&color=a51611 [⛳liberapay]: https://liberapay.com/pboling/donate [🖇osc-all-img]: https://img.shields.io/opencollective/all/kettle-dev [🖇osc-sponsors-img]: https://img.shields.io/opencollective/sponsors/kettle-dev [🖇osc-backers-img]: https://img.shields.io/opencollective/backers/kettle-dev [🖇osc-backers]: https://opencollective.com/kettle-dev#backer [🖇osc-backers-i]: https://opencollective.com/kettle-dev/backers/badge.svg?style=flat [🖇osc-sponsors]: https://opencollective.com/kettle-dev#sponsor [🖇osc-sponsors-i]: https://opencollective.com/kettle-dev/sponsors/badge.svg?style=flat [🖇osc-all-bottom-img]: https://img.shields.io/opencollective/all/kettle-dev?style=for-the-badge [🖇osc-sponsors-bottom-img]: https://img.shields.io/opencollective/sponsors/kettle-dev?style=for-the-badge [🖇osc-backers-bottom-img]: https://img.shields.io/opencollective/backers/kettle-dev?style=for-the-badge [🖇osc]: https://opencollective.com/kettle-dev [🖇sponsor-img]: https://img.shields.io/badge/Sponsor_Me!-pboling.svg?style=social&logo=github [🖇sponsor-bottom-img]: https://img.shields.io/badge/Sponsor_Me!-pboling-blue?style=for-the-badge&logo=github [🖇sponsor]: https://github.com/sponsors/pboling [🖇kofi-img]: https://img.shields.io/badge/ko--fi-%E2%9C%93-a51611.svg?style=flat [🖇kofi]: https://ko-fi.com/pboling [🖇buyme-small-img]: https://img.shields.io/badge/buy_me_a_coffee-%E2%9C%93-a51611.svg?style=flat [🖇buyme-img]: https://img.buymeacoffee.com/button-api/?text=Buy%20me%20a%20latte&emoji=&slug=pboling&button_colour=FFDD00&font_colour=000000&font_family=Cookie&outline_colour=000000&coffee_colour=ffffff [🖇buyme]: https://www.buymeacoffee.com/pboling [🖇paypal-img]: https://img.shields.io/badge/donate-paypal-a51611.svg?style=flat&logo=paypal [🖇paypal-bottom-img]: https://img.shields.io/badge/donate-paypal-a51611.svg?style=for-the-badge&logo=paypal&color=0A0A0A [🖇paypal]: https://www.paypal.com/paypalme/peterboling [🖇floss-funding.dev]: https://floss-funding.dev [🖇floss-funding-gem]: https://github.com/galtzo-floss/floss_funding [✉️discord-invite]: https://discord.gg/3qme4XHNKN [✉️discord-invite-img-ftb]: https://img.shields.io/discord/1373797679469170758?style=for-the-badge&logo=discord [✉️ruby-friends-img]: https://img.shields.io/badge/daily.dev-%F0%9F%92%8E_Ruby_Friends-0A0A0A?style=for-the-badge&logo=dailydotdev&logoColor=white [✉️ruby-friends]: https://app.daily.dev/squads/rubyfriends [✉️ruby-forum-top-img]: https://img.shields.io/discourse/topics?server=https%3A%2F%2Fwww.rubyforum.org&style=flat&logo=discourse&label=Ruby%20Users%20Forum [✉️ruby-forum-img]: https://img.shields.io/discourse/topics?server=https%3A%2F%2Fwww.rubyforum.org&style=for-the-badge&logo=discourse&label=Ruby%20Users%20Forum [✉️ruby-forum]: https://www.rubyforum.org/tag/kettle-dev [✇bundle-group-pattern]: https://gist.github.com/pboling/4564780 [⛳️gem-namespace]: https://github.com/kettle-dev/kettle-test [⛳️namespace-img]: https://img.shields.io/badge/namespace-Kettle::Test-3C2D2D.svg?style=square&logo=ruby&logoColor=white [⛳️gem-name]: https://clickgems.clickhouse.com/dashboard/kettle-test [⛳️name-img]: https://img.shields.io/badge/name-kettle--test-3C2D2D.svg?style=square&logo=rubygems&logoColor=red [⛳️tag-img]: https://img.shields.io/github/tag/kettle-dev/kettle-test.svg [⛳️tag]: https://github.com/kettle-dev/kettle-test/releases [🚂maint-blog]: http://www.railsbling.com/tags/kettle-test [🚂maint-blog-img]: https://img.shields.io/badge/blog-railsbling-0093D0.svg?style=for-the-badge&logo=rubyonrails&logoColor=orange [🚂maint-contact]: http://www.railsbling.com/contact [🚂maint-contact-img]: https://img.shields.io/badge/Contact-Maintainer-0093D0.svg?style=flat&logo=rubyonrails&logoColor=red [💖🖇linkedin]: http://www.linkedin.com/in/peterboling [💖🖇linkedin-img]: https://img.shields.io/badge/LinkedIn-Profile-0B66C2?style=flat&logo=newjapanprowrestling [💖✌️wellfound]: https://wellfound.com/u/peter-boling [💖✌️wellfound-img]: https://img.shields.io/badge/peter--boling-orange?style=flat&logo=wellfound [💖💲crunchbase]: https://www.crunchbase.com/person/peter-boling [💖💲crunchbase-img]: https://img.shields.io/badge/peter--boling-purple?style=flat&logo=crunchbase [💖🐘ruby-mast]: https://ruby.social/@galtzo [💖🐘ruby-mast-img]: https://img.shields.io/mastodon/follow/109447111526622197?domain=https://ruby.social&style=flat&logo=mastodon&label=Ruby%20@galtzo [💖🦋bluesky]: https://bsky.app/profile/galtzo.com [💖🦋bluesky-img]: https://img.shields.io/badge/@galtzo.com-0285FF?style=flat&logo=bluesky&logoColor=white [💖🌳linktree]: https://linktr.ee/galtzo [💖🌳linktree-img]: https://img.shields.io/badge/galtzo-purple?style=flat&logo=linktree [💖💁🏼‍♂️devto]: https://dev.to/galtzo [💖💁🏼‍♂️devto-img]: https://img.shields.io/badge/dev.to-0A0A0A?style=flat&logo=devdotto&logoColor=white [💖💁🏼‍♂️aboutme]: https://about.me/peter.boling [💖💁🏼‍♂️aboutme-img]: https://img.shields.io/badge/about.me-0A0A0A?style=flat&logo=aboutme&logoColor=white [💖🧊berg]: https://codeberg.org/pboling [💖🐙hub]: https://github.org/pboling [💖🛖hut]: https://sr.ht/~galtzo/ [💖🧪lab]: https://gitlab.com/pboling [👨🏼‍🏫expsup-upwork]: https://www.upwork.com/freelancers/~014942e9b056abdf86?mp_source=share [👨🏼‍🏫expsup-upwork-img]: https://img.shields.io/badge/UpWork-13544E?style=for-the-badge&logo=Upwork&logoColor=white [👨🏼‍🏫expsup-codementor]: https://www.codementor.io/peterboling?utm_source=github&utm_medium=button&utm_term=peterboling&utm_campaign=github [👨🏼‍🏫expsup-codementor-img]: https://img.shields.io/badge/CodeMentor-Get_Help-1abc9c?style=for-the-badge&logo=CodeMentor&logoColor=white [🏙️entsup-tidelift]: https://tidelift.com/subscription/pkg/rubygems-kettle-test?utm_source=rubygems-kettle-test&utm_medium=referral&utm_campaign=readme [🏙️entsup-tidelift-img]: https://img.shields.io/badge/Tidelift_and_Sonar-Enterprise_Support-FD3456?style=for-the-badge&logo=sonar&logoColor=white [🏙️entsup-tidelift-sonar]: https://blog.tidelift.com/tidelift-joins-sonar [💁🏼‍♂️peterboling]: http://www.peterboling.com [🚂railsbling]: http://www.railsbling.com [📜src-gl-img]: https://img.shields.io/badge/GitLab-FBA326?style=for-the-badge&logo=Gitlab&logoColor=orange [📜src-gl]: https://gitlab.com/kettle-dev/kettle-test [📜src-cb-img]: https://img.shields.io/badge/CodeBerg-4893CC?style=for-the-badge&logo=CodeBerg&logoColor=blue [📜src-cb]: https://codeberg.org/kettle-dev/kettle-test [📜src-gh-img]: https://img.shields.io/badge/GitHub-238636?style=for-the-badge&logo=GitHub&logoColor=green [📜src-gh]: https://github.com/kettle-dev/kettle-test [📜docs-cr-rd-img]: https://img.shields.io/badge/RubyDoc-Current_Release-943CD2?style=for-the-badge&logo=readthedocs&logoColor=white [📜docs-head-rd-img]: https://img.shields.io/badge/YARD_on_Galtzo.com-HEAD-943CD2?style=for-the-badge&logo=readthedocs&logoColor=white [📜gl-wiki]: https://gitlab.com/kettle-dev/kettle-test/-/wikis/home [📜gh-wiki]: https://github.com/kettle-dev/kettle-test/wiki [📜gl-wiki-img]: https://img.shields.io/badge/wiki-gitlab-943CD2.svg?style=for-the-badge&logo=gitlab&logoColor=white [📜gh-wiki-img]: https://img.shields.io/badge/wiki-github-943CD2.svg?style=for-the-badge&logo=github&logoColor=white [👽dl-rank]: https://clickgems.clickhouse.com/dashboard/kettle-test [👽dl-ranki]: https://img.shields.io/gem/dt/kettle-test.svg [👽version]: https://clickgems.clickhouse.com/dashboard/kettle-test [👽versioni]: https://img.shields.io/gem/v/kettle-test.svg [🏀qlty-mnt]: https://qlty.sh/gh/kettle-dev/projects/kettle-test [🏀qlty-mnti]: https://qlty.sh/gh/kettle-dev/projects/kettle-test/maintainability.svg [🏀qlty-cov]: https://qlty.sh/gh/kettle-dev/projects/kettle-test/metrics/code?sort=coverageRating [🏀qlty-covi]: https://qlty.sh/gh/kettle-dev/projects/kettle-test/coverage.svg [🏀codecov]: https://codecov.io/gh/kettle-dev/kettle-test [🏀codecovi]: https://codecov.io/gh/kettle-dev/kettle-test/graph/badge.svg [🏀coveralls]: https://coveralls.io/github/kettle-dev/kettle-test?branch=main [🏀coveralls-img]: https://coveralls.io/repos/github/kettle-dev/kettle-test/badge.svg?branch=main [🚎ruby-2.4-wf]: https://github.com/kettle-dev/kettle-test/actions/workflows/ruby-2.4.yml [🚎ruby-2.5-wf]: https://github.com/kettle-dev/kettle-test/actions/workflows/ruby-2.5.yml [🚎ruby-2.6-wf]: https://github.com/kettle-dev/kettle-test/actions/workflows/ruby-2.6.yml [🚎ruby-2.7-wf]: https://github.com/kettle-dev/kettle-test/actions/workflows/ruby-2.7.yml [🚎ruby-3.0-wf]: https://github.com/kettle-dev/kettle-test/actions/workflows/ruby-3.0.yml [🚎ruby-3.1-wf]: https://github.com/kettle-dev/kettle-test/actions/workflows/ruby-3.1.yml [🚎ruby-3.2-wf]: https://github.com/kettle-dev/kettle-test/actions/workflows/ruby-3.2.yml [🚎ruby-3.3-wf]: https://github.com/kettle-dev/kettle-test/actions/workflows/ruby-3.3.yml [🚎ruby-3.4-wf]: https://github.com/kettle-dev/kettle-test/actions/workflows/ruby-3.4.yml [🚎jruby-9.2-wf]: https://github.com/kettle-dev/kettle-test/actions/workflows/jruby-9.2.yml [🚎jruby-9.3-wf]: https://github.com/kettle-dev/kettle-test/actions/workflows/jruby-9.3.yml [🚎jruby-9.4-wf]: https://github.com/kettle-dev/kettle-test/actions/workflows/jruby-9.4.yml [🚎jruby-10.0-wf]: https://github.com/kettle-dev/kettle-test/actions/workflows/jruby-10.0.yml [🚎truby-22.3-wf]: https://github.com/kettle-dev/kettle-test/actions/workflows/truffleruby-22.3.yml [🚎truby-23.0-wf]: https://github.com/kettle-dev/kettle-test/actions/workflows/truffleruby-23.0.yml [🚎truby-23.1-wf]: https://github.com/kettle-dev/kettle-test/actions/workflows/truffleruby-23.1.yml [🚎truby-24.2-wf]: https://github.com/kettle-dev/kettle-test/actions/workflows/truffleruby-24.2.yml [🚎truby-25.0-wf]: https://github.com/kettle-dev/kettle-test/actions/workflows/truffleruby-25.0.yml [🚎truby-33.0-wf]: https://github.com/kettle-dev/kettle-test/actions/workflows/truffleruby-33.0.yml [🚎2-cov-wf]: https://github.com/kettle-dev/kettle-test/actions/workflows/coverage.yml [🚎2-cov-wfi]: https://github.com/kettle-dev/kettle-test/actions/workflows/coverage.yml/badge.svg [🚎3-hd-wf]: https://github.com/kettle-dev/kettle-test/actions/workflows/heads.yml [🚎3-hd-wfi]: https://github.com/kettle-dev/kettle-test/actions/workflows/heads.yml/badge.svg [🚎5-st-wf]: https://github.com/kettle-dev/kettle-test/actions/workflows/style.yml [🚎5-st-wfi]: https://github.com/kettle-dev/kettle-test/actions/workflows/style.yml/badge.svg [🚎9-t-wf]: https://github.com/kettle-dev/kettle-test/actions/workflows/truffle.yml [🚎9-t-wfi]: https://github.com/kettle-dev/kettle-test/actions/workflows/truffle.yml/badge.svg [🚎10-j-wf]: https://github.com/kettle-dev/kettle-test/actions/workflows/jruby.yml [🚎10-j-wfi]: https://github.com/kettle-dev/kettle-test/actions/workflows/jruby.yml/badge.svg [🚎11-c-wf]: https://github.com/kettle-dev/kettle-test/actions/workflows/current.yml [🚎11-c-wfi]: https://github.com/kettle-dev/kettle-test/actions/workflows/current.yml/badge.svg [🚎12-crh-wf]: https://github.com/kettle-dev/kettle-test/actions/workflows/dep-heads.yml [🚎12-crh-wfi]: https://github.com/kettle-dev/kettle-test/actions/workflows/dep-heads.yml/badge.svg [🚎13-🔒️-wf]: https://github.com/kettle-dev/kettle-test/actions/workflows/locked_deps.yml [🚎13-🔒️-wfi]: https://github.com/kettle-dev/kettle-test/actions/workflows/locked_deps.yml/badge.svg [🚎14-🔓️-wf]: https://github.com/kettle-dev/kettle-test/actions/workflows/unlocked_deps.yml [🚎14-🔓️-wfi]: https://github.com/kettle-dev/kettle-test/actions/workflows/unlocked_deps.yml/badge.svg [💎ruby-2.4i]: https://img.shields.io/badge/Ruby-2.4-DF00CA?style=for-the-badge&logo=ruby&logoColor=white [💎ruby-2.5i]: https://img.shields.io/badge/Ruby-2.5-DF00CA?style=for-the-badge&logo=ruby&logoColor=white [💎ruby-2.6i]: https://img.shields.io/badge/Ruby-2.6-DF00CA?style=for-the-badge&logo=ruby&logoColor=white [💎ruby-2.7i]: https://img.shields.io/badge/Ruby-2.7-DF00CA?style=for-the-badge&logo=ruby&logoColor=white [💎ruby-3.0i]: https://img.shields.io/badge/Ruby-3.0-CC342D?style=for-the-badge&logo=ruby&logoColor=white [💎ruby-3.1i]: https://img.shields.io/badge/Ruby-3.1-CC342D?style=for-the-badge&logo=ruby&logoColor=white [💎ruby-3.2i]: https://img.shields.io/badge/Ruby-3.2-CC342D?style=for-the-badge&logo=ruby&logoColor=white [💎ruby-3.3i]: https://img.shields.io/badge/Ruby-3.3-CC342D?style=for-the-badge&logo=ruby&logoColor=white [💎ruby-3.4i]: https://img.shields.io/badge/Ruby-3.4-CC342D?style=for-the-badge&logo=ruby&logoColor=white [💎ruby-c-i]: https://img.shields.io/badge/Ruby-current-CC342D?style=for-the-badge&logo=ruby&logoColor=green [💎ruby-headi]: https://img.shields.io/badge/Ruby-HEAD-CC342D?style=for-the-badge&logo=ruby&logoColor=blue [💎truby-22.3i]: https://img.shields.io/badge/Truffle_Ruby-22.3-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink [💎truby-23.0i]: https://img.shields.io/badge/Truffle_Ruby-23.0-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink [💎truby-23.1i]: https://img.shields.io/badge/Truffle_Ruby-23.1-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink [💎truby-24.2i]: https://img.shields.io/badge/Truffle_Ruby-24.2-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink [💎truby-25.0i]: https://img.shields.io/badge/Truffle_Ruby-25.0-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink [💎truby-33.0i]: https://img.shields.io/badge/Truffle_Ruby-33.0-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink [💎truby-c-i]: https://img.shields.io/badge/Truffle_Ruby-current-34BCB1?style=for-the-badge&logo=ruby&logoColor=green [💎truby-headi]: https://img.shields.io/badge/Truffle_Ruby-HEAD-34BCB1?style=for-the-badge&logo=ruby&logoColor=blue [💎jruby-9.2i]: https://img.shields.io/badge/JRuby-9.2-FBE742?style=for-the-badge&logo=ruby&logoColor=red [💎jruby-9.3i]: https://img.shields.io/badge/JRuby-9.3-FBE742?style=for-the-badge&logo=ruby&logoColor=red [💎jruby-9.4i]: https://img.shields.io/badge/JRuby-9.4-FBE742?style=for-the-badge&logo=ruby&logoColor=red [💎jruby-10.0i]: https://img.shields.io/badge/JRuby-10.0-FBE742?style=for-the-badge&logo=ruby&logoColor=red [💎jruby-c-i]: https://img.shields.io/badge/JRuby-current-FBE742?style=for-the-badge&logo=ruby&logoColor=green [💎jruby-headi]: https://img.shields.io/badge/JRuby-HEAD-FBE742?style=for-the-badge&logo=ruby&logoColor=blue [🤝gh-issues]: https://github.com/kettle-dev/kettle-test/issues [🤝gh-pulls]: https://github.com/kettle-dev/kettle-test/pulls [🤝gl-issues]: https://gitlab.com/kettle-dev/kettle-test/-/issues [🤝gl-pulls]: https://gitlab.com/kettle-dev/kettle-test/-/merge_requests [🤝cb-issues]: https://codeberg.org/kettle-dev/kettle-test/issues [🤝cb-pulls]: https://codeberg.org/kettle-dev/kettle-test/pulls [🤝cb-donate]: https://donate.codeberg.org/ [🤝contributing]: https://github.com/kettle-dev/kettle-test/blob/main/CONTRIBUTING.md [🏀codecov-g]: https://codecov.io/gh/kettle-dev/kettle-test/graph/badge.svg [🖐contrib-rocks]: https://contrib.rocks [🖐contributors]: https://github.com/kettle-dev/kettle-test/graphs/contributors [🖐contributors-img]: https://contrib.rocks/image?repo=kettle-dev/kettle-test [🚎contributors-gl]: https://gitlab.com/kettle-dev/kettle-test/-/graphs/main [🪇conduct]: https://github.com/kettle-dev/kettle-test/blob/main/CODE_OF_CONDUCT.md [🪇conduct-img]: https://img.shields.io/badge/Contributor_Covenant-2.1-259D6C.svg [📌pvc]: http://guides.rubygems.org/patterns/#pessimistic-version-constraint [📌semver]: https://semver.org/spec/v2.0.0.html [📌semver-img]: https://img.shields.io/badge/semver-2.0.0-259D6C.svg?style=flat [📌semver-breaking]: https://github.com/semver/semver/issues/716#issuecomment-869336139 [📌major-versions-not-sacred]: https://tom.preston-werner.com/2022/05/23/major-version-numbers-are-not-sacred.html [📌changelog]: https://github.com/kettle-dev/kettle-test/blob/main/CHANGELOG.md [📗keep-changelog]: https://keepachangelog.com/en/1.0.0/ [📗keep-changelog-img]: https://img.shields.io/badge/keep--a--changelog-1.0.0-34495e.svg?style=flat [📌gitmoji]: https://gitmoji.dev [📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ [🧮kloc-img]: https://img.shields.io/badge/KLOC-0.095-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue [🔐security]: https://github.com/kettle-dev/kettle-test/blob/main/SECURITY.md [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year [📄license]: LICENSE.md [📄license-ref]: LICENSE.md [📄license-img]: https://img.shields.io/badge/License-AGPL--3.0--only_OR_PolyForm--Small--Business--1.0.0-259D6C.svg [📄license-compat]: https://www.apache.org/legal/resolved.html#category-x [📄license-compat-img]: https://img.shields.io/badge/Apache_Incompatible:_Category_X-%E2%9C%97-C0392B.svg?style=flat&logo=Apache [📄ilo-declaration]: https://www.ilo.org/declaration/lang--en/index.htm [📄ilo-declaration-img]: https://img.shields.io/badge/ILO_Fundamental_Principles-✓-259D6C.svg?style=flat [🚎yard-current]: http://rubydoc.info/gems/kettle-test [🚎yard-head]: https://kettle-test.galtzo.com [💎stone_checksums]: https://github.com/galtzo-floss/stone_checksums [💎SHA_checksums]: https://gitlab.com/kettle-dev/kettle-test/-/tree/main/checksums [💎rlts]: https://github.com/rubocop-lts/rubocop-lts [💎rlts-img]: https://img.shields.io/badge/code_style_&_linting-rubocop--lts-34495e.svg?plastic&logo=ruby&logoColor=white [💎appraisal2]: https://github.com/appraisal-rb/appraisal2 [💎appraisal2-img]: https://img.shields.io/badge/appraised_by-appraisal2-34495e.svg?plastic&logo=ruby&logoColor=white [💎d-in-dvcs]: https://railsbling.com/posts/dvcs/put_the_d_in_dvcs/ | Field | Value | |---|---| | Package | kettle-test | | Description | 🍲 Kettle::Test is a meta tool from kettle-dev to streamline testing. Acts as a shim dependency, pulling in many other dependencies, to give you OOTB productivity with a RubyGem, or Ruby app project. Configures RSpec w/ syntactic sugar to make writing tests, and testing more scenarios, easier.Configures each dependency library for proper use in the test suite, so they arrive ready to go. Fund overlooked open source projects - bottom of stack, dev/test dependencies: floss-funding.dev | | Homepage | https://github.com/kettle-dev/kettle-test | | Source | https://github.com/kettle-dev/kettle-test | | License | `AGPL-3.0-only` OR `PolyForm-Small-Business-1.0.0` | | Funding | https://github.com/sponsors/pboling, https://ko-fi.com/pboling, https://liberapay.com/pboling/donate, https://opencollective.com/kettle-dev, https://thanks.dev/u/gh/pboling, https://tidelift.com/funding/github/rubygems/kettle-test, https://www.buymeacoffee.com/pboling |