rspec-puppet-yaml 0.1.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 +7 -0
- data/.gitignore +16 -0
- data/.inch.yml +4 -0
- data/.rspec +2 -0
- data/.travis.yml +29 -0
- data/.yardopts +2 -0
- data/CODE_OF_CONDUCT.md +75 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +93 -0
- data/LICENSE.txt +21 -0
- data/README.md +759 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/rspec-puppet/matcher_helpers.rb +326 -0
- data/lib/rspec-puppet/support_copy.rb +66 -0
- data/lib/rspec-puppet-yaml/data_helpers.rb +176 -0
- data/lib/rspec-puppet-yaml/extenders.rb +28 -0
- data/lib/rspec-puppet-yaml/parser.rb +512 -0
- data/lib/rspec-puppet-yaml/version.rb +11 -0
- data/lib/rspec-puppet-yaml.rb +8 -0
- data/rspec-puppet-yaml.gemspec +45 -0
- metadata +208 -0
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
# Converts the supplied YAML data into rspec tests. When this is called from
|
|
2
|
+
# a *_spec.rb file from RSpec, testing begins immediately upon parsing.
|
|
3
|
+
#
|
|
4
|
+
# @param yaml_file [String] Path to a YAML file containing rspec-puppet tests
|
|
5
|
+
def parse_rspec_puppet_yaml(yaml_file)
|
|
6
|
+
test_data = __load_rspec_puppet_yaml_data(yaml_file)
|
|
7
|
+
|
|
8
|
+
# The top-most entity must be a 'describe', which must have both name (which
|
|
9
|
+
# must be identical to the entity-under-test) and type-of-entity (in case the
|
|
10
|
+
# user failed to follow the prescribed directory structure for unit testing
|
|
11
|
+
# Puppet modules). RSpec docs often show more than one top-level describe,
|
|
12
|
+
# so this function supports the same.
|
|
13
|
+
rspec_file = caller_locations.select {|e| e.path =~ /.+_spec.rb$/}
|
|
14
|
+
.first
|
|
15
|
+
.path
|
|
16
|
+
default_describe = {
|
|
17
|
+
'name' => __get_eut_name(yaml_file, rspec_file),
|
|
18
|
+
'type' => guess_type_from_path(rspec_file)
|
|
19
|
+
}
|
|
20
|
+
describes = []
|
|
21
|
+
RSpec::Puppet::Yaml::DataHelpers.get_array_of_named_hashes(
|
|
22
|
+
'describe',
|
|
23
|
+
test_data,
|
|
24
|
+
).each { |desc| describes << default_describe.merge(desc)}
|
|
25
|
+
__apply_rspec_puppet_describes(describes, test_data)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Identify the name of the entity under test.
|
|
29
|
+
#
|
|
30
|
+
# @note The __ prefix denotes this as a "private" function. Do not call this
|
|
31
|
+
# directly.
|
|
32
|
+
#
|
|
33
|
+
# @param [String] rspec_yaml_file_name YAML file name that describes tests.
|
|
34
|
+
# @param [String] rspec_file_name Name of the *_spec.rb file that is requesting
|
|
35
|
+
# parsed results from `rspec_yaml_file_name`.
|
|
36
|
+
# @return [String] Name of the entity under test.
|
|
37
|
+
def __get_eut_name(rspec_yaml_file_name, rspec_file_name)
|
|
38
|
+
base_yaml = File.basename(rspec_yaml_file_name)
|
|
39
|
+
base_caller = File.basename(rspec_file_name)
|
|
40
|
+
|
|
41
|
+
if base_yaml =~ /^(.+)(_spec)?\.ya?ml$/
|
|
42
|
+
$1.to_s
|
|
43
|
+
elsif base_caller =~ /^(.+)_spec\.rb$/
|
|
44
|
+
$1.to_s
|
|
45
|
+
else
|
|
46
|
+
'unknown'
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Generates an RSpec `describe {}` and its contents.
|
|
51
|
+
#
|
|
52
|
+
# @note The __ prefix denotes this as a "private" function. Do not call this
|
|
53
|
+
# directly.
|
|
54
|
+
#
|
|
55
|
+
# @param apply_attrs [Hash] Definition of the entity and its contents.
|
|
56
|
+
# @param parent_data [Hash] Used for recursion, this is the parent for this
|
|
57
|
+
# entity.
|
|
58
|
+
def __apply_rspec_puppet_describe(apply_attrs = {}, parent_data = {})
|
|
59
|
+
desc_name = RSpec::Puppet::Yaml::DataHelpers.get_named_value(
|
|
60
|
+
'name',
|
|
61
|
+
apply_attrs
|
|
62
|
+
)
|
|
63
|
+
desc_type = RSpec::Puppet::Yaml::DataHelpers.get_named_value(
|
|
64
|
+
'type',
|
|
65
|
+
apply_attrs
|
|
66
|
+
)
|
|
67
|
+
if desc_type.nil?
|
|
68
|
+
describe(desc_name) do
|
|
69
|
+
__apply_rspec_puppet_content(apply_attrs, parent_data)
|
|
70
|
+
end
|
|
71
|
+
else
|
|
72
|
+
describe(desc_name, :type => desc_type) do
|
|
73
|
+
__apply_rspec_puppet_content(apply_attrs, parent_data)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Generates an RSpec `context {}` and its contents.
|
|
79
|
+
#
|
|
80
|
+
# @note The __ prefix denotes this as a "private" function. Do not call this
|
|
81
|
+
# directly.
|
|
82
|
+
#
|
|
83
|
+
# @param apply_attrs [Hash] Definition of the entity and its contents.
|
|
84
|
+
# @param parent_data [Hash] Used for recursion, this is the parent for this
|
|
85
|
+
# entity.
|
|
86
|
+
def __apply_rspec_puppet_context(apply_attrs = {}, parent_data = {})
|
|
87
|
+
context_name = RSpec::Puppet::Yaml::DataHelpers.get_named_value(
|
|
88
|
+
'name',
|
|
89
|
+
apply_attrs
|
|
90
|
+
)
|
|
91
|
+
context(context_name) do
|
|
92
|
+
__apply_rspec_puppet_content(apply_attrs, parent_data)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# An extension for RSpec, variants are contexts that repeat all parent tests
|
|
97
|
+
# with specified tweaks to their inputs and expectations.
|
|
98
|
+
#
|
|
99
|
+
# @note The __ prefix denotes this as a "private" function. Do not call this
|
|
100
|
+
# directly.
|
|
101
|
+
#
|
|
102
|
+
# @param apply_attrs [Hash] Definition of the entity and its contents.
|
|
103
|
+
# @param parent_data [Hash] Used for recursion, this is the parent for this
|
|
104
|
+
# entity.
|
|
105
|
+
def __apply_rspec_puppet_variant(apply_attrs = {}, parent_data = {})
|
|
106
|
+
variant_name = RSpec::Puppet::Yaml::DataHelpers.get_named_value(
|
|
107
|
+
'name',
|
|
108
|
+
apply_attrs
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
# The deep_merge gem's funtionality unfortunately changes the destination
|
|
112
|
+
# Hash, even when you attempt to store the result to another variable and use
|
|
113
|
+
# the non-bang method call. This seems like a pretty serious bug, to me,
|
|
114
|
+
# despite the gem's documentation implying that this will happen. IMHO, the
|
|
115
|
+
# gem's author made a very poor decision in how the bang and non-bang behavior
|
|
116
|
+
# would differ (merely a difference in the default values of its options
|
|
117
|
+
# rather than the Ruby-norm of affecting or not-affecting the calling Object).
|
|
118
|
+
# To workaround this issue and protect the original destination against
|
|
119
|
+
# unwanted change, a deep copy of the destination Hash must be taken and used.
|
|
120
|
+
parent_dup = Marshal.load(Marshal.dump(parent_data))
|
|
121
|
+
context_data = parent_dup.select do |k,v|
|
|
122
|
+
!['variants', 'before', 'after', 'subject'].include?(k.to_s)
|
|
123
|
+
end
|
|
124
|
+
context_data.deep_merge!(
|
|
125
|
+
apply_attrs,
|
|
126
|
+
{ :extend_existing_arrays => false,
|
|
127
|
+
:merge_hash_arrays => true,
|
|
128
|
+
:merge_nil_values => false,
|
|
129
|
+
:overwrite_arrays => false,
|
|
130
|
+
:preserve_unmergeables => false,
|
|
131
|
+
:sort_merged_arrays => false
|
|
132
|
+
}
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
context(variant_name) do
|
|
136
|
+
__apply_rspec_puppet_content(context_data, parent_data)
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Generates a set of RSpec `describe` entities.
|
|
141
|
+
#
|
|
142
|
+
# @note The __ prefix denotes this as a "private" function. Do not call this
|
|
143
|
+
# directly.
|
|
144
|
+
#
|
|
145
|
+
# @param describes [Array[Hash]] Set of entities to generate. Each element must
|
|
146
|
+
# be a Hash that has a :name or 'name' attribute.
|
|
147
|
+
# @param parent_data [Hash] Used for recursion, this is the parent for this
|
|
148
|
+
# entity.
|
|
149
|
+
def __apply_rspec_puppet_describes(describes = [], parent_data = {})
|
|
150
|
+
bad_input = false
|
|
151
|
+
|
|
152
|
+
# Input must be an Array
|
|
153
|
+
if !describes.kind_of?(Array)
|
|
154
|
+
bad_input = true
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Every element of the input must be a Hash, each with a :name attribute
|
|
158
|
+
describes.each do |container|
|
|
159
|
+
if !container.is_a?(Hash)
|
|
160
|
+
bad_input = true
|
|
161
|
+
elsif !container.has_key?('name') && !container.has_key?(:name)
|
|
162
|
+
bad_input = true
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
if bad_input
|
|
167
|
+
raise ArgumentError, "__apply_rspec_puppet_describes requires an Array of Hashes, each with a :name attribute."
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
describes.each do |container|
|
|
171
|
+
__apply_rspec_puppet_describe(container, parent_data)
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
# Generates a set of RSpec `context` entities.
|
|
176
|
+
#
|
|
177
|
+
# @note The __ prefix denotes this as a "private" function. Do not call this
|
|
178
|
+
# directly.
|
|
179
|
+
#
|
|
180
|
+
# @param contexts [Array[Hash]] Set of entities to generate. Each element must
|
|
181
|
+
# be a Hash that has a :name or 'name' attribute.
|
|
182
|
+
# @param parent_data [Hash] Used for recursion, this is the parent for this
|
|
183
|
+
# entity.
|
|
184
|
+
def __apply_rspec_puppet_contexts(contexts = [], parent_data = {})
|
|
185
|
+
bad_input = false
|
|
186
|
+
|
|
187
|
+
# Input must be an Array
|
|
188
|
+
if !contexts.kind_of?(Array)
|
|
189
|
+
bad_input = true
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
# Every element of the input must be a Hash, each with a :name attribute
|
|
193
|
+
contexts.each do |container|
|
|
194
|
+
if !container.is_a?(Hash)
|
|
195
|
+
bad_input = true
|
|
196
|
+
elsif !container.has_key?('name') && !container.has_key?(:name)
|
|
197
|
+
bad_input = true
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
if bad_input
|
|
202
|
+
raise ArgumentError, "__apply_rspec_puppet_contexts requires an Array of Hashes, each with a :name attribute."
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
contexts.each do |container|
|
|
206
|
+
__apply_rspec_puppet_context(container, parent_data)
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
# Generates a set of variants of RSpec entities.
|
|
211
|
+
#
|
|
212
|
+
# @note The __ prefix denotes this as a "private" function. Do not call this
|
|
213
|
+
# directly.
|
|
214
|
+
#
|
|
215
|
+
# @param variants [Array[Hash]] Set of entities to generate. Each element must
|
|
216
|
+
# be a Hash that has a :name or 'name' attribute.
|
|
217
|
+
# @param parent_data [Hash] Used for recursion, this is the parent for this
|
|
218
|
+
# entity.
|
|
219
|
+
def __apply_rspec_puppet_variants(variants = [], parent_data = {})
|
|
220
|
+
bad_input = false
|
|
221
|
+
|
|
222
|
+
# Input must be an Array
|
|
223
|
+
if !variants.kind_of?(Array)
|
|
224
|
+
bad_input = true
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
# Every element of the input must be a Hash, each with a :name attribute
|
|
228
|
+
variants.each do |variant|
|
|
229
|
+
if !variant.is_a?(Hash)
|
|
230
|
+
bad_input = true
|
|
231
|
+
elsif !variant.has_key?('name') && !variant.has_key?(:name)
|
|
232
|
+
bad_input = true
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
if bad_input
|
|
237
|
+
raise ArgumentError, "__apply_rspec_puppet_variants requires an Array of Hashes, each with a :name attribute."
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
variants.each { |variant| __apply_rspec_puppet_variant(variant, parent_data) }
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
# Generates a set of RSpec `it {}` "examples".
|
|
244
|
+
#
|
|
245
|
+
# @note The __ prefix denotes this as a "private" function. Do not call this
|
|
246
|
+
# directly.
|
|
247
|
+
#
|
|
248
|
+
# @param tests [Hash] Set of examples to build.
|
|
249
|
+
def __apply_rspec_puppet_tests(tests = {})
|
|
250
|
+
tests.each do |method, props|
|
|
251
|
+
# props must be split into args and tests based on method
|
|
252
|
+
case method.to_s
|
|
253
|
+
when /^(!)?((contain|create)_.+)$/
|
|
254
|
+
# There can be only one beyond this point, so recurse as necessary
|
|
255
|
+
if 1 < props.keys.count
|
|
256
|
+
props.each { |k,v| __apply_rspec_puppet_tests({method => {k => v}})}
|
|
257
|
+
return # Avoid processing the first entry twice
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
positive_test = $1.nil?
|
|
261
|
+
apply_method = $2
|
|
262
|
+
args = [ props.keys.first ]
|
|
263
|
+
calls = props.values.first
|
|
264
|
+
when /^(!)?(have_.+_count)$/
|
|
265
|
+
positive_test = $1.nil?
|
|
266
|
+
apply_method = $2
|
|
267
|
+
args = props
|
|
268
|
+
calls = {}
|
|
269
|
+
when /^(!)?(compile)$/
|
|
270
|
+
positive_test = $1.nil?
|
|
271
|
+
apply_method = $2
|
|
272
|
+
args = []
|
|
273
|
+
calls = props
|
|
274
|
+
when /^(!)?(run)$/
|
|
275
|
+
positive_test = $1.nil?
|
|
276
|
+
apply_method = $2
|
|
277
|
+
args = []
|
|
278
|
+
calls = props
|
|
279
|
+
when /^(!)?(be_valid_type)$/
|
|
280
|
+
positive_test = $1.nil?
|
|
281
|
+
apply_method = $2
|
|
282
|
+
args = []
|
|
283
|
+
calls = props
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
matcher = RSpec::Puppet::MatcherHelpers.get_matcher_for(
|
|
287
|
+
apply_method,
|
|
288
|
+
args,
|
|
289
|
+
calls
|
|
290
|
+
)
|
|
291
|
+
|
|
292
|
+
if positive_test
|
|
293
|
+
it { is_expected.to matcher }
|
|
294
|
+
else
|
|
295
|
+
it { is_expected.not_to matcher }
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
# Generates an RSpec `before {}` entity with one or more global-scope method
|
|
301
|
+
# calls as its contents.
|
|
302
|
+
#
|
|
303
|
+
# @note The __ prefix denotes this as a "private" function. Do not call this
|
|
304
|
+
# directly.
|
|
305
|
+
#
|
|
306
|
+
# @param commands [Variant[String,Array[String]]] Command or commands to call.
|
|
307
|
+
def __apply_rspec_puppet_before(commands)
|
|
308
|
+
if !commands.nil?
|
|
309
|
+
if commands.kind_of?(Array)
|
|
310
|
+
before do
|
|
311
|
+
commands.each { |command| Object.send(command.to_s.to_sym) }
|
|
312
|
+
end
|
|
313
|
+
elsif !commands.is_a?(Hash)
|
|
314
|
+
before { Object.send(commands.to_s.to_sym) }
|
|
315
|
+
else
|
|
316
|
+
raise ArgumentError, "__apply_rspec_puppet_before requires a command String or an Array of commands."
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
# Generates an RSpec `after {}` entity with one or more global-scope method
|
|
322
|
+
# calls as its contents.
|
|
323
|
+
#
|
|
324
|
+
# @note The __ prefix denotes this as a "private" function. Do not call this
|
|
325
|
+
# directly.
|
|
326
|
+
#
|
|
327
|
+
# @param commands [Variant[String,Array[String]]] Command or commands to call.
|
|
328
|
+
def __apply_rspec_puppet_after(commands)
|
|
329
|
+
if !commands.nil?
|
|
330
|
+
if commands.kind_of?(Array)
|
|
331
|
+
after do
|
|
332
|
+
commands.each { |command| Object.send(command.to_s.to_sym) }
|
|
333
|
+
end
|
|
334
|
+
elsif !commands.is_a?(Hash)
|
|
335
|
+
after { Object.send(commands.to_s.to_sym) }
|
|
336
|
+
else
|
|
337
|
+
raise ArgumentError, "__apply_rspec_puppet_after requires a command String or an Array of commands."
|
|
338
|
+
end
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
# Generates an RSpec `subject {}` entity.
|
|
343
|
+
#
|
|
344
|
+
# @note The __ prefix denotes this as a "private" function. Do not call this
|
|
345
|
+
# directly.
|
|
346
|
+
#
|
|
347
|
+
# @param subject [Any] The subject descriptor.
|
|
348
|
+
def __apply_rspec_puppet_subject(subject)
|
|
349
|
+
if !subject.nil?
|
|
350
|
+
subject { __expand_data_commands(subject) }
|
|
351
|
+
end
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
# Sets all let variables.
|
|
355
|
+
#
|
|
356
|
+
# @note The __ prefix denotes this as a "private" function. Do not call this
|
|
357
|
+
# directly.
|
|
358
|
+
#
|
|
359
|
+
# @param lets [Hash] The data to scan for let variables
|
|
360
|
+
#
|
|
361
|
+
# @example As YAML
|
|
362
|
+
# ---
|
|
363
|
+
# let:
|
|
364
|
+
# facts:
|
|
365
|
+
# kernel: Linux
|
|
366
|
+
# os:
|
|
367
|
+
# family: RedHat
|
|
368
|
+
# name: CentOS
|
|
369
|
+
# release:
|
|
370
|
+
# major: 7
|
|
371
|
+
# minor: 1
|
|
372
|
+
# params:
|
|
373
|
+
# require: '%{eval:ref("Package", "my-package")}'
|
|
374
|
+
# nodes:
|
|
375
|
+
# '%{eval:ref("Node", "dbnode")}': '%{eval:ref("Myapp::Mycomponent", "myapp")}'
|
|
376
|
+
def __apply_rspec_puppet_lets(lets = {})
|
|
377
|
+
__expand_data_commands(lets).each { |k,v| let(k.to_sym) { v } }
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
# Recursively expands specially-formatted commands with or without arguments to
|
|
381
|
+
# them found within serialized data.
|
|
382
|
+
#
|
|
383
|
+
# @param serialized_data [Any] The data to check for expansion markers and
|
|
384
|
+
# expand them, when present.
|
|
385
|
+
# @return [Any] Expanded or original (when there are no expansion markers) data.
|
|
386
|
+
def __expand_data_commands(serialized_data)
|
|
387
|
+
return nil if serialized_data.nil?
|
|
388
|
+
if serialized_data.kind_of?(Array)
|
|
389
|
+
expanded_data = []
|
|
390
|
+
serialized_data.each { |elem| expanded_data << __expand_data_commands(elem) }
|
|
391
|
+
elsif serialized_data.is_a?(Hash)
|
|
392
|
+
expanded_data = {}
|
|
393
|
+
serialized_data.each do |k,v|
|
|
394
|
+
expanded_data[__expand_data_commands(k)] = __expand_data_commands(v)
|
|
395
|
+
end
|
|
396
|
+
else
|
|
397
|
+
test_data = serialized_data.to_s
|
|
398
|
+
if test_data =~ /^%{eval:(.+)}$/
|
|
399
|
+
test_eval = $1
|
|
400
|
+
begin
|
|
401
|
+
test_value = eval test_eval
|
|
402
|
+
rescue Exception => ex
|
|
403
|
+
test_value = "#{ex.class}: #{test_eval}. #{ex.message}"
|
|
404
|
+
end
|
|
405
|
+
else
|
|
406
|
+
test_value = serialized_data
|
|
407
|
+
end
|
|
408
|
+
expanded_data = test_value
|
|
409
|
+
end
|
|
410
|
+
expanded_data
|
|
411
|
+
end
|
|
412
|
+
|
|
413
|
+
# Generates all specified RSpec entities. This is assumed to be run within a
|
|
414
|
+
# valid RSpec container, like `describe` or `context`.
|
|
415
|
+
#
|
|
416
|
+
# @note The __ prefix denotes this as a "private" function. Do not call this
|
|
417
|
+
# directly.
|
|
418
|
+
#
|
|
419
|
+
# @param apply_data [Hash] The entities to generate.
|
|
420
|
+
# @param parent_data [Hash] Used for recursion, this is the parent of the
|
|
421
|
+
# receiving entity.
|
|
422
|
+
def __apply_rspec_puppet_content(apply_data = {}, parent_data = {})
|
|
423
|
+
__apply_rspec_puppet_subject(
|
|
424
|
+
RSpec::Puppet::Yaml::DataHelpers.get_named_value(
|
|
425
|
+
'subject',
|
|
426
|
+
apply_data
|
|
427
|
+
)
|
|
428
|
+
)
|
|
429
|
+
__apply_rspec_puppet_lets(
|
|
430
|
+
RSpec::Puppet::Yaml::DataHelpers.get_named_hash(
|
|
431
|
+
'let',
|
|
432
|
+
apply_data
|
|
433
|
+
)
|
|
434
|
+
)
|
|
435
|
+
__apply_rspec_puppet_before(
|
|
436
|
+
RSpec::Puppet::Yaml::DataHelpers.get_named_value(
|
|
437
|
+
'before',
|
|
438
|
+
apply_data
|
|
439
|
+
)
|
|
440
|
+
)
|
|
441
|
+
__apply_rspec_puppet_after(
|
|
442
|
+
RSpec::Puppet::Yaml::DataHelpers.get_named_value(
|
|
443
|
+
'after',
|
|
444
|
+
apply_data
|
|
445
|
+
)
|
|
446
|
+
)
|
|
447
|
+
__apply_rspec_puppet_tests(
|
|
448
|
+
RSpec::Puppet::Yaml::DataHelpers.get_named_hash(
|
|
449
|
+
'tests',
|
|
450
|
+
apply_data
|
|
451
|
+
)
|
|
452
|
+
)
|
|
453
|
+
__apply_rspec_puppet_describes(
|
|
454
|
+
RSpec::Puppet::Yaml::DataHelpers.get_array_of_named_hashes(
|
|
455
|
+
'describe',
|
|
456
|
+
apply_data
|
|
457
|
+
),
|
|
458
|
+
apply_data
|
|
459
|
+
)
|
|
460
|
+
__apply_rspec_puppet_contexts(
|
|
461
|
+
RSpec::Puppet::Yaml::DataHelpers.get_array_of_named_hashes(
|
|
462
|
+
'context',
|
|
463
|
+
apply_data
|
|
464
|
+
),
|
|
465
|
+
apply_data
|
|
466
|
+
)
|
|
467
|
+
__apply_rspec_puppet_variants(
|
|
468
|
+
RSpec::Puppet::Yaml::DataHelpers.get_array_of_named_hashes(
|
|
469
|
+
'variants',
|
|
470
|
+
apply_data
|
|
471
|
+
),
|
|
472
|
+
apply_data
|
|
473
|
+
)
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
# Attempts to load the YAML test data and return its data.
|
|
477
|
+
#
|
|
478
|
+
# @note The __ prefix denotes this as a "private" function. Do not call this
|
|
479
|
+
# directly.
|
|
480
|
+
#
|
|
481
|
+
# @param yaml_file [String] Path to the YAML file to load.
|
|
482
|
+
# @return [Hash] The data from the YAML file.
|
|
483
|
+
#
|
|
484
|
+
# @raise IOError when the source file is not valid YAML or does not
|
|
485
|
+
# contain a Hash.
|
|
486
|
+
def __load_rspec_puppet_yaml_data(yaml_file)
|
|
487
|
+
# The test data file must exist
|
|
488
|
+
if !File.exists?(yaml_file)
|
|
489
|
+
raise IOError, "#{yaml_file} does not exit."
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
begin
|
|
493
|
+
yaml_data = YAML.load_file(yaml_file)
|
|
494
|
+
rescue Psych::SyntaxError => ex
|
|
495
|
+
raise IOError, "#{yaml_file} contains a YAML syntax error."
|
|
496
|
+
rescue ArgumentError => ex
|
|
497
|
+
raise IOError, "#{yaml_file} contains missing or undefined entities."
|
|
498
|
+
rescue
|
|
499
|
+
raise IOError, "#{yaml_file} could not be read or is not YAML."
|
|
500
|
+
end
|
|
501
|
+
|
|
502
|
+
# Must be a populated Hash
|
|
503
|
+
if yaml_data.nil? || !yaml_data.is_a?(Hash)
|
|
504
|
+
yaml_data = nil
|
|
505
|
+
raise IOError, "#{yaml_file} is not a valid YAML Hash data structure."
|
|
506
|
+
elsif yaml_data.empty?
|
|
507
|
+
yaml_data = nil
|
|
508
|
+
raise IOError, "#{yaml_file} contains no legible tests."
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
yaml_data
|
|
512
|
+
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
require 'rspec-puppet/matcher_helpers'
|
|
2
|
+
require 'rspec-puppet/support_copy'
|
|
3
|
+
require "rspec-puppet-yaml/version"
|
|
4
|
+
require 'rspec-puppet-yaml/data_helpers'
|
|
5
|
+
require 'rspec-puppet-yaml/extenders'
|
|
6
|
+
require 'rspec-puppet-yaml/parser'
|
|
7
|
+
require 'deep_merge'
|
|
8
|
+
require 'yaml'
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require "rspec-puppet-yaml/version"
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "rspec-puppet-yaml"
|
|
8
|
+
spec.version = RSpec::Puppet::Yaml::VERSION
|
|
9
|
+
spec.authors = ["William W. Kimball, Jr., MBA, MSIS"]
|
|
10
|
+
spec.email = ["github-rspec-puppet-yaml@kimballstuff.com"]
|
|
11
|
+
|
|
12
|
+
spec.summary = %q{Enables the use of YAML to specify rspec tests for Puppet projects}
|
|
13
|
+
spec.description = %q{rspec is effective but quite hard to learn for Puppet authors who don't wish to take up Ruby. YAML is comparatively easy to pick up and most Puppet authors are necessarily exposed to it. This extension enables Puppet code authors to define their rspec-puppet tests in YAML instead of Ruby.}
|
|
14
|
+
spec.homepage = "https://github.com/wwkimball/rspec-puppet-yaml"
|
|
15
|
+
spec.license = "MIT"
|
|
16
|
+
|
|
17
|
+
# It's not clear why I would want to disable pushing this public gem to RubyGems.org...
|
|
18
|
+
## Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
|
19
|
+
## to allow pushing to a single host or delete this section to allow pushing to any host.
|
|
20
|
+
#if spec.respond_to?(:metadata)
|
|
21
|
+
# spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
|
|
22
|
+
#else
|
|
23
|
+
# raise "RubyGems 2.0 or newer is required to protect against " \
|
|
24
|
+
# "public gem pushes."
|
|
25
|
+
#end
|
|
26
|
+
|
|
27
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
28
|
+
f.match(%r{^(test|spec|features)/})
|
|
29
|
+
end
|
|
30
|
+
spec.bindir = "exe"
|
|
31
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
32
|
+
spec.require_paths = ["lib"]
|
|
33
|
+
|
|
34
|
+
spec.add_development_dependency "bundler", "~> 1.15"
|
|
35
|
+
spec.add_development_dependency "rake", "~> 12.0"
|
|
36
|
+
spec.add_development_dependency "yard", "~> 0.9"
|
|
37
|
+
spec.add_development_dependency "json", "~> 2.1"
|
|
38
|
+
spec.add_development_dependency "puppet", "~> 5"
|
|
39
|
+
spec.add_development_dependency "puppetlabs_spec_helper", "~> 2.3"
|
|
40
|
+
spec.add_development_dependency "puppet-strings", "~> 1"
|
|
41
|
+
spec.add_development_dependency "rspec-puppet-facts", "~> 1.8"
|
|
42
|
+
|
|
43
|
+
spec.add_dependency "rspec-puppet", "~> 2.6"
|
|
44
|
+
spec.add_dependency "deep_merge", "~> 1.1"
|
|
45
|
+
end
|