rspec-puppet-utils 2.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- data.tar.gz: a4dd63771ed01e8d6afa8f1e971ee5d34fd5422c
4
- metadata.gz: c6a81e4e44b6d5e1198e5c4d27c4d9bf3d383cec
3
+ data.tar.gz: 1cee9e4a75b93b9b3d2bbdd4d9c18d6f224c5448
4
+ metadata.gz: da8f2e5c38ad50874bfcdba758d6e239922654da
5
5
  SHA512:
6
- data.tar.gz: f0b85634b96353cee343e2238264a90b8a03aca441125c5fe7d08b048f803c8e38fd303e5a678d0641513d1fd64f14151d03b0366b3c4db53f94dbc949f32f27
7
- metadata.gz: 39365b0ebfbfa4af02a41502d0f8bfa268648dee536082f871fe2cd8d7efbe5afa35ae6fc75e483185551d9fee6d644c3de7aa51b3e93b898747b0d65eb4c205
6
+ data.tar.gz: d75f54a18d91e8ca31bf1ed170ec118e35b1253cf9f91ac3dd9e972d4234e91cefcd8a9ec912324d7e92a4683e9d9438a02b28210123caab03e27f3b503a7d71
7
+ metadata.gz: 8135746b0dfe552fd456f5b5eb747a1180f4c8c943d1918ee8b1beb0b46004fd3dcce66fed644a4c78748279f6dfa7069e952956ef4d28c21783c3976f460983
data/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  This is a more refined version of a previous project about [rspec-puppet unit testing](https://github.com/TomPoulton/rspec-puppet-unit-testing), it provides a class for mocking functions, a harness for testing templates, and a simple tool for testing hiera data files. The motivation for mocking functions etc is provided in that project so I won't go over it here.
4
4
 
5
+ See [release notes for v2.0.0](../../wiki/Release-Notes#v200)
6
+
5
7
  ## Usage
6
8
 
7
9
  ### MockFunction
@@ -127,6 +129,15 @@ describe 'YAML hieradata' do
127
129
  }
128
130
  end
129
131
 
132
+ # Supply a list of files that the key must be in
133
+ # (all matches in all other files are still validated)
134
+ # :live and :qa correspond to live.yaml and qa.yaml
135
+ it 'should override password in live and qa' do
136
+ validator.validate('password', [:live, :qa]) { |v|
137
+ expect ...
138
+ }
139
+ end
140
+
130
141
  end
131
142
 
132
143
  end
@@ -3,35 +3,46 @@ module RSpecPuppetUtils
3
3
 
4
4
  class Validator
5
5
 
6
- attr_reader :data
6
+ attr_reader :data, :load_errors
7
7
 
8
- def validate(key, &block)
9
- raise ValidationError, 'No data available, try #load first' if @data.nil? || @data.empty?
10
-
11
- found = false
8
+ def validate(key, required_files = [], &block)
9
+ pre_checks(required_files)
10
+ @found = false
12
11
  @data.keys.each do |file|
13
- keys = get_matching_keys(key, file)
14
- keys.each do |matched_key|
15
- found = true
16
- begin
17
- block.call(@data[file][matched_key])
18
- rescue Exception => e
19
- raise ValidationError, "#{matched_key} is invalid in #{file}: #{e.message}"
20
- end
21
- end
12
+ validate_file file, key, required_files, &block
22
13
  end
23
- raise ValidationError, "No match for #{key.inspect} was not found in any files" unless found
14
+ raise ValidationError, "No match for #{key.inspect} was not found in any files" unless @found
15
+ raise ValidationError, "No match for #{key.inspect} was not found in: #{required_files.join ', '}" unless required_files.empty?
24
16
  end
25
17
 
26
18
  private
27
19
 
20
+ def pre_checks(required_files)
21
+ raise ValidationError, "Errors occurred during data load:\n#{@load_errors.join "\n"}\n" unless @load_errors.empty?
22
+ raise StandardError, 'No data available, try #load first' if @data.nil? || @data.empty?
23
+ raise ArgumentError, 'required files should be an Array' unless required_files.is_a?(Array)
24
+ end
25
+
26
+ def validate_file(file, key, required_files, &block)
27
+ keys = get_matching_keys key, file
28
+ keys.each do |matched_key|
29
+ @found = true
30
+ begin
31
+ required_files.delete file
32
+ block.call @data[file][matched_key]
33
+ rescue StandardError => e
34
+ raise ValidationError, "#{matched_key} is invalid in #{file}: #{e.message}"
35
+ end
36
+ end
37
+ end
38
+
28
39
  def get_matching_keys(key, file)
29
40
  if key.is_a?(String) || key.is_a?(Symbol)
30
41
  keys = @data[file].has_key?(key) ? [key] : []
31
42
  elsif key.is_a?(Regexp)
32
43
  keys = @data[file].keys.select { |k| k.to_s =~ key }
33
44
  else
34
- raise ValidationError, 'Search key must be a String, Symbol or a Regexp'
45
+ raise ArgumentError, 'Search key must be a String, Symbol or a Regexp'
35
46
  end
36
47
  keys
37
48
  end
@@ -12,31 +12,43 @@ module RSpecPuppetUtils
12
12
  @extensions = extensions.map {|ext| ext =~ /\..*/ ? ext : ".#{ext}" }
13
13
  end
14
14
 
15
- def load(ignore_empty = false)
16
-
17
- files = Dir.glob(File.join(@directory, '**', '*')).reject { |path|
18
- File.directory?(path) || !@extensions.include?(File.extname path )
19
- }
20
-
15
+ def load_data(*args)
16
+ @load_errors = []
21
17
  @data = {}
22
- files.each { |file|
18
+ files = find_yaml_files
19
+ files.each { |file| load_data_for_file file, args.include?(:ignore_empty) }
20
+ self
21
+ end
23
22
 
24
- # Assume all file names are unique i.e. thing.yaml and thing.yml don't both exist
25
- file_name = File.basename(file).split('.').first
23
+ # Deprecated - delete soon!
24
+ def load(ignore_empty = false)
25
+ warn '#load is deprecated, use #load_data instead'
26
+ ignore_empty ? load_data(:ignore_empty) : load_data
27
+ raise ValidationError, @load_errors[0] unless @load_errors.empty?
28
+ end
26
29
 
27
- begin
28
- yaml = File.open(file) { |yf|
29
- YAML::load( yf )
30
- }
31
- rescue ArgumentError => e
32
- raise StandardError, "Yaml Syntax error in file #{file}: #{e.message}"
33
- end
34
- raise StandardError, "Yaml file is empty: #{file}" unless yaml || ignore_empty
30
+ private
31
+
32
+ def load_data_for_file(file, ignore_empty)
33
+ # Assume all file names are unique i.e. thing.yaml and thing.yml don't both exist
34
+ file_name = File.basename(file).split('.').first
35
+ begin
36
+ yaml = File.open(file) { |yf| YAML::load( yf ) }
37
+ rescue ArgumentError => e
38
+ @load_errors.push "Error in file #{file}: #{e.message}"
39
+ return
40
+ end
41
+ @load_errors.push "Yaml file is empty: #{file}" unless yaml || ignore_empty
42
+ @data[file_name.to_sym] = yaml if yaml
43
+ end
35
44
 
36
- @data[file_name.to_sym] = yaml if yaml
45
+ def find_yaml_files
46
+ Dir.glob(File.join(@directory, '**', '*')).reject { |path|
47
+ File.directory?(path) || !@extensions.include?(File.extname path )
37
48
  }
38
-
39
49
  end
50
+
40
51
  end
52
+
41
53
  end
42
54
  end
@@ -1,7 +1,7 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  Gem::Specification.new do |gem|
3
3
  gem.name = 'rspec-puppet-utils'
4
- gem.version = '2.0.0'
4
+ gem.version = '2.0.1'
5
5
  gem.description = 'Helper classes for mock/stub functions, templates and hierdata'
6
6
  gem.summary = ''
7
7
  gem.author = 'Tom Poulton'
@@ -4,7 +4,10 @@ require 'lib/hieradata/validator'
4
4
  include RSpecPuppetUtils
5
5
 
6
6
  module HieraData
7
- class Test < Validator
7
+ class TestValidator < Validator
8
+ def initialize
9
+ @load_errors = []
10
+ end
8
11
  def load
9
12
  @data = {
10
13
  :file1 => {
@@ -17,18 +20,24 @@ module HieraData
17
20
  'hello' => 'world',
18
21
  'missmatch' => ['array'],
19
22
  'hat' => 'fedora',
23
+ },
24
+ :file3 => {
25
+ 'squid' => 'giant',
20
26
  }
21
27
  }
22
28
  end
23
29
  def load_empty
24
30
  @data = {}
25
31
  end
32
+ def set_load_errors(errors)
33
+ @load_errors = errors
34
+ end
26
35
  end
27
36
  end
28
37
 
29
38
  describe HieraData::Validator do
30
39
 
31
- validator = HieraData::Test.new
40
+ validator = HieraData::TestValidator.new
32
41
  validator.load
33
42
 
34
43
  it 'should have public data variable' do
@@ -92,24 +101,67 @@ describe HieraData::Validator do
92
101
 
93
102
  end
94
103
 
104
+ context 'with required files' do
105
+
106
+ it 'should raise error if required files in not an Array' do
107
+ expect {
108
+ validator.validate('cat', nil) { }
109
+ }.to raise_error ArgumentError, 'required files should be an Array'
110
+ end
111
+
112
+ it 'should raise error when key is not found in required file' do
113
+ expect {
114
+ validator.validate('cat', [:file2]) { }
115
+ }.to raise_error HieraData::ValidationError
116
+ end
117
+
118
+ it 'should report which files are missing the key' do
119
+ expect {
120
+ validator.validate('cat', [:file2, :file3]) { }
121
+ }.to raise_error HieraData::ValidationError, 'No match for "cat" was not found in: file2, file3'
122
+ end
123
+
124
+ it 'should report broader error if key is not in any files' do
125
+ expect {
126
+ validator.validate('dog', [:file1]) { }
127
+ }.to raise_error HieraData::ValidationError, 'No match for "dog" was not found in any files'
128
+ end
129
+
130
+ end
131
+
132
+ it 'should raise error if key is not a valid type' do
133
+ expect {
134
+ validator.validate(['key']) { }
135
+ }.to raise_error ArgumentError, 'Search key must be a String, Symbol or a Regexp'
136
+ end
137
+
138
+ it 'should raise error if there were load errors' do
139
+ load_error_validator = HieraData::TestValidator.new
140
+ load_error_validator.load_empty
141
+ load_error_validator.set_load_errors ['file1 is empty', 'file2 has syntax errors']
142
+ expect {
143
+ load_error_validator.validate('') { }
144
+ }.to raise_error HieraData::ValidationError, /file1 is empty\nfile2 has syntax errors/
145
+ end
146
+
95
147
  it 'should raise error if data is nil' do
96
- nil_validator = HieraData::Test.new
148
+ nil_validator = HieraData::TestValidator.new
97
149
  expect {
98
150
  nil_validator.validate('meh') { }
99
- }.to raise_error HieraData::ValidationError, /No data available/
151
+ }.to raise_error StandardError, /No data available/
100
152
  end
101
153
 
102
154
  it 'should raise error if data is empty' do
103
- empty_validator = HieraData::Test.new
155
+ empty_validator = HieraData::TestValidator.new
104
156
  empty_validator.load_empty
105
157
  expect {
106
158
  empty_validator.validate('meh') { }
107
- }.to raise_error HieraData::ValidationError, /No data available/
159
+ }.to raise_error StandardError, /No data available/
108
160
  end
