Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 12 additions & 13 deletions .rubocop_todo.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
# This configuration was generated by
# `rubocop --auto-gen-config`
# on 2026-04-07 18:30:30 UTC using RuboCop version 1.85.1.
# on 2026-05-15 19:52:05 UTC using RuboCop version 1.85.1.
# 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] -> Jan '25 (Updated deps and v10 prep) - 369 files inspected, 704 offenses detected, 112 offenses autocorrectable
# TODO - [LH] -> Mar '25 (v10 prep) - 370 files inspected, 721 offenses detected, 116 offenses autocorrectable
# TODO - [LH] -> Dec '25 - 375 files inspected, 713 offenses detected, 109 offenses autocorrectable
# TODO - [LH] -> Dec '25 (query prep) - 378 files inspected, 729 offenses detected, 109 offenses autocorrectable
# TODO - [LH] -> Mar '26 (v11 prep) - 389 files inspected, 747 offenses detected, 108 offenses autocorrectable
# TODO - [LH] -> Apr '26 (v11 prep) - 393 files inspected, 740 offenses detected, 106 offenses autocorrectable
# TODO - [LH] -> May '26 (v11.0.0) - 391 files inspected, 740 offenses detected, 105 offenses autocorrectable

# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
Expand All @@ -22,10 +20,17 @@ Layout/EmptyLineBetweenDefs:

# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: AllowInHeredoc.
Layout/TrailingWhitespace:
# Configuration parameters: EnforcedStyle.
# SupportedStyles: empty_lines, empty_lines_except_namespace, empty_lines_special, no_empty_lines
Layout/EmptyLinesAroundModuleBody:
Exclude:
- 'lib/cucumber/glue/multiple_world.rb'

# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
Layout/HeredocIndentation:
Exclude:
- 'spec/cucumber/step_match_search_spec.rb'
- 'lib/cucumber/glue/multiple_world.rb'

# Offense count: 2
Lint/IneffectiveAccessModifier:
Expand Down Expand Up @@ -214,12 +219,6 @@ RSpec/InstanceVariable:
- 'spec/cucumber/step_match_spec.rb'
- 'spec/support/shared_context/http_server.rb'

# Offense count: 2
# This cop supports safe autocorrection (--autocorrect).
RSpec/LeadingSubject:
Exclude:
- 'spec/cucumber/rake/forked_cucumber_runner_spec.rb'

