summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAzul <azul@riseup.net>2016-09-19 09:51:38 +0200
committerAzul <azul@riseup.net>2016-09-19 09:51:38 +0200
commita1c7d68b05f142322a190b450971d27c076310a9 (patch)
tree75b171436d9f1109025904fda4cc650b2570a74b
parentd3c9ec2c815a4cd79cfaf40d1de0365fdec90cb2 (diff)
refactor: separate handler chain from dispatcher
Handler Chain is of handlers that respond to call. Invoking handle(*args) on the chain will call the handlers with the given args until one of them returns a result that is truethy (i.e. not false or nil). Extracted from the dispatcher so we can also handle exceptions there in the future. (So that if one of the network connections to the request_handlers fails we can continue while still tracking the failed exception.)
-rw-r--r--lib/nickserver/dispatcher.rb9
-rw-r--r--lib/nickserver/handler_chain.rb26
-rw-r--r--test/unit/handler_chain_test.rb45
3 files changed, 73 insertions, 7 deletions
diff --git a/lib/nickserver/dispatcher.rb b/lib/nickserver/dispatcher.rb
index 7a584e5..9968e95 100644
--- a/lib/nickserver/dispatcher.rb
+++ b/lib/nickserver/dispatcher.rb
@@ -35,10 +35,7 @@ module Nickserver
protected
def handle(request)
- handler_chain.each do |handler|
- response = handler.call request
- return response if response
- end
+ handler_chain.handle request
rescue RuntimeError => exc
puts "Error: #{exc}"
puts exc.backtrace
@@ -46,13 +43,11 @@ module Nickserver
end
def handler_chain
- [
- RequestHandlers::InvalidEmailHandler,
+ HandlerChain.new RequestHandlers::InvalidEmailHandler,
RequestHandlers::LocalEmailHandler,
RequestHandlers::HkpEmailHandler,
RequestHandlers::FingerprintHandler,
Proc.new { Nickserver::Response.new(404, "404 Not Found\n") }
- ]
end
def send_response(response)
diff --git a/lib/nickserver/handler_chain.rb b/lib/nickserver/handler_chain.rb
new file mode 100644
index 0000000..a0eba4d
--- /dev/null
+++ b/lib/nickserver/handler_chain.rb
@@ -0,0 +1,26 @@
+#
+# Handler Chain
+#
+# A chain of handlers that respond to call. Invoking handle(*args) on the chain
+# will call the handlers with the given args until one of them returns a result
+# that is truethy (i.e. not false or nil).
+#
+# Extracted from the dispatcher so we can also handle exceptions here in the
+# future.
+#
+
+module Nickserver
+ class HandlerChain
+
+ def initialize(*handlers)
+ @handlers = handlers
+ end
+
+ def handle(*args)
+ result = nil
+ _handled_by = @handlers.find{|h| result = h.call(*args)}
+ result
+ end
+
+ end
+end
diff --git a/test/unit/handler_chain_test.rb b/test/unit/handler_chain_test.rb
new file mode 100644
index 0000000..067f11e
--- /dev/null
+++ b/test/unit/handler_chain_test.rb
@@ -0,0 +1,45 @@
+require 'test_helper'
+require 'nickserver/handler_chain'
+
+class HandlerChainTest < Minitest::Test
+
+ def test_initialization
+ assert chain
+ end
+
+ def test_noop
+ assert_nil chain.handle
+ end
+
+ def test_triggering_handlers
+ handler_mock.expect :call, nil, [:a, :b]
+ chain handler_mock
+ chain.handle :a, :b
+ handler_mock.verify
+ end
+
+ def test_returns_handler_result
+ chain handler_with_nil, handler_with_result
+ assert_equal :result, chain.handle
+ end
+
+
+ protected
+
+ def chain(*handlers)
+ @chain ||= Nickserver::HandlerChain.new(*handlers)
+ end
+
+ def handler_mock
+ @handler ||= Minitest::Mock.new
+ end
+
+ def handler_with_nil
+ Proc.new {}
+ end
+
+ def handler_with_result
+ Proc.new { :result }
+ end
+
+end