diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 35af4cd1..145f46bb 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,17 +1,15 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2026-01-06 12:52:49 UTC using RuboCop version 1.81.7. +# on 2026-04-06 21:27:57 UTC using RuboCop version 1.81.7. # 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. -# TODO: [LH] v14 Pre-release iteration -> 58 files inspected, 392 offenses detected, 100 offenses auto-correctable -# TODO: [LH] v14 Pre-release iteration 2 (Rubocop upgrade) -> 60 files inspected, 324 offenses detected, 86 offenses autocorrectable -# TODO: [LH] v14 Pre-release iteration 3 (Rubocop additional upgrade) -> 60 files inspected, 267 offenses detected, 26 offenses autocorrectable # TODO: [LH] v15 Release incoming (Minimum ruby bump) -> 60 files inspected, 234 offenses detected, 12 offenses autocorrectable # TODO: [LH] v15.1 (Minor fixes) -> 60 files inspected, 239 offenses detected, 15 offenses autocorrectable # TODO: [LH] v16 (Gherkin/Message bump) -> 61 files inspected, 272 offenses detected, 60 offenses autocorrectable +# TODO: [LH] v16.2 (Generic refactors / new events) -> 79 files inspected, 222 offenses detected, 10 offenses autocorrectable # Offense count: 1 # This cop supports safe autocorrection (--autocorrect). diff --git a/lib/cucumber/core/compiler.rb b/lib/cucumber/core/compiler.rb index 7cfecf02..252eb26c 100644 --- a/lib/cucumber/core/compiler.rb +++ b/lib/cucumber/core/compiler.rb @@ -16,7 +16,7 @@ class Compiler attr_reader :receiver, :gherkin_query, :id_generator private :receiver, :gherkin_query, :id_generator - def initialize(receiver, gherkin_query, event_bus = nil) + def initialize(receiver, gherkin_query, event_bus) @receiver = receiver @id_generator = Cucumber::Messages::Helpers::IdGenerator::UUID.new @gherkin_query = gherkin_query @@ -42,7 +42,7 @@ def create_test_case(pickle) parent_locations = parent_locations_from_pickle(pickle) tags = tags_from_pickle(pickle, uri) Test::Case.new(id_generator.new_id, pickle.name, test_steps, location, parent_locations, tags, pickle.language).tap do |test_case| - @event_bus&.test_case_created(test_case, pickle) + @event_bus.test_case_created(test_case, pickle) end end @@ -50,7 +50,7 @@ def create_test_step(pickle_step, uri) location = location_from_pickle_step(pickle_step, uri) multiline_arg = create_multiline_arg(pickle_step, uri) Test::Step.new(id_generator.new_id, pickle_step.text, location, multiline_arg).tap do |test_step| - @event_bus&.test_step_created(test_step, pickle_step) + @event_bus.test_step_created(test_step, pickle_step) end end diff --git a/lib/cucumber/core/gherkin/document.rb b/lib/cucumber/core/gherkin/document.rb index c8dd1fa2..9b6f3b44 100644 --- a/lib/cucumber/core/gherkin/document.rb +++ b/lib/cucumber/core/gherkin/document.rb @@ -6,10 +6,10 @@ module Gherkin class Document attr_reader :uri, :body, :language - def initialize(uri, body, language = nil) - @uri = uri - @body = body - @language = language || 'en' + def initialize(uri, body, language = 'en') + @uri = uri + @body = body + @language = language end def to_s diff --git a/lib/cucumber/core/gherkin/parser.rb b/lib/cucumber/core/gherkin/parser.rb index 2029c0d9..3ee8eea6 100644 --- a/lib/cucumber/core/gherkin/parser.rb +++ b/lib/cucumber/core/gherkin/parser.rb @@ -64,15 +64,11 @@ def update_gherkin_query(message) end def type(message) - if !message.gherkin_document.nil? - :gherkin_document - elsif !message.pickle.nil? - :pickle - elsif message.parse_error - :parse_error - else - :unknown - end + return :gherkin_document if message.gherkin_document + return :pickle if message.pickle + return :parse_error if message.parse_error + + :unknown end end end diff --git a/lib/cucumber/core/platform.rb b/lib/cucumber/core/platform.rb deleted file mode 100644 index 341fa07e..00000000 --- a/lib/cucumber/core/platform.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -# Detect the platform we're running on so we can tweak behaviour -# in various places. -require 'rbconfig' - -module Cucumber - unless defined?(Cucumber::VERSION) - JRUBY = defined?(JRUBY_VERSION) - IRONRUBY = defined?(RUBY_ENGINE) && RUBY_ENGINE == 'ironruby' - WINDOWS = RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ - OS_X = RbConfig::CONFIG['host_os'] =~ /darwin/ - WINDOWS_MRI = WINDOWS && !JRUBY && !IRONRUBY - RUBY_2_0 = RUBY_VERSION =~ /^2\.0/ - RUBY_1_9 = RUBY_VERSION =~ /^1\.9/ - end -end diff --git a/lib/cucumber/core/test/action.rb b/lib/cucumber/core/test/action.rb index 2f49ccf5..79e81000 100644 --- a/lib/cucumber/core/test/action.rb +++ b/lib/cucumber/core/test/action.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true -require 'cucumber/core/test/location' -require 'cucumber/core/test/result' -require 'cucumber/core/test/timer' +require_relative 'location' +require_relative 'result' +require_relative 'timer' -require 'cucumber/core/test/action/defined' -require 'cucumber/core/test/action/undefined' -require 'cucumber/core/test/action/unskippable' +require_relative 'action/defined' +require_relative 'action/undefined' +require_relative 'action/unskippable' diff --git a/lib/cucumber/core/test/around_hook.rb b/lib/cucumber/core/test/around_hook.rb index cf0d3108..d0558a9e 100644 --- a/lib/cucumber/core/test/around_hook.rb +++ b/lib/cucumber/core/test/around_hook.rb @@ -13,10 +13,6 @@ def describe_to(visitor, *, &) visitor.around_hook(self, *, &) end - def hook? - true - end - def execute(*_args, &continue) @timer.start @block.call(continue) @@ -27,6 +23,10 @@ def execute(*_args, &continue) failed(e) end + def hook? + true + end + private def failed(exception) diff --git a/lib/cucumber/core/test/case.rb b/lib/cucumber/core/test/case.rb index 608431e2..f3a585da 100644 --- a/lib/cucumber/core/test/case.rb +++ b/lib/cucumber/core/test/case.rb @@ -1,8 +1,9 @@ # frozen_string_literal: true -require 'cucumber/core/test/result' require 'cucumber/tag_expressions' +require_relative 'result' + module Cucumber module Core module Test @@ -22,8 +23,8 @@ def initialize(id, name, test_steps, location, parent_locations, tags, language, @around_hooks = around_hooks end - def step_count - test_steps.count + def ==(other) + eql?(other) end def describe_to(visitor, *args) @@ -37,20 +38,25 @@ def describe_to(visitor, *args) self end - def with_steps(test_steps) - self.class.new(id, name, test_steps, location, parent_locations, tags, language, around_hooks) + def eql?(other) + other.hash == hash end - def with_around_hooks(around_hooks) - self.class.new(id, name, test_steps, location, parent_locations, tags, language, around_hooks) + def hash + location.hash end - def match_tags?(*expressions) - expressions.flatten.all? { |expression| match_single_tag_expression?(expression) } + def inspect + "#<#{self.class}: #{location}>" end - def match_name?(name_regexp) - name =~ name_regexp + def matching_locations + [ + parent_locations, + location, + tags.map(&:location), + test_steps.map(&:matching_locations) + ].flatten end def match_locations?(queried_locations) @@ -61,29 +67,24 @@ def match_locations?(queried_locations) end end - def matching_locations - [ - parent_locations, - location, - tags.map(&:location), - test_steps.map(&:matching_locations) - ].flatten + def match_name?(name_regexp) + name =~ name_regexp end - def inspect - "#<#{self.class}: #{location}>" + def match_tags?(*expressions) + expressions.flatten.all? { |expression| match_single_tag_expression?(expression) } end - def hash - location.hash + def step_count + test_steps.count end - def eql?(other) - other.hash == hash + def with_around_hooks(around_hooks) + self.class.new(id, name, test_steps, location, parent_locations, tags, language, around_hooks) end - def ==(other) - eql?(other) + def with_steps(test_steps) + self.class.new(id, name, test_steps, location, parent_locations, tags, language, around_hooks) end private diff --git a/lib/cucumber/core/test/data_table.rb b/lib/cucumber/core/test/data_table.rb index f8d88411..bc03f28b 100644 --- a/lib/cucumber/core/test/data_table.rb +++ b/lib/cucumber/core/test/data_table.rb @@ -16,60 +16,52 @@ module Test # # And a matching StepDefinition: # - # Given /I have:/ do |table| + # Given('I have:') do |table| # data = table.raw # end # # This will store [['a', 'b'], ['c', 'd']] in the data variable. # class DataTable - # Creates a new instance. +raw+ should be an Array of Array of String - # or an Array of Hash + attr_reader :raw + + # Creates a new instance. +raw+ should be a square (2d), array of strings or an array of hashes + # # You don't typically create your own DataTable objects - Cucumber will do # it internally and pass them to your Step Definitions. - # def initialize(rows) raw = ensure_array_of_array(rows) verify_rows_are_same_length(raw) @raw = raw.freeze end - attr_reader :raw - - def describe_to(visitor, *) - visitor.data_table(self, *) - end - def to_step_definition_arg - dup + def ==(other) + other.class == self.class && raw == other.raw end def data_table? true end + def describe_to(visitor, *) + visitor.data_table(self, *) + end + def doc_string? false end # Creates a copy of this table - # def dup self.class.new(raw.dup) end - # Returns a new, transposed table. Example: - # - # | a | 7 | 4 | - # | b | 9 | 2 | - # - # Gets converted into the following: - # - # | a | b | - # | 7 | 9 | - # | 4 | 2 | - # - def transpose - self.class.new(raw.transpose) + def inspect + %{#<#{self.class} #{raw.inspect}>} + end + + def lines_count + raw.count end def map(&block) @@ -80,26 +72,26 @@ def map(&block) self.class.new(new_raw) end - def lines_count - raw.count - end - - def ==(other) - other.class == self.class && raw == other.raw + def to_step_definition_arg + dup end - def inspect - %{#<#{self.class} #{raw.inspect})>} + # Returns a new, transposed table. Example: + # + # | a | 7 | 4 | + # | b | 9 | 2 | + # + # Gets converted into the following: + # + # | a | b | + # | 7 | 9 | + # | 4 | 2 | + def transpose + self.class.new(raw.transpose) end private - def verify_rows_are_same_length(raw) - raw.transpose - rescue IndexError - raise ArgumentError, 'Rows must all be the same length' - end - def ensure_array_of_array(array) array[0].is_a?(Hash) ? hashes_to_array(array) : array end @@ -108,6 +100,12 @@ def hashes_to_array(hashes) header = hashes[0].keys.sort [header] + hashes.map { |hash| header.map { |key| hash[key] } } end + + def verify_rows_are_same_length(raw) + raw.transpose + rescue IndexError + raise ArgumentError, 'Rows must all be the same length' + end end end end diff --git a/lib/cucumber/core/test/doc_string.rb b/lib/cucumber/core/test/doc_string.rb index b52410b2..ef3db070 100644 --- a/lib/cucumber/core/test/doc_string.rb +++ b/lib/cucumber/core/test/doc_string.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require 'delegate' + module Cucumber module Core module Test @@ -19,7 +20,6 @@ module Test # example above, that would return: "I like\nCucumber sandwich" # # Note how the indentation from the source is stripped away. - # class DocString < SimpleDelegator attr_reader :content_type, :content @@ -29,47 +29,47 @@ def initialize(content, content_type) super(@content) end - def describe_to(visitor, *) - visitor.doc_string(self, *) + def ==(other) + return false if other.respond_to?(:content_type) && content_type != other.content_type + return content == other.to_str if other.respond_to?(:to_str) + + false end def data_table? false end - def doc_string? - true + def describe_to(visitor, *) + visitor.doc_string(self, *) end - def map - raise ArgumentError, 'No block given' unless block_given? - - new_content = yield content - self.class.new(new_content, content_type) + def doc_string? + true end - def to_step_definition_arg - self + def inspect + [ + %(#<#{self.class}), + %( """#{content_type}), + %( #{@content}), + %( """>) + ].join("\n") end def lines_count lines.count + 2 end - def ==(other) - return false if other.respond_to?(:content_type) && content_type != other.content_type - return content == other.to_str if other.respond_to?(:to_str) + def map + raise ArgumentError, 'No block given' unless block_given? - false + new_content = yield content + self.class.new(new_content, content_type) end - def inspect - [ - %(#<#{self.class}), - %( """#{content_type}), - %( #{@content}), - %( """>) - ].join("\n") + def to_step_definition_arg + self end end end diff --git a/lib/cucumber/core/test/empty_multiline_argument.rb b/lib/cucumber/core/test/empty_multiline_argument.rb index bae98703..aa64f62c 100644 --- a/lib/cucumber/core/test/empty_multiline_argument.rb +++ b/lib/cucumber/core/test/empty_multiline_argument.rb @@ -4,28 +4,28 @@ module Cucumber module Core module Test class EmptyMultilineArgument - def describe_to(*) - self - end - def data_table? false end + def describe_to(*) + self + end + def doc_string? false end - def map - self + def inspect + "#<#{self.class}>" end def lines_count 0 end - def inspect - "#<#{self.class}>" + def map + self end end end diff --git a/lib/cucumber/core/test/filters.rb b/lib/cucumber/core/test/filters.rb index 45238dee..80b88177 100644 --- a/lib/cucumber/core/test/filters.rb +++ b/lib/cucumber/core/test/filters.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true -require 'cucumber/core/test/filters/locations_filter' -require 'cucumber/core/test/filters/name_filter' -require 'cucumber/core/test/filters/tag_filter' +require_relative 'filters/locations_filter' +require_relative 'filters/name_filter' +require_relative 'filters/tag_filter' diff --git a/lib/cucumber/core/test/hook_step.rb b/lib/cucumber/core/test/hook_step.rb index 3667c5ae..cebafd42 100644 --- a/lib/cucumber/core/test/hook_step.rb +++ b/lib/cucumber/core/test/hook_step.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'cucumber/core/test/step' +require_relative 'step' module Cucumber module Core diff --git a/lib/cucumber/core/test/location.rb b/lib/cucumber/core/test/location.rb index c4f0e06e..ca98bb07 100644 --- a/lib/cucumber/core/test/location.rb +++ b/lib/cucumber/core/test/location.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require 'forwardable' -require 'cucumber/core/platform' require 'set' module Cucumber diff --git a/lib/cucumber/core/test/step.rb b/lib/cucumber/core/test/step.rb index 76786954..4a5a14d9 100644 --- a/lib/cucumber/core/test/step.rb +++ b/lib/cucumber/core/test/step.rb @@ -1,8 +1,7 @@ # frozen_string_literal: true -require 'cucumber/core/test/result' -require 'cucumber/core/test/action' -require 'cucumber/core/test/empty_multiline_argument' +require_relative 'action' +require_relative 'empty_multiline_argument' module Cucumber module Core @@ -20,48 +19,48 @@ def initialize(id, text, location, multiline_arg = Test::EmptyMultilineArgument. @action = action end - def describe_to(visitor, *) - visitor.test_step(self, *) + def action_location + @action.location end - def hook? - false + def backtrace_line + "#{location}:in `#{text}'" end - def skip(*) - @action.skip(*) + def describe_to(visitor, *) + visitor.test_step(self, *) end def execute(*) @action.execute(*) end - def with_action(action_location = nil, &) - self.class.new(id, text, location, multiline_arg, Test::Action::Defined.new(action_location, &)) + def hook? + false end - def with_unskippable_action(action_location = nil, &) - self.class.new(id, text, location, multiline_arg, Test::Action::Unskippable.new(action_location, &)) + def inspect + "#<#{self.class}: #{location}>" end - def backtrace_line - "#{location}:in `#{text}'" + def matching_locations + [location.merge(multiline_arg)] end - def to_s - text + def skip(*) + @action.skip(*) end - def action_location - @action.location + def to_s + text end - def matching_locations - [location.merge(multiline_arg)] + def with_action(action_location = nil, &) + self.class.new(id, text, location, multiline_arg, Test::Action::Defined.new(action_location, &)) end - def inspect - "#<#{self.class}: #{location}>" + def with_unskippable_action(action_location = nil, &) + self.class.new(id, text, location, multiline_arg, Test::Action::Unskippable.new(action_location, &)) end end end diff --git a/lib/cucumber/core/test/tag.rb b/lib/cucumber/core/test/tag.rb index e6e536ee..d857c25d 100644 --- a/lib/cucumber/core/test/tag.rb +++ b/lib/cucumber/core/test/tag.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require_relative 'location' + module Cucumber module Core module Test diff --git a/lib/cucumber/core/test/timer.rb b/lib/cucumber/core/test/timer.rb index cc87c387..906de0ae 100644 --- a/lib/cucumber/core/test/timer.rb +++ b/lib/cucumber/core/test/timer.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'cucumber/core/test/result' +require_relative 'result' module Cucumber module Core diff --git a/spec/cucumber/core/test/case_spec.rb b/spec/cucumber/core/test/case_spec.rb index beb6a026..eb5febff 100644 --- a/spec/cucumber/core/test/case_spec.rb +++ b/spec/cucumber/core/test/case_spec.rb @@ -2,7 +2,6 @@ require 'cucumber/core' require 'cucumber/core/gherkin/writer' -require 'cucumber/core/platform' require 'cucumber/core/test/case' describe Cucumber::Core::Test::Case do diff --git a/spec/cucumber/core_spec.rb b/spec/cucumber/core_spec.rb index 4ff754ee..7cf2c6b6 100644 --- a/spec/cucumber/core_spec.rb +++ b/spec/cucumber/core_spec.rb @@ -6,7 +6,6 @@ require 'cucumber/core' require 'cucumber/core/filter' require 'cucumber/core/gherkin/writer' -require 'cucumber/core/platform' require 'cucumber/core/report/summary' require 'cucumber/core/test/around_hook' require 'cucumber/core/test/filters'