foodcritic 10.2.2 → 10.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (165) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +24 -2
  3. data/Gemfile +2 -1
  4. data/README.md +7 -1
  5. data/Rakefile +55 -35
  6. data/bin/foodcritic +1 -7
  7. data/features/024_check_for_missing_platforms.feature +3 -4
  8. data/features/continuous_integration_support.feature +2 -2
  9. data/features/step_definitions/cookbook_steps.rb +24 -285
  10. data/features/support/command_helpers.rb +3 -0
  11. data/foodcritic.gemspec +12 -6
  12. data/lib/foodcritic/api.rb +14 -2
  13. data/lib/foodcritic/command_line.rb +8 -0
  14. data/lib/foodcritic/linter.rb +1 -1
  15. data/lib/foodcritic/output.rb +17 -3
  16. data/lib/foodcritic/rules/fc008.rb +8 -6
  17. data/lib/foodcritic/rules/fc024.rb +1 -1
  18. data/lib/foodcritic/rules/fc045.rb +1 -8
  19. data/lib/foodcritic/rules/fc068.rb +1 -1
  20. data/lib/foodcritic/rules/fc069.rb +365 -0
  21. data/lib/foodcritic/rules/fc070.rb +63 -0
  22. data/lib/foodcritic/rules/fc071.rb +6 -0
  23. data/lib/foodcritic/rules/fc072.rb +6 -0
  24. data/lib/foodcritic/rules/fc073.rb +17 -0
  25. data/lib/foodcritic/rules/fc074.rb +10 -0
  26. data/lib/foodcritic/rules/fc075.rb +9 -0
  27. data/lib/foodcritic/version.rb +1 -1
  28. data/spec/functional/fc001_spec.rb +67 -0
  29. data/spec/functional/fc008_spec.rb +33 -0
  30. data/spec/functional/fc011_spec.rb +20 -0
  31. data/spec/functional/fc012_spec.rb +20 -0
  32. data/spec/functional/fc016_spec.rb +48 -0
  33. data/spec/functional/fc028_spec.rb +48 -0
  34. data/spec/functional/fc029_spec.rb +33 -0
  35. data/spec/functional/fc031_spec.rb +14 -0
  36. data/spec/functional/fc042_spec.rb +13 -0
  37. data/spec/functional/fc045_spec.rb +18 -0
  38. data/spec/functional/fc052_spec.rb +13 -0
  39. data/spec/functional/fc053_spec.rb +13 -0
  40. data/spec/functional/fc055_spec.rb +18 -0
  41. data/spec/functional/fc056_spec.rb +18 -0
  42. data/spec/functional/fc061_spec.rb +48 -0
  43. data/spec/functional/fc062_spec.rb +13 -0
  44. data/spec/functional/fc063_spec.rb +18 -0
  45. data/spec/functional/fc064_spec.rb +13 -0
  46. data/spec/functional/fc065_spec.rb +13 -0
  47. data/spec/functional/fc066_spec.rb +13 -0
  48. data/spec/functional/fc067_spec.rb +13 -0
  49. data/spec/functional/fc068_spec.rb +13 -0
  50. data/spec/functional/fc069_spec.rb +23 -0
  51. data/spec/functional/fc070_spec.rb +38 -0
  52. data/spec/functional/fc071_spec.rb +14 -0
  53. data/spec/functional/fc072_spec.rb +13 -0
  54. data/spec/functional/fc073_spec.rb +56 -0
  55. data/spec/functional/fc074_spec.rb +39 -0
  56. data/spec/functional/fc075_spec.rb +41 -0
  57. data/spec/functional/root_aliases_spec.rb +13 -0
  58. data/spec/regression/cookbooks.txt +0 -2
  59. data/spec/regression/expected/activemq.txt +5 -0
  60. data/spec/regression/expected/apparmor.txt +8 -0
  61. data/spec/regression/expected/apt.txt +12 -0
  62. data/spec/regression/expected/aws.txt +13 -0
  63. data/spec/regression/expected/bluepill.txt +6 -0
  64. data/spec/regression/expected/boost.txt +6 -0
  65. data/spec/regression/expected/build-essential.txt +6 -0
  66. data/spec/regression/expected/chef-client.txt +13 -0
  67. data/spec/regression/expected/chef-server.txt +12 -0
  68. data/spec/regression/expected/chef.txt +36 -0
  69. data/spec/regression/expected/chef_handler.txt +7 -0
  70. data/spec/regression/expected/cron.txt +7 -0
  71. data/spec/regression/expected/database.txt +13 -0
  72. data/spec/regression/expected/dmg.txt +12 -0
  73. data/spec/regression/expected/drbd.txt +25 -0
  74. data/spec/regression/expected/dynect.txt +29 -0
  75. data/spec/regression/expected/erlang.txt +4 -0
  76. data/spec/regression/expected/fail2ban.txt +4 -0
  77. data/spec/regression/expected/firewall.txt +12 -0
  78. data/spec/regression/expected/gecode.txt +8 -0
  79. data/spec/regression/expected/gems.txt +31 -0
  80. data/spec/regression/expected/gunicorn.txt +9 -0
  81. data/spec/regression/expected/heartbeat.txt +8 -0
  82. data/spec/regression/expected/homebrew.txt +8 -0
  83. data/spec/regression/expected/iis.txt +30 -0
  84. data/spec/regression/expected/iptables.txt +8 -0
  85. data/spec/regression/expected/jetty.txt +11 -0
  86. data/spec/regression/expected/jpackage.txt +8 -0
  87. data/spec/regression/expected/keepalived.txt +4 -0
  88. data/spec/regression/expected/kickstart.txt +14 -0
  89. data/spec/regression/expected/logwatch.txt +4 -0
  90. data/spec/regression/expected/lvm.txt +12 -0
  91. data/spec/regression/expected/maradns.txt +13 -0
  92. data/spec/regression/expected/maven.txt +9 -0
  93. data/spec/regression/expected/memcached.txt +30 -0
  94. data/spec/regression/expected/motd-tail.txt +4 -0
  95. data/spec/regression/expected/mysql.txt +12 -0
  96. data/spec/regression/expected/ohai.txt +6 -0
  97. data/spec/regression/expected/openldap.txt +10 -0
  98. data/spec/regression/expected/openssh.txt +4 -0
  99. data/spec/regression/expected/openssl.txt +5 -0
  100. data/spec/regression/expected/partial_search.txt +5 -0
  101. data/spec/regression/expected/passenger_apache2.txt +29 -0
  102. data/spec/regression/expected/perl.txt +11 -0
  103. data/spec/regression/expected/php.txt +9 -0
  104. data/spec/regression/expected/postfix.txt +6 -0
  105. data/spec/regression/expected/powershell.txt +8 -0
  106. data/spec/regression/expected/resolver.txt +6 -0
  107. data/spec/regression/expected/rsync.txt +10 -0
  108. data/spec/regression/expected/rsyslog.txt +8 -0
  109. data/spec/regression/expected/sql_server.txt +4 -0
  110. data/spec/regression/expected/sqlite.txt +4 -0
  111. data/spec/regression/expected/ssh_known_hosts.txt +5 -0
  112. data/spec/regression/expected/stompserver.txt +5 -0
  113. data/spec/regression/expected/subversion.txt +5 -0
  114. data/spec/regression/expected/sudo.txt +8 -0
  115. data/spec/regression/expected/tftp.txt +5 -0
  116. data/spec/regression/expected/tomcat.txt +8 -0
  117. data/spec/regression/expected/transmission.txt +10 -0
  118. data/spec/regression/expected/ubuntu.txt +4 -0
  119. data/spec/regression/expected/ufw.txt +9 -0
  120. data/spec/regression/expected/unicorn.txt +6 -0
  121. data/spec/regression/expected/users.txt +7 -0
  122. data/spec/regression/expected/vim.txt +6 -0
  123. data/spec/regression/expected/webpi.txt +7 -0
  124. data/spec/regression/expected/whitelist-node-attrs.txt +6 -0
  125. data/spec/regression/expected/windows.txt +57 -0
  126. data/spec/regression/expected/wix.txt +4 -0
  127. data/spec/regression/expected/xfs.txt +4 -0
  128. data/spec/regression/expected/xml.txt +4 -0
  129. data/spec/regression/expected/yum.txt +17 -0
  130. data/spec/regression/expected/zlib.txt +4 -0
  131. data/spec/regression/expected/zsh.txt +4 -0
  132. data/spec/regression/regression_spec.rb +16 -10
  133. data/spec/spec_helper.rb +115 -10
  134. data/spec/{foodcritic → unit}/api_spec.rb +549 -593
  135. data/spec/{foodcritic → unit}/chef_spec.rb +15 -15
  136. data/spec/unit/command_line_spec.rb +122 -0
  137. data/spec/{foodcritic → unit}/domain_spec.rb +12 -12
  138. data/spec/{foodcritic → unit}/linter_spec.rb +20 -35
  139. data/spec/{foodcritic → unit}/template_spec.rb +13 -13
  140. metadata +161 -33
  141. data/features/001_check_node_access.feature +0 -60
  142. data/features/008_check_for_boilerplate_metadata.feature +0 -25
  143. data/features/011_check_for_markdown_readme.feature +0 -20
  144. data/features/012_check_for_deprecated_readme_format.feature +0 -20
  145. data/features/016_check_for_no_lwrp_default_action.feature +0 -25
  146. data/features/028_check_for_incorrect_platform_method.feature +0 -20
  147. data/features/029_check_for_no_leading_cookbook_name.feature +0 -18
  148. data/features/031_check_for_metadata_existence.feature +0 -15
  149. data/features/042_check_for_deprecated_require_recipe.feature +0 -15
  150. data/features/045_check_for_cookbook_name_in_metadata.feature +0 -20
  151. data/features/052_check_for_metadata_using_suggests_keyword.feature +0 -15
  152. data/features/053_check_for_metadata_using_recommends_keyword.feature +0 -15
  153. data/features/055_check_for_no_maintainer.feature +0 -25
  154. data/features/056_check_for_no_maintainer_email.feature +0 -25
  155. data/features/061_valid_cookbook_version_should_be_defined.feature +0 -55
  156. data/features/062_cookbook_should_have_cookbook_version.feature +0 -50
  157. data/features/063_cookbook_incorrectly_depends_on_itself.feature +0 -15
  158. data/features/064_check_for_no_issues_url.feature +0 -25
  159. data/features/065_check_for_no_source_url.feature +0 -25
  160. data/features/066_check_for_no_chef_version_metadata.feature +0 -20
  161. data/features/067_check_for_no_supports_metadata.feature +0 -20
  162. data/features/068_check_for_no_license_metadata.feature +0 -20
  163. data/spec/foodcritic/command_line_spec.rb +0 -74
  164. data/spec/regression/expected-output.txt +0 -355
  165. data/spec/regression_helpers.rb +0 -37
@@ -0,0 +1,4 @@
1
+ FC064: Ensure issues_url is set in metadata: ./metadata.rb:1
2
+ FC065: Ensure source_url is set in metadata: ./metadata.rb:1
3
+ FC066: Ensure chef_version is set in metadata: ./metadata.rb:1
4
+ FC069: Ensure standardized license defined in metadata: ./metadata.rb:1
@@ -0,0 +1,4 @@
1
+ FC064: Ensure issues_url is set in metadata: ./metadata.rb:1
2
+ FC065: Ensure source_url is set in metadata: ./metadata.rb:1
3
+ FC066: Ensure chef_version is set in metadata: ./metadata.rb:1
4
+ FC069: Ensure standardized license defined in metadata: ./metadata.rb:1
@@ -0,0 +1,4 @@
1
+ FC064: Ensure issues_url is set in metadata: ./metadata.rb:1
2
+ FC065: Ensure source_url is set in metadata: ./metadata.rb:1
3
+ FC066: Ensure chef_version is set in metadata: ./metadata.rb:1
4
+ FC069: Ensure standardized license defined in metadata: ./metadata.rb:1
@@ -0,0 +1,17 @@
1
+ FC009: Resource attribute not recognised: ./recipes/epel.rb:27
2
+ FC017: LWRP does not notify when updated: ./providers/key.rb:25
3
+ FC017: LWRP does not notify when updated: ./providers/repository.rb:28
4
+ FC017: LWRP does not notify when updated: ./providers/repository.rb:45
5
+ FC038: Invalid resource action: ./recipes/epel.rb:27
6
+ FC043: Prefer new notification syntax: ./providers/key.rb:60
7
+ FC043: Prefer new notification syntax: ./providers/repository.rb:94
8
+ FC059: LWRP provider does not declare use_inline_resources: ./providers/key.rb:1
9
+ FC059: LWRP provider does not declare use_inline_resources: ./providers/repository.rb:1
10
+ FC064: Ensure issues_url is set in metadata: ./metadata.rb:1
11
+ FC065: Ensure source_url is set in metadata: ./metadata.rb:1
12
+ FC066: Ensure chef_version is set in metadata: ./metadata.rb:1
13
+ FC069: Ensure standardized license defined in metadata: ./metadata.rb:1
14
+ FC070: Ensure supports metadata defines valid platforms: ./metadata.rb:1
15
+ FC072: Metadata should not contain "attribute" keyword: ./metadata.rb:1
16
+ FC074: LWRP should use DSL to define resource's default action: ./resources/key.rb:1
17
+ FC074: LWRP should use DSL to define resource's default action: ./resources/repository.rb:1
@@ -0,0 +1,4 @@
1
+ FC064: Ensure issues_url is set in metadata: ./metadata.rb:1
2
+ FC065: Ensure source_url is set in metadata: ./metadata.rb:1
3
+ FC066: Ensure chef_version is set in metadata: ./metadata.rb:1
4
+ FC069: Ensure standardized license defined in metadata: ./metadata.rb:1
@@ -0,0 +1,4 @@
1
+ FC064: Ensure issues_url is set in metadata: ./metadata.rb:1
2
+ FC065: Ensure source_url is set in metadata: ./metadata.rb:1
3
+ FC066: Ensure chef_version is set in metadata: ./metadata.rb:1
4
+ FC069: Ensure standardized license defined in metadata: ./metadata.rb:1
@@ -1,17 +1,23 @@
1
- require_relative "../regression_helpers"
1
+ require "spec_helper"
2
2
 
3
3
  describe "regression test" do
4
+ command("#{File.expand_path("../../../bin/foodcritic", __FILE__)} .", allow_error: true)
4
5
 
5
- let(:expected_lint_output) do
6
- File.read("spec/regression/expected-output.txt")
7
- end
6
+ IO.readlines(File.expand_path("../cookbooks.txt", __FILE__)).each do |line|
7
+ name, ref = line.strip.split(":")
8
8
 
9
- let(:actual_lint_output) do
10
- lint_regression_cookbooks
11
- end
9
+ context "with cookbook #{name}" do
10
+ before do
11
+ command("git clone -q https://github.com/chef-cookbooks/#{name}.git .")
12
+ command("git checkout -q #{ref}")
13
+ end
12
14
 
13
- it "should result in the expected matches against a pinned set of cookbooks" do
14
- actual_lint_output.must_equal expected_lint_output
15
+ it "should match expected output" do
16
+ expected_output = IO.readlines(File.expand_path("../expected/#{name}.txt", __FILE__))
17
+ expected_output.each do |expected_line|
18
+ expect(subject.stdout).to include expected_line
19
+ end
20
+ end
21
+ end
15
22
  end
16
-
17
23
  end
