Skip to content
Browse files

more refactor

  • Loading branch information...
1 parent f571293 commit 7818c4316e2a014c38a5e5e0481a9ed9927ea05b @kristianmandrup committed
View
2 README.md
@@ -94,7 +94,7 @@ end
A `FlowHandler` can use Executors to encapsulate execution logic, which again can execute Commands that encapsulate business logic related to the user Session or models (data).
-The FlowHandler can manage Redirect, Render and Notifications in a standardized, much more Object Oriented fashion, which adheres to the Single Responsibility pattern.
+The FlowHandler can manage a Redirecter, Renderer and Notifier in a standardized, much more Object Oriented fashion, which adheres to the Single Responsibility pattern.
Controll has built in notification management which work both for flash messages (or other types of notifications) and as return codes for use in flow-control logic.
View
1 lib/controll/flow_handler.rb
@@ -6,6 +6,7 @@ module FlowHandler
autoload :Control, 'controll/flow_handler/control'
autoload :Redirecter, 'controll/flow_handler/redirecter'
autoload :Renderer, 'controll/flow_handler/renderer'
+ autoload :Fallback, 'controll/flow_handler/fallback'
autoload :EventHelper, 'controll/flow_handler/event_helper'
end
end
View
13 lib/controll/flow_handler/base.rb
@@ -6,20 +6,7 @@ def initialize path
@path = path.to_s
end
- def perform controller
- raise NotImplementedError, 'You must implement the #perform method'
- end
-
class << self
- # any subclass of Base should have an inherited(base) class method added
- # which adds itself to the list of action_handler which the parent class
- # (i.e class that subclass is contained in!) supports
- def inherited(base)
- (class << self; self; end).send :define_method, :inherited do |base|
- base.parent.add_action_handler self.name.demodulize
- end
- end
-
def action event
raise NotImplementedError, 'You must implement the #action class method'
end
View
31 lib/controll/flow_handler/control.rb
@@ -7,28 +7,31 @@ class Control
include Macros
- attr_reader :controller, :action_handlers
+ attr_reader :controller, :action
- def initialize controller, action_handlers = []
+ def initialize controller
@controller = controller
- @action_handlers = action_handlers unless action_handlers.blank?
end
+ # sets action to first action_handler that matches event
+ # returns self
def execute
- executor.execute
- fallback if !executed?
- self
+ return executor.execute
+ rescue StandardError
+ fallback
end
def executor
@executor ||= Executor.new self, action_handlers: action_handlers
end
- def action_handlers
- @action_handlers ||= []
- end
+ delegate :executed?, to: :executor
class << self
+ def action_handlers
+ @action_handlers ||= []
+ end
+
def add_action_handler name
@action_handlers ||= []
@action_handlers << name.to_s.underscore.to_sym
@@ -37,14 +40,16 @@ def add_action_handler name
protected
+ attr_writer :action
+
delegate :command!, to: :controller
- def event
- raise NotImplementedError, 'You must define an #event method that at least returns an event (Symbol). You can use an Executor for this.'
+ def action_handlers
+ self.class.action_handlers
end
- def fallback_action
- do_redirect root_url
+ def event
+ raise NotImplementedError, 'You must define an #event method that at least returns an event (Symbol). You can use an Executor for this.'
end
end
end
View
30 lib/controll/flow_handler/control/executor.rb
@@ -1,29 +1,37 @@
module Controll::FlowHandler
class Control
class Executor < Controll::Executor::Base
- NoEventsDefinedError = Controll::FlowHandler::Render::NoEventsDefinedError
- NoRedirectionFoundError = Controll::FlowHandler::Redirect::NoRedirectionFoundError
+ NoEventsDefinedError = Controll::FlowHandler::NoEventsDefinedError
+ NoRedirectionFoundError = Controll::FlowHandler::NoRedirectionFoundError
- def execute
- errors = []
+ def initialize initiator, options = {}
+ super
+ # puts "options: #{options}"
+ end
+
+ def execute
action_handlers.each do |action_handler|
begin
action_handler_clazz = handler_class(action_handler)
next unless action_handler_clazz
- action = action_handler_clazz.action(event)
- execute_with action
- return if executed?
+ return action_handler_clazz.action(event)
rescue NoEventsDefinedError => e
errors << e
rescue NoRedirectionFoundError => e
errors << e
end
end
- raise ActionEventError, "#{errors.join ','}" unless errors.empty?
+ fallback
+ end
+
+ def errors
+ @errors ||= []
end
protected
+ delegate :event, to: :initiator
+
def action_handlers
@action_handlers ||= options[:action_handlers]
end
@@ -35,12 +43,6 @@ def handler_class action_handler
nil
end
- def execute_with action
- return if !action
- action.perform(controller)
- executed!
- end
-
def executed?
@executed
end
View
43 lib/controll/flow_handler/control/macros.rb
@@ -4,19 +4,24 @@ module Macros
extend ActiveSupport::Concern
module ClassMethods
- def handler response_type, options = {}, &block
- unless [:render, :repsonse].include? response_type.to_sym
- raise ArgumentError, "Must be either :render or :response"
+ def handler handler_type, options = {}, &block
+ unless valid_handlers.include? handler_type.to_sym
+ raise ArgumentError, "Must one of: #{valid_handlers} was: #{handler_type}"
end
+
+ parent = options[:parent] || "Controll::FlowHandler::#{response_type.to_s.camelize}".constantize
- clazz_name = "#{parent}::#{response_type.to_s.camelize}"
- parent = options[:parent] || "Controll::FlowHandler::#{response_type}".constantize
+ clazz_name = handler_type.to_s.camelize
+ context = self.kind_of?(Class) ? self : self.class
clazz = parent ? Class.new(parent) : Class.new
- Object.const_set clazz_name, clazz
- context = self.kind_of?(Class) ? self : self.class
+ context.const_set clazz_name, clazz
clazz = context.const_get(clazz_name)
+ container_class_name = clazz.name.sub(/\.*(::\w+)$/, '')
+ container_class = container_class_name.constantize
+ container_class.add_action_handler clazz.name.demodulize
+
clazz.instance_eval(&block) if block_given?
clazz
end
@@ -25,6 +30,10 @@ def renderer options = {}, &block
handler :renderer, options = {}, &block
end
+ def fallback options = {}, &block
+ handler :fallback, options = {}, &block
+ end
+
def redirecter options = {}, &block
handler :redirecter, options = {}, &block
end
@@ -36,17 +45,17 @@ def event &block
end
end
- def fallback &block
- raise ArgumentError, "Must be called with a block" unless block_given?
- define_method(:fallback, &block)
- end
+ # def set_action_handlers *names, &block
+ # raise ArgumentError, "Must be called with names of action handlers" if names.empty?
- def action_handlers *names, &block
- raise ArgumentError, "Must be called with names of action handlers" if names.empty?
- define_method :action_handlers do
- value = block_given? ? instance_eval(&block) : names.flatten
- instance_variable_get("@action_handlers") || instance_variable_set("@action_handlers", value)
- end
+ # define_method :action_handlers do
+ # value = block_given? ? instance_eval(&block) : names.flatten
+ # instance_variable_get("@action_handlers") || instance_variable_set("@action_handlers", value)
+ # end
+ # end
+
+ def valid_handlers
+ [:renderer, :redirecter, :fallback]
end
end
end
View
7 lib/controll/flow_handler/fallback.rb
@@ -0,0 +1,7 @@
+module Controll::FlowHandler
+ class Fallback
+ def perform controller
+ controller.fallback
+ end
+ end
+end
View
6 lib/controll/flow_handler/redirecter.rb
@@ -18,6 +18,12 @@ class << self
attr_writer :action_clazz
attr_reader :types
+ def inherited base
+ if base.parent.respond_to? :add_action_handler
+ base.add_action_handler self.name.demodulize
+ end
+ end
+
def action event
path = action_clazz.new(event, redirections, types).map
self.new path unless path.blank?
View
8 lib/controll/flow_handler/renderer.rb
@@ -16,8 +16,10 @@ def perform controller
end
class << self
- def inherited(base)
- base.parent.add_action_handler self.name.underscore
+ def inherited base
+ if base.parent.respond_to? :add_action_handler
+ base.add_action_handler self.name.demodulize
+ end
end
def action event, path = nil
@@ -54,7 +56,7 @@ def check!
end
end
- include Controll::FlowHandler::EventHelper
+ include Controll::Event::Helper
end
end
end
View
12 lib/controll/helper.rb
@@ -14,6 +14,18 @@ module Helper
delegate :command, :command!, :use_command, to: :commander
+ def execute
+ action.perform(self)
+ end
+
+ def action
+ @action ||= executor.execute
+ end
+
+ def fallback_action
+ do_redirect root_url
+ end
+
module ClassMethods
# TODO: refactor - all use exactly the same pattern - can be generated!
def commander name, options = {}
View
57 spec/controll/flow_handler/control_spec.rb
@@ -12,36 +12,39 @@ def default
end
end
-class EmptyEventFlowHandler < Controll::FlowHandler::Control
- def event
+module FlowHandlers
+ class EmptyEvent < Control
+ def event
+ end
end
-end
-class UpdateEventWithoutHandlerMapping < Controll::FlowHandler::Control
- def event
- :update
+ class UpdateEventWithoutHandler < Control
+ def event
+ :update
+ end
end
-end
-class UpdateEventFlowHandler < Controll::FlowHandler::Control
- def event
- :update
- end
- class Render < Controll::FlowHandler::Render
- set_events :update
- set_default_path 'default'
- end
-end
+ class UpdateEvent < Control
+ def event
+ :update
+ end
-class UpdateEventNoMatchFlowHandler < Controll::FlowHandler::Control
- def event
- :update
+ renderer do
+ events :update
+ default_path 'default'
+ end
end
- class Render < Controll::FlowHandler::Render
- set_events :create
- set_default_path '/default'
+ class UpdateEventNoMatch < Control
+ def event
+ :update
+ end
+
+ renderer do
+ events :create
+ default_path '/default'
+ end
end
end
@@ -70,7 +73,7 @@ class Render < Controll::FlowHandler::Render
context 'A Control FlowHandler with empty #event method' do
subject { flow_handler.new controller }
- let(:flow_handler) { EmptyEventFlowHandler }
+ let(:flow_handler) { FlowHandlers::EmptyEvent }
let(:controller) { MyController::Update.new }
describe '.initialize' do
@@ -94,7 +97,7 @@ class Render < Controll::FlowHandler::Render
context 'A Control FlowHandler where #event returns :update notice event' do
subject { flow_handler.new controller }
- let(:flow_handler) { UpdateEventWithoutHandlerMapping }
+ let(:flow_handler) { FlowHandlers::UpdateEventWithoutHandler }
let(:controller) { MyController::Update.new }
describe '.initialize' do
@@ -114,7 +117,7 @@ class Render < Controll::FlowHandler::Render
context 'A Control FlowHandler where #event returns :update notice event and has a Render class with matching mapping' do
subject { flow_handler.new controller }
- let(:flow_handler) { UpdateEventFlowHandler }
+ let(:flow_handler) { FlowHandlers::UpdateEvent }
let(:controller) { MyController::Update.new }
describe '.initialize' do
@@ -126,7 +129,7 @@ class Render < Controll::FlowHandler::Render
describe '.execute' do
# since event returns nil
specify do
- expect { subject.execute }.to_not raise_error(Controll::FlowHandler::Control::ActionEventError)
+ expect { subject.execute }.to_not raise_error(Controll::FlowHandler::ActionEventError)
end
specify do
@@ -139,7 +142,7 @@ class Render < Controll::FlowHandler::Render
context 'A Control FlowHandler where #event returns :update notice event and has a Render class with NO matching mapping' do
subject { flow_handler.new controller }
- let(:flow_handler) { UpdateEventNoMatchFlowHandler }
+ let(:flow_handler) { FlowHandlers::UpdateEventNoMatch }
let(:controller) { MyController::Update.new }
describe '.initialize' do
View
2 spec/controll/flow_handler/render_spec.rb
@@ -13,7 +13,7 @@ def self.events
end
class HelloRender < Controll::FlowHandler::Render
- set_events :hello, :damn
+ events :hello, :damn
set_default_path '/default'
end

0 comments on commit 7818c43

Please sign in to comment.
Something went wrong with that request. Please try again.