109
161
 
110
162
  end
111
163
 
112
- describe HieraData::Validator do
164
+ describe HieraData::ValidationError do
113
165
 
114
166
  it 'should inherit from StandardError' do
115
167
  expect(HieraData::ValidationError.ancestors).to include StandardError
@@ -1,3 +1,4 @@
1
+ require 'spec_helper'
1
2
  require 'lib/hieradata/yaml_validator'
2
3
 
3
4
  include RSpecPuppetUtils
@@ -9,69 +10,130 @@ describe HieraData::YamlValidator do
9
10
  expect(validator).to be_a_kind_of HieraData::Validator
10
11
  end
11
12
 
12
- context 'with valid yaml' do
13
+ describe '#load_data' do
13
14
 
14
- validator = HieraData::YamlValidator.new('spec/fixtures/hieradata/valid')
15
- validator.load
15
+ context 'with valid yaml' do
16
+
17
+ validator = HieraData::YamlValidator.new('spec/fixtures/hieradata/valid')
18
+ validator.load_data
19
+
20
+ it 'should load yaml files into data' do
21
+ expect(validator.data.keys.size).to_not be 0
22
+ end
23
+
24
+ it 'should load yaml files recursively' do
25
+ expect(validator.data.keys).to include :nested
26
+ end
27
+
28
+ it 'should load yaml data from files' do
29
+ expect(validator.data[:valid]['string-value']).to eq 'a string'
30
+ end
31
+
32
+ it 'should not add any load errors' do
33
+ expect(validator.load_errors).to be_an Array
34
+ expect(validator.load_errors).to be_empty
35
+ end
16
36
 
