summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Keiser <jkeiser@opscode.com>2014-04-29 15:20:03 -0700
committerJohn Keiser <jkeiser@opscode.com>2014-04-29 15:20:03 -0700
commit90b5dd9580d29e3558ccb0169cff461d4561fba0 (patch)
treef366fe8fc43db1c9a3c97154eb04b87ec6fa1bdb
parenta84653e5f57109e3ac153ef686c9230da19da21d (diff)
downloadchef-jk/insert_at.tar.gz
Add insert_at to resource_collectionjk/insert_at
-rw-r--r--lib/chef/resource_collection.rb25
-rw-r--r--spec/unit/resource_collection_spec.rb33
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