Skip to content
This repository has been archived by the owner on Sep 19, 2020. It is now read-only.

Commit

Permalink
Share AST when resource_name is an expr, refs #31.
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrew Crump committed Jun 5, 2012
1 parent 008b1d1 commit a675a31
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 4 deletions.
17 changes: 13 additions & 4 deletions lib/foodcritic/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,8 @@ def match(node)
# Decode resource notifications.
#
# @param [Nokogiri::XML::Node] ast The AST to check for notifications.
# @return [Array] A flat array of notifications.
# @return [Array] A flat array of notifications. The resource_name may be
# a string or a Node if the resource name is an expression.
def notifications(ast)
return [] unless ast.respond_to?(:xpath)
ast.xpath('//command[ident/@value="notifies" or
Expand All @@ -194,14 +195,22 @@ def notifications(ast)
symbol/ident[1]/@value')
if params.empty?
target = notifies.xpath('args_add_block/args_add/
descendant::tstring_content[1]/@value').to_s
match = target.match(/^([^\[]+)\[(.+)\]$/)
descendant::tstring_content/@value').to_s
match = target.match(/^([^\[]+)\[(.*)\]$/)
next unless match
resource_type, resource_name =
match.captures.tap{|m| m[0] = m[0].to_sym}
if notifies.xpath('descendant::string_embexpr').empty?
next if resource_name.empty?
else
resource_name =
notifies.xpath('args_add_block/args_add/string_literal')
end
else
resource_type = params.xpath('symbol[1]/ident/@value').to_s.to_sym
resource_name = params.xpath('string_add[1]/tstring_content/@value').to_s
resource_name = params.xpath('string_add[1][count(../
descendant::string_add) = 1]/tstring_content/@value').to_s
resource_name = params if resource_name.empty?
end
{
:type =>
Expand Down
106 changes: 106 additions & 0 deletions spec/foodcritic/api_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,48 @@ def parse_ast(str)
})).must_be_empty
end
end
describe "returns empty if the resource name is missing" do
it "old-style notifications" do
api.notifications(parse_ast(%q{
template "/etc/nscd.conf" do
source "nscd.conf"
owner "root"
group "root"
notifies :restart, resources(:service)
end
})).must_be_empty
end
it "old-style subscriptions" do
api.notifications(parse_ast(%q{
template "/etc/nscd.conf" do
source "nscd.conf"
owner "root"
group "root"
subscribes :restart, resources(:service)
end
})).must_be_empty
end
it "new-style notifications" do
api.notifications(parse_ast(%q{
template "/etc/nscd.conf" do
source "nscd.conf"
owner "root"
group "root"
notifies :restart, "service[]"
end
})).must_be_empty
end
it "new-style subscriptions" do
api.notifications(parse_ast(%q{
template "/etc/nscd.conf" do
source "nscd.conf"
owner "root"
group "root"
subscribes :restart, "service[]"
end
})).must_be_empty
end
end
end
it "understands the old-style notifications" do
api.notifications(parse_ast(%q{
Expand Down Expand Up @@ -860,6 +902,70 @@ def parse_ast(str)
})).first[:notification_timing].must_equal(:immediately)
end
end
describe "resource names as expressions" do
describe "returns the AST for an embedded string" do
it "old-style notifications" do
assert api.notifications(parse_ast(%q{
template "/etc/foo.conf" do
notifies :create, resources(:template => "/etc/bar/#{resource}.bar")
end
})).first[:resource_name].respond_to?(:xpath),
"Expected resource_name with string expression to respond to #xpath"
end
it "new-style notifications" do
assert api.notifications(parse_ast(%q{
template "/etc/foo.conf" do
notifies :create, "template[/etc/bar/#{resource}.bar]"
end
})).first[:resource_name].respond_to?(:xpath),
"Expected resource_name with string expression to respond to #xpath"
end
it "new-style notifications - complete resource_name" do
assert api.notifications(parse_ast(%q{
template "/etc/foo.conf" do
notifies :create, "template[#{template_path}]"
end
})).first[:resource_name].respond_to?(:xpath),
"Expected resource_name with string expression to respond to #xpath"
end
end
describe "returns the AST for node attribute" do
it "old-style notifications" do
assert api.notifications(parse_ast(%q{
template "/etc/foo.conf" do
notifies :restart, resources(:service => node['foo']['service'])
end
})).first[:resource_name].respond_to?(:xpath),
"Expected resource_name with node attribute to respond to #xpath"
end
it "new-style notifications" do
assert api.notifications(parse_ast(%q{
template "/etc/foo.conf" do
notifies :restart, "service[#{node['foo']['service']}]"
end
})).first[:resource_name].respond_to?(:xpath),
"Expected resource_name with node attribute to respond to #xpath"
end
end
describe "returns the AST for variable reference" do
it "old-style notifications" do
assert api.notifications(parse_ast(%q{
template "/etc/foo.conf" do
notifies :restart, resources(:service => my_service)
end
})).first[:resource_name].respond_to?(:xpath),
"Expected resource_name with var ref to respond to #xpath"
end
it "new-style notifications" do
assert api.notifications(parse_ast(%q{
template "/etc/foo.conf" do
notifies :restart, "service[#{my_service}]"
end
})).first[:resource_name].respond_to?(:xpath),
"Expected resource_name with var ref to respond to #xpath"
end
end
end
end

describe "#os_command?" do
Expand Down

0 comments on commit a675a31

Please sign in to comment.