Added ErrorHalt middleware which is prepended to all builder actions

This commit is contained in:
Mitchell Hashimoto 2010-07-04 18:15:41 +02:00
parent 221bdcbf63
commit 05a01f5953
4 changed files with 53 additions and 7 deletions

View File

@ -50,12 +50,19 @@ module Vagrant
# @param [Vagrant::Action::Environment] env The action environment
# @return [Object] A callable object
def to_app(env)
items = stack.collect do |item|
# Prepend the error halt task so errneous environments are halted
# before the chain even begins.
items = stack.dup.unshift([ErrorHalt, [], nil])
# Convert each middleware into a lambda which takes the next
# middleware.
items = items.collect do |item|
klass, args, block = item
lambda { |app| klass.new(app, env, *args, &block) }
end
items << lambda { |env| } # The final step, which simply returns
# Append the final step and convert into flattened call chain.
items << lambda { |env| }
items[0...-1].reverse.inject(items.last) { |a,e| e.call(a) }
end

View File

@ -0,0 +1,14 @@
module Vagrant
class Action
# A middleware which simply halts if the environment is erroneous.
class ErrorHalt
def initialize(app,env)
@app = app
end
def call(env)
@app.call(env) if !env.error?
end
end
end
end

View File

@ -47,16 +47,17 @@ class ActionBuilderTest < Test::Unit::TestCase
end
context "converting to an app" do
should "initialize each middleware with app and env" do
# TODO: better testing of this method... somehow
should "preprend error halt to the chain" do
result = mock("result")
env = {:a => :b}
middleware = mock("middleware")
middleware.expects(:new).with(anything, env).returns(result)
@instance.use middleware
assert_equal result, @instance.to_app(env)
result = @instance.to_app(env)
assert result.kind_of?(Vagrant::Action::ErrorHalt)
end
# TODO: Better testing of this method
end
context "calling" do
@ -79,8 +80,11 @@ class ActionBuilderTest < Test::Unit::TestCase
true
end
env = Vagrant::Action::Environment.new(nil)
env[:key] = :value
@instance.use(mw)
@instance.call(:key => :value)
@instance.call(env)
end
end
end

View File

@ -0,0 +1,21 @@
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
class ErrorHaltTest < Test::Unit::TestCase
setup do
@klass = Vagrant::Action::ErrorHalt
@app, @env = mock_action_data
@instance = @klass.new(@app, @env)
end
should "continue the chain if no error" do
assert !@env.error?
@app.expects(:call).with(@env).once
@instance.call(@env)
end
should "halt the chain if an error occured" do
@env.error!(:foo)
@app.expects(:call).never
@instance.call(@env)
end
end