data/spec/spec_helper.rb CHANGED
@@ -1,15 +1,120 @@
1
- begin
2
- require "simplecov"
3
- SimpleCov.start do
4
- add_filter "/spec/"
1
+ require "shellwords"
2
+
3
+ require "rspec_command"
4
+ require "simplecov"
5
+
6
+ SimpleCov.start do
7
+ add_filter "/spec/"
8
+ end
9
+
10
+ module FunctionalHelpers
11
+ extend RSpec::Matchers::DSL
12
+
13
+ matcher :violate_rule do |rule_id = nil|
14
+ match do |cmd|
15
+ if location
16
+ cmd.stdout =~ /^#{expected}:.*: \.\/#{location}/
17
+ else
18
+ cmd.stdout =~ /^#{expected}:/
19
+ end
20
+ end
21
+ chain :in, :location
22
+ failure_message do |cmd|
23
+ "expected a violation of rule #{expected}#{location && " in #{location}"}, output was:\n#{cmd.stdout}"
24
+ end
25
+ failure_message_when_negated do |cmd|
26
+ "expected no violation of rule #{expected}#{location && " in #{location}"}, output was:\n#{cmd.stdout}"
27
+ end
28
+ # Override the default behavior from RSpec for the expected value, use
29
+ # define_method insetad of def so we can see the _rule_id variable in closure.
30
+ define_method(:expected) do
31
+ # Fill in the top-level example group description as the rule ID if not specified.
32
+ rule_id || method_missing(:class).parent_groups.last.description
33
+ end
34
+ end
35
+
36
+ def foodcritic_command(*args)
37
+ output = StringIO.new
38
+ error = StringIO.new
39
+ begin
40
+ # Don't use the block form of chdir because for some reason it can't be
41
+ # nested.
42
+ cwd = Dir.pwd
43
+ Dir.chdir(temp_path)
44
+ $stderr = error
45
+ exitstatus = FoodCritic::CommandLine.main(args, output)
46
+ ensure
47
+ $stderr = STDERR
48
+ Dir.chdir(cwd)
49
+ end
50
+ RSpecCommand::OutputString.new(output.string, error.string).tap do |out|
51
+ out.define_singleton_method(:exitstatus) { exitstatus }
52
+ end
5
53
  end
6
- rescue LoadError
7
- warn "warning: simplecov gem not found; skipping coverage"
54
+
55
+ module ClassMethods
56
+ def foodcritic_command(*args)
57
+ metadata[:foodcritic_command] = true
58
+ subject do |example|
59
+ foodcritic_command(*args)
60
+ end
61
+ end
62
+
63
+ def attributes_file(*args, &block)
64
+ file("attributes/default.rb", *args, &block)
65
+ end
66
+
67
+ def resource_file(*args, &block)
68
+ file("resources/my_resource.rb", *args, &block)
69
+ end
70
+
71
+ def library_file(*args, &block)
72
+ file("libraries/helper.rb", *args, &block)
73
+ end
74
+
75
+ def recipe_file(*args, &block)
76
+ file("recipes/default.rb", *args, &block)
77
+ end
78
+
79
+ def metadata_file(*args, &block)
80
+ file("metadata.rb", *args, &block)
81
+ end
82
+
83
+ def included(klass)
84
+ super
85
+ klass.extend ClassMethods
86
+ # Set a default subject command, can be overridden if needed.
87
+ klass.foodcritic_command("--no-progress", ".")
88
+ end
89
+ end
90
+
91
+ extend ClassMethods
8
92
  end
9
93
 
10
- require "minitest/spec"
11
- require "minitest/autorun"
12
- require "minitest/reporters"
13
- MiniTest::Reporters.use!
94
+ RSpec.configure do |config|
95
+ # Basic configuraiton
96
+ config.run_all_when_everything_filtered = true
97
+ config.filter_run(:focus) unless ENV["CI"]
98
+
99
+ # Run specs in random order to surface order dependencies. If you find an
100
+ # order dependency and want to debug it, you can fix the order by providing
101
+ # the seed, which is printed after each run.
102
+ # --seed 1234
103
+ config.order = "random"
104
+
105
+ # Set some metadata based on test folders.
106
+ config.define_derived_metadata(file_path: %r{spec/unit}) do |metadata|
107
+ metadata[:unit] = true
108
+ end
109
+ config.define_derived_metadata(file_path: %r{spec/functional}) do |metadata|
110
+ metadata[:functional] = true
111
+ end
112
+ config.define_derived_metadata(file_path: %r{spec/regression}) do |metadata|
113
+ metadata[:regression] = true
114
+ end
115
+
116
+ config.include RSpecCommand
117
+ config.include FunctionalHelpers, functional: true
118
+ end
14
119
 
15
120
  require_relative "../lib/foodcritic"
@@ -1,4 +1,4 @@
1
- require_relative "../spec_helper"
1
+ require "spec_helper"
2
2
 
3
3
  describe FoodCritic::Api do
4
4
 
@@ -13,7 +13,7 @@ describe FoodCritic::Api do
13
13
  api.class.ancestors.map { |a| a.public_methods }.flatten.sort.uniq
14
14
  end
15
15
  it "exposes the expected api to rule authors" do
16
- (api.public_methods.sort - ignorable_methods).must_equal([
16
+ expect(api.public_methods.sort - ignorable_methods).to eq [
17
17
  :attribute_access,
18
18
  :checks_for_chef_solo?,
19
19
  :chef_dsl_methods,
@@ -24,6 +24,7 @@ describe FoodCritic::Api do
24
24
  :cookbook_maintainer_email,
25
25
  :cookbook_name,
26
26
  :declared_dependencies,
27
+ :ensure_file_exists,
27
28
  :field,
28
29
  :field_value,
29
30
  :file_match,
@@ -51,295 +52,271 @@ describe FoodCritic::Api do
51
52
  :template_paths,
52
53
  :templates_included,
53
54
  :valid_query?,
54
- ])
55
+ ]
55
56
  end
56
57
  end
57
58
 
58
59
  describe "#attribute_access" do
59
- let(:ast) { MiniTest::Mock.new }
60
+ let(:ast) { double() }
60
61
  it "returns empty if the provided ast does not support XPath" do
61
- api.attribute_access(nil, :type => :vivified).must_be_empty
62
+ expect(api.attribute_access(nil, :type => :vivified)).to be_empty
62
63
  end
63
64
  it "returns empty if the provided ast has no matches" do
64
- ast.expect :xpath, [], [String]
65
+ expect(ast).to receive(:xpath).with(kind_of(String), kind_of(FoodCritic::Api::AttFilter)).and_return([]).exactly(3).times
65
66
  [:vivified, :string, :symbol].each do |access_type|
66
- api.attribute_access([], :type => :vivified).must_be_empty
67
+ expect(api.attribute_access(ast, :type => access_type)).to be_empty
67
68
  end
68
69
  end
69
70
  it "raises if the specified node type is not recognised" do
70
- ast.expect :xpath, [], [String]
71
- lambda do
72
- api.attribute_access(ast, :type => :cymbals)
73
- end.must_raise(ArgumentError)
71
+ allow(ast).to receive(:xpath)
72
+ expect { api.attribute_access(ast, :type => :cymbals) }.to raise_error ArgumentError
74
73
  end
75
74
  it "does not raise if the specified node type is valid" do
76
- ast.expect :xpath, [], [/field/, FoodCritic::Api::AttFilter]
77
- ast.expect :xpath, [], [/symbol/, FoodCritic::Api::AttFilter]
78
- ast.expect :xpath, [], [/tstring_content/, FoodCritic::Api::AttFilter]
75
+ expect(ast).to receive(:xpath).with(/field/, FoodCritic::Api::AttFilter).and_return([])
76
+ expect(ast).to receive(:xpath).with(/symbol/, FoodCritic::Api::AttFilter).and_return([])
77
+ expect(ast).to receive(:xpath).with(/tstring_content/, FoodCritic::Api::AttFilter).and_return([])
79
78
  [:vivified, :symbol, :string].each do |access_type|
80
79
  api.attribute_access(ast, :type => access_type)
81
80
  end
82
81
  end
83
82
  it "returns vivified attributes access" do
84
- call = MiniTest::Mock.new
85
- call.expect :xpath, [], [/args_add_block/]
86
- call.expect :xpath, %w{node bar}, [/ident/]
87
- call.expect :xpath, ["foo"], [/@value/]
88
- ast.expect :xpath, [call], [String, FoodCritic::Api::AttFilter]
89
- api.attribute_access(ast, :type => :vivified).must_equal([call])
90
- ast.verify
91
- call.verify
83
+ call = double()
84
+ expect(call).to receive(:xpath).with(/args_add_block/).and_return([])
85
+ expect(call).to receive(:xpath).with(/ident/).and_return(%w{node bar})
86
+ expect(call).to receive(:xpath).with(/@value/).and_return("foo")
87
+ expect(ast).to receive(:xpath).with(kind_of(String), kind_of(FoodCritic::Api::AttFilter)).and_return([call])
88
+ expect(api.attribute_access(ast, :type => :vivified)).to eq [call]
92
89
  end
93
90
  it "doesn't flag searching for a node by name as symbol access" do
94
91
  ast = parse_ast(%q{baz = search(:node, "name:#{node['foo']['bar']}")[0]})
95
- api.attribute_access(ast, :type => :symbol).must_be_empty
92
+ expect(api.attribute_access(ast, :type => :symbol)).to be_empty
96
93
  end
97
94
  describe :ignoring_attributes do
98
95
  it "doesn't ignore run_state by default for backwards compatibility" do
99
96
  ast = parse_ast("node.run_state['bar'] = 'baz'")
100
- api.attribute_access(ast).wont_be_empty
97
+ expect(api.attribute_access(ast)).to_not be_empty
101
98
  end
102
99
  it "allows run_state to be ignored" do
103
100
  ast = parse_ast("node.run_state['bar'] = 'baz'")
104
- api.attribute_access(ast, :ignore => ["run_state"]).must_be_empty
101
+ expect(api.attribute_access(ast, :ignore => ["run_state"])).to be_empty
105
102
  end
106
103
  it "allows run_state to be ignored (symbols access)" do
107
104
  ast = parse_ast("node.run_state[:bar] = 'baz'")
108
- api.attribute_access(ast, :ignore => ["run_state"]).must_be_empty
105
+ expect(api.attribute_access(ast, :ignore => ["run_state"])).to be_empty
109
106
  end
110
107
  it "allows any attribute to be ignored" do
111
108
  ast = parse_ast("node['bar'] = 'baz'")
112
- api.attribute_access(ast, :ignore => ["bar"]).must_be_empty
109
+ expect(api.attribute_access(ast, :ignore => ["bar"])).to be_empty
113
110
  end
114
111
  it "allows any attribute to be ignored (symbols access)" do
115
112
  ast = parse_ast("node[:bar] = 'baz'")
116
- api.attribute_access(ast, :ignore => ["bar"]).must_be_empty
113
+ expect(api.attribute_access(ast, :ignore => ["bar"])).to be_empty
117
114
  end
118
115
  it "allows any attribute to be ignored (dot access)" do
119
116
  ast = parse_ast("node.bar = 'baz'")
120
- api.attribute_access(ast, :ignore => ["bar"]).must_be_empty
117
+ expect(api.attribute_access(ast, :ignore => ["bar"])).to be_empty
121
118
  end
122
119
  it "includes the children of attributes" do
123
120
  ast = parse_ast("node['foo']['bar'] = 'baz'")
124
- api.attribute_access(ast).map { |a| a["value"] }.must_equal(%w{foo bar})
121
+ expect(api.attribute_access(ast).map { |a| a["value"] }).to eq %w{foo bar}
125
122
  end
126
123
  it "does not include children of removed attributes" do
127
124
  ast = parse_ast("node['foo']['bar'] = 'baz'")
128
- api.attribute_access(ast, :ignore => ["foo"]).must_be_empty
125
+ expect(api.attribute_access(ast, :ignore => ["foo"])).to be_empty
129
126
  end
130
127
  it "coerces ignore values to enumerate them" do
131
128
  ast = parse_ast("node.run_state['bar'] = 'baz'")
132
- api.attribute_access(ast, :ignore => "run_state").must_be_empty
129
+ expect(api.attribute_access(ast, :ignore => "run_state")).to be_empty
133
130
  end
134
131
  it "can ignore multiple attributes" do
135
132
  ast = parse_ast(%q{
136
133
  node['bar'] = 'baz'
137
134
  node.foo = 'baz'
138
135
  })
139
- api.attribute_access(ast, :ignore => %w{foo bar}).must_be_empty
136
+ expect(api.attribute_access(ast, :ignore => %w{foo bar})).to be_empty
140
137
  end
141
138
  end
142
139
  end
143
140
 
144
141
  describe "#checks_for_chef_solo?" do
145
- let(:ast) { MiniTest::Mock.new }
142
+ let(:ast) { double() }
143
+ around do |ex|
144
+ begin
145
+ $stderr = StringIO.new
146
+ ex.run
147
+ ensure
148
+ $stderr = STDERR
149
+ end
150
+ end
146
151
  it "raises if the provided ast does not support XPath" do
147
- lambda { api.checks_for_chef_solo?(nil) }.must_raise(ArgumentError)
152
+ expect { api.checks_for_chef_solo?(nil) }.to raise_error ArgumentError
148
153
  end
149
154
  it "returns false if there is no reference to chef solo" do
150
- ast.expect :xpath, [], [String]
151
- ast.expect :xpath, [], [String]
152
- refute api.checks_for_chef_solo?(ast)
155
+ expect(ast).to receive(:xpath).with(kind_of(String)).and_return([]).twice
156
+ expect(api.checks_for_chef_solo?(ast)).to be_falsey
153
157
  end
154
158
  it "returns true if there is one reference to chef solo" do
155
- ast.expect :xpath, ["aref"], [String]
156
- assert api.checks_for_chef_solo?(ast)
159
+ expect(ast).to receive(:xpath).with(kind_of(String)).and_return(["aref"])
160
+ expect(api.checks_for_chef_solo?(ast)).to be_truthy
157
161
  end
158
162
  it "returns true if there are multiple references to chef solo" do
159
- ast.expect :xpath, %w{aref aref}, [String]
160
- assert api.checks_for_chef_solo?(ast)
163
+ expect(ast).to receive(:xpath).with(kind_of(String)).and_return(%w{aref aref})
164
+ expect(api.checks_for_chef_solo?(ast)).to be_truthy
161
165
  end
162
166
  end
163
167
 
164
168
  describe "#chef_solo_search_supported?" do
169
+ around do |ex|
170
+ begin
171
+ $stderr = StringIO.new
172
+ ex.run
173
+ ensure
174
+ $stderr = STDERR
175
+ end
176
+ end
165
177
  it "returns false if the recipe path is nil" do
166
- refute api.chef_solo_search_supported?(nil)
178
+ expect(api.chef_solo_search_supported?(nil)).to be_falsey
167
179
  end
168
180
  it "returns false if the recipe path does not exist" do
169
- refute api.chef_solo_search_supported?("/tmp/non-existent-path")
181
+ expect(api.chef_solo_search_supported?("/tmp/non-existent-path")).to be_falsey
170
182
  end
171
183
  end
172
184
 
173
185
  describe "#metadata_field" do
174
- # TODO we should do this with a double instead
175
- # but this is the accepted pattern so far so...
176
- def mock_cookbook(metadata_path)
177
- dir = File.dirname(metadata_path)
178
- unless File.directory?(dir)
179
- FileUtils.mkdir_p(dir)
180
- end
181
- File.open(metadata_path, "w") { |file| file.write('name "YOUR_COOKBOOK_NAME"') }
182
- FileUtils.mkdir_p(File.join(dir, "templates/defaults"))
183
- File.open(File.join(dir, "templates", "defaults", "test.erb"), "w") { |file| file.write("Some erb") }
184
- end
186
+ file "metadata.rb", 'name "YOUR_COOKBOOK_NAME"'
185
187
 
186
188
  it "returns the 'name' value when passed a metadata file and the name field" do
187
- mock_cookbook("/tmp/fc/mock/cb/metadata.rb")
188
- api.metadata_field("/tmp/fc/mock/cb/", "name").must_equal "YOUR_COOKBOOK_NAME"
189
+ expect(api.metadata_field(temp_path, "name")).to eq "YOUR_COOKBOOK_NAME"
189
190
  end
190
191
 
191
192
  it "it raises if a invalid field is requested" do
192
- lambda { api.metadata_field("/tmp/fc/mock/cb/", "bogus_field") }.must_raise RuntimeError
193
+ expect { api.metadata_field(temp_path, "bogus_field") }.to raise_error RuntimeError
193
194
  end
194
195
 
195
196
  it "it raises if a invalid file is requested" do
196
- lambda { api.metadata_field("/tmp/some/bogus/cookbook/path", "name") }.must_raise RuntimeError
197
+ expect { api.metadata_field("/invalid", "name") }.to raise_error RuntimeError
197
198
  end
198
199
  end
199
200
 
200
201
  describe "#cookbook_base_path" do
201
- # TODO we should do this with a mock instead
202
- # but this is the accepted pattern so far so...
203
- def mock_cookbook(metadata_path)
204
- dir = File.dirname(metadata_path)
205
- unless File.directory?(dir)
206
- FileUtils.mkdir_p(dir)
202
+ file "templates/defaults/test.erb"
203
+
204
+ context "with a metadata.rb" do
205
+ file "metadata.rb"
206
+
207
+ it "returns the cookbook dir when passed the path itself" do
208
+ expect(api.cookbook_base_path(temp_path)).to eq temp_path
207
209
  end
