chefspec-chef 9.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +30 -0
  3. data/LICENSE +22 -0
  4. data/Rakefile +85 -0
  5. data/chefspec-chef.gemspec +30 -0
  6. data/lib/chefspec/api/core.rb +217 -0
  7. data/lib/chefspec/api/described.rb +53 -0
  8. data/lib/chefspec/api/do_nothing.rb +26 -0
  9. data/lib/chefspec/api/include_any_recipe.rb +24 -0
  10. data/lib/chefspec/api/include_recipe.rb +28 -0
  11. data/lib/chefspec/api/link.rb +28 -0
  12. data/lib/chefspec/api/notifications.rb +40 -0
  13. data/lib/chefspec/api/reboot.rb +14 -0
  14. data/lib/chefspec/api/render_file.rb +37 -0
  15. data/lib/chefspec/api/state_attrs.rb +30 -0
  16. data/lib/chefspec/api/stubs.rb +183 -0
  17. data/lib/chefspec/api/stubs_for.rb +139 -0
  18. data/lib/chefspec/api/subscriptions.rb +37 -0
  19. data/lib/chefspec/api/user.rb +230 -0
  20. data/lib/chefspec/api.rb +39 -0
  21. data/lib/chefspec/berkshelf.rb +63 -0
  22. data/lib/chefspec/cacher.rb +64 -0
  23. data/lib/chefspec/coverage/filters.rb +82 -0
  24. data/lib/chefspec/coverage.rb +247 -0
  25. data/lib/chefspec/deprecations.rb +46 -0
  26. data/lib/chefspec/errors.rb +48 -0
  27. data/lib/chefspec/expect_exception.rb +51 -0
  28. data/lib/chefspec/extensions/chef/client.rb +21 -0
  29. data/lib/chefspec/extensions/chef/conditional.rb +16 -0
  30. data/lib/chefspec/extensions/chef/cookbook/gem_installer.rb +33 -0
  31. data/lib/chefspec/extensions/chef/cookbook_loader.rb +14 -0
  32. data/lib/chefspec/extensions/chef/cookbook_uploader.rb +12 -0
  33. data/lib/chefspec/extensions/chef/data_query.rb +49 -0
  34. data/lib/chefspec/extensions/chef/lwrp_base.rb +29 -0
  35. data/lib/chefspec/extensions/chef/provider.rb +39 -0
  36. data/lib/chefspec/extensions/chef/resource/freebsd_package.rb +17 -0
  37. data/lib/chefspec/extensions/chef/resource.rb +188 -0
  38. data/lib/chefspec/extensions/chef/run_context/cookbook_compiler.rb +84 -0
  39. data/lib/chefspec/extensions/chef/securable.rb +19 -0
  40. data/lib/chefspec/extensions/ohai/system.rb +11 -0
  41. data/lib/chefspec/extensions.rb +21 -0
  42. data/lib/chefspec/file_cache_path_proxy.rb +15 -0
  43. data/lib/chefspec/formatter.rb +282 -0
  44. data/lib/chefspec/librarian.rb +51 -0
  45. data/lib/chefspec/matchers/do_nothing_matcher.rb +52 -0
  46. data/lib/chefspec/matchers/include_any_recipe_matcher.rb +51 -0
  47. data/lib/chefspec/matchers/include_recipe_matcher.rb +46 -0
  48. data/lib/chefspec/matchers/link_to_matcher.rb +37 -0
  49. data/lib/chefspec/matchers/notifications_matcher.rb +143 -0
  50. data/lib/chefspec/matchers/render_file_matcher.rb +140 -0
  51. data/lib/chefspec/matchers/resource_matcher.rb +175 -0
  52. data/lib/chefspec/matchers/state_attrs_matcher.rb +71 -0
  53. data/lib/chefspec/matchers/subscribes_matcher.rb +72 -0
  54. data/lib/chefspec/matchers.rb +13 -0
  55. data/lib/chefspec/mixins/normalize.rb +22 -0
  56. data/lib/chefspec/policyfile.rb +69 -0
  57. data/lib/chefspec/renderer.rb +145 -0
  58. data/lib/chefspec/rspec.rb +21 -0
  59. data/lib/chefspec/runner.rb +8 -0
  60. data/lib/chefspec/server.rb +4 -0
  61. data/lib/chefspec/server_methods.rb +173 -0
  62. data/lib/chefspec/server_runner.rb +76 -0
  63. data/lib/chefspec/solo_runner.rb +516 -0
  64. data/lib/chefspec/stubs/command_registry.rb +11 -0
  65. data/lib/chefspec/stubs/command_stub.rb +37 -0
  66. data/lib/chefspec/stubs/data_bag_item_registry.rb +13 -0
  67. data/lib/chefspec/stubs/data_bag_item_stub.rb +25 -0
  68. data/lib/chefspec/stubs/data_bag_registry.rb +13 -0
  69. data/lib/chefspec/stubs/data_bag_stub.rb +23 -0
  70. data/lib/chefspec/stubs/registry.rb +32 -0
  71. data/lib/chefspec/stubs/search_registry.rb +13 -0
  72. data/lib/chefspec/stubs/search_stub.rb +25 -0
  73. data/lib/chefspec/stubs/stub.rb +38 -0
  74. data/lib/chefspec/util.rb +58 -0
  75. data/lib/chefspec/version.rb +3 -0
  76. data/lib/chefspec/zero_server.rb +142 -0
  77. data/lib/chefspec.rb +75 -0
  78. data/spec/spec_helper.rb +12 -0
  79. data/spec/support/hash.rb +35 -0
  80. data/spec/unit/cacher_spec.rb +70 -0
  81. data/spec/unit/coverage/filters_spec.rb +60 -0
  82. data/spec/unit/deprecations_spec.rb +52 -0
  83. data/spec/unit/errors_spec.rb +57 -0
  84. data/spec/unit/expect_exception_spec.rb +32 -0
  85. data/spec/unit/macros_spec.rb +119 -0
  86. data/spec/unit/matchers/do_nothing_matcher.rb +5 -0
  87. data/spec/unit/matchers/include_any_recipe_matcher_spec.rb +52 -0
  88. data/spec/unit/matchers/include_recipe_matcher_spec.rb +38 -0
  89. data/spec/unit/matchers/link_to_matcher_spec.rb +55 -0
  90. data/spec/unit/matchers/notifications_matcher_spec.rb +39 -0
  91. data/spec/unit/matchers/render_file_matcher_spec.rb +68 -0
  92. data/spec/unit/matchers/resource_matcher_spec.rb +5 -0
  93. data/spec/unit/matchers/state_attrs_matcher_spec.rb +68 -0
  94. data/spec/unit/matchers/subscribes_matcher_spec.rb +63 -0
  95. data/spec/unit/renderer_spec.rb +69 -0
  96. data/spec/unit/server_runner_spec.rb +28 -0
  97. data/spec/unit/solo_runner_spec.rb +171 -0
  98. data/spec/unit/stubs/command_registry_spec.rb +27 -0
  99. data/spec/unit/stubs/command_stub_spec.rb +61 -0
  100. data/spec/unit/stubs/data_bag_item_registry_spec.rb +39 -0
  101. data/spec/unit/stubs/data_bag_item_stub_spec.rb +36 -0
  102. data/spec/unit/stubs/data_bag_registry_spec.rb +39 -0
  103. data/spec/unit/stubs/data_bag_stub_spec.rb +35 -0
  104. data/spec/unit/stubs/registry_spec.rb +29 -0
  105. data/spec/unit/stubs/search_registry_spec.rb +39 -0
  106. data/spec/unit/stubs/search_stub_spec.rb +36 -0
  107. data/spec/unit/stubs/stub_spec.rb +64 -0
  108. data/templates/coverage/human.erb +22 -0
  109. data/templates/coverage/json.erb +8 -0
  110. data/templates/coverage/table.erb +14 -0
  111. data/templates/errors/cookbook_path_not_found.erb +3 -0
  112. data/templates/errors/erb_template_parse_error.erb +5 -0
  113. data/templates/errors/gem_load_error.erb +7 -0
  114. data/templates/errors/invalid_berkshelf_options.erb +4 -0
  115. data/templates/errors/may_need_to_specify_platform.erb +25 -0
  116. data/templates/errors/no_conversion_error.erb +1 -0
  117. data/templates/errors/not_stubbed.erb +7 -0
  118. data/templates/errors/shell_out_not_stubbed.erb +10 -0
  119. data/templates/errors/template_not_found.erb +9 -0
  120. metadata +221 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ff591aba0dfcbf3e5260ac9a313dcb6d4712e242399a1141d8b5a4826a38510e
