From 90b5dd9580d29e3558ccb0169cff461d4561fba0 Mon Sep 17 00:00:00 2001 From: John Keiser Date: Tue, 29 Apr 2014 15:20:03 -0700 Subject: Add insert_at to resource_collection --- lib/chef/resource_collection.rb | 25 +++++++++++++++++-------- spec/unit/resource_collection_spec.rb | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 8 deletions(-) diff --git a/lib/chef/resource_collection.rb b/lib/chef/resource_collection.rb index a528a18aed..181328a1fc 100644 --- a/lib/chef/resource_collection.rb +++ b/lib/chef/resource_collection.rb @@ -67,24 +67,33 @@ class Chef alias_method :push, :<< def insert(resource) - is_chef_resource(resource) if @insert_after_idx # in the middle of executing a run, so any resources inserted now should # be placed after the most recent addition done by the currently executing # resource - @resources.insert(@insert_after_idx + 1, resource) - # update name -> location mappings and register new resource - @resources_by_name.each_key do |key| - @resources_by_name[key] += 1 if @resources_by_name[key] > @insert_after_idx - end - @resources_by_name[resource.to_s] = @insert_after_idx + 1 + insert_at(@insert_after_idx + 1, resource) @insert_after_idx += 1 else + is_chef_resource(resource) @resources << resource @resources_by_name[resource.to_s] = @resources.length - 1 end end + def insert_at(insert_at_index, *resources) + resources.each do |resource| + is_chef_resource(resource) + end + @resources.insert(insert_at_index, *resources) + # update name -> location mappings and register new resource + @resources_by_name.each_key do |key| + @resources_by_name[key] += resources.size if @resources_by_name[key] >= insert_at_index + end + resources.each_with_index do |resource, i| + @resources_by_name[resource.to_s] = insert_at_index + i + end + end + def each @resources.each do |resource| yield resource @@ -247,7 +256,7 @@ class Chef def is_chef_resource(arg) unless arg.kind_of?(Chef::Resource) - raise ArgumentError, "Members must be Chef::Resource's" + raise ArgumentError, "Cannot insert a #{arg.class} into a resource collection: must be a Chef::Resource or descendant thereof" end true end diff --git a/spec/unit/resource_collection_spec.rb b/spec/unit/resource_collection_spec.rb index cf62f5ff40..eddd92e098 100644 --- a/spec/unit/resource_collection_spec.rb +++ b/spec/unit/resource_collection_spec.rb @@ -88,6 +88,39 @@ describe Chef::ResourceCollection do end end + describe "insert_at" do + it "should accept only Chef::Resources" do + lambda { @rc.insert_at(0, @resource, @resource) }.should_not raise_error + lambda { @rc.insert_at(0, "string") }.should raise_error + lambda { @rc.insert_at(0, @resource, "string") }.should raise_error + end + + it "should toss an error if it receives a bad index" do + @rc.insert_at(10, @resource) + end + + it "should insert resources at the beginning when asked" do + @rc.insert(Chef::Resource::ZenMaster.new('1')) + @rc.insert(Chef::Resource::ZenMaster.new('2')) + @rc.insert_at(0, Chef::Resource::ZenMaster.new('X')) + @rc.all_resources.map { |r| r.name }.should == [ 'X', '1', '2' ] + end + + it "should insert resources in the middle when asked" do + @rc.insert(Chef::Resource::ZenMaster.new('1')) + @rc.insert(Chef::Resource::ZenMaster.new('2')) + @rc.insert_at(1, Chef::Resource::ZenMaster.new('X')) + @rc.all_resources.map { |r| r.name }.should == [ '1', 'X', '2' ] + end + + it "should insert resources at the end when asked" do + @rc.insert(Chef::Resource::ZenMaster.new('1')) + @rc.insert(Chef::Resource::ZenMaster.new('2')) + @rc.insert_at(2, Chef::Resource::ZenMaster.new('X')) + @rc.all_resources.map { |r| r.name }.should == [ '1', '2', 'X' ] + end + end + describe "each" do it "should allow you to iterate over every resource in the collection" do load_up_resources -- cgit v1.2.1