208
- File.open(metadata_path, "w") { |file| file.write('name "YOUR_COOKBOOK_NAME"') }
209
- FileUtils.mkdir_p(File.join(dir, "templates/defaults"))
210
- File.open(File.join(dir, "templates", "defaults", "test.erb"), "w") { |file| file.write("Some erb") }
211
- end
212
210
 
213
- it "returns the cookbook dir when passed the path itself" do
214
- mock_cookbook("/tmp/fc/mock/cb/metadata.rb")
215
- api.cookbook_base_path("/tmp/fc/mock/cb/").must_equal "/tmp/fc/mock/cb"
211
+ it "returns the cookbook dir when passed a nested directory" do
212
+ expect(api.cookbook_base_path("#{temp_path}/templates/defaults/test.erb")).to eq temp_path
213
+ end
216
214
  end
217
215
 
218
- it "returns the cookbook dir when passed a nested directory" do
219
- mock_cookbook("/tmp/fc/mock/cb/metadata.rb")
220
- api.cookbook_base_path("/tmp/fc/mock/cb/templates/defaults/test.erb").must_equal "/tmp/fc/mock/cb"
221
- end
216
+ context "with a metadata.json" do
217
+ file "metadata.json"
222
218
 
223
- it "returns the cookbook dir when path contains cookbook like names" do
224
- mock_cookbook("/tmp/fc/mock/resources/cb/metadata.rb")
225
- api.cookbook_base_path("/tmp/fc/mock/resources/cb/templates/defaults/test.erb").must_equal "/tmp/fc/mock/resources/cb"
226
- end
219
+ it "returns the cookbook dir when passed the path itself" do
220
+ expect(api.cookbook_base_path(temp_path)).to eq temp_path
221
+ end
227
222
 
228
- it "returns the cookbook dir when path has a metadata.json not metadata.rb" do
229
- mock_cookbook("/tmp/fc/mock/cb/metadata.json")
230
- api.cookbook_base_path("/tmp/fc/mock/cb/templates/defaults/test.erb").must_equal "/tmp/fc/mock/cb"
223
+ it "returns the cookbook dir when passed a nested directory" do
224
+ expect(api.cookbook_base_path("#{temp_path}/templates/defaults/test.erb")).to eq temp_path
225
+ end
231
226
  end
232
- end
233
227
 
234
- describe "#cookbook_name" do
235
- def mock_cookbook_metadata(f)
236
- dir = File.dirname(f)
237
- unless File.directory?(dir)
238
- FileUtils.mkdir_p(dir)
228
+ context "with complex nested folders with metadata.rb" do
229
+ file "metadata.rb"
230
+ file "templates/metadata.rb"
231
+
232
+ it "returns the cookbook dir when path contains cookbook like names" do
233
+ expect(api.cookbook_base_path("#{temp_path}/templates/defaults/test.erb")).to eq "#{temp_path}/templates"
239
234
  end
240
- File.open(f, "w") { |file| file.write('name "YOUR_COOKBOOK_NAME"') }
241
235
  end
236
+ end
242
237
 
243
- metadata_path = "/tmp/fc/mock/cb/metadata.rb"
238
+ describe "#cookbook_name" do
244
239
  it "raises if passed a nil" do
245
- lambda { api.cookbook_name(nil) }.must_raise ArgumentError
240
+ expect { api.cookbook_name(nil) }.to raise_error ArgumentError
246
241
  end
247
242
  it "raises if passed an empty string" do
248
- lambda { api.cookbook_name("") }.must_raise ArgumentError
243
+ expect { api.cookbook_name("") }.to raise_error ArgumentError
249
244
  end
250
245
  it "returns the cookbook name when passed a recipe" do
251
246
  recipe_path = "cookbooks/apache2/recipes/default.rb"
252
- api.cookbook_name(recipe_path).must_equal "apache2"
247
+ expect(api.cookbook_name(recipe_path)).to eq "apache2"
253
248
  end
254
249
  it "returns the cookbook name when passed the cookbook metadata" do
255
- api.cookbook_name("cookbooks/apache2/metadata.rb").must_equal "apache2"
250
+ expect(api.cookbook_name("cookbooks/apache2/metadata.rb")).to eq "apache2"
256
251
  end
257
252
  it "returns the cookbook name when passed a template" do
258
253
  erb_path = "cookbooks/apache2/templates/default/a2ensite.erb"
259
- api.cookbook_name(erb_path).must_equal "apache2"
254
+ expect(api.cookbook_name(erb_path)).to eq "apache2"
260
255
  end
261
- it "returns the cookbook name when passed the cookbook metadata with a name field" do
262
- mock_cookbook_metadata(metadata_path)
263
- api.cookbook_name(metadata_path).must_equal "YOUR_COOKBOOK_NAME"
256
+ context "with a metadata.rb" do
257
+ file "metadata.rb", 'name "YOUR_COOKBOOK_NAME"'
258
+ it "returns the cookbook name when passed the cookbook metadata with a name field" do
259
+ expect(api.cookbook_name(temp_path)).to eq "YOUR_COOKBOOK_NAME"
260
+ end
264
261
  end
265
262
  end
266
263
 
267
264
  describe "#cookbook_maintainer" do
268
- def mock_cookbook_metadata(f)
269
- dir = File.dirname(f)
270
- unless File.directory?(dir)
271
- FileUtils.mkdir_p(dir)
272
- end
273
- File.open(f, "w") { |file| file.write('maintainer "YOUR_COMPANY_NAME"') }
274
- end
275
-
276
- metadata_path = "/tmp/fc/mock/cb/metadata.rb"
277
265
  it "raises if passed a nil" do
278
- lambda { api.cookbook_maintainer(nil) }.must_raise ArgumentError
266
+ expect { api.cookbook_maintainer(nil) }.to raise_error ArgumentError
279
267
  end
280
268
  it "raises if passed an empty string" do
281
- lambda { api.cookbook_maintainer("") }.must_raise ArgumentError
269
+ expect { api.cookbook_maintainer("") }.to raise_error ArgumentError
282
270
  end
283
271
  it "raises if the path does not exist" do
284
- lambda { api.cookbook_maintainer("/tmp/non-existent-path") }.must_raise RuntimeError
272
+ expect { api.cookbook_maintainer("/invalid") }.to raise_error RuntimeError
285
273
  end
286
- it "returns the cookbook maintainer when passed the cookbook metadata" do
287
- mock_cookbook_metadata(metadata_path)
288
- api.cookbook_maintainer(metadata_path).must_equal "YOUR_COMPANY_NAME"
289
- end
290
- it "returns the cookbook maintainer when passed a recipe" do
291
- mock_cookbook_metadata(metadata_path)
292
- api.cookbook_maintainer("/tmp/fc/mock/cb/recipes/default.rb").must_equal "YOUR_COMPANY_NAME"
293
- end
294
- it "returns the cookbook maintainer when passed a template" do
295
- mock_cookbook_metadata(metadata_path)
296
- api.cookbook_maintainer("/tmp/fc/mock/cb/templates/default/mock.erb").must_equal "YOUR_COMPANY_NAME"
274
+ context "with a metadata.rb" do
275
+ file "metadata.rb", 'maintainer "YOUR_COMPANY_NAME"'
276
+ it "returns the cookbook maintainer when passed the cookbook metadata" do
277
+ expect(api.cookbook_maintainer(temp_path)).to eq "YOUR_COMPANY_NAME"
278
+ end
279
+ it "returns the cookbook maintainer when passed a recipe" do
280
+ expect(api.cookbook_maintainer("#{temp_path}/recipes/default.rb")).to eq "YOUR_COMPANY_NAME"
281
+ end
282
+ it "returns the cookbook maintainer when passed a template" do
283
+ expect(api.cookbook_maintainer("#{temp_path}/templates/default/mock.erb")).to eq "YOUR_COMPANY_NAME"
284
+ end
297
285
  end
298
286
  end
299
287
 
300
288
  describe "#cookbook_maintainer_email" do
301
- def mock_cookbook_metadata(f)
302
- dir = File.dirname(f)
303
- unless File.directory?(dir)
304
- FileUtils.mkdir_p(dir)
305
- end
306
- File.open(f, "w") { |file| file.write('maintainer_email "YOUR_EMAIL"') }
307
- end
308
-
309
- metadata_path = "/tmp/fc/mock/cb/metadata.rb"
310
289
  it "raises if passed a nil" do
311
- lambda { api.cookbook_maintainer_email(nil) }.must_raise ArgumentError
290
+ expect { api.cookbook_maintainer_email(nil) }.to raise_error ArgumentError
312
291
  end
313
292
  it "raises if passed an empty string" do
314
- lambda { api.cookbook_maintainer_email("") }.must_raise ArgumentError
293
+ expect { api.cookbook_maintainer_email("") }.to raise_error ArgumentError
315
294
  end
316
295
  it "raises if the path does not exist" do
317
- lambda { api.cookbook_maintainer_email("/tmp/non-existent-path") }.must_raise RuntimeError
296
+ expect { api.cookbook_maintainer_email("/invalid") }.to raise_error RuntimeError
318
297
  end
319
- it "returns the cookbook maintainer_email when passed the cookbook metadata" do
320
- mock_cookbook_metadata(metadata_path)
321
- api.cookbook_maintainer_email(metadata_path).must_equal "YOUR_EMAIL"
322
- end
323
- it "returns the cookbook maintainer_email when passed a recipe" do
324
- mock_cookbook_metadata(metadata_path)
325
- api.cookbook_maintainer_email("/tmp/fc/mock/cb/recipes/default.rb").must_equal "YOUR_EMAIL"
326
- end
327
- it "returns the cookbook maintainer_email when passed a template" do
328
- mock_cookbook_metadata(metadata_path)
329
- api.cookbook_maintainer_email("/tmp/fc/mock/cb/templates/default/mock.erb").must_equal "YOUR_EMAIL"
298
+ context "with a metadata.rb" do
299
+ file "metadata.rb", 'maintainer_email "YOUR_EMAIL"'
300
+ it "returns the cookbook maintainer_email when passed the cookbook metadata" do
301
+ expect(api.cookbook_maintainer_email(temp_path)).to eq "YOUR_EMAIL"
302
+ end
303
+ it "returns the cookbook maintainer_email when passed a recipe" do
304
+ expect(api.cookbook_maintainer_email("#{temp_path}/recipes/default.rb")).to eq "YOUR_EMAIL"
305
+ end
306
+ it "returns the cookbook maintainer_email when passed a template" do
307
+ expect(api.cookbook_maintainer_email("#{temp_path}/templates/default/mock.erb")).to eq "YOUR_EMAIL"
308
+ end
330
309
  end
331
310
  end
332
311
 
333
312
  describe "#declared_dependencies" do
334
313
  it "raises if the ast does not support XPath" do
335
- lambda { api.declared_dependencies(nil) }.must_raise ArgumentError
314
+ expect { api.declared_dependencies(nil) }.to raise_error ArgumentError
336
315
  end
337
316
  it "returns an empty if there are no declared dependencies" do
338
- ast = MiniTest::Mock.new
339
- 3.times do
340
- ast.expect :xpath, [], [String]
341
- end
342
- api.declared_dependencies(ast).must_be_empty
317
+ ast = double
318
+ expect(ast).to receive(:xpath).with(kind_of(String)).and_return([]).twice
319
+ expect(api.declared_dependencies(ast)).to be_empty
343
320
  end
344
321
  it "includes only cookbook names in the returned array" do
345
322
  ast = Nokogiri::XML(%q{
@@ -372,7 +349,7 @@ describe FoodCritic::Api do
372
349
  </args_add_block>
373
350
  </command>
374
351
  })
375
- api.declared_dependencies(ast).must_equal ["mysql"]
352
+ expect(api.declared_dependencies(ast)).to eq ["mysql"]
376
353
  end
377
354
  end
378
355
 
@@ -380,39 +357,39 @@ describe FoodCritic::Api do
380
357
  describe :simple_ast do
381
358
  let(:ast) { parse_ast('name "webserver"') }
382
359
  it "raises if the field name is nil" do
383
- lambda { api.field(ast, nil) }.must_raise ArgumentError
360
+ expect { api.field(ast, nil) }.to raise_error ArgumentError
384
361
  end
385
362
  it "raises if the field name is empty" do
386
- lambda { api.field(ast, "") }.must_raise ArgumentError
363
+ expect { api.field(ast, "") }.to raise_error ArgumentError
387
364
  end
388
365
  it "returns empty if the field is not present" do
389
- api.field(ast, :common_name).must_be_empty
366
+ expect(api.field(ast, :common_name)).to be_empty
390
367
  end
391
368
  it "accepts a string for the field name" do
392
- api.field(ast, "name").wont_be_empty
369
+ expect(api.field(ast, "name")).to_not be_empty
393
370
  end
394
371
  it "accepts a symbol for the field name" do
395
- api.field(ast, :name).wont_be_empty
372
+ expect(api.field(ast, :name)).to_not be_empty
396
373
  end
397
374
  end
398
375
  it "returns fields when the value is an embedded string expression" do
399
376
  ast = parse_ast(%q{
400
377
  name "#{foo}_#{bar}"
401
378
  }.strip)
402
- api.field(ast, :name).size.must_equal 1
379
+ expect(api.field(ast, :name).size).to eq 1
403
380
  end
404
381
  it "returns fields when the value is a method call" do
405
382
  ast = parse_ast(%q{
406
383
  name generate_name
407
384
  }.strip)
408
- api.field(ast, :name).size.must_equal 1
385
+ expect(api.field(ast, :name).size).to eq 1
409
386
  end
410
387
  it "returns both fields if the field is specified twice" do
411
388
  ast = parse_ast(%q{
412
389
  name "webserver"
413
390
  name "database"
414
391
  }.strip)
415
- api.field(ast, :name).size.must_equal 2
392
+ expect(api.field(ast, :name).size).to eq 2
416
393
  end
417
394
  end
418
395
 
@@ -420,113 +397,104 @@ describe FoodCritic::Api do
420
397
  describe :simple_ast do
421
398
  let(:ast) { parse_ast('name "webserver"') }
422
399
  it "raises if the field name is nil" do
423
- lambda { api.field_value(ast, nil) }.must_raise ArgumentError
400
+ expect { api.field_value(ast, nil) }.to raise_error ArgumentError
424
401
  end
425
402
  it "raises if the field name is empty" do
426
- lambda { api.field_value(ast, "") }.must_raise ArgumentError
403
+ expect { api.field_value(ast, "") }.to raise_error ArgumentError
427
404
  end
428
405
  it "is falsy if the field is not present" do
429
- refute api.field_value(ast, :common_name)
406
+ expect(api.field_value(ast, :common_name)).to be_falsey
430
407
  end
431
408
  it "accepts a string for the field name" do
432
- api.field_value(ast, "name").must_equal "webserver"
409
+ expect(api.field_value(ast, "name")).to eq "webserver"
433
410
  end
434
411
  it "accepts a symbol for the field name" do
435
- api.field_value(ast, :name).must_equal "webserver"
412
+ expect(api.field_value(ast, :name)).to eq "webserver"
436
413
  end
437
414
  end
438
415
  it "is falsy when the value is an embedded string expression" do
439
416
  ast = parse_ast(%q{
440
417
  name "#{foo}_#{bar}"
441
418
  }.strip)
442
- refute api.field_value(ast, :name)
419
+ expect(api.field_value(ast, :name)).to be_falsey
443
420
  end
444
421
  it "is falsy when the value is a method call" do
445
422
  ast = parse_ast(%q{
446
423
  name generate_name('foo')
447
424
  }.strip)
448
- refute api.field_value(ast, :name)
425
+ expect(api.field_value(ast, :name)).to be_falsey
449
426
  end
450
427
  it "returns the last value if the field is specified twice" do
451
428
  ast = parse_ast(%q{
452
429
  name "webserver"
453
430
  name "database"
454
431
  }.strip)
455
- api.field_value(ast, :name).must_equal "database"
432
+ expect(api.field_value(ast, :name)).to eq "database"
456
433
  end
457
434
  end
458
435
 
459
436
  describe "#file_match" do
460
437
  it "includes the provided filename in the match" do
461
- api.file_match("foo.rb")[:filename].must_equal "foo.rb"
438
+ expect(api.file_match("foo.rb")[:filename]).to eq "foo.rb"
462
439
  end
