puppetlabs-onceover 5.0.3 → 5.0.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 (32) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -0
  3. data/.rubocop_todo.yml +35 -15
  4. data/CHANGELOG.md +387 -3
  5. data/Gemfile +1 -0
  6. data/lib/puppetlabs-onceover/cli/plugins.rb +3 -3
  7. data/lib/puppetlabs-onceover/controlrepo.rb +8 -7
  8. data/lib/puppetlabs-onceover/version.rb +1 -1
  9. data/spec/fixtures/controlrepos/deploy_test/Puppetfile +3 -0
  10. data/spec/fixtures/controlrepos/deploy_test/a_dir/nested_file.txt +1 -0
  11. data/spec/fixtures/controlrepos/deploy_test/a_symlink +1 -0
  12. data/spec/fixtures/controlrepos/deploy_test/environment.conf +1 -0
  13. data/spec/fixtures/controlrepos/deploy_test/regular_file.txt +1 -0
  14. data/spec/puppetlabs-onceover/beaker_spec.rb +293 -0
  15. data/spec/puppetlabs-onceover/class_spec.rb +89 -0
  16. data/spec/puppetlabs-onceover/cli/run_spec.rb +80 -0
  17. data/spec/puppetlabs-onceover/cli/show_spec.rb +67 -0
  18. data/spec/puppetlabs-onceover/cli_spec.rb +79 -0
  19. data/spec/puppetlabs-onceover/controlrepo_spec.rb +787 -5
  20. data/spec/puppetlabs-onceover/deploy_spec.rb +246 -0
  21. data/spec/puppetlabs-onceover/group_spec.rb +121 -0
  22. data/spec/puppetlabs-onceover/logger_spec.rb +30 -0
  23. data/spec/puppetlabs-onceover/node_spec.rb +124 -0
  24. data/spec/puppetlabs-onceover/rake_tasks_spec.rb +173 -0
  25. data/spec/puppetlabs-onceover/rspec/formatters_spec.rb +361 -0
  26. data/spec/puppetlabs-onceover/runner_spec.rb +307 -0
  27. data/spec/puppetlabs-onceover/test_spec.rb +177 -0
  28. data/spec/puppetlabs-onceover/testconfig_spec.rb +451 -0
  29. data/spec/puppetlabs-onceover/vendored_modules_spec.rb +302 -0
  30. data/spec/puppetlabs-onceover/version_spec.rb +10 -0
  31. data/spec/spec_helper.rb +8 -0
  32. metadata +22 -1
