diff options
author | John Keiser <jkeiser@opscode.com> | 2014-04-29 15:20:03 -0700 |
---|---|---|
committer | John Keiser <jkeiser@opscode.com> | 2014-04-29 15:20:03 -0700 |
commit | 90b5dd9580d29e3558ccb0169cff461d4561fba0 (patch) | |
tree | f366fe8fc43db1c9a3c97154eb04b87ec6fa1bdb | |
parent | a84653e5f57109e3ac153ef686c9230da19da21d (diff) | |
download | chef-jk/insert_at.tar.gz |
Add insert_at to resource_collectionjk/insert_at
-rw-r--r-- | lib/chef/resource_collection.rb | 25 | ||||
-rw-r--r-- | 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 |