463
440
  it "retains the full provided filename path in the match" do
464
- api.file_match("foo/bar/foo.rb")[:filename].must_equal "foo/bar/foo.rb"
441
+ expect(api.file_match("foo/bar/foo.rb")[:filename]).to eq "foo/bar/foo.rb"
465
442
  end
466
443
  it "raises an error if the provided filename is nil" do
467
- lambda { api.file_match(nil) }.must_raise(ArgumentError)
444
+ expect { api.file_match(nil) }.to raise_error ArgumentError
468
445
  end
469
446
  it "sets the line and column to the beginning of the file" do
470
447
  match = api.file_match("bar.rb")
471
- match[:line].must_equal 1
472
- match[:column].must_equal 1
448
+ expect(match[:line]).to eq 1
449
+ expect(match[:column]).to eq 1
473
450
  end
474
451
  end
475
452
 
476
453
  describe "#find_resources" do
477
- let(:ast) { MiniTest::Mock.new }
454
+ let(:ast) { double() }
478
455
  it "returns empty unless the ast supports XPath" do
479
- api.find_resources(nil).must_be_empty
456
+ expect(api.find_resources(nil)).to be_empty
480
457
  end
481
458
  it "restricts by resource type when provided" do
482
- ast.expect :xpath, ["method_add_block"],
483
- ["//method_add_block[command/ident[@value='file']]" +
484
- "[command/ident/@value != 'action']"]
459
+ expect(ast).to receive(:xpath).with("//method_add_block[command/ident[@value='file']][command/ident/@value != 'action']").and_return(["method_add_block"])
485
460
  api.find_resources(ast, :type => "file")
486
- ast.verify
487
461
  end
488
462
  it "does not restrict by resource type when not provided" do
489
- ast.expect :xpath, ["method_add_block"],
490
- ["//method_add_block[command/ident]" +
491
- "[command/ident/@value != 'action']"]
463
+ expect(ast).to receive(:xpath).with("//method_add_block[command/ident][command/ident/@value != 'action']").and_return(["method_add_block"])
492
464
  api.find_resources(ast)
493
- ast.verify
494
465
  end
495
466
  it "allows resource type to be specified as :any" do
496
- ast.expect :xpath, ["method_add_block"],
497
- ["//method_add_block[command/ident]" +
498
- "[command/ident/@value != 'action']"]
467
+ expect(ast).to receive(:xpath).with("//method_add_block[command/ident][command/ident/@value != 'action']").and_return(["method_add_block"])
499
468
  api.find_resources(ast, :type => :any)
500
- ast.verify
501
469
  end
502
470
  it "returns any matches" do
503
- ast.expect :xpath, ["method_add_block"], [String]
504
- api.find_resources(ast).must_equal ["method_add_block"]
471
+ expect(ast).to receive(:xpath).with(kind_of(String)).and_return(["method_add_block"])
472
+ expect(api.find_resources(ast)).to eq ["method_add_block"]
505
473
  end
506
474
  end
507
475
 
508
476
  describe "#included_recipes" do
477
+ let(:ast) { double() }
509
478
  it "raises if the ast does not support XPath" do
510
- lambda { api.included_recipes(nil) }.must_raise ArgumentError
479
+ expect { api.included_recipes(nil) }.to raise_error ArgumentError
511
480
  end
512
481
  it "returns an empty hash if there are no included recipes" do
513
- ast = MiniTest::Mock.new.expect :xpath, [], [String]
514
- api.included_recipes(ast).keys.must_be_empty
482
+ expect(ast).to receive(:xpath).with(kind_of(String)).and_return([])
483
+ expect(api.included_recipes(ast).keys).to be_empty
515
484
  end
516
485
  it "returns a hash keyed by recipe name" do
517
- ast = MiniTest::Mock.new.expect :xpath, [{ "value" => "foo::bar" }],
518
- [String]
519
- api.included_recipes(ast).keys.must_equal ["foo::bar"]
486
+ expect(ast).to receive(:xpath).with(kind_of(String)).and_return([{ "value" => "foo::bar" }])
487
+ expect(api.included_recipes(ast).keys).to eq ["foo::bar"]
520
488
  end
521
489
  it "returns a hash where the values are the matching nodes" do
522
- ast = MiniTest::Mock.new.expect :xpath, [{ "value" => "foo::bar" }],
523
- [String]
524
- api.included_recipes(ast).values.must_equal [[{ "value" => "foo::bar" }]]
490
+ expect(ast).to receive(:xpath).with(kind_of(String)).and_return([{ "value" => "foo::bar" }])
491
+ expect(api.included_recipes(ast).values).to eq [[{ "value" => "foo::bar" }]]
525
492
  end
526
493
  it "correctly keys an included recipe specified as a string literal" do
527
- api.included_recipes(parse_ast(%q{
494
+ ast = parse_ast(%q{
528
495
  include_recipe "foo::default"
529
- })).keys.must_equal ["foo::default"]
496
+ })
497
+ expect(api.included_recipes(ast).keys).to eq ["foo::default"]
530
498
  end
531
499
  describe "embedded expression - recipe name" do
532
500
  let(:ast) do
@@ -535,16 +503,16 @@ describe FoodCritic::Api do
535
503
  })
536
504
  end
537
505
  it "returns the literal string component by default" do
538
- api.included_recipes(ast).keys.must_equal ["foo::"]
506
+ expect(api.included_recipes(ast).keys).to eq ["foo::"]
539
507
  end
540
508
  it "returns the literal string part of the AST" do
541
- api.included_recipes(ast)["foo::"].first.must_respond_to(:xpath)
509
+ expect(api.included_recipes(ast)["foo::"].first).to respond_to :xpath
542
510
  end
543
511
  it "returns empty if asked to exclude statements with embedded expressions" do
544
- api.included_recipes(ast, :with_partial_names => false).must_be_empty
512
+ expect(api.included_recipes(ast, :with_partial_names => false)).to be_empty
545
513
  end
546
514
  it "returns the literals if asked to include statements with embedded expressions" do
547
- api.included_recipes(ast, :with_partial_names => true).keys.must_equal ["foo::"]
515
+ expect(api.included_recipes(ast, :with_partial_names => true).keys).to eq ["foo::"]
548
516
  end
549
517
  end
550
518
  describe "embedded expression - cookbook name" do
@@ -554,13 +522,13 @@ describe FoodCritic::Api do
554
522
  })
555
523
  end
556
524
  it "returns the literal string component by default" do
557
- api.included_recipes(ast).keys.must_equal ["::bar"]
525
+ expect(api.included_recipes(ast).keys).to eq ["::bar"]
558
526
  end
559
527
  it "returns the literal string part of the AST" do
560
- api.included_recipes(ast)["::bar"].first.must_respond_to(:xpath)
528
+ expect(api.included_recipes(ast)["::bar"].first).to respond_to :xpath
561
529
  end
562
530
  it "returns empty if asked to exclude statements with embedded expressions" do
563
- api.included_recipes(ast, :with_partial_names => false).must_be_empty
531
+ expect(api.included_recipes(ast, :with_partial_names => false)).to be_empty
564
532
  end
565
533
  end
566
534
  describe "embedded expression - partial cookbook name" do
@@ -570,13 +538,13 @@ describe FoodCritic::Api do
570
538
  })
571
539
  end
572
540
  it "returns the literal string component by default" do
573
- api.included_recipes(ast).keys.must_equal ["_foo::bar"]
541
+ expect(api.included_recipes(ast).keys).to eq ["_foo::bar"]
574
542
  end
575
543
  it "returns the literal string part of the AST" do
576
- api.included_recipes(ast)["_foo::bar"].first.must_respond_to(:xpath)
544
+ expect(api.included_recipes(ast)["_foo::bar"].first).to respond_to :xpath
577
545
  end
578
546
  it "returns empty if asked to exclude statements with embedded expressions" do
579
- api.included_recipes(ast, :with_partial_names => false).must_be_empty
547
+ expect(api.included_recipes(ast, :with_partial_names => false)).to be_empty
580
548
  end
581
549
  end
582
550
  end
@@ -585,289 +553,306 @@ describe FoodCritic::Api do
585
553
  describe "#is_att_type" do
586
554
  let(:filter) { FoodCritic::Api::AttFilter.new }
587
555
  it "returns empty if the argument is not enumerable" do
588
- filter.is_att_type(nil).must_be_empty
556
+ expect(filter.is_att_type(nil)).to be_empty
589
557
  end
590
558
  it "filters out values that are not Chef node attribute types" do
591
559
  nodes = %w{node node badger default override ostrich set normal}
592
- filter.is_att_type(nodes).uniq.size.must_equal 5
560
+ expect(filter.is_att_type(nodes).uniq.size).to eq 5
593
561
  end
594
562
  it "returns all filtered nodes" do
595
563
  nodes = %w{node node override default normal set set override}
596
- filter.is_att_type(nodes).must_equal nodes
564
+ expect(filter.is_att_type(nodes)).to eq nodes
597
565
  end
598
566
  it "returns empty if there are no Chef node attribute types" do
599
567
  nodes = %w{squirrel badger pooh tigger}
600
- filter.is_att_type(nodes).must_be_empty
568
+ expect(filter.is_att_type(nodes)).to be_empty
601
569
  end
602
570
  end
603
571
  end
604
572
 
605
573
  describe "#literal_searches" do
606
- let(:ast) { MiniTest::Mock.new }
574
+ let(:ast) { double() }
607
575
  it "returns empty if the AST does not support XPath expressions" do
608
- api.literal_searches(nil).must_be_empty
576
+ expect(api.literal_searches(nil)).to be_empty
609
577
  end
610
578
  it "returns empty if the AST has no elements" do
611
- ast.expect :xpath, [], [String]
612
- api.literal_searches(ast).must_be_empty
579
+ expect(ast).to receive(:xpath).with(kind_of(String)).and_return([])
580
+ expect(api.literal_searches(ast)).to be_empty
613
581
  end
614
582
  it "returns the AST elements for each literal search" do
615
- ast.expect :xpath, ["tstring_content"], [String]
616
- api.literal_searches(ast).must_equal ["tstring_content"]
583
+ expect(ast).to receive(:xpath).with(kind_of(String)).and_return(["tstring_content"])
584
+ expect(api.literal_searches(ast)).to eq ["tstring_content"]
617
585
  end
618
586
  end
619
587
 
620
588
  describe "#match" do
621
589
  it "raises if the provided node is nil" do
622
- lambda { api.match(nil) }.must_raise(ArgumentError)
590
+ expect { api.match(nil) }.to raise_error ArgumentError
623
591
  end
624
592
  it "raises if the provided node does not support XPath" do
625
- lambda { api.match(Object.new) }.must_raise(ArgumentError)
593
+ expect { api.match(Object.new) }.to raise_error ArgumentError
626
594
  end
627
595
  it "returns nil if there is no nested position node" do
628
- node = MiniTest::Mock.new
629
- node.expect :xpath, [], ["descendant::pos"]
630
- api.match(node).must_be_nil
596
+ node = double()
597
+ expect(node).to receive(:xpath).with("descendant::pos").and_return([])
598
+ expect(api.match(node)).to be nil
631
599
  end
632
600
  it "uses the position of the first position node if there are multiple" do
633
- node = MiniTest::Mock.new
634
- node.expect(:xpath,
635
- [{ "name" => "pos", "line" => "1", "column" => "10" },
636
- { "name" => "pos", "line" => "3", "column" => "16" }],
637
- ["descendant::pos"])
601
+ node = double()
602
+ expect(node).to receive(:xpath).with("descendant::pos").and_return([
603
+ { "name" => "pos", "line" => "1", "column" => "10" },
604
+ { "name" => "pos", "line" => "3", "column" => "16" }])
638
605
  match = api.match(node)
639
- match[:line].must_equal(1)
640
- match[:column].must_equal(10)
606
+ expect(match[:line]).to eq 1
607
+ expect(match[:column]).to eq 10
641
608
  end
642
609
  describe :matched_node_name do
643
610
  let(:node) do
644
- node = MiniTest::Mock.new
645
- node.expect :xpath, [{ "name" => "pos", "line" => "1",
646
- "column" => "10" }], ["descendant::pos"]
611
+ node = double()
612
+ expect(node).to receive(:xpath).with("descendant::pos").and_return([{ "name" => "pos", "line" => "1", "column" => "10" }])
647
613
  node
648
614
  end
649
615
  it "includes the name of the node in the match" do
650
- node.expect :name, "command"
651
- api.match(node).must_equal({ :matched => "command", :line => 1,
652
- :column => 10 })
616
+ expect(node).to receive(:name).and_return("command")
617
+ expect(api.match(node)).to eq({ :matched => "command", :line => 1,
618
+ :column => 10 })
653
619
  end
654
620
  it "sets the matched name to empty if the element does not have a name" do
655
- api.match(node).must_equal({ :matched => "", :line => 1, :column => 10 })
621
+ expect(api.match(node)).to eq({ :matched => "", :line => 1, :column => 10 })
656
622
  end
657
623
  end
658
624
  end
659
625
 
660
626
  describe "#notifications" do
661
627
  it "returns empty if the provided AST does not support XPath" do
662
- api.notifications(nil).must_be_empty
628
+ expect(api.notifications(nil)).to be_empty
663
629
  end
664
630
  it "returns empty if there are no notifications" do
665
- api.notifications(parse_ast(%q{
631
+ ast = parse_ast(%q{
666
632
  template "/etc/nscd.conf" do
667
633
  source "nscd.conf"
668
634
  owner "root"
669
635
  group "root"
670
636
  end
671
- })).must_be_empty
637
+ })
638
+ expect(api.notifications(ast)).to be_empty
672
639
  end
673
640
  describe "malformed syntax" do
674
641
  it "returns empty if no notifies value is provided" do
675
- api.notifications(parse_ast(%q{
642
+ ast = parse_ast(%q{
676
643
  template "/etc/nscd.conf" do
677
644
  source "nscd.conf"
678
645
  owner "root"
679
646
  group "root"
680
647
  notifies
681
648
  end
682
- })).must_be_empty
649
+ })
650
+ expect(api.notifications(ast)).to be_empty
683
651
  end
684
652
  it "returns empty if no subscribes value is provided" do
685
- api.notifications(parse_ast(%q{
653
+ ast = parse_ast(%q{
686
654
  template "/etc/nscd.conf" do
687
655
  source "nscd.conf"
688
656
  owner "root"
689
657
  group "root"
690
658
  subscribes
691
659
  end
692
- })).must_be_empty
660
+ })
661
+ expect(api.notifications(ast)).to be_empty
693
662
  end
694
663
  it "returns empty if only the notifies action is provided" do
695
- api.notifications(parse_ast(%q{
664
+ ast = parse_ast(%q{
696
665
  template "/etc/nscd.conf" do
697
666
  source "nscd.conf"
698
667
  owner "root"
699
668
  group "root"
700
669
  notifies :restart
701
670
  end
702
- })).must_be_empty
671
+ })
672
+ expect(api.notifications(ast)).to be_empty
703
673
  end
704
674
  it "returns empty if only the subscribes action is provided" do
705
- api.notifications(parse_ast(%q{
675
+ ast = parse_ast(%q{
706
676
  template "/etc/nscd.conf" do
707
677
  source "nscd.conf"
708
678
  owner "root"
709
679
  group "root"
710
680
  subscribes :restart
711
681
  end
712
- })).must_be_empty
682
+ })
683
+ expect(api.notifications(ast)).to be_empty
713
684
  end
714
685
  describe "returns empty if the service name is missing" do
715
686
  it "old-style notifications" do
716
- api.notifications(parse_ast(%q{
687
+ ast = parse_ast(%q{
717
688
  template "/etc/nscd.conf" do
718
689
  source "nscd.conf"
719
690
  owner "root"
720
691
  group "root"
721
692
  notifies :restart, resources(:service)
722
693
  end
723
- })).must_be_empty
694
+ })
695
+ expect(api.notifications(ast)).to be_empty
724
696
  end
725
697
  it "old-style subscriptions" do
726
- api.notifications(parse_ast(%q{
698
+ ast = parse_ast(%q{
727
699
  template "/etc/nscd.conf" do
728
700
  source "nscd.conf"
729
701
  owner "root"
730
702
  group "root"
731
703
  subscribes:restart, resources(:service)
732
704
  end
733
- })).must_be_empty
705
+ })
706
+ expect(api.notifications(ast)).to be_empty
734
707
  end
735
708
  it "new-style notifications" do
