chefspec 2.0.1 → 3.0.0.beta.1
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.
- checksums.yaml +4 -4
- data/lib/chefspec.rb +30 -44
- data/lib/chefspec/api.rb +74 -0
- data/lib/chefspec/api/apt_package.rb +192 -0
- data/lib/chefspec/api/batch.rb +43 -0
- data/lib/chefspec/api/chef_gem.rb +191 -0
- data/lib/chefspec/api/cookbook_file.rb +166 -0
- data/lib/chefspec/api/cron.rb +80 -0
- data/lib/chefspec/api/deploy.rb +117 -0
- data/lib/chefspec/api/directory.rb +80 -0
- data/lib/chefspec/api/dpkg_package.rb +117 -0
- data/lib/chefspec/api/easy_install_package.rb +154 -0
- data/lib/chefspec/api/env.rb +117 -0
- data/lib/chefspec/api/erl_call.rb +43 -0
- data/lib/chefspec/api/execute.rb +43 -0
- data/lib/chefspec/api/file.rb +166 -0
- data/lib/chefspec/api/freebsd_package.rb +80 -0
- data/lib/chefspec/api/gem_package.rb +191 -0
- data/lib/chefspec/api/git.rb +117 -0
- data/lib/chefspec/api/group.rb +154 -0
- data/lib/chefspec/api/http_request.rb +228 -0
- data/lib/chefspec/api/ifconfig.rb +154 -0
- data/lib/chefspec/api/include_recipe.rb +26 -0
- data/lib/chefspec/api/ips_package.rb +117 -0
- data/lib/chefspec/api/link.rb +102 -0
- data/lib/chefspec/api/log.rb +43 -0
- data/lib/chefspec/api/macports_package.rb +154 -0
- data/lib/chefspec/api/mdadm.rb +117 -0
- data/lib/chefspec/api/mount.rb +192 -0
- data/lib/chefspec/api/notifications.rb +38 -0
- data/lib/chefspec/api/ohai.rb +43 -0
- data/lib/chefspec/api/package.rb +192 -0
- data/lib/chefspec/api/pacman_package.rb +155 -0
- data/lib/chefspec/api/portage_package.rb +155 -0
- data/lib/chefspec/api/powershell_script.rb +43 -0
- data/lib/chefspec/api/registry_key.rb +166 -0
- data/lib/chefspec/api/remote_directory.rb +120 -0
- data/lib/chefspec/api/remote_file.rb +166 -0
- data/lib/chefspec/api/render_file.rb +32 -0
- data/lib/chefspec/api/route.rb +80 -0
- data/lib/chefspec/api/rpm_package.rb +117 -0
- data/lib/chefspec/api/ruby_block.rb +37 -0
- data/lib/chefspec/api/script.rb +228 -0
- data/lib/chefspec/api/service.rb +246 -0
- data/lib/chefspec/api/smartos_package.rb +117 -0
- data/lib/chefspec/api/solaris_package.rb +80 -0
- data/lib/chefspec/api/subversion.rb +154 -0
- data/lib/chefspec/api/template.rb +166 -0
- data/lib/chefspec/api/user.rb +228 -0
- data/lib/chefspec/api/yum_package.rb +154 -0
- data/lib/chefspec/berkshelf.rb +37 -0
- data/lib/chefspec/deprecations.rb +151 -0
- data/lib/chefspec/errors.rb +99 -0
- data/lib/chefspec/expect_exception.rb +45 -0
- data/lib/chefspec/extensions/chef/client.rb +15 -0
- data/lib/chefspec/extensions/chef/conditional.rb +11 -0
- data/lib/chefspec/extensions/chef/data_query.rb +29 -0
- data/lib/chefspec/extensions/chef/lwrp_base.rb +44 -0
- data/lib/chefspec/extensions/chef/resource.rb +27 -0
- data/lib/chefspec/extensions/chef/securable.rb +19 -0
- data/lib/chefspec/formatter.rb +270 -0
- data/lib/chefspec/macros.rb +217 -0
- data/lib/chefspec/matchers.rb +9 -0
- data/lib/chefspec/matchers/include_recipe_matcher.rb +45 -0
- data/lib/chefspec/matchers/link_to_matcher.rb +28 -0
- data/lib/chefspec/matchers/notifications_matcher.rb +92 -0
- data/lib/chefspec/matchers/render_file_matcher.rb +72 -0
- data/lib/chefspec/matchers/resource_matcher.rb +143 -0
- data/lib/chefspec/renderer.rb +137 -0
- data/lib/chefspec/rspec.rb +17 -0
- data/lib/chefspec/runner.rb +274 -0
- data/lib/chefspec/stubs/command_registry.rb +11 -0
- data/lib/chefspec/stubs/command_stub.rb +37 -0
- data/lib/chefspec/stubs/data_bag_item_registry.rb +13 -0
- data/lib/chefspec/stubs/data_bag_item_stub.rb +25 -0
- data/lib/chefspec/stubs/data_bag_registry.rb +13 -0
- data/lib/chefspec/stubs/data_bag_stub.rb +23 -0
- data/lib/chefspec/stubs/registry.rb +32 -0
- data/lib/chefspec/stubs/search_registry.rb +13 -0
- data/lib/chefspec/stubs/search_stub.rb +25 -0
- data/lib/chefspec/stubs/stub.rb +37 -0
- data/lib/chefspec/version.rb +1 -2
- metadata +100 -103
- data/lib/chef/expect_exception.rb +0 -34
- data/lib/chef/formatters/chefspec.rb +0 -233
- data/lib/chef/knife/cookbook_create_specs.rb +0 -107
- data/lib/chefspec/chef_runner.rb +0 -275
- data/lib/chefspec/helpers/describe.rb +0 -17
- data/lib/chefspec/matchers/cron.rb +0 -7
- data/lib/chefspec/matchers/env.rb +0 -8
- data/lib/chefspec/matchers/execute.rb +0 -33
- data/lib/chefspec/matchers/file.rb +0 -83
- data/lib/chefspec/matchers/file_content.rb +0 -32
- data/lib/chefspec/matchers/group.rb +0 -8
- data/lib/chefspec/matchers/include_recipe.rb +0 -20
- data/lib/chefspec/matchers/link.rb +0 -14
- data/lib/chefspec/matchers/log.rb +0 -21
- data/lib/chefspec/matchers/notifications.rb +0 -43
- data/lib/chefspec/matchers/package.rb +0 -39
- data/lib/chefspec/matchers/python.rb +0 -7
- data/lib/chefspec/matchers/ruby_block.rb +0 -13
- data/lib/chefspec/matchers/script.rb +0 -34
- data/lib/chefspec/matchers/service.rb +0 -25
- data/lib/chefspec/matchers/shared.rb +0 -132
- data/lib/chefspec/matchers/user.rb +0 -8
- data/lib/chefspec/minitest.rb +0 -195
- data/lib/chefspec/monkey_patches/conditional.rb +0 -19
- data/lib/chefspec/monkey_patches/hash.rb +0 -23
- data/lib/chefspec/monkey_patches/lwrp_base.rb +0 -45
- data/lib/chefspec/monkey_patches/provider.rb +0 -43
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
RSpec.configure do |config|
|
|
2
|
+
config.include(ChefSpec::API)
|
|
3
|
+
config.include(ChefSpec::Macros)
|
|
4
|
+
|
|
5
|
+
config.after(:each) do
|
|
6
|
+
ChefSpec::Stubs::CommandRegistry.reset!
|
|
7
|
+
ChefSpec::Stubs::DataBagRegistry.reset!
|
|
8
|
+
ChefSpec::Stubs::DataBagItemRegistry.reset!
|
|
9
|
+
ChefSpec::Stubs::SearchRegistry.reset!
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
config.add_setting :cookbook_path
|
|
13
|
+
config.add_setting :log_level, default: :warn
|
|
14
|
+
config.add_setting :path
|
|
15
|
+
config.add_setting :platform
|
|
16
|
+
config.add_setting :version
|
|
17
|
+
end
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
require 'fauxhai'
|
|
2
|
+
require 'chef/client'
|
|
3
|
+
require 'chef/mash'
|
|
4
|
+
require 'chef/providers'
|
|
5
|
+
require 'chef/resources'
|
|
6
|
+
|
|
7
|
+
module ChefSpec
|
|
8
|
+
class Runner
|
|
9
|
+
#
|
|
10
|
+
# Defines a new runner method on the +ChefSpec::Runner+.
|
|
11
|
+
#
|
|
12
|
+
# @param [Symbol] resource_name
|
|
13
|
+
# the name of the resource to define a method
|
|
14
|
+
#
|
|
15
|
+
# @return [self]
|
|
16
|
+
#
|
|
17
|
+
def self.define_runner_method(resource_name)
|
|
18
|
+
define_method(resource_name) do |identity|
|
|
19
|
+
find_resource(resource_name, identity)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
self
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# @return [Hash]
|
|
26
|
+
attr_reader :options
|
|
27
|
+
|
|
28
|
+
# @return [Chef::RunContext]
|
|
29
|
+
attr_reader :run_context
|
|
30
|
+
|
|
31
|
+
#
|
|
32
|
+
# Instantiate a new Runner to run examples with.
|
|
33
|
+
#
|
|
34
|
+
# @example Instantiate a new Runner
|
|
35
|
+
# ChefSpec::Runner.new
|
|
36
|
+
#
|
|
37
|
+
# @example Specifying the platform and version
|
|
38
|
+
# ChefSpec::Runner.new(platform: 'ubuntu', version: '12.04')
|
|
39
|
+
#
|
|
40
|
+
# @example Specifying the cookbook path
|
|
41
|
+
# ChefSpec::Runner.new(cookbook_path: ['/cookbooks'])
|
|
42
|
+
#
|
|
43
|
+
# @example Specifying the log level
|
|
44
|
+
# ChefSpec::Runner.new(log_level: :info)
|
|
45
|
+
#
|
|
46
|
+
#
|
|
47
|
+
# @param [Hash] options
|
|
48
|
+
# The options for the new runner
|
|
49
|
+
#
|
|
50
|
+
# @option options [Symbol] :log_level
|
|
51
|
+
# The log level to use (default is :warn)
|
|
52
|
+
# @option options [String] :platform
|
|
53
|
+
# The platform to load Ohai attributes from (must be present in fauxhai)
|
|
54
|
+
# @option options [String] :version
|
|
55
|
+
# The version of the platform to load Ohai attributes from (must be present in fauxhai)
|
|
56
|
+
# @option options [String] :path
|
|
57
|
+
# Path of a json file that will be passed to fauxhai as :path option
|
|
58
|
+
# @option options [Array<String>] :step_into
|
|
59
|
+
# The list of LWRPs to evaluate
|
|
60
|
+
#
|
|
61
|
+
# @yield [node] Configuration block for Chef::Node
|
|
62
|
+
#
|
|
63
|
+
def initialize(options = {}, &block)
|
|
64
|
+
@options = options = {
|
|
65
|
+
cookbook_path: RSpec.configuration.cookbook_path || calling_cookbook_path(caller),
|
|
66
|
+
log_level: RSpec.configuration.log_level,
|
|
67
|
+
path: RSpec.configuration.path,
|
|
68
|
+
platform: RSpec.configuration.platform,
|
|
69
|
+
version: RSpec.configuration.version,
|
|
70
|
+
}.merge(options)
|
|
71
|
+
|
|
72
|
+
Chef::Log.level = options[:log_level]
|
|
73
|
+
|
|
74
|
+
Chef::Config.reset!
|
|
75
|
+
Chef::Config.formatters.clear
|
|
76
|
+
Chef::Config.add_formatter('chefspec')
|
|
77
|
+
Chef::Config[:cache_type] = 'Memory'
|
|
78
|
+
Chef::Config[:cookbook_path] = Array(options[:cookbook_path])
|
|
79
|
+
Chef::Config[:force_logger] = true
|
|
80
|
+
Chef::Config[:solo] = true
|
|
81
|
+
|
|
82
|
+
yield node if block_given?
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
#
|
|
86
|
+
# Execute the specified recipes on the node, without actually converging
|
|
87
|
+
# the node. This is the equivalent of `chef-apply`.
|
|
88
|
+
#
|
|
89
|
+
# @example Converging a single recipe
|
|
90
|
+
# chef_run.apply('example::default')
|
|
91
|
+
#
|
|
92
|
+
# @example Converging multiple recipes
|
|
93
|
+
# chef_run.apply('example::default', 'example::secondary')
|
|
94
|
+
#
|
|
95
|
+
#
|
|
96
|
+
# @param [Array] recipe_names
|
|
97
|
+
# The names of the recipe or recipes to apply
|
|
98
|
+
#
|
|
99
|
+
# @return [ChefSpec::Runner]
|
|
100
|
+
# A reference to the calling Runner (for chaining purposes)
|
|
101
|
+
#
|
|
102
|
+
def apply(*recipe_names)
|
|
103
|
+
recipe_names.each do |recipe_name|
|
|
104
|
+
cookbook, recipe = Chef::Recipe.parse_recipe_name(recipe_name)
|
|
105
|
+
recipe_path = File.join(Dir.pwd, 'recipes', "#{recipe}.rb")
|
|
106
|
+
|
|
107
|
+
recipe = Chef::Recipe.new(cookbook, recipe, run_context)
|
|
108
|
+
recipe.from_file(recipe_path)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
@resources = {}
|
|
112
|
+
@run_context = Chef::RunContext.new(client.node, {}, client.events)
|
|
113
|
+
|
|
114
|
+
Chef::Runner.new(@run_context).converge
|
|
115
|
+
self
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
#
|
|
119
|
+
# Execute the given `run_list` on the node, without actually converging
|
|
120
|
+
# the node.
|
|
121
|
+
#
|
|
122
|
+
# @example Converging a single recipe
|
|
123
|
+
# chef_run.converge('example::default')
|
|
124
|
+
#
|
|
125
|
+
# @example Converging multiple recipes
|
|
126
|
+
# chef_run.converge('example::default', 'example::secondary')
|
|
127
|
+
#
|
|
128
|
+
#
|
|
129
|
+
# @param [Array] recipe_names
|
|
130
|
+
# The names of the recipe or recipes to converge
|
|
131
|
+
#
|
|
132
|
+
# @return [ChefSpec::Runner]
|
|
133
|
+
# A reference to the calling Runner (for chaining purposes)
|
|
134
|
+
#
|
|
135
|
+
def converge(*recipe_names)
|
|
136
|
+
node.run_list.reset!
|
|
137
|
+
recipe_names.each { |recipe_name| node.run_list.add(recipe_name) }
|
|
138
|
+
|
|
139
|
+
return self if dry_run?
|
|
140
|
+
|
|
141
|
+
# Reset the resource collection
|
|
142
|
+
@resources = {}
|
|
143
|
+
|
|
144
|
+
client.build_node
|
|
145
|
+
@run_context = client.setup_run_context
|
|
146
|
+
|
|
147
|
+
Chef::Runner.new(@run_context).converge
|
|
148
|
+
self
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
#
|
|
152
|
+
# The +Chef::Node+ corresponding to this Runner.
|
|
153
|
+
#
|
|
154
|
+
# @return [Chef::Node]
|
|
155
|
+
#
|
|
156
|
+
def node
|
|
157
|
+
return @node if @node
|
|
158
|
+
|
|
159
|
+
@node = client.node
|
|
160
|
+
@node.instance_variable_set(:@runner, self)
|
|
161
|
+
@node.class.send(:attr_reader, :runner)
|
|
162
|
+
@node
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
#
|
|
166
|
+
# The full collection of resources for this Runner.
|
|
167
|
+
#
|
|
168
|
+
# @return [Hash<String, Chef::Resource>]
|
|
169
|
+
#
|
|
170
|
+
def resources
|
|
171
|
+
@resources ||= {}
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
#
|
|
175
|
+
# Find the resource with the declared type and resource name.
|
|
176
|
+
#
|
|
177
|
+
# @example Find a template at `/etc/foo`
|
|
178
|
+
# chef_run.find_resource(:template, '/etc/foo') #=> #<Chef::Resource::Template>
|
|
179
|
+
#
|
|
180
|
+
#
|
|
181
|
+
# @param [Symbol] type
|
|
182
|
+
# The type of resource (sometimes called `resource_name`) such as `file`
|
|
183
|
+
# or `directory`.
|
|
184
|
+
# @param [String, Regexp] name
|
|
185
|
+
# The value of the name attribute or identity attribute for the resource.
|
|
186
|
+
#
|
|
187
|
+
# @return [Chef::Resource, nil]
|
|
188
|
+
# The matching resource, or nil if one is not found
|
|
189
|
+
#
|
|
190
|
+
def find_resource(type, name)
|
|
191
|
+
return resources["#{type}[#{name}]"] if resources["#{type}[#{name}]"]
|
|
192
|
+
|
|
193
|
+
resources.values.find do |resource|
|
|
194
|
+
resource.resource_name.to_sym == type && (name === resource.identity || name === resource.name)
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
#
|
|
199
|
+
# Find the resource with the declared type.
|
|
200
|
+
#
|
|
201
|
+
# @example Find all template resources
|
|
202
|
+
# chef_run.find_resources('template') #=> [#<Chef::Resource::Template>, #...]
|
|
203
|
+
#
|
|
204
|
+
#
|
|
205
|
+
# @param [Symbol] type
|
|
206
|
+
# The type of resource such as `:file` or `:directory`.
|
|
207
|
+
#
|
|
208
|
+
# @return [Array<Chef::Resource>]
|
|
209
|
+
# The matching resources
|
|
210
|
+
#
|
|
211
|
+
def find_resources(type)
|
|
212
|
+
resources.select do |_, resource|
|
|
213
|
+
resource.resource_name.to_s == type.to_s
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
#
|
|
218
|
+
# The list of LWRPs to step into and evaluate.
|
|
219
|
+
#
|
|
220
|
+
# @return [Array<String>]
|
|
221
|
+
#
|
|
222
|
+
def step_into
|
|
223
|
+
@step_into ||= Array(options[:step_into] || [])
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
#
|
|
227
|
+
# Boolean method to determine if this Runner is in `dry_run` mode.
|
|
228
|
+
#
|
|
229
|
+
# @return [Boolean]
|
|
230
|
+
#
|
|
231
|
+
def dry_run?
|
|
232
|
+
!!options[:dry_run]
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
#
|
|
236
|
+
# This runner as a string.
|
|
237
|
+
#
|
|
238
|
+
# @return [String] Currently includes the run_list. Format of the string may change between versions of this gem.
|
|
239
|
+
#
|
|
240
|
+
def to_s
|
|
241
|
+
return "chef_run: #{node.run_list.to_s}" unless node.run_list.empty?
|
|
242
|
+
'chef_run'
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
#
|
|
246
|
+
# The runner as a String with helpful output.
|
|
247
|
+
#
|
|
248
|
+
# @return [String]
|
|
249
|
+
#
|
|
250
|
+
def inspect
|
|
251
|
+
"#<#{self.class} options: #{options.inspect}, run_list: '#{node.run_list.to_s}'>"
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
private
|
|
255
|
+
def calling_cookbook_path(kaller)
|
|
256
|
+
calling_spec = kaller.find { |line| line =~ /\/spec/ }
|
|
257
|
+
bits = calling_spec.split(':', 2).first.split(File::SEPARATOR)
|
|
258
|
+
spec_dir = bits.index('spec') || 0
|
|
259
|
+
|
|
260
|
+
File.expand_path(File.join(bits.slice(0, spec_dir), '..'))
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
#
|
|
264
|
+
def client
|
|
265
|
+
return @client if @client
|
|
266
|
+
|
|
267
|
+
@client = Chef::Client.new
|
|
268
|
+
@client.ohai.data = Mash.from_hash(Fauxhai.mock(options).data)
|
|
269
|
+
@client.load_node
|
|
270
|
+
@client.build_node
|
|
271
|
+
@client
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require_relative 'stub'
|
|
2
|
+
|
|
3
|
+
module ChefSpec
|
|
4
|
+
module Stubs
|
|
5
|
+
class CommandStub < Stub
|
|
6
|
+
attr_reader :block
|
|
7
|
+
attr_reader :command
|
|
8
|
+
attr_reader :value
|
|
9
|
+
|
|
10
|
+
def initialize(command, &block)
|
|
11
|
+
@command = command
|
|
12
|
+
@block = block
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def and_return(value)
|
|
16
|
+
@value = value
|
|
17
|
+
self
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def result
|
|
21
|
+
if @block
|
|
22
|
+
@block.call
|
|
23
|
+
else
|
|
24
|
+
@value
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def signature
|
|
29
|
+
if @block
|
|
30
|
+
"stub_command(#{@command.inspect}) { # Ruby code }"
|
|
31
|
+
else
|
|
32
|
+
"stub_command(#{@command.inspect}).and_return(#{@value})"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require_relative 'stub'
|
|
2
|
+
|
|
3
|
+
module ChefSpec
|
|
4
|
+
module Stubs
|
|
5
|
+
class DataBagItemStub < Stub
|
|
6
|
+
attr_reader :block
|
|
7
|
+
attr_reader :id
|
|
8
|
+
attr_reader :bag
|
|
9
|
+
|
|
10
|
+
def initialize(bag, id, &block)
|
|
11
|
+
@bag = bag.to_s
|
|
12
|
+
@id = id
|
|
13
|
+
@block = block
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def signature
|
|
17
|
+
if @block
|
|
18
|
+
"stub_data_bag_item(#{@bag.inspect}, #{@id.inspect}) { # Ruby code }"
|
|
19
|
+
else
|
|
20
|
+
"stub_data_bag_item(#{@bag.inspect}, #{@id.inspect}).and_return(#{@value})"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require_relative 'stub'
|
|
2
|
+
|
|
3
|
+
module ChefSpec
|
|
4
|
+
module Stubs
|
|
5
|
+
class DataBagStub < Stub
|
|
6
|
+
attr_reader :block
|
|
7
|
+
attr_reader :bag
|
|
8
|
+
|
|
9
|
+
def initialize(bag, &block)
|
|
10
|
+
@bag = bag.to_s
|
|
11
|
+
@block = block
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def signature
|
|
15
|
+
if @block
|
|
16
|
+
"stub_data_bag(#{@bag.inspect}) { # Ruby code }"
|
|
17
|
+
else
|
|
18
|
+
"stub_data_bag(#{@bag.inspect}).and_return(#{@value})"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module ChefSpec
|
|
2
|
+
module Stubs
|
|
3
|
+
class Registry
|
|
4
|
+
class << self
|
|
5
|
+
extend Forwardable
|
|
6
|
+
def_delegators :instance, :reset!, :register, :stubs, :stubs=, :stub_for
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
include Singleton
|
|
10
|
+
|
|
11
|
+
# @return [Hash<Symbol, Array<SearchStub>>]
|
|
12
|
+
attr_accessor :stubs
|
|
13
|
+
|
|
14
|
+
def initialize
|
|
15
|
+
reset!
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def reset!
|
|
19
|
+
@stubs = []
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def register(stub)
|
|
23
|
+
@stubs.insert(0, stub)
|
|
24
|
+
stub
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def stub_for(*args)
|
|
28
|
+
raise ArgumentError, '#stub_for is an abstract function'
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|