summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLamont Granquist <lamont@scriptkiddie.org>2016-09-20 11:38:28 -0700
committerLamont Granquist <lamont@scriptkiddie.org>2016-09-20 11:38:28 -0700
commit057c450f4aa02e7f97a9cce6d506899a190509c1 (patch)
treea28b8bbc118267b586d3d63579f83ae972bc65c9
parent795e2cb806407151aa009fe0f56f138d1c5a7b2d (diff)
downloadchef-057c450f4aa02e7f97a9cce6d506899a190509c1.tar.gz
fix method_access and array handling in node presenter
Signed-off-by: Lamont Granquist <lamont@scriptkiddie.org>
-rw-r--r--lib/chef/knife/core/generic_presenter.rb28
-rw-r--r--spec/unit/knife/core/ui_spec.rb9
2 files changed, 20 insertions, 17 deletions
diff --git a/lib/chef/knife/core/generic_presenter.rb b/lib/chef/knife/core/generic_presenter.rb
index f273cb5bca..323c2cf350 100644
--- a/lib/chef/knife/core/generic_presenter.rb
+++ b/lib/chef/knife/core/generic_presenter.rb
@@ -175,23 +175,19 @@ class Chef
def extract_nested_value(data, nested_value_spec)
nested_value_spec.split(".").each do |attr|
- if data.nil?
- nil # don't get no method error on nil
- # Must check :[] before attr because spec can include
- # `keys` - want the key named `keys`, not a list of
- # available keys.
- elsif data.respond_to?(:[]) && data.has_key?(attr)
- data = data[attr]
- elsif data.respond_to?(attr.to_sym)
- data = data.send(attr.to_sym)
- else
- data = begin
- data.send(attr.to_sym)
- rescue NoMethodError
- nil
- end
- end
+ data =
+ if data.is_a?(Array)
+ data[attr.to_i]
+ elsif data.respond_to?(:[], false) && data.key?(attr)
+ data[attr]
+ elsif data.respond_to?(attr.to_sym, false)
+ # handles -a chef_environment and other things that hang of the node and aren't really attributes
+ data.public_send(attr.to_sym)
+ else
+ nil
+ end
end
+ # necessary for coercing hashable non-attribute objects hanging off the node into real hashes
( !data.kind_of?(Array) && data.respond_to?(:to_hash) ) ? data.to_hash : data
end
diff --git a/spec/unit/knife/core/ui_spec.rb b/spec/unit/knife/core/ui_spec.rb
index 9f525f22f0..59c308e692 100644
--- a/spec/unit/knife/core/ui_spec.rb
+++ b/spec/unit/knife/core/ui_spec.rb
@@ -377,12 +377,19 @@ EOM
end
it "should return the name attribute" do
- allow_any_instance_of(Chef::Node).to receive(:name).and_return("chef.localdomain")
input = Chef::Node.new
+ input.name("chef.localdomain")
@ui.config[:attribute] = "name"
expect(@ui.format_for_display(input)).to eq( { "chef.localdomain" => { "name" => "chef.localdomain" } })
end
+ it "works with arrays" do
+ input = Chef::Node.new
+ input.default["array"] = %w{zero one two}
+ @ui.config[:attribute] = "array.1"
+ expect(@ui.format_for_display(input)).to eq( nil => { "array.1" => "one" })
+ end
+
it "returns nil when given an attribute path that isn't a name or attribute" do
input = { "keys" => { "keys" => "values" }, "hi" => "ho", "id" => "sample-data-bag-item" }
non_existing_path = "nope.nada.nothingtoseehere"