Skip to content

Commit

Permalink
Merge branch 'CHEF-3799'
Browse files Browse the repository at this point in the history
  • Loading branch information
danielsdeleo committed Jan 28, 2013
2 parents c9afae1 + ea0205d commit 98ca747
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 1 deletion.
9 changes: 8 additions & 1 deletion lib/chef/node/attribute_collections.rb
Expand Up @@ -154,7 +154,14 @@ def []=(key, value)
alias :attribute? :has_key?

def method_missing(symbol, *args)
if args.empty?
# Calling `puts arg` implicitly calls #to_ary on `arg`. If `arg` does
# not implement #to_ary, ruby recognizes it as a single argument, and
# if it returns an Array, then ruby prints each element. If we don't
# account for that here, we'll auto-vivify a VividMash for the key
# :to_ary which creates an unwanted key and raises a TypeError.
if symbol == :to_ary
super
elsif args.empty?
self[symbol]
elsif symbol.to_s =~ /=$/
key_to_set = symbol.to_s[/^(.+)=$/, 1]
Expand Down
13 changes: 13 additions & 0 deletions spec/unit/node/attribute_spec.rb
Expand Up @@ -234,6 +234,19 @@
end
end

describe "when printing attribute components" do

it "does not cause a type error" do
# See CHEF-3799; IO#puts implicitly calls #to_ary on its argument. This
# is expected to raise a NoMethodError or return an Array. `to_ary` is
# the "strict" conversion method that should only be implemented by
# things that are truly Array-like, so NoMethodError is the right choice.
# (cf. there is no Hash#to_ary).
lambda { @attributes.default.to_ary }.should raise_error(NoMethodError)
end

end

describe "when fetching values based on precedence" do
before do
@attributes.default["default"] = "cookbook default"
Expand Down

0 comments on commit 98ca747

Please sign in to comment.