17
- it 'should load yaml files into data' do
18
- expect(validator.data.keys.size).to_not be 0
19
37
  end
20
38
 
21
- it 'should load yaml files recursively' do
22
- expect(validator.data.keys).to include :nested
39
+ context 'with multiple extensions' do
40
+
41
+ validator = HieraData::YamlValidator.new('spec/fixtures/hieradata/valid', ['yaml', 'foo'])
42
+ validator.load_data
43
+
44
+ it 'should load yml files into data' do
45
+ expect(validator.data).to have_key :other
46
+ end
47
+
23
48
  end
24
49
 
25
- it 'should load yaml data from files' do
26
- expect(validator.data[:valid]['string-value']).to eq 'a string'
50
+ context 'with extensions as string' do
51
+
52
+ it 'should load yml files into data' do
53
+ expect { HieraData::YamlValidator.new('meh', 'whooops') }.to raise_error ArgumentError, /extensions should be an Array/
54
+ end
55
+
27
56
  end
28
57
 
29
- end
58
+ context 'with invalid yaml' do
59
+
60
+ validator = HieraData::YamlValidator.new('spec/fixtures/hieradata/invalid')
30
61
 
31
- context 'with multiple extensions' do
62
+ it 'should not raise error' do
63
+ expect {
64
+ validator.load_data
65
+ }.to_not raise_error
66
+ end
32
67
 