736
- api.notifications(parse_ast(%q{
709
+ ast = parse_ast(%q{
737
710
  template "/etc/nscd.conf" do
738
711
  source "nscd.conf"
739
712
  owner "root"
740
713
  group "root"
741
714
  notifies :restart, "service"
742
715
  end
743
- })).must_be_empty
716
+ })
717
+ expect(api.notifications(ast)).to be_empty
744
718
  end
745
719
  it "new-style subscriptions" do
746
- api.notifications(parse_ast(%q{
720
+ ast = parse_ast(%q{
747
721
  template "/etc/nscd.conf" do
748
722
  source "nscd.conf"
749
723
  owner "root"
750
724
  group "root"
751
725
  subscribes:restart, "service"
752
726
  end
753
- })).must_be_empty
727
+ })
728
+ expect(api.notifications(ast)).to be_empty
754
729
  end
755
730
  end
756
731
  describe "returns empty if the resource type is missing" do
757
732
  it "old-style notifications" do
758
- api.notifications(parse_ast(%q{
733
+ ast = parse_ast(%q{
759
734
  template "/etc/nscd.conf" do
760
735
  source "nscd.conf"
761
736
  owner "root"
762
737
  group "root"
763
738
  notifies :restart, resources("nscd")
764
739
  end
765
- })).must_be_empty
740
+ })
741
+ expect(api.notifications(ast)).to be_empty
766
742
  end
767
743
  it "old-style subscriptions" do
768
- api.notifications(parse_ast(%q{
744
+ ast = parse_ast(%q{
769
745
  template "/etc/nscd.conf" do
770
746
  source "nscd.conf"
771
747
  owner "root"
772
748
  group "root"
773
749
  subscribes :restart, resources("nscd")
774
750
  end
775
- })).must_be_empty
751
+ })
752
+ expect(api.notifications(ast)).to be_empty
776
753
  end
777
754
  it "new-style notifications" do
778
- api.notifications(parse_ast(%q{
755
+ ast = parse_ast(%q{
779
756
  template "/etc/nscd.conf" do
780
757
  source "nscd.conf"
781
758
  owner "root"
782
759
  group "root"
783
760
  notifies :restart, "nscd"
784
761
  end
785
- })).must_be_empty
762
+ })
763
+ expect(api.notifications(ast)).to be_empty
786
764
  end
787
765
  it "new-style subscriptions" do
788
- api.notifications(parse_ast(%q{
766
+ ast = parse_ast(%q{
789
767
  template "/etc/nscd.conf" do
790
768
  source "nscd.conf"
791
769
  owner "root"
792
770
  group "root"
793
771
  subscribes :restart, "nscd"
794
772
  end
795
- })).must_be_empty
773
+ })
774
+ expect(api.notifications(ast)).to be_empty
796
775
  end
797
776
  end
798
777
  describe "returns empty if the resource name is missing" do
799
778
  it "old-style notifications" do
800
- api.notifications(parse_ast(%q{
779
+ ast = parse_ast(%q{
801
780
  template "/etc/nscd.conf" do
802
781
  source "nscd.conf"
803
782
  owner "root"
804
783
  group "root"
805
784
  notifies :restart, resources(:service)
806
785
  end
807
- })).must_be_empty
786
+ })
787
+ expect(api.notifications(ast)).to be_empty
808
788
  end
809
789
  it "old-style subscriptions" do
810
- api.notifications(parse_ast(%q{
790
+ ast = parse_ast(%q{
811
791
  template "/etc/nscd.conf" do
812
792
  source "nscd.conf"
813
793
  owner "root"
814
794
  group "root"
815
795
  subscribes :restart, resources(:service)
816
796
  end
817
- })).must_be_empty
797
+ })
798
+ expect(api.notifications(ast)).to be_empty
818
799
  end
819
800
  it "new-style notifications" do
820
- api.notifications(parse_ast(%q{
801
+ ast = parse_ast(%q{
821
802
  template "/etc/nscd.conf" do
822
803
  source "nscd.conf"
823
804
  owner "root"
824
805
  group "root"
825
806
  notifies :restart, "service[]"
826
807
  end
827
- })).must_be_empty
808
+ })
809
+ expect(api.notifications(ast)).to be_empty
828
810
  end
829
811
  it "new-style subscriptions" do
830
- api.notifications(parse_ast(%q{
812
+ ast = parse_ast(%q{
831
813
  template "/etc/nscd.conf" do
832
814
  source "nscd.conf"
833
815
  owner "root"
834
816
  group "root"
835
817
  subscribes :restart, "service[]"
836
818
  end
837
- })).must_be_empty
819
+ })
820
+ expect(api.notifications(ast)).to be_empty
838
821
  end
839
822
  end
840
823
  it "returns empty if the left square bracket is missing" do
841
- api.notifications(parse_ast(%q{
824
+ ast = parse_ast(%q{
842
825
  template "/etc/nscd.conf" do
843
826
  source "nscd.conf"
844
827
  owner "root"
845
828
  group "root"
846
829
  subscribes :restart, "servicefoo]"
847
830
  end
848
- })).must_be_empty
831
+ })
832
+ expect(api.notifications(ast)).to be_empty
849
833
  end
850
834
  it "returns empty if the right square bracket is missing" do
851
- api.notifications(parse_ast(%q{
835
+ ast = parse_ast(%q{
852
836
  template "/etc/nscd.conf" do
853
837
  source "nscd.conf"
854
838
  owner "root"
855
839
  group "root"
856
840
  subscribes :restart, "service[foo"
857
841
  end
858
- })).must_be_empty
842
+ })
843
+ expect(api.notifications(ast)).to be_empty
859
844
  end
860
845
  end
861
846
  it "understands the old-style notifications" do