@@ -0,0 +1,451 @@
1
+ require 'spec_helper'
2
+ require 'puppetlabs-onceover/testconfig'
3
+ require 'puppetlabs-onceover/controlrepo'
4
+ require 'tempfile'
5
+ require 'tmpdir'
6
+ require 'yaml'
7
+ require 'fileutils'
8
+
9
+ describe "PuppetlabsOnceover::TestConfig" do
10
+ before(:each) do
11
+ PuppetlabsOnceover::Class.class_variable_set(:@@all, [])
12
+ PuppetlabsOnceover::Node.class_variable_set(:@@all, [])
13
+ PuppetlabsOnceover::Group.class_variable_set(:@@all, [])
14
+ PuppetlabsOnceover::Test.class_variable_set(:@@all, [])
15
+ logger.level = :fatal
16
+ # Silence the deprecation warnings printed by the deprecated methods under test,
17
+ # they're expected noise, not something we're asserting on.
18
+ end
19
+
20
+ # Helper to write an arbitrary onceover.yaml-shaped hash out to a real tempfile,
21
+ # since some branches (malformed YAML, missing 'type' deprecation, all_tests, etc.)
22
+ # aren't exercised by any checked-in fixture.
23
+ def write_yaml(hash)
24
+ file = Tempfile.new(['onceover', '.yaml'])
25
+ file.write(hash.to_yaml)
26
+ file.close
27
+ file.path
28
+ end
29
+
30
+ let(:function_mocking_repo) do
31
+ PuppetlabsOnceover::Controlrepo.new(path: 'spec/fixtures/controlrepos/function_mocking')
32
+ end
33
+
34
+ let(:puppet_controlrepo) do
35
+ PuppetlabsOnceover::Controlrepo.new(
36
+ path: File.expand_path('spec/fixtures/controlrepos/puppet_controlrepo'),
37
+ tempdir: Dir.mktmpdir('onceover-testconfig-spec')
38
+ )
39
+ end
40
+
41
+ describe "#initialize" do
42
+ it "raises a friendly error when the file does not exist" do
43
+ expect do
44
+ PuppetlabsOnceover::TestConfig.new('spec/fixtures/controlrepos/does_not_exist/onceover.yaml')
45
+ end.to raise_error(RuntimeError, /Could not find/)
46
+ end
47
+
48
+ it "raises a friendly error when the YAML is malformed" do
49
+ file = Tempfile.new(['bad', '.yaml'])
50
+ file.write("classes: [\nnodes: not: valid: :yaml")
51
+ file.close
52
+
53
+ expect do
54
+ PuppetlabsOnceover::TestConfig.new(file.path)
55
+ end.to raise_error(RuntimeError, /Could not parse/)
56
+ end
57
+
58
+ it "loads classes/nodes/groups/test_matrix from a real onceover.yaml, expanding regex classes via the controlrepo" do
59
+ function_mocking_repo
60
+ config = PuppetlabsOnceover::TestConfig.new('spec/fixtures/controlrepos/function_mocking/spec/onceover.yaml')
61
+
62
+ expect(config.classes).not_to be_empty
63
+ expect(config.classes.map(&:name)).to all(match(/role::/))
64
+ expect(config.nodes.map(&:name)).to eq(['CentOS-7.0-64'])
65
+ expect(config.spec_tests).not_to be_empty
66
+ expect(config.acceptance_tests).to eq([])
67
+ end
68
+
69
+ it "builds the default 'all_nodes'/'all_classes' groups even with no explicit node_groups/class_groups" do
70
+ function_mocking_repo
71
+ config = PuppetlabsOnceover::TestConfig.new('spec/fixtures/controlrepos/function_mocking/spec/onceover.yaml')
72
+ expect(config.node_groups.map(&:name)).to include('all_nodes')
73
+ expect(config.class_groups.map(&:name)).to include('all_classes')
74
+ end
75
+
76
+ it "builds subtractive node_groups and populates both spec_tests and acceptance_tests" do
77
+ puppet_controlrepo
78
+ # caching's yaml has a subtractive-free node_group but a class_groups subtraction and both
79
+ # 'spec' and no acceptance -- use the puppet_controlrepo yaml instead, which has a
80
+ # subtractive class_group (linux_classes) and tags.
81
+ config = PuppetlabsOnceover::TestConfig.new('spec/fixtures/controlrepos/puppet_controlrepo/spec/onceover.yaml')
82
+ expect(config.class_groups.map(&:name)).to include('linux_classes')
83
+ expect(config.spec_tests).not_to be_empty
84
+ # the 'master' matrix entry sets a tag
85
+ master_test = config.spec_tests.find { |t| t.tags.include?('master') }
86
+ expect(master_test).not_to be_nil
87
+ end
88
+
89
+ it "builds both acceptance_tests and spec_tests from an 'all_tests' matrix entry" do
90
+ function_mocking_repo
91
+ yaml_path = write_yaml(
92
+ 'classes' => ['role::test_data_return'],
93
+ 'nodes' => ['CentOS-7.0-64'],
94
+ 'test_matrix' => [
95
+ { 'all_nodes' => { 'classes' => 'all_classes', 'tests' => 'all_tests' } }
96
+ ]
97
+ )
98
+ config = PuppetlabsOnceover::TestConfig.new(yaml_path)
99
+ expect(config.spec_tests).not_to be_empty
100
+ expect(config.acceptance_tests).not_to be_empty
101
+ expect(config.spec_tests).to eq(config.acceptance_tests)
102
+ end
103
+
104
+ it "populates only acceptance_tests from an 'acceptance' matrix entry" do
105
+ function_mocking_repo
106
+ yaml_path = write_yaml(
107
+ 'classes' => ['role::test_data_return'],
108
+ 'nodes' => ['CentOS-7.0-64'],
109
+ 'test_matrix' => [
110
+ { 'all_nodes' => { 'classes' => 'all_classes', 'tests' => 'acceptance' } }
111
+ ]
112
+ )
113
+ config = PuppetlabsOnceover::TestConfig.new(yaml_path)
114
+ expect(config.spec_tests).to eq([])
115
+ expect(config.acceptance_tests).not_to be_empty
116
+ end
117
+
118
+ it "warns about the deprecated 'type' key on mocked functions but still loads them" do
119
+ function_mocking_repo
120
+ yaml_path = write_yaml(
121
+ 'classes' => ['role::test_data_return'],
122
+ 'nodes' => ['CentOS-7.0-64'],
123
+ 'test_matrix' => [{ 'all_nodes' => { 'classes' => 'all_classes', 'tests' => 'spec' } }],
124
+ 'functions' => { 'myfunc' => { 'type' => 'ruby', 'returns' => 'foo' } }
125
+ )
126
+ expect(logger).to receive(:warn).with(/'type' key for mocked functions is deprecated/)
127
+ config = PuppetlabsOnceover::TestConfig.new(yaml_path)
128
+ expect(config.mock_functions).to have_key('myfunc')
129
+ end
130
+
131
+ it "sets filter_tags/filter_classes/filter_nodes/skip_r10k/force/fail_fast from opts" do
132
+ function_mocking_repo
133
+ config = PuppetlabsOnceover::TestConfig.new(
134
+ 'spec/fixtures/controlrepos/function_mocking/spec/onceover.yaml',
135
+ tags: 'foo,bar', classes: 'role::test_data_return', nodes: 'CentOS-7.0-64',
136
+ skip_r10k: true, force: true, fail_fast: true
137
+ )
138
+ expect(config.filter_tags).to eq(%w[foo bar])
139
+ expect(config.filter_classes.map(&:name)).to eq(['role::test_data_return'])
140
+ expect(config.filter_nodes.map(&:name)).to eq(['CentOS-7.0-64'])
141
+ expect(config.skip_r10k).to eq(true)
142
+ expect(config.force).to eq(true)
143
+ expect(config.fail_fast).to eq(true)
144
+ end
145
+
146
+ it "defaults skip_r10k/force/fail_fast to false when opts don't set them" do
147
+ function_mocking_repo
148
+ config = PuppetlabsOnceover::TestConfig.new('spec/fixtures/controlrepos/function_mocking/spec/onceover.yaml')
149
+ expect(config.skip_r10k).to eq(false)
150
+ expect(config.force).to eq(false)
151
+ expect(config.fail_fast).to eq(false)
152
+ expect(config.filter_tags).to be_nil
153
+ expect(config.filter_classes).to be_nil
154
+ expect(config.filter_nodes).to be_nil
155
+ end
156
+
157
+ it "defaults formatters based on :parallel when opts[:format] is [:defaults]" do
158
+ function_mocking_repo
159
+ config = PuppetlabsOnceover::TestConfig.new(
160
+ 'spec/fixtures/controlrepos/function_mocking/spec/onceover.yaml',
161
+ format: [:defaults]
162
+ )
163
+ expect(config.formatters).to eq(['PuppetlabsOnceoverFormatter'])
164
+
165
+ config_parallel = PuppetlabsOnceover::TestConfig.new(
166
+ 'spec/fixtures/controlrepos/function_mocking/spec/onceover.yaml',
167
+ format: [:defaults], parallel: true
168
+ )
169
+ expect(config_parallel.formatters).to eq(['PuppetlabsOnceoverFormatterParallel'])
170
+ end
171
+
172
+ it "uses an explicit :format option verbatim when given" do
173
+ function_mocking_repo
174
+ config = PuppetlabsOnceover::TestConfig.new(
175
+ 'spec/fixtures/controlrepos/function_mocking/spec/onceover.yaml',
176
+ format: ['documentation']
177
+ )
178
+ expect(config.formatters).to eq(['documentation'])
179
+ end
180
+
181
+ it "sets strict_variables based on opts[:strict_variables]" do
182
+ function_mocking_repo
183
+ yes_config = PuppetlabsOnceover::TestConfig.new(
184
+ 'spec/fixtures/controlrepos/function_mocking/spec/onceover.yaml', strict_variables: true
185
+ )
186
+ no_config = PuppetlabsOnceover::TestConfig.new(
187
+ 'spec/fixtures/controlrepos/function_mocking/spec/onceover.yaml', strict_variables: false
188
+ )
189
+ expect(yes_config.strict_variables).to eq('yes')
190
+ expect(no_config.strict_variables).to eq('no')
191
+ end
192
+ end
193
+
194
+ describe "#to_s" do
195
+ it "renders a colorized summary" do
196
+ function_mocking_repo
197
+ config = PuppetlabsOnceover::TestConfig.new('spec/fixtures/controlrepos/function_mocking/spec/onceover.yaml')
198
+ expect(config.to_s).to include('classes')
199
+ expect(config.to_s).to include('CentOS-7.0-64')
200
+ end
201
+ end
202
+
203
+ describe ".find_list" do
204
+ before(:each) { function_mocking_repo }
205
+
206
+ it "finds a group's members" do
207
+ a = PuppetlabsOnceover::Node.new('node_a')
208
+ PuppetlabsOnceover::Group.new('mygroup', [a])
209
+ expect(PuppetlabsOnceover::TestConfig.find_list('mygroup')).to eq([a])
210
+ end
211
+
212
+ it "wraps a single class match in an array" do
213
+ cls = PuppetlabsOnceover::Class.new('role::a')
214
+ expect(PuppetlabsOnceover::TestConfig.find_list('role::a')).to eq([cls])
215
+ end
216
+
217
+ it "wraps a single node match in an array" do
218
+ node = PuppetlabsOnceover::Node.new('node_a')
219
+ expect(PuppetlabsOnceover::TestConfig.find_list('node_a')).to eq([node])
220
+ end
221
+
222
+ it "raises when nothing matches, and restores the logger level afterwards" do
223
+ logger.level = :info
224
+ expect do
225
+ PuppetlabsOnceover::TestConfig.find_list('totally_unknown_thing')
226
+ end.to raise_error(RuntimeError, /Could not find totally_unknown_thing/)
227
+ expect(logger.level).to eq(1) # :info
228
+ end
229
+ end
230
+
231
+ describe ".subtractive_to_list" do
232
+ before(:each) { function_mocking_repo }
233
+
234
+ it "subtracts the exclude list's members from the include list's members" do
235
+ a = PuppetlabsOnceover::Node.new('node_a')
236
+ b = PuppetlabsOnceover::Node.new('node_b')
237
+ PuppetlabsOnceover::Group.new('all', [a, b])
238
+ PuppetlabsOnceover::Group.new('excluded', [b])
239
+
240
+ result = PuppetlabsOnceover::TestConfig.subtractive_to_list('include' => 'all', 'exclude' => 'excluded')
241
+ expect(result).to eq([a])
242
+ end
243
+
244
+ it "raises when 'exclude' is missing" do
245
+ expect do
246
+ PuppetlabsOnceover::TestConfig.subtractive_to_list('include' => 'all')
247
+ end.to raise_error(RuntimeError, /must have an `exclude`/)
248
+ end
249
+
250
+ it "raises when 'include' is missing" do
251
+ expect do
252
+ PuppetlabsOnceover::TestConfig.subtractive_to_list('exclude' => 'all')
253
+ end.to raise_error(RuntimeError, /must have an `exclude`/)
254
+ end
255
+ end
256
+
257
+ describe "#verify_spec_test" do
258
+ let!(:repo) { function_mocking_repo }
259
+ let(:config) { PuppetlabsOnceover::TestConfig.new('spec/fixtures/controlrepos/function_mocking/spec/onceover.yaml') }
260
+
261
+ it "does not raise when a factset exists for every node in the test" do
262
+ test = config.spec_tests.first
263
+ expect { config.verify_spec_test(repo, test) }.not_to raise_error
264
+ end
265
+
266
+ it "raises when a node's factset cannot be found" do
267
+ missing_node = PuppetlabsOnceover::Node.new('totally_missing_node')
268
+ fake_test = double('test', nodes: [missing_node])
269
+ expect { config.verify_spec_test(repo, fake_test) }.to raise_error(RuntimeError, /Could not find factset/)
270
+ end
271
+ end
272
+
273
+ describe "#verify_acceptance_test" do
274
+ let!(:repo) { puppet_controlrepo }
275
+ let(:config) { PuppetlabsOnceover::TestConfig.new('spec/fixtures/controlrepos/puppet_controlrepo/spec/onceover.yaml') }
276
+
277
+ it "warns about deprecation, and does not raise when the node is in the nodeset" do
278
+ config # force TestConfig#initialize to run first, populating Node.all
279
+ node = PuppetlabsOnceover::Node.find('CentOS-7.0-64')
280
+ test = double('test', nodes: [node])
281
+ expect { config.verify_acceptance_test(repo, test) }.to output(/DEPRECATION/).to_stderr
282
+ end
283
+
284
+ it "raises when the node is not present in the nodeset file" do
285
+ config
286
+ missing_node = PuppetlabsOnceover::Node.new('totally_missing_node')
287
+ test = double('test', nodes: [missing_node])
288
+ expect { config.verify_acceptance_test(repo, test) }.to raise_error(RuntimeError, /Could not find nodeset/)
289
+ end
290
+ end
291
+
292
+ describe "#pre_condition" do
293
+ it "concatenates every *.pp file under spec/pre_conditions into one string" do
294
+ puppet_controlrepo
295
+ config = PuppetlabsOnceover::TestConfig.new(
296
+ 'spec/fixtures/controlrepos/puppet_controlrepo/spec/onceover.yaml',
297
+ path: 'spec/fixtures/controlrepos/puppet_controlrepo'
298
+ )
299
+ result = config.pre_condition
300
+ expect(result).to be_a(String)
301
+ expect(result).to include('puppet_enterprise')
302
+ end
303
+
304
+ it "returns nil when there are no pre_condition files" do
305
+ function_mocking_repo
306
+ config = PuppetlabsOnceover::TestConfig.new(
307
+ 'spec/fixtures/controlrepos/function_mocking/spec/onceover.yaml',
308
+ path: 'spec/fixtures/controlrepos/function_mocking'
309
+ )
310
+ expect(config.pre_condition).to be_nil
311
+ end
312
+ end
313
+
314
+ describe "writer methods" do
315
+ let!(:repo) { puppet_controlrepo }
316
+ let(:config) do
317
+ PuppetlabsOnceover::TestConfig.new(
318
+ 'spec/fixtures/controlrepos/puppet_controlrepo/spec/onceover.yaml',
319
+ path: repo.root
320
+ )
321
+ end
322
+ let(:location) { Dir.mktmpdir('onceover-testconfig-writer-spec') }
323
+
324
+ it "#write_spec_test renders a spec file for a test" do
325
+ test = config.spec_tests.first
326
+ config.write_spec_test(location, test)
327
+ expect(File.exist?("#{location}/#{test}_spec.rb")).to eq(true)
328
+ end
329
+
330
+ it "#write_acceptance_tests warns about deprecation and renders acceptance_spec.rb" do
331
+ expect { config.write_acceptance_tests(location, config.spec_tests) }.to output(/DEPRECATION/).to_stderr
332
+ expect(File.exist?("#{location}/acceptance_spec.rb")).to eq(true)
333
+ end
334
+
335
+ it "#write_spec_helper_acceptance renders spec_helper_acceptance.rb" do
336
+ config.write_spec_helper_acceptance(location, repo)
337
+ expect(File.exist?("#{location}/spec_helper_acceptance.rb")).to eq(true)
338
+ end
339
+
340
+ it "#write_rakefile renders a Rakefile" do
341
+ config.write_rakefile(location, 'spec/**/*_spec.rb')
342
+ expect(File.exist?("#{location}/Rakefile")).to eq(true)
343
+ end
344
+
345
+ it "#write_spec_helper renders spec_helper.rb, mutating repo.temp_modulepath as a side effect" do
346
+ config.write_spec_helper(location, repo)
347
+ expect(File.exist?("#{location}/spec_helper.rb")).to eq(true)
348
+ expect(repo.temp_modulepath).to include(repo.tempdir)
349
+ end
350
+ end
351
+
352
+ describe "#copy_spec_files" do
353
+ it "copies every file matching the included_specs glob from repo.spec_dir into repo.tempdir/spec" do
354
+ repo = puppet_controlrepo
355
+ config = PuppetlabsOnceover::TestConfig.new('spec/fixtures/controlrepos/puppet_controlrepo/spec/onceover.yaml')
356
+ # In the real flow write_spec_helper (or similar) creates this dir first; the production
357
+ # copy_spec_files code only mkdir_p's for individual *files*, not for directory entries
358
+ # encountered before any file inside them, so we replicate that ordering here.
359
+ FileUtils.mkdir_p("#{repo.tempdir}/spec")
360
+ config.copy_spec_files(repo)
361
+ expect(File.exist?("#{repo.tempdir}/spec/onceover.yaml")).to eq(true)
362
+ end
363
+
364
+ it "respects a custom include_spec_files glob from the yaml" do
365
+ repo = function_mocking_repo
366
+ yaml_path = write_yaml(
367
+ 'classes' => ['role::test_data_return'],
368
+ 'nodes' => ['CentOS-7.0-64'],
369
+ 'test_matrix' => [{ 'all_nodes' => { 'classes' => 'all_classes', 'tests' => 'spec' } }],
370
+ 'include_spec_files' => 'onceover.yaml'
371
+ )
372
+ config = PuppetlabsOnceover::TestConfig.new(yaml_path, path: 'spec/fixtures/controlrepos/function_mocking',
373
+ tempdir: Dir.mktmpdir('onceover-copy-spec'))
374
+ config.copy_spec_files(repo)
375
+ expect(File.exist?("#{repo.tempdir}/spec/onceover.yaml")).to eq(true)
376
+ end
377
+ end
378
+
379
+ describe "#create_fixtures_symlinks" do
380
+ # NOTE: the File::ALT_SEPARATOR branch inside create_fixtures_symlinks (the
381
+ # Dir.create_junction / `mklink /J` Windows-junction path) can't be exercised
382
+ # here -- File::ALT_SEPARATOR is only ever truthy when Ruby itself is running
383
+ # on Windows, which this suite does not run on. Left uncovered deliberately;
384
+ # the non-Windows FileUtils.ln_s branch below is what we actually cover.
385
+ it "symlinks every module on the temp_modulepath into repo.tempdir/spec/fixtures/modules" do
386
+ repo = puppet_controlrepo
387
+ config = PuppetlabsOnceover::TestConfig.new(
388
+ 'spec/fixtures/controlrepos/puppet_controlrepo/spec/onceover.yaml',
389
+ path: repo.root
390
+ )
391
+ location = "#{repo.tempdir}/spec"
392
+ FileUtils.mkdir_p(location)
393
+ config.write_spec_helper(location, repo)
394
+
395
+ # Normally r10k would have deployed real module content under the tempdir's
396
+ # environmentpath before this step runs; simulate that with a dummy module dir.
397
+ dummy_module_dir = "#{repo.temp_modulepath.split(':').first}/dummymodule"
398
+ FileUtils.mkdir_p(dummy_module_dir)
399
+
400
+ config.create_fixtures_symlinks(repo)
401
+
402
+ links = Dir["#{repo.tempdir}/spec/fixtures/modules/*"]
403
+ expect(links).not_to be_empty
404
+ expect(File.symlink?(links.first)).to eq(true)
405
+ end
406
+ end
407
+
408
+ describe "#run_filters and #filter_test" do
409
+ let!(:repo) { function_mocking_repo }
410
+ let!(:config) { PuppetlabsOnceover::TestConfig.new('spec/fixtures/controlrepos/function_mocking/spec/onceover.yaml') }
411
+
412
+ it "returns every test untouched when no filters are configured" do
413
+ tests = config.spec_tests.dup
414
+ expect(config.run_filters(tests.dup)).to eq(tests)
415
+ end
416
+
417
+ it "keeps only tests whose classes match filter_classes" do
418
+ config.filter_classes = [PuppetlabsOnceover::Class.find('role::test_data_return')]
419
+ config.filter_tags = nil
420
+ config.filter_nodes = nil
421
+ filtered = config.run_filters(config.spec_tests.dup)
422
+ expect(filtered).to all(satisfy { |t| t.classes.include?(config.filter_classes.first) })
423
+ end
424
+
425
+ it "keeps only tests whose nodes match filter_nodes" do
426
+ config.filter_nodes = [PuppetlabsOnceover::Node.find('CentOS-7.0-64')]
427
+ filtered = config.run_filters(config.spec_tests.dup)
428
+ expect(filtered).to all(satisfy { |t| t.nodes.include?(config.filter_nodes.first) })
429
+ end
430
+
431
+ it "keeps only tests whose tags match filter_tags" do
432
+ test_with_tag = PuppetlabsOnceover::Test.new('CentOS-7.0-64', 'role::test_data_return', 'tags' => 'important')
433
+ config.filter_tags = ['important']
434
+ filtered = config.run_filters([test_with_tag])
435
+ expect(filtered).to eq([test_with_tag])
436
+ end
437
+
438
+ it "excludes tests whose tag matches a negated (~) filter" do
439
+ test_with_tag = PuppetlabsOnceover::Test.new('CentOS-7.0-64', 'role::test_data_return', 'tags' => 'skip_me')
440
+ config.filter_tags = ['~skip_me']
441
+ filtered = config.run_filters([test_with_tag])
442
+ expect(filtered).to eq([])
443
+ end
444
+
445
+ it "#filter_test returns false when the test has no value at all for that method" do
446
+ test_without_tags = PuppetlabsOnceover::Test.new('CentOS-7.0-64', 'role::test_data_return', {})
447
+ allow(test_without_tags).to receive(:tags).and_return(nil)
448
+ expect(config.filter_test(test_without_tags, 'tags', 'anything')).to eq(false)
449
+ end
450
+ end
451
+ end