diff options
author | John Keiser <john@johnkeiser.com> | 2015-05-15 23:06:51 -0700 |
---|---|---|
committer | John Keiser <john@johnkeiser.com> | 2015-06-23 14:42:27 -0700 |
commit | e8a80c674bfb67b6839eb8498a73da61d0e9cdc0 (patch) | |
tree | 010453ba5d9d7f787a7c5e92afac0deee6cca0cd /spec/integration | |
parent | 87a8b49efbccb6934ff2bacb8f8df53d1caf5e46 (diff) | |
download | chef-e8a80c674bfb67b6839eb8498a73da61d0e9cdc0.tar.gz |
Create the `action :name do ... end` syntax for Resource
Diffstat (limited to 'spec/integration')
-rw-r--r-- | spec/integration/recipes/resource_action_spec.rb | 338 |
1 files changed, 338 insertions, 0 deletions
diff --git a/spec/integration/recipes/resource_action_spec.rb b/spec/integration/recipes/resource_action_spec.rb new file mode 100644 index 0000000000..8e8071abbc --- /dev/null +++ b/spec/integration/recipes/resource_action_spec.rb @@ -0,0 +1,338 @@ +require 'support/shared/integration/integration_helper' + +describe "Resource.action" do + include IntegrationSupport + + def converge(str=nil, file=nil, line=nil, &block) + if block + super(&block) + else + super() do + eval(str, nil, file, line) + end + end + end + + shared_context "ActionJackson" do + it "The default action is the first declared action" do + converge <<-EOM, __FILE__, __LINE__+1 + #{resource_dsl} 'hi' do + foo 'foo!' + end + EOM + expect(ActionJackson.ran_action).to eq :access_recipe_dsl + expect(ActionJackson.succeeded).to eq true + end + + it "The action can access recipe DSL" do + converge <<-EOM, __FILE__, __LINE__+1 + #{resource_dsl} 'hi' do + foo 'foo!' + action :access_recipe_dsl + end + EOM + expect(ActionJackson.ran_action).to eq :access_recipe_dsl + expect(ActionJackson.succeeded).to eq true + end + + it "The action can access attributes" do + converge <<-EOM, __FILE__, __LINE__+1 + #{resource_dsl} 'hi' do + foo 'foo!' + action :access_attribute + end + EOM + expect(ActionJackson.ran_action).to eq :access_attribute + expect(ActionJackson.succeeded).to eq 'foo!' + end + + it "The action can access public methods" do + converge <<-EOM, __FILE__, __LINE__+1 + #{resource_dsl} 'hi' do + foo 'foo!' + action :access_method + end + EOM + expect(ActionJackson.ran_action).to eq :access_method + expect(ActionJackson.succeeded).to eq 'foo_public!' + end + + it "The action can access protected methods" do + converge <<-EOM, __FILE__, __LINE__+1 + #{resource_dsl} 'hi' do + foo 'foo!' + action :access_protected_method + end + EOM + expect(ActionJackson.ran_action).to eq :access_protected_method + expect(ActionJackson.succeeded).to eq 'foo_protected!' + end + + it "The action cannot access private methods" do + expect { + converge(<<-EOM, __FILE__, __LINE__+1) + #{resource_dsl} 'hi' do + foo 'foo!' + action :access_private_method + end + EOM + }.to raise_error(NameError) + expect(ActionJackson.ran_action).to eq :access_private_method + end + + it "The action cannot access resource instance variables" do + converge <<-EOM, __FILE__, __LINE__+1 + #{resource_dsl} 'hi' do + foo 'foo!' + action :access_instance_variable + end + EOM + expect(ActionJackson.ran_action).to eq :access_instance_variable + expect(ActionJackson.succeeded).to be_nil + end + + it "The action does not compile until the prior resource has converged" do + converge <<-EOM, __FILE__, __LINE__+1 + ruby_block 'wow' do + block do + ActionJackson.ruby_block_converged = 'ruby_block_converged!' + end + end + + #{resource_dsl} 'hi' do + foo 'foo!' + action :access_class_method + end + EOM + expect(ActionJackson.ran_action).to eq :access_class_method + expect(ActionJackson.succeeded).to eq 'ruby_block_converged!' + end + + it "The action's resources converge before the next resource converges" do + converge <<-EOM, __FILE__, __LINE__+1 + #{resource_dsl} 'hi' do + foo 'foo!' + action :access_attribute + end + + ruby_block 'wow' do + block do + ActionJackson.ruby_block_converged = ActionJackson.succeeded + end + end + EOM + expect(ActionJackson.ran_action).to eq :access_attribute + expect(ActionJackson.succeeded).to eq 'foo!' + expect(ActionJackson.ruby_block_converged).to eq 'foo!' + end + end + + context "With resource 'action_jackson'" do + before(:context) { + class ActionJackson < Chef::Resource + provides :action_jackson + def foo(value=nil) + @foo = value if value + @foo + end + def blarghle(value=nil) + @blarghle = value if value + @blarghle + end + + class <<self + attr_accessor :ran_action + attr_accessor :succeeded + attr_accessor :ruby_block_converged + end + + public def foo_public + 'foo_public!' + end + protected def foo_protected + 'foo_protected!' + end + private def foo_private + 'foo_private!' + end + + action :access_recipe_dsl do + ActionJackson.ran_action = :access_recipe_dsl + ruby_block 'hi there' do + block do + ActionJackson.succeeded = true + end + end + end + action :access_attribute do + ActionJackson.ran_action = :access_attribute + ActionJackson.succeeded = foo + ActionJackson.succeeded += " #{blarghle}" if blarghle + ActionJackson.succeeded += " #{bar}" if respond_to?(:bar) + end + action :access_attribute2 do + ActionJackson.ran_action = :access_attribute2 + ActionJackson.succeeded = foo + ActionJackson.succeeded += " #{blarghle}" if blarghle + ActionJackson.succeeded += " #{bar}" if respond_to?(:bar) + end + action :access_method do + ActionJackson.ran_action = :access_method + ActionJackson.succeeded = foo_public + end + action :access_protected_method do + ActionJackson.ran_action = :access_protected_method + ActionJackson.succeeded = foo_protected + end + action :access_private_method do + ActionJackson.ran_action = :access_private_method + ActionJackson.succeeded = foo_private + end + action :access_instance_variable do + ActionJackson.ran_action = :access_instance_variable + ActionJackson.succeeded = @foo + end + action :access_class_method do + ActionJackson.ran_action = :access_class_method + ActionJackson.succeeded = ActionJackson.ruby_block_converged + end + end + } + before(:each) { + ActionJackson.ran_action = :error + ActionJackson.succeeded = :error + ActionJackson.ruby_block_converged = :error + } + + it_behaves_like "ActionJackson" do + let(:resource_dsl) { :action_jackson } + end + + context "And 'action_jackgrandson' inheriting from ActionJackson and changing nothing" do + before(:context) { + class ActionJackgrandson < ActionJackson + provides :action_jackgrandson + end + } + + it_behaves_like "ActionJackson" do + let(:resource_dsl) { :action_jackgrandson } + end + end + + context "And 'action_jackalope' inheriting from ActionJackson with an extra attribute and action" do + before(:context) { + class ActionJackalope < ActionJackson + provides :action_jackalope + + def foo(value=nil) + @foo = "#{value}alope" if value + @foo + end + def bar(value=nil) + @bar = "#{value}alope" if value + @bar + end + class <<self + attr_accessor :jackalope_ran + end + action :access_jackalope do + ActionJackalope.jackalope_ran = :access_jackalope + ActionJackalope.succeeded = "#{foo} #{blarghle} #{bar}" + end + action :access_attribute do + super() + ActionJackalope.jackalope_ran = :access_attribute + ActionJackalope.succeeded = ActionJackson.succeeded + end + end + } + before do + ActionJackalope.jackalope_ran = nil + end + + context "action_jackson still behaves the same" do + it_behaves_like "ActionJackson" do + let(:resource_dsl) { :action_jackson } + end + end + + it "The default action remains the same even though new actions were specified first" do + converge { + action_jackalope 'hi' do + foo 'foo!' + bar 'bar!' + end + } + expect(ActionJackson.ran_action).to eq :access_recipe_dsl + expect(ActionJackson.succeeded).to eq true + end + + it "new actions run, and can access overridden, new, and overridden attributes" do + converge { + action_jackalope 'hi' do + foo 'foo!' + bar 'bar!' + blarghle 'blarghle!' + action :access_jackalope + end + } + expect(ActionJackalope.jackalope_ran).to eq :access_jackalope + expect(ActionJackalope.succeeded).to eq "foo!alope blarghle! bar!alope" + end + + it "overridden actions run, call super, and can access overridden, new, and overridden attributes" do + converge { + action_jackalope 'hi' do + foo 'foo!' + bar 'bar!' + blarghle 'blarghle!' + action :access_attribute + end + } + expect(ActionJackson.ran_action).to eq :access_attribute + expect(ActionJackson.succeeded).to eq "foo!alope blarghle! bar!alope" + expect(ActionJackalope.jackalope_ran).to eq :access_attribute + expect(ActionJackalope.succeeded).to eq "foo!alope blarghle! bar!alope" + end + + it "non-overridden actions run and can access overridden and non-overridden variables (but not necessarily new ones)" do + converge { + action_jackalope 'hi' do + foo 'foo!' + bar 'bar!' + blarghle 'blarghle!' + action :access_attribute2 + end + } + expect(ActionJackson.ran_action).to eq :access_attribute2 + expect(ActionJackson.succeeded).to eq("foo!alope blarghle! bar!alope").or(eq("foo!alope blarghle!")) + end + end + end + + context "With a resource with no actions" do + before(:context) { + class NoActionJackson < Chef::Resource + provides :no_action_jackson + def foo(value=nil) + @foo = value if value + @foo + end + + class <<self + attr_accessor :action_was + end + end + } + it "The default action is :nothing" do + converge { + no_action_jackson 'hi' do + foo 'foo!' + NoActionJackson.action_was = action + end + } + expect(NoActionJackson.action_was).to eq :nothing + end + end +end |