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 # @param [Vagrant::Action::Environment] env The action environment
# @return [Object] A callable object # @return [Object] A callable object
def to_app(env) 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 klass, args, block = item
lambda { |app| klass.new(app, env, *args, &block) } lambda { |app| klass.new(app, env, *args, &block) }
end 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) } items[0...-1].reverse.inject(items.last) { |a,e| e.call(a) }
end 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 end
context "converting to an app" do context "converting to an app" do
should "initialize each middleware with app and env" do should "preprend error halt to the chain" do
# TODO: better testing of this method... somehow
result = mock("result") result = mock("result")
env = {:a => :b} env = {:a => :b}
middleware = mock("middleware") middleware = mock("middleware")
middleware.expects(:new).with(anything, env).returns(result) middleware.expects(:new).with(anything, env).returns(result)
@instance.use middleware @instance.use middleware
assert_equal result, @instance.to_app(env) result = @instance.to_app(env)
assert result.kind_of?(Vagrant::Action::ErrorHalt)
end end
# TODO: Better testing of this method
end end
context "calling" do context "calling" do
@ -79,8 +80,11 @@ class ActionBuilderTest < Test::Unit::TestCase
true true
end end
env = Vagrant::Action::Environment.new(nil)
env[:key] = :value
@instance.use(mw) @instance.use(mw)
@instance.call(:key => :value) @instance.call(env)
end end
end 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