Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

even more refactoring

  • Loading branch information...
commit cc81c3a2487fd840019104b266f84033f7a3eba8 1 parent 145e06b
@kristianmandrup authored
View
56 lib/controll/enabler.rb
@@ -1,67 +1,51 @@
module Controll
module Enabler
autoload :Macros, 'controll/enabler/macros'
+ autoload :Notify, 'controll/enabler/notify'
autoload :PathResolver, 'controll/enabler/path_resolver'
+ autoload :PathHandler, 'controll/enabler/path_handler'
+ autoload :Maps, 'controll/enabler/maps'
extend ActiveSupport::Concern
class NotIncluded < StandardError; end
- included do
- include Controll::Helper::Notify
- include Controll::Helper::Params
+ included do
+ include Controll::Helper::Params
+ include Controll::Helper::Session
+
+ include Notify
include Macros
+ include Maps
delegate :command, :command!, :use_command, to: :commander
end
- module ClassMethods
- def redirect_map map = {}
- @redirect_map ||= map
- end
-
- def render_map map = {}
- @render_map ||= map
- end
-
- def assistant_methods *names
- options = names.extract_options!
- assistant = options[:to] || :assistant
- delegate names, to: assistant
- end
- end
-
# override this for custom Controller specific fallback action
- def do_fallback event
- do_redirect root_url
+ def do_fallback action
+ do_redirect fallback_path
end
def do_redirect *args
- options = args.extract_options!
- path = path_resolver.extract_path(:redirect_map, *args)
- process_notifications
- redirect_to path, *args
+ redirecter.execute *args
end
def do_render *args
- options = args.extract_options!
- path = path_resolver.extract_path :render_paths, *args
- process_notifications
- render path, *args
- end
+ renderer.execute *args
+ end
protected
- def redirect_map
- self.class.redirect_map
+ def fallback_path
+ root_url
end
- def render_paths
- self.class.render_map
+ def renderer
+ @renderer||= PathHandler.new self, :render
end
- def path_resolver
- @path_resolver ||= PathResolver.new self
+ def redirecter
+ @redirecter ||= PathHandler.new self, :redirect
end
end
end
View
22 lib/controll/enabler/macros.rb
@@ -46,6 +46,15 @@ def notifier name, options = {}
end
end
+ def flow_handler name, options = {}
+ define_method :flow_handler do
+ unless instance_variable_get("@flow_handler")
+ clazz = "FlowHandlers::#{name.to_s.camelize}".constantize
+ instance_variable_set "@flow_handler", clazz.new(self, options)
+ end
+ end
+ end
+
def assistant name, options = {}
define_method :assistant do
unless instance_variable_get("@assistant")
@@ -55,14 +64,11 @@ def assistant name, options = {}
end
end
- def flow_handler name, options = {}
- define_method :flow_handler do
- unless instance_variable_get("@flow_handler")
- clazz = "FlowHandlers::#{name.to_s.camelize}".constantize
- instance_variable_set "@flow_handler", clazz.new(self, options)
- end
- end
- end
+ def assistant_methods *names
+ options = names.extract_options!
+ assistant = options[:to] || :assistant
+ delegate names, to: assistant
+ end
end
end
end
View
15 lib/controll/enabler/maps.rb
@@ -0,0 +1,15 @@
+module Controll::Enabler
+ module Maps
+ extend ActiveSupport::Concern
+
+ module ClassMethods
+ def redirect_map map = {}
+ @redirect_map ||= map
+ end
+
+ def render_map map = {}
+ @render_map ||= map
+ end
+ end
+ end
+end
View
6 lib/controll/helper/notify.rb → lib/controll/enabler/notify.rb
@@ -1,5 +1,5 @@
module Controll
- module Helper
+ module Enabler
module Notify
extend ActiveSupport::Concern
@@ -16,8 +16,8 @@ module Notify
include Controll::Event::Helper
- def notify name, *args
- events << create_event(name, *args)
+ def notify event, *args
+ events << normalize(event, *args)
self # enable method chaining on controller
end
View
49 lib/controll/enabler/path_handler.rb
@@ -0,0 +1,49 @@
+module Controll::Enabler
+ class PathHandler
+ attr_reader :controller, :type, :options, :path
+
+ def initialize controller, type
+ @controller, @type = [controller, type]
+ end
+
+ def map
+ @map ||= controller.class.send("#{type}_map")
+ end
+
+ alias_method :control_action, :type
+
+ def self.renderer controller, map
+ self.new controller, map, :render
+ end
+
+ def self.redirecter controller, map
+ self.new controller, map, :redirect
+ end
+
+ def execute *args
+ extract! *args
+ process_notifications
+ path ? handle_path : fallback
+ end
+
+ protected
+
+ def handle_path
+ controller.send control_action, path, options
+ end
+
+ def fallback
+ controller.do_fallback action
+ end
+
+ def extract! *args
+ @options = args.extract_options!
+ action = args.first
+ @path = path_resolver(map).resolve action
+ end
+
+ def path_resolver map
+ @path_resolver ||= PathResolver.new controller, map
+ end
+ end
+end
View
86 lib/controll/enabler/path_resolver.rb
@@ -1,46 +1,44 @@
-module Controll
- module Enabler
- class PathResolver
- class PathResolverError < StandardError; end
-
- attr_reader :caller
-
- def initialize caller
- @caller = caller
- end
-
- def extract_path map_type, path = nil
- return resolve_path(map_type) if path.nil?
-
- case path
- when Symbol
- raise "Caller must have a notice method" unless caller.respond_to? :notice
- caller.notice path
- end
- resolve_path map_type
- end
-
- def resolve_path map_type
- raise "Caller must have a #main_event method" unless caller.respond_to? :main_event
- caller.send(map_type).each do |path, events|
- return path.to_s if matches? events
- end
- raise PathResolverError, "Path could not be resolved for: #{event.name}"
- end
-
- protected
-
- def matches? events
- event_matcher.match?(events)
- end
-
- def event_matcher
- @event_matcher ||= Controll::Event::Matcher.new event
- end
-
- def event
- @event ||= caller.main_event
- end
+module Controll::Enabler
+ class PathResolver
+ attr_reader :caller, :event_map
+
+ def initialize caller, event_map
+ @caller = caller
+ @event_map = event_map
+ end
+
+ def resolve action = nil
+ @path ||= handle action
+ end
+
+ protected
+
+ alias_method :controller, :caller
+
+ delegate :notify, :main_event, to: :caller
+
+ def handle action
+ case action
+ when Controll::FlowHandler::Fallback
+ nil
+ when Controll::FlowHandler::PathAction
+ action.resolved_path
+ when Symbol, Controll::Event
+ resolve_event action
+ else
+ resolve_event
+ end
+ rescue Controll::FlowHandler::PathActionError
+ nil
+ end
+
+ def resolve_event event = nil
+ notify event if event
+ mapper.map_event
end
+
+ def mapper
+ @mapper ||= Controll::FlowHandler::Mapper.new main_event, event_map
+ end
end
-end
+end
View
4 lib/controll/event/helper.rb
@@ -1,11 +1,11 @@
module Controll
module Event::Helper
- def normalize event
+ def normalize event, *args
case event
when Controll::Event
event
when Symbol
- create_event event
+ create_event event, *args
when Hash, Hashie::Mash
create_event event.delete(:name), event
else
View
1  lib/controll/flow_handler.rb
@@ -9,6 +9,7 @@ module FlowHandler
autoload :Renderer, 'controll/flow_handler/renderer'
autoload :Fallback, 'controll/flow_handler/fallback'
autoload :EventHelper, 'controll/flow_handler/event_helper'
+ autoload :Mapper, 'controll/flow_handler/mapper'
end
end
View
11 lib/controll/flow_handler/errors.rb
@@ -1,11 +1,14 @@
module Controll::FlowHandler
class ActionEventError < StandardError; end
+ class PathActionError < StandardError; end
+
# Redirect
- class NoRedirectionFoundError < StandardError; end
+ class NoRedirectionFoundError < PathActionError; end
# Render
- class NoEventsDefinedError < StandardError; end
- class NoDefaultPathDefinedError < StandardError; end
- class BadPathError < StandardError; end
+ class NoEventsDefinedError < PathActionError; end
+ class NoDefaultPathDefinedError < PathActionError; end
+
+ class BadPathError < PathActionError; end
end
View
8 lib/controll/flow_handler/fallback.rb
@@ -2,13 +2,13 @@ module Controll::FlowHandler
class Fallback < Action
attr_reader :controller, :event
- def initialize controller, event
+ def initialize controller, event = nil
@controller = controller
- @event = event
+ @event = event if event
end
def perform
- error_check!
+ error_check! if event
controller.do_fallback self
end
@@ -17,7 +17,7 @@ def type
end
class << self
- def action controller, event
+ def action controller, event = nil
self.new controller, event
end
end
View
41 lib/controll/flow_handler/mapper.rb
@@ -0,0 +1,41 @@
+module Controll::FlowHandler
+ class Mapper
+ attr_reader :event_map, :event
+
+ NoRedirectionFoundError = Controll::FlowHandler::NoRedirectionFoundError
+
+ def initialize event, event_map
+ @event ||= normalize event
+
+ unless valid_map? event_map
+ raise ArgumentError, "Invalid redirect map: #{event_map}, must be a non-empty Hash"
+ end
+ @event_map ||= event_map
+ end
+
+ # An event can also be a Symbol,
+ # in which case it is a :notice event
+ def map_event
+ event_map.each do |path, events|
+ return path.to_s if valid? events
+ end
+ raise NoRedirectionFoundError, "No path could be found for event: #{event.inspect} in map: #{event_map}"
+ end
+
+ protected
+
+ include Controll::Event::Helper
+
+ def valid_map? event_map
+ event_map.kind_of?(Hash) && !event_map.blank?
+ end
+
+ def valid? events
+ matcher(event).match?(events)
+ end
+
+ def matcher event
+ @matcher ||= Controll::Event::Matcher.new event
+ end
+ end
+end
View
1  lib/controll/flow_handler/master/executor.rb
@@ -8,7 +8,6 @@ class Executor < Controll::Executor::Base
def initialize initiator, options = {}
super
- # puts "options: #{options}"
end
def execute
View
2  lib/controll/flow_handler/path_action.rb
@@ -11,8 +11,8 @@ def resolved_path
end
class << self
+ # do sth useful here?
def inherited base
- raise NotImplementedError, 'You must implement the #inherited class method'
end
end
end
View
6 lib/controll/flow_handler/redirecter/action.rb
@@ -36,12 +36,8 @@ def redirect_map
end
def mapper redirect_map
- @mapper ||= mapper_class.new event, redirect_map
+ @mapper ||= Controll::FlowHandler::Mapper.new event, redirect_map
end
-
- def mapper_class
- Controll::FlowHandler::Redirect::Mapper
- end
end
end
end
View
43 lib/controll/flow_handler/redirecter/mapper.rb
@@ -1,43 +0,0 @@
-module Controll::FlowHandler
- class Redirecter < Base
- class Mapper
- attr_reader :redirect_map, :event
-
- NoRedirectionFoundError = Controll::FlowHandler::NoRedirectionFoundError
-
- def initialize event, redirect_map
- @event ||= normalize event
-
- unless valid_map? redirect_map
- raise ArgumentError, "Invalid redirect map: #{redirect_map}, must be a Hash"
- end
- @redirect_map ||= redirect_map
- end
-
- # An events can also be a Symbol,
- # in which case it is a :notice event
- def map
- redirect_map.each do |path, events|
- return path.to_s if valid? events
- end
- raise NoRedirectionFoundError, "No path could be found for event: #{event} in map: #{redirect_map}"
- end
-
- protected
-
- include Controll::FlowHandler::EventHelper
-
- def valid_map? redirect_map
- redirect_map.kind_of?(Hash) && !redirect_map.blank?
- end
-
- def valid? events
- matcher(event).match?(events)
- end
-
- def matcher event
- @matcher ||= Controll::Helper::EventMatcher.new event
- end
- end
- end
-end
View
8 lib/controll/flow_handler/renderer.rb
@@ -7,6 +7,8 @@ def type
:render
end
+ # TODO: Should combine with Redirecter style, allowing for multiple render path mappings!
+ # This is fx useful for Wizards etc. where one Controller can render to many views, depending on state
class << self
def inherited base
if base.parent.respond_to? :add_action_handler
@@ -26,14 +28,16 @@ def action controller, event, path = nil
# (class << hello; self; end)
def default_path str = nil, &block
(class << self; self; end).send :define_method, :default_path do
- block_given? ? yield : str
+ block_given? ? instance_eval(&block) : str
end
end
def events *args, &block
(class << self; self; end).send :define_method, :events do
- block_given? ? yield : args.flatten
+ args.flatten
end
+
+ default_path(&block) if block_given?
end
protected
View
1  lib/controll/helper.rb
@@ -1,7 +1,6 @@
module Controll
module Helper
autoload :HashAccess, 'controll/helper/hash_access'
- autoload :Notify, 'controll/helper/notify'
autoload :Params, 'controll/helper/params'
autoload :Session, 'controll/helper/session'
end
View
22 spec/controll/enabler/maps_spec.rb
@@ -0,0 +1,22 @@
+describe Controll::Enabler::Maps do
+ subject { controller.new }
+ let(:controller) { MyController }
+
+ describe '.redirect_map {}' do
+ before :all do
+ controller.redirect_map :index => %w{alpha beta}
+ end
+
+ specify do
+ controller.redirect_map.should == {:index => ['alpha', 'beta'] }
+ end
+ end
+
+ describe '.render_map {}' do
+ before :all do
+ controller.render_map :index => %w{alpha beta}
+ end
+
+ its(:render_paths) { should == {:index => ['alpha', 'beta'] } }
+ end
+end
View
23 spec/controll/enabler/path_handler_spec.rb
@@ -0,0 +1,23 @@
+require 'spec_helper'
+
+class MySweetController
+ include Controll::Enabler
+
+ redirect_map :index => %w{success}
+
+ render_map :show => %w{success}
+
+ # Mocking!
+ def render path
+ path
+ end
+ alias_method :redirect_to, :render
+end
+
+describe Controll::Enabler::PathHandler do
+ subject { Controll::Enabler::PathHandler.new controller }
+
+ let(:controller) { MySweetController.new }
+
+ describe '.path_for action' do
+end
View
79 spec/controll/enabler/path_resolver_spec.rb
@@ -0,0 +1,79 @@
+require 'spec_helper'
+
+class MySweetController
+ include Controll::Enabler
+
+ def fallback_path
+ 'root'
+ end
+
+ def away
+ 'away'
+ end
+
+ def perfect
+ 'perfect'
+ end
+end
+
+describe Controll::Enabler::PathResolver do
+ let(:controller) { MySweetController.new }
+
+ let(:render_map) { {'perfect' => [:cool, :sweet], 'home' => [:success] }}
+ let(:redirect_map) { {'inperfect' => [:cool, :sweet], 'away' => [:success] }}
+
+ let(:redirect_action) { Controll::FlowHandler::Redirecter.new controller, redirect_path }
+ let(:render_action) { Controll::FlowHandler::Renderer.new controller, render_path }
+ let(:fallback_action) { Controll::FlowHandler::Fallback.new controller }
+
+ let(:render_path) { 'perfect' }
+ let(:redirect_path) { 'away' }
+
+ context 'initialize controller, render_map' do
+ subject { Controll::Enabler::PathResolver.new controller, render_map }
+
+ its(:caller) { should == controller }
+ its(:controller) { should == controller }
+ its(:event_map) { should == render_map }
+
+ describe '.resolve' do
+ specify do
+ subject.resolve.should == 'home'
+ end
+
+ describe '.resolve :cool' do
+ specify do
+ subject.resolve(:cool).should == 'perfect'
+ end
+ end
+
+ describe '.resolve :uncool' do
+ specify do
+ subject.resolve(:uncool).should_not == 'perfect'
+ end
+
+ specify do
+ subject.resolve(:uncool).should == nil
+ end
+ end
+
+ describe '.resolve Fallback Action' do
+ specify do
+ subject.resolve(fallback_action).should == nil
+ end
+ end
+
+ describe '.resolve Render Action' do
+ specify do
+ subject.resolve(render_action).should == render_path
+ end
+ end
+
+ describe '.resolve Redirect Action' do
+ specify do
+ subject.resolve(redirect_action).should == redirect_path
+ end
+ end
+ end
+ end
+end
View
18 spec/controll/enabler_spec.rb
@@ -14,24 +14,6 @@ def render path
subject { controller.new }
let(:controller) { MyController }
- describe 'maps' do
- describe '.redirect_map {}' do
- before :all do
- controller.redirect_map :index => %w{alpha beta}
- end
-
- its(:redirect_map) { should == {:index => ['alpha', 'beta'] } }
- end
-
- describe '.redirect_map {}' do
- before :all do
- controller.render_map :index => %w{alpha beta}
- end
-
- its(:render_paths) { should == {:index => ['alpha', 'beta'] } }
- end
- end
-
context 'instance' do
describe 'do_redirect *args' do
specify do
View
49 spec/controll/helper/path_resolver_spec.rb
@@ -1,49 +0,0 @@
-require 'spec_helper'
-
-class MySweetController
- include Controll::Enabler
-
- redirect_map :index => %w{success}
-
- render_map :show => %w{success}
-
- # Mocking!
- def render path
- path
- end
- alias_method :redirect_to, :render
-end
-
-describe Controll::Helper::PathResolver do
- subject { Controll::Helper::PathResolver.new controller }
-
- let(:controller) { MySweetController.new }
-
- describe '.extract_path' do
- describe ':redirect_map' do
- specify do
- subject.extract_path(:redirect_map).should == 'index'
- end
- end
-
- describe ':render_paths' do
- specify do
- subject.extract_path(:render_paths).should == 'show'
- end
- end
- end
-
- describe '.resolve_path' do
- describe ':redirect_map' do
- specify do
- subject.resolve_path(:redirect_map).should == 'index'
- end
- end
-
- describe ':render_paths' do
- specify do
- subject.resolve_path(:render_paths).should == 'show'
- end
- end
- end
-end
Please sign in to comment.
Something went wrong with that request. Please try again.