puppet-lint-array_formatting-check 0.9.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 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