rspec-puppet 2.12.0 → 4.0.0
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/CHANGELOG.md +151 -478
- data/README.md +71 -168
- data/bin/rspec-puppet-init +4 -3
- data/lib/rspec-puppet/adapters.rb +84 -236
- data/lib/rspec-puppet/cache.rb +3 -2
- data/lib/rspec-puppet/consts.rb +16 -14
- data/lib/rspec-puppet/coverage.rb +37 -42
- data/lib/rspec-puppet/errors.rb +6 -6
- data/lib/rspec-puppet/example/class_example_group.rb +3 -1
- data/lib/rspec-puppet/example/define_example_group.rb +3 -1
- data/lib/rspec-puppet/example/function_example_group.rb +42 -57
- data/lib/rspec-puppet/example/host_example_group.rb +3 -1
- data/lib/rspec-puppet/example/provider_example_group.rb +2 -0
- data/lib/rspec-puppet/example/type_alias_example_group.rb +4 -2
- data/lib/rspec-puppet/example/type_example_group.rb +3 -1
- data/lib/rspec-puppet/example.rb +6 -9
- data/lib/rspec-puppet/facter_impl.rb +11 -10
- data/lib/rspec-puppet/matchers/allow_value.rb +10 -10
- data/lib/rspec-puppet/matchers/compile.rb +54 -61
- data/lib/rspec-puppet/matchers/count_generic.rb +18 -18
- data/lib/rspec-puppet/matchers/create_generic.rb +67 -79
- data/lib/rspec-puppet/matchers/dynamic_matchers.rb +15 -4
- data/lib/rspec-puppet/matchers/include_class.rb +5 -4
- data/lib/rspec-puppet/matchers/parameter_matcher.rb +11 -12
- data/lib/rspec-puppet/matchers/raise_error.rb +5 -1
- data/lib/rspec-puppet/matchers/run.rb +41 -44
- data/lib/rspec-puppet/matchers/type_matchers.rb +37 -48
- data/lib/rspec-puppet/matchers.rb +2 -0
- data/lib/rspec-puppet/monkey_patches/win32/registry.rb +7 -5
- data/lib/rspec-puppet/monkey_patches/win32/taskscheduler.rb +3 -1
- data/lib/rspec-puppet/monkey_patches/windows/taskschedulerconstants.rb +208 -205
- data/lib/rspec-puppet/monkey_patches.rb +80 -93
- data/lib/rspec-puppet/rake_task.rb +6 -4
- data/lib/rspec-puppet/raw_string.rb +2 -0
- data/lib/rspec-puppet/sensitive.rb +31 -39
- data/lib/rspec-puppet/setup.rb +45 -56
- data/lib/rspec-puppet/spec_helper.rb +2 -3
- data/lib/rspec-puppet/support.rb +129 -177
- data/lib/rspec-puppet/tasks/release_test.rb +8 -5
- data/lib/rspec-puppet/version.rb +5 -0
- data/lib/rspec-puppet.rb +37 -61
- metadata +17 -13
- data/lib/rspec-puppet/example/application_example_group.rb +0 -19
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'rspec-puppet/facter_impl'
|
|
2
4
|
|
|
3
5
|
module RSpec::Puppet
|
|
4
6
|
module Adapters
|
|
5
|
-
|
|
6
7
|
class Base
|
|
7
8
|
# Set up all Puppet settings applicable for this Puppet version as
|
|
8
9
|
# application defaults.
|
|
@@ -11,12 +12,6 @@ module RSpec::Puppet
|
|
|
11
12
|
# executing RSpec context. When a setting is specified both in the global configuration and in
|
|
12
13
|
# the example group, the setting in the example group is preferred.
|
|
13
14
|
#
|
|
14
|
-
# @example Configuring a Puppet setting from a global RSpec configuration value
|
|
15
|
-
# RSpec.configure do |config|
|
|
16
|
-
# config.parser = "future"
|
|
17
|
-
# end
|
|
18
|
-
# # => Puppet[:parser] will be future
|
|
19
|
-
#
|
|
20
15
|
# @example Configuring a Puppet setting from within an RSpec example group
|
|
21
16
|
# RSpec.describe 'my_module::my_class', :type => :class do
|
|
22
17
|
# let(:module_path) { "/Users/luke/modules" }
|
|
@@ -41,102 +36,51 @@ module RSpec::Puppet
|
|
|
41
36
|
# @param example_group [RSpec::Core::ExampleGroup] The RSpec context to use for local settings
|
|
42
37
|
# @return [void]
|
|
43
38
|
def setup_puppet(example_group)
|
|
39
|
+
case RSpec.configuration.facter_implementation.to_sym
|
|
40
|
+
when :rspec
|
|
41
|
+
# Lazily instantiate FacterTestImpl here to optimize memory
|
|
42
|
+
# allocation, as the proc will only be called if FacterImpl is unset
|
|
43
|
+
set_facter_impl(proc { RSpec::Puppet::FacterTestImpl.new })
|
|
44
|
+
when :facter
|
|
45
|
+
set_facter_impl(Facter)
|
|
46
|
+
else
|
|
47
|
+
raise "Unsupported facter_implementation '#{RSpec.configuration.facter_implementation}'"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
Puppet.runtime[:facter] = FacterImpl
|
|
51
|
+
|
|
44
52
|
settings = settings_map.map do |puppet_setting, rspec_setting|
|
|
45
53
|
[puppet_setting, get_setting(example_group, rspec_setting)]
|
|
46
54
|
end.flatten
|
|
47
|
-
default_hash = {:
|
|
55
|
+
default_hash = { confdir: '/dev/null', vardir: '/dev/null' }
|
|
48
56
|
if defined?(Puppet::Test::TestHelper) && Puppet::Test::TestHelper.respond_to?(:app_defaults_for_tests, true)
|
|
49
57
|
default_hash.merge!(Puppet::Test::TestHelper.send(:app_defaults_for_tests))
|
|
50
58
|
end
|
|
51
59
|
settings_hash = default_hash.merge(Hash[*settings])
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
Puppet.settings.initialize_app_defaults(settings_hash)
|
|
56
|
-
|
|
57
|
-
# Forcefully apply the environmentpath setting instead of relying on
|
|
58
|
-
# the application defaults as Puppet::Test::TestHelper automatically
|
|
59
|
-
# sets this value as well, overriding our application default
|
|
60
|
-
Puppet.settings[:environmentpath] = settings_hash[:environmentpath] if settings_hash.key?(:environmentpath)
|
|
61
|
-
else
|
|
62
|
-
# Set settings the old way for Puppet 2.x, because that's how
|
|
63
|
-
# they're defaulted in that version of Puppet::Test::TestHelper and
|
|
64
|
-
# we won't be able to override them otherwise.
|
|
65
|
-
settings_hash.each do |setting, value|
|
|
66
|
-
Puppet.settings[setting] = value
|
|
60
|
+
if Gem.win_platform?
|
|
61
|
+
settings_hash.each_with_object(settings_hash) do |(k, v), h|
|
|
62
|
+
h[k] = v == '/dev/null' ? 'c:/nul/' : v
|
|
67
63
|
end
|
|
68
64
|
end
|
|
69
65
|
|
|
70
|
-
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
def get_setting(example_group, rspec_setting)
|
|
74
|
-
if example_group.respond_to?(rspec_setting)
|
|
75
|
-
example_group.send(rspec_setting)
|
|
76
|
-
else
|
|
77
|
-
RSpec.configuration.send(rspec_setting)
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
def catalog(node, exported)
|
|
82
|
-
if exported
|
|
83
|
-
# Use the compiler directly to skip the filtering done by the indirector
|
|
84
|
-
Puppet::Parser::Compiler.compile(node).filter { |r| !r.exported? }
|
|
85
|
-
else
|
|
86
|
-
Puppet::Resource::Catalog.indirection.find(node.name, :use_node => node)
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
def current_environment
|
|
91
|
-
Puppet::Node::Environment.new(@environment_name)
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
def settings_map
|
|
95
|
-
[
|
|
96
|
-
[:modulepath, :module_path],
|
|
97
|
-
[:config, :config],
|
|
98
|
-
[:confdir, :confdir],
|
|
99
|
-
]
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
def modulepath
|
|
103
|
-
Puppet[:modulepath].split(File::PATH_SEPARATOR)
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
# @return [String, nil] The path to the Puppet manifest if it is present and set, nil otherwise.
|
|
107
|
-
def manifest
|
|
108
|
-
Puppet[:manifest]
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
class Adapter40 < Base
|
|
113
|
-
#
|
|
114
|
-
# @api private
|
|
115
|
-
#
|
|
116
|
-
# Set the FacterImpl constant to the given Facter implementation or noop
|
|
117
|
-
# if the constant is already set. If a proc is given, it will only be
|
|
118
|
-
# called if FacterImpl is not defined.
|
|
119
|
-
#
|
|
120
|
-
# @param impl [Object, Proc] An object or a proc that implements the Facter API
|
|
121
|
-
def set_facter_impl(impl)
|
|
122
|
-
return if defined?(FacterImpl)
|
|
66
|
+
Puppet.settings.initialize_app_defaults(settings_hash)
|
|
123
67
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
68
|
+
# Forcefully apply the environmentpath setting instead of relying on
|
|
69
|
+
# the application defaults as Puppet::Test::TestHelper automatically
|
|
70
|
+
# sets this value as well, overriding our application default
|
|
71
|
+
Puppet.settings[:environmentpath] = settings_hash[:environmentpath] if settings_hash.key?(:environmentpath)
|
|
127
72
|
|
|
128
|
-
|
|
129
|
-
super
|
|
73
|
+
@environment_name = example_group.environment
|
|
130
74
|
|
|
131
|
-
if rspec_modulepath = RSpec.configuration.module_path
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
75
|
+
modulepath = if (rspec_modulepath = RSpec.configuration.module_path)
|
|
76
|
+
rspec_modulepath.split(File::PATH_SEPARATOR)
|
|
77
|
+
else
|
|
78
|
+
Puppet[:environmentpath].split(File::PATH_SEPARATOR).map do |path|
|
|
79
|
+
File.join(path, 'fixtures', 'modules')
|
|
80
|
+
end
|
|
81
|
+
end
|
|
138
82
|
|
|
139
|
-
if rspec_manifest = RSpec.configuration.manifest
|
|
83
|
+
if (rspec_manifest = RSpec.configuration.manifest)
|
|
140
84
|
manifest = rspec_manifest
|
|
141
85
|
else
|
|
142
86
|
manifest_paths = Puppet[:environmentpath].split(File::PATH_SEPARATOR).map do |path|
|
|
@@ -155,29 +99,57 @@ module RSpec::Puppet
|
|
|
155
99
|
|
|
156
100
|
Puppet.push_context(
|
|
157
101
|
{
|
|
158
|
-
:
|
|
159
|
-
:
|
|
160
|
-
:
|
|
102
|
+
environments: loader,
|
|
103
|
+
current_environment: env,
|
|
104
|
+
loaders: Puppet::Pops::Loaders.new(env)
|
|
161
105
|
},
|
|
162
|
-
|
|
106
|
+
'Setup rspec-puppet environments'
|
|
163
107
|
)
|
|
164
108
|
end
|
|
165
109
|
|
|
166
|
-
def
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
])
|
|
110
|
+
def get_setting(example_group, rspec_setting)
|
|
111
|
+
if example_group.respond_to?(rspec_setting)
|
|
112
|
+
example_group.send(rspec_setting)
|
|
113
|
+
else
|
|
114
|
+
RSpec.configuration.send(rspec_setting)
|
|
115
|
+
end
|
|
173
116
|
end
|
|
174
117
|
|
|
175
118
|
def catalog(node, exported)
|
|
176
119
|
node.environment = current_environment
|
|
177
120
|
# Override $::environment to workaround PUP-5835, where Puppet otherwise
|
|
178
121
|
# stores a symbol for the parameter
|
|
179
|
-
|
|
180
|
-
|
|
122
|
+
if node.parameters['environment'] != node.parameters['environment'].to_s
|
|
123
|
+
node.parameters['environment'] = current_environment.name.to_s
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
catalog = if exported
|
|
127
|
+
# Use the compiler directly to skip the filtering done by the indirector
|
|
128
|
+
Puppet::Parser::Compiler.compile(node).filter { |r| !r.exported? }
|
|
129
|
+
else
|
|
130
|
+
Puppet::Resource::Catalog.indirection.find(node.name, use_node: node)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
Puppet::Pops::Evaluator::DeferredResolver.resolve_and_replace(node.facts, catalog)
|
|
134
|
+
|
|
135
|
+
catalog
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def current_environment
|
|
139
|
+
Puppet::Node::Environment.new(@environment_name)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def settings_map
|
|
143
|
+
[
|
|
144
|
+
%i[modulepath module_path],
|
|
145
|
+
%i[basemodulepath basemodulepath],
|
|
146
|
+
%i[config config],
|
|
147
|
+
%i[confdir confdir],
|
|
148
|
+
%i[environmentpath environmentpath],
|
|
149
|
+
%i[hiera_config hiera_config],
|
|
150
|
+
%i[strict_variables strict_variables],
|
|
151
|
+
%i[vendormoduledir vendormoduledir]
|
|
152
|
+
]
|
|
181
153
|
end
|
|
182
154
|
|
|
183
155
|
def current_environment
|
|
@@ -188,9 +160,6 @@ module RSpec::Puppet
|
|
|
188
160
|
current_environment.modulepath
|
|
189
161
|
end
|
|
190
162
|
|
|
191
|
-
# Puppet 4.0 specially handles environments that don't have a manifest set, so we check for the no manifest value
|
|
192
|
-
# and return nil when it is set.
|
|
193
|
-
#
|
|
194
163
|
# @return [String, nil] The path to the Puppet manifest if it is present and set, nil otherwise.
|
|
195
164
|
def manifest
|
|
196
165
|
m = current_environment.manifest
|
|
@@ -200,148 +169,27 @@ module RSpec::Puppet
|
|
|
200
169
|
m
|
|
201
170
|
end
|
|
202
171
|
end
|
|
203
|
-
end
|
|
204
|
-
|
|
205
|
-
class Adapter4X < Adapter40
|
|
206
|
-
def setup_puppet(example_group)
|
|
207
|
-
super
|
|
208
|
-
|
|
209
|
-
set_facter_impl(Facter)
|
|
210
|
-
end
|
|
211
|
-
|
|
212
|
-
def settings_map
|
|
213
|
-
super.concat([
|
|
214
|
-
[:trusted_server_facts, :trusted_server_facts]
|
|
215
|
-
])
|
|
216
|
-
end
|
|
217
|
-
end
|
|
218
172
|
|
|
219
|
-
class Adapter6X < Adapter40
|
|
220
|
-
#
|
|
221
173
|
# @api private
|
|
222
174
|
#
|
|
223
|
-
#
|
|
224
|
-
#
|
|
175
|
+
# Set the FacterImpl constant to the given Facter implementation or noop
|
|
176
|
+
# if the constant is already set. If a proc is given, it will only be
|
|
177
|
+
# called if FacterImpl is not defined.
|
|
225
178
|
#
|
|
226
|
-
# @
|
|
227
|
-
def
|
|
228
|
-
|
|
229
|
-
begin
|
|
230
|
-
Puppet.runtime[:facter]
|
|
231
|
-
@supports_facter_runtime = true
|
|
232
|
-
rescue
|
|
233
|
-
@supports_facter_runtime = false
|
|
234
|
-
end
|
|
235
|
-
end
|
|
236
|
-
|
|
237
|
-
@supports_facter_runtime
|
|
238
|
-
end
|
|
239
|
-
|
|
240
|
-
def setup_puppet(example_group)
|
|
241
|
-
case RSpec.configuration.facter_implementation.to_sym
|
|
242
|
-
when :rspec
|
|
243
|
-
if supports_facter_runtime?
|
|
244
|
-
# Lazily instantiate FacterTestImpl here to optimize memory
|
|
245
|
-
# allocation, as the proc will only be called if FacterImpl is unset
|
|
246
|
-
set_facter_impl(proc { RSpec::Puppet::FacterTestImpl.new })
|
|
247
|
-
Puppet.runtime[:facter] = FacterImpl
|
|
248
|
-
else
|
|
249
|
-
warn "Facter runtime implementations are not supported in Puppet #{Puppet.version}, continuing with facter_implementation 'facter'"
|
|
250
|
-
RSpec.configuration.facter_implementation = :facter
|
|
251
|
-
set_facter_impl(Facter)
|
|
252
|
-
end
|
|
253
|
-
when :facter
|
|
254
|
-
set_facter_impl(Facter)
|
|
255
|
-
else
|
|
256
|
-
raise "Unsupported facter_implementation '#{RSpec.configuration.facter_implementation}'"
|
|
257
|
-
end
|
|
258
|
-
|
|
259
|
-
super
|
|
260
|
-
end
|
|
261
|
-
|
|
262
|
-
def settings_map
|
|
263
|
-
super.concat([
|
|
264
|
-
[:basemodulepath, :basemodulepath],
|
|
265
|
-
[:vendormoduledir, :vendormoduledir],
|
|
266
|
-
])
|
|
267
|
-
end
|
|
268
|
-
|
|
269
|
-
def catalog(node, _exported)
|
|
270
|
-
super.tap do |c|
|
|
271
|
-
Puppet::Pops::Evaluator::DeferredResolver.resolve_and_replace(node.facts, c)
|
|
272
|
-
end
|
|
273
|
-
end
|
|
274
|
-
end
|
|
275
|
-
|
|
276
|
-
class Adapter30 < Base
|
|
277
|
-
def settings_map
|
|
278
|
-
super.concat([
|
|
279
|
-
[:manifestdir, :manifest_dir],
|
|
280
|
-
[:manifest, :manifest],
|
|
281
|
-
[:templatedir, :template_dir],
|
|
282
|
-
[:hiera_config, :hiera_config],
|
|
283
|
-
])
|
|
284
|
-
end
|
|
285
|
-
end
|
|
286
|
-
|
|
287
|
-
class Adapter32 < Adapter30
|
|
288
|
-
def settings_map
|
|
289
|
-
super.concat([
|
|
290
|
-
[:parser, :parser],
|
|
291
|
-
])
|
|
292
|
-
end
|
|
293
|
-
end
|
|
294
|
-
|
|
295
|
-
class Adapter33 < Adapter32
|
|
296
|
-
def settings_map
|
|
297
|
-
super.concat([
|
|
298
|
-
[:ordering, :ordering],
|
|
299
|
-
[:stringify_facts, :stringify_facts],
|
|
300
|
-
])
|
|
301
|
-
end
|
|
302
|
-
end
|
|
303
|
-
|
|
304
|
-
class Adapter34 < Adapter33
|
|
305
|
-
def settings_map
|
|
306
|
-
super.concat([
|
|
307
|
-
[:trusted_node_data, :trusted_node_data],
|
|
308
|
-
])
|
|
309
|
-
end
|
|
310
|
-
end
|
|
311
|
-
|
|
312
|
-
class Adapter35 < Adapter34
|
|
313
|
-
def settings_map
|
|
314
|
-
super.concat([
|
|
315
|
-
[:strict_variables, :strict_variables],
|
|
316
|
-
])
|
|
317
|
-
end
|
|
318
|
-
end
|
|
179
|
+
# @param impl [Object, Proc] An object or a proc that implements the Facter API
|
|
180
|
+
def set_facter_impl(impl)
|
|
181
|
+
return if defined?(FacterImpl)
|
|
319
182
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
super.concat([
|
|
323
|
-
[:manifestdir, :manifest_dir],
|
|
324
|
-
[:manifest, :manifest],
|
|
325
|
-
[:templatedir, :template_dir],
|
|
326
|
-
])
|
|
183
|
+
impl = impl.call if impl.is_a?(Proc)
|
|
184
|
+
Object.send(:const_set, :FacterImpl, impl)
|
|
327
185
|
end
|
|
328
186
|
end
|
|
329
187
|
|
|
330
188
|
def self.get
|
|
331
189
|
[
|
|
332
|
-
['
|
|
333
|
-
['4.1', Adapter4X],
|
|
334
|
-
['4.0', Adapter40],
|
|
335
|
-
['3.5', Adapter35],
|
|
336
|
-
['3.4', Adapter34],
|
|
337
|
-
['3.3', Adapter33],
|
|
338
|
-
['3.2', Adapter32],
|
|
339
|
-
['3.0', Adapter30],
|
|
340
|
-
['2.7', Adapter27]
|
|
190
|
+
['7.11', Base]
|
|
341
191
|
].each do |(version, klass)|
|
|
342
|
-
if Puppet::Util::Package.versioncmp(Puppet.version, version) >= 0
|
|
343
|
-
return klass.new
|
|
344
|
-
end
|
|
192
|
+
return klass.new if Puppet::Util::Package.versioncmp(Puppet.version, version) >= 0
|
|
345
193
|
end
|
|
346
194
|
raise "Puppet version #{Puppet.version} is not supported."
|
|
347
195
|
end
|
data/lib/rspec-puppet/cache.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module RSpec::Puppet
|
|
2
4
|
class Cache
|
|
3
|
-
|
|
4
5
|
MAX_ENTRIES = 16
|
|
5
6
|
|
|
6
7
|
# @param [Proc] default_proc The default proc to use to fetch objects on cache miss
|
|
@@ -12,7 +13,7 @@ module RSpec::Puppet
|
|
|
12
13
|
|
|
13
14
|
def get(*args, &blk)
|
|
14
15
|
key = Marshal.load(Marshal.dump(args))
|
|
15
|
-
if @cache.
|
|
16
|
+
if @cache.key?(key)
|
|
16
17
|
# Cache hit
|
|
17
18
|
# move that entry last to make it "most recenty used"
|
|
18
19
|
@lra.insert(-1, @lra.delete_at(@lra.index(args)))
|
data/lib/rspec-puppet/consts.rb
CHANGED
|
@@ -1,27 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module RSpec::Puppet::Consts
|
|
2
4
|
STUBBED_CONSTS = {
|
|
3
|
-
:
|
|
5
|
+
posix: {
|
|
4
6
|
'File::PATH_SEPARATOR' => ':',
|
|
5
7
|
'File::ALT_SEPARATOR' => nil,
|
|
6
|
-
'Pathname::SEPARATOR_PAT' => /#{Regexp.quote('/')}
|
|
8
|
+
'Pathname::SEPARATOR_PAT' => /#{Regexp.quote('/')}/
|
|
7
9
|
},
|
|
8
|
-
:
|
|
10
|
+
windows: {
|
|
9
11
|
'File::PATH_SEPARATOR' => ';',
|
|
10
|
-
'File::ALT_SEPARATOR' =>
|
|
11
|
-
'Pathname::SEPARATOR_PAT' => /[#{Regexp.quote(
|
|
12
|
+
'File::ALT_SEPARATOR' => '\\',
|
|
13
|
+
'Pathname::SEPARATOR_PAT' => /[#{Regexp.quote('\\')}#{Regexp.quote('/')}]/
|
|
12
14
|
}
|
|
13
|
-
}
|
|
15
|
+
}.freeze
|
|
14
16
|
|
|
15
17
|
FEATURES = {
|
|
16
|
-
:
|
|
17
|
-
:
|
|
18
|
-
:
|
|
19
|
-
},
|
|
20
|
-
:windows => {
|
|
21
|
-
:posix => false,
|
|
22
|
-
:microsoft_windows => true,
|
|
18
|
+
posix: {
|
|
19
|
+
posix: true,
|
|
20
|
+
microsoft_windows: false
|
|
23
21
|
},
|
|
24
|
-
|
|
22
|
+
windows: {
|
|
23
|
+
posix: false,
|
|
24
|
+
microsoft_windows: true
|
|
25
|
+
}
|
|
26
|
+
}.freeze
|
|
25
27
|
|
|
26
28
|
def self.stub_consts_for(platform)
|
|
27
29
|
STUBBED_CONSTS[platform].each do |const_name, const_value|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'tmpdir'
|
|
2
4
|
require 'digest'
|
|
3
5
|
require 'json'
|
|
@@ -16,23 +18,22 @@ end
|
|
|
16
18
|
|
|
17
19
|
module RSpec::Puppet
|
|
18
20
|
class Coverage
|
|
19
|
-
|
|
20
21
|
attr_accessor :filters, :filters_regex
|
|
21
22
|
|
|
22
23
|
class << self
|
|
23
24
|
extend Forwardable
|
|
24
25
|
|
|
25
|
-
delegated_methods = [
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
26
|
+
delegated_methods = %i[
|
|
27
|
+
instance
|
|
28
|
+
add
|
|
29
|
+
cover!
|
|
30
|
+
report!
|
|
31
|
+
filters
|
|
32
|
+
filters_regex
|
|
33
|
+
add_filter
|
|
34
|
+
add_filter_regex
|
|
35
|
+
add_from_catalog
|
|
36
|
+
results
|
|
36
37
|
]
|
|
37
38
|
|
|
38
39
|
def_delegators(*delegated_methods)
|
|
@@ -112,23 +113,21 @@ module RSpec::Puppet
|
|
|
112
113
|
end
|
|
113
114
|
|
|
114
115
|
def add(resource)
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
return unless !exists?(resource) && !filtered?(resource)
|
|
117
|
+
|
|
118
|
+
@collection[resource.to_s] = ResourceWrapper.new(resource)
|
|
118
119
|
end
|
|
119
120
|
|
|
120
121
|
def add_filter(type, title)
|
|
121
122
|
type = capitalize_name(type)
|
|
122
123
|
|
|
123
|
-
if type == 'Class'
|
|
124
|
-
title = capitalize_name(title)
|
|
125
|
-
end
|
|
124
|
+
title = capitalize_name(title) if type == 'Class'
|
|
126
125
|
|
|
127
126
|
@filters << "#{type}[#{title}]"
|
|
128
127
|
end
|
|
129
128
|
|
|
130
129
|
def add_filter_regex(type, pattern)
|
|
131
|
-
raise ArgumentError
|
|
130
|
+
raise ArgumentError, 'pattern argument must be a Regexp' unless pattern.is_a?(Regexp)
|
|
132
131
|
|
|
133
132
|
type = capitalize_name(type)
|
|
134
133
|
|
|
@@ -145,7 +144,7 @@ module RSpec::Puppet
|
|
|
145
144
|
|
|
146
145
|
# match an even number of backslashes before the anchor - this indicates that the anchor was not escaped
|
|
147
146
|
# note the necessity for the negative lookbehind `(?<!)` to assert that there is no backslash before this
|
|
148
|
-
src = if
|
|
147
|
+
src = if /(?<!\\)(\\\\)*(?:\\[zZ]|\$)\z/.match?(src)
|
|
149
148
|
src.gsub(/(?:\\[zZ]|\$)\z/, '')
|
|
150
149
|
else
|
|
151
150
|
# no anchor at the end
|
|
@@ -157,7 +156,9 @@ module RSpec::Puppet
|
|
|
157
156
|
|
|
158
157
|
# add all resources from catalog declared in module test_module
|
|
159
158
|
def add_from_catalog(catalog, test_module)
|
|
160
|
-
coverable_resources = catalog.to_a.reject
|
|
159
|
+
coverable_resources = catalog.to_a.reject do |resource|
|
|
160
|
+
!test_module.nil? && filter_resource?(resource, test_module)
|
|
161
|
+
end
|
|
161
162
|
coverable_resources.each do |resource|
|
|
162
163
|
add(resource)
|
|
163
164
|
end
|
|
@@ -171,9 +172,9 @@ module RSpec::Puppet
|
|
|
171
172
|
end
|
|
172
173
|
|
|
173
174
|
def cover!(resource)
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
175
|
+
return unless !filtered?(resource) && (wrapper = find(resource))
|
|
176
|
+
|
|
177
|
+
wrapper.touch!
|
|
177
178
|
end
|
|
178
179
|
|
|
179
180
|
def report!(coverage_desired = nil)
|
|
@@ -213,9 +214,9 @@ module RSpec::Puppet
|
|
|
213
214
|
coverage_desired ||= 0
|
|
214
215
|
|
|
215
216
|
if coverage_desired.is_a?(Numeric) && coverage_desired.to_f <= 100.00 && coverage_desired.to_f >= 0.0
|
|
216
|
-
coverage_test = RSpec.describe(
|
|
217
|
+
coverage_test = RSpec.describe('Code coverage')
|
|
217
218
|
coverage_results = coverage_test.example("must cover at least #{coverage_desired}% of resources") do
|
|
218
|
-
expect(
|
|
219
|
+
expect(coverage_actual.to_f).to be >= coverage_desired.to_f
|
|
219
220
|
end
|
|
220
221
|
coverage_test.run(RSpec.configuration.reporter)
|
|
221
222
|
|
|
@@ -248,8 +249,8 @@ module RSpec::Puppet
|
|
|
248
249
|
report[:touched] = @collection.count { |_, resource| resource.touched? }
|
|
249
250
|
report[:untouched] = report[:total] - report[:touched]
|
|
250
251
|
|
|
251
|
-
coverage = report[:total].to_f
|
|
252
|
-
report[:coverage] =
|
|
252
|
+
coverage = report[:total].to_f.positive? ? ((report[:touched].to_f / report[:total]) * 100) : 100.0
|
|
253
|
+
report[:coverage] = '%5.2f' % coverage
|
|
253
254
|
|
|
254
255
|
report[:resources] = Hash[*@collection.map do |name, wrapper|
|
|
255
256
|
[name, wrapper.to_hash]
|
|
@@ -258,10 +259,10 @@ module RSpec::Puppet
|
|
|
258
259
|
text = [
|
|
259
260
|
"Total resources: #{report[:total]}",
|
|
260
261
|
"Touched resources: #{report[:touched]}",
|
|
261
|
-
"Resource coverage: #{report[:coverage]}%"
|
|
262
|
+
"Resource coverage: #{report[:coverage]}%"
|
|
262
263
|
]
|
|
263
264
|
|
|
264
|
-
if report[:untouched]
|
|
265
|
+
if (report[:untouched]).positive?
|
|
265
266
|
text += ['', 'Untouched resources:']
|
|
266
267
|
untouched_resources = report[:resources].reject { |_, r| r[:touched] }
|
|
267
268
|
text += untouched_resources.map { |name, _| " #{name}" }.sort
|
|
@@ -288,25 +289,19 @@ module RSpec::Puppet
|
|
|
288
289
|
# @param test_module [String] The name of the module under test
|
|
289
290
|
# @return [true, false]
|
|
290
291
|
def filter_resource?(resource, test_module)
|
|
291
|
-
if filtered?(resource)
|
|
292
|
-
return true
|
|
293
|
-
end
|
|
292
|
+
return true if filtered?(resource)
|
|
294
293
|
|
|
295
294
|
if resource.type == 'Class'
|
|
296
295
|
module_name = resource.title.split('::').first.downcase
|
|
297
|
-
if module_name != test_module
|
|
298
|
-
return true
|
|
299
|
-
end
|
|
296
|
+
return true if module_name != test_module
|
|
300
297
|
end
|
|
301
298
|
|
|
302
299
|
if resource.file
|
|
303
300
|
paths = module_paths(test_module)
|
|
304
|
-
unless paths.any? { |path| resource.file.include?(path) }
|
|
305
|
-
return true
|
|
306
|
-
end
|
|
301
|
+
return true unless paths.any? { |path| resource.file.include?(path) }
|
|
307
302
|
end
|
|
308
303
|
|
|
309
|
-
|
|
304
|
+
false
|
|
310
305
|
end
|
|
311
306
|
|
|
312
307
|
# Find all paths that may contain testable resources for a module.
|
|
@@ -330,7 +325,7 @@ module RSpec::Puppet
|
|
|
330
325
|
end
|
|
331
326
|
|
|
332
327
|
def capitalize_name(name)
|
|
333
|
-
name.split('::').map
|
|
328
|
+
name.split('::').map(&:capitalize).join('::')
|
|
334
329
|
end
|
|
335
330
|
|
|
336
331
|
class ResourceWrapper
|
|
@@ -346,7 +341,7 @@ module RSpec::Puppet
|
|
|
346
341
|
|
|
347
342
|
def to_hash
|
|
348
343
|
{
|
|
349
|
-
:
|
|
344
|
+
touched: touched?
|
|
350
345
|
}
|
|
351
346
|
end
|
|
352
347
|
|
data/lib/rspec-puppet/errors.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module RSpec::Puppet
|
|
2
4
|
module Errors
|
|
3
5
|
class MatchError < StandardError
|
|
@@ -11,18 +13,16 @@ module RSpec::Puppet
|
|
|
11
13
|
end
|
|
12
14
|
|
|
13
15
|
def message
|
|
14
|
-
if @param.to_s == 'content'
|
|
16
|
+
if (@param.to_s == 'content') && expected.is_a?(String)
|
|
15
17
|
if negative == true
|
|
16
18
|
"#{param} not set to supplied string"
|
|
17
19
|
else
|
|
18
20
|
"#{param} set to supplied string"
|
|
19
21
|
end
|
|
22
|
+
elsif negative == true
|
|
23
|
+
"#{param} not set to #{expected.inspect} but it is set to #{actual.inspect}"
|
|
20
24
|
else
|
|
21
|
-
|
|
22
|
-
"#{param} not set to #{expected.inspect} but it is set to #{actual.inspect}"
|
|
23
|
-
else
|
|
24
|
-
"#{param} set to #{expected.inspect} but it is set to #{actual.inspect}"
|
|
25
|
-
end
|
|
25
|
+
"#{param} set to #{expected.inspect} but it is set to #{actual.inspect}"
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
28
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module RSpec::Puppet
|
|
2
4
|
module ClassExampleGroup
|
|
3
5
|
include RSpec::Puppet::ManifestMatchers
|
|
@@ -8,7 +10,7 @@ module RSpec::Puppet
|
|
|
8
10
|
end
|
|
9
11
|
|
|
10
12
|
def exported_resources
|
|
11
|
-
|
|
13
|
+
-> { load_catalogue(:class, true) }
|
|
12
14
|
end
|
|
13
15
|
|
|
14
16
|
def rspec_puppet_cleanup
|