862
- api.notifications(parse_ast(%q{
847
+ ast = parse_ast(%q{
863
848
  template "/etc/nscd.conf" do
864
849
  source "nscd.conf"
865
850
  owner "root"
866
851
  group "root"
867
852
  notifies :restart, resources(:service => "nscd")
868
853
  end
869
- })).must_equal(
870
- [{
854
+ })
855
+ expect(api.notifications(ast)).to eq [{
871
856
  :type => :notifies,
872
857
  :action => :restart,
873
858
  :resource_type => :service,
@@ -875,18 +860,17 @@ describe FoodCritic::Api do
875
860
  :timing => :delayed,
876
861
  :style => :old,
877
862
  }]
878
- )
879
863
  end
880
864
  it "understands old-style notifications with :'symbol' literals as action" do
881
- api.notifications(parse_ast(%q{
865
+ ast = parse_ast(%q{
882
866
  template "/etc/nscd.conf" do
883
867
  source "nscd.conf"
884
868
  owner "root"
885
869
  group "root"
886
870
  notifies :'soft-restart', resources(:service => "nscd")
887
871
  end
888
- })).must_equal(
889
- [{
872
+ })
873
+ expect(api.notifications(ast)).to eq [{
890
874
  :type => :notifies,
891
875
  :action => :'soft-restart',
892
876
  :resource_type => :service,
@@ -894,18 +878,17 @@ describe FoodCritic::Api do
894
878
  :timing => :delayed,
895
879
  :style => :old,
896
880
  }]
897
- )
898
881
  end
899
882
  it "understands old-style notifications with added parentheses" do
900
- api.notifications(parse_ast(%q{
883
+ ast = parse_ast(%q{
901
884
  template "/etc/nscd.conf" do
902
885
  source "nscd.conf"
903
886
  owner "root"
904
887
  group "root"
905
888
  notifies(:restart, resources(:service => "nscd"))
906
889
  end
907
- })).must_equal(
908
- [{
890
+ })
891
+ expect(api.notifications(ast)).to eq [{
909
892
  :type => :notifies,
910
893
  :action => :restart,
911
894
  :resource_type => :service,
@@ -913,18 +896,17 @@ describe FoodCritic::Api do
913
896
  :timing => :delayed,
914
897
  :style => :old,
915
898
  }]
916
- )
917
899
  end
918
900
  it "understands old-style notifications with ruby 1.9 hash syntax" do
919
- api.notifications(parse_ast(%q{
901
+ ast = parse_ast(%q{
920
902
  template "/etc/nscd.conf" do
921
903
  source "nscd.conf"
922
904
  owner "root"
923
905
  group "root"
924
906
  notifies :restart, resources(service: "nscd")
925
907
  end
926
- })).must_equal(
927
- [{
908
+ })
909
+ expect(api.notifications(ast)).to eq [{
928
910
  :type => :notifies,
929
911
  :action => :restart,
930
912
  :resource_type => :service,
@@ -932,18 +914,17 @@ describe FoodCritic::Api do
932
914
  :timing => :delayed,
933
915
  :style => :old,
934
916
  }]
935
- )
936
917
  end
937
918
  it "understands the old-style subscriptions" do
938
- api.notifications(parse_ast(%q{
919
+ ast = parse_ast(%q{
939
920
  template "/etc/nscd.conf" do
940
921
  source "nscd.conf"
941
922
  owner "root"
942
923
  group "root"
943
924
  subscribes :restart, resources(:service => "nscd")
944
925
  end
945
- })).must_equal(
946
- [{
926
+ })
927
+ expect(api.notifications(ast)).to eq [{
947
928
  :type => :subscribes,
948
929
  :action => :restart,
949
930
  :resource_type => :service,
@@ -951,18 +932,17 @@ describe FoodCritic::Api do
951
932
  :timing => :delayed,
952
933
  :style => :old,
953
934
  }]
954
- )
955
935
  end
956
936
  it "understands old-style subscriptions with added parentheses" do
957
- api.notifications(parse_ast(%q{
937
+ ast = parse_ast(%q{
958
938
  template "/etc/nscd.conf" do
959
939
  source "nscd.conf"
960
940
  owner "root"
961
941
  group "root"
962
942
  subscribes(:restart, resources(:service => "nscd"))
963
943
  end
964
- })).must_equal(
965
- [{
944
+ })
945
+ expect(api.notifications(ast)).to eq [{
966
946
  :type => :subscribes,
967
947
  :action => :restart,
968
948
  :resource_type => :service,
@@ -970,18 +950,17 @@ describe FoodCritic::Api do
970
950
  :timing => :delayed,
971
951
  :style => :old,
972
952
  }]
973
- )
974
953
  end
975
954
  it "understands the new-style notifications" do
976
- api.notifications(parse_ast(%q{
955
+ ast = parse_ast(%q{
977
956
  template "/etc/nscd.conf" do
978
957
  source "nscd.conf"
979
958
  owner "root"
980
959
  group "root"
981
960
  notifies :restart, "service[nscd]"
982
961
  end
983
- })).must_equal(
984
- [{
962
+ })
963
+ expect(api.notifications(ast)).to eq [{
985
964
  :type => :notifies,
986
965
  :action => :restart,
987
966
  :resource_type => :service,
@@ -989,18 +968,17 @@ describe FoodCritic::Api do
989
968
  :timing => :delayed,
990
969
  :style => :new,
991
970
  }]
992
- )
993
971
  end
994
972
  it "understands new-style notifications with :'symbol' literals as action" do
995
- api.notifications(parse_ast(%q{
973
+ ast = parse_ast(%q{
996
974
  template "/etc/nscd.conf" do
997
975
  source "nscd.conf"
998
976
  owner "root"
999
977
  group "root"
1000
978
  notifies :'soft-restart', "service[nscd]"
1001
979
  end
1002
- })).must_equal(
1003
- [{
980
+ })
981
+ expect(api.notifications(ast)).to eq [{
1004
982
  :type => :notifies,
1005
983
  :action => :'soft-restart',
1006
984
  :resource_type => :service,
@@ -1008,18 +986,17 @@ describe FoodCritic::Api do
1008
986
  :timing => :delayed,
1009
987
  :style => :new,
1010
988
  }]
1011
- )
1012
989
  end
1013
990
  it "understands new-style notifications with added parentheses" do
1014
- api.notifications(parse_ast(%q{
991
+ ast = parse_ast(%q{
1015
992
  template "/etc/nscd.conf" do
1016
993
  source "nscd.conf"
1017
994
  owner "root"
1018
995
  group "root"
1019
996
  notifies(:restart, "service[nscd]")
1020
997
  end
1021
- })).must_equal(
1022
- [{
998
+ })
999
+ expect(api.notifications(ast)).to eq [{
1023
1000
  :type => :notifies,
1024
1001
  :action => :restart,
1025
1002
  :resource_type => :service,
@@ -1027,18 +1004,17 @@ describe FoodCritic::Api do
1027
1004
  :timing => :delayed,
1028
1005
  :style => :new,
1029
1006
  }]
1030
- )
1031
1007
  end
1032
1008
  it "understands the new-style subscriptions" do
1033
- api.notifications(parse_ast(%q{
1009
+ ast = parse_ast(%q{
1034
1010
  template "/etc/nscd.conf" do
1035
1011
  source "nscd.conf"
1036
1012
  owner "root"
1037
1013
  group "root"
1038
1014
  subscribes :restart, "service[nscd]"
1039
1015
  end
1040
- })).must_equal(
1041
- [{
1016
+ })
1017
+ expect(api.notifications(ast)).to eq [{
1042
1018
  :type => :subscribes,
1043
1019
  :action => :restart,
1044
1020
  :resource_type => :service,
@@ -1046,18 +1022,17 @@ describe FoodCritic::Api do
1046
1022
  :timing => :delayed,
1047
1023
  :style => :new,
1048
1024
  }]
1049
- )
1050
1025
  end
1051
1026
  it "understands new-style subscriptions with added parentheses" do
1052
- api.notifications(parse_ast(%q{
1027
+ ast = parse_ast(%q{
1053
1028
  template "/etc/nscd.conf" do
1054
1029
  source "nscd.conf"
1055
1030
  owner "root"
1056
1031
  group "root"
1057
1032
  subscribes(:restart, "service[nscd]")
1058
1033
  end
1059
- })).must_equal(
1060
- [{
1034
+ })
1035
+ expect(api.notifications(ast)).to eq [{
1061
1036
  :type => :subscribes,
1062
1037
  :action => :restart,
1063
1038
  :resource_type => :service,
@@ -1065,11 +1040,10 @@ describe FoodCritic::Api do
1065
1040
  :timing => :delayed,
1066
1041
  :style => :new,
1067
1042
  }]
1068
- )
1069
1043
  end
1070
1044
  describe "supports a resource both notifying and subscribing" do
1071
1045
  it "old-style notifications" do
1072
- api.notifications(parse_ast(%q{
1046
+ ast = parse_ast(%q{
1073
1047
  template "/etc/nscd.conf" do
1074
1048
  source "nscd.conf"
1075
1049
  owner "root"
@@ -1077,7 +1051,8 @@ describe FoodCritic::Api do
1077
1051
  notifies :restart, resources(:service => "nscd")
1078
1052
  subscribes :create, resources(:template => "/etc/nscd.conf")
1079
1053
  end
1080
- })).must_equal([
1054
+ })
1055
+ expect(api.notifications(ast)).to eq [
1081
1056
  {
1082
1057
  :type => :notifies,
1083
1058
  :action => :restart,
@@ -1094,10 +1069,10 @@ describe FoodCritic::Api do
1094
1069
  :timing => :delayed,
1095
1070
  :style => :old,
1096
1071
  },
1097
- ])
1072
+ ]
1098
1073
  end
1099
1074
  it "new-style notifications" do
1100
- api.notifications(parse_ast(%q{
1075
+ ast = parse_ast(%q{
1101
1076
  template "/etc/nscd.conf" do
1102
1077
  source "nscd.conf"
1103
1078
  owner "root"
@@ -1105,7 +1080,8 @@ describe FoodCritic::Api do
1105
1080
  notifies :restart, "service[nscd]"
1106
1081
  subscribes :create, "template[/etc/nscd.conf]"
1107
1082
  end
1108
- })).must_equal([
1083
+ })
1084
+ expect(api.notifications(ast)).to eq [
1109
1085
  {
1110
1086
  :type => :notifies,
1111
1087
  :action => :restart,
@@ -1122,19 +1098,19 @@ describe FoodCritic::Api do
1122
1098
  :timing => :delayed,
1123
1099
  :style => :new,
1124
1100
  },
1125
- ])
1101
+ ]
1126
1102
  end
1127
1103
  end
1128
1104
  it "understands the old-style notifications with timing" do
1129
- api.notifications(parse_ast(%q{
1105
+ ast = parse_ast(%q{
1130
1106
  template "/etc/nscd.conf" do
1131
1107
  source "nscd.conf"
1132
1108
  owner "root"
1133
1109
  group "root"
1134
1110
  notifies :restart, resources(:service => "nscd"), :immediately
1135
1111
  end
1136
- })).must_equal(
1137
- [{
1112
+ })
1113
+ expect(api.notifications(ast)).to eq [{
1138
1114
  :type => :notifies,
1139
1115
  :action => :restart,
1140
1116
  :resource_type => :service,
@@ -1142,18 +1118,17 @@ describe FoodCritic::Api do
1142
1118
  :timing => :immediate,
1143
1119
  :style => :old,
1144
1120
  }]
1145
- )
1146
1121
  end
1147
1122
  it "understands the old-style subscriptions with timing" do
1148
- api.notifications(parse_ast(%q{
1123
+ ast = parse_ast(%q{
1149
1124
  template "/etc/nscd.conf" do
1150
1125
  source "nscd.conf"
1151
1126
  owner "root"
1152
1127
  group "root"
1153
1128
  subscribes :restart, resources(:service => "nscd"), :immediately
1154
1129
  end
1155
- })).must_equal(
1156
- [{
1130
+ })
1131
+ expect(api.notifications(ast)).to eq [{
1157
1132
  :type => :subscribes,
1158
1133
  :action => :restart,
1159
1134
  :resource_type => :service,
@@ -1161,18 +1136,17 @@ describe FoodCritic::Api do
1161
1136
  :timing => :immediate,
1162
1137
  :style => :old,
1163
1138
  }]
1164
- )
1165
1139
  end
1166
1140
  it "understands the new-style notifications with timing" do
1167
- api.notifications(parse_ast(%q{
1141
+ ast = parse_ast(%q{
1168
1142
  template "/etc/nscd.conf" do
1169
1143
  source "nscd.conf"
1170
1144
  owner "root"
1171
1145
  group "root"
1172
1146
  notifies :restart, "service[nscd]", :immediately
1173
1147
  end
1174
- })).must_equal(
1175
- [{
1148
+ })
1149
+ expect(api.notifications(ast)).to eq [{
1176
1150
  :type => :notifies,
1177
1151
  :action => :restart,
1178
1152
  :resource_type => :service,
@@ -1180,18 +1154,17 @@ describe FoodCritic::Api do
1180
1154
  :timing => :immediate,
1181
1155
  :style => :new,
1182
1156
  }]
1183
- )
1184
1157
  end
1185
1158
  it "understands the new-style subscriptions with timing" do
1186
- api.notifications(parse_ast(%q{
1159
+ ast = parse_ast(%q{
1187
1160
  template "/etc/nscd.conf" do
1188
1161
  source "nscd.conf"
1189
1162
  owner "root"
1190
1163
  group "root"
1191
1164
  subscribes :restart, "service[nscd]", :immediately
1192
1165
  end
1193
- })).must_equal(
1194
- [{
1166
+ })
1167
+ expect(api.notifications(ast)).to eq [{
1195
1168
  :type => :subscribes,
1196
1169
  :action => :restart,
1197
1170
  :resource_type => :service,
@@ -1199,11 +1172,10 @@ describe FoodCritic::Api do
1199
1172
  :timing => :immediate,
1200
1173
  :style => :new,
1201
1174
  }]
1202
- )
1203
1175
  end
1204
1176
  describe "can be passed an individual resource" do
1205
1177
  it "old-style notifications" do
1206
- api.notifications(api.find_resources(parse_ast(%q{
1178
+ ast = parse_ast(%q{
1207
1179
  service "nscd" do
1208
1180
  action :start
1209
1181
  end
@@ -1213,14 +1185,15 @@ describe FoodCritic::Api do
1213
1185
  group "root"
1214
1186
  notifies :restart, resources(:service => "nscd")
1215
1187
  end
1216
- }), :type => :template).first).must_equal([
1188
+ })
1189
+ expect(api.notifications(api.find_resources(ast, :type => :template).first)).to eq [
1217
1190
  { :type => :notifies, :action => :restart, :resource_type => :service,
1218
1191
  :resource_name => "nscd", :timing => :delayed,
1219
1192
  :style => :old },
1220
- ])
1193
+ ]
1221
1194
  end
1222
1195
  it "old-style subscriptions" do
1223
- api.notifications(api.find_resources(parse_ast(%q{
1196
+ ast = parse_ast(%q{
1224
1197
  service "nscd" do
1225
1198
  action :start
1226
1199
  end
@@ -1230,14 +1203,15 @@ describe FoodCritic::Api do
1230
1203
  group "root"
1231
1204
  subscribes :restart, resources(:service => "nscd")
1232
1205
  end
1233
- }), :type => :template).first).must_equal([
1206
+ })
1207
+ expect(api.notifications(api.find_resources(ast, :type => :template).first)).to eq [
1234
1208
  { :type => :subscribes, :action => :restart, :resource_type => :service,
1235
1209
  :resource_name => "nscd", :timing => :delayed,
1236
1210
  :style => :old },
1237
- ])
1211
+ ]
1238
1212
  end
1239
1213
  it "new-style notifications" do
1240
- api.notifications(api.find_resources(parse_ast(%q{
1214
+ ast = parse_ast(%q{
1241
1215
  service "nscd" do
1242
1216
  action :start
1243
1217
  end
@@ -1247,14 +1221,15 @@ describe FoodCritic::Api do
1247
1221
  group "root"
1248
1222
  notifies :restart, "service[nscd]"
1249
1223
  end
1250
- }), :type => :template).first).must_equal([
1224
+ })
1225
+ expect(api.notifications(api.find_resources(ast, :type => :template).first)).to eq [
1251
1226
  { :type => :notifies, :action => :restart, :resource_type => :service,
1252
1227
  :resource_name => "nscd", :timing => :delayed,
1253
1228
  :style => :new },
1254
- ])
1229
+ ]
1255
1230
  end
1256
1231
  it "new-style subscriptions" do
1257
- api.notifications(api.find_resources(parse_ast(%q{
1232
+ ast = parse_ast(%q{
1258
1233
  service "nscd" do
1259
1234
  action :start
1260
1235
  end
@@ -1264,16 +1239,17 @@ describe FoodCritic::Api do
1264
1239
  group "root"
1265
1240
  subscribes :restart, "service[nscd]"
1266
1241
  end
1267
- }), :type => :template).first).must_equal([
1242
+ })
1243
+ expect(api.notifications(api.find_resources(ast, :type => :template).first)).to eq [
1268
1244
  { :type => :subscribes, :action => :restart, :resource_type => :service,
1269
1245
  :resource_name => "nscd", :timing => :delayed,
1270
1246
  :style => :new },
1271
- ])
1247
+ ]
1272
1248
  end
1273
1249
  end
1274
1250
  describe "supports multiple notifications on a single resource" do
1275
1251
  it "old-style notifications" do
1276
- api.notifications(parse_ast(%q{
1252
+ ast = parse_ast(%q{
1277
1253
  template "/etc/nscd.conf" do
1278
1254
  source "nscd.conf"
1279
1255
  owner "root"
@@ -1281,8 +1257,8 @@ describe FoodCritic::Api do
1281
1257
  notifies :stop, resources(:service => "nscd")
1282
1258
  notifies :start, resources(:service => "nscd")
1283
1259
  end
1284
- })).must_equal(
1285
- [
1260
+ })
1261
+ expect(api.notifications(ast)).to eq [
1286
1262
  { :type => :notifies, :action => :stop, :resource_type => :service,
1287
1263
  :resource_name => "nscd", :timing => :delayed,
1288
1264
  :style => :old },
@@ -1290,10 +1266,9 @@ describe FoodCritic::Api do
1290
1266
  :resource_name => "nscd", :timing => :delayed,
1291
1267
  :style => :old },
1292
1268
  ]
1293
- )
1294
1269
  end
1295
1270
  it "old-style subscriptions" do
1296
- api.notifications(parse_ast(%q{
1271
+ ast = parse_ast(%q{
1297
1272
  template "/etc/nscd.conf" do
1298
1273
  source "nscd.conf"
1299
1274
  owner "root"
@@ -1301,8 +1276,8 @@ describe FoodCritic::Api do
1301
1276
  subscribes :stop, resources(:service => "nscd")
1302
1277
  subscribes :start, resources(:service => "nscd")
1303
1278
  end
1304
- })).must_equal(
1305
- [
1279
+ })
1280
+ expect(api.notifications(ast)).to eq [
1306
1281
  { :type => :subscribes, :action => :stop, :resource_type => :service,
1307
1282
  :resource_name => "nscd", :timing => :delayed,
1308
1283
  :style => :old },
@@ -1310,10 +1285,9 @@ describe FoodCritic::Api do
1310
1285
  :resource_name => "nscd", :timing => :delayed,
1311
1286
  :style => :old },
1312
1287
  ]
1313
- )
1314
1288
  end
1315
1289
  it "new-style notifications" do
1316
- api.notifications(parse_ast(%q{
1290
+ ast = parse_ast(%q{
1317
1291
  template "/etc/nscd.conf" do
1318
1292
  source "nscd.conf"
1319
1293
  owner "root"
@@ -1321,8 +1295,8 @@ describe FoodCritic::Api do
1321
1295
  notifies :stop, "service[nscd]"
1322
1296
  notifies :start, "service[nscd]"
1323
1297
  end
1324
- })).must_equal(
1325
- [
1298
+ })
1299
+ expect(api.notifications(ast)).to eq [
1326
1300
  { :type => :notifies, :action => :stop, :resource_type => :service,
1327
1301
  :resource_name => "nscd", :timing => :delayed,
1328
1302
  :style => :new },
@@ -1330,10 +1304,9 @@ describe FoodCritic::Api do
1330
1304
  :resource_name => "nscd", :timing => :delayed,
1331
1305
  :style => :new },
1332
1306
  ]
1333
- )
1334
1307
  end
1335
1308
  it "new-style subscriptions" do
1336
- api.notifications(parse_ast(%q{
1309
+ ast = parse_ast(%q{
1337
1310
  template "/etc/nscd.conf" do
1338
1311
  source "nscd.conf"
1339
1312
  owner "root"
@@ -1341,8 +1314,8 @@ describe FoodCritic::Api do
1341
1314
  subscribes :stop, "service[nscd]"
1342
1315
  subscribes :start, "service[nscd]"
1343
1316
  end
1344
- })).must_equal(
1345
- [
1317
+ })
1318
+ expect(api.notifications(ast)).to eq [
1346
1319
  { :type => :subscribes, :action => :stop, :resource_type => :service,
1347
1320
  :resource_name => "nscd", :timing => :delayed,
1348
1321
  :style => :new },
@@ -1350,242 +1323,260 @@ describe FoodCritic::Api do
1350
1323
  :resource_name => "nscd", :timing => :delayed,
1351
1324
  :style => :new },
1352
1325
  ]
1353
- )
1354
1326
  end
1355
1327
  end
1356
1328
  describe "understands notifications for an execute resource" do
1357
1329
  it "old-style notifications" do
1358
- api.notifications(parse_ast(%q{
1330
+ ast = parse_ast(%q{
1359
1331
  template "/tmp/foo.bar" do
1360
1332
  source "foo.bar.erb"
1361
1333
  notifies :run, resources(:execute => "foo")
1362
1334
  end
1363
- })).must_equal(
1364
- [{ :type => :notifies, :action => :run, :resource_type => :execute,
1335
+ })
1336
+ expect(api.notifications(ast)).to eq [
1337
+ { :type => :notifies, :action => :run, :resource_type => :execute,
1365
1338
  :resource_name => "foo", :timing => :delayed,
1366
- :style => :old }]
1367
- )
1339
+ :style => :old },
1340
+ ]
1368
1341
  end
1369
1342
  it "old-style subscriptions" do
1370
- api.notifications(parse_ast(%q{
1343
+ ast = parse_ast(%q{
1371
1344
  template "/tmp/foo.bar" do
1372
1345
  source "foo.bar.erb"
1373
1346
  subscribes :run, resources(:execute => "foo")
1374
1347
  end
1375
- })).must_equal(
1376
- [{ :type => :subscribes, :action => :run, :resource_type => :execute,
1348
+ })
1349
+ expect(api.notifications(ast)).to eq [
1350
+ { :type => :subscribes, :action => :run, :resource_type => :execute,
1377
1351
  :resource_name => "foo", :timing => :delayed,
1378
- :style => :old }]
1379
- )
1352
+ :style => :old },
1353
+ ]
1380
1354
  end
1381
1355
  it "old-style notifications" do
1382
- api.notifications(parse_ast(%q{
1356
+ ast = parse_ast(%q{
1383
1357
  template "/tmp/foo.bar" do
1384
1358
  source "foo.bar.erb"
1385
1359
  notifies :run, "execute[foo]"
1386
1360
  end
1387
- })).must_equal(
1388
- [{ :type => :notifies, :action => :run, :resource_type => :execute,
1361
+ })
1362
+ expect(api.notifications(ast)).to eq [
1363
+ { :type => :notifies, :action => :run, :resource_type => :execute,
1389
1364
  :resource_name => "foo", :timing => :delayed,
1390
- :style => :new }]
1391
- )
1365
+ :style => :new },
1366
+ ]
1392
1367
  end
1393
1368
  it "old-style subscriptions" do
1394
- api.notifications(parse_ast(%q{
1369
+ ast = parse_ast(%q{
1395
1370
  template "/tmp/foo.bar" do
1396
1371
  source "foo.bar.erb"
1397
1372
  subscribes :run, "execute[foo]"
1398
1373
  end
1399
- })).must_equal(
1400
- [{ :type => :subscribes, :action => :run, :resource_type => :execute,
1374
+ })
1375
+ expect(api.notifications(ast)).to eq [
1376
+ { :type => :subscribes, :action => :run, :resource_type => :execute,
1401
1377
  :resource_name => "foo", :timing => :delayed,
1402
- :style => :new }]
1403
- )
1378
+ :style => :new },
1379
+ ]
1404
1380
  end
1405
1381
  end
1406
1382
  describe "sets the notification timing to delayed if specified" do
1407
1383
  it "old-style notifications" do
1408
- api.notifications(parse_ast(%q{
1384
+ ast = parse_ast(%q{
1409
1385
  template "/etc/foo.conf" do
1410
1386
  notifies :run, resources(execute => "robespierre"), :delayed
1411
1387
  end
1412
- })).first[:timing].must_equal(:delayed)
1388
+ })
1389
+ expect(api.notifications(ast).first[:timing]).to eq :delayed
1413
1390
  end
1414
1391
  it "old-style subscriptions" do
1415
- api.notifications(parse_ast(%q{
1392
+ ast = parse_ast(%q{
1416
1393
  template "/etc/foo.conf" do
1417
1394
  subscribes :run, resources(execute => "robespierre"), :delayed
1418
1395
  end
1419
- })).first[:timing].must_equal(:delayed)
1396
+ })
1397
+ expect(api.notifications(ast).first[:timing]).to eq :delayed
1420
1398
  end
1421
1399
  it "new-style notifications" do
1422
- api.notifications(parse_ast(%q{
1400
+ ast = parse_ast(%q{
1423
1401
  template "/etc/foo.conf" do
1424
1402
  notifies :run, "execute[robespierre]", :delayed
1425
1403
  end
1426
- })).first[:timing].must_equal(:delayed)
1404
+ })
1405
+ expect(api.notifications(ast).first[:timing]).to eq :delayed
1427
1406
  end
1428
1407
  it "new-style subscriptions" do
1429
- api.notifications(parse_ast(%q{
1408
+ ast = parse_ast(%q{
1430
1409
  template "/etc/foo.conf" do
1431
1410
  subscribes :run, "execute[robespierre]", :delayed
1432
1411
  end
1433
- })).first[:timing].must_equal(:delayed)
1412
+ })
1413
+ expect(api.notifications(ast).first[:timing]).to eq :delayed
1434
1414
  end
1435
1415
  end
1436
1416
  describe "sets the notification timing to immediate if specified as immediate" do
1437
1417
  it "old-style notifications" do
1438
- api.notifications(parse_ast(%q{
1418
+ ast = parse_ast(%q{
1439
1419
  template "/etc/foo.conf" do
1440
1420
  notifies :run, resources(execute => "robespierre"), :immediate
1441
1421
  end
1442
- })).first[:timing].must_equal(:immediate)
1422
+ })
1423
+ expect(api.notifications(ast).first[:timing]).to eq :immediate
1443
1424
  end
1444
1425
  it "old-style subscriptions" do
1445
- api.notifications(parse_ast(%q{
1426
+ ast = parse_ast(%q{
1446
1427
  template "/etc/foo.conf" do
1447
1428
  subscribes :run, resources(execute => "robespierre"), :immediate
1448
1429
  end
1449
- })).first[:timing].must_equal(:immediate)
1430
+ })
1431
+ expect(api.notifications(ast).first[:timing]).to eq :immediate
1450
1432
  end
1451
1433
  it "new-style notifications" do
1452
- api.notifications(parse_ast(%q{
1434
+ ast = parse_ast(%q{
1453
1435
  template "/etc/foo.conf" do
1454
1436
  notifies :run, "execute[robespierre]", :immediate
1455
1437
  end
1456
- })).first[:timing].must_equal(:immediate)
1438
+ })
1439
+ expect(api.notifications(ast).first[:timing]).to eq :immediate
1457
1440
  end
1458
1441
  it "new-style subscriptions" do
1459
- api.notifications(parse_ast(%q{
1442
+ ast = parse_ast(%q{
1460
1443
  template "/etc/foo.conf" do
1461
1444
  subscribes :run, "execute[robespierre]", :immediate
1462
1445
  end
1463
- })).first[:timing].must_equal(:immediate)
1446
+ })
1447
+ expect(api.notifications(ast).first[:timing]).to eq :immediate
1464
1448
  end
1465
-
1466
1449
  end
1450
+
1467
1451
  describe "sets the notification timing to immediate if specified as immediately" do
1468
1452
  it "old-style notifications" do
1469
- api.notifications(parse_ast(%q{
1453
+ ast = parse_ast(%q{
1470
1454
  template "/etc/foo.conf" do
1471
1455
  notifies :run, resources(execute => "robespierre"), :immediately
1472
1456
  end
1473
- })).first[:timing].must_equal(:immediate)
1457
+ })
1458
+ expect(api.notifications(ast).first[:timing]).to eq :immediate
1474
1459
  end
1475
1460
  it "old-style subscriptions" do
1476
- api.notifications(parse_ast(%q{
1461
+ ast = parse_ast(%q{
1477
1462
  template "/etc/foo.conf" do
1478
1463
  subscribes :run, resources(execute => "robespierre"), :immediately
1479
1464
  end
1480
- })).first[:timing].must_equal(:immediate)
1465
+ })
1466
+ expect(api.notifications(ast).first[:timing]).to eq :immediate
1481
1467
  end
1482
1468
  it "new-style notifications" do
1483
- api.notifications(parse_ast(%q{
1469
+ ast = parse_ast(%q{
1484
1470
  template "/etc/foo.conf" do
1485
1471
  notifies :run, "execute[robespierre]", :immediately
1486
1472
  end
1487
- })).first[:timing].must_equal(:immediate)
1473
+ })
1474
+ expect(api.notifications(ast).first[:timing]).to eq :immediate
1488
1475
  end
1489
1476
  it "new-style subscriptions" do
1490
- api.notifications(parse_ast(%q{
1477
+ ast = parse_ast(%q{
1491
1478
  template "/etc/foo.conf" do
1492
1479
  subscribes :run, "execute[robespierre]", :immediately
1493
1480
  end
1494
- })).first[:timing].must_equal(:immediate)
1481
+ })
1482
+ expect(api.notifications(ast).first[:timing]).to eq :immediate
1495
1483
  end
1496
1484
  end
1497
1485
  it "passes unrecognised notification timings through unchanged" do
1498
- api.notifications(parse_ast(%q{
1486
+ ast = parse_ast(%q{
1499
1487
  template "/etc/foo.conf" do
1500
1488
  notifies :run, resources(execute => "robespierre"), :forthwith
1501
1489
  end
1502
- })).first[:timing].must_equal(:forthwith)
1490
+ })
1491
+ expect(api.notifications(ast).first[:timing]).to eq :forthwith
1503
1492
  end
1504
1493
  describe "resource names as expressions" do
1505
1494
  describe "returns the AST for an embedded string" do
1506
1495
  it "old-style notifications" do
1507
- assert api.notifications(parse_ast(%q{
1496
+ ast = parse_ast(%q{
1508
1497
  template "/etc/foo.conf" do
1509
1498
  notifies :create, resources(:template => "/etc/bar/#{resource}.bar")
1510
1499
  end
1511
- })).first[:resource_name].respond_to?(:xpath),
1512
- "Expected resource_name with string expression to respond to #xpath"
1500
+ })
1501
+ expect(api.notifications(ast).first[:resource_name]).to respond_to :xpath
1513
1502
  end
1514
1503
  it "new-style notifications" do
1515
- assert api.notifications(parse_ast(%q{
1504
+ ast = parse_ast(%q{
1516
1505
  template "/etc/foo.conf" do
1517
1506
  notifies :create, "template[/etc/bar/#{resource}.bar]"
1518
1507
  end
1519
- })).first[:resource_name].respond_to?(:xpath),
1520
- "Expected resource_name with string expression to respond to #xpath"
1508
+ })
1509
+ expect(api.notifications(ast).first[:resource_name]).to respond_to :xpath
1521
1510
  end
1522
1511
  it "new-style notifications - complete resource_name" do
1523
- assert api.notifications(parse_ast(%q{
1512
+ ast = parse_ast(%q{
1524
1513
  template "/etc/foo.conf" do
1525
1514
  notifies :create, "template[#{template_path}]"
1526
1515
  end
1527
- })).first[:resource_name].respond_to?(:xpath),
1528
- "Expected resource_name with string expression to respond to #xpath"
1516
+ })
1517
+ expect(api.notifications(ast).first[:resource_name]).to respond_to :xpath
1529
1518
  end
1530
1519
  end
1531
1520
  describe "returns the AST for node attribute" do
1532
1521
  it "old-style notifications" do
1533
- assert api.notifications(parse_ast(%q{
1522
+ ast = parse_ast(%q{
1534
1523
  template "/etc/foo.conf" do
1535
1524
  notifies :restart, resources(:service => node['foo']['service'])
1536
1525
  end
1537
- })).first[:resource_name].respond_to?(:xpath),
1538
- "Expected resource_name with node attribute to respond to #xpath"
1526
+ })
1527
+ expect(api.notifications(ast).first[:resource_name]).to respond_to :xpath
1539
1528
  end
1540
1529
  it "new-style notifications" do
1541
- assert api.notifications(parse_ast(%q{
1530
+ ast = parse_ast(%q{
1542
1531
  template "/etc/foo.conf" do
1543
1532
  notifies :restart, "service[#{node['foo']['service']}]"
1544
1533
  end
1545
- })).first[:resource_name].respond_to?(:xpath),
1546
- "Expected resource_name with node attribute to respond to #xpath"
1534
+ })
1535
+ expect(api.notifications(ast).first[:resource_name]).to respond_to :xpath
1547
1536
  end
1548
1537
  end
1549
1538
  describe "returns the AST for variable reference" do
1550
1539
  it "old-style notifications" do
1551
- assert api.notifications(parse_ast(%q{
1540
+ ast = parse_ast(%q{
1552
1541
  template "/etc/foo.conf" do
1553
1542
  notifies :restart, resources(:service => my_service)
1554
1543
  end
1555
- })).first[:resource_name].respond_to?(:xpath),
1556
- "Expected resource_name with var ref to respond to #xpath"
1544
+ })
1545
+ expect(api.notifications(ast).first[:resource_name]).to respond_to :xpath
1557
1546
  end
1558
1547
  it "new-style notifications" do
1559
- assert api.notifications(parse_ast(%q{
1548
+ ast = parse_ast(%q{
1560
1549
  template "/etc/foo.conf" do
1561
1550
  notifies :restart, "service[#{my_service}]"
1562
1551
  end
1563
- })).first[:resource_name].respond_to?(:xpath),
1564
- "Expected resource_name with var ref to respond to #xpath"
1552
+ })
1553
+ expect(api.notifications(ast).first[:resource_name]).to respond_to :xpath
1565
1554
  end
1566
1555
  end
1567
1556
  end
1568
1557
  describe "mark style of notification" do
1569
1558
  it "specifies that the notification was in the old style" do
1570
- assert api.notifications(parse_ast(%q{
1559
+ ast = parse_ast(%q{
1571
1560
  template "/etc/foo.conf" do
1572
1561
  notifies :restart, resources(:service => 'foo')
1573
1562
  end
1574
- })).first[:style].must_equal :old
1563
+ })
1564
+ expect(api.notifications(ast).first[:style]).to eq :old
1575
1565
  end
1576
1566
  it "specifies that the notification was in the new style" do
1577
- assert api.notifications(parse_ast(%q{
1567
+ ast = parse_ast(%q{
1578
1568
  template "/etc/foo.conf" do
1579
1569
  notifies :restart, "service[foo]"
1580
1570
  end
1581
- })).first[:style].must_equal :new
1571
+ })
1572
+ expect(api.notifications(ast).first[:style]).to eq :new
1582
1573
  end
1583
1574
  end
1584
1575
  end
1585
1576
 
1586
1577
  describe "#read_ast" do
1587
1578
  it "raises if the file cannot be read" do
1588
- lambda { api.read_ast(nil) }.must_raise(TypeError)
1579
+ expect { api.read_ast(nil) }.to raise_error TypeError
1589
1580
  end
1590
1581
  end
1591
1582
 
@@ -1598,10 +1589,10 @@ describe FoodCritic::Api do
1598
1589
  end.new
1599
1590
  end
1600
1591
  it "raises if the resource does not support XPath" do
1601
- lambda { api.resource_attribute(nil, "mode") }.must_raise ArgumentError
1592
+ expect { api.resource_attribute(nil, "mode") }.to raise_error ArgumentError
1602
1593
  end
1603
1594
  it "raises if the attribute name is empty" do
1604
- lambda { api.resource_attribute(resource, "") }.must_raise ArgumentError
1595
+ expect { api.resource_attribute(resource, "") }.to raise_error ArgumentError
1605
1596
  end
1606
1597
  end
1607
1598
 
@@ -1610,7 +1601,7 @@ describe FoodCritic::Api do
1610
1601
  api.resource_attributes(api.find_resources(parse_ast(str)).first)
1611
1602
  end
1612
1603
  it "raises if the resource does not support XPath" do
1613
- lambda { api.resource_attributes(nil) }.must_raise ArgumentError
1604
+ expect { api.resource_attributes(nil) }.to raise_error ArgumentError
1614
1605
  end
1615
1606
  it "returns a string value for a literal string" do
1616
1607
  atts = str_to_atts(%q{
@@ -1618,8 +1609,7 @@ describe FoodCritic::Api do
1618
1609
  owner "root"
1619
1610
  end
1620
1611
  })
1621
- atts["owner"].wont_be_nil
1622
- atts["owner"].must_equal "root"
1612
+ expect(atts["owner"]).to eq "root"
1623
1613
  end
1624
1614
  it "returns a truthy value for a literal true" do
1625
1615
  atts = str_to_atts(%q{
@@ -1627,8 +1617,7 @@ describe FoodCritic::Api do
1627
1617
  recursive true
1628
1618
  end
1629
1619
  })
1630
- atts["recursive"].wont_be_nil
1631
- atts["recursive"].must_equal true
1620
+ expect(atts["recursive"]).to be true
1632
1621
  end
1633
1622
  it "returns a truthy value for a literal false" do
1634
1623
  atts = str_to_atts(%q{
@@ -1636,8 +1625,7 @@ describe FoodCritic::Api do
1636
1625
  recursive false
1637
1626
  end
1638
1627
  })
1639
- atts["recursive"].wont_be_nil
1640
- atts["recursive"].must_equal false
1628
+ expect(atts["recursive"]).to be false
1641
1629
  end
1642
1630
  it "decodes numeric attributes correctly" do
1643
1631
  atts = str_to_atts(%q{
@@ -1646,8 +1634,7 @@ describe FoodCritic::Api do
1646
1634
  mode 0755
1647
1635
  end
1648
1636
  })
1649
- atts["mode"].wont_be_nil
1650
- atts["mode"].must_equal "0755"
1637
+ expect(atts["mode"]).to eq "0755"
1651
1638
  end
1652
1639
  describe "block attributes" do
1653
1640
  it "includes attributes with brace block values in the result" do
@@ -1658,9 +1645,8 @@ describe FoodCritic::Api do
1658
1645
  only_if { File.exists?("/etc/bar") }
1659
1646
  end
1660
1647
  })
1661
- atts["only_if"].wont_be_nil
1662
- atts["only_if"].must_respond_to :xpath
1663
- atts["only_if"].name.must_equal "brace_block"
1648
+ expect(atts["only_if"]).to respond_to :xpath
1649
+ expect(atts["only_if"].name).to eq "brace_block"
1664
1650
  end
1665
1651
  it "includes attributes with do block values in the result" do
1666
1652
  atts = str_to_atts(%q{
@@ -1673,9 +1659,8 @@ describe FoodCritic::Api do
1673
1659
  end
1674
1660
  end
1675
1661
  })
1676
- atts["only_if"].wont_be_nil
1677
- atts["only_if"].must_respond_to :xpath
1678
- atts["only_if"].name.must_equal "do_block"
1662
+ expect(atts["only_if"]).to respond_to :xpath
1663
+ expect(atts["only_if"].name).to eq "do_block"
1679
1664
  end
1680
1665
  it "supports multiple block attributes" do
1681
1666
  atts = str_to_atts(%q{
@@ -1686,12 +1671,10 @@ describe FoodCritic::Api do
1686
1671
  not_if { true }
1687
1672
  end
1688
1673
  })
1689
- atts["only_if"].wont_be_nil
1690
- atts["only_if"].must_respond_to :xpath
1691
- atts["only_if"].name.must_equal "brace_block"
1692
- atts["not_if"].wont_be_nil
1693
- atts["not_if"].must_respond_to :xpath
1694
- atts["not_if"].name.must_equal "brace_block"
1674
+ expect(atts["only_if"]).to respond_to :xpath
1675
+ expect(atts["only_if"].name).to eq "brace_block"
1676
+ expect(atts["not_if"]).to respond_to :xpath
1677
+ expect(atts["not_if"].name).to eq "brace_block"
1695
1678
  end
1696
1679
  it "doesn't include method calls in ruby blocks" do
1697
1680
  atts = str_to_atts(%q{
@@ -1705,16 +1688,13 @@ describe FoodCritic::Api do
1705
1688
  not_if { false }
1706
1689
  end
1707
1690
  })
1708
- atts.keys.wont_include "foo"
1709
- atts["block"].wont_be_nil
1710
- atts["block"].must_respond_to :xpath
1711
- atts["block"].name.must_equal "do_block"
1712
- atts["only_if"].wont_be_nil
1713
- atts["only_if"].must_respond_to :xpath
1714
- atts["only_if"].name.must_equal "brace_block"
1715
- atts["not_if"].wont_be_nil
1716
- atts["not_if"].must_respond_to :xpath
1717
- atts["not_if"].name.must_equal "brace_block"
1691
+ expect(atts.keys).to_not include "foo"
1692
+ expect(atts["block"]).to respond_to :xpath
1693
+ expect(atts["block"].name).to eq "do_block"
1694
+ expect(atts["only_if"]).to respond_to :xpath
1695
+ expect(atts["only_if"].name).to eq "brace_block"
1696
+ expect(atts["not_if"]).to respond_to :xpath
1697
+ expect(atts["not_if"].name).to eq "brace_block"
1718
1698
  end
1719
1699
  it "includes notifications in the result" do
1720
1700
  atts = str_to_atts(%q{
@@ -1722,9 +1702,8 @@ describe FoodCritic::Api do
1722
1702
  notifies :restart, "service[apache]"
1723
1703
  end
1724
1704
  })
1725
- atts["notifies"].wont_be_nil
1726
- atts["notifies"].must_respond_to :xpath
1727
- atts["notifies"].name.must_equal "args_add_block"
1705
+ expect(atts["notifies"]).to respond_to :xpath
1706
+ expect(atts["notifies"].name).to eq "args_add_block"
1728
1707
  end
1729
1708
  it "includes old-style notifications in the result" do
1730
1709
  atts = str_to_atts(%q{
@@ -1732,90 +1711,91 @@ describe FoodCritic::Api do
1732
1711
  notifies :restart, resources(:service => "apache")
1733
1712
  end
1734
1713
  })
1735
- atts["notifies"].wont_be_nil
1736
- atts["notifies"].must_respond_to :xpath
1737
- atts["notifies"].name.must_equal "args_add_block"
1714
+ expect(atts["notifies"]).to respond_to :xpath
1715
+ expect(atts["notifies"].name).to eq "args_add_block"
1738
1716
  end
1739
1717
  end
1740
1718
  end
1741
1719
 
1742
1720
  describe "#resource_attributes_by_type" do
1743
1721
  it "raises if the ast does not support XPath" do
1744
- lambda { api.resource_attributes_by_type(nil) }.must_raise ArgumentError
1722
+ expect { api.resource_attributes_by_type(nil) }.to raise_error ArgumentError
1745
1723
  end
1746
1724
  it "returns an empty hash if there are no resources" do
1747
- ast = MiniTest::Mock.new.expect :xpath, [], [String]
1748
- api.resource_attributes_by_type(ast).keys.must_be_empty
1725
+ ast = double()
1726
+ expect(ast).to receive(:xpath).with(kind_of(String)).and_return([])
1727
+ expect(api.resource_attributes_by_type(ast)).to be_empty
1749
1728
  end
1750
1729
  end
1751
1730
 
1752
1731
  describe "#resource_name" do
1753
1732
  it "raises if the resource does not support XPath" do
1754
- lambda { api.resource_name("foo") }.must_raise ArgumentError
1733
+ expect { api.resource_name("foo") }.to raise_error ArgumentError
1755
1734
  end
1756
1735
  it "returns the resource name for a resource" do
1757
- ast = MiniTest::Mock.new
1758
- ast.expect :xpath, "bob", [String]
1759
- api.resource_name(ast).must_equal "bob"
1736
+ ast = double()
1737
+ expect(ast).to receive(:xpath).with(kind_of(String)).and_return("bob")
1738
+ expect(api.resource_name(ast)).to eq "bob"
1760
1739
  end
1761
1740
  end
1762
1741
 
1763
1742
  describe "#resources_by_type" do
1764
1743
  it "raises if the ast does not support XPath" do
1765
- lambda { api.resources_by_type(nil) }.must_raise ArgumentError
1744
+ expect { api.resources_by_type(nil) }.to raise_error ArgumentError
1766
1745
  end
1767
1746
  it "returns an empty hash if there are no resources" do
1768
- ast = MiniTest::Mock.new.expect :xpath, [], [String]
1769
- api.resources_by_type(ast).keys.must_be_empty
1747
+ ast = double()
1748
+ expect(ast).to receive(:xpath).with(kind_of(String)).and_return([])
1749
+ expect(api.resources_by_type(ast)).to be_empty
1770
1750
  end
1771
1751
  end
1772
1752
 
1773
1753
  describe "#resource_type" do
1774
1754
  it "raises if the resource does not support XPath" do
1775
- lambda { api.resource_type(nil) }.must_raise ArgumentError
1755
+ expect { api.resource_type(nil) }.to raise_error ArgumentError
1776
1756
  end
1777
1757
  it "raises if the resource type cannot be determined" do
1778
- ast = MiniTest::Mock.new
1779
- ast.expect :xpath, "", [String]
1780
- lambda { api.resource_type(ast) }.must_raise ArgumentError
1758
+ ast = double()
1759
+ expect(ast).to receive(:xpath).with(kind_of(String)).and_return("")
1760
+ expect { api.resource_type(ast) }.to raise_error ArgumentError
1781
1761
  end
1782
1762
  it "returns the resource type for a resource" do
1783
- ast = MiniTest::Mock.new
1784
- ast.expect :xpath, "directory", [String]
1785
- api.resource_type(ast).must_equal "directory"
1763
+ ast = double()
1764
+ expect(ast).to receive(:xpath).with(kind_of(String)).and_return("directory")
1765
+ expect(api.resource_type(ast)).to eq "directory"
1786
1766
  end
1787
1767
  end
1788
1768
 
1789
1769
  describe "#ruby_code?" do
1790
1770
  it "says a nil is not ruby code" do
1791
- refute api.ruby_code?(nil)
1771
+ expect(api.ruby_code?(nil)).to be_falsey
1792
1772
  end
1793
1773
  it "says an empty string is not ruby code" do
1794
- refute api.ruby_code?("")
1774
+ expect(api.ruby_code?("")).to be_falsey
1795
1775
  end
1796
1776
  it "coerces arguments to a string" do
1797
- assert api.ruby_code?(%w{foo bar})
1777
+ expect(api.ruby_code?(%w{foo bar})).to be_truthy
1798
1778
  end
1799
1779
  it "returns true for a snippet of ruby code" do
1800
- assert api.ruby_code?("assert api.ruby_code?(nil)")
1780
+ expect(api.ruby_code?("assert api.ruby_code?(nil)")).to be_truthy
1801
1781
  end
1802
1782
  it "returns false for a unix command" do
1803
- refute api.ruby_code?("find -type f -print")
1783
+ expect(api.ruby_code?("find -type f -print")).to be_falsey
1804
1784
  end
1805
1785
  end
1806
1786
 
1807
1787
  describe "#searches" do
1808
- let(:ast) { MiniTest::Mock.new }
1788
+ let(:ast) { double() }
1809
1789
  it "returns empty if the AST does not support XPath expressions" do
1810
- api.searches("not-an-ast").must_be_empty
1790
+ expect(api.searches("not-an-ast")).to be_empty
1811
1791
  end
1812
1792
  it "returns empty if the AST has no elements" do
1813
- ast.expect :xpath, [], [String]
1814
- api.searches(ast).must_be_empty
1793
+ expect(ast).to receive(:xpath).with(kind_of(String)).and_return([])
1794
+ expect(api.searches(ast)).to be_empty
1815
1795
  end
1816
1796
  it "returns the AST elements for each use of search" do
1817
- ast.expect :xpath, ["ident"], [String]
1818
- api.searches(ast).must_equal ["ident"]
1797
+ expect(ast).to receive(:xpath).with(kind_of(String)).and_return(["ident"])
1798
+ expect(api.searches(ast)).to eq ["ident"]
1819
1799
  end
1820
1800
  end
1821
1801
 
@@ -1824,20 +1804,19 @@ describe FoodCritic::Api do
1824
1804
  api.standard_cookbook_subdirs.each { |s| s }
1825
1805
  end
1826
1806
  it "is sorted in alphabetical order" do
1827
- api.standard_cookbook_subdirs.must_equal(
1828
- api.standard_cookbook_subdirs.sort)
1807
+ expect(api.standard_cookbook_subdirs).to eq api.standard_cookbook_subdirs.sort
1829
1808
  end
1830
1809
  it "includes the directories generated by knife create cookbook" do
1831
1810
  %w{attributes definitions files libraries providers recipes resources
1832
1811
  templates}.each do |dir|
1833
- api.standard_cookbook_subdirs.must_include dir
1812
+ expect(api.standard_cookbook_subdirs).to include dir
1834
1813
  end
1835
1814
  end
1836
1815
  it "does not include the spec directory" do
1837
- api.standard_cookbook_subdirs.wont_include "spec"
1816
+ expect(api.standard_cookbook_subdirs).to_not include "spec"
1838
1817
  end
1839
1818
  it "does not include a subdirectory of a subdirectory" do
1840
- api.standard_cookbook_subdirs.wont_include "default"
1819
+ expect(api.standard_cookbook_subdirs).to_not include "default"
1841
1820
  end
1842
1821
  end
1843
1822
 
@@ -1846,60 +1825,60 @@ describe FoodCritic::Api do
1846
1825
  api.supported_platforms(parse_ast(str))
1847
1826
  end
1848
1827
  it "returns an empty if no platforms are specified as supported" do
1849
- supports("name 'example'").must_be_empty
1828
+ expect(supports("name 'example'")).to be_empty
1850
1829
  end
1851
1830
  describe :ignored_support_declarations do
1852
1831
  it "should ignore supports without any arguments" do
1853
- supports("supports").must_be_empty
1832
+ expect(supports("supports")).to be_empty
1854
1833
  end
1855
1834
  it "should ignore supports where an embedded string expression is used" do
1856
- supports('supports "red#{hat}"').must_be_empty
1835
+ expect(supports('supports "red#{hat}"')).to be_empty
1857
1836
  end
1858
1837
  end
1859
1838
  it "returns the supported platform names if multiple are given" do
1860
- supports(%q{
1839
+ expect(supports(%q{
1861
1840
  supports "redhat"
1862
1841
  supports "scientific"
1863
- }).must_equal([{ :platform => "redhat", :versions => [] },
1864
- { :platform => "scientific", :versions => [] }])
1842
+ })).to eq [{ :platform => "redhat", :versions => [] },
1843
+ { :platform => "scientific", :versions => [] }]
1865
1844
  end
1866
1845
  it "sorts the platform names in alphabetical order" do
1867
- supports(%q{
1846
+ expect(supports(%q{
1868
1847
  supports "scientific"
1869
1848
  supports "redhat"
1870
- }).must_equal([{ :platform => "redhat", :versions => [] },
1871
- { :platform => "scientific", :versions => [] }])
1849
+ })).to eq [{ :platform => "redhat", :versions => [] },
1850
+ { :platform => "scientific", :versions => [] }]
1872
1851
  end
1873
1852
  it "handles support declarations that include version constraints" do
1874
- supports(%q{
1853
+ expect(supports(%q{
1875
1854
  supports "redhat", '>= 6'
1876
- }).must_equal([{ :platform => "redhat", :versions => [">= 6"] }])
1855
+ })).to eq [{ :platform => "redhat", :versions => [">= 6"] }]
1877
1856
  end
1878
1857
  it "handles support declarations that include obsoleted version constraints" do
1879
- supports(%q{
1858
+ expect(supports(%q{
1880
1859
  supports 'redhat', '> 5.0', '< 7.0'
1881
1860
  supports 'scientific', '> 5.0', '< 6.0'
1882
- }).must_equal([{ :platform => "redhat", :versions => ["> 5.0", "< 7.0"] },
1883
- { :platform => "scientific", :versions => ["> 5.0", "< 6.0"] }])
1861
+ })).to eq [{ :platform => "redhat", :versions => ["> 5.0", "< 7.0"] },
1862
+ { :platform => "scientific", :versions => ["> 5.0", "< 6.0"] }]
1884
1863
  end
1885
1864
  it "normalises platform symbol references to strings" do
1886
- supports(%q{
1865
+ expect(supports(%q{
1887
1866
  supports :ubuntu
1888
- }).must_equal([{ :platform => "ubuntu", :versions => [] }])
1867
+ })).to eq [{ :platform => "ubuntu", :versions => [] }]
1889
1868
  end
1890
1869
  it "handles support declarations as symbols that include version constraints" do
1891
- supports(%q{
1870
+ expect(supports(%q{
1892
1871
  supports :redhat, '>= 6'
1893
- }).must_equal([{ :platform => "redhat", :versions => [">= 6"] }])
1872
+ })).to eq [{ :platform => "redhat", :versions => [">= 6"] }]
1894
1873
  end
1895
1874
  it "understands support declarations that use word lists" do
1896
- supports(%q{
1875
+ expect(supports(%q{
1897
1876
  %w{redhat centos fedora}.each do |os|
1898
- supports os
1899
- end
1900
- }).must_equal([{ :platform => "centos", :versions => [] },
1901
- { :platform => "fedora", :versions => [] },
1902
- { :platform => "redhat", :versions => [] }])
1877
+ supports os
1878
+ end
1879
+ })).to eq [{ :platform => "centos", :versions => [] },
1880
+ { :platform => "fedora", :versions => [] },
1881
+ { :platform => "redhat", :versions => [] }]
1903
1882
  end
1904
1883
  end
1905
1884
 
@@ -1920,67 +1899,44 @@ describe FoodCritic::Api do
1920
1899
 
1921
1900
  it "returns the path of the containing template when there are no partials" do
1922
1901
  ast = parse_ast("<%= foo.erb %>")
1923
- api.stub :read_ast, ast do
1924
- api.templates_included(["foo.erb"], "foo.erb").must_equal ["foo.erb"]
1925
- end
1902
+ expect(api).to receive(:read_ast).with("foo.erb").and_return(ast)
1903
+ expect(api.templates_included(["foo.erb"], "foo.erb")).to eq ["foo.erb"]
1926
1904
  end
1927
1905
 
1928
1906
  it "returns the path of the containing template and any partials" do
1929
- api.instance_variable_set(:@asts, {
1930
- :main => template_ast('<%= render "included_1.erb" %>
1931
- <%= render "included_2.erb" %>'),
1932
- :ok => template_ast("<%= @foo %>"),
1933
- })
1934
- def api.read_ast(path)
1935
- case path
1936
- when /main/ then @asts[:main]
1937
- else @asts[:ok]
1938
- end
1939
- end
1940
- api.templates_included(all_templates,
1941
- "templates/default/main.erb").must_equal(
1942
- ["templates/default/main.erb",
1943
- "templates/default/included_1.erb",
1944
- "templates/default/included_2.erb"]
1945
- )
1907
+ main_ast = template_ast('<%= render "included_1.erb" %>
1908
+ <%= render "included_2.erb" %>')
1909
+ inner_ast = template_ast("<%= @foo %>")
1910
+ expect(api).to receive(:read_ast).with(/main/).and_return(main_ast)
1911
+ expect(api).to receive(:read_ast).and_return(inner_ast).twice
1912
+ expect(api.templates_included(all_templates, "templates/default/main.erb")).to eq [
1913
+ "templates/default/main.erb",
1914
+ "templates/default/included_1.erb",
1915
+ "templates/default/included_2.erb",
1916
+ ]
1946
1917
  end
1947
1918
 
1948
1919
  it "doesn't mistake render options for partial template names" do
1949
- api.instance_variable_set(:@asts, {
1950
- :main => template_ast('<%= render "included_1.erb",
1951
- :variables => {:foo => "included_2.erb"} %>'),
1952
- :ok => template_ast("<%= @foo %>"),
1953
- })
1954
- def api.read_ast(path)
1955
- case path
1956
- when /main/ then @asts[:main]
1957
- else @asts[:ok]
1958
- end
1959
- end
1960
- api.templates_included(all_templates,
1961
- "templates/default/main.erb").must_equal(
1962
- ["templates/default/main.erb", "templates/default/included_1.erb"]
1963
- )
1920
+ main_ast = template_ast('<%= render "included_1.erb",
1921
+ :variables => {:foo => "included_2.erb"} %>')
1922
+ inner_ast = template_ast("<%= @foo %>")
1923
+ expect(api).to receive(:read_ast).with(/main/).and_return(main_ast)
1924
+ expect(api).to receive(:read_ast).and_return(inner_ast)
1925
+ expect(api.templates_included(all_templates, "templates/default/main.erb")).to eq [
1926
+ "templates/default/main.erb",
1927
+ "templates/default/included_1.erb",
1928
+ ]
1964
1929
  end
1965
1930
 
1966
1931
  it "raises if included partials have cycles" do
1967
- api.instance_variable_set(:@asts, {
1968
- :main => template_ast('<%= render "included_1.erb" %>
1969
- <%= render "included_2.erb" %>'),
1970
- :loop => template_ast('<%= render "main.erb" %>'),
1971
- :ok => template_ast("<%= foo %>"),
1972
- })
1973
- def api.read_ast(path)
1974
- case path
1975
- when /main/ then @asts[:main]
1976
- when /included_2/ then @asts[:loop]
1977
- else @asts[:ok]
1978
- end
1979
- end
1980
- err = lambda do
1981
- api.templates_included(all_templates, "templates/default/main.erb")
1982
- end.must_raise(FoodCritic::Api::RecursedTooFarError)
1983
- err.message.must_equal "templates/default/main.erb"
1932
+ main_ast = template_ast('<%= render "included_1.erb" %>
1933
+ <%= render "included_2.erb" %>')
1934
+ loop_ast = template_ast('<%= render "main.erb" %>')
1935
+ inner_ast = template_ast("<%= foo %>")
1936
+ expect(api).to receive(:read_ast).with(/main/).and_return(main_ast).at_least(:once)
1937
+ expect(api).to receive(:read_ast).with(/included_2/).and_return(loop_ast).at_least(:once)
1938
+ expect(api).to receive(:read_ast).and_return(inner_ast).at_least(:once)
1939
+ expect { api.templates_included(all_templates, "templates/default/main.erb") }.to raise_error(FoodCritic::Api::RecursedTooFarError, "templates/default/main.erb")
1984
1940
  end
1985
1941
  end
1986
1942