puppet-lint-array_formatting-check 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c130a6b549e23b5a62141163214c8dc669e2ec4cf4e2969773a853bf490d60e7
4
+ data.tar.gz: d4233449808f9190aa3683639a99586ad89417280c370c256262d8af40a3e8aa
5
+ SHA512:
6
+ metadata.gz: fee2c7bccde0fcf12cd2e1187556cc5ba2531ce7063f266da5fc309de07e01236f5d9e696991d3af19e824b54b2b7892a9e4c44b8f9a21f0b7379a086c876805
7
+ data.tar.gz: 6e198fc7fa4705566971abe7a486af1653cf43e3c85ffb0794c61e003528655358a444b64f727cbf5cf7da67a6bbf46571b4524d3b4aa1d7794406d1e7d41f70
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 Adam Manzer
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,71 @@
1
+ # puppet-lint array formatting check
2
+
3
+ A new check for puppet-lint that ensures array formatting conforms to the [Puppet Style Guide](https://puppet.com/docs/puppet/6.0/style_guide.html#arrays-and-hashes) on arrays; namely that each element should be on a separate line.
4
+
5
+ It will take an array formatted as
6
+
7
+ ```puppet
8
+ $packages = [ 'vim', 'sl', 'bind-utils', ]
9
+ ```
10
+
11
+ and ensure that it's formatted as
12
+
13
+ ```puppet
14
+ $packages = [
15
+ 'vim',
16
+ 'sl',
17
+ 'bind-utils',
18
+ ]
19
+ ```
20
+
21
+ In the name of readability, it'll ignore arrays with one element.
22
+
23
+ ```puppet
24
+ $my_short_package_list = [ 'emacs', ]
25
+ ```
26
+
27
+ ## Installation
28
+
29
+ To use this plugin, add the following line to your Gemfile
30
+
31
+ ```ruby
32
+ gem 'puppet-lint-array_formatting-check'
33
+ ```
34
+
35
+ and then run `bundle install`.
36
+
37
+ You can also install it at a user level using
38
+
39
+ ```bash
40
+ gem install --user-install puppet-lint-array_formatting-check
41
+ ```
42
+
43
+ or at a system level using
44
+
45
+ ```bash
46
+ sudo gem install puppet-lint-array_formatting-check
47
+ ```
48
+
49
+ ## Usage
50
+
51
+ This plugin provides a new check to `puppet-lint`.
52
+
53
+ ### array-formatting
54
+
55
+ **--fix support: Yes**
56
+
57
+ This check will raise warnings for every element in an array that should be on its own line
58
+
59
+ ```
60
+ WARNING: expected newline before element
61
+ ```
62
+
63
+ It will also flag instances of extra newlines in arrays
64
+
65
+ ```
66
+ WARNING: unexpected newline
67
+ ```
68
+
69
+ ### Author
70
+
71
+ [Adam Manzer](https://gitlab.com/amanzer)
@@ -0,0 +1,133 @@
1
+ PuppetLint.new_check(:array_formatting) do
2
+ def process_array
3
+ # When we arrive here, the @manifest enumerator is "pointing" to
4
+ # the opening LBRACK. Start by iterating that to point to the
5
+ # first element of the array:
6
+ token = @manifest.next
7
+ manifest_array = []
8
+ len_of_nested_array = 0
9
+
10
+ # Scan through the manifest until we encounter a RBRACK to close this array
11
+ until [:RBRACK].include?(token.type) || token.nil?
12
+ # If we encounter an LBRACK, we need to get our recursion on
13
+ if [:LBRACK].include?(token.type)
14
+ # Push the opening of the array as a placeholder unless the last token was a classref.
15
+ # If it was, it was already pushed, so skip pushing.
16
+ # We want to treat a classref and an array opening as a single token.
17
+ manifest_array.push token unless %i[CLASSREF TYPE].include?(token.prev_code_token.type)
18
+ # Recursively process this nested array.
19
+ # Store return so we know if the child array was processed or not.
20
+ len_of_nested_array = process_array
21
+ # If we encounter something _other_ than COMMA, WHITESPACE, or INDENT, push it.
22
+ # These don't include NEWLINE(s), which is what we need to keep track of.
23
+ elsif !%i[COMMA WHITESPACE INDENT].include?(token.type)
24
+ manifest_array.push token
25
+ end
26
+ # Advance. (We're still looking for that RBRACK)
27
+ token = @manifest.next
28
+ end
29
+
30
+ # We've found the RBRACK, and built a copy of the array in the Puppet manifest in the
31
+ # local variable manifest_array. Before we start validating, let's try to return early.
32
+ #
33
+ # Check the number of objects (tokens + newlines) we found, including child arrays.
34
+ # If it's one or less, we can leave and return that we're *not* formatting
35
+ return manifest_array.length if (manifest_array.length < 2) && (len_of_nested_array < 2)
36
+
37
+ # Array is 2 or more elements. Time to validate it.
38
+ #
39
+ # First element of the array should be a NEWLINE.
40
+ prev_token_was_newline = false
41
+
42
+ # Start iterating our rebuilt array
43
+ manifest_array.each_index do |x|
44
+ if !prev_token_was_newline && [:NEWLINE].include?(manifest_array[x].type)
45
+ # We were expecting a newline, so yay
46
+ prev_token_was_newline = true
47
+ elsif prev_token_was_newline && ![:NEWLINE].include?(manifest_array[x].type)
48
+ # We were expecting something other than a newline, so yay
49
+ prev_token_was_newline = false
50
+ elsif !prev_token_was_newline && ![:NEWLINE].include?(manifest_array[x].type)
51
+ # We were expecting a newline. :-(
52
+ notify :warning,
53
+ message: 'expected newline before element',
54
+ line: manifest_array[x].line,
55
+ column: manifest_array[x].column,
56
+ token: manifest_array[x]
57
+ # prev_token_was_newline is already false, so this isn't required
58
+ # prev_token_was_newline = false
59
+ elsif prev_token_was_newline && [:NEWLINE].include?(manifest_array[x].type)
60
+ # We got an extra newline. Let's fix that up while we're at it.
61
+ notify :warning,
62
+ message: 'unexpected newline',
63
+ line: manifest_array[x].line,
64
+ column: manifest_array[x].column,
65
+ token: manifest_array[x]
66
+ # prev_token_was_newline is already true, so this isn't required
67
+ # prev_token_was_newline = true
68
+ else
69
+ # Something has gone horribly wrong. The truth table says we should never be here.
70
+ notify :error,
71
+ message: 'parsing error',
72
+ line: manifest_array[x].line,
73
+ column: manifest_array[x].column
74
+ end
75
+ # Next manifest_array item
76
+ end
77
+
78
+ # All elements of the array are done.
79
+ # If the last token (not including the RBRACK) wasn't a newline, throw a warning.
80
+ # Since we previously used token to scan forward to the ],
81
+ # token is already pointing to the offending ].
82
+ if !prev_token_was_newline # rubocop:disable NegatedIf "I find this clearer than `unless prev_token_was_newline`"
83
+ notify :warning,
84
+ message: 'expected newline before close',
85
+ line: token.line,
86
+ column: token.column,
87
+ token: token
88
+ end
89
+
90
+ # Return the length of the array so we can make assumptions about
91
+ # whether we're formatting or not
92
+ manifest_array.length
93
+ end
94
+
95
+ def check
96
+ # Create an instance-scope enumerator to walk through the Puppet manifest
97
+ @manifest = tokens.each
98
+ loop do
99
+ token = @manifest.next
100
+ next unless [:LBRACK].include?(token.type)
101
+
102
+ # Found an array! Send if off for processing unless it's actually a Classref.
103
+ # We can disregard the return, becuase this is a top level array, and has no 'parent' to affect
104
+ process_array unless %i[CLASSREF TYPE].include?(token.prev_code_token.type)
105
+ end
106
+ end
107
+
108
+ def fix(problem)
109
+ token_index = tokens.find_index(problem[:token])
110
+ case problem[:message]
111
+ when 'parsing error'
112
+ # Truth table says we should never get here
113
+ raise PuppetLint::NoFix
114
+ when 'unexpected newline'
115
+ # If we delete the INDENT first, we change the index of the offending token,
116
+ # so we need to do the token first, then the INDENT
117
+ tokens.delete_at(token_index)
118
+ # If the previous token is an Indent, we'll want to delete that too
119
+ tokens.delete_at(token_index - 1) if [:INDENT].include?(problem[:token].prev_token.type)
120
+ when 'expected newline before element', 'expected newline before close'
121
+ # If the preceeding token is a whitespace, replace it with a newline instead
122
+ # so that we don't end up with trailing whitespaces
123
+ if %i[WHITESPACE INDENT].include?(problem[:token].prev_token.type)
124
+ problem[:token].prev_token.type = :NEWLINE
125
+ else
126
+ # Create a new Puppet Token object and insert it into the Puppet manifest in the correct location.
127
+ # The location specified in Token.new() apparently doesn't matter since we're manually inserting it
128
+ # into the Tokens array at the proper position using token_index.
129
+ tokens.insert(token_index, PuppetLint::Lexer::Token.new(:NEWLINE, '\n', 0, 0))
130
+ end
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,1023 @@
1
+ # Rubocop has a problem with some of my examples.
2
+ # Since they're Puppet code, inside a ruby file,
3
+ # I'm going to blame different syntaxes.
4
+ # rubocop:disable TrailingCommaInArguments
5
+ require 'spec_helper'
6
+
7
+ describe 'array_formatting' do
8
+ let(:msg) { 'expected newline before element' }
9
+ let(:msg_end) { 'expected newline before close' }
10
+ let(:msg_newline) { 'unexpected newline' }
11
+
12
+ context 'with fix disabled' do
13
+ context 'on code with an empty array' do
14
+ let(:code) { '$services = []' }
15
+
16
+ it 'should detect no problem' do
17
+ expect(problems).to have(0).problems
18
+ end
19
+ end
20
+ context 'on code with a single-item array' do
21
+ let(:code) { "$my_string = [ 'a' ]" }
22
+
23
+ it 'should detect no problem' do
24
+ expect(problems).to have(0).problems
25
+ end
26
+ end
27
+ context 'on code with a single-item array with a comma' do
28
+ let(:code) { "$my_string = [ 'a', ]" }
29
+
30
+ it 'should detect no problem' do
31
+ expect(problems).to have(0).problems
32
+ end
33
+ end
34
+ context 'on code with a triple-nested array of weirdness' do
35
+ let(:code) { '$my_array = [[[ 1 ]]]' }
36
+
37
+ it 'should detect no problem' do
38
+ expect(problems).to have(0).problems
39
+ end
40
+ end
41
+ context 'on code with a properly formatted array of numbers' do
42
+ let(:code) do
43
+ # Removes the 10 indentation spaces by replacing them with nothing
44
+ # Thanks to Marius Rieder in check_strict_indent_spec
45
+ <<-ARRAY.gsub(/^ {10}/, '')
46
+ $my_numbers = [
47
+ 1,
48
+ 2,
49
+ 3,
50
+ ]
51
+ ARRAY
52
+ end
53
+
54
+ it 'should not detect any problems' do
55
+ expect(problems).to have(0).problems
56
+ end
57
+ end
58
+ context 'on code with a spaced single-line array' do
59
+ let(:code) { "$my_strings = [ 'a', \"b\", 'c', 4, ]" }
60
+
61
+ it 'should detect 5 problems' do
62
+ expect(problems).to have(5).problems
63
+ end
64
+
65
+ it 'should create a warning' do
66
+ # There should be a warning message, matching the
67
+ # message above, flagged after the opening '['
68
+ expect(problems).to contain_warning(msg).on_line(1).in_column(17)
69
+ expect(problems).to contain_warning(msg).on_line(1).in_column(22)
70
+ expect(problems).to contain_warning(msg).on_line(1).in_column(27)
71
+ expect(problems).to contain_warning(msg).on_line(1).in_column(32)
72
+ expect(problems).to contain_warning(msg_end).on_line(1).in_column(35)
73
+ end
74
+ end
75
+ context 'on code with an unspaced single-line array' do
76
+ let(:code) { "$my_strings = ['a','b','c',4]" }
77
+
78
+ it 'should detect 5 problems' do
79
+ expect(problems).to have(5).problems
80
+ end
81
+
82
+ it 'should create a warning' do
83
+ # There should be a warning message, matching the
84
+ # message above, flagged after the opening '['
85
+ expect(problems).to contain_warning(msg).on_line(1).in_column(16)
86
+ expect(problems).to contain_warning(msg).on_line(1).in_column(20)
87
+ expect(problems).to contain_warning(msg).on_line(1).in_column(24)
88
+ expect(problems).to contain_warning(msg).on_line(1).in_column(28)
89
+ expect(problems).to contain_warning(msg_end).on_line(1).in_column(29)
90
+ end
91
+ end
92
+ context 'on code with an inconsistently separated array' do
93
+ let(:code) do
94
+ <<-ARRAY.gsub(/^ {10}/, '')
95
+ file{[
96
+ '/etc', '/etc/app',
97
+ '/opt', '/opt/app',
98
+ ]:
99
+ ensure => directory,
100
+ }
101
+ ARRAY
102
+ end
103
+
104
+ it 'should detect 2 problems' do
105
+ expect(problems).to have(2).problems
106
+ end
107
+
108
+ it 'should create warnings' do
109
+ expect(problems).to contain_warning(msg).on_line(2).in_column(11)
110
+ expect(problems).to contain_warning(msg).on_line(3).in_column(11)
111
+ end
112
+ end
113
+ context 'on code with an array with extra newlines' do
114
+ let(:code) do
115
+ # rubocop:disable TrailingWhitespace
116
+ <<-ARRAY.gsub(/^ {10}/, '')
117
+ file{[
118
+ '/etc',
119
+
120
+ '/etc/app',
121
+ '/opt',
122
+
123
+ '/opt/app',
124
+ ]:
125
+ ensure => directory,
126
+ }
127
+ ARRAY
128
+ # rubocop:enable TrailingWhitespace
129
+ end
130
+
131
+ it 'should detect 2 problems' do
132
+ expect(problems).to have(2).problems
133
+ end
134
+
135
+ it 'should create warnings' do
136
+ expect(problems).to contain_warning(msg_newline).on_line(3).in_column(3)
137
+ expect(problems).to contain_warning(msg_newline).on_line(6).in_column(3)
138
+ end
139
+ end
140
+ context 'on code with a single child array of two elements' do
141
+ let(:code) { '$my_array = [[ 1, 2 ]]' }
142
+
143
+ it 'should detect 5 problems' do
144
+ expect(problems).to have(5).problems
145
+ end
146
+
147
+ it 'should create warnings' do
148
+ expect(problems).to contain_warning(msg).on_line(1).in_column(14)
149
+ expect(problems).to contain_warning(msg).on_line(1).in_column(16)
150
+ expect(problems).to contain_warning(msg).on_line(1).in_column(19)
151
+ expect(problems).to contain_warning(msg_end).on_line(1).in_column(21)
152
+ expect(problems).to contain_warning(msg_end).on_line(1).in_column(22)
153
+ end
154
+ end
155
+ context 'on code with a two array-element array' do
156
+ let(:code) { "$my_array = [ [1], ['a',] ]" }
157
+
158
+ it 'should detect 3 problems' do
159
+ expect(problems).to have(3).problems
160
+ end
161
+
162
+ it 'should create warnings' do
163
+ expect(problems).to contain_warning(msg).on_line(1).in_column(15)
164
+ expect(problems).to contain_warning(msg).on_line(1).in_column(20)
165
+ expect(problems).to contain_warning(msg_end).on_line(1).in_column(27)
166
+ end
167
+ end
168
+ context 'on code with an array with a two-element array nested second' do
169
+ let(:code) { "$my_array = [ [1], ['a', 'b'] ]" }
170
+
171
+ it 'should detect 6 problems' do
172
+ expect(problems).to have(6).problems
173
+ end
174
+
175
+ it 'should create warnings' do
176
+ expect(problems).to contain_warning(msg).on_line(1).in_column(15)
177
+ expect(problems).to contain_warning(msg).on_line(1).in_column(20)
178
+ expect(problems).to contain_warning(msg).on_line(1).in_column(21)
179
+ expect(problems).to contain_warning(msg).on_line(1).in_column(26)
180
+ expect(problems).to contain_warning(msg_end).on_line(1).in_column(29)
181
+ expect(problems).to contain_warning(msg_end).on_line(1).in_column(31)
182
+ end
183
+ end
184
+ context 'on code with an array with a two-element array nested first' do
185
+ let(:code) { "$my_array = [ [1,2], ['a',] ]" }
186
+
187
+ it 'should detect 6 problems' do
188
+ expect(problems).to have(6).problems
189
+ end
190
+
191
+ it 'should create warnings' do
192
+ expect(problems).to contain_warning(msg).on_line(1).in_column(15)
193
+ expect(problems).to contain_warning(msg).on_line(1).in_column(16)
194
+ expect(problems).to contain_warning(msg).on_line(1).in_column(18)
195
+ expect(problems).to contain_warning(msg_end).on_line(1).in_column(19)
196
+ expect(problems).to contain_warning(msg).on_line(1).in_column(22)
197
+ expect(problems).to contain_warning(msg_end).on_line(1).in_column(29)
198
+ end
199
+ end
200
+ context 'on code with a single-value classref' do
201
+ let(:code) { "subscribe => File['/etc/fstab']" }
202
+
203
+ it 'should detect no problems' do
204
+ expect(problems).to have(0).problems
205
+ end
206
+ end
207
+ context 'on code with a single-value classref in an array' do
208
+ let(:code) { "subscribe => [File['/etc/fstab'],]" }
209
+
210
+ it 'should detect no problems' do
211
+ expect(problems).to have(0).problems
212
+ end
213
+ end
214
+ context 'on code with a multi-classref array' do
215
+ let(:code) { "subscribe => [File['/etc/fstab'], Service['sshd'],]" }
216
+
217
+ it 'should detect three problems' do
218
+ expect(problems).to have(3).problems
219
+ end
220
+
221
+ it 'should create warnings' do
222
+ expect(problems).to contain_warning(msg).on_line(1).in_column(15)
223
+ expect(problems).to contain_warning(msg).on_line(1).in_column(35)
224
+ expect(problems).to contain_warning(msg_end).on_line(1).in_column(51)
225
+ end
226
+ end
227
+ context 'on code with a nested classref array' do
228
+ let(:code) { "subscribe => [ File['/etc/fstab','/etc/auto.master',] ]," }
229
+
230
+ it 'should detect 5 problems' do
231
+ expect(problems).to have(5).problems
232
+ end
233
+
234
+ it 'should create warnings' do
235
+ expect(problems).to contain_warning(msg).on_line(1).in_column(16)
236
+ expect(problems).to contain_warning(msg).on_line(1).in_column(21)
237
+ expect(problems).to contain_warning(msg).on_line(1).in_column(34)
238
+ expect(problems).to contain_warning(msg_end).on_line(1).in_column(53)
239
+ expect(problems).to contain_warning(msg_end).on_line(1).in_column(55)
240
+ end
241
+ end
242
+ context 'on code with an array of multiple classrefs' do
243
+ let(:code) { "subscribe => [File['/etc/fstab','/etc/auto.master'], Service['sshd'],]" }
244
+
245
+ it 'should detect six problems' do
246
+ expect(problems).to have(6).problems
247
+ end
248
+
249
+ it 'should create warnings' do
250
+ expect(problems).to contain_warning(msg).on_line(1).in_column(15)
251
+ expect(problems).to contain_warning(msg).on_line(1).in_column(20)
252
+ expect(problems).to contain_warning(msg).on_line(1).in_column(33)
253
+ expect(problems).to contain_warning(msg_end).on_line(1).in_column(51)
254
+ expect(problems).to contain_warning(msg).on_line(1).in_column(54)
255
+ expect(problems).to contain_warning(msg_end).on_line(1).in_column(70)
256
+ end
257
+ end
258
+ context 'on code with an array of 2 two-value classrefs' do
259
+ let(:code) { "subscribe => [File['/etc/fstab','/etc/auto.master'], Service['sshd',$ntp::service],]" }
260
+
261
+ it 'should detect six problems' do
262
+ expect(problems).to have(9).problems
263
+ end
264
+
265
+ it 'should create warnings' do
266
+ expect(problems).to contain_warning(msg).on_line(1).in_column(15)
267
+ expect(problems).to contain_warning(msg).on_line(1).in_column(20)
268
+ expect(problems).to contain_warning(msg).on_line(1).in_column(33)
269
+ expect(problems).to contain_warning(msg_end).on_line(1).in_column(51)
270
+ expect(problems).to contain_warning(msg).on_line(1).in_column(54)
271
+ expect(problems).to contain_warning(msg).on_line(1).in_column(62)
272
+ expect(problems).to contain_warning(msg).on_line(1).in_column(69)
273
+ expect(problems).to contain_warning(msg_end).on_line(1).in_column(82)
274
+ expect(problems).to contain_warning(msg_end).on_line(1).in_column(84)
275
+ end
276
+ end
277
+ context 'on code with an Enum' do
278
+ let(:code) { 'Enum[3.3, 5] $voltage' }
279
+
280
+ it 'should detect no problem' do
281
+ expect(problems).to have(0).problems
282
+ end
283
+ end
284
+ context 'on code with six different arrays' do
285
+ let(:code) do
286
+ <<-CODE.gsub(/^ {10}/, '')
287
+ $file_list1 = ['/etc/file1', '/etc/file2']
288
+ $file_list2 = ['/etc/file3',]
289
+ $file_list3 = ['/etc/file4', '/etc/file5',]
290
+ file{[ $file_list1,
291
+ $file_list2, $file_list3,
292
+ ]:
293
+ ensure => directory,
294
+ subscribe => [File[$file_list1, $file_list2]]
295
+ notify => [File[$file_list2, $file_list3]]
296
+ }
297
+ CODE
298
+ end
299
+
300
+ it 'should detect 18 problems' do
301
+ expect(problems).to have(18).problems
302
+ end
303
+
304
+ it 'should create warnings' do
305
+ expect(problems).to contain_warning(msg).on_line(1).in_column(16)
306
+ expect(problems).to contain_warning(msg).on_line(1).in_column(30)
307
+ expect(problems).to contain_warning(msg_end).on_line(1).in_column(42)
308
+ expect(problems).to contain_warning(msg).on_line(3).in_column(16)
309
+ expect(problems).to contain_warning(msg).on_line(3).in_column(30)
310
+ expect(problems).to contain_warning(msg_end).on_line(3).in_column(43)
311
+ expect(problems).to contain_warning(msg).on_line(4).in_column(8)
312
+ expect(problems).to contain_warning(msg).on_line(5).in_column(16)
313
+ expect(problems).to contain_warning(msg).on_line(8).in_column(17)
314
+ expect(problems).to contain_warning(msg).on_line(8).in_column(22)
315
+ expect(problems).to contain_warning(msg).on_line(8).in_column(35)
316
+ expect(problems).to contain_warning(msg_end).on_line(8).in_column(46)
317
+ expect(problems).to contain_warning(msg_end).on_line(8).in_column(47)
318
+ expect(problems).to contain_warning(msg).on_line(9).in_column(17)
319
+ expect(problems).to contain_warning(msg).on_line(9).in_column(22)
320
+ expect(problems).to contain_warning(msg).on_line(9).in_column(35)
321
+ expect(problems).to contain_warning(msg_end).on_line(9).in_column(46)
322
+ expect(problems).to contain_warning(msg_end).on_line(9).in_column(47)
323
+ end
324
+ end
325
+ context 'on a complete code example with no issues' do
326
+ let(:code) do
327
+ <<-CODE.gsub(/^ {10}/, '')
328
+ class testing(
329
+ Enum['present', 'absent'] $package_ensure,
330
+ Array[String] $keys,
331
+ Boolean $keys_enable,
332
+ Optional[Integer[0]] $panic,
333
+ Optional[Array[String]] $pool,
334
+ Variant[Boolean, Integer[0,1]] $tos_cohort,
335
+ ) {
336
+ if $facts['is_virtual'] {
337
+ $_tinker = pick($tinker, true)
338
+ } else {
339
+ $tinker = pick($tinker, false)
340
+ }
341
+ Class['::ntp::install']
342
+ -> Class['::ntp::config']
343
+ ~> Class['::ntp::service']
344
+ }
345
+ CODE
346
+ end
347
+
348
+ it 'should detect no problem' do
349
+ expect(problems).to have(0).problems
350
+ end
351
+ end
352
+ context 'on a complete code example with one bad array' do
353
+ let(:code) do
354
+ <<-CODE.gsub(/^ {10}/, '')
355
+ class testing(
356
+ Enum['present', 'absent'] $package_ensure,
357
+ Array[String] $keys,
358
+ Boolean $keys_enable,
359
+ Optional[Integer[0]] $panic,
360
+ Optional[Array[String]] $pool,
361
+ Variant[Boolean, Integer[0,1]] $tos_cohort,
362
+ ) {
363
+ if $facts['is_virtual'] {
364
+ $_tinker = pick($tinker, true)
365
+ } else {
366
+ $tinker = pick($tinker, false)
367
+ }
368
+ $keys_parameters = [$keys, $keys_enable]
369
+ Class['::ntp::install']
370
+ -> Class['::ntp::config']
371
+ ~> Class['::ntp::service']
372
+ }
373
+ CODE
374
+ end
375
+
376
+ it 'should detect 3 problems' do
377
+ expect(problems).to have(3).problems
378
+ end
379
+
380
+ it 'should create warnings' do
381
+ expect(problems).to contain_warning(msg).on_line(14).in_column(23)
382
+ expect(problems).to contain_warning(msg).on_line(14).in_column(30)
383
+ expect(problems).to contain_warning(msg_end).on_line(14).in_column(42)
384
+ end
385
+ end
386
+ end
387
+ context 'with fix enabled' do
388
+ before do
389
+ PuppetLint.configuration.fix = true
390
+ end
391
+
392
+ after do
393
+ PuppetLint.configuration.fix = false
394
+ end
395
+ context 'on code with an empty array' do
396
+ let(:code) { '$services = []' }
397
+
398
+ it 'should detect no problem' do
399
+ expect(problems).to have(0).problems
400
+ end
401
+
402
+ it 'should not modify the manifest' do
403
+ expect(manifest).to eq(code)
404
+ end
405
+ end
406
+ context 'on code with a single-item array' do
407
+ let(:code) { "$my_string = [ 'a' ]" }
408
+
409
+ it 'should detect no problem' do
410
+ expect(problems).to have(0).problems
411
+ end
412
+
413
+ it 'should not modify the manifest' do
414
+ expect(manifest).to eq(code)
415
+ end
416
+ end
417
+ context 'on code with a single-item array with a comma' do
418
+ let(:code) { "$my_string = [ 'a', ]" }
419
+
420
+ it 'should detect no problem' do
421
+ expect(problems).to have(0).problems
422
+ end
423
+
424
+ it 'should not modify the manifest' do
425
+ expect(manifest).to eq(code)
426
+ end
427
+ end
428
+ context 'on code with a triple-nested array of weirdness' do
429
+ let(:code) { '$my_array = [[[ 1 ]]]' }
430
+
431
+ it 'should detect no problem' do
432
+ expect(problems).to have(0).problems
433
+ end
434
+
435
+ it 'should not modify the manifest' do
436
+ expect(manifest).to eq(code)
437
+ end
438
+ end
439
+ context 'on code with a properly formatted array of numbers' do
440
+ let(:code) do
441
+ # Removes the 10 indentation spaces by replacing them with nothing
442
+ # Thanks to Marius Rieder in check_strict_indent_spec
443
+ <<-ARRAY.gsub(/^ {10}/, '')
444
+ $my_numbers = [
445
+ 1,
446
+ 2,
447
+ 3,
448
+ ]
449
+ ARRAY
450
+ end
451
+
452
+ it 'should not detect any problems' do
453
+ expect(problems).to have(0).problems
454
+ end
455
+
456
+ it 'should not modify the manifest' do
457
+ expect(manifest).to eq(code)
458
+ end
459
+ end
460
+ context 'on code with a spaced single-line array' do
461
+ let(:code) { "$my_strings = [ 'a', \"b\", 'c', 4, ]" }
462
+
463
+ it 'should detect 5 problems' do
464
+ expect(problems).to have(5).problems
465
+ end
466
+
467
+ it 'should generate fixes' do
468
+ # There should be a warning message, matching the
469
+ # message above, flagged after the opening '['
470
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(17)
471
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(22)
472
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(27)
473
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(32)
474
+ expect(problems).to contain_fixed(msg_end).on_line(1).in_column(35)
475
+ end
476
+
477
+ it 'should properly format the array' do
478
+ expect(manifest).to eq("$my_strings = [\n'a',\n\"b\",\n'c',\n4,\n]")
479
+ end
480
+ end
481
+ context 'on code with an unspaced single-line array' do
482
+ let(:code) { "$my_strings = ['a','b','c',4]" }
483
+
484
+ it 'should detect 5 problems' do
485
+ expect(problems).to have(5).problems
486
+ end
487
+
488
+ it 'should generate fixes' do
489
+ # There should be a warning message, matching the
490
+ # message above, flagged after the opening '['
491
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(16)
492
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(20)
493
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(24)
494
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(28)
495
+ expect(problems).to contain_fixed(msg_end).on_line(1).in_column(29)
496
+ end
497
+
498
+ it 'should properly format the array' do
499
+ expect(manifest).to eq("$my_strings = [\n'a',\n'b',\n'c',\n4\n]")
500
+ end
501
+ end
502
+ context 'on code with an inconsistently separated array' do
503
+ let(:code) do
504
+ <<-ARRAY.gsub(/^ {10}/, '')
505
+ file{[
506
+ '/etc', '/etc/app',
507
+ '/opt', '/opt/app',
508
+ ]:
509
+ ensure => directory,
510
+ }
511
+ ARRAY
512
+ end
513
+
514
+ it 'should detect 2 problems' do
515
+ expect(problems).to have(2).problems
516
+ end
517
+
518
+ it 'should create fixes ' do
519
+ expect(problems).to contain_fixed(msg).on_line(2).in_column(11)
520
+ expect(problems).to contain_fixed(msg).on_line(3).in_column(11)
521
+ end
522
+
523
+ it 'should properly format the array' do
524
+ expect(manifest).to eq(
525
+ # This is the expected code. This plugin doesn't do indentation, so it's expected
526
+ # that the moved lines will be "bad" indentation. Hopefully the indentation fixer
527
+ # can run after this plugin.
528
+ <<-ARRAY.gsub(/^ {12}/, '')
529
+ file{[
530
+ '/etc',
531
+ '/etc/app',
532
+ '/opt',
533
+ '/opt/app',
534
+ ]:
535
+ ensure => directory,
536
+ }
537
+ ARRAY
538
+ )
539
+ end
540
+ end
541
+ context 'on code with an array with extra newlines' do
542
+ let(:code) do
543
+ # rubocop:disable TrailingWhitespace
544
+ <<-ARRAY.gsub(/^ {10}/, '')
545
+ file{[
546
+ '/etc',
547
+
548
+ '/etc/app',
549
+ '/opt',
550
+
551
+ '/opt/app',
552
+ ]:
553
+ ensure => directory,
554
+ }
555
+ ARRAY
556
+ # rubocop:enable TrailingWhitespace
557
+ end
558
+
559
+ it 'should detect 2 problems' do
560
+ expect(problems).to have(2).problems
561
+ end
562
+
563
+ it 'should create fixes' do
564
+ expect(problems).to contain_fixed(msg_newline).on_line(3).in_column(3)
565
+ expect(problems).to contain_fixed(msg_newline).on_line(6).in_column(3)
566
+ end
567
+
568
+ it 'should properly format the array' do
569
+ expect(manifest).to eq(
570
+ <<-ARRAY.gsub(/^ {12}/, '')
571
+ file{[
572
+ '/etc',
573
+ '/etc/app',
574
+ '/opt',
575
+ '/opt/app',
576
+ ]:
577
+ ensure => directory,
578
+ }
579
+ ARRAY
580
+ )
581
+ end
582
+ end
583
+ context 'on code with a single child array of two elements' do
584
+ let(:code) { '$my_array = [[ 1, 2 ]]' }
585
+
586
+ it 'should detect 5 problems' do
587
+ expect(problems).to have(5).problems
588
+ end
589
+
590
+ it 'should create fixes' do
591
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(14)
592
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(16)
593
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(19)
594
+ expect(problems).to contain_fixed(msg_end).on_line(1).in_column(21)
595
+ expect(problems).to contain_fixed(msg_end).on_line(1).in_column(22)
596
+ end
597
+
598
+ it 'should properly format the array' do
599
+ expect(manifest).to eq(
600
+ # Again, this plugin doesn't indent
601
+ <<-ARRAY.chomp.gsub(/^ {12}/, '')
602
+ $my_array = [
603
+ [
604
+ 1,
605
+ 2
606
+ ]
607
+ ]
608
+ ARRAY
609
+ )
610
+ end
611
+ end
612
+ context 'on code with a two array-element array' do
613
+ let(:code) { "$my_array = [ [1], ['a',] ]" }
614
+
615
+ it 'should detect 3 problems' do
616
+ expect(problems).to have(3).problems
617
+ end
618
+
619
+ it 'should create fixes' do
620
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(15)
621
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(20)
622
+ expect(problems).to contain_fixed(msg_end).on_line(1).in_column(27)
623
+ end
624
+
625
+ it 'should properly format the array' do
626
+ expect(manifest).to eq(
627
+ # Again, this plugin doesn't indent
628
+ <<-ARRAY.chomp.gsub(/^ {12}/, '')
629
+ $my_array = [
630
+ [1],
631
+ ['a',]
632
+ ]
633
+ ARRAY
634
+ )
635
+ end
636
+ end
637
+ context 'on code with an array with a two-element array nested second' do
638
+ let(:code) { "$my_array = [ [1], ['a', 'b'] ]" }
639
+
640
+ it 'should detect 6 problems' do
641
+ expect(problems).to have(6).problems
642
+ end
643
+
644
+ it 'should create fixes' do
645
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(15)
646
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(20)
647
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(21)
648
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(26)
649
+ expect(problems).to contain_fixed(msg_end).on_line(1).in_column(29)
650
+ expect(problems).to contain_fixed(msg_end).on_line(1).in_column(31)
651
+ end
652
+
653
+ it 'should properly format the array' do
654
+ expect(manifest).to eq(
655
+ # Again, this plugin doesn't indent
656
+ <<-ARRAY.chomp.gsub(/^ {12}/, '')
657
+ $my_array = [
658
+ [1],
659
+ [
660
+ 'a',
661
+ 'b'
662
+ ]
663
+ ]
664
+ ARRAY
665
+ )
666
+ end
667
+ end
668
+ context 'on code with an array with a two-element array nested first' do
669
+ let(:code) { "$my_array = [ [1,2], ['a',] ]" }
670
+
671
+ it 'should detect 6 problems' do
672
+ expect(problems).to have(6).problems
673
+ end
674
+
675
+ it 'should create fixes' do
676
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(15)
677
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(16)
678
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(18)
679
+ expect(problems).to contain_fixed(msg_end).on_line(1).in_column(19)
680
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(22)
681
+ expect(problems).to contain_fixed(msg_end).on_line(1).in_column(29)
682
+ end
683
+
684
+ it 'should properly format the array' do
685
+ expect(manifest).to eq(
686
+ # Again, this plugin doesn't indent
687
+ <<-ARRAY.chomp.gsub(/^ {12}/, '')
688
+ $my_array = [
689
+ [
690
+ 1,
691
+ 2
692
+ ],
693
+ ['a',]
694
+ ]
695
+ ARRAY
696
+ )
697
+ end
698
+ end
699
+ context 'on code with a single-value classref' do
700
+ let(:code) { "subscribe => File['/etc/fstab']" }
701
+
702
+ it 'should detect no problems' do
703
+ expect(problems).to have(0).problems
704
+ end
705
+
706
+ it 'should not modify the manifest' do
707
+ expect(manifest).to eq(code)
708
+ end
709
+ end
710
+ context 'on code with a single-value classref in an array' do
711
+ let(:code) { "subscribe => [File['/etc/fstab'],]" }
712
+
713
+ it 'should detect no problems' do
714
+ expect(problems).to have(0).problems
715
+ end
716
+
717
+ it 'should not modify the manifest' do
718
+ expect(manifest).to eq(code)
719
+ end
720
+ end
721
+ context 'on code with a multi-classref array' do
722
+ let(:code) { "subscribe => [File['/etc/fstab'], Service['sshd'],]" }
723
+
724
+ it 'should detect three problems' do
725
+ expect(problems).to have(3).problems
726
+ end
727
+
728
+ it 'should create fixes' do
729
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(15)
730
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(35)
731
+ expect(problems).to contain_fixed(msg_end).on_line(1).in_column(51)
732
+ end
733
+
734
+ it 'should properly format the array' do
735
+ expect(manifest).to eq(
736
+ <<-ARRAY.chomp.gsub(/^ {12}/, '')
737
+ subscribe => [
738
+ File['/etc/fstab'],
739
+ Service['sshd'],
740
+ ]
741
+ ARRAY
742
+ )
743
+ end
744
+ end
745
+ context 'on code with a nested classref array' do
746
+ let(:code) { "subscribe => [ File['/etc/fstab','/etc/auto.master',] ]," }
747
+
748
+ it 'should detect 5 problems' do
749
+ expect(problems).to have(5).problems
750
+ end
751
+
752
+ it 'should create fixes' do
753
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(16)
754
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(21)
755
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(34)
756
+ expect(problems).to contain_fixed(msg_end).on_line(1).in_column(53)
757
+ expect(problems).to contain_fixed(msg_end).on_line(1).in_column(55)
758
+ end
759
+
760
+ it 'should properly format the array' do
761
+ expect(manifest).to eq(
762
+ <<-ARRAY.chomp.gsub(/^ {12}/, '')
763
+ subscribe => [
764
+ File[
765
+ '/etc/fstab',
766
+ '/etc/auto.master',
767
+ ]
768
+ ],
769
+ ARRAY
770
+ )
771
+ end
772
+ end
773
+ context 'on code with an array of multiple classrefs' do
774
+ let(:code) { "subscribe => [File['/etc/fstab','/etc/auto.master'], Service['sshd'],]" }
775
+
776
+ it 'should detect six problems' do
777
+ expect(problems).to have(6).problems
778
+ end
779
+
780
+ it 'should create fixes' do
781
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(15)
782
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(20)
783
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(33)
784
+ expect(problems).to contain_fixed(msg_end).on_line(1).in_column(51)
785
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(54)
786
+ expect(problems).to contain_fixed(msg_end).on_line(1).in_column(70)
787
+ end
788
+
789
+ it 'should properly format the array' do
790
+ expect(manifest).to eq(
791
+ <<-ARRAY.chomp.gsub(/^ {12}/, '')
792
+ subscribe => [
793
+ File[
794
+ '/etc/fstab',
795
+ '/etc/auto.master'
796
+ ],
797
+ Service['sshd'],
798
+ ]
799
+ ARRAY
800
+ )
801
+ end
802
+ end
803
+ context 'on code with an array of 2 two-value classrefs' do
804
+ let(:code) { "subscribe => [File['/etc/fstab','/etc/auto.master'], Service['sshd',$ntp::service],]" }
805
+
806
+ it 'should detect six problems' do
807
+ expect(problems).to have(9).problems
808
+ end
809
+
810
+ it 'should create fixes' do
811
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(15)
812
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(20)
813
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(33)
814
+ expect(problems).to contain_fixed(msg_end).on_line(1).in_column(51)
815
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(54)
816
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(62)
817
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(69)
818
+ expect(problems).to contain_fixed(msg_end).on_line(1).in_column(82)
819
+ expect(problems).to contain_fixed(msg_end).on_line(1).in_column(84)
820
+ end
821
+
822
+ it 'should properly format the array' do
823
+ expect(manifest).to eq(
824
+ <<-ARRAY.chomp.gsub(/^ {12}/, '')
825
+ subscribe => [
826
+ File[
827
+ '/etc/fstab',
828
+ '/etc/auto.master'
829
+ ],
830
+ Service[
831
+ 'sshd',
832
+ $ntp::service
833
+ ],
834
+ ]
835
+ ARRAY
836
+ )
837
+ end
838
+ end
839
+ context 'on code fragment with an Enum' do
840
+ let(:code) { 'Enum[3.3, 5] $voltage' }
841
+
842
+ it 'should detect no problem' do
843
+ expect(problems).to have(0).problems
844
+ end
845
+
846
+ it 'should not modify the manifest' do
847
+ expect(manifest).to eq(code)
848
+ end
849
+ end
850
+ context 'on code with six different arrays' do
851
+ let(:code) do
852
+ <<-CODE.gsub(/^ {10}/, '')
853
+ $file_list1 = ['/etc/file1', '/etc/file2']
854
+ $file_list2 = ['/etc/file3',]
855
+ $file_list3 = ['/etc/file4', '/etc/file5',]
856
+ file{[ $file_list1,
857
+ $file_list2, $file_list3,
858
+ ]:
859
+ ensure => directory,
860
+ subscribe => [File[$file_list1, $file_list2]]
861
+ notify => [File[$file_list2, $file_list3]]
862
+ }
863
+ CODE
864
+ end
865
+
866
+ it 'should detect 18 problems' do
867
+ expect(problems).to have(18).problems
868
+ end
869
+
870
+ it 'should create fixes' do
871
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(16)
872
+ expect(problems).to contain_fixed(msg).on_line(1).in_column(30)
873
+ expect(problems).to contain_fixed(msg_end).on_line(1).in_column(42)
874
+ expect(problems).to contain_fixed(msg).on_line(3).in_column(16)
875
+ expect(problems).to contain_fixed(msg).on_line(3).in_column(30)
876
+ expect(problems).to contain_fixed(msg_end).on_line(3).in_column(43)
877
+ expect(problems).to contain_fixed(msg).on_line(4).in_column(8)
878
+ expect(problems).to contain_fixed(msg).on_line(5).in_column(16)
879
+ expect(problems).to contain_fixed(msg).on_line(8).in_column(17)
880
+ expect(problems).to contain_fixed(msg).on_line(8).in_column(22)
881
+ expect(problems).to contain_fixed(msg).on_line(8).in_column(35)
882
+ expect(problems).to contain_fixed(msg_end).on_line(8).in_column(46)
883
+ expect(problems).to contain_fixed(msg_end).on_line(8).in_column(47)
884
+ expect(problems).to contain_fixed(msg).on_line(9).in_column(17)
885
+ expect(problems).to contain_fixed(msg).on_line(9).in_column(22)
886
+ expect(problems).to contain_fixed(msg).on_line(9).in_column(35)
887
+ expect(problems).to contain_fixed(msg_end).on_line(9).in_column(46)
888
+ expect(problems).to contain_fixed(msg_end).on_line(9).in_column(47)
889
+ end
890
+
891
+ it 'should properly format the code' do
892
+ # Don't forget this plugin doesn't do indentation, and the $file_list2 use below was
893
+ # already properly indented in the original code
894
+ expect(manifest).to eq(
895
+ <<-CODE.gsub(/^ {12}/, '')
896
+ $file_list1 = [
897
+ '/etc/file1',
898
+ '/etc/file2'
899
+ ]
900
+ $file_list2 = ['/etc/file3',]
901
+ $file_list3 = [
902
+ '/etc/file4',
903
+ '/etc/file5',
904
+ ]
905
+ file{[
906
+ $file_list1,
907
+ $file_list2,
908
+ $file_list3,
909
+ ]:
910
+ ensure => directory,
911
+ subscribe => [
912
+ File[
913
+ $file_list1,
914
+ $file_list2
915
+ ]
916
+ ]
917
+ notify => [
918
+ File[
919
+ $file_list2,
920
+ $file_list3
921
+ ]
922
+ ]
923
+ }
924
+ CODE
925
+ )
926
+ end
927
+ end
928
+ context 'on a complete code example with no issues' do
929
+ let(:code) do
930
+ <<-CODE.gsub(/^ {10}/, '')
931
+ class testing(
932
+ Enum['present', 'absent'] $package_ensure,
933
+ Array[String] $keys,
934
+ Boolean $keys_enable,
935
+ Optional[Integer[0]] $panic,
936
+ Optional[Array[String]] $pool,
937
+ Variant[Boolean, Integer[0,1]] $tos_cohort,
938
+ ) {
939
+ if $facts['is_virtual'] {
940
+ $_tinker = pick($tinker, true)
941
+ } else {
942
+ $tinker = pick($tinker, false)
943
+ }
944
+ Class['::ntp::install']
945
+ -> Class['::ntp::config']
946
+ ~> Class['::ntp::service']
947
+ }
948
+ CODE
949
+ end
950
+
951
+ it 'should detect no problem' do
952
+ expect(problems).to have(0).problems
953
+ end
954
+
955
+ it 'should not modify the manifest' do
956
+ expect(manifest).to eq(code)
957
+ end
958
+ end
959
+ context 'on a complete code example with one bad array' do
960
+ let(:code) do
961
+ <<-CODE.gsub(/^ {10}/, '')
962
+ class testing(
963
+ Enum['present', 'absent'] $package_ensure,
964
+ Array[String] $keys,
965
+ Boolean $keys_enable,
966
+ Optional[Integer[0]] $panic,
967
+ Optional[Array[String]] $pool,
968
+ Variant[Boolean, Integer[0,1]] $tos_cohort,
969
+ ) {
970
+ if $facts['is_virtual'] {
971
+ $_tinker = pick($tinker, true)
972
+ } else {
973
+ $tinker = pick($tinker, false)
974
+ }
975
+ $keys_parameters = [$keys, $keys_enable]
976
+ Class['::ntp::install']
977
+ -> Class['::ntp::config']
978
+ ~> Class['::ntp::service']
979
+ }
980
+ CODE
981
+ end
982
+
983
+ it 'should detect 3 problems' do
984
+ expect(problems).to have(3).problems
985
+ end
986
+
987
+ it 'should create fixes' do
988
+ expect(problems).to contain_fixed(msg).on_line(14).in_column(23)
989
+ expect(problems).to contain_fixed(msg).on_line(14).in_column(30)
990
+ expect(problems).to contain_fixed(msg_end).on_line(14).in_column(42)
991
+ end
992
+
993
+ it 'should properly format the manifest' do
994
+ expect(manifest).to eq(
995
+ <<-CODE.gsub(/^ {12}/, '')
996
+ class testing(
997
+ Enum['present', 'absent'] $package_ensure,
998
+ Array[String] $keys,
999
+ Boolean $keys_enable,
1000
+ Optional[Integer[0]] $panic,
1001
+ Optional[Array[String]] $pool,
1002
+ Variant[Boolean, Integer[0,1]] $tos_cohort,
1003
+ ) {
1004
+ if $facts['is_virtual'] {
1005
+ $_tinker = pick($tinker, true)
1006
+ } else {
1007
+ $tinker = pick($tinker, false)
1008
+ }
1009
+ $keys_parameters = [
1010
+ $keys,
1011
+ $keys_enable
1012
+ ]
1013
+ Class['::ntp::install']
1014
+ -> Class['::ntp::config']
1015
+ ~> Class['::ntp::service']
1016
+ }
1017
+ CODE
1018
+ )
1019
+ end
1020
+ end
1021
+ end
1022
+ end
1023
+ # rubocop:enable TrailingCommaInArguments