Skip to content
Merged
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Please visit [cucumber/CONTRIBUTING.md](https://github.com/cucumber/cucumber/blo

### Changed
- Increased upper bounds of `cucumber-messages` to v34 and `cucumber-gherkin` to v42
- **BREAKING CHANGE:** Event base class has been internally refactored. See upgrading notes for [19.0.0.md](upgrading_notes/19.0.0.md#upgrading-to-cucumber-core-1900), for full changes

## [18.0.0] - 2026-07-13
### Changed
Expand Down
67 changes: 8 additions & 59 deletions lib/cucumber/core/event.rb
Original file line number Diff line number Diff line change
@@ -1,61 +1,10 @@
# frozen_string_literal: true

module Cucumber
module Core
class Event
# Macro to generate new subclasses of {Event} with attribute readers.
def self.new(*events)
# Use normal constructor for subclasses of Event
return super if ancestors.index(Event).positive?

Class.new(Event) do
# NB: We need to use metaprogramming here instead of direct variable obtainment
# because JRuby does not guarantee the order in which variables are defined is equivalent
# to the order in which they are obtainable
#
# See https://github.com/jruby/jruby/issues/7988 for more info
attr_reader(*events)

define_method(:initialize) do |*attributes|
events.zip(attributes) do |name, value|
instance_variable_set(:"@#{name}", value)
end
end
end
end

def to_h
instance_variables.to_h do |variable_name|
[variable_name[1..].to_sym, instance_variable_get(variable_name)]
end
end

def attributes
instance_variables.map { |var| instance_variable_get(var) }
end

def event_id
self.class.event_id
end

class << self
# @return [Symbol] the underscored name of the class to be used as the key in an event registry
def event_id
underscore(name.split('::').last).to_sym
end

private

def underscore(string)
string
.to_s
.gsub('::', '/')
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
.tr('-', '_')
.downcase
end
end
end
end
end
require_relative 'event/envelope'
require_relative 'event/gherkin_source_parsed'
require_relative 'event/test_case_created'
require_relative 'event/test_case_started'
require_relative 'event/test_case_finished'
require_relative 'event/test_step_created'
require_relative 'event/test_step_started'
require_relative 'event/test_step_finished'
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

module Cucumber
module Core
module Events
module Event
# An archetype of what each Cucumber Event defined in cucumber-ruby must adhere to
class Base
# The "key" name of the class to be used as the key in the event registry (Underscored name symbolized)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

module Cucumber
module Core
module Events
module Event
class Envelope < Base
attr_reader :envelope

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

module Cucumber
module Core
module Events
module Event
# Signals that a gherkin source has been parsed
class GherkinSourceParsed < Base
# @return [GherkinDocument] the GherkinDocument Ast Node that was parsed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

module Cucumber
module Core
module Events
module Event
# Signals that a Test::Case was created from a Pickle
class TestCaseCreated < Base
attr_reader :test_case, :pickle
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# frozen_string_literal: true

require_relative '../event'
require_relative 'base'

module Cucumber
module Core
module Events
module Event
# Signals that a {Test::Case} has finished executing
class TestCaseFinished < Base
# @return [Test::Case] that was executed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

module Cucumber
module Core
module Events
module Event
# Signals that a {Test::Case} is about to be executed
class TestCaseStarted < Base
# @return [Cucumber::Core::Test::Case] the test case to be executed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

module Cucumber
module Core
module Events
module Event
# Signals that a Test::Step was created from a PickleStep
class TestStepCreated < Base
attr_reader :test_step, :pickle_step
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

module Cucumber
module Core
module Events
module Event
# Signals that a {Test::Step} has finished executing
class TestStepFinished < Base
# @return [Cucumber::Core::Test::Step] the test step that was executed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

module Cucumber
module Core
module Events
module Event
# Signals that a {Test::Step} is about to be executed
class TestStepStarted < Base
# @return [Cucumber::Core::Test::Step] the test step to be executed
Expand Down
26 changes: 24 additions & 2 deletions lib/cucumber/core/event_bus.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

require_relative 'events'
require_relative 'event'

module Cucumber
module Core
Expand All @@ -11,8 +11,30 @@ module Core
class EventBus
attr_reader :event_types

# The registry contains all the event registered in the core, that will be used by the {EventBus} by default.
def self.registry
build_registry(
Event::Envelope,
Event::GherkinSourceParsed,
Event::TestCaseCreated,
Event::TestCaseStarted,
Event::TestCaseFinished,
Event::TestStepCreated,
Event::TestStepStarted,
Event::TestStepFinished
)
end

# Build an event registry to be passed to the {EventBus} constructor from a list of types.
# Each type must respond to `event_id` so that it can be added to the registry hash
#
# @return [Hash{Symbol => Class}]
def self.build_registry(*types)
types.to_h { |type| [type.event_id, type] }
end

# @param registry [Hash{Symbol => Class}] a hash of event types to use on the bus
def initialize(registry = Events.registry)
def initialize(registry = self.class.registry)
@event_types = registry.freeze
@handlers = {}
@event_queue = []
Expand Down
38 changes: 0 additions & 38 deletions lib/cucumber/core/events.rb

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

describe Cucumber::Core::Events::Base do
describe Cucumber::Core::Event::Base do
subject(:event) { my_event_type.new(1, 2) }

let(:my_event_type) do
Expand Down
Loading