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 +7 -0
- data/LICENSE +21 -0
- data/README.md +71 -0
- data/lib/puppet-lint/plugins/check_array_formatting.rb +133 -0
- data/spec/puppet-lint/plugins/check_array_formatting_spec.rb +1023 -0
- data/spec/spec_helper.rb +11 -0
- metadata +154 -0
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
|