# Offense count: 2
# This cop supports safe autocorrection (--autocorrect).
RSpec/MatchArray:
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ Please visit [cucumber/CONTRIBUTING.md](https://github.com/cucumber/cucumber/blo
### Changed
- Heavy refactor to the internals for message building (Used in formatters - should be no noticeable change)
([#1853](https://github.com/cucumber/cucumber-ruby/pull/1853) [luke-hill](https://github.com/luke-hill))
- Refactor to internal error logic (No user facing changes)

### Removed
- Removed a bunch of RSpec support logic that was no longer used in the codebase (This includes some legacy pending
logic and some old rspec helper files)
- Removed handling of a Ruby 2.1 system error (Minimum Ruby is now 3.2)

## [11.0.0] - 2026-04-14
### Added
Expand Down
66 changes: 43 additions & 23 deletions lib/cucumber/errors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,49 @@
require 'cucumber/core/test/result'

module Cucumber
# Raised when a step matches 2 or more StepDefinitions
class Ambiguous < StandardError
def initialize(step_name, step_definitions, used_guess)
# TODO: [LH] - Just use a heredoc here to fix this up
message = String.new
message << "Ambiguous match of \"#{step_name}\":\n\n"
message << step_definitions.map(&:backtrace_line).join("\n")
message << "\n\n"
message << "You can run again with --guess to make Cucumber be more smart about it\n" unless used_guess
super(message)
end
end

class FeatureFolderNotFoundException < RuntimeError
def initialize(path)
@path = path
super
end

def message
"No such file or directory - #{@path}"
end
end

class FileNotFoundException < RuntimeError
attr_reader :path

def initialize(original_exception, path)
@path = path
super(original_exception)
end
end

# Raised when a StepDefinition's block invokes World#pending
class Pending < Core::Test::Result::Pending
end

class TagExcess < StandardError
def initialize(messages)
super(messages.join("\n"))
end
end

# Raised when there is no matching StepDefinition for a step.
class Undefined < Core::Test::Result::Undefined
def self.from(result, step_name)
Expand All @@ -27,27 +70,4 @@ def initialize(step_name)
super %(Undefined dynamic step: "#{step_name}")
end
end

# Raised when a StepDefinition's block invokes World#pending
class Pending < Core::Test::Result::Pending
end

# Raised when a step matches 2 or more StepDefinitions
class Ambiguous < StandardError
def initialize(step_name, step_definitions, used_guess)
# TODO: [LH] - Just use a heredoc here to fix this up
message = String.new
message << "Ambiguous match of \"#{step_name}\":\n\n"
message << step_definitions.map(&:backtrace_line).join("\n")
message << "\n\n"
message << "You can run again with --guess to make Cucumber be more smart about it\n" unless used_guess
super(message)
end
end

class TagExcess < StandardError
def initialize(messages)
super(messages.join("\n"))
end
end
end
1 change: 0 additions & 1 deletion lib/cucumber/glue/hook.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

module Cucumber
module Glue
# TODO: Kill pointless wrapper for Before, After and AfterStep hooks with fire
class Hook
attr_reader :id, :tag_expressions, :location, :name

Expand Down
26 changes: 26 additions & 0 deletions lib/cucumber/glue/multiple_world.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# frozen_string_literal: true

module Cucumber
module Glue
# Raised if there are 2 or more World blocks.
class MultipleWorld < StandardError
def initialize(first_proc, second_proc)
super(error_message(first_proc, second_proc))
end

def error_message(first_proc, second_proc)
<<~MESSAGE
You can only pass a proc to #World once, but it's happening
in 2 places:
#{Glue.backtrace_line(first_proc, 'World')}
#{Glue.backtrace_line(second_proc, 'World')}
Use Ruby modules instead to extend your worlds. See the Cucumber::Glue::Dsl#World RDoc
or http://wiki.github.com/cucumber/cucumber/a-whole-new-world.


MESSAGE
end
end

end
end
12 changes: 12 additions & 0 deletions lib/cucumber/glue/nil_world.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

module Cucumber
module Glue
# Raised if a World block returns Nil.
class NilWorld < StandardError
def initialize
super('World procs should never return nil')
end
end
end
end
25 changes: 3 additions & 22 deletions lib/cucumber/glue/registry_and_more.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,35 +15,16 @@
require 'cucumber/step_match'
require 'cucumber/events/step_definition_registered'

require_relative 'multiple_world'
require_relative 'nil_world'

module Cucumber
module Glue
def self.backtrace_line(proc, name)
location = Cucumber::Core::Test::Location.from_source_location(*proc.source_location)
"#{location}:in `#{name}'"
end

# Raised if a World block returns Nil.
class NilWorld < StandardError
def initialize
super('World procs should never return nil')
end
end

# Raised if there are 2 or more World blocks.
class MultipleWorld < StandardError
def initialize(first_proc, second_proc)
# TODO: [LH] - Just use a heredoc here to fix this up
message = String.new
message << "You can only pass a proc to #World once, but it's happening\n"
message << "in 2 places:\n\n"
message << Glue.backtrace_line(first_proc, 'World') << "\n"
message << Glue.backtrace_line(second_proc, 'World') << "\n\n"
message << "Use Ruby modules instead to extend your worlds. See the Cucumber::Glue::Dsl#World RDoc\n"
message << "or http://wiki.github.com/cucumber/cucumber/a-whole-new-world.\n\n"
super(message)
end
end

# TODO: This class has too many responsibilities, split off
class RegistryAndMore
attr_reader :current_world, :step_definitions
Expand Down
8 changes: 1 addition & 7 deletions lib/cucumber/rspec/doubles.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,9 @@
World(RSpec::Mocks::ExampleMethods)

Before do
if RSpec::Mocks::Version::STRING >= '2.9.9'
RSpec::Mocks.setup
else
RSpec::Mocks.setup(self)
end
RSpec::Mocks.setup(self)
end

After do
RSpec::Mocks.verify
ensure
RSpec::Mocks.teardown
end
59 changes: 17 additions & 42 deletions lib/cucumber/runtime.rb
Original file line number Diff line number Diff line change
@@ -1,52 +1,27 @@
# frozen_string_literal: true

require 'fileutils'
require 'cucumber/configuration'
require 'cucumber/load_path'
require 'cucumber/formatter/duration'
require 'cucumber/file_specs'
require 'cucumber/filters'
require 'cucumber/formatter/fanout'
require 'cucumber/gherkin/i18n'
require 'cucumber/glue/registry_wrapper'
require 'cucumber/step_match_search'
require 'cucumber/messages'
require 'cucumber/runtime/meta_message_builder'
require 'sys/uname'

module Cucumber
module FixRuby21Bug9285
def message
String(super).gsub('@ rb_sysopen ', '')
end
end

class FileException < RuntimeError
attr_reader :path

def initialize(original_exception, path)
@path = path
super(original_exception)
end
end

class FileNotFoundException < FileException
end

class FeatureFolderNotFoundException < RuntimeError
def initialize(path)
@path = path
super
end
require 'cucumber/core'
require 'cucumber/messages'

def message
"No such file or directory - #{@path}"
end
end
require_relative 'configuration'
require_relative 'errors'
require_relative 'file_specs'
require_relative 'filters'
require_relative 'load_path'
require_relative 'step_match_search'

require_relative 'formatter/duration'
require_relative 'formatter/fanout'
require_relative 'gherkin/i18n'
require_relative 'glue/registry_wrapper'
require_relative 'runtime/meta_message_builder'
require_relative 'runtime/support_code'
require_relative 'runtime/user_interface'

require 'cucumber/core'
require 'cucumber/runtime/user_interface'
require 'cucumber/runtime/support_code'
module Cucumber
class Runtime
attr_reader :results, :support_code, :configuration

Expand Down
1 change: 0 additions & 1 deletion spec/cucumber/glue/registry_and_more_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# frozen_string_literal: true

require 'spec_helper'
require 'cucumber/glue/registry_and_more'
require 'cucumber/cucumber_expressions/parameter_type'
require 'support/fake_objects'
Expand Down
Loading