33
- validator = HieraData::YamlValidator.new('spec/fixtures/hieradata/valid', ['yaml', 'foo'])
34
- validator.load
68
+ it 'should add error to load_errors' do
69
+ expect(validator.load_errors).to be_an Array
70
+ expect(validator.load_errors.size).to eq 1
71
+ expect(validator.load_errors[0]).to match /Error in file .*\/invalid.yaml/
72
+ end
35
73
 
36
- it 'should load yml files into data' do
37
- expect(validator.data).to have_key :other
38
74
  end
39
75
 
40
- end
76
+ context 'with empty yaml' do
41
77
 
42
- context 'with extensions as string' do
78
+ subject(:validator) { HieraData::YamlValidator.new('spec/fixtures/hieradata/empty') }
43
79
 
44
- it 'should load yml files into data' do
45
- expect { HieraData::YamlValidator.new('meh', 'whooops') }.to raise_error ArgumentError, /extensions should be an Array/
46
- end
80
+ it 'should not raise error by default' do
81
+ expect {
82
+ validator.load_data
83
+ }.to_not raise_error # /Yaml file is empty: .*\/empty.yaml/
84
+ end
47
85
 
48
- end
86
+ it 'should add error to load_errors' do
87
+ validator.load_data
88
+ expect(validator.load_errors).to be_an Array
89
+ expect(validator.load_errors.size).to eq 1
90
+ expect(validator.load_errors[0]).to match /Yaml file is empty: .*\/empty.yaml/
91
+ end
92
+
93
+ it 'should ignore empty files when flag is set' do
94
+ expect { validator.load_data :ignore_empty }.to_not raise_error
95
+ end
49
96
 
