From 45540b43855bf1ed36b8e97f170ed35b0e50e42d Mon Sep 17 00:00:00 2001 From: Luke Hill Date: Fri, 5 Sep 2025 18:06:49 +0100 Subject: [PATCH 01/18] Initial files --- ruby/Gemfile | 5 +++ ruby/Gemfile.lock | 73 +++++++++++++++++++++++++++++++++ ruby/LICENSE | 21 ++++++++++ ruby/README.md | 81 +++++++++++++++++++++++++++++++++++++ ruby/VERSION | 1 + ruby/cucumber-query.gemspec | 32 +++++++++++++++ 6 files changed, 213 insertions(+) create mode 100644 ruby/Gemfile create mode 100644 ruby/Gemfile.lock create mode 100644 ruby/LICENSE create mode 100644 ruby/README.md create mode 100644 ruby/VERSION create mode 100644 ruby/cucumber-query.gemspec diff --git a/ruby/Gemfile b/ruby/Gemfile new file mode 100644 index 00000000..7f4f5e95 --- /dev/null +++ b/ruby/Gemfile @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +source 'https://rubygems.org' + +gemspec diff --git a/ruby/Gemfile.lock b/ruby/Gemfile.lock new file mode 100644 index 00000000..01462746 --- /dev/null +++ b/ruby/Gemfile.lock @@ -0,0 +1,73 @@ +PATH + remote: . + specs: + cucumber-compatibility-kit (21.0.0) + +GEM + remote: https://rubygems.org/ + specs: + ast (2.4.2) + diff-lcs (1.5.1) + json (2.9.1) + language_server-protocol (3.17.0.4) + lint_roller (1.1.0) + parallel (1.26.3) + parser (3.3.9.0) + ast (~> 2.4.1) + racc + prism (1.4.0) + racc (1.8.1) + rainbow (3.1.1) + regexp_parser (2.10.0) + rspec (3.13.0) + rspec-core (~> 3.13.0) + rspec-expectations (~> 3.13.0) + rspec-mocks (~> 3.13.0) + rspec-core (3.13.2) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.3) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.2) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-support (3.13.2) + rubocop (1.80.2) + json (~> 2.3) + language_server-protocol (~> 3.17.0.2) + lint_roller (~> 1.1.0) + parallel (~> 1.10) + parser (>= 3.3.0.2) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 2.9.3, < 3.0) + rubocop-ast (>= 1.46.0, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 4.0) + rubocop-ast (1.46.0) + parser (>= 3.3.7.2) + prism (~> 1.4) + rubocop-performance (1.25.0) + lint_roller (~> 1.1) + rubocop (>= 1.75.0, < 2.0) + rubocop-ast (>= 1.38.0, < 2.0) + rubocop-rspec (3.7.0) + lint_roller (~> 1.1) + rubocop (~> 1.72, >= 1.72.1) + ruby-progressbar (1.13.0) + unicode-display_width (3.1.4) + unicode-emoji (~> 4.0, >= 4.0.4) + unicode-emoji (4.0.4) + +PLATFORMS + ruby + x86_64-linux + +DEPENDENCIES + cucumber-compatibility-kit! + rspec (~> 3.13) + rubocop (~> 1.80.0) + rubocop-performance (~> 1.25.0) + rubocop-rspec (~> 3.7.0) + +BUNDLED WITH + 2.6.2 diff --git a/ruby/LICENSE b/ruby/LICENSE new file mode 100644 index 00000000..d23a133d --- /dev/null +++ b/ruby/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Cucumber Ltd and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/ruby/README.md b/ruby/README.md new file mode 100644 index 00000000..faeb97a2 --- /dev/null +++ b/ruby/README.md @@ -0,0 +1,81 @@ +# The Cucumber Compatibility Kit for Ruby + +The CCK - aka. Cucumber Compatibility Kit - is a set of features and Messages. +It aims to validate an implementation of the +[Cucumber Messages protocol](https://github.com/cucumber/common/tree/main/messages#cucumber-messages). + +## Overview + +This kit (gem), consists of a set of features, miscellaneous files and messages: + +- Each area will contain one feature, which, once executed, will emit an exhaustive set of messages +as specified by the protocol +- Some of these areas may "also" require miscellaneous files to be used when testing functions +such as attaching images or documents or reading data from files +- Each area will contain a set of messages - serialized as a single `.ndjson` file +This is the reference for the CCK, that a given feature from the kit, when executed using any dedicated +step definitions, must emit the **exact** corresponding messages + +## Installation and Usage + +Add `cucumber-compatibility-kit` to your `Gemfile` as a development dependency, and +install it: + + bundle install + +Then add a spec that could look like this: + +```ruby +# spec/my_compatibility_checks_spec.rb +require 'cucumber/compatibility_kit' + +describe Cucumber::CompatibilityKit, type: :feature do + let(:cucumber_command) { 'bundle exec cucumber --publish-quiet --profile none --format message' } + + # Don't run the retry or skipped CCK Examples (For whatever reason) + examples = Cucumber::CompatibilityKit.gherkin.reject { |example| example == 'retry' || example == 'skipped' } + + examples.each do |example_name| + describe "'#{example_name}' example" do + include_examples 'cucumber compatibility kit' do + let(:example) { example_name } + # You will need to specify the relative support code and cck paths + let(:messages) { `#{cucumber_command} --require #{support_code_path} #{cck_path}` } + end + end + end +end +``` + +`CucumberCompatibilityKit.gherkin` will return an array that lists all the gherkin examples available within the CCK. +Here, we want to execute all of them except the `retry` and `skipped` ones (For whatever reason). + +`let(:messages)` will execute the cucumber command. As we are using the `message` formatter, `messages` will +then contain the messages as a `ndjson` document with one message per line. + +You can use `gem open cucumber-compatibility-kit` in order to take a look at the features and the +expected messages they should produce. They are available in the `features` folder within the gem. + +## More info + +The Cucumber Compatibility Kit is part of the development tools of [Cucumber](https://cucumber.io). +It allows us to make sure that all our implementations are properly supporting our internal protocol +and thus are compatible (and consistent), with each other and our common tools like the [html-formatter](https://github.com/cucumber/html-formatter). + +It can be a valuable tool if you are developing integration with cucumber, or your own implementation of it. + +Join us on [github/cucumber/compatibility-kit](https://github.com/cucumber/compatibility-kit) +to get more help if you need to. + +You can also take a look on [cucumber-ruby](https://github.com/cucumber/cucumber-ruby/blob/v9.2.0/compatibility/cck_spec.rb) +to see how the kit is used there. + +## Development + +Before building this project locally, the samples must be copied from the `devkit`. Use: + +``` +cd ../devkit +npm ci && npm run copy-to:ruby +cd ../ruby +``` diff --git a/ruby/VERSION b/ruby/VERSION new file mode 100644 index 00000000..fb5b5130 --- /dev/null +++ b/ruby/VERSION @@ -0,0 +1 @@ +21.0.0 diff --git a/ruby/cucumber-query.gemspec b/ruby/cucumber-query.gemspec new file mode 100644 index 00000000..e0150586 --- /dev/null +++ b/ruby/cucumber-query.gemspec @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +Gem::Specification.new do |s| + s.name = 'cucumber-query' + s.version = File.read(File.expand_path('VERSION', __dir__)).strip + s.authors = ['Luke Hill'] + s.description = 'Cucumber Query - query messages' + s.summary = "#{s.name}-#{s.version}" + s.email = 'cukebot@cucumber.io' + s.homepage = 'https://github.com/cucumber/query' + s.platform = Gem::Platform::RUBY + s.license = 'MIT' + s.required_ruby_version = '>= 3.2' + s.required_rubygems_version = '>= 3.2.8' + + s.metadata = { + 'bug_tracker_uri' => 'https://github.com/cucumber/query/issues', + 'changelog_uri' => 'https://github.com/cucumber/query/blob/main/CHANGELOG.md', + 'documentation_uri' => 'https://github.com/cucumber/query/blob/main/CONTRIBUTING.md', + 'mailing_list_uri' => 'https://groups.google.com/forum/#!forum/cukes', + 'source_code_uri' => 'https://github.com/cucumber/query/blob/main/ruby' + } + + s.add_development_dependency 'rspec', '~> 3.13' + s.add_development_dependency 'rubocop', '~> 1.80.0' + s.add_development_dependency 'rubocop-performance', '~> 1.25.0' + s.add_development_dependency 'rubocop-rspec', '~> 3.7.0' + + s.files = Dir['README.md', 'LICENSE', 'lib/**/*'] + s.rdoc_options = ['--charset=UTF-8'] + s.require_path = 'lib' +end From 56dca0947c2789a7e230a04d3338b27a417f3915 Mon Sep 17 00:00:00 2001 From: Luke Hill Date: Fri, 5 Sep 2025 18:08:01 +0100 Subject: [PATCH 02/18] Add hidden files --- ruby/.gitignore | 2 ++ ruby/.rspec | 1 + ruby/.rubocop.yml | 19 +++++++++++++++++++ 3 files changed, 22 insertions(+) create mode 100644 ruby/.gitignore create mode 100644 ruby/.rspec create mode 100644 ruby/.rubocop.yml diff --git a/ruby/.gitignore b/ruby/.gitignore new file mode 100644 index 00000000..7ae6fcfb --- /dev/null +++ b/ruby/.gitignore @@ -0,0 +1,2 @@ +Gemfile.lock +*.gem diff --git a/ruby/.rspec b/ruby/.rspec new file mode 100644 index 00000000..4e1e0d2f --- /dev/null +++ b/ruby/.rspec @@ -0,0 +1 @@ +--color diff --git a/ruby/.rubocop.yml b/ruby/.rubocop.yml new file mode 100644 index 00000000..b9132120 --- /dev/null +++ b/ruby/.rubocop.yml @@ -0,0 +1,19 @@ +plugins: + - rubocop-performance + - rubocop-rspec + +inherit_mode: + merge: + - Exclude + +AllCops: + TargetRubyVersion: 3.2 + NewCops: enable + +# Stylistic preference for cucumber +Gemspec/DevelopmentDependencies: + Enabled: false + +# Disabled on our repo's to enable polyglot-release +Gemspec/RequireMFA: + Enabled: false From 28b8f39fb692b9cd4b2f731344f486d0c1906aa6 Mon Sep 17 00:00:00 2001 From: Luke Hill Date: Fri, 5 Sep 2025 18:08:51 +0100 Subject: [PATCH 03/18] Fix typo --- testdata/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testdata/README.md b/testdata/README.md index ed981627..b2136edc 100644 --- a/testdata/README.md +++ b/testdata/README.md @@ -4,7 +4,7 @@ Query uses the examples from the [cucumber compatibility kit](https://github.com for acceptance testing. These examples consist of `.ndjson` files created by the [`fake-cucumber` reference implementation](https://github.com/cucumber/fake-cucumber). -* The `.njdon` files are copied in by running `npm install`. +* The `.ndjson` files are copied in by running `npm install`. * The expected `.xml` files are created by running the `QueryTest#updateExpectedXmlReportFiles` test. From 586594efec48eb1c72b6236dd1eebb43f5fa975e Mon Sep 17 00:00:00 2001 From: Luke Hill Date: Fri, 5 Sep 2025 18:27:46 +0100 Subject: [PATCH 04/18] Add cucumber messages to runtime requirements and port over existing queries --- ruby/Gemfile.lock | 6 ++- ruby/cucumber-query.gemspec | 2 + ruby/lib/cucumber/query/errors.rb | 8 ++++ ruby/lib/cucumber/query/hook_by_test_step.rb | 32 ++++++++++++++ ruby/lib/cucumber/query/pickle_by_test.rb | 26 ++++++++++++ .../query/pickle_step_by_test_step.rb | 26 ++++++++++++ .../query/step_definitions_by_test_step.rb | 40 ++++++++++++++++++ .../query/test_case_started_by_test_case.rb | 42 +++++++++++++++++++ ruby/lib/cucumber/query/test_run_started.rb | 17 ++++++++ 9 files changed, 197 insertions(+), 2 deletions(-) create mode 100644 ruby/lib/cucumber/query/errors.rb create mode 100644 ruby/lib/cucumber/query/hook_by_test_step.rb create mode 100644 ruby/lib/cucumber/query/pickle_by_test.rb create mode 100644 ruby/lib/cucumber/query/pickle_step_by_test_step.rb create mode 100644 ruby/lib/cucumber/query/step_definitions_by_test_step.rb create mode 100644 ruby/lib/cucumber/query/test_case_started_by_test_case.rb create mode 100644 ruby/lib/cucumber/query/test_run_started.rb diff --git a/ruby/Gemfile.lock b/ruby/Gemfile.lock index 01462746..a598c6b3 100644 --- a/ruby/Gemfile.lock +++ b/ruby/Gemfile.lock @@ -1,12 +1,14 @@ PATH remote: . specs: - cucumber-compatibility-kit (21.0.0) + cucumber-query (21.0.0) + cucumber-messages (> 25, < 30) GEM remote: https://rubygems.org/ specs: ast (2.4.2) + cucumber-messages (28.1.0) diff-lcs (1.5.1) json (2.9.1) language_server-protocol (3.17.0.4) @@ -63,7 +65,7 @@ PLATFORMS x86_64-linux DEPENDENCIES - cucumber-compatibility-kit! + cucumber-query! rspec (~> 3.13) rubocop (~> 1.80.0) rubocop-performance (~> 1.25.0) diff --git a/ruby/cucumber-query.gemspec b/ruby/cucumber-query.gemspec index e0150586..d7b32e4b 100644 --- a/ruby/cucumber-query.gemspec +++ b/ruby/cucumber-query.gemspec @@ -21,6 +21,8 @@ Gem::Specification.new do |s| 'source_code_uri' => 'https://github.com/cucumber/query/blob/main/ruby' } + s.add_dependency 'cucumber-messages', '> 25', '< 30' + s.add_development_dependency 'rspec', '~> 3.13' s.add_development_dependency 'rubocop', '~> 1.80.0' s.add_development_dependency 'rubocop-performance', '~> 1.25.0' diff --git a/ruby/lib/cucumber/query/errors.rb b/ruby/lib/cucumber/query/errors.rb new file mode 100644 index 00000000..6526fec1 --- /dev/null +++ b/ruby/lib/cucumber/query/errors.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +module Cucumber + module Query + TestCaseUnknownError = Class.new(StandardError) + TestStepUnknownError = Class.new(StandardError) + end +end diff --git a/ruby/lib/cucumber/query/hook_by_test_step.rb b/ruby/lib/cucumber/query/hook_by_test_step.rb new file mode 100644 index 00000000..4d495ffc --- /dev/null +++ b/ruby/lib/cucumber/query/hook_by_test_step.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require_relative 'errors' + +module Cucumber + module Query + class HookByTestStep + def initialize(config) + @hook_id_by_test_step_id = {} + + config.on_event :test_step_created, &method(:on_test_step_created) + config.on_event :hook_test_step_created, &method(:on_hook_test_step_created) + end + + def hook_id(test_step) + return @hook_id_by_test_step_id[test_step.id] if @hook_id_by_test_step_id.key?(test_step.id) + + raise TestStepUnknownError, "No hook found for #{test_step.id} }. Known: #{@hook_id_by_test_step_id.keys}" + end + + private + + def on_test_step_created(event) + @hook_id_by_test_step_id[event.test_step.id] = nil + end + + def on_hook_test_step_created(event) + @hook_id_by_test_step_id[event.test_step.id] = event.hook.id + end + end + end +end diff --git a/ruby/lib/cucumber/query/pickle_by_test.rb b/ruby/lib/cucumber/query/pickle_by_test.rb new file mode 100644 index 00000000..73dcbb7e --- /dev/null +++ b/ruby/lib/cucumber/query/pickle_by_test.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require_relative 'errors' + +module Cucumber + module Query + class PickleByTest + def initialize(config) + @pickle_id_by_test_case_id = {} + config.on_event :test_case_created, &method(:on_test_case_created) + end + + def pickle_id(test_case) + return @pickle_id_by_test_case_id[test_case.id] if @pickle_id_by_test_case_id.key?(test_case.id) + + raise TestCaseUnknownError, "No pickle found for #{test_case.id} }. Known: #{@pickle_id_by_test_case_id.keys}" + end + + private + + def on_test_case_created(event) + @pickle_id_by_test_case_id[event.test_case.id] = event.pickle.id + end + end + end +end diff --git a/ruby/lib/cucumber/query/pickle_step_by_test_step.rb b/ruby/lib/cucumber/query/pickle_step_by_test_step.rb new file mode 100644 index 00000000..42e788b5 --- /dev/null +++ b/ruby/lib/cucumber/query/pickle_step_by_test_step.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require_relative 'errors' + +module Cucumber + module Query + class PickleStepByTestStep + def initialize(config) + @pickle_id_step_by_test_step_id = {} + config.on_event :test_step_created, &method(:on_test_step_created) + end + + def pickle_step_id(test_step) + return @pickle_id_step_by_test_step_id[test_step.id] if @pickle_id_step_by_test_step_id.key?(test_step.id) + + raise TestStepUnknownError, "No pickle step found for #{test_step.id} }. Known: #{@pickle_id_step_by_test_step_id.keys}" + end + + private + + def on_test_step_created(event) + @pickle_id_step_by_test_step_id[event.test_step.id] = event.pickle_step.id + end + end + end +end diff --git a/ruby/lib/cucumber/query/step_definitions_by_test_step.rb b/ruby/lib/cucumber/query/step_definitions_by_test_step.rb new file mode 100644 index 00000000..cc524afc --- /dev/null +++ b/ruby/lib/cucumber/query/step_definitions_by_test_step.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require_relative 'errors' + +module Cucumber + module Query + class StepDefinitionsByTestStep + def initialize(config) + @step_definition_ids_by_test_step_id = {} + @step_match_arguments_by_test_step_id = {} + + config.on_event :test_step_created, &method(:on_test_step_created) + config.on_event :step_activated, &method(:on_step_activated) + end + + def step_definition_ids(test_step) + return @step_definition_ids_by_test_step_id[test_step.id] if @step_definition_ids_by_test_step_id.key?(test_step.id) + + raise TestStepUnknownError, "No step definition found for #{test_step.id} }. Known: #{@step_definition_ids_by_test_step_id.keys}" + end + + def step_match_arguments(test_step) + return @step_match_arguments_by_test_step_id[test_step.id] if @step_match_arguments_by_test_step_id.key?(test_step.id) + + raise TestStepUnknownError, "No step match arguments found for #{test_step.id} }. Known: #{@step_match_arguments_by_test_step_id.keys}" + end + + private + + def on_test_step_created(event) + @step_definition_ids_by_test_step_id[event.test_step.id] = [] + end + + def on_step_activated(event) + @step_definition_ids_by_test_step_id[event.test_step.id] << event.step_match.step_definition.id + @step_match_arguments_by_test_step_id[event.test_step.id] = event.step_match.step_arguments + end + end + end +end diff --git a/ruby/lib/cucumber/query/test_case_started_by_test_case.rb b/ruby/lib/cucumber/query/test_case_started_by_test_case.rb new file mode 100644 index 00000000..5584cf68 --- /dev/null +++ b/ruby/lib/cucumber/query/test_case_started_by_test_case.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +require_relative 'errors' + +module Cucumber + module Query + class TestCaseStartedByTestCase + def initialize(config) + @config = config + config.on_event :test_case_created, &method(:on_test_case_created) + config.on_event :test_case_started, &method(:on_test_case_started) + + @attempts_by_test_case_id = {} + @test_case_started_id_by_test_case_id = {} + end + + def attempt_by_test_case(test_case) + raise TestCaseUnknownError, "No test case found for #{test_case.id} }. Known: #{@attempts_by_test_case_id.keys}" unless @attempts_by_test_case_id.key?(test_case.id) + + @attempts_by_test_case_id[test_case.id] + end + + def test_case_started_id_by_test_case(test_case) + raise TestCaseUnknownError, "No test case found for #{test_case.id} }. Known: #{@test_case_started_id_by_test_case_id.keys}" unless @test_case_started_id_by_test_case_id.key?(test_case.id) + + @test_case_started_id_by_test_case_id[test_case.id] + end + + private + + def on_test_case_created(event) + @attempts_by_test_case_id[event.test_case.id] = 0 + @test_case_started_id_by_test_case_id[event.test_case.id] = nil + end + + def on_test_case_started(event) + @attempts_by_test_case_id[event.test_case.id] += 1 + @test_case_started_id_by_test_case_id[event.test_case.id] = @config.id_generator.new_id + end + end + end +end diff --git a/ruby/lib/cucumber/query/test_run_started.rb b/ruby/lib/cucumber/query/test_run_started.rb new file mode 100644 index 00000000..6a28c074 --- /dev/null +++ b/ruby/lib/cucumber/query/test_run_started.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require_relative 'errors' + +module Cucumber + module Query + class TestRunStarted + def initialize(config) + @config = config + end + + def id + @id ||= @config.id_generator.new_id + end + end + end +end From 43481b22ea7b6d4136da0aa2631a6ae63470ff4c Mon Sep 17 00:00:00 2001 From: Luke Hill Date: Fri, 5 Sep 2025 18:33:45 +0100 Subject: [PATCH 05/18] Add in spec files --- ruby/.rspec | 1 + .../cucumber/query/hook_by_test_step_spec.rb | 94 ++++++++++ .../cucumber/query/pickle_by_test_spec.rb | 57 ++++++ .../query/pickle_step_by_test_step_spec.rb | 62 +++++++ .../step_definitions_by_test_step_spec.rb | 163 ++++++++++++++++++ .../test_case_started_by_test_case_spec.rb | 83 +++++++++ ruby/spec/spec_helper.rb | 0 7 files changed, 460 insertions(+) create mode 100644 ruby/spec/cucumber/query/hook_by_test_step_spec.rb create mode 100644 ruby/spec/cucumber/query/pickle_by_test_spec.rb create mode 100644 ruby/spec/cucumber/query/pickle_step_by_test_step_spec.rb create mode 100644 ruby/spec/cucumber/query/step_definitions_by_test_step_spec.rb create mode 100644 ruby/spec/cucumber/query/test_case_started_by_test_case_spec.rb create mode 100644 ruby/spec/spec_helper.rb diff --git a/ruby/.rspec b/ruby/.rspec index 4e1e0d2f..3687797e 100644 --- a/ruby/.rspec +++ b/ruby/.rspec @@ -1 +1,2 @@ +--require spec_helper --color diff --git a/ruby/spec/cucumber/query/hook_by_test_step_spec.rb b/ruby/spec/cucumber/query/hook_by_test_step_spec.rb new file mode 100644 index 00000000..6a9bf9d5 --- /dev/null +++ b/ruby/spec/cucumber/query/hook_by_test_step_spec.rb @@ -0,0 +1,94 @@ +# frozen_string_literal: true + +require 'cucumber/formatter/spec_helper' + +require 'cucumber/query/hook_by_test_step' + +describe Cucumber::Query::HookByTestStep do + extend Cucumber::Formatter::SpecHelperDsl + include Cucumber::Formatter::SpecHelper + + before do + Cucumber::Term::ANSIColor.coloring = false + @test_cases = [] + + @out = StringIO.new + @config = actual_runtime.configuration.with_options(out_stream: @out) + @formatter = described_class.new(@config) + + @config.on_event :test_case_started do |event| + @test_cases << event.test_case + end + + @hook_ids = [] + @config.on_event :envelope do |event| + next unless event.envelope.hook + + @hook_ids << event.envelope.hook.id + end + end + + context 'given a single feature' do + before do + run_defined_feature + end + + context 'with a scenario' do + describe '#pickle_step_id' do + define_feature <<-FEATURE + Feature: Banana party + + Scenario: Monkey eats banana + Given there are bananas + FEATURE + + define_steps do + Before() {} + After() {} + end + + it 'provides the ID of the Before Hook used to generate the Test::Step' do + test_case = @test_cases.first + expect(@formatter.hook_id(test_case.test_steps.first)).to eq(@hook_ids.first) + end + + it 'provides the ID of the After Hook used to generate the Test::Step' do + test_case = @test_cases.first + expect(@formatter.hook_id(test_case.test_steps.last)).to eq(@hook_ids.last) + end + + it 'returns nil if the step was not generated from a hook' do + test_case = @test_cases.first + expect(@formatter.hook_id(test_case.test_steps[1])).to be_nil + end + + it 'raises an exception when the test_step is unknown' do + test_step = double + allow(test_step).to receive(:id).and_return('whatever-id') + + expect { @formatter.hook_id(test_step) }.to raise_error(Cucumber::Formatter::TestStepUnknownError) + end + end + end + + context 'with AfterStep hooks' do + describe '#pickle_step_id' do + define_feature <<-FEATURE + Feature: Banana party + + Scenario: Monkey eats banana + Given there are bananas + FEATURE + + define_steps do + AfterStep() {} + end + + it 'provides the ID of the AfterStepHook used to generate the Test::Step' do + test_case = @test_cases.first + expect(@formatter.hook_id(test_case.test_steps.last)).to eq(@hook_ids.first) + end + end + end + end +end diff --git a/ruby/spec/cucumber/query/pickle_by_test_spec.rb b/ruby/spec/cucumber/query/pickle_by_test_spec.rb new file mode 100644 index 00000000..5f790eaf --- /dev/null +++ b/ruby/spec/cucumber/query/pickle_by_test_spec.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +require 'cucumber/formatter/spec_helper' +require 'cucumber/query/pickle_by_test' + +describe Cucumber::Query::PickleByTest do + extend Cucumber::Formatter::SpecHelperDsl + include Cucumber::Formatter::SpecHelper + + before do + Cucumber::Term::ANSIColor.coloring = false + @test_cases = [] + + @out = StringIO.new + @config = actual_runtime.configuration.with_options(out_stream: @out) + @formatter = described_class.new(@config) + + @config.on_event :test_case_created do |event| + @test_cases << event.test_case + end + + @pickle_ids = [] + @config.on_event :envelope do |event| + next unless event.envelope.pickle + + @pickle_ids << event.envelope.pickle.id + end + end + + describe 'given a single feature' do + before do + run_defined_feature + end + + describe 'with a scenario' do + describe '#pickle_id' do + define_feature <<-FEATURE + Feature: Banana party + + Scenario: Monkey eats banana + Given there are bananas + FEATURE + + it 'provides the ID of the pickle used to generate the Test::Case' do + expect(@formatter.pickle_id(@test_cases.first)).to eq(@pickle_ids.first) + end + + it 'raises an error when the Test::Case is unknown' do + test_case = double + allow(test_case).to receive(:id).and_return('whatever-id') + + expect { @formatter.pickle_id(test_case) }.to raise_error(Cucumber::Formatter::TestCaseUnknownError) + end + end + end + end +end diff --git a/ruby/spec/cucumber/query/pickle_step_by_test_step_spec.rb b/ruby/spec/cucumber/query/pickle_step_by_test_step_spec.rb new file mode 100644 index 00000000..2a7415a4 --- /dev/null +++ b/ruby/spec/cucumber/query/pickle_step_by_test_step_spec.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +require 'cucumber/formatter/spec_helper' +require 'cucumber/formatter/query/pickle_step_by_test_step' + +describe Cucumber::Query::PickleStepByTestStep do + extend Cucumber::Formatter::SpecHelperDsl + include Cucumber::Formatter::SpecHelper + + before do + Cucumber::Term::ANSIColor.coloring = false + @test_cases = [] + + @out = StringIO.new + @config = actual_runtime.configuration.with_options(out_stream: @out) + @formatter = described_class.new(@config) + + @config.on_event :test_case_created do |event| + @test_cases << event.test_case + end + + @pickle_step_ids = [] + @config.on_event :envelope do |event| + next unless event.envelope.pickle + + event.envelope.pickle.steps.each do |step| + @pickle_step_ids << step.id + end + end + end + + describe 'given a single feature' do + before do + run_defined_feature + end + + describe 'with a scenario' do + describe '#pickle_step_id' do + define_feature <<-FEATURE + Feature: Banana party + + Scenario: Monkey eats banana + Given there are bananas + FEATURE + + it 'provides the ID of the PickleStep used to generate the Test::Step' do + test_case = @test_cases.first + test_step = test_case.test_steps.first + + expect(@formatter.pickle_step_id(test_step)).to eq(@pickle_step_ids.first) + end + + it 'raises an exception when the test_step is unknown' do + test_step = double + allow(test_step).to receive(:id).and_return('whatever-id') + + expect { @formatter.pickle_step_id(test_step) }.to raise_error(Cucumber::Formatter::TestStepUnknownError) + end + end + end + end +end diff --git a/ruby/spec/cucumber/query/step_definitions_by_test_step_spec.rb b/ruby/spec/cucumber/query/step_definitions_by_test_step_spec.rb new file mode 100644 index 00000000..5b7ab1fd --- /dev/null +++ b/ruby/spec/cucumber/query/step_definitions_by_test_step_spec.rb @@ -0,0 +1,163 @@ +# frozen_string_literal: true + +require 'cucumber/formatter/spec_helper' +require 'cucumber/formatter/query/step_definitions_by_test_step' + +describe Cucumber::Query::StepDefinitionsByTestStep do + extend Cucumber::Formatter::SpecHelperDsl + include Cucumber::Formatter::SpecHelper + + before do + Cucumber::Term::ANSIColor.coloring = false + @test_cases = [] + + @out = StringIO.new + @config = actual_runtime.configuration.with_options(out_stream: @out) + @formatter = described_class.new(@config) + + @config.on_event :test_case_created do |event| + @test_cases << event.test_case + end + + @step_definition_ids = [] + @config.on_event :envelope do |event| + next unless event.envelope.step_definition + + @step_definition_ids << event.envelope.step_definition.id + end + end + + describe 'given a single feature' do + before do + run_defined_feature + end + + describe '#step_definition_ids' do + context 'with a matching step' do + define_steps do + Given(/^there are bananas$/) {} + end + + define_feature <<-FEATURE + Feature: Banana party + + Scenario: Monkey eats banana + Given there are bananas + FEATURE + + it 'provides the ID of the StepDefinition that matches Test::Step' do + test_case = @test_cases.first + test_step = test_case.test_steps.first + + expect(@formatter.step_definition_ids(test_step)).to eq([@step_definition_ids.first]) + end + end + + context 'with a step that was not activated' do + context 'when there is no match' do + define_feature <<-FEATURE + Feature: Banana party + + Scenario: Monkey eats banana + Given there are bananas + FEATURE + + it 'returns an empty array' do + test_case = @test_cases.first + test_step = test_case.test_steps.first + + expect(@formatter.step_definition_ids(test_step)).to be_empty + end + end + + context 'when there are multiple matches' do + define_steps do + Given(/^there are bananas$/) {} + Given(/^there .* bananas$/) {} + end + + define_feature <<-FEATURE + Feature: Banana party + + Scenario: Monkey eats banana + Given there are bananas + FEATURE + + it 'returns an empty array as the step is not activated' do + test_case = @test_cases.first + test_step = test_case.test_steps.first + + expect(@formatter.step_definition_ids(test_step)).to be_empty + end + end + end + + context 'with an unknown step' do + define_feature 'Feature: Banana party' + + it 'raises an exception' do + test_step = double + allow(test_step).to receive(:id).and_return('whatever-id') + + expect { @formatter.step_definition_ids(test_step) }.to raise_error(Cucumber::Formatter::TestStepUnknownError) + end + end + end + + describe '#step_match_arguments' do + context 'with a matching step without arguments' do + define_steps do + Given(/^there are bananas$/) {} + end + + define_feature <<-FEATURE + Feature: Banana party + + Scenario: Monkey eats banana + Given there are bananas + FEATURE + + it 'returns an empty list' do + test_case = @test_cases.first + test_step = test_case.test_steps.first + + expect(@formatter.step_match_arguments(test_step)).to be_empty + end + end + + context 'with a matching step with arguments' do + define_steps do + Given(/^there are (.*)$/) {} + end + + define_feature <<-FEATURE + Feature: Banana party + + Scenario: Monkey eats banana + Given there are bananas + FEATURE + + it 'returns an empty list' do + test_case = @test_cases.first + test_step = test_case.test_steps.first + matches = @formatter.step_match_arguments(test_step) + + expect(matches.count).to eq(1) + expect(matches.first).to be_a(Cucumber::CucumberExpressions::Argument) + expect(matches.first.group.value).to eq('bananas') + end + end + + context 'with an unknown step' do + define_feature 'Feature: Banana party' + + it 'raises an exception' do + test_step = double + allow(test_step).to receive(:id).and_return('whatever-id') + + expect { @formatter.step_match_arguments(test_step) }.to raise_error(Cucumber::Formatter::TestStepUnknownError) + end + end + end + end +end diff --git a/ruby/spec/cucumber/query/test_case_started_by_test_case_spec.rb b/ruby/spec/cucumber/query/test_case_started_by_test_case_spec.rb new file mode 100644 index 00000000..7ed82b48 --- /dev/null +++ b/ruby/spec/cucumber/query/test_case_started_by_test_case_spec.rb @@ -0,0 +1,83 @@ +# frozen_string_literal: true + +require 'cucumber/formatter/spec_helper' +require 'cucumber/formatter/query/test_case_started_by_test_case' + + +describe Cucumber::Query::TestCaseStartedByTestCase do + extend Cucumber::Formatter::SpecHelperDsl + include Cucumber::Formatter::SpecHelper + + before(:each) do + Cucumber::Term::ANSIColor.coloring = false + + @out = StringIO.new + @config = actual_runtime.configuration.with_options(out_stream: @out) + @formatter = described_class.new(@config) + end + + let(:unknown_test_case) do + test_case = double + allow(test_case).to receive(:id).and_return('whatever-id') + test_case + end + + describe '#attempt_by_test_case' do + it 'raises an exception when the TestCase is unknown' do + expect { @formatter.attempt_by_test_case(unknown_test_case) }.to raise_exception(TestCaseUnknownError) + end + + context 'when the test case has been declared' do + before do + @test_case = double + allow(@test_case).to receive(:id).and_return('some-valid-id') + + @config.notify :test_case_created, @test_case, nil + end + + it 'returns 0 if no test_case_started event has been fired' do + expect(@formatter.attempt_by_test_case(@test_case)).to eq(0) + end + + it 'increments the attemp on every test_case_started event' do + @config.notify :test_case_started, @test_case + expect(@formatter.attempt_by_test_case(@test_case)).to eq(1) + + @config.notify :test_case_started, @test_case + expect(@formatter.attempt_by_test_case(@test_case)).to eq(2) + end + end + end + + describe '#test_case_started_id_by_test_case' do + it 'raises an exception when the TestCase is unknown' do + expect { @formatter.test_case_started_id_by_test_case(unknown_test_case) }.to raise_exception(TestCaseUnknownError) + end + + context 'when the test case has been declared' do + before do + @test_case = double + allow(@test_case).to receive(:id).and_return('some-valid-id') + + @config.notify :test_case_created, @test_case, nil + end + + it 'returns nil if no test_case_started event has been fired' do + expect(@formatter.test_case_started_id_by_test_case(@test_case)).to be_nil + end + + it 'gives a new id when a test_case_started event is fired' do + @config.notify :test_case_started, @test_case + + first_attempt_id = @formatter.test_case_started_id_by_test_case(@test_case) + expect(first_attempt_id).not_to be_nil + + @config.notify :test_case_started, @test_case + second_attempt_id = @formatter.test_case_started_id_by_test_case(@test_case) + expect(second_attempt_id).not_to be_nil + + expect(second_attempt_id).not_to eq(first_attempt_id) + end + end + end +end diff --git a/ruby/spec/spec_helper.rb b/ruby/spec/spec_helper.rb new file mode 100644 index 00000000..e69de29b From 0abdd830d37dbdd73d7b0bc784bd1921a2690267 Mon Sep 17 00:00:00 2001 From: Luke Hill Date: Fri, 5 Sep 2025 18:48:07 +0100 Subject: [PATCH 06/18] Fix up all loading, relations and requirements --- ruby/Gemfile.lock | 39 +++++++++++- ruby/cucumber-query.gemspec | 1 + .../cucumber/query/hook_by_test_step_spec.rb | 5 -- ruby/spec/spec_helper.rb | 12 ++++ ruby/spec/support/gherkin_helper.rb | 13 ++++ ruby/spec/support/runner_helper.rb | 63 +++++++++++++++++++ 6 files changed, 127 insertions(+), 6 deletions(-) create mode 100644 ruby/spec/support/gherkin_helper.rb create mode 100644 ruby/spec/support/runner_helper.rb diff --git a/ruby/Gemfile.lock b/ruby/Gemfile.lock index a598c6b3..a65432fe 100644 --- a/ruby/Gemfile.lock +++ b/ruby/Gemfile.lock @@ -8,11 +8,44 @@ GEM remote: https://rubygems.org/ specs: ast (2.4.2) - cucumber-messages (28.1.0) + base64 (0.3.0) + bigdecimal (3.2.3) + builder (3.3.0) + cucumber (10.1.0) + base64 (~> 0.2) + builder (~> 3.2) + cucumber-ci-environment (> 9, < 11) + cucumber-core (> 15, < 17) + cucumber-cucumber-expressions (> 17, < 19) + cucumber-html-formatter (> 20.3, < 22) + diff-lcs (~> 1.5) + logger (~> 1.6) + mini_mime (~> 1.1) + multi_test (~> 1.1) + sys-uname (~> 1.3) + cucumber-ci-environment (10.0.1) + cucumber-core (15.2.1) + cucumber-gherkin (> 27, < 33) + cucumber-messages (> 26, < 30) + cucumber-tag-expressions (> 5, < 7) + cucumber-cucumber-expressions (18.0.1) + bigdecimal + cucumber-gherkin (32.2.0) + cucumber-messages (> 25, < 28) + cucumber-html-formatter (21.14.0) + cucumber-messages (> 19, < 28) + cucumber-messages (27.2.0) + cucumber-tag-expressions (6.1.2) diff-lcs (1.5.1) + ffi (1.17.2) + ffi (1.17.2-x86_64-linux-gnu) json (2.9.1) language_server-protocol (3.17.0.4) lint_roller (1.1.0) + logger (1.7.0) + memoist3 (1.0.0) + mini_mime (1.1.5) + multi_test (1.1.0) parallel (1.26.3) parser (3.3.9.0) ast (~> 2.4.1) @@ -56,6 +89,9 @@ GEM lint_roller (~> 1.1) rubocop (~> 1.72, >= 1.72.1) ruby-progressbar (1.13.0) + sys-uname (1.4.1) + ffi (~> 1.1) + memoist3 (~> 1.0.0) unicode-display_width (3.1.4) unicode-emoji (~> 4.0, >= 4.0.4) unicode-emoji (4.0.4) @@ -65,6 +101,7 @@ PLATFORMS x86_64-linux DEPENDENCIES + cucumber (~> 10.1) cucumber-query! rspec (~> 3.13) rubocop (~> 1.80.0) diff --git a/ruby/cucumber-query.gemspec b/ruby/cucumber-query.gemspec index d7b32e4b..b152a6a4 100644 --- a/ruby/cucumber-query.gemspec +++ b/ruby/cucumber-query.gemspec @@ -23,6 +23,7 @@ Gem::Specification.new do |s| s.add_dependency 'cucumber-messages', '> 25', '< 30' + s.add_development_dependency 'cucumber', '~> 10.1' s.add_development_dependency 'rspec', '~> 3.13' s.add_development_dependency 'rubocop', '~> 1.80.0' s.add_development_dependency 'rubocop-performance', '~> 1.25.0' diff --git a/ruby/spec/cucumber/query/hook_by_test_step_spec.rb b/ruby/spec/cucumber/query/hook_by_test_step_spec.rb index 6a9bf9d5..83c44b0b 100644 --- a/ruby/spec/cucumber/query/hook_by_test_step_spec.rb +++ b/ruby/spec/cucumber/query/hook_by_test_step_spec.rb @@ -1,13 +1,8 @@ # frozen_string_literal: true -require 'cucumber/formatter/spec_helper' - require 'cucumber/query/hook_by_test_step' describe Cucumber::Query::HookByTestStep do - extend Cucumber::Formatter::SpecHelperDsl - include Cucumber::Formatter::SpecHelper - before do Cucumber::Term::ANSIColor.coloring = false @test_cases = [] diff --git a/ruby/spec/spec_helper.rb b/ruby/spec/spec_helper.rb index e69de29b..3c684fd4 100644 --- a/ruby/spec/spec_helper.rb +++ b/ruby/spec/spec_helper.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +require 'cucumber' +require 'cucumber/core' + +require_relative 'support/runner_helper' +require_relative 'support/gherkin_helper' + +RSpec.configure do |c| + c.include RunnerHelper + c.extend GherkinHelper +end diff --git a/ruby/spec/support/gherkin_helper.rb b/ruby/spec/support/gherkin_helper.rb new file mode 100644 index 00000000..9303804a --- /dev/null +++ b/ruby/spec/support/gherkin_helper.rb @@ -0,0 +1,13 @@ + +module GherkinHelper + attr_reader :feature_content, :step_defs, :feature_filename + + def define_feature(string, feature_file = 'spec.feature') + @feature_content = string + @feature_filename = feature_file + end + + def define_steps(&block) + @step_defs = block + end +end diff --git a/ruby/spec/support/runner_helper.rb b/ruby/spec/support/runner_helper.rb new file mode 100644 index 00000000..eebbbfc7 --- /dev/null +++ b/ruby/spec/support/runner_helper.rb @@ -0,0 +1,63 @@ +module RunnerHelper + + include Cucumber::Core + + def run_defined_feature + define_steps + actual_runtime.visitor = Cucumber::Formatter::Fanout.new([@formatter]) + receiver = Test::Runner.new(event_bus) + + event_bus.gherkin_source_read(gherkin_doc.uri, gherkin_doc.body) + + compile [gherkin_doc], receiver, filters, event_bus + + event_bus.test_run_finished + end + + def filters + # TODO: Remove duplication with runtime.rb#filters + [ + Cucumber::Filters::ActivateSteps.new( + Cucumber::StepMatchSearch.new(actual_runtime.support_code.registry.method(:step_matches), actual_runtime.configuration), + actual_runtime.configuration + ), + Cucumber::Filters::ApplyAfterStepHooks.new(actual_runtime.support_code), + Cucumber::Filters::ApplyBeforeHooks.new(actual_runtime.support_code), + Cucumber::Filters::ApplyAfterHooks.new(actual_runtime.support_code), + Cucumber::Filters::ApplyAroundHooks.new(actual_runtime.support_code), + Cucumber::Filters::BroadcastTestRunStartedEvent.new(actual_runtime.configuration), + Cucumber::Filters::BroadcastTestCaseReadyEvent.new(actual_runtime.configuration), + Cucumber::Filters::PrepareWorld.new(actual_runtime) + ] + end + + def gherkin_doc + Cucumber::Core::Gherkin::Document.new(self.class.feature_filename, gherkin) + end + + def gherkin + self.class.feature_content || raise('No feature content defined!') + end + + def actual_runtime + @actual_runtime ||= Cucumber::Runtime.new(options) + end + + def event_bus + actual_runtime.configuration.event_bus + end + + def define_steps + step_defs = self.class.step_defs + + return unless step_defs + + dsl = Object.new + dsl.extend Cucumber::Glue::Dsl + dsl.instance_exec(&step_defs) + end + + def options + {} + end +end From 592f5fa9c7b89be1f39547ea9bb25f8a9be12cfb Mon Sep 17 00:00:00 2001 From: Luke Hill Date: Fri, 5 Sep 2025 18:48:18 +0100 Subject: [PATCH 07/18] Alter error class for new API --- ruby/spec/cucumber/query/hook_by_test_step_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/spec/cucumber/query/hook_by_test_step_spec.rb b/ruby/spec/cucumber/query/hook_by_test_step_spec.rb index 83c44b0b..24bb16ce 100644 --- a/ruby/spec/cucumber/query/hook_by_test_step_spec.rb +++ b/ruby/spec/cucumber/query/hook_by_test_step_spec.rb @@ -61,7 +61,7 @@ test_step = double allow(test_step).to receive(:id).and_return('whatever-id') - expect { @formatter.hook_id(test_step) }.to raise_error(Cucumber::Formatter::TestStepUnknownError) + expect { @formatter.hook_id(test_step) }.to raise_error(Cucumber::Query::TestStepUnknownError) end end end From 31f8e15643245cab7aaae106cf5ba78a53c0e3cd Mon Sep 17 00:00:00 2001 From: Luke Hill Date: Fri, 5 Sep 2025 18:50:45 +0100 Subject: [PATCH 08/18] Alter all other tests to pass --- ruby/spec/cucumber/query/pickle_by_test_spec.rb | 6 +----- .../query/pickle_step_by_test_step_spec.rb | 8 ++------ .../query/step_definitions_by_test_step_spec.rb | 10 +++------- .../query/test_case_started_by_test_case_spec.rb | 15 +++++---------- 4 files changed, 11 insertions(+), 28 deletions(-) diff --git a/ruby/spec/cucumber/query/pickle_by_test_spec.rb b/ruby/spec/cucumber/query/pickle_by_test_spec.rb index 5f790eaf..6ccce6e5 100644 --- a/ruby/spec/cucumber/query/pickle_by_test_spec.rb +++ b/ruby/spec/cucumber/query/pickle_by_test_spec.rb @@ -1,12 +1,8 @@ # frozen_string_literal: true -require 'cucumber/formatter/spec_helper' require 'cucumber/query/pickle_by_test' describe Cucumber::Query::PickleByTest do - extend Cucumber::Formatter::SpecHelperDsl - include Cucumber::Formatter::SpecHelper - before do Cucumber::Term::ANSIColor.coloring = false @test_cases = [] @@ -49,7 +45,7 @@ test_case = double allow(test_case).to receive(:id).and_return('whatever-id') - expect { @formatter.pickle_id(test_case) }.to raise_error(Cucumber::Formatter::TestCaseUnknownError) + expect { @formatter.pickle_id(test_case) }.to raise_error(Cucumber::Query::TestCaseUnknownError) end end end diff --git a/ruby/spec/cucumber/query/pickle_step_by_test_step_spec.rb b/ruby/spec/cucumber/query/pickle_step_by_test_step_spec.rb index 2a7415a4..608fabfa 100644 --- a/ruby/spec/cucumber/query/pickle_step_by_test_step_spec.rb +++ b/ruby/spec/cucumber/query/pickle_step_by_test_step_spec.rb @@ -1,12 +1,8 @@ # frozen_string_literal: true -require 'cucumber/formatter/spec_helper' -require 'cucumber/formatter/query/pickle_step_by_test_step' +require 'cucumber/query/pickle_step_by_test_step' describe Cucumber::Query::PickleStepByTestStep do - extend Cucumber::Formatter::SpecHelperDsl - include Cucumber::Formatter::SpecHelper - before do Cucumber::Term::ANSIColor.coloring = false @test_cases = [] @@ -54,7 +50,7 @@ test_step = double allow(test_step).to receive(:id).and_return('whatever-id') - expect { @formatter.pickle_step_id(test_step) }.to raise_error(Cucumber::Formatter::TestStepUnknownError) + expect { @formatter.pickle_step_id(test_step) }.to raise_error(Cucumber::Query::TestStepUnknownError) end end end diff --git a/ruby/spec/cucumber/query/step_definitions_by_test_step_spec.rb b/ruby/spec/cucumber/query/step_definitions_by_test_step_spec.rb index 5b7ab1fd..23c55b7c 100644 --- a/ruby/spec/cucumber/query/step_definitions_by_test_step_spec.rb +++ b/ruby/spec/cucumber/query/step_definitions_by_test_step_spec.rb @@ -1,12 +1,8 @@ # frozen_string_literal: true -require 'cucumber/formatter/spec_helper' -require 'cucumber/formatter/query/step_definitions_by_test_step' +require 'cucumber/query/step_definitions_by_test_step' describe Cucumber::Query::StepDefinitionsByTestStep do - extend Cucumber::Formatter::SpecHelperDsl - include Cucumber::Formatter::SpecHelper - before do Cucumber::Term::ANSIColor.coloring = false @test_cases = [] @@ -99,7 +95,7 @@ test_step = double allow(test_step).to receive(:id).and_return('whatever-id') - expect { @formatter.step_definition_ids(test_step) }.to raise_error(Cucumber::Formatter::TestStepUnknownError) + expect { @formatter.step_definition_ids(test_step) }.to raise_error(Cucumber::Query::TestStepUnknownError) end end end @@ -155,7 +151,7 @@ test_step = double allow(test_step).to receive(:id).and_return('whatever-id') - expect { @formatter.step_match_arguments(test_step) }.to raise_error(Cucumber::Formatter::TestStepUnknownError) + expect { @formatter.step_match_arguments(test_step) }.to raise_error(Cucumber::Query::TestStepUnknownError) end end end diff --git a/ruby/spec/cucumber/query/test_case_started_by_test_case_spec.rb b/ruby/spec/cucumber/query/test_case_started_by_test_case_spec.rb index 7ed82b48..ed85e51a 100644 --- a/ruby/spec/cucumber/query/test_case_started_by_test_case_spec.rb +++ b/ruby/spec/cucumber/query/test_case_started_by_test_case_spec.rb @@ -1,13 +1,8 @@ # frozen_string_literal: true -require 'cucumber/formatter/spec_helper' -require 'cucumber/formatter/query/test_case_started_by_test_case' - +require 'cucumber/query/test_case_started_by_test_case' describe Cucumber::Query::TestCaseStartedByTestCase do - extend Cucumber::Formatter::SpecHelperDsl - include Cucumber::Formatter::SpecHelper - before(:each) do Cucumber::Term::ANSIColor.coloring = false @@ -23,8 +18,8 @@ end describe '#attempt_by_test_case' do - it 'raises an exception when the TestCase is unknown' do - expect { @formatter.attempt_by_test_case(unknown_test_case) }.to raise_exception(TestCaseUnknownError) + it 'raises an error when the TestCase is unknown' do + expect { @formatter.attempt_by_test_case(unknown_test_case) }.to raise_error(Cucumber::Query::TestCaseUnknownError) end context 'when the test case has been declared' do @@ -50,8 +45,8 @@ end describe '#test_case_started_id_by_test_case' do - it 'raises an exception when the TestCase is unknown' do - expect { @formatter.test_case_started_id_by_test_case(unknown_test_case) }.to raise_exception(TestCaseUnknownError) + it 'raises an error when the TestCase is unknown' do + expect { @formatter.test_case_started_id_by_test_case(unknown_test_case) }.to raise_error(Cucumber::Query::TestCaseUnknownError) end context 'when the test case has been declared' do From ba58ab979345dd55f05f12e81756c0434ab37d84 Mon Sep 17 00:00:00 2001 From: Luke Hill Date: Fri, 5 Sep 2025 18:51:26 +0100 Subject: [PATCH 09/18] Auto-gen rubocop config; --- ruby/.rubocop.yml | 2 + ruby/.rubocop_todo.yml | 113 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 ruby/.rubocop_todo.yml diff --git a/ruby/.rubocop.yml b/ruby/.rubocop.yml index b9132120..4c19d3f7 100644 --- a/ruby/.rubocop.yml +++ b/ruby/.rubocop.yml @@ -1,3 +1,5 @@ +inherit_from: .rubocop_todo.yml + plugins: - rubocop-performance - rubocop-rspec diff --git a/ruby/.rubocop_todo.yml b/ruby/.rubocop_todo.yml new file mode 100644 index 00000000..8c6ecb8c --- /dev/null +++ b/ruby/.rubocop_todo.yml @@ -0,0 +1,113 @@ +# This configuration was generated by +# `rubocop --auto-gen-config` +# on 2025-09-05 17:51:10 UTC using RuboCop version 1.80.2. +# The point is for the user to remove these configuration records +# one by one as the offenses are removed from the code base. +# Note that changes in the inspected code, or installation of new +# versions of RuboCop, may require this file to be generated again. + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: empty_lines, empty_lines_except_namespace, empty_lines_special, no_empty_lines +Layout/EmptyLinesAroundModuleBody: + Exclude: + - 'spec/support/runner_helper.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +Layout/LeadingEmptyLines: + Exclude: + - 'spec/support/gherkin_helper.rb' + +# Offense count: 8 +# Configuration parameters: AllowComments, AllowEmptyLambdas. +Lint/EmptyBlock: + Exclude: + - 'spec/cucumber/query/hook_by_test_step_spec.rb' + - 'spec/cucumber/query/step_definitions_by_test_step_spec.rb' + +# Offense count: 2 +# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes. +Metrics/AbcSize: + Max: 30 + +# Offense count: 1 +# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. +Metrics/MethodLength: + Max: 13 + +# Offense count: 8 +Performance/MethodObjectAsBlock: + Exclude: + - 'lib/cucumber/query/hook_by_test_step.rb' + - 'lib/cucumber/query/pickle_by_test.rb' + - 'lib/cucumber/query/pickle_step_by_test_step.rb' + - 'lib/cucumber/query/step_definitions_by_test_step.rb' + - 'lib/cucumber/query/test_case_started_by_test_case.rb' + +# Offense count: 1 +# Configuration parameters: Prefixes, AllowedPatterns. +# Prefixes: when, with, without +RSpec/ContextWording: + Exclude: + - 'spec/cucumber/query/hook_by_test_step_spec.rb' + +# Offense count: 2 +# Configuration parameters: CountAsOne. +RSpec/ExampleLength: + Max: 7 + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: implicit, each, example +RSpec/HookArgument: + Exclude: + - 'spec/cucumber/query/test_case_started_by_test_case_spec.rb' + +# Offense count: 87 +# Configuration parameters: AssignmentOnly. +RSpec/InstanceVariable: + Exclude: + - 'spec/cucumber/query/hook_by_test_step_spec.rb' + - 'spec/cucumber/query/pickle_by_test_spec.rb' + - 'spec/cucumber/query/pickle_step_by_test_step_spec.rb' + - 'spec/cucumber/query/step_definitions_by_test_step_spec.rb' + - 'spec/cucumber/query/test_case_started_by_test_case_spec.rb' + +# Offense count: 3 +RSpec/MultipleExpectations: + Max: 3 + +# Offense count: 12 +# Configuration parameters: AllowedGroups. +RSpec/NestedGroups: + Max: 5 + +# Offense count: 6 +# Configuration parameters: AllowedConstants. +Style/Documentation: + Exclude: + - 'lib/cucumber/query/hook_by_test_step.rb' + - 'lib/cucumber/query/pickle_by_test.rb' + - 'lib/cucumber/query/pickle_step_by_test_step.rb' + - 'lib/cucumber/query/step_definitions_by_test_step.rb' + - 'lib/cucumber/query/test_case_started_by_test_case.rb' + - 'lib/cucumber/query/test_run_started.rb' + +# Offense count: 2 +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: always, always_true, never +Style/FrozenStringLiteralComment: + Exclude: + - 'spec/support/gherkin_helper.rb' + - 'spec/support/runner_helper.rb' + +# Offense count: 8 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings. +# URISchemes: http, https +Layout/LineLength: + Max: 196 From e1971d424b556163483ba03907f5f78b0f7741f1 Mon Sep 17 00:00:00 2001 From: Luke Hill Date: Fri, 5 Sep 2025 18:54:36 +0100 Subject: [PATCH 10/18] Add note about duplication of code --- ruby/spec/support/gherkin_helper.rb | 1 + ruby/spec/support/runner_helper.rb | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ruby/spec/support/gherkin_helper.rb b/ruby/spec/support/gherkin_helper.rb index 9303804a..a8f83c42 100644 --- a/ruby/spec/support/gherkin_helper.rb +++ b/ruby/spec/support/gherkin_helper.rb @@ -1,3 +1,4 @@ +# TODO: This file is adapted / duplicated from SpecHelperDSL and SpecHelper in cucumber-ruby module GherkinHelper attr_reader :feature_content, :step_defs, :feature_filename diff --git a/ruby/spec/support/runner_helper.rb b/ruby/spec/support/runner_helper.rb index eebbbfc7..8cb9fc03 100644 --- a/ruby/spec/support/runner_helper.rb +++ b/ruby/spec/support/runner_helper.rb @@ -1,3 +1,5 @@ +# TODO: This file is adapted / duplicated from SpecHelperDSL and SpecHelper in cucumber-ruby + module RunnerHelper include Cucumber::Core @@ -15,7 +17,6 @@ def run_defined_feature end def filters - # TODO: Remove duplication with runtime.rb#filters [ Cucumber::Filters::ActivateSteps.new( Cucumber::StepMatchSearch.new(actual_runtime.support_code.registry.method(:step_matches), actual_runtime.configuration), From eb1faf7dd6acbf33add47bf8ed22da88a77878e5 Mon Sep 17 00:00:00 2001 From: Luke Hill Date: Fri, 5 Sep 2025 19:01:10 +0100 Subject: [PATCH 11/18] Minor linting and starting to unpick redundant pieces of spec support --- ruby/spec/cucumber/query/hook_by_test_step_spec.rb | 8 +++----- ruby/spec/cucumber/query/pickle_by_test_spec.rb | 8 +++----- .../cucumber/query/pickle_step_by_test_step_spec.rb | 8 +++----- .../query/step_definitions_by_test_step_spec.rb | 8 +++----- .../query/test_case_started_by_test_case_spec.rb | 4 +--- ruby/spec/support/gherkin_helper.rb | 4 ++-- ruby/spec/support/runner_helper.rb | 12 ++++-------- 7 files changed, 19 insertions(+), 33 deletions(-) diff --git a/ruby/spec/cucumber/query/hook_by_test_step_spec.rb b/ruby/spec/cucumber/query/hook_by_test_step_spec.rb index 24bb16ce..79a8d748 100644 --- a/ruby/spec/cucumber/query/hook_by_test_step_spec.rb +++ b/ruby/spec/cucumber/query/hook_by_test_step_spec.rb @@ -6,17 +6,15 @@ before do Cucumber::Term::ANSIColor.coloring = false @test_cases = [] - - @out = StringIO.new - @config = actual_runtime.configuration.with_options(out_stream: @out) + @config = actual_runtime.configuration.with_options(out_stream: StringIO.new) @formatter = described_class.new(@config) - @config.on_event :test_case_started do |event| + @config.on_event(:test_case_started) do |event| @test_cases << event.test_case end @hook_ids = [] - @config.on_event :envelope do |event| + @config.on_event(:envelope) do |event| next unless event.envelope.hook @hook_ids << event.envelope.hook.id diff --git a/ruby/spec/cucumber/query/pickle_by_test_spec.rb b/ruby/spec/cucumber/query/pickle_by_test_spec.rb index 6ccce6e5..b59b8295 100644 --- a/ruby/spec/cucumber/query/pickle_by_test_spec.rb +++ b/ruby/spec/cucumber/query/pickle_by_test_spec.rb @@ -6,17 +6,15 @@ before do Cucumber::Term::ANSIColor.coloring = false @test_cases = [] - - @out = StringIO.new - @config = actual_runtime.configuration.with_options(out_stream: @out) + @config = actual_runtime.configuration.with_options(out_stream: StringIO.new) @formatter = described_class.new(@config) - @config.on_event :test_case_created do |event| + @config.on_event(:test_case_created) do |event| @test_cases << event.test_case end @pickle_ids = [] - @config.on_event :envelope do |event| + @config.on_event(:envelope) do |event| next unless event.envelope.pickle @pickle_ids << event.envelope.pickle.id diff --git a/ruby/spec/cucumber/query/pickle_step_by_test_step_spec.rb b/ruby/spec/cucumber/query/pickle_step_by_test_step_spec.rb index 608fabfa..5b2af0b5 100644 --- a/ruby/spec/cucumber/query/pickle_step_by_test_step_spec.rb +++ b/ruby/spec/cucumber/query/pickle_step_by_test_step_spec.rb @@ -6,17 +6,15 @@ before do Cucumber::Term::ANSIColor.coloring = false @test_cases = [] - - @out = StringIO.new - @config = actual_runtime.configuration.with_options(out_stream: @out) + @config = actual_runtime.configuration.with_options(out_stream: StringIO.new) @formatter = described_class.new(@config) - @config.on_event :test_case_created do |event| + @config.on_event(:test_case_created) do |event| @test_cases << event.test_case end @pickle_step_ids = [] - @config.on_event :envelope do |event| + @config.on_event(:envelope) do |event| next unless event.envelope.pickle event.envelope.pickle.steps.each do |step| diff --git a/ruby/spec/cucumber/query/step_definitions_by_test_step_spec.rb b/ruby/spec/cucumber/query/step_definitions_by_test_step_spec.rb index 23c55b7c..340c2868 100644 --- a/ruby/spec/cucumber/query/step_definitions_by_test_step_spec.rb +++ b/ruby/spec/cucumber/query/step_definitions_by_test_step_spec.rb @@ -6,17 +6,15 @@ before do Cucumber::Term::ANSIColor.coloring = false @test_cases = [] - - @out = StringIO.new - @config = actual_runtime.configuration.with_options(out_stream: @out) + @config = actual_runtime.configuration.with_options(out_stream: StringIO.new) @formatter = described_class.new(@config) - @config.on_event :test_case_created do |event| + @config.on_event(:test_case_created) do |event| @test_cases << event.test_case end @step_definition_ids = [] - @config.on_event :envelope do |event| + @config.on_event(:envelope) do |event| next unless event.envelope.step_definition @step_definition_ids << event.envelope.step_definition.id diff --git a/ruby/spec/cucumber/query/test_case_started_by_test_case_spec.rb b/ruby/spec/cucumber/query/test_case_started_by_test_case_spec.rb index ed85e51a..29785496 100644 --- a/ruby/spec/cucumber/query/test_case_started_by_test_case_spec.rb +++ b/ruby/spec/cucumber/query/test_case_started_by_test_case_spec.rb @@ -5,9 +5,7 @@ describe Cucumber::Query::TestCaseStartedByTestCase do before(:each) do Cucumber::Term::ANSIColor.coloring = false - - @out = StringIO.new - @config = actual_runtime.configuration.with_options(out_stream: @out) + @config = actual_runtime.configuration.with_options(out_stream: StringIO.new) @formatter = described_class.new(@config) end diff --git a/ruby/spec/support/gherkin_helper.rb b/ruby/spec/support/gherkin_helper.rb index a8f83c42..29bc3e6c 100644 --- a/ruby/spec/support/gherkin_helper.rb +++ b/ruby/spec/support/gherkin_helper.rb @@ -1,7 +1,7 @@ # TODO: This file is adapted / duplicated from SpecHelperDSL and SpecHelper in cucumber-ruby module GherkinHelper - attr_reader :feature_content, :step_defs, :feature_filename + attr_reader :feature_content, :step_definitions, :feature_filename def define_feature(string, feature_file = 'spec.feature') @feature_content = string @@ -9,6 +9,6 @@ def define_feature(string, feature_file = 'spec.feature') end def define_steps(&block) - @step_defs = block + @step_definitions = block end end diff --git a/ruby/spec/support/runner_helper.rb b/ruby/spec/support/runner_helper.rb index 8cb9fc03..44d5f67b 100644 --- a/ruby/spec/support/runner_helper.rb +++ b/ruby/spec/support/runner_helper.rb @@ -41,7 +41,7 @@ def gherkin end def actual_runtime - @actual_runtime ||= Cucumber::Runtime.new(options) + @actual_runtime ||= Cucumber::Runtime.new({}) end def event_bus @@ -49,16 +49,12 @@ def event_bus end def define_steps - step_defs = self.class.step_defs + step_definitions = self.class.step_definitions - return unless step_defs + return unless step_definitions dsl = Object.new dsl.extend Cucumber::Glue::Dsl - dsl.instance_exec(&step_defs) - end - - def options - {} + dsl.instance_exec(&step_definitions) end end From 0a757e8f0095344aff2ccaa435eaac2498d76433 Mon Sep 17 00:00:00 2001 From: Luke Hill Date: Fri, 5 Sep 2025 19:06:50 +0100 Subject: [PATCH 12/18] Lint / DRY up tests --- .../cucumber/query/hook_by_test_step_spec.rb | 15 ++++++--------- .../spec/cucumber/query/pickle_by_test_spec.rb | 1 - .../query/pickle_step_by_test_step_spec.rb | 6 +++--- .../step_definitions_by_test_step_spec.rb | 18 +++++++----------- .../test_case_started_by_test_case_spec.rb | 17 +++++++---------- 5 files changed, 23 insertions(+), 34 deletions(-) diff --git a/ruby/spec/cucumber/query/hook_by_test_step_spec.rb b/ruby/spec/cucumber/query/hook_by_test_step_spec.rb index 79a8d748..2b060412 100644 --- a/ruby/spec/cucumber/query/hook_by_test_step_spec.rb +++ b/ruby/spec/cucumber/query/hook_by_test_step_spec.rb @@ -4,7 +4,6 @@ describe Cucumber::Query::HookByTestStep do before do - Cucumber::Term::ANSIColor.coloring = false @test_cases = [] @config = actual_runtime.configuration.with_options(out_stream: StringIO.new) @formatter = described_class.new(@config) @@ -21,6 +20,8 @@ end end + let(:first_test_case) { @test_cases.first } + context 'given a single feature' do before do run_defined_feature @@ -41,18 +42,15 @@ end it 'provides the ID of the Before Hook used to generate the Test::Step' do - test_case = @test_cases.first - expect(@formatter.hook_id(test_case.test_steps.first)).to eq(@hook_ids.first) + expect(@formatter.hook_id(first_test_case.test_steps.first)).to eq(@hook_ids.first) end it 'provides the ID of the After Hook used to generate the Test::Step' do - test_case = @test_cases.first - expect(@formatter.hook_id(test_case.test_steps.last)).to eq(@hook_ids.last) + expect(@formatter.hook_id(first_test_case.test_steps.last)).to eq(@hook_ids.last) end it 'returns nil if the step was not generated from a hook' do - test_case = @test_cases.first - expect(@formatter.hook_id(test_case.test_steps[1])).to be_nil + expect(@formatter.hook_id(first_test_case.test_steps[1])).to be_nil end it 'raises an exception when the test_step is unknown' do @@ -78,8 +76,7 @@ end it 'provides the ID of the AfterStepHook used to generate the Test::Step' do - test_case = @test_cases.first - expect(@formatter.hook_id(test_case.test_steps.last)).to eq(@hook_ids.first) + expect(@formatter.hook_id(first_test_case.test_steps.last)).to eq(@hook_ids.first) end end end diff --git a/ruby/spec/cucumber/query/pickle_by_test_spec.rb b/ruby/spec/cucumber/query/pickle_by_test_spec.rb index b59b8295..65d92217 100644 --- a/ruby/spec/cucumber/query/pickle_by_test_spec.rb +++ b/ruby/spec/cucumber/query/pickle_by_test_spec.rb @@ -4,7 +4,6 @@ describe Cucumber::Query::PickleByTest do before do - Cucumber::Term::ANSIColor.coloring = false @test_cases = [] @config = actual_runtime.configuration.with_options(out_stream: StringIO.new) @formatter = described_class.new(@config) diff --git a/ruby/spec/cucumber/query/pickle_step_by_test_step_spec.rb b/ruby/spec/cucumber/query/pickle_step_by_test_step_spec.rb index 5b2af0b5..0f5b1ea3 100644 --- a/ruby/spec/cucumber/query/pickle_step_by_test_step_spec.rb +++ b/ruby/spec/cucumber/query/pickle_step_by_test_step_spec.rb @@ -4,7 +4,6 @@ describe Cucumber::Query::PickleStepByTestStep do before do - Cucumber::Term::ANSIColor.coloring = false @test_cases = [] @config = actual_runtime.configuration.with_options(out_stream: StringIO.new) @formatter = described_class.new(@config) @@ -23,6 +22,8 @@ end end + let(:first_test_case) { @test_cases.first } + describe 'given a single feature' do before do run_defined_feature @@ -38,8 +39,7 @@ FEATURE it 'provides the ID of the PickleStep used to generate the Test::Step' do - test_case = @test_cases.first - test_step = test_case.test_steps.first + test_step = first_test_case.test_steps.first expect(@formatter.pickle_step_id(test_step)).to eq(@pickle_step_ids.first) end diff --git a/ruby/spec/cucumber/query/step_definitions_by_test_step_spec.rb b/ruby/spec/cucumber/query/step_definitions_by_test_step_spec.rb index 340c2868..40d9c946 100644 --- a/ruby/spec/cucumber/query/step_definitions_by_test_step_spec.rb +++ b/ruby/spec/cucumber/query/step_definitions_by_test_step_spec.rb @@ -4,7 +4,6 @@ describe Cucumber::Query::StepDefinitionsByTestStep do before do - Cucumber::Term::ANSIColor.coloring = false @test_cases = [] @config = actual_runtime.configuration.with_options(out_stream: StringIO.new) @formatter = described_class.new(@config) @@ -21,6 +20,8 @@ end end + let(:first_test_case) { @test_cases.first } + describe 'given a single feature' do before do run_defined_feature @@ -40,8 +41,7 @@ FEATURE it 'provides the ID of the StepDefinition that matches Test::Step' do - test_case = @test_cases.first - test_step = test_case.test_steps.first + test_step = first_test_case.test_steps.first expect(@formatter.step_definition_ids(test_step)).to eq([@step_definition_ids.first]) end @@ -57,8 +57,7 @@ FEATURE it 'returns an empty array' do - test_case = @test_cases.first - test_step = test_case.test_steps.first + test_step = first_test_case.test_steps.first expect(@formatter.step_definition_ids(test_step)).to be_empty end @@ -78,8 +77,7 @@ FEATURE it 'returns an empty array as the step is not activated' do - test_case = @test_cases.first - test_step = test_case.test_steps.first + test_step = first_test_case.test_steps.first expect(@formatter.step_definition_ids(test_step)).to be_empty end @@ -112,8 +110,7 @@ FEATURE it 'returns an empty list' do - test_case = @test_cases.first - test_step = test_case.test_steps.first + test_step = first_test_case.test_steps.first expect(@formatter.step_match_arguments(test_step)).to be_empty end @@ -132,8 +129,7 @@ FEATURE it 'returns an empty list' do - test_case = @test_cases.first - test_step = test_case.test_steps.first + test_step = first_test_case.test_steps.first matches = @formatter.step_match_arguments(test_step) expect(matches.count).to eq(1) diff --git a/ruby/spec/cucumber/query/test_case_started_by_test_case_spec.rb b/ruby/spec/cucumber/query/test_case_started_by_test_case_spec.rb index 29785496..38ed3e97 100644 --- a/ruby/spec/cucumber/query/test_case_started_by_test_case_spec.rb +++ b/ruby/spec/cucumber/query/test_case_started_by_test_case_spec.rb @@ -3,8 +3,7 @@ require 'cucumber/query/test_case_started_by_test_case' describe Cucumber::Query::TestCaseStartedByTestCase do - before(:each) do - Cucumber::Term::ANSIColor.coloring = false + before do @config = actual_runtime.configuration.with_options(out_stream: StringIO.new) @formatter = described_class.new(@config) end @@ -24,8 +23,7 @@ before do @test_case = double allow(@test_case).to receive(:id).and_return('some-valid-id') - - @config.notify :test_case_created, @test_case, nil + @config.notify(:test_case_created, @test_case, nil) end it 'returns 0 if no test_case_started event has been fired' do @@ -33,10 +31,10 @@ end it 'increments the attemp on every test_case_started event' do - @config.notify :test_case_started, @test_case + @config.notify(:test_case_started, @test_case) expect(@formatter.attempt_by_test_case(@test_case)).to eq(1) - @config.notify :test_case_started, @test_case + @config.notify(:test_case_started, @test_case) expect(@formatter.attempt_by_test_case(@test_case)).to eq(2) end end @@ -51,8 +49,7 @@ before do @test_case = double allow(@test_case).to receive(:id).and_return('some-valid-id') - - @config.notify :test_case_created, @test_case, nil + @config.notify(:test_case_created, @test_case, nil) end it 'returns nil if no test_case_started event has been fired' do @@ -60,12 +57,12 @@ end it 'gives a new id when a test_case_started event is fired' do - @config.notify :test_case_started, @test_case + @config.notify(:test_case_started, @test_case) first_attempt_id = @formatter.test_case_started_id_by_test_case(@test_case) expect(first_attempt_id).not_to be_nil - @config.notify :test_case_started, @test_case + @config.notify(:test_case_started, @test_case) second_attempt_id = @formatter.test_case_started_id_by_test_case(@test_case) expect(second_attempt_id).not_to be_nil From d6d50e7e35f89504b217758db71a300efe52f17f Mon Sep 17 00:00:00 2001 From: Luke Hill Date: Fri, 5 Sep 2025 19:19:18 +0100 Subject: [PATCH 13/18] Linting for tests and 1 bug fix where test case started was firing prematurely --- ruby/lib/cucumber/query/hook_by_test_step.rb | 4 +-- ruby/lib/cucumber/query/pickle_by_test.rb | 3 +- .../query/pickle_step_by_test_step.rb | 3 +- .../query/step_definitions_by_test_step.rb | 4 +-- .../query/test_case_started_by_test_case.rb | 6 ++-- .../cucumber/query/hook_by_test_step_spec.rb | 20 +++++------ .../cucumber/query/pickle_by_test_spec.rb | 15 ++++---- .../query/pickle_step_by_test_step_spec.rb | 14 ++++---- .../step_definitions_by_test_step_spec.rb | 26 +++++++------- .../test_case_started_by_test_case_spec.rb | 35 +++++++++---------- 10 files changed, 65 insertions(+), 65 deletions(-) diff --git a/ruby/lib/cucumber/query/hook_by_test_step.rb b/ruby/lib/cucumber/query/hook_by_test_step.rb index 4d495ffc..c1a1e4f8 100644 --- a/ruby/lib/cucumber/query/hook_by_test_step.rb +++ b/ruby/lib/cucumber/query/hook_by_test_step.rb @@ -8,8 +8,8 @@ class HookByTestStep def initialize(config) @hook_id_by_test_step_id = {} - config.on_event :test_step_created, &method(:on_test_step_created) - config.on_event :hook_test_step_created, &method(:on_hook_test_step_created) + config.on_event(:test_step_created, &method(:on_test_step_created)) + config.on_event(:hook_test_step_created, &method(:on_hook_test_step_created)) end def hook_id(test_step) diff --git a/ruby/lib/cucumber/query/pickle_by_test.rb b/ruby/lib/cucumber/query/pickle_by_test.rb index 73dcbb7e..c8668b28 100644 --- a/ruby/lib/cucumber/query/pickle_by_test.rb +++ b/ruby/lib/cucumber/query/pickle_by_test.rb @@ -7,7 +7,8 @@ module Query class PickleByTest def initialize(config) @pickle_id_by_test_case_id = {} - config.on_event :test_case_created, &method(:on_test_case_created) + + config.on_event(:test_case_created, &method(:on_test_case_created)) end def pickle_id(test_case) diff --git a/ruby/lib/cucumber/query/pickle_step_by_test_step.rb b/ruby/lib/cucumber/query/pickle_step_by_test_step.rb index 42e788b5..cac53537 100644 --- a/ruby/lib/cucumber/query/pickle_step_by_test_step.rb +++ b/ruby/lib/cucumber/query/pickle_step_by_test_step.rb @@ -7,7 +7,8 @@ module Query class PickleStepByTestStep def initialize(config) @pickle_id_step_by_test_step_id = {} - config.on_event :test_step_created, &method(:on_test_step_created) + + config.on_event(:test_step_created, &method(:on_test_step_created)) end def pickle_step_id(test_step) diff --git a/ruby/lib/cucumber/query/step_definitions_by_test_step.rb b/ruby/lib/cucumber/query/step_definitions_by_test_step.rb index cc524afc..7894c24f 100644 --- a/ruby/lib/cucumber/query/step_definitions_by_test_step.rb +++ b/ruby/lib/cucumber/query/step_definitions_by_test_step.rb @@ -9,8 +9,8 @@ def initialize(config) @step_definition_ids_by_test_step_id = {} @step_match_arguments_by_test_step_id = {} - config.on_event :test_step_created, &method(:on_test_step_created) - config.on_event :step_activated, &method(:on_step_activated) + config.on_event(:test_step_created, &method(:on_test_step_created)) + config.on_event(:step_activated, &method(:on_step_activated)) end def step_definition_ids(test_step) diff --git a/ruby/lib/cucumber/query/test_case_started_by_test_case.rb b/ruby/lib/cucumber/query/test_case_started_by_test_case.rb index 5584cf68..08005fec 100644 --- a/ruby/lib/cucumber/query/test_case_started_by_test_case.rb +++ b/ruby/lib/cucumber/query/test_case_started_by_test_case.rb @@ -7,11 +7,11 @@ module Query class TestCaseStartedByTestCase def initialize(config) @config = config - config.on_event :test_case_created, &method(:on_test_case_created) - config.on_event :test_case_started, &method(:on_test_case_started) - @attempts_by_test_case_id = {} @test_case_started_id_by_test_case_id = {} + + config.on_event(:test_case_created, &method(:on_test_case_created)) + config.on_event(:test_case_started, &method(:on_test_case_started)) end def attempt_by_test_case(test_case) diff --git a/ruby/spec/cucumber/query/hook_by_test_step_spec.rb b/ruby/spec/cucumber/query/hook_by_test_step_spec.rb index 2b060412..85d1a113 100644 --- a/ruby/spec/cucumber/query/hook_by_test_step_spec.rb +++ b/ruby/spec/cucumber/query/hook_by_test_step_spec.rb @@ -5,22 +5,22 @@ describe Cucumber::Query::HookByTestStep do before do @test_cases = [] - @config = actual_runtime.configuration.with_options(out_stream: StringIO.new) - @formatter = described_class.new(@config) + @hook_ids = [] - @config.on_event(:test_case_started) do |event| + config.on_event(:test_case_started) do |event| @test_cases << event.test_case end - @hook_ids = [] - @config.on_event(:envelope) do |event| + config.on_event(:envelope) do |event| next unless event.envelope.hook @hook_ids << event.envelope.hook.id end end + let(:config) { actual_runtime.configuration.with_options(out_stream: StringIO.new) } let(:first_test_case) { @test_cases.first } + let(:formatter) { described_class.new(config) } context 'given a single feature' do before do @@ -42,22 +42,22 @@ end it 'provides the ID of the Before Hook used to generate the Test::Step' do - expect(@formatter.hook_id(first_test_case.test_steps.first)).to eq(@hook_ids.first) + expect(formatter.hook_id(first_test_case.test_steps.first)).to eq(@hook_ids.first) end it 'provides the ID of the After Hook used to generate the Test::Step' do - expect(@formatter.hook_id(first_test_case.test_steps.last)).to eq(@hook_ids.last) + expect(formatter.hook_id(first_test_case.test_steps.last)).to eq(@hook_ids.last) end it 'returns nil if the step was not generated from a hook' do - expect(@formatter.hook_id(first_test_case.test_steps[1])).to be_nil + expect(formatter.hook_id(first_test_case.test_steps[1])).to be_nil end it 'raises an exception when the test_step is unknown' do test_step = double allow(test_step).to receive(:id).and_return('whatever-id') - expect { @formatter.hook_id(test_step) }.to raise_error(Cucumber::Query::TestStepUnknownError) + expect { formatter.hook_id(test_step) }.to raise_error(Cucumber::Query::TestStepUnknownError) end end end @@ -76,7 +76,7 @@ end it 'provides the ID of the AfterStepHook used to generate the Test::Step' do - expect(@formatter.hook_id(first_test_case.test_steps.last)).to eq(@hook_ids.first) + expect(formatter.hook_id(first_test_case.test_steps.last)).to eq(@hook_ids.first) end end end diff --git a/ruby/spec/cucumber/query/pickle_by_test_spec.rb b/ruby/spec/cucumber/query/pickle_by_test_spec.rb index 65d92217..f570949a 100644 --- a/ruby/spec/cucumber/query/pickle_by_test_spec.rb +++ b/ruby/spec/cucumber/query/pickle_by_test_spec.rb @@ -5,21 +5,22 @@ describe Cucumber::Query::PickleByTest do before do @test_cases = [] - @config = actual_runtime.configuration.with_options(out_stream: StringIO.new) - @formatter = described_class.new(@config) + @pickle_ids = [] - @config.on_event(:test_case_created) do |event| + config.on_event(:test_case_created) do |event| @test_cases << event.test_case end - @pickle_ids = [] - @config.on_event(:envelope) do |event| + config.on_event(:envelope) do |event| next unless event.envelope.pickle @pickle_ids << event.envelope.pickle.id end end + let(:config) { actual_runtime.configuration.with_options(out_stream: StringIO.new) } + let(:formatter) { described_class.new(config) } + describe 'given a single feature' do before do run_defined_feature @@ -35,14 +36,14 @@ FEATURE it 'provides the ID of the pickle used to generate the Test::Case' do - expect(@formatter.pickle_id(@test_cases.first)).to eq(@pickle_ids.first) + expect(formatter.pickle_id(@test_cases.first)).to eq(@pickle_ids.first) end it 'raises an error when the Test::Case is unknown' do test_case = double allow(test_case).to receive(:id).and_return('whatever-id') - expect { @formatter.pickle_id(test_case) }.to raise_error(Cucumber::Query::TestCaseUnknownError) + expect { formatter.pickle_id(test_case) }.to raise_error(Cucumber::Query::TestCaseUnknownError) end end end diff --git a/ruby/spec/cucumber/query/pickle_step_by_test_step_spec.rb b/ruby/spec/cucumber/query/pickle_step_by_test_step_spec.rb index 0f5b1ea3..d1e0a483 100644 --- a/ruby/spec/cucumber/query/pickle_step_by_test_step_spec.rb +++ b/ruby/spec/cucumber/query/pickle_step_by_test_step_spec.rb @@ -5,15 +5,13 @@ describe Cucumber::Query::PickleStepByTestStep do before do @test_cases = [] - @config = actual_runtime.configuration.with_options(out_stream: StringIO.new) - @formatter = described_class.new(@config) + @pickle_step_ids = [] - @config.on_event(:test_case_created) do |event| + config.on_event(:test_case_created) do |event| @test_cases << event.test_case end - @pickle_step_ids = [] - @config.on_event(:envelope) do |event| + config.on_event(:envelope) do |event| next unless event.envelope.pickle event.envelope.pickle.steps.each do |step| @@ -22,7 +20,9 @@ end end + let(:config) { actual_runtime.configuration.with_options(out_stream: StringIO.new) } let(:first_test_case) { @test_cases.first } + let(:formatter) { described_class.new(config) } describe 'given a single feature' do before do @@ -41,14 +41,14 @@ it 'provides the ID of the PickleStep used to generate the Test::Step' do test_step = first_test_case.test_steps.first - expect(@formatter.pickle_step_id(test_step)).to eq(@pickle_step_ids.first) + expect(formatter.pickle_step_id(test_step)).to eq(@pickle_step_ids.first) end it 'raises an exception when the test_step is unknown' do test_step = double allow(test_step).to receive(:id).and_return('whatever-id') - expect { @formatter.pickle_step_id(test_step) }.to raise_error(Cucumber::Query::TestStepUnknownError) + expect { formatter.pickle_step_id(test_step) }.to raise_error(Cucumber::Query::TestStepUnknownError) end end end diff --git a/ruby/spec/cucumber/query/step_definitions_by_test_step_spec.rb b/ruby/spec/cucumber/query/step_definitions_by_test_step_spec.rb index 40d9c946..a89e3940 100644 --- a/ruby/spec/cucumber/query/step_definitions_by_test_step_spec.rb +++ b/ruby/spec/cucumber/query/step_definitions_by_test_step_spec.rb @@ -5,22 +5,22 @@ describe Cucumber::Query::StepDefinitionsByTestStep do before do @test_cases = [] - @config = actual_runtime.configuration.with_options(out_stream: StringIO.new) - @formatter = described_class.new(@config) + @step_definition_ids = [] - @config.on_event(:test_case_created) do |event| + config.on_event(:test_case_created) do |event| @test_cases << event.test_case end - - @step_definition_ids = [] - @config.on_event(:envelope) do |event| + + config.on_event(:envelope) do |event| next unless event.envelope.step_definition @step_definition_ids << event.envelope.step_definition.id end end + let(:config) { actual_runtime.configuration.with_options(out_stream: StringIO.new) } let(:first_test_case) { @test_cases.first } + let(:formatter) { described_class.new(config) } describe 'given a single feature' do before do @@ -43,7 +43,7 @@ it 'provides the ID of the StepDefinition that matches Test::Step' do test_step = first_test_case.test_steps.first - expect(@formatter.step_definition_ids(test_step)).to eq([@step_definition_ids.first]) + expect(formatter.step_definition_ids(test_step)).to eq([@step_definition_ids.first]) end end @@ -59,7 +59,7 @@ it 'returns an empty array' do test_step = first_test_case.test_steps.first - expect(@formatter.step_definition_ids(test_step)).to be_empty + expect(formatter.step_definition_ids(test_step)).to be_empty end end @@ -79,7 +79,7 @@ it 'returns an empty array as the step is not activated' do test_step = first_test_case.test_steps.first - expect(@formatter.step_definition_ids(test_step)).to be_empty + expect(formatter.step_definition_ids(test_step)).to be_empty end end end @@ -91,7 +91,7 @@ test_step = double allow(test_step).to receive(:id).and_return('whatever-id') - expect { @formatter.step_definition_ids(test_step) }.to raise_error(Cucumber::Query::TestStepUnknownError) + expect { formatter.step_definition_ids(test_step) }.to raise_error(Cucumber::Query::TestStepUnknownError) end end end @@ -112,7 +112,7 @@ it 'returns an empty list' do test_step = first_test_case.test_steps.first - expect(@formatter.step_match_arguments(test_step)).to be_empty + expect(formatter.step_match_arguments(test_step)).to be_empty end end @@ -130,7 +130,7 @@ it 'returns an empty list' do test_step = first_test_case.test_steps.first - matches = @formatter.step_match_arguments(test_step) + matches = formatter.step_match_arguments(test_step) expect(matches.count).to eq(1) expect(matches.first).to be_a(Cucumber::CucumberExpressions::Argument) @@ -145,7 +145,7 @@ test_step = double allow(test_step).to receive(:id).and_return('whatever-id') - expect { @formatter.step_match_arguments(test_step) }.to raise_error(Cucumber::Query::TestStepUnknownError) + expect { formatter.step_match_arguments(test_step) }.to raise_error(Cucumber::Query::TestStepUnknownError) end end end diff --git a/ruby/spec/cucumber/query/test_case_started_by_test_case_spec.rb b/ruby/spec/cucumber/query/test_case_started_by_test_case_spec.rb index 38ed3e97..0f943c6f 100644 --- a/ruby/spec/cucumber/query/test_case_started_by_test_case_spec.rb +++ b/ruby/spec/cucumber/query/test_case_started_by_test_case_spec.rb @@ -3,11 +3,8 @@ require 'cucumber/query/test_case_started_by_test_case' describe Cucumber::Query::TestCaseStartedByTestCase do - before do - @config = actual_runtime.configuration.with_options(out_stream: StringIO.new) - @formatter = described_class.new(@config) - end - + let(:config) { actual_runtime.configuration.with_options(out_stream: StringIO.new) } + let(:formatter) { described_class.new(config) } let(:unknown_test_case) do test_case = double allow(test_case).to receive(:id).and_return('whatever-id') @@ -16,54 +13,54 @@ describe '#attempt_by_test_case' do it 'raises an error when the TestCase is unknown' do - expect { @formatter.attempt_by_test_case(unknown_test_case) }.to raise_error(Cucumber::Query::TestCaseUnknownError) + expect { formatter.attempt_by_test_case(unknown_test_case) }.to raise_error(Cucumber::Query::TestCaseUnknownError) end context 'when the test case has been declared' do before do @test_case = double allow(@test_case).to receive(:id).and_return('some-valid-id') - @config.notify(:test_case_created, @test_case, nil) + config.notify(:test_case_created, @test_case, nil) end it 'returns 0 if no test_case_started event has been fired' do - expect(@formatter.attempt_by_test_case(@test_case)).to eq(0) + expect(formatter.attempt_by_test_case(@test_case)).to eq(0) end it 'increments the attemp on every test_case_started event' do - @config.notify(:test_case_started, @test_case) - expect(@formatter.attempt_by_test_case(@test_case)).to eq(1) + config.notify(:test_case_started, @test_case) + expect(formatter.attempt_by_test_case(@test_case)).to eq(1) - @config.notify(:test_case_started, @test_case) - expect(@formatter.attempt_by_test_case(@test_case)).to eq(2) + config.notify(:test_case_started, @test_case) + expect(formatter.attempt_by_test_case(@test_case)).to eq(2) end end end describe '#test_case_started_id_by_test_case' do it 'raises an error when the TestCase is unknown' do - expect { @formatter.test_case_started_id_by_test_case(unknown_test_case) }.to raise_error(Cucumber::Query::TestCaseUnknownError) + expect { formatter.test_case_started_id_by_test_case(unknown_test_case) }.to raise_error(Cucumber::Query::TestCaseUnknownError) end context 'when the test case has been declared' do before do @test_case = double allow(@test_case).to receive(:id).and_return('some-valid-id') - @config.notify(:test_case_created, @test_case, nil) + config.notify(:test_case_created, @test_case, nil) end it 'returns nil if no test_case_started event has been fired' do - expect(@formatter.test_case_started_id_by_test_case(@test_case)).to be_nil + expect(formatter.test_case_started_id_by_test_case(@test_case)).to be_nil end it 'gives a new id when a test_case_started event is fired' do - @config.notify(:test_case_started, @test_case) + config.notify(:test_case_started, @test_case) - first_attempt_id = @formatter.test_case_started_id_by_test_case(@test_case) + first_attempt_id = formatter.test_case_started_id_by_test_case(@test_case) expect(first_attempt_id).not_to be_nil - @config.notify(:test_case_started, @test_case) - second_attempt_id = @formatter.test_case_started_id_by_test_case(@test_case) + config.notify(:test_case_started, @test_case) + second_attempt_id = formatter.test_case_started_id_by_test_case(@test_case) expect(second_attempt_id).not_to be_nil expect(second_attempt_id).not_to eq(first_attempt_id) From 8ab0e973a7200f02a12a2efbcf1305e4cd214948 Mon Sep 17 00:00:00 2001 From: Luke Hill Date: Fri, 5 Sep 2025 19:33:20 +0100 Subject: [PATCH 14/18] Add in legacy ns; --- ruby/lib/cucumber/query/errors.rb | 8 ---- ruby/lib/cucumber/query/hook_by_test_step.rb | 32 -------------- ruby/lib/cucumber/query/legacy/errors.rb | 10 +++++ .../query/legacy/hook_by_test_step.rb | 34 ++++++++++++++ .../cucumber/query/legacy/pickle_by_test.rb | 29 ++++++++++++ .../query/legacy/pickle_step_by_test_step.rb | 29 ++++++++++++ .../legacy/step_definitions_by_test_step.rb | 42 ++++++++++++++++++ .../legacy/test_case_started_by_test_case.rb | 44 +++++++++++++++++++ .../cucumber/query/legacy/test_run_started.rb | 19 ++++++++ ruby/lib/cucumber/query/pickle_by_test.rb | 27 ------------ .../query/pickle_step_by_test_step.rb | 27 ------------ .../query/step_definitions_by_test_step.rb | 40 ----------------- .../query/test_case_started_by_test_case.rb | 42 ------------------ ruby/lib/cucumber/query/test_run_started.rb | 17 ------- .../{ => legacy}/hook_by_test_step_spec.rb | 6 +-- .../query/{ => legacy}/pickle_by_test_spec.rb | 6 +-- .../pickle_step_by_test_step_spec.rb | 6 +-- .../step_definitions_by_test_step_spec.rb | 8 ++-- .../test_case_started_by_test_case_spec.rb | 8 ++-- 19 files changed, 224 insertions(+), 210 deletions(-) delete mode 100644 ruby/lib/cucumber/query/errors.rb delete mode 100644 ruby/lib/cucumber/query/hook_by_test_step.rb create mode 100644 ruby/lib/cucumber/query/legacy/errors.rb create mode 100644 ruby/lib/cucumber/query/legacy/hook_by_test_step.rb create mode 100644 ruby/lib/cucumber/query/legacy/pickle_by_test.rb create mode 100644 ruby/lib/cucumber/query/legacy/pickle_step_by_test_step.rb create mode 100644 ruby/lib/cucumber/query/legacy/step_definitions_by_test_step.rb create mode 100644 ruby/lib/cucumber/query/legacy/test_case_started_by_test_case.rb create mode 100644 ruby/lib/cucumber/query/legacy/test_run_started.rb delete mode 100644 ruby/lib/cucumber/query/pickle_by_test.rb delete mode 100644 ruby/lib/cucumber/query/pickle_step_by_test_step.rb delete mode 100644 ruby/lib/cucumber/query/step_definitions_by_test_step.rb delete mode 100644 ruby/lib/cucumber/query/test_case_started_by_test_case.rb delete mode 100644 ruby/lib/cucumber/query/test_run_started.rb rename ruby/spec/cucumber/query/{ => legacy}/hook_by_test_step_spec.rb (93%) rename ruby/spec/cucumber/query/{ => legacy}/pickle_by_test_spec.rb (89%) rename ruby/spec/cucumber/query/{ => legacy}/pickle_step_by_test_step_spec.rb (89%) rename ruby/spec/cucumber/query/{ => legacy}/step_definitions_by_test_step_spec.rb (94%) rename ruby/spec/cucumber/query/{ => legacy}/test_case_started_by_test_case_spec.rb (89%) diff --git a/ruby/lib/cucumber/query/errors.rb b/ruby/lib/cucumber/query/errors.rb deleted file mode 100644 index 6526fec1..00000000 --- a/ruby/lib/cucumber/query/errors.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true - -module Cucumber - module Query - TestCaseUnknownError = Class.new(StandardError) - TestStepUnknownError = Class.new(StandardError) - end -end diff --git a/ruby/lib/cucumber/query/hook_by_test_step.rb b/ruby/lib/cucumber/query/hook_by_test_step.rb deleted file mode 100644 index c1a1e4f8..00000000 --- a/ruby/lib/cucumber/query/hook_by_test_step.rb +++ /dev/null @@ -1,32 +0,0 @@ -# frozen_string_literal: true - -require_relative 'errors' - -module Cucumber - module Query - class HookByTestStep - def initialize(config) - @hook_id_by_test_step_id = {} - - config.on_event(:test_step_created, &method(:on_test_step_created)) - config.on_event(:hook_test_step_created, &method(:on_hook_test_step_created)) - end - - def hook_id(test_step) - return @hook_id_by_test_step_id[test_step.id] if @hook_id_by_test_step_id.key?(test_step.id) - - raise TestStepUnknownError, "No hook found for #{test_step.id} }. Known: #{@hook_id_by_test_step_id.keys}" - end - - private - - def on_test_step_created(event) - @hook_id_by_test_step_id[event.test_step.id] = nil - end - - def on_hook_test_step_created(event) - @hook_id_by_test_step_id[event.test_step.id] = event.hook.id - end - end - end -end diff --git a/ruby/lib/cucumber/query/legacy/errors.rb b/ruby/lib/cucumber/query/legacy/errors.rb new file mode 100644 index 00000000..fc94315d --- /dev/null +++ b/ruby/lib/cucumber/query/legacy/errors.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module Cucumber + module Query + module Legacy + TestCaseUnknownError = Class.new(StandardError) + TestStepUnknownError = Class.new(StandardError) + end + end +end diff --git a/ruby/lib/cucumber/query/legacy/hook_by_test_step.rb b/ruby/lib/cucumber/query/legacy/hook_by_test_step.rb new file mode 100644 index 00000000..7953684a --- /dev/null +++ b/ruby/lib/cucumber/query/legacy/hook_by_test_step.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require_relative 'errors' + +module Cucumber + module Query + module Legacy + class HookByTestStep + def initialize(config) + @hook_id_by_test_step_id = {} + + config.on_event(:test_step_created, &method(:on_test_step_created)) + config.on_event(:hook_test_step_created, &method(:on_hook_test_step_created)) + end + + def hook_id(test_step) + return @hook_id_by_test_step_id[test_step.id] if @hook_id_by_test_step_id.key?(test_step.id) + + raise TestStepUnknownError, "No hook found for #{test_step.id} }. Known: #{@hook_id_by_test_step_id.keys}" + end + + private + + def on_test_step_created(event) + @hook_id_by_test_step_id[event.test_step.id] = nil + end + + def on_hook_test_step_created(event) + @hook_id_by_test_step_id[event.test_step.id] = event.hook.id + end + end + end + end +end diff --git a/ruby/lib/cucumber/query/legacy/pickle_by_test.rb b/ruby/lib/cucumber/query/legacy/pickle_by_test.rb new file mode 100644 index 00000000..c9a5a35c --- /dev/null +++ b/ruby/lib/cucumber/query/legacy/pickle_by_test.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require_relative 'errors' + +module Cucumber + module Query + module Legacy + class PickleByTest + def initialize(config) + @pickle_id_by_test_case_id = {} + + config.on_event(:test_case_created, &method(:on_test_case_created)) + end + + def pickle_id(test_case) + return @pickle_id_by_test_case_id[test_case.id] if @pickle_id_by_test_case_id.key?(test_case.id) + + raise TestCaseUnknownError, "No pickle found for #{test_case.id} }. Known: #{@pickle_id_by_test_case_id.keys}" + end + + private + + def on_test_case_created(event) + @pickle_id_by_test_case_id[event.test_case.id] = event.pickle.id + end + end + end + end +end diff --git a/ruby/lib/cucumber/query/legacy/pickle_step_by_test_step.rb b/ruby/lib/cucumber/query/legacy/pickle_step_by_test_step.rb new file mode 100644 index 00000000..aee77f74 --- /dev/null +++ b/ruby/lib/cucumber/query/legacy/pickle_step_by_test_step.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require_relative 'errors' + +module Cucumber + module Query + module Legacy + class PickleStepByTestStep + def initialize(config) + @pickle_id_step_by_test_step_id = {} + + config.on_event(:test_step_created, &method(:on_test_step_created)) + end + + def pickle_step_id(test_step) + return @pickle_id_step_by_test_step_id[test_step.id] if @pickle_id_step_by_test_step_id.key?(test_step.id) + + raise TestStepUnknownError, "No pickle step found for #{test_step.id} }. Known: #{@pickle_id_step_by_test_step_id.keys}" + end + + private + + def on_test_step_created(event) + @pickle_id_step_by_test_step_id[event.test_step.id] = event.pickle_step.id + end + end + end + end +end diff --git a/ruby/lib/cucumber/query/legacy/step_definitions_by_test_step.rb b/ruby/lib/cucumber/query/legacy/step_definitions_by_test_step.rb new file mode 100644 index 00000000..ae82f7c6 --- /dev/null +++ b/ruby/lib/cucumber/query/legacy/step_definitions_by_test_step.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +require_relative 'errors' + +module Cucumber + module Query + module Legacy + class StepDefinitionsByTestStep + def initialize(config) + @step_definition_ids_by_test_step_id = {} + @step_match_arguments_by_test_step_id = {} + + config.on_event(:test_step_created, &method(:on_test_step_created)) + config.on_event(:step_activated, &method(:on_step_activated)) + end + + def step_definition_ids(test_step) + return @step_definition_ids_by_test_step_id[test_step.id] if @step_definition_ids_by_test_step_id.key?(test_step.id) + + raise TestStepUnknownError, "No step definition found for #{test_step.id} }. Known: #{@step_definition_ids_by_test_step_id.keys}" + end + + def step_match_arguments(test_step) + return @step_match_arguments_by_test_step_id[test_step.id] if @step_match_arguments_by_test_step_id.key?(test_step.id) + + raise TestStepUnknownError, "No step match arguments found for #{test_step.id} }. Known: #{@step_match_arguments_by_test_step_id.keys}" + end + + private + + def on_test_step_created(event) + @step_definition_ids_by_test_step_id[event.test_step.id] = [] + end + + def on_step_activated(event) + @step_definition_ids_by_test_step_id[event.test_step.id] << event.step_match.step_definition.id + @step_match_arguments_by_test_step_id[event.test_step.id] = event.step_match.step_arguments + end + end + end + end +end diff --git a/ruby/lib/cucumber/query/legacy/test_case_started_by_test_case.rb b/ruby/lib/cucumber/query/legacy/test_case_started_by_test_case.rb new file mode 100644 index 00000000..8153cc50 --- /dev/null +++ b/ruby/lib/cucumber/query/legacy/test_case_started_by_test_case.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +require_relative 'errors' + +module Cucumber + module Query + module Legacy + class TestCaseStartedByTestCase + def initialize(config) + @config = config + @attempts_by_test_case_id = {} + @test_case_started_id_by_test_case_id = {} + + config.on_event(:test_case_created, &method(:on_test_case_created)) + config.on_event(:test_case_started, &method(:on_test_case_started)) + end + + def attempt_by_test_case(test_case) + raise TestCaseUnknownError, "No test case found for #{test_case.id} }. Known: #{@attempts_by_test_case_id.keys}" unless @attempts_by_test_case_id.key?(test_case.id) + + @attempts_by_test_case_id[test_case.id] + end + + def test_case_started_id_by_test_case(test_case) + raise TestCaseUnknownError, "No test case found for #{test_case.id} }. Known: #{@test_case_started_id_by_test_case_id.keys}" unless @test_case_started_id_by_test_case_id.key?(test_case.id) + + @test_case_started_id_by_test_case_id[test_case.id] + end + + private + + def on_test_case_created(event) + @attempts_by_test_case_id[event.test_case.id] = 0 + @test_case_started_id_by_test_case_id[event.test_case.id] = nil + end + + def on_test_case_started(event) + @attempts_by_test_case_id[event.test_case.id] += 1 + @test_case_started_id_by_test_case_id[event.test_case.id] = @config.id_generator.new_id + end + end + end + end +end diff --git a/ruby/lib/cucumber/query/legacy/test_run_started.rb b/ruby/lib/cucumber/query/legacy/test_run_started.rb new file mode 100644 index 00000000..ccc1a162 --- /dev/null +++ b/ruby/lib/cucumber/query/legacy/test_run_started.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require_relative 'errors' + +module Cucumber + module Query + module Legacy + class TestRunStarted + def initialize(config) + @config = config + end + + def id + @id ||= @config.id_generator.new_id + end + end + end + end +end diff --git a/ruby/lib/cucumber/query/pickle_by_test.rb b/ruby/lib/cucumber/query/pickle_by_test.rb deleted file mode 100644 index c8668b28..00000000 --- a/ruby/lib/cucumber/query/pickle_by_test.rb +++ /dev/null @@ -1,27 +0,0 @@ -# frozen_string_literal: true - -require_relative 'errors' - -module Cucumber - module Query - class PickleByTest - def initialize(config) - @pickle_id_by_test_case_id = {} - - config.on_event(:test_case_created, &method(:on_test_case_created)) - end - - def pickle_id(test_case) - return @pickle_id_by_test_case_id[test_case.id] if @pickle_id_by_test_case_id.key?(test_case.id) - - raise TestCaseUnknownError, "No pickle found for #{test_case.id} }. Known: #{@pickle_id_by_test_case_id.keys}" - end - - private - - def on_test_case_created(event) - @pickle_id_by_test_case_id[event.test_case.id] = event.pickle.id - end - end - end -end diff --git a/ruby/lib/cucumber/query/pickle_step_by_test_step.rb b/ruby/lib/cucumber/query/pickle_step_by_test_step.rb deleted file mode 100644 index cac53537..00000000 --- a/ruby/lib/cucumber/query/pickle_step_by_test_step.rb +++ /dev/null @@ -1,27 +0,0 @@ -# frozen_string_literal: true - -require_relative 'errors' - -module Cucumber - module Query - class PickleStepByTestStep - def initialize(config) - @pickle_id_step_by_test_step_id = {} - - config.on_event(:test_step_created, &method(:on_test_step_created)) - end - - def pickle_step_id(test_step) - return @pickle_id_step_by_test_step_id[test_step.id] if @pickle_id_step_by_test_step_id.key?(test_step.id) - - raise TestStepUnknownError, "No pickle step found for #{test_step.id} }. Known: #{@pickle_id_step_by_test_step_id.keys}" - end - - private - - def on_test_step_created(event) - @pickle_id_step_by_test_step_id[event.test_step.id] = event.pickle_step.id - end - end - end -end diff --git a/ruby/lib/cucumber/query/step_definitions_by_test_step.rb b/ruby/lib/cucumber/query/step_definitions_by_test_step.rb deleted file mode 100644 index 7894c24f..00000000 --- a/ruby/lib/cucumber/query/step_definitions_by_test_step.rb +++ /dev/null @@ -1,40 +0,0 @@ -# frozen_string_literal: true - -require_relative 'errors' - -module Cucumber - module Query - class StepDefinitionsByTestStep - def initialize(config) - @step_definition_ids_by_test_step_id = {} - @step_match_arguments_by_test_step_id = {} - - config.on_event(:test_step_created, &method(:on_test_step_created)) - config.on_event(:step_activated, &method(:on_step_activated)) - end - - def step_definition_ids(test_step) - return @step_definition_ids_by_test_step_id[test_step.id] if @step_definition_ids_by_test_step_id.key?(test_step.id) - - raise TestStepUnknownError, "No step definition found for #{test_step.id} }. Known: #{@step_definition_ids_by_test_step_id.keys}" - end - - def step_match_arguments(test_step) - return @step_match_arguments_by_test_step_id[test_step.id] if @step_match_arguments_by_test_step_id.key?(test_step.id) - - raise TestStepUnknownError, "No step match arguments found for #{test_step.id} }. Known: #{@step_match_arguments_by_test_step_id.keys}" - end - - private - - def on_test_step_created(event) - @step_definition_ids_by_test_step_id[event.test_step.id] = [] - end - - def on_step_activated(event) - @step_definition_ids_by_test_step_id[event.test_step.id] << event.step_match.step_definition.id - @step_match_arguments_by_test_step_id[event.test_step.id] = event.step_match.step_arguments - end - end - end -end diff --git a/ruby/lib/cucumber/query/test_case_started_by_test_case.rb b/ruby/lib/cucumber/query/test_case_started_by_test_case.rb deleted file mode 100644 index 08005fec..00000000 --- a/ruby/lib/cucumber/query/test_case_started_by_test_case.rb +++ /dev/null @@ -1,42 +0,0 @@ -# frozen_string_literal: true - -require_relative 'errors' - -module Cucumber - module Query - class TestCaseStartedByTestCase - def initialize(config) - @config = config - @attempts_by_test_case_id = {} - @test_case_started_id_by_test_case_id = {} - - config.on_event(:test_case_created, &method(:on_test_case_created)) - config.on_event(:test_case_started, &method(:on_test_case_started)) - end - - def attempt_by_test_case(test_case) - raise TestCaseUnknownError, "No test case found for #{test_case.id} }. Known: #{@attempts_by_test_case_id.keys}" unless @attempts_by_test_case_id.key?(test_case.id) - - @attempts_by_test_case_id[test_case.id] - end - - def test_case_started_id_by_test_case(test_case) - raise TestCaseUnknownError, "No test case found for #{test_case.id} }. Known: #{@test_case_started_id_by_test_case_id.keys}" unless @test_case_started_id_by_test_case_id.key?(test_case.id) - - @test_case_started_id_by_test_case_id[test_case.id] - end - - private - - def on_test_case_created(event) - @attempts_by_test_case_id[event.test_case.id] = 0 - @test_case_started_id_by_test_case_id[event.test_case.id] = nil - end - - def on_test_case_started(event) - @attempts_by_test_case_id[event.test_case.id] += 1 - @test_case_started_id_by_test_case_id[event.test_case.id] = @config.id_generator.new_id - end - end - end -end diff --git a/ruby/lib/cucumber/query/test_run_started.rb b/ruby/lib/cucumber/query/test_run_started.rb deleted file mode 100644 index 6a28c074..00000000 --- a/ruby/lib/cucumber/query/test_run_started.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -require_relative 'errors' - -module Cucumber - module Query - class TestRunStarted - def initialize(config) - @config = config - end - - def id - @id ||= @config.id_generator.new_id - end - end - end -end diff --git a/ruby/spec/cucumber/query/hook_by_test_step_spec.rb b/ruby/spec/cucumber/query/legacy/hook_by_test_step_spec.rb similarity index 93% rename from ruby/spec/cucumber/query/hook_by_test_step_spec.rb rename to ruby/spec/cucumber/query/legacy/hook_by_test_step_spec.rb index 85d1a113..b7100eed 100644 --- a/ruby/spec/cucumber/query/hook_by_test_step_spec.rb +++ b/ruby/spec/cucumber/query/legacy/hook_by_test_step_spec.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true -require 'cucumber/query/hook_by_test_step' +require 'cucumber/query/legacy/hook_by_test_step' -describe Cucumber::Query::HookByTestStep do +describe Cucumber::Query::Legacy::HookByTestStep do before do @test_cases = [] @hook_ids = [] @@ -57,7 +57,7 @@ test_step = double allow(test_step).to receive(:id).and_return('whatever-id') - expect { formatter.hook_id(test_step) }.to raise_error(Cucumber::Query::TestStepUnknownError) + expect { formatter.hook_id(test_step) }.to raise_error(Cucumber::Query::Legacy::TestStepUnknownError) end end end diff --git a/ruby/spec/cucumber/query/pickle_by_test_spec.rb b/ruby/spec/cucumber/query/legacy/pickle_by_test_spec.rb similarity index 89% rename from ruby/spec/cucumber/query/pickle_by_test_spec.rb rename to ruby/spec/cucumber/query/legacy/pickle_by_test_spec.rb index f570949a..e463b84d 100644 --- a/ruby/spec/cucumber/query/pickle_by_test_spec.rb +++ b/ruby/spec/cucumber/query/legacy/pickle_by_test_spec.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true -require 'cucumber/query/pickle_by_test' +require 'cucumber/query/legacy/pickle_by_test' -describe Cucumber::Query::PickleByTest do +describe Cucumber::Query::Legacy::PickleByTest do before do @test_cases = [] @pickle_ids = [] @@ -43,7 +43,7 @@ test_case = double allow(test_case).to receive(:id).and_return('whatever-id') - expect { formatter.pickle_id(test_case) }.to raise_error(Cucumber::Query::TestCaseUnknownError) + expect { formatter.pickle_id(test_case) }.to raise_error(Cucumber::Query::Legacy::TestCaseUnknownError) end end end diff --git a/ruby/spec/cucumber/query/pickle_step_by_test_step_spec.rb b/ruby/spec/cucumber/query/legacy/pickle_step_by_test_step_spec.rb similarity index 89% rename from ruby/spec/cucumber/query/pickle_step_by_test_step_spec.rb rename to ruby/spec/cucumber/query/legacy/pickle_step_by_test_step_spec.rb index d1e0a483..7b16c027 100644 --- a/ruby/spec/cucumber/query/pickle_step_by_test_step_spec.rb +++ b/ruby/spec/cucumber/query/legacy/pickle_step_by_test_step_spec.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true -require 'cucumber/query/pickle_step_by_test_step' +require 'cucumber/query/legacy/pickle_step_by_test_step' -describe Cucumber::Query::PickleStepByTestStep do +describe Cucumber::Query::Legacy::PickleStepByTestStep do before do @test_cases = [] @pickle_step_ids = [] @@ -48,7 +48,7 @@ test_step = double allow(test_step).to receive(:id).and_return('whatever-id') - expect { formatter.pickle_step_id(test_step) }.to raise_error(Cucumber::Query::TestStepUnknownError) + expect { formatter.pickle_step_id(test_step) }.to raise_error(Cucumber::Query::Legacy::TestStepUnknownError) end end end diff --git a/ruby/spec/cucumber/query/step_definitions_by_test_step_spec.rb b/ruby/spec/cucumber/query/legacy/step_definitions_by_test_step_spec.rb similarity index 94% rename from ruby/spec/cucumber/query/step_definitions_by_test_step_spec.rb rename to ruby/spec/cucumber/query/legacy/step_definitions_by_test_step_spec.rb index a89e3940..398d6623 100644 --- a/ruby/spec/cucumber/query/step_definitions_by_test_step_spec.rb +++ b/ruby/spec/cucumber/query/legacy/step_definitions_by_test_step_spec.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true -require 'cucumber/query/step_definitions_by_test_step' +require 'cucumber/query/legacy/step_definitions_by_test_step' -describe Cucumber::Query::StepDefinitionsByTestStep do +describe Cucumber::Query::Legacy::StepDefinitionsByTestStep do before do @test_cases = [] @step_definition_ids = [] @@ -91,7 +91,7 @@ test_step = double allow(test_step).to receive(:id).and_return('whatever-id') - expect { formatter.step_definition_ids(test_step) }.to raise_error(Cucumber::Query::TestStepUnknownError) + expect { formatter.step_definition_ids(test_step) }.to raise_error(Cucumber::Query::Legacy::TestStepUnknownError) end end end @@ -145,7 +145,7 @@ test_step = double allow(test_step).to receive(:id).and_return('whatever-id') - expect { formatter.step_match_arguments(test_step) }.to raise_error(Cucumber::Query::TestStepUnknownError) + expect { formatter.step_match_arguments(test_step) }.to raise_error(Cucumber::Query::Legacy::TestStepUnknownError) end end end diff --git a/ruby/spec/cucumber/query/test_case_started_by_test_case_spec.rb b/ruby/spec/cucumber/query/legacy/test_case_started_by_test_case_spec.rb similarity index 89% rename from ruby/spec/cucumber/query/test_case_started_by_test_case_spec.rb rename to ruby/spec/cucumber/query/legacy/test_case_started_by_test_case_spec.rb index 0f943c6f..b27b6ebc 100644 --- a/ruby/spec/cucumber/query/test_case_started_by_test_case_spec.rb +++ b/ruby/spec/cucumber/query/legacy/test_case_started_by_test_case_spec.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true -require 'cucumber/query/test_case_started_by_test_case' +require 'cucumber/query/legacy/test_case_started_by_test_case' -describe Cucumber::Query::TestCaseStartedByTestCase do +describe Cucumber::Query::Legacy::TestCaseStartedByTestCase do let(:config) { actual_runtime.configuration.with_options(out_stream: StringIO.new) } let(:formatter) { described_class.new(config) } let(:unknown_test_case) do @@ -13,7 +13,7 @@ describe '#attempt_by_test_case' do it 'raises an error when the TestCase is unknown' do - expect { formatter.attempt_by_test_case(unknown_test_case) }.to raise_error(Cucumber::Query::TestCaseUnknownError) + expect { formatter.attempt_by_test_case(unknown_test_case) }.to raise_error(Cucumber::Query::Legacy::TestCaseUnknownError) end context 'when the test case has been declared' do @@ -39,7 +39,7 @@ describe '#test_case_started_id_by_test_case' do it 'raises an error when the TestCase is unknown' do - expect { formatter.test_case_started_id_by_test_case(unknown_test_case) }.to raise_error(Cucumber::Query::TestCaseUnknownError) + expect { formatter.test_case_started_id_by_test_case(unknown_test_case) }.to raise_error(Cucumber::Query::Legacy::TestCaseUnknownError) end context 'when the test case has been declared' do From 6559a25c179366857edee7658223be5f12c1ca1e Mon Sep 17 00:00:00 2001 From: Luke Hill Date: Fri, 5 Sep 2025 19:44:34 +0100 Subject: [PATCH 15/18] Ported over helpers from JS --- ruby/lib/cucumber/query/foo/bar.rb | 1 + ruby/lib/cucumber/query/helpers.rb | 23 +++++++++++++++++++++++ ruby/lib/cucumber/query/query.rb | 3 +++ 3 files changed, 27 insertions(+) create mode 100644 ruby/lib/cucumber/query/foo/bar.rb create mode 100644 ruby/lib/cucumber/query/helpers.rb create mode 100644 ruby/lib/cucumber/query/query.rb diff --git a/ruby/lib/cucumber/query/foo/bar.rb b/ruby/lib/cucumber/query/foo/bar.rb new file mode 100644 index 00000000..cd877773 --- /dev/null +++ b/ruby/lib/cucumber/query/foo/bar.rb @@ -0,0 +1 @@ +'placeholder' diff --git a/ruby/lib/cucumber/query/helpers.rb b/ruby/lib/cucumber/query/helpers.rb new file mode 100644 index 00000000..0c59d7cf --- /dev/null +++ b/ruby/lib/cucumber/query/helpers.rb @@ -0,0 +1,23 @@ +require 'cucumber/messages/test_step_result_status' + +module Cucumber + module Query + module Helpers + def status_ordinal(status) + [ + TestStepResultStatus::UNKNOWN, + TestStepResultStatus::PASSED, + TestStepResultStatus::SKIPPED, + TestStepResultStatus::PENDING, + TestStepResultStatus::UNDEFINED, + TestStepResultStatus::AMBIGUOUS, + TestStepResultStatus::FAILED + ].index(status) + end + + def assert(target, failure_message) + raise StandardError, failure_message unless target + end + end + end +end diff --git a/ruby/lib/cucumber/query/query.rb b/ruby/lib/cucumber/query/query.rb new file mode 100644 index 00000000..19fb08de --- /dev/null +++ b/ruby/lib/cucumber/query/query.rb @@ -0,0 +1,3 @@ +require_relative 'helpers' + +require_relative 'foo/bar' From d67d975663bc2e963d7128f9bfbb10d9630a51c1 Mon Sep 17 00:00:00 2001 From: Luke Hill Date: Fri, 5 Sep 2025 20:33:27 +0100 Subject: [PATCH 16/18] Initial implementation of initializer and update method --- ruby/lib/cucumber/query/query.rb | 79 ++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/ruby/lib/cucumber/query/query.rb b/ruby/lib/cucumber/query/query.rb index 19fb08de..80691def 100644 --- a/ruby/lib/cucumber/query/query.rb +++ b/ruby/lib/cucumber/query/query.rb @@ -1,3 +1,82 @@ require_relative 'helpers' require_relative 'foo/bar' + +module Cucumber + class Query + def initialize + @test_step_result_by_pickle_id = [{}] + @test_step_results_by_pickle_step_id = [[]] + @test_case_by_pickle_id = [] + @pickle_id_by_test_step_id = [] + @pickle_step_id_by_test_step_id = [] + @test_step_results_by_test_step_id = [[]] + @test_step_ids_by_pickle_step_id = [{}] + @hooks_by_id = {} + @attachments_by_test_step_id = [] + @step_match_arguments_lists_by_pickle_step_id = [{}] + @meta = :not_sure_on_this + @test_run_started = :not_sure_on_this + @test_run_finished = :not_sure_on_this + @test_case_started_by_id = [] + @lineage_by_id = [] + @step_by_id = [] + @pickle_by_id = [] + @pickle_step_by_id = [] + @step_definition_by_id = {} + @test_case_by_id = [] + @test_case_finished_by_test_case_started_id = [[]] + @test_step_started_by_test_case_started_id = [[]] + @test_step_finished_by_test_case_started_id = [[]] + @attachments_by_test_case_started_id = [[]] + end + + def update(envelope) + @meta = envelope.meta if envelope.meta + update_gherkin_document(envelope.gherkin_document) if envelope.gherkin_document + update_pickle(envelope.pickle) if envelope.gherkin_document + @hooks_by_id[envelope.hook.id] = envelope.hook if envelope.hook + @step_definition_by_id[envelope.step_definition.id] = envelope.step_definition if envelope.step_definition + @test_run_started = envelope.test_run_started if envelope.test_run_started + update_test_case(envelope.test_case) if envelope.test_case + update_test_case_started(envelope.test_case_started) if envelope.test_case_started + update_test_step_started(envelope.test_step_started) if envelope.test_step_started + update_attachment(envelope.attachment) if envelope.attachment + update_test_step_finished(envelope.test_step_finished) if envelope.test_step_finished + update_test_case_finished(envelope.test_case_finished) if envelope.test_case_finished + @test_run_finished = envelope.test_run_finished if envelope.test_run_finished + end + + def update_gherkin_document(gherkin_document) + :not_yet_implemented + end + + def update_pickle(pickle) + :not_yet_implemented + end + + def update_test_case(test_case) + :not_yet_implemented + end + + def update_test_case_started(test_case_started) + :not_yet_implemented + end + + def update_test_step_started(test_step_started) + :not_yet_implemented + end + + def update_attachment(attachment) + :not_yet_implemented + end + + def update_test_step_finished(test_step_finished) + :not_yet_implemented + end + + def update_test_case_finished(test_case_finished) + :not_yet_implemented + end + end +end From 5907172240d13c09c34db739e9e4c52e2cfab546 Mon Sep 17 00:00:00 2001 From: Luke Hill Date: Fri, 5 Sep 2025 20:34:19 +0100 Subject: [PATCH 17/18] Remove un-needed placeholder --- ruby/lib/cucumber/query/foo/bar.rb | 1 - ruby/lib/cucumber/query/query.rb | 2 -- 2 files changed, 3 deletions(-) delete mode 100644 ruby/lib/cucumber/query/foo/bar.rb diff --git a/ruby/lib/cucumber/query/foo/bar.rb b/ruby/lib/cucumber/query/foo/bar.rb deleted file mode 100644 index cd877773..00000000 --- a/ruby/lib/cucumber/query/foo/bar.rb +++ /dev/null @@ -1 +0,0 @@ -'placeholder' diff --git a/ruby/lib/cucumber/query/query.rb b/ruby/lib/cucumber/query/query.rb index 80691def..319e38ee 100644 --- a/ruby/lib/cucumber/query/query.rb +++ b/ruby/lib/cucumber/query/query.rb @@ -1,7 +1,5 @@ require_relative 'helpers' -require_relative 'foo/bar' - module Cucumber class Query def initialize From 3643ae91ca2b238262263fc4863703bdca5378fd Mon Sep 17 00:00:00 2001 From: Luke Hill Date: Fri, 5 Sep 2025 20:34:47 +0100 Subject: [PATCH 18/18] Regen the rubocop config; --- ruby/.rubocop_todo.yml | 93 ++++++++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 39 deletions(-) diff --git a/ruby/.rubocop_todo.yml b/ruby/.rubocop_todo.yml index 8c6ecb8c..4f132b72 100644 --- a/ruby/.rubocop_todo.yml +++ b/ruby/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2025-09-05 17:51:10 UTC using RuboCop version 1.80.2. +# on 2025-09-05 19:34:38 UTC using RuboCop version 1.80.2. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -16,65 +16,76 @@ Layout/EmptyLinesAroundModuleBody: # Offense count: 1 # This cop supports safe autocorrection (--autocorrect). -Layout/LeadingEmptyLines: +# Configuration parameters: AllowInHeredoc. +Layout/TrailingWhitespace: Exclude: - - 'spec/support/gherkin_helper.rb' + - 'spec/cucumber/query/legacy/step_definitions_by_test_step_spec.rb' # Offense count: 8 # Configuration parameters: AllowComments, AllowEmptyLambdas. Lint/EmptyBlock: Exclude: - - 'spec/cucumber/query/hook_by_test_step_spec.rb' - - 'spec/cucumber/query/step_definitions_by_test_step_spec.rb' + - 'spec/cucumber/query/legacy/hook_by_test_step_spec.rb' + - 'spec/cucumber/query/legacy/step_definitions_by_test_step_spec.rb' + +# Offense count: 8 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods, NotImplementedExceptions. +# NotImplementedExceptions: NotImplementedError +Lint/UnusedMethodArgument: + Exclude: + - 'lib/cucumber/query/query.rb' -# Offense count: 2 +# Offense count: 4 # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes. Metrics/AbcSize: - Max: 30 + Max: 43 # Offense count: 1 +# Configuration parameters: AllowedMethods, AllowedPatterns. +Metrics/CyclomaticComplexity: + Max: 14 + +# Offense count: 3 # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. Metrics/MethodLength: - Max: 13 + Max: 24 + +# Offense count: 1 +# Configuration parameters: AllowedMethods, AllowedPatterns. +Metrics/PerceivedComplexity: + Max: 14 # Offense count: 8 Performance/MethodObjectAsBlock: Exclude: - - 'lib/cucumber/query/hook_by_test_step.rb' - - 'lib/cucumber/query/pickle_by_test.rb' - - 'lib/cucumber/query/pickle_step_by_test_step.rb' - - 'lib/cucumber/query/step_definitions_by_test_step.rb' - - 'lib/cucumber/query/test_case_started_by_test_case.rb' + - 'lib/cucumber/query/legacy/hook_by_test_step.rb' + - 'lib/cucumber/query/legacy/pickle_by_test.rb' + - 'lib/cucumber/query/legacy/pickle_step_by_test_step.rb' + - 'lib/cucumber/query/legacy/step_definitions_by_test_step.rb' + - 'lib/cucumber/query/legacy/test_case_started_by_test_case.rb' # Offense count: 1 # Configuration parameters: Prefixes, AllowedPatterns. # Prefixes: when, with, without RSpec/ContextWording: Exclude: - - 'spec/cucumber/query/hook_by_test_step_spec.rb' + - 'spec/cucumber/query/legacy/hook_by_test_step_spec.rb' -# Offense count: 2 +# Offense count: 1 # Configuration parameters: CountAsOne. RSpec/ExampleLength: Max: 7 -# Offense count: 1 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: implicit, each, example -RSpec/HookArgument: - Exclude: - - 'spec/cucumber/query/test_case_started_by_test_case_spec.rb' - -# Offense count: 87 +# Offense count: 32 # Configuration parameters: AssignmentOnly. RSpec/InstanceVariable: Exclude: - - 'spec/cucumber/query/hook_by_test_step_spec.rb' - - 'spec/cucumber/query/pickle_by_test_spec.rb' - - 'spec/cucumber/query/pickle_step_by_test_step_spec.rb' - - 'spec/cucumber/query/step_definitions_by_test_step_spec.rb' - - 'spec/cucumber/query/test_case_started_by_test_case_spec.rb' + - 'spec/cucumber/query/legacy/hook_by_test_step_spec.rb' + - 'spec/cucumber/query/legacy/pickle_by_test_spec.rb' + - 'spec/cucumber/query/legacy/pickle_step_by_test_step_spec.rb' + - 'spec/cucumber/query/legacy/step_definitions_by_test_step_spec.rb' + - 'spec/cucumber/query/legacy/test_case_started_by_test_case_spec.rb' # Offense count: 3 RSpec/MultipleExpectations: @@ -85,23 +96,27 @@ RSpec/MultipleExpectations: RSpec/NestedGroups: Max: 5 -# Offense count: 6 +# Offense count: 8 # Configuration parameters: AllowedConstants. Style/Documentation: Exclude: - - 'lib/cucumber/query/hook_by_test_step.rb' - - 'lib/cucumber/query/pickle_by_test.rb' - - 'lib/cucumber/query/pickle_step_by_test_step.rb' - - 'lib/cucumber/query/step_definitions_by_test_step.rb' - - 'lib/cucumber/query/test_case_started_by_test_case.rb' - - 'lib/cucumber/query/test_run_started.rb' - -# Offense count: 2 + - 'lib/cucumber/query/helpers.rb' + - 'lib/cucumber/query/legacy/hook_by_test_step.rb' + - 'lib/cucumber/query/legacy/pickle_by_test.rb' + - 'lib/cucumber/query/legacy/pickle_step_by_test_step.rb' + - 'lib/cucumber/query/legacy/step_definitions_by_test_step.rb' + - 'lib/cucumber/query/legacy/test_case_started_by_test_case.rb' + - 'lib/cucumber/query/legacy/test_run_started.rb' + - 'lib/cucumber/query/query.rb' + +# Offense count: 4 # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: EnforcedStyle. # SupportedStyles: always, always_true, never Style/FrozenStringLiteralComment: Exclude: + - 'lib/cucumber/query/helpers.rb' + - 'lib/cucumber/query/query.rb' - 'spec/support/gherkin_helper.rb' - 'spec/support/runner_helper.rb' @@ -110,4 +125,4 @@ Style/FrozenStringLiteralComment: # Configuration parameters: AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings. # URISchemes: http, https Layout/LineLength: - Max: 196 + Max: 198