Builder fully tested
This commit is contained in:
parent
6eefc8e874
commit
c88adbc0f7
|
@ -1,26 +1,50 @@
|
|||
module Vagrant
|
||||
class Action
|
||||
# Action builder which provides a nice DSL for building up
|
||||
# a middleware sequence for Vagrant actions. This code is based
|
||||
# heavily off of `Rack::Builder` and `ActionDispatch::MiddlewareStack`
|
||||
# in Rack and Rails, respectively.
|
||||
class Builder
|
||||
# Initializes the builder. An optional block can be passed which
|
||||
# will be evaluated in the context of the instance.
|
||||
def initialize(&block)
|
||||
instance_eval(&block) if block_given?
|
||||
end
|
||||
|
||||
# Returns the current stack of middlewares. You probably won't
|
||||
# need to use this directly, and its recommended that you don't.
|
||||
#
|
||||
# @return [Array]
|
||||
def stack
|
||||
@stack ||= []
|
||||
end
|
||||
|
||||
# Adds a middleware class to the middleware stack. Any additional
|
||||
# args and a block, if given, are saved and passed to the initializer
|
||||
# of the middleware.
|
||||
#
|
||||
# @param [Class] middleware The middleware class
|
||||
def use(middleware, *args, &block)
|
||||
stack << [middleware, args, block]
|
||||
end
|
||||
|
||||
def to_app
|
||||
inner = @ins.last
|
||||
# Converts the builder stack to a runnable action sequence.
|
||||
#
|
||||
# @param [Vagrant::Action::Environment] env The action environment
|
||||
# @return [Object] A callable object
|
||||
def to_app(env)
|
||||
items = stack.collect do |item|
|
||||
klass, args, block = item
|
||||
lambda { |app| klass.new(app, env, *args, &block) }
|
||||
end
|
||||
|
||||
@ins[0...-1].reverse.inject(inner) { |a,e| e.call(a) }
|
||||
items << lambda { |env| } # The final step, which simply returns
|
||||
items[0...-1].reverse.inject(items.last) { |a,e| e.call(a) }
|
||||
end
|
||||
|
||||
# Runs the builder stack with the given environment.
|
||||
def call(env)
|
||||
to_app.call(env)
|
||||
to_app(env).call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
module Vagrant
|
||||
class Action
|
||||
# Represents an action environment which is what is passed
|
||||
# to the `call` method of each action. This environment contains
|
||||
# some helper methods for accessing the environment as well
|
||||
# as being a hash, to store any additional options.
|
||||
class Environment < Hash
|
||||
# The {Vagrant::Environment} object represented by this
|
||||
# action environment.
|
||||
attr_reader :env
|
||||
|
||||
def new(env)
|
||||
@env = env
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,22 +0,0 @@
|
|||
module Vagrant
|
||||
module Actions
|
||||
# Represents a middleware stack for Vagrant actions. Vagrant
|
||||
# actions are created and can be extended with middlewares.
|
||||
#
|
||||
# The exact nature of how this will work is not set in stone.
|
||||
class MiddlewareStack
|
||||
# Initializes the middleware stack with the given name.
|
||||
def initialize(key)
|
||||
@stack = []
|
||||
end
|
||||
|
||||
def use(klass)
|
||||
@stack << klass
|
||||
end
|
||||
|
||||
def run(endpoint)
|
||||
@stack << endpoint
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -36,7 +36,41 @@ 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
|
||||
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
||||
context "calling" do
|
||||
def mock_middleware
|
||||
middleware = Class.new do
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
should "convert to an app then call with the env" do
|
||||
mw = mock_middleware
|
||||
mw.any_instance.expects(:call).with() do |env|
|
||||
assert env.has_key?(:key)
|
||||
true
|
||||
end
|
||||
|
||||
@instance.use(mw)
|
||||
@instance.call(:key => :value)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
||||
|
||||
class ActionEnvironmentTest < Test::Unit::TestCase
|
||||
setup do
|
||||
@klass = Vagrant::Action::Environment
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue