From 45b5f034c4f952e1495cee61ef4cd7eadcce4aa5 Mon Sep 17 00:00:00 2001 From: Matijs van Zuijlen Date: Fri, 31 May 2024 13:48:28 +0200 Subject: [PATCH 1/3] Only support symbols to specify events --- lib/aruba/event_bus/name_resolver.rb | 42 ---------------------- spec/aruba/event_bus/name_resolver_spec.rb | 40 --------------------- spec/aruba/event_bus_spec.rb | 26 ++++---------- 3 files changed, 6 insertions(+), 102 deletions(-) diff --git a/lib/aruba/event_bus/name_resolver.rb b/lib/aruba/event_bus/name_resolver.rb index 5c696605..53410d92 100644 --- a/lib/aruba/event_bus/name_resolver.rb +++ b/lib/aruba/event_bus/name_resolver.rb @@ -53,46 +53,6 @@ def constantize(camel_cased_word) end end - # @private - # Convert a class in to an event class - class ClassResolver - class << self - def match?(event_id) - event_id.is_a? Class - end - - # Which types are supported - def supports - [Class] - end - end - - def transform(_, event_id) - event_id - end - end - - # @private - # Convert a string in to an event class - class StringResolver - include ResolveHelpers - - class << self - def match?(event_id) - event_id.is_a? String - end - - # Which types are supported - def supports - [String] - end - end - - def transform(_, event_id) - constantize(event_id) - end - end - # @private # Convert a symbol in to an event class class SymbolResolver @@ -141,8 +101,6 @@ def initialize(default_namespace) @default_namespace = default_namespace @resolvers = [] - @resolvers << ClassResolver - @resolvers << StringResolver @resolvers << SymbolResolver @resolvers << FailingResolver end diff --git a/spec/aruba/event_bus/name_resolver_spec.rb b/spec/aruba/event_bus/name_resolver_spec.rb index 6fedf651..81c83ab0 100644 --- a/spec/aruba/event_bus/name_resolver_spec.rb +++ b/spec/aruba/event_bus/name_resolver_spec.rb @@ -13,52 +13,12 @@ end describe "#transform" do - context "when name is string" do - context "when simple" do - let(:original_name) { "Events::MyEvent" } - - it { expect(resolved_name).to eq Events::MyEvent } - end - - context "when prefixed" do - let(:original_name) { "::Events::MyEvent" } - - it { expect(resolved_name).to eq Events::MyEvent } - end - end - - context "when name is class" do - let(:original_name) { Events::MyEvent } - - it { expect(resolved_name).to eq Events::MyEvent } - end - context "when name is symbol" do let(:original_name) { :my_event } it { expect(resolved_name).to eq Events::MyEvent } end - context "when namespace ..." do - before do - stub_const("MyLib::Events::MyEvent", Class.new) - end - - context "when is string" do - let(:default_name_space) { "MyLib::Events" } - let(:original_name) { :my_event } - - it { expect(resolved_name).to eq MyLib::Events::MyEvent } - end - - context "when is module" do - let(:default_name_space) { MyLib::Events } - let(:original_name) { :my_event } - - it { expect(resolved_name).to eq MyLib::Events::MyEvent } - end - end - context "when invalid" do let(:original_name) { 1 } diff --git a/spec/aruba/event_bus_spec.rb b/spec/aruba/event_bus_spec.rb index 799c5bfc..48ed347d 100644 --- a/spec/aruba/event_bus_spec.rb +++ b/spec/aruba/event_bus_spec.rb @@ -23,7 +23,7 @@ describe "#notify" do before do - bus.register(event_klass) do |event| + bus.register(:test_event) do |event| @received_payload = event end end @@ -54,10 +54,10 @@ let(:received_events) { [] } before do - bus.register(Events::TestEvent) do |event| + bus.register(:test_event) do |event| received_events << event end - bus.register(Events::TestEvent) do |event| + bus.register(:test_event) do |event| received_events << event end end @@ -69,20 +69,6 @@ end end - context "when event id is a string" do - let(:received_payload) { [] } - - before do - bus.register("Events::TestEvent") do |event| - received_payload << event - end - - bus.notify event_instance - end - - it { expect(received_payload).to include event_instance } - end - context "when event id is a symbol" do let(:received_payload) { [] } @@ -101,7 +87,7 @@ let(:received_payload) { [] } before do - bus.register [event_klass, another_event_klass] do |event| + bus.register [:test_event, :another_test_event] do |event| received_payload << event end end @@ -115,7 +101,7 @@ context "when valid custom handler" do before do - bus.register(event_klass, MyHandler.new) + bus.register(:test_event, MyHandler.new) end it { expect { bus.notify event_instance }.not_to raise_error } @@ -123,7 +109,7 @@ context "when malformed custom handler" do it "raises an ArgumentError" do - expect { bus.register(event_klass, MyMalformedHandler.new) } + expect { bus.register(:test_event, MyMalformedHandler.new) } .to raise_error ArgumentError end end From 4cbb4dc89cab71dbdb7c0bfaa98f827622ca2ce6 Mon Sep 17 00:00:00 2001 From: Matijs van Zuijlen Date: Fri, 31 May 2024 17:16:46 +0200 Subject: [PATCH 2/3] Base Aruba event bus on the core Cucumber event bus --- lib/aruba/errors.rb | 3 -- lib/aruba/event_bus.rb | 51 ++++------------------------ lib/aruba/event_bus/name_resolver.rb | 3 +- lib/aruba/events.rb | 20 +++++++---- lib/aruba/runtime.rb | 2 +- spec/aruba/event_bus_spec.rb | 15 +++----- 6 files changed, 27 insertions(+), 67 deletions(-) diff --git a/lib/aruba/errors.rb b/lib/aruba/errors.rb index 04d05900..d9d9897c 100644 --- a/lib/aruba/errors.rb +++ b/lib/aruba/errors.rb @@ -33,7 +33,4 @@ class CommandAlreadyStartedError < Error; end # Raised if an event name cannot be resolved class EventNameResolveError < StandardError; end - - # Raised if given object is not an event - class NoEventError < StandardError; end end diff --git a/lib/aruba/event_bus.rb b/lib/aruba/event_bus.rb index b6ed34b5..934976ab 100644 --- a/lib/aruba/event_bus.rb +++ b/lib/aruba/event_bus.rb @@ -2,6 +2,7 @@ require "aruba/event_bus/name_resolver" require "aruba/errors" +require "cucumber/core/event_bus" module Aruba # Event bus @@ -9,55 +10,15 @@ module Aruba # Implements and in-process pub-sub events broadcaster allowing multiple observers # to subscribe to different events that fire as your tests are executed. # - class EventBus - # Create EventBus - # - # @param [#transform] resolver - # A resolver which transforms Symbol, String, Class into an event Class. - def initialize(resolver) - @resolver = resolver - @handlers = Hash.new { |h, k| h[k] = [] } - end - - # Register for an event - # - # @param [String, Symbol, Class, Array] event_ids - # If Array, register multiple events witht the same handler. If String, - # Symbol, Class register handler for given event. - # - # @param [#call] handler_object - # The handler object, needs to have method `#call`. Either - # `handler_object` or `block` can be defined. The handler object gets the - # event passed to `#call`. - # - # @yield - # Handler block which gets the event passed as parameter. - def register(event_ids, handler_object = nil, &handler_proc) - handler = handler_proc || handler_object - - if handler.nil? || !handler.respond_to?(:call) - raise ArgumentError, "Please pass either an object#call or a handler block" + class EventBus < Cucumber::Core::EventBus + def register(ids, handler_object = nil, &handler_proc) + Array(ids).each do |event_id| + on(event_id, handler_object, &handler_proc) end - - Array(event_ids).flatten.each do |id| - @handlers[ - @resolver.transform(id).to_s - ] << handler - end - - nil end - # Broadcast an event - # - # @param [Object] event - # An object of registered event class. This object is passed to the event - # handler. - # def notify(event) - raise NoEventError, "Please pass an event object, not a class" if event.is_a?(Class) - - @handlers[event.class.to_s].each { |handler| handler.call(event) } + broadcast(event) end end end diff --git a/lib/aruba/event_bus/name_resolver.rb b/lib/aruba/event_bus/name_resolver.rb index 53410d92..f1fc4f19 100644 --- a/lib/aruba/event_bus/name_resolver.rb +++ b/lib/aruba/event_bus/name_resolver.rb @@ -1,11 +1,12 @@ # frozen_string_literal: true require "aruba/errors" +require "cucumber/core/event_bus" # Event notification library module Aruba # EventBus - class EventBus + class EventBus < Cucumber::Core::EventBus # Resolve name to Event name class NameResolver # @private diff --git a/lib/aruba/events.rb b/lib/aruba/events.rb index 90364487..6ee270fe 100644 --- a/lib/aruba/events.rb +++ b/lib/aruba/events.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require "cucumber/core/event" + # Aruba module Aruba # Events @@ -10,13 +12,7 @@ module Events # inherited by normal events # # @private - class BasicEvent - attr_reader :entity - - def initialize(entity) - @entity = entity - end - end + class BasicEvent < Cucumber::Core::Event.new(:entity); end # Command was stopped class CommandStopped < BasicEvent; end @@ -38,5 +34,15 @@ class ChangedWorkingDirectory < BasicEvent; end # The configuration was changed class ChangedConfiguration < BasicEvent; end + + def self.registry + [CommandStarted, + CommandStopped, + AddedEnvironmentVariable, + ChangedEnvironmentVariable, + DeletedEnvironmentVariable, + ChangedWorkingDirectory, + ChangedConfiguration].to_h { |klass| [klass.event_id, klass] } + end end end diff --git a/lib/aruba/runtime.rb b/lib/aruba/runtime.rb index d975a93e..df0c396a 100644 --- a/lib/aruba/runtime.rb +++ b/lib/aruba/runtime.rb @@ -42,7 +42,7 @@ class Runtime attr_accessor :config, :environment, :logger, :command_monitor, :announcer, :event_bus def initialize(opts = {}) - @event_bus = EventBus.new(EventBus::NameResolver.new(Aruba::Events)) + @event_bus = EventBus.new(Aruba::Events.registry) @announcer = opts.fetch(:announcer, Aruba.platform.announcer.new) @config = opts.fetch(:config, ConfigWrapper.new(Aruba.config.make_copy, @event_bus)) diff --git a/spec/aruba/event_bus_spec.rb b/spec/aruba/event_bus_spec.rb index 48ed347d..3ae6b79b 100644 --- a/spec/aruba/event_bus_spec.rb +++ b/spec/aruba/event_bus_spec.rb @@ -5,7 +5,10 @@ describe Aruba::EventBus do let(:bus) { described_class.new(name_resolver) } - let(:name_resolver) { Aruba::EventBus::NameResolver.new("Events") } + let(:name_resolver) do + { test_event: Events::TestEvent, + another_test_event: Events::AnotherTestEvent } + end let(:event_klass) { Events::TestEvent } let(:event_instance) { event_klass.new } @@ -16,7 +19,6 @@ before do stub_const("Events::TestEvent", Class.new) stub_const("Events::AnotherTestEvent", Class.new) - stub_const("Events::MalformedTestEvent", Module.new) stub_const("MyHandler", Class.new { def call(*); end }) stub_const("MyMalformedHandler", Class.new) end @@ -44,7 +46,7 @@ context "when event is not an event instance" do it "raises an error" do - expect { bus.notify event_klass }.to raise_error Aruba::NoEventError + expect { bus.notify event_klass }.to raise_error ArgumentError end end end @@ -107,13 +109,6 @@ it { expect { bus.notify event_instance }.not_to raise_error } end - context "when malformed custom handler" do - it "raises an ArgumentError" do - expect { bus.register(:test_event, MyMalformedHandler.new) } - .to raise_error ArgumentError - end - end - context "when no handler is given" do it "raises an ArgumentError" do expect { bus.register(event_klass) }.to raise_error ArgumentError From 1179a73c0182016a96321a5a2a74f68a6aa8329e Mon Sep 17 00:00:00 2001 From: Matijs van Zuijlen Date: Fri, 31 May 2024 17:48:47 +0200 Subject: [PATCH 3/3] Remove obsolete Aruba::EventBus::NameResolver --- Manifest.txt | 1 - lib/aruba/errors.rb | 3 - lib/aruba/event_bus.rb | 2 - lib/aruba/event_bus/name_resolver.rb | 119 --------------------- spec/aruba/event_bus/name_resolver_spec.rb | 31 ------ spec/aruba/event_bus_spec.rb | 4 +- 6 files changed, 2 insertions(+), 158 deletions(-) delete mode 100644 lib/aruba/event_bus/name_resolver.rb delete mode 100644 spec/aruba/event_bus/name_resolver_spec.rb diff --git a/Manifest.txt b/Manifest.txt index e17c8df5..c1fd0745 100644 --- a/Manifest.txt +++ b/Manifest.txt @@ -32,7 +32,6 @@ lib/aruba/cucumber/parameter_types.rb lib/aruba/cucumber/testing_frameworks.rb lib/aruba/errors.rb lib/aruba/event_bus.rb -lib/aruba/event_bus/name_resolver.rb lib/aruba/events.rb lib/aruba/file_size.rb lib/aruba/generators/script_file.rb diff --git a/lib/aruba/errors.rb b/lib/aruba/errors.rb index d9d9897c..5c79b01c 100644 --- a/lib/aruba/errors.rb +++ b/lib/aruba/errors.rb @@ -30,7 +30,4 @@ class CommandNotFoundError < ArgumentError; end # Raised if command was already started, otherwise aruba forgets about the # previous pid and you've got hidden commands run class CommandAlreadyStartedError < Error; end - - # Raised if an event name cannot be resolved - class EventNameResolveError < StandardError; end end diff --git a/lib/aruba/event_bus.rb b/lib/aruba/event_bus.rb index 934976ab..069aa657 100644 --- a/lib/aruba/event_bus.rb +++ b/lib/aruba/event_bus.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "aruba/event_bus/name_resolver" -require "aruba/errors" require "cucumber/core/event_bus" module Aruba diff --git a/lib/aruba/event_bus/name_resolver.rb b/lib/aruba/event_bus/name_resolver.rb deleted file mode 100644 index f1fc4f19..00000000 --- a/lib/aruba/event_bus/name_resolver.rb +++ /dev/null @@ -1,119 +0,0 @@ -# frozen_string_literal: true - -require "aruba/errors" -require "cucumber/core/event_bus" - -# Event notification library -module Aruba - # EventBus - class EventBus < Cucumber::Core::EventBus - # Resolve name to Event name - class NameResolver - # @private - # Helpers for Resolvers - module ResolveHelpers - def camel_case(underscored_name) - underscored_name.to_s.split("_").map { |word| word.upcase[0] + word[1..] }.join - end - - # Thanks ActiveSupport - # (Only needed to support Ruby 1.9.3 and JRuby) - def constantize(camel_cased_word) - names = camel_cased_word.split("::") - - # Trigger a built-in NameError exception including the ill-formed - # constant in the message. - Object.const_get(camel_cased_word) if names.empty? - - # Remove the first blank element in case of '::ClassName' notation. - names.shift if names.size > 1 && names.first.empty? - - names.inject(Object) do |constant, name| - if constant == Object - constant.const_get(name) - else - candidate = constant.const_get(name) - - next candidate if constant.const_defined?(name, false) - - next candidate unless Object.const_defined?(name) - - # Go down the ancestors to check if it is owned directly. The check - # stops when we reach Object or the end of ancestors tree. - constant = constant.ancestors.inject do |const, ancestor| - break const if ancestor == Object - break ancestor if ancestor.const_defined?(name, false) - - const - end - - # owner is in Object, so raise - constant.const_get(name, false) - end - end - end - end - - # @private - # Convert a symbol in to an event class - class SymbolResolver - include ResolveHelpers - - class << self - def match?(event_id) - event_id.is_a? Symbol - end - - # Which types are supported - def supports - [Symbol] - end - end - - def transform(default_namespace, event_id) - constantize("#{default_namespace}::#{camel_case(event_id)}") - end - end - - # @private - # Default failing resolver - # - # This comes into play if the user passes an invalid event type - class FailingResolver - class << self - def match?(event_id) - raise ArgumentError, - %(Input type "#{event_id.class}" of event_id "#{event_id}" is invalid) - end - - def supports - [] - end - end - end - - protected - - attr_reader :resolvers, :default_namespace - - public - - def initialize(default_namespace) - @default_namespace = default_namespace - - @resolvers = [] - @resolvers << SymbolResolver - @resolvers << FailingResolver - end - - def transform(event_id) - resolvers.find { |r| r.match? event_id }.new.transform(default_namespace, event_id) - rescue StandardError => e - types = @resolvers.map(&:supports).flatten.join(", ") - message = "Transforming \"#{event_id}\" into an event class failed." \ - " Supported types are: #{types}. #{e.message}." - raise EventNameResolveError, message, cause: e - end - end - end -end diff --git a/spec/aruba/event_bus/name_resolver_spec.rb b/spec/aruba/event_bus/name_resolver_spec.rb deleted file mode 100644 index 81c83ab0..00000000 --- a/spec/aruba/event_bus/name_resolver_spec.rb +++ /dev/null @@ -1,31 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe Aruba::EventBus::NameResolver do - let(:resolver) { described_class.new(default_name_space) } - - let(:default_name_space) { "Events" } - let(:resolved_name) { resolver.transform(original_name) } - - before do - stub_const("Events::MyEvent", Class.new) - end - - describe "#transform" do - context "when name is symbol" do - let(:original_name) { :my_event } - - it { expect(resolved_name).to eq Events::MyEvent } - end - - context "when invalid" do - let(:original_name) { 1 } - - it { - expect { resolved_name } - .to raise_error Aruba::EventNameResolveError, /Transforming "1"/ - } - end - end -end diff --git a/spec/aruba/event_bus_spec.rb b/spec/aruba/event_bus_spec.rb index 3ae6b79b..f5372fb3 100644 --- a/spec/aruba/event_bus_spec.rb +++ b/spec/aruba/event_bus_spec.rb @@ -3,9 +3,9 @@ require "spec_helper" describe Aruba::EventBus do - let(:bus) { described_class.new(name_resolver) } + let(:bus) { described_class.new(registry) } - let(:name_resolver) do + let(:registry) do { test_event: Events::TestEvent, another_test_event: Events::AnotherTestEvent } end