50
- context 'with invalid yaml' do
97
+ it 'should not add empty files to @data' do
98
+ validator.load_data :ignore_empty
99
+ expect(validator.data.keys).to_not include :empty
100
+ end
51
101
 
52
- validator = HieraData::YamlValidator.new('spec/fixtures/hieradata/invalid')
102
+ it 'should add non empty files to data' do
103
+ validator.load_data :ignore_empty
104
+ expect(validator.data.keys).to include :not_empty
105
+ end
53
106
 
54
- it 'should raise error with syntax error' do
55
- expect { validator.load }.to raise_error StandardError, /Yaml Syntax error in file .*\/invalid.yaml/
56
107
  end
57
108
 
58
- end
109
+ it 'should return validator instance' do
110
+ validator = HieraData::YamlValidator.new('spec/fixtures/hieradata/valid')
111
+ expect(validator.load_data).to eq validator
112
+ end
59
113
 
60
- context 'with empty yaml' do
114
+ end
61
115
 
62
- validator = HieraData::YamlValidator.new('spec/fixtures/hieradata/empty')
116
+ describe '#load' do
63
117
 
64
- it 'should raise error' do
65
- expect { validator.load }.to raise_error StandardError, /Yaml file is empty: .*\/empty.yaml/
118
+ subject(:validator) { HieraData::YamlValidator.new('spec/fixtures/hieradata/empty') }
119
+ before(:each) do
120
+ validator.stubs(:warn) # Hide warn message from output
66
121
  end
67
122
 
68
- it 'should ignore empty files when flag is set' do
123
+ it 'should support old #load method' do
69
124
  expect { validator.load true }.to_not raise_error
125
+ expect(validator.data.keys).to include :not_empty
126
+ end
127
+
128
+ it 'should still throw errors if necessary' do
129
+ expect {
130
+ validator.load
131
+ }.to raise_error HieraData::ValidationError
70
132
  end
71
133
 
72
- it 'should not add empty files to @data' do
134
+ it 'should warn when using old #load method' do
135
+ validator.expects(:warn).with('#load is deprecated, use #load_data instead').once
73
136
  validator.load true
74
- expect(validator.data.keys).to_not include :empty
75
137
  end
76
138
 
77
139
  end
@@ -0,0 +1,2 @@
1
+ ---
2
+ 'key' : 'value'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-puppet-utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Poulton
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2014-03-19 00:00:00 Z
12
+ date: 2014-03-24 00:00:00 Z
13
13
  dependencies: []
14
14
 
15
15
  description: Helper classes for mock/stub functions, templates and hierdata
@@ -37,6 +37,7 @@ files:
37
37
  - spec/classes/template_harness_spec.rb
38
38
  - spec/classes/utils_spec.rb
39
39
  - spec/fixtures/hieradata/empty/empty.yaml
40
+ - spec/fixtures/hieradata/empty/not_empty.yaml
40
41
  - spec/fixtures/hieradata/invalid/invalid.yaml
41
42
  - spec/fixtures/hieradata/valid/other.foo
42
43
  - spec/fixtures/hieradata/valid/sub/nested.yaml
@@ -76,6 +77,7 @@ test_files:
76
77
  - spec/classes/template_harness_spec.rb
77
78
  - spec/classes/utils_spec.rb
78
79
  - spec/fixtures/hieradata/empty/empty.yaml
80
+ - spec/fixtures/hieradata/empty/not_empty.yaml
79
81
  - spec/fixtures/hieradata/invalid/invalid.yaml
80
82
  - spec/fixtures/hieradata/valid/other.foo
81
83
  - spec/fixtures/hieradata/valid/sub/nested.yaml