Added ErrorHalt middleware which is prepended to all builder actions
This commit is contained in:
parent
221bdcbf63
commit
05a01f5953
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -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
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue