From bad5ba559f874f7a0256c8b7f17f99294ce7a3af Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 4 Jul 2010 03:48:16 +0200 Subject: [PATCH] Actions on Environment and making them runnable --- lib/vagrant/action.rb | 26 ++++++++++++++++++++------ lib/vagrant/action/builder.rb | 12 ++++++++++++ lib/vagrant/action/environment.rb | 2 +- lib/vagrant/environment.rb | 9 +++++++++ test/vagrant/action_test.rb | 24 ++++++++++++++++++++++++ test/vagrant/environment_test.rb | 14 ++++++++++++++ 6 files changed, 80 insertions(+), 7 deletions(-) create mode 100644 test/vagrant/action_test.rb diff --git a/lib/vagrant/action.rb b/lib/vagrant/action.rb index adc8eb76b..cd13db558 100644 --- a/lib/vagrant/action.rb +++ b/lib/vagrant/action.rb @@ -1,4 +1,7 @@ module Vagrant + # Manages action running and registration. Every Vagrant environment + # has an instance of {Action} to allow for running in the context of + # the environment. class Action class << self # Returns the list of registered actions. @@ -14,13 +17,24 @@ module Vagrant def register(key, callable) @actions[key] = callable end + end - # Runs a registered action with the given key. - # - # @param [Symbol] key - def run(key) - @actions[key].call - end + # The environment to run the actions in. + attr_reader :env + + # Initializes the action with the given environment which the actions + # will be run in. + # + # @param [Environment] env + def initialize(env) + @env = env + end + + # Runs the given callable object in the context of the environment. + # + # @param [Object] callable An object which responds to `call`. + def run(callable) + callable.call(Action::Environment.new(env)) end end end diff --git a/lib/vagrant/action/builder.rb b/lib/vagrant/action/builder.rb index f10d3e58a..3e507bd6c 100644 --- a/lib/vagrant/action/builder.rb +++ b/lib/vagrant/action/builder.rb @@ -4,6 +4,18 @@ module Vagrant # a middleware sequence for Vagrant actions. This code is based # heavily off of `Rack::Builder` and `ActionDispatch::MiddlewareStack` # in Rack and Rails, respectively. + # + # Usage + # + # Building an action sequence is very easy: + # + # app = Vagrant::Action::Builder.new do + # use MiddlewareA + # use MiddlewareB + # end + # + # Vagrant::Action.run(app) + # class Builder # Initializes the builder. An optional block can be passed which # will be evaluated in the context of the instance. diff --git a/lib/vagrant/action/environment.rb b/lib/vagrant/action/environment.rb index 974ae4483..9f75ffb38 100644 --- a/lib/vagrant/action/environment.rb +++ b/lib/vagrant/action/environment.rb @@ -9,7 +9,7 @@ module Vagrant # action environment. attr_reader :env - def new(env) + def initialize(env) @env = env end end diff --git a/lib/vagrant/environment.rb b/lib/vagrant/environment.rb index f58608e1c..0ec2ff2c8 100644 --- a/lib/vagrant/environment.rb +++ b/lib/vagrant/environment.rb @@ -21,6 +21,7 @@ module Vagrant attr_reader :active_list attr_reader :commands attr_reader :logger + attr_reader :actions #--------------------------------------------------------------- # Class Methods @@ -142,6 +143,7 @@ module Vagrant load_vm! load_active_list! load_commands! + load_actions! self end @@ -301,6 +303,13 @@ module Vagrant @commands = Command.new(self) end + # Loads the instance of {Action} for this environment. This allows + # users of the instance to run action sequences in the context of + # this environment. + def load_actions! + @actions = Action.new(self) + end + #--------------------------------------------------------------- # Methods to manage VM #--------------------------------------------------------------- diff --git a/test/vagrant/action_test.rb b/test/vagrant/action_test.rb new file mode 100644 index 000000000..b7f36ea3a --- /dev/null +++ b/test/vagrant/action_test.rb @@ -0,0 +1,24 @@ +require File.join(File.dirname(__FILE__), '..', 'test_helper') + +class ActionTest < Test::Unit::TestCase + setup do + @klass = Vagrant::Action + end + + context "with an instance" do + setup do + @instance = @klass.new(mock_environment) + end + + should "run the callable item with the proper context" do + callable = mock("callable") + callable.expects(:call).with() do |env| + assert env.kind_of?(Vagrant::Action::Environment) + assert_equal @instance.env, env.env + true + end + + @instance.run(callable) + end + end +end diff --git a/test/vagrant/environment_test.rb b/test/vagrant/environment_test.rb index 5f6e37c47..68c6f458d 100644 --- a/test/vagrant/environment_test.rb +++ b/test/vagrant/environment_test.rb @@ -226,6 +226,7 @@ class EnvironmentTest < Test::Unit::TestCase @env.expects(:load_vm!).once.in_sequence(call_seq) @env.expects(:load_active_list!).once.in_sequence(call_seq) @env.expects(:load_commands!).once.in_sequence(call_seq) + @env.expects(:load_actions!).once.in_sequence(call_seq) assert_equal @env, @env.load! end end @@ -614,6 +615,19 @@ class EnvironmentTest < Test::Unit::TestCase assert_equal commands, @env.commands end end + + context "loading actions" do + setup do + @env = mock_environment + end + + should "initialize the Action object with the given environment" do + result = mock("result") + Vagrant::Action.expects(:new).with(@env).returns(result) + @env.load_actions! + assert_equal result, @env.actions + end + end end context "requiring properties" do