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
4 changes: 4 additions & 0 deletions lib/cucumber/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,10 @@ def id_generator
@id_generator ||= Cucumber::Messages::Helpers::IdGenerator::UUID.new
end

def test_run_started_id
@test_run_started_id ||= id_generator.new_id
end

private

def default_features_paths
Expand Down
63 changes: 6 additions & 57 deletions lib/cucumber/formatter/message_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def initialize(config)
@ast_lookup = AstLookup.new(config)
@repository = Cucumber::Repository.new

@test_run_started_id = config.id_generator.new_id
@test_run_started_id = config.test_run_started_id

# Fake Query objects
@test_case_by_step_id = {}
Expand All @@ -28,7 +28,6 @@ def initialize(config)
# Ensure all handlers for events occur after all ivars are instantiated

config.on_event :gherkin_source_parsed, &method(:on_gherkin_source_parsed)
config.on_event :gherkin_source_read, &method(:on_gherkin_source_read)

config.on_event :hook_test_step_created, &method(:on_hook_test_step_created)

Expand All @@ -42,14 +41,15 @@ def initialize(config)
config.on_event :test_run_started, &method(:on_test_run_started)
config.on_event :test_run_finished, &method(:on_test_run_finished)

config.on_event :test_run_hook_started, &method(:on_test_run_hook_started)
config.on_event :test_run_hook_finished, &method(:on_test_run_hook_finished)

config.on_event :test_step_created, &method(:on_test_step_created)
config.on_event :test_step_started, &method(:on_test_step_started)
config.on_event :test_step_finished, &method(:on_test_step_finished)

config.on_event :undefined_parameter_type, &method(:on_undefined_parameter_type)
config.on_event :envelope, &method(:on_envelope)
end

def on_envelope(event)
@current_test_run_hook_started_id = event.envelope.test_run_hook_started.id if event.envelope.test_run_hook_started
end

def attach(src, media_type, filename)
Expand Down Expand Up @@ -90,18 +90,6 @@ def on_gherkin_source_parsed(_event)
# TODO: Handle GherkinSourceParsed
end

def on_gherkin_source_read(event)
message = Cucumber::Messages::Envelope.new(
source: Cucumber::Messages::Source.new(
uri: event.path,
data: event.body,
media_type: 'text/x.cucumber.gherkin+plain'
)
)

@config.event_bus.envelope(message)
end

def on_hook_test_step_created(event)
@hook_id_by_test_step_id[event.test_step.id] = event.hook.id
end
Expand Down Expand Up @@ -203,45 +191,6 @@ def on_test_run_finished(event)
@config.event_bus.envelope(message)
end

def on_test_run_hook_started(event)
@current_test_run_hook_started_id = @config.id_generator.new_id

message = Cucumber::Messages::Envelope.new(
test_run_hook_started: Cucumber::Messages::TestRunHookStarted.new(
id: @current_test_run_hook_started_id,
hook_id: event.hook.id,
test_run_started_id: @test_run_started_id,
timestamp: time_to_timestamp(Time.now)
)
)

@config.event_bus.envelope(message)
end

def on_test_run_hook_finished(event)
result = event.test_result
result_message = result.to_message

if result.failed?
result_message = Cucumber::Messages::TestStepResult.new(
status: result_message.status,
duration: result_message.duration,
message: create_error_message(result.exception),
exception: create_exception_object(result, result.exception)
)
end

message = Cucumber::Messages::Envelope.new(
test_run_hook_finished: Cucumber::Messages::TestRunHookFinished.new(
test_run_hook_started_id: @current_test_run_hook_started_id,
timestamp: time_to_timestamp(Time.now),
result: result_message
)
)

@config.event_bus.envelope(message)
end

def on_test_step_created(event)
@pickle_id_step_by_test_step_id[event.test_step.id] = event.pickle_step.id
@step_definition_ids_by_test_step_id[event.test_step.id] = []
Expand Down
81 changes: 75 additions & 6 deletions lib/cucumber/glue/registry_and_more.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
require 'cucumber/cucumber_expressions/cucumber_expression'
require 'cucumber/cucumber_expressions/regular_expression'
require 'cucumber/cucumber_expressions/cucumber_expression_generator'
require 'cucumber/messages/helpers/time_conversion'

require 'cucumber/glue/dsl'
require 'cucumber/glue/snippet'
require 'cucumber/glue/hook'
Expand Down Expand Up @@ -48,6 +50,8 @@ def initialize(first_proc, second_proc)
class RegistryAndMore
attr_reader :current_world, :step_definitions

include Cucumber::Messages::Helpers::TimeConversion

all_keywords = ::Gherkin::DIALECTS.keys.map do |dialect_name|
dialect = ::Gherkin::Dialect.for(dialect_name)
dialect.given_keywords + dialect.when_keywords + dialect.then_keywords + dialect.and_keywords + dialect.but_keywords
Expand Down Expand Up @@ -98,14 +102,20 @@ def define_parameter_type(parameter_type)
def register_rb_step_definition(string_or_regexp, proc_or_sym, options)
step_definition = StepDefinition.new(@configuration.id_generator.new_id, self, string_or_regexp, proc_or_sym, options)
@step_definitions << step_definition
@configuration.notify :step_definition_registered, step_definition
@configuration.notify :envelope, step_definition.to_envelope
@configuration.notify(:step_definition_registered, step_definition)
@configuration.notify(:envelope, step_definition.to_envelope)
step_definition
rescue Cucumber::CucumberExpressions::UndefinedParameterTypeError => e
# TODO: add a way to extract the parameter type directly from the error.
type_name = e.message.match(/^Undefined parameter type ['|{](.*)['|}].?$/)[1]

@configuration.notify :undefined_parameter_type, type_name, string_or_regexp
@configuration.notify(:undefined_parameter_type, e.undefined_parameter_type_name, string_or_regexp)
# Move the below code into cucumber-expressions. Once done. Switch the line for
# @configuration.notify(:envelope, e.to_envelope(string_or_regexp))
to_envelope = Cucumber::Messages::Envelope.new(
undefined_parameter_type: Cucumber::Messages::UndefinedParameterType.new(
name: e.undefined_parameter_type_name,
expression: string_or_regexp
)
)
@configuration.notify(:envelope, to_envelope)
end

def build_rb_world_factory(world_modules, namespaced_world_modules, proc)
Expand Down Expand Up @@ -195,17 +205,76 @@ def create_expression(string_or_regexp)

def invoke_run_hook(hook, pseudo_method)
@configuration.notify(:test_run_hook_started, hook)

current_test_run_hook_started_id = @configuration.id_generator.new_id
started_envelope = test_run_hook_started_envelope(hook, current_test_run_hook_started_id)
@configuration.notify(:envelope, started_envelope)

timer = Core::Test::Timer.new.start
begin
hook.invoke(pseudo_method, [])
@configuration.notify(:test_run_hook_finished, hook, Core::Test::Result::Passed.new(timer.duration))
finished_envelope = test_run_hook_finished_envelope(Core::Test::Result::Passed.new(timer.duration), current_test_run_hook_started_id)
@configuration.notify(:envelope, finished_envelope)
true
rescue StandardError => e
@configuration.notify(:test_run_hook_finished, hook, Core::Test::Result::Failed.new(timer.duration, e))
finished_envelope = test_run_hook_finished_envelope(Core::Test::Result::Failed.new(timer.duration, e), current_test_run_hook_started_id)
@configuration.notify(:envelope, finished_envelope)
false
end
end

def test_run_hook_started_envelope(hook, id)
Cucumber::Messages::Envelope.new(
test_run_hook_started: Cucumber::Messages::TestRunHookStarted.new(
id: id,
hook_id: hook.id,
test_run_started_id: @configuration.test_run_started_id,
timestamp: time_to_timestamp(Time.now)
)
)
end

def test_run_hook_finished_envelope(test_result, test_run_hook_started_id)
result = test_result
result_message = result.to_message

if result.failed?
result_message = Cucumber::Messages::TestStepResult.new(
status: result_message.status,
duration: result_message.duration,
message: create_error_message(result.exception),
exception: create_exception_object(result, result.exception)
)
end

Cucumber::Messages::Envelope.new(
test_run_hook_finished: Cucumber::Messages::TestRunHookFinished.new(
test_run_hook_started_id: test_run_hook_started_id,
timestamp: time_to_timestamp(Time.now),
result: result_message
)
)
end

def create_error_message(message_element)
<<~ERROR_MESSAGE
#{message_element.message} (#{message_element.class})
#{message_element.backtrace}
ERROR_MESSAGE
end

def create_exception_object(result, message_element)
return unless result.failed?

Cucumber::Messages::Exception.new(
type: message_element.class,
message: message_element.message,
stack_trace: message_element.backtrace.join("\n")
)
end

def parameter_type_envelope(parameter_type)
# TODO: should this be moved to Cucumber::Expression::ParameterType#to_envelope ??
# Note: that would mean that cucumber-expression would depend on cucumber-messages
Expand Down
16 changes: 16 additions & 0 deletions lib/cucumber/runtime.rb
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,22 @@ def features
@features ||= feature_files.map do |path|
source = NormalisedEncodingFile.read(path)
@configuration.notify :gherkin_source_read, path, source

# TODO: When core is v17+ switch the below code out to the following
# Cucumber::Core::Gherkin::Document.new(path, source).tap do |document|
# @configuration.notify(:envelope, document.to_envelope)
# end
to_envelope =
Cucumber::Messages::Envelope.new(
source: Cucumber::Messages::Source.new(
uri: path,
data: source,
media_type: 'text/x.cucumber.gherkin+plain'
)
)

@configuration.notify(:envelope, to_envelope)

Cucumber::Core::Gherkin::Document.new(path, source)
end
end
Expand Down
Loading