4
+ data.tar.gz: 76c87147defb9b4e50aac7d3f21e7c8b7e8ec37366cdb008841df885547269b1
5
+ SHA512:
6
+ metadata.gz: 843e62a9f07eca7637e0a319624b889a400ccf618dfc5c94080068ee3291207ca2284291c33f34253f8ce61854438a5a8a380863ffb3c0d8dff889230e347fbd
7
+ data.tar.gz: 8af007117d07d1024cded0ce067168567d0907595fc0c0a62db5648c66b2d23a203e67e39141c5b493092f4b744a5210397ed9bde11c8ffafd1bdbc831f69c46
data/Gemfile ADDED
@@ -0,0 +1,30 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem "rake"
7
+ gem "redcarpet"
8
+ gem "yard"
9
+ gem "pry"
10
+ gem "pry-byebug"
11
+ gem "chefstyle"
12
+ end
13
+
14
+ if ENV["GEMFILE_MOD"]
15
+ puts "GEMFILE_MOD: #{ENV["GEMFILE_MOD"]}"
16
+ instance_eval(ENV["GEMFILE_MOD"])
17
+ else
18
+ gem "chef", git: "https://github.com/chef/chef"
19
+ gem "ohai", git: "https://github.com/chef/ohai"
20
+ end
21
+
22
+ # TODO: remove when we drop ruby 2.5
23
+ if Gem.ruby_version < Gem::Version.new("2.6")
24
+ # 16.7.23 required ruby 2.6+
25
+ gem "chef-utils", "< 16.7.23"
26
+ end
27
+
28
+ # If you want to load debugging tools into the bundle exec sandbox,
29
+ # add these additional dependencies into Gemfile.local
30
+ eval_gemfile(__FILE__ + ".local") if File.exist?(__FILE__ + ".local")
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License
2
+
3
+ Copyright (C) 2011 by Andrew Crump
4
+ Copyright (C) 2013 by Seth Vargo
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,85 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core"
3
+ require "rspec/core/rake_task"
4
+ require "yard/rake/yardoc_task"
5
+ require "tmpdir"
6
+ require "rspec"
7
+ require "chefspec"
8
+ require "chefstyle"
9
+
10
+ require "chef/version"
11
+
12
+ require "rubocop/rake_task"
13
+ RuboCop::RakeTask.new(:style) do |task|
14
+ task.options << "--display-cop-names"
15
+ end
16
+
17
+ YARD::Rake::YardocTask.new
18
+
19
+ RSpec::Core::RakeTask.new(:unit) do |t|
20
+ t.rspec_opts = [].tap do |a|
21
+ a.push("--color")
22
+ a.push("--format progress")
23
+ end.join(" ")
24
+ end
25
+
26
+ failed = []
27
+ start_time = nil
28
+
29
+ namespace :acceptance do |ns|
30
+
31
+ Dir.foreach("examples") do |dir|
32
+ next if %w{. .. .DS_Store}.include?(dir)
33
+
34
+ desc "#{dir} acceptance tests"
35
+ task dir.to_sym do
36
+ start_time ||= Time.now
37
+ Dir.mktmpdir do |tmp|
38
+ FileUtils.cp_r("examples/#{dir}", tmp)
39
+
40
+ pwd = Dir.pwd
41
+
42
+ Dir.chdir "#{tmp}/#{dir}" do
43
+ puts "rspec examples/#{dir}"
44
+
45
+ #
46
+ # This bit of mildly awful magic below is to load each file into an in-memory
47
+ # RSpec runner while keeping a persistent ChefZero server alive.
48
+ #
49
+ load "#{pwd}/lib/chefspec/rspec.rb"
50
+
51
+ RSpec.configure do |config|
52
+ config.full_backtrace = true
53
+ config.color = true
54
+ config.run_all_when_everything_filtered = true
55
+ config.filter_run(:focus)
56
+ config.before(:suite) do
57
+ ChefSpec::ZeroServer.setup!
58
+ end
59
+ config.after(:each) do
60
+ ChefSpec::ZeroServer.reset!
61
+ end
62
+ end
63
+
64
+ RSpec.clear_examples
65
+ exitstatus = RSpec::Core::Runner.run(["spec"])
66
+ RSpec.reset
67
+ failed << dir unless exitstatus == 0
68
+ end
69
+ end
70
+ end
71
+ end
72
+ rescue Errno::ENOENT # examples dir is probably missing
73
+ puts "The rake acceptance tests require a full git checkout of chefspec including all examples files!"
74
+
75
+ end
76
+
77
+ task acceptance: Rake.application.tasks.select { |t| t.name.start_with?("acceptance:") } do
78
+ puts "Acceptance tests took #{Time.now - start_time} seconds"
79
+ raise "some tests failed: #{failed.join(", ")}" unless failed.empty?
80
+ end
81
+
82
+ desc "Run all tests"
83
+ task test: %i{unit acceptance}
84
+
85
+ task default: [:test]
@@ -0,0 +1,30 @@
1
+ lib = File.expand_path("lib", __dir__)
2
+ $:.unshift lib unless $:.include?(lib)
3
+ require "chefspec/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "chefspec-chef"
7
+ s.version = ChefSpec::VERSION
8
+ s.authors = ["Andrew Crump", "Seth Vargo"]
9
+ s.email = ["andrew.crump@ieee.org", "sethvargo@gmail.com"]
10
+ s.summary = "Write RSpec examples and generate coverage reports for " \
11
+ "Chef recipes!"
12
+ s.description = "ChefSpec is a unit testing and resource coverage " \
13
+ "(code coverage) framework for testing Chef cookbooks " \
14
+ "ChefSpec makes it easy to write examples and get fast " \
15
+ "feedback on cookbook changes without the need for " \
16
+ "virtual machines or cloud servers."
17
+ s.homepage = "https://github.com/chef/chefspec"
18
+ s.license = "MIT"
19
+
20
+ # Packaging
21
+ s.files = %w{LICENSE Rakefile Gemfile chefspec-chef.gemspec} + Dir.glob("{lib,templates,spec}/**/*", File::FNM_DOTMATCH).reject { |f| File.directory?(f) }
22
+ s.require_paths = ["lib"]
23
+
24
+ s.required_ruby_version = ">= 2.5"
25
+
26
+ s.add_dependency "chef", ">= 15"
27
+ s.add_dependency "chef-cli"
28
+ s.add_dependency "fauxhai-chef", ">= 9.3"
29
+ s.add_dependency "rspec", "~> 3.0"
30
+ end
@@ -0,0 +1,217 @@
1
+ module ChefSpec
2
+ module API
3
+ # Module containing the core RSpec API for ChefSpec.
4
+ module Core
5
+ # Pull in the needed machinery to use `around` and `let` in here.
6
+ extend RSpec::SharedContext
7
+
8
+ # Activate all of the various ChefSpec stubs for the duraction of this
9
+ # example block.
10
+ around do |ex|
11
+ old_chefspec_mode = $CHEFSPEC_MODE
12
+ $CHEFSPEC_MODE = true
13
+ begin
14
+ # Only run the preload if a platform is configured via the new system
15
+ # since otherwise it will spam warnings about the platform not being
16
+ # set.
17
+ chef_runner_instance.preload! if chefspec_platform
18
+ ex.run
19
+ ensure
20
+ $CHEFSPEC_MODE = old_chefspec_mode
21
+ end
22
+ end
23
+
24
+ # Let variables to set data in a scoped way. Used below by
25
+ # {ClassMethods#platform}.
26
+ let(:chefspec_default_attributes) { chefspec_attributes(:default_attributes) }
27
+ let(:chefspec_normal_attributes) { chefspec_attributes(:normal_attributes) }
28
+ let(:chefspec_override_attributes) { chefspec_attributes(:override_attributes) }
29
+ let(:chefspec_automatic_attributes) { chefspec_attributes(:automatic_attributes) }
30
+ let(:chefspec_platform) { nil }
31
+ let(:chefspec_platform_version) { nil }
32
+
33
+ # Compute the options for the runner.
34
+ #
35
+ # @abstract
36
+ # @return [Hash<Symbol, Object>]
37
+ def chef_runner_options
38
+ options = {
39
+ step_into: chefspec_ancestor_gather([], :step_into) { |memo, val| memo | val },
40
+ default_attributes: chefspec_default_attributes,
41
+ normal_attributes: chefspec_normal_attributes,
42
+ override_attributes: chefspec_override_attributes,
43
+ automatic_attributes: chefspec_automatic_attributes,
44
+ spec_declaration_locations: self.class.declaration_locations.last[0],
45
+ }
46
+ # Only specify these if set in the example so we don't override the
47
+ # global settings.
48
+ options[:platform] = chefspec_platform if chefspec_platform
49
+ options[:version] = chefspec_platform_version if chefspec_platform_version
50
+ # Merge in any final overrides.
51
+ options.update(chefspec_attributes(:chefspec_options).symbolize_keys)
52
+ options
53
+ end
54
+
55
+ # Class of runner to use.
56
+ #
57
+ # @abstract
58
+ # @return [Class]
59
+ def chef_runner_class
60
+ ChefSpec::SoloRunner
61
+ end
62
+
63
+ # Create an instance of the runner.
64
+ #
65
+ # This should only be used in cases where the `let()` cache would be a problem.
66
+ #
67
+ # @return [ChefSpec::SoloRunner]
68
+ def chef_runner_instance
69
+ chef_runner_class.new(chef_runner_options)
70
+ end
71
+
72
+ # Set up the runner object but don't actually run anything yet.
73
+ let(:chef_runner) { chef_runner_instance }
74
+
75
+ # By default, run the recipe in the base `describe` block.
76
+ let(:chef_run) { chef_runner.converge(described_recipe) }
77
+
78
+ # Helper method for some of the nestable test value methods like
79
+ # {ClassMethods#default_attributes} and {ClassMethods#step_into}.
80
+ #
81
+ # @api private
82
+ # @param start [Object] Initial value for the reducer.
83
+ # @param method [Symbol] Name of the group-level method to call on each
84
+ # ancestor.
85
+ # @param block [Proc] Reducer callable.
86
+ # @return [Object]
87
+ def chefspec_ancestor_gather(start, method, &block)
88
+ candidate_ancestors = self.class.ancestors.select { |cls| cls.respond_to?(method) && cls != ChefSpec::API::Core }
89
+ candidate_ancestors.reverse.inject(start) do |memo, cls|
90
+ block.call(memo, cls.send(method))
91
+ end
92
+ end
93
+
94
+ # Special case of {#chefspec_ancestor_gather} because we do it four times.
95
+ #
96
+ # @api private
97
+ # @param method [Symbol] Name of the group-level method to call on each
98
+ # ancestor.
99
+ # @return [Mash]
100
+ def chefspec_attributes(method)
101
+ chefspec_ancestor_gather(Mash.new, method) do |memo, val|
102
+ Chef::Mixin::DeepMerge.merge(memo, val)
103
+ end
104
+ end
105
+
106
+ # Methods that will end up as group-level.
107
+ #
108
+ # @api private
109
+ module ClassMethods
110
+ # Set the Fauxhai platform to use for this example group.
111
+ #
112
+ # @example
113
+ # describe 'myrecipe' do
114
+ # platform 'ubuntu', '18.04'
115
+ # @param name [String] Platform name to set.
116
+ # @param version [String, nil] Platform version to set.
117
+ # @return [void]
118
+ def platform(name, version = nil)
119
+ let(:chefspec_platform) { name }
120
+ let(:chefspec_platform_version) { version }
121
+ end
122
+
123
+ # Use an in-line block of recipe code for this example group rather
124
+ # than a recipe from a cookbook.
125
+ #
126
+ # @example
127
+ # describe 'my_resource' do
128
+ # recipe do
129
+ # my_resource 'helloworld'
130
+ # end
131
+ # @param block [Proc] A block of Chef recipe code.
132
+ # @return [void]
133
+ def recipe(&block)
134
+ let(:chef_run) do
135
+ chef_runner.converge_block(&block)
136
+ end
137
+ end
138
+
139
+ # Set default-level node attributes to use for this example group.
140
+ #
141
+ # @example
142
+ # describe 'myapp::install' do
143
+ # default_attributes['myapp']['version'] = '1.0'
144
+ # @return [Chef::Node::VividMash]
145
+ def default_attributes
146
+ @chefspec_default_attributes ||= Chef::Node::VividMash.new
147
+ end
148
+
149
+ # Set normal-level node attributes to use for this example group.
150
+ #
151
+ # @example
152
+ # describe 'myapp::install' do
153
+ # normal_attributes['myapp']['version'] = '1.0'
154
+ # @return [Chef::Node::VividMash]
155
+ def normal_attributes
156
+ @chefspec_normal_attributes ||= Chef::Node::VividMash.new
157
+ end
158
+
159
+ # Set override-level node attributes to use for this example group.
160
+ #
161
+ # @example
162
+ # describe 'myapp::install' do
163
+ # override_attributes['myapp']['version'] = '1.0'
164
+ # @return [Chef::Node::VividMash]
165
+ def override_attributes
166
+ @chefspec_override_attributes ||= Chef::Node::VividMash.new
167
+ end
168
+
169
+ # Set automatic-level node attributes to use for this example group.
170
+ #
171
+ # @example
172
+ # describe 'myapp::install' do
173
+ # automatic_attributes['kernel']['machine'] = 'ppc64'
174
+ # @return [Chef::Node::VividMash]
175
+ def automatic_attributes
176
+ @chefspec_automatic_attributes ||= Chef::Node::VividMash.new
177
+ end
178
+
179
+ # Set additional ChefSpec runner options to use for this example group.
180
+ #
181
+ # @example
182
+ # describe 'myapp::install' do
183
+ # chefspec_options[:log_level] = :debug
184
+ # @return [Chef::Node::VividMash]
185
+ def chefspec_options
186
+ @chefspec_options ||= Chef::Node::VividMash.new
187
+ end
188
+
189
+ # Add resources to the step_into list for this example group.
190
+ #
191
+ # @example
192
+ # describe 'myapp::install' do
193
+ # step_into :my_resource
194
+ # @return [Array]
195
+ def step_into(*resources)
196
+ @chefspec_step_into ||= []
197
+ @chefspec_step_into |= resources.flatten.map(&:to_s)
198
+ end
199
+
200
+ # @api private
201
+ def included(klass)
202
+ super
203
+ # Inject classmethods into the group.
204
+ klass.extend(ClassMethods)
205
+ # If the describe block is aimed at string or resource/provider class
206
+ # then set the default subject to be the Chef run.
207
+ if klass.described_class.nil? || klass.described_class.is_a?(Class) && (klass.described_class < Chef::Resource || klass.described_class < Chef::Provider)
208
+ klass.subject { chef_run }
209
+ end
210
+ end
211
+ end
212
+
213
+ extend ClassMethods
214
+
215
+ end
216
+ end
217
+ end
@@ -0,0 +1,53 @@
1
+ module ChefSpec
2
+ module API
3
+ module Described
4
+ #
5
+ # The name of the currently running cookbook spec. Given the top-level
6
+ # +describe+ block is of the format:
7
+ #
8
+ # describe 'my_cookbook::my_recipe' do
9
+ # # ...
10
+ # end
11
+ #
12
+ # The value of +described_cookbook+ is "my_cookbook".
13
+ #
14
+ # @example Using +described_cookbook+ in a context block
15
+ # context "#{described_recipe} installs foo" do
16
+ # # ...
17
+ # end
18
+ #
19
+ #
20
+ # @return [String]
21
+ #
22
+ def described_cookbook
23
+ described_recipe.split("::").first
24
+ end
25
+
26
+ #
27
+ # The name of the currently running recipe spec. Given the top-level
28
+ # +describe+ block is of the format:
29
+ #
30
+ # describe 'my_cookbook::my_recipe' do
31
+ # # ...
32
+ # end
33
+ #
34
+ # The value of +described_recipe+ is "my_cookbook::my_recipe".
35
+ #
36
+ # @example Using +described_recipe+ in the +ChefSpec::SoloRunner+
37
+ # let(:chef_run) { ChefSpec::SoloRunner.new.converge(described_recipe) }
38
+ #
39
+ #
40
+ # @return [String]
41
+ #
42
+ def described_recipe
43
+ scope = is_a?(Class) ? self : self.class
44
+
45
+ metahash = scope.metadata
46
+ metahash = metahash[:parent_example_group] while metahash.key?(:parent_example_group)
47
+
48
+ metahash[:description].to_s
49
+ end
50
+
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,26 @@
1
+ module ChefSpec
2
+ module API
3
+ module DoNothing
4
+ #
5
+ # Assert that a resource in the Chef run does not perform any actions. Given
6
+ # a resource with +action :nothing+:
7
+ #
8
+ # package 'apache2' do
9
+ # action :nothing
10
+ # end
11
+ #
12
+ # The Examples section demonstrates the different ways to test that no
13
+ # actions were performed on a resource in a Chef run.
14
+ #
15
+ # @example Assert the +package+ does not perform any actions
16
+ # expect(chef_run.package('apache2')).to do_nothing
17
+ #
18
+ # @return [ChefSpec::Matchers::DoNothingMatcher]
19
+ #
20
+ def do_nothing
21
+ ChefSpec::Matchers::DoNothingMatcher.new
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,24 @@
1
+ module ChefSpec
2
+ module API
3
+ module IncludeAnyRecipe
4
+ #
5
+ # Assert that a Chef run includes any recipe.
6
+ #
7
+ # include_recipe 'apache2::default'
8
+ #
9
+ # The Examples section demonstrates the different ways to test an
10
+ # +include_any_recipe+ directive with ChefSpec.
11
+ #
12
+ # @example Assert the Chef run did not include any recipes
13
+ # expect(chef_run).not_to include_any_recipe
14
+ #
15
+ #
16
+ # @return [ChefSpec::Matchers::IncludeAnyRecipeMatcher]
17
+ #
18
+ def include_any_recipe
19
+ ChefSpec::Matchers::IncludeAnyRecipeMatcher.new
20
+ end
21
+ alias_method :include_any_recipes, :include_any_recipe
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,28 @@
1
+ module ChefSpec
2
+ module API
3
+ module IncludeRecipe
4
+ #
5
+ # Assert that a Chef run includes a certain recipe. Given a Chef Recipe
6
+ # that calls +include_recipe+:
7
+ #
8
+ # include_recipe 'apache2::default'
9
+ #
10
+ # The Examples section demonstrates the different ways to test an
11
+ # +include_recipe+ directive with ChefSpec.
12
+ #
13
+ # @example Assert the +apache2::default+ recipe is included in the Chef run
14
+ # expect(chef_run).to include_recipe('apache2::default')
15
+ #
16
+ #
17
+ # @param [String] recipe_name
18
+ # the name of the recipe to be included
19
+ #
20
+ # @return [ChefSpec::Matchers::IncludeRecipeMatcher]
21
+ #
22
+ def include_recipe(recipe_name)
23
+ ChefSpec::Matchers::IncludeRecipeMatcher.new(recipe_name)
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,28 @@
1
+ module ChefSpec
2
+ module API
3
+ module Link
4
+ #
5
+ # Assert that a symlink links to a specific path. This is really
6
+ # syntactic sugar for the following:
7
+ #
8
+ # expect(chef_run).to create_link('/tmp/thing').with(to: '/tmp/other_thing')
9
+ #
10
+ # @example Using +link_to+ with a String path
11
+ # link = chef_run.link('/tmp/thing')
12
+ # expect(link).to link_to('/tmp/other_thing')
13
+ #
14
+ # @example Using +link_to+ with a regular expression
15
+ # expect(link).to link_to(/\/tmp/(.+)/)
16
+ #
17
+ # @param [String, Regex] path
18
+ # the path to link to
19
+ #
20
+ # @return [ChefSpec::Matchers::LinkToMatcher]
21
+ #
22
+ def link_to(path)
23
+ ChefSpec::Matchers::LinkToMatcher.new(path)
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,40 @@
1
+ module ChefSpec
2
+ module API
3
+ module Notifications
4
+ #
5
+ # Assert that a resource notifies another. Given a Chef Recipe that
6
+ # notifies a template resource to restart apache:
7
+ #
8
+ # template '/etc/apache2/config' do
9
+ # notifies :restart, 'service[apache2]'
10
+ # end
11
+ #
12
+ # The Examples section demonstrates the different ways to test an
13
+ # notifications on a resource with ChefSpec.
14
+ #
15
+ # @example Assert the template notifies apache of something
16
+ # template = chef_run.template('/etc/apache2.conf')
17
+ # expect(template).to notify('service[apache2]')
18
+ #
19
+ # @example Assert the template notifies apache to restart
20
+ # expect(template).to notify('service[apache2]').to(:restart)
21
+ #
22
+ # @example Assert the template notifies apache to restart immediately
23
+ # expect(template).to notify('service[apache2]').to(:restart).immediately
24
+ #
25
+ # @example Assert the template notifies apache to restart delayed
26
+ # expect(template).to notify('service[apache2]').to(:restart).delayed
27
+ #
28
+ #
29
+ # @param [String] signature
30
+ # the signature of the notification to match
31
+ #
32
+ # @return [ChefSpec::Matchers::NotificationsMatcher]
33
+ #
34
+ def notify(signature)
35
+ ChefSpec::Matchers::NotificationsMatcher.new(signature)
36
+ end
37
+
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,14 @@
1
+ module ChefSpec
2
+ module API
3
+ module Reboot
4
+ def now_reboot(resource_name)
5
+ ChefSpec::Matchers::ResourceMatcher.new(:reboot, :reboot_now, resource_name)
6
+ end
7
+
8
+ def request_reboot(resource_name)
9
+ ChefSpec::Matchers::ResourceMatcher.new(:reboot, :request_reboot, resource_name)
10
+ end
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,37 @@
1
+ module ChefSpec
2
+ module API
3
+ module RenderFile
4
+ #
5
+ # Assert that a file is rendered by the Chef run. This matcher works for
6
+ # +template+, +file+, and +cookbook_file+ resources. The content from the
7
+ # resource must be convertable to a string; verifying the content of a
8
+ # binary file is not permissible at this time.
9
+ #
10
+ # @example Assert a template is rendered
11
+ # expect(chef_run).to render_file('/etc/foo')
12
+ #
13
+ # @example Assert a template is rendered with certain content
14
+ # expect(template).to render_file('/etc/foo').with_content('This is a file')
15
+ #
16
+ # @example Assert a template is rendered with matching content
17
+ # expect(template).to render_file('/etc/foo').with_content(/^This(.+)$/)
18
+ #
19
+ # @example Assert a template is rendered with content matching any RSpec matcher
20
+ # expect(template).to render_file('/etc/foo').with_content(starts_with('This'))
21
+ #
22
+ # @example Assert a partial path to a template is rendered with matching content
23
+ # expect(template).to render_file(/\/etc\/foo-(\d+)$/).with_content(/^This(.+)$/)
24
+ #
25
+ #
26
+ # @param [String] path
27
+ # the path of the file to render
28
+ #
29
+ # @return [ChefSpec::Matchers::RenderFileMatcher]
30
+ #
31
+ def render_file(path)
32
+ ChefSpec::Matchers::RenderFileMatcher.new(path)
33
+ end
34
+
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,30 @@
1
+ module ChefSpec
2
+ module API
3
+ module StateAttrs
4
+ #
5
+ # Assert that a Chef resource has certain state attributes (since Chef
6
+ # 11.8.0):
7
+ #
8
+ # state_attrs :time, :temperature
9
+ #
10
+ # @see https://github.com/opscode/chef/blob/e43d7ebda/lib/chef/resource/file.rb#L32-L37
11
+ #
12
+ # The Examples section demonstrates the different ways to test a
13
+ # resource's +state_attrs+ with ChefSpec.
14
+ #
15
+ # @example Assert the +lwrp+ resource has two state attributes
16
+ # expect(lwrp).to have_state_attrs(:time, :temperature)
17
+ #
18
+ #
19
+ # @param [Array] state_attrs
20
+ # the list of state attributes to assert
21
+ #
22
+ # @return [ChefSpec::Matchers::StateAttrsMatcher]
23
+ #
24
+ def have_state_attrs(*state_attrs)
25
+ ChefSpec::Matchers::StateAttrsMatcher.new(state_attrs)
26
+ end
27
+
28
+ end
29
+ end
30
+ end