puppet-lint 2.3.0 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +74 -0
  3. data/.rubocop_todo.yml +89 -0
  4. data/.travis.yml +11 -9
  5. data/CHANGELOG.md +54 -0
  6. data/Gemfile +3 -0
  7. data/Rakefile +14 -3
  8. data/appveyor.yml +1 -4
  9. data/bin/puppet-lint +1 -1
  10. data/lib/puppet-lint.rb +25 -21
  11. data/lib/puppet-lint/bin.rb +15 -19
  12. data/lib/puppet-lint/checkplugin.rb +24 -17
  13. data/lib/puppet-lint/checks.rb +42 -31
  14. data/lib/puppet-lint/configuration.rb +11 -8
  15. data/lib/puppet-lint/data.rb +236 -164
  16. data/lib/puppet-lint/lexer.rb +225 -203
  17. data/lib/puppet-lint/lexer/token.rb +34 -18
  18. data/lib/puppet-lint/optparser.rb +33 -30
  19. data/lib/puppet-lint/plugins.rb +42 -38
  20. data/lib/puppet-lint/plugins/check_classes/arrow_on_right_operand_line.rb +26 -28
  21. data/lib/puppet-lint/plugins/check_classes/autoloader_layout.rb +21 -20
  22. data/lib/puppet-lint/plugins/check_classes/class_inherits_from_params_class.rb +8 -9
  23. data/lib/puppet-lint/plugins/check_classes/code_on_top_scope.rb +9 -8
  24. data/lib/puppet-lint/plugins/check_classes/inherits_across_namespaces.rb +12 -11
  25. data/lib/puppet-lint/plugins/check_classes/names_containing_dash.rb +13 -12
  26. data/lib/puppet-lint/plugins/check_classes/names_containing_uppercase.rb +14 -13
  27. data/lib/puppet-lint/plugins/check_classes/nested_classes_or_defines.rb +9 -10
  28. data/lib/puppet-lint/plugins/check_classes/parameter_order.rb +40 -31
  29. data/lib/puppet-lint/plugins/check_classes/right_to_left_relationship.rb +3 -2
  30. data/lib/puppet-lint/plugins/check_classes/variable_scope.rb +21 -24
  31. data/lib/puppet-lint/plugins/check_comments/slash_comments.rb +3 -2
  32. data/lib/puppet-lint/plugins/check_comments/star_comments.rb +6 -5
  33. data/lib/puppet-lint/plugins/check_conditionals/case_without_default.rb +21 -20
  34. data/lib/puppet-lint/plugins/check_conditionals/selector_inside_resource.rb +10 -13
  35. data/lib/puppet-lint/plugins/check_documentation/documentation.rb +26 -17
  36. data/lib/puppet-lint/plugins/check_nodes/unquoted_node_name.rb +11 -11
  37. data/lib/puppet-lint/plugins/check_resources/duplicate_params.rb +4 -3
  38. data/lib/puppet-lint/plugins/check_resources/ensure_first_param.rb +17 -18
  39. data/lib/puppet-lint/plugins/check_resources/ensure_not_symlink_target.rb +17 -16
  40. data/lib/puppet-lint/plugins/check_resources/file_mode.rb +22 -23
  41. data/lib/puppet-lint/plugins/check_resources/unquoted_file_mode.rb +14 -13
  42. data/lib/puppet-lint/plugins/check_resources/unquoted_resource_title.rb +9 -8
  43. data/lib/puppet-lint/plugins/check_strings/double_quoted_strings.rb +8 -8
  44. data/lib/puppet-lint/plugins/check_strings/only_variable_string.rb +29 -42
  45. data/lib/puppet-lint/plugins/check_strings/puppet_url_without_modules.rb +5 -4
  46. data/lib/puppet-lint/plugins/check_strings/quoted_booleans.rb +3 -2
  47. data/lib/puppet-lint/plugins/check_strings/single_quote_string_with_variables.rb +4 -3
  48. data/lib/puppet-lint/plugins/check_strings/variables_not_enclosed.rb +3 -2
  49. data/lib/puppet-lint/plugins/check_variables/variable_contains_dash.rb +9 -8
  50. data/lib/puppet-lint/plugins/check_variables/variable_is_lowercase.rb +9 -8
  51. data/lib/puppet-lint/plugins/check_whitespace/140chars.rb +9 -9
  52. data/lib/puppet-lint/plugins/check_whitespace/2sp_soft_tabs.rb +4 -3
  53. data/lib/puppet-lint/plugins/check_whitespace/80chars.rb +10 -10
  54. data/lib/puppet-lint/plugins/check_whitespace/arrow_alignment.rb +23 -22
  55. data/lib/puppet-lint/plugins/check_whitespace/hard_tabs.rb +3 -2
  56. data/lib/puppet-lint/plugins/check_whitespace/trailing_whitespace.rb +3 -2
  57. data/lib/puppet-lint/tasks/puppet-lint.rb +3 -3
  58. data/lib/puppet-lint/version.rb +1 -1
  59. data/puppet-lint.gemspec +4 -4
  60. data/spec/puppet-lint/bin_spec.rb +268 -140
  61. data/spec/puppet-lint/checks_spec.rb +229 -0
  62. data/spec/puppet-lint/configuration_spec.rb +10 -9
  63. data/spec/puppet-lint/data_spec.rb +84 -0
  64. data/spec/puppet-lint/ignore_overrides_spec.rb +71 -40
  65. data/spec/puppet-lint/lexer/token_spec.rb +1 -1
  66. data/spec/puppet-lint/lexer_spec.rb +306 -73
  67. data/spec/puppet-lint/plugins/check_classes/arrow_on_right_operand_line_spec.rb +12 -6
  68. data/spec/puppet-lint/plugins/check_classes/autoloader_layout_spec.rb +10 -10
  69. data/spec/puppet-lint/plugins/check_classes/class_inherits_from_params_class_spec.rb +15 -11
  70. data/spec/puppet-lint/plugins/check_classes/code_on_top_scope_spec.rb +26 -21
  71. data/spec/puppet-lint/plugins/check_classes/inherits_across_namespaces_spec.rb +3 -3
  72. data/spec/puppet-lint/plugins/check_classes/name_contains_uppercase_spec.rb +4 -5
  73. data/spec/puppet-lint/plugins/check_classes/names_containing_dash_spec.rb +13 -0
  74. data/spec/puppet-lint/plugins/check_classes/nested_classes_or_defines_spec.rb +33 -25
  75. data/spec/puppet-lint/plugins/check_classes/parameter_order_spec.rb +80 -55
  76. data/spec/puppet-lint/plugins/check_classes/right_to_left_relationship_spec.rb +2 -2
  77. data/spec/puppet-lint/plugins/check_classes/variable_scope_spec.rb +165 -130
  78. data/spec/puppet-lint/plugins/check_comments/slash_comments_spec.rb +2 -2
  79. data/spec/puppet-lint/plugins/check_comments/star_comments_spec.rb +53 -35
  80. data/spec/puppet-lint/plugins/check_conditionals/case_without_default_spec.rb +59 -49
  81. data/spec/puppet-lint/plugins/check_conditionals/selector_inside_resource_spec.rb +18 -14
  82. data/spec/puppet-lint/plugins/check_documentation/documentation_spec.rb +14 -10
  83. data/spec/puppet-lint/plugins/check_nodes/unquoted_node_name_spec.rb +7 -7
  84. data/spec/puppet-lint/plugins/check_resources/duplicate_params_spec.rb +54 -44
  85. data/spec/puppet-lint/plugins/check_resources/ensure_first_param_spec.rb +114 -89
  86. data/spec/puppet-lint/plugins/check_resources/ensure_not_symlink_target_spec.rb +41 -30
  87. data/spec/puppet-lint/plugins/check_resources/file_mode_spec.rb +46 -40
  88. data/spec/puppet-lint/plugins/check_resources/unquoted_file_mode_spec.rb +46 -40
  89. data/spec/puppet-lint/plugins/check_resources/unquoted_resource_title_spec.rb +95 -71
  90. data/spec/puppet-lint/plugins/check_strings/double_quoted_strings_spec.rb +28 -24
  91. data/spec/puppet-lint/plugins/check_strings/only_variable_string_spec.rb +11 -9
  92. data/spec/puppet-lint/plugins/check_strings/puppet_url_without_modules_spec.rb +1 -2
  93. data/spec/puppet-lint/plugins/check_strings/single_quote_string_with_variables_spec.rb +18 -14
  94. data/spec/puppet-lint/plugins/check_variables/variable_contains_dash_spec.rb +1 -1
  95. data/spec/puppet-lint/plugins/check_variables/variable_is_lowercase_spec.rb +1 -1
  96. data/spec/puppet-lint/plugins/check_whitespace/140chars_spec.rb +22 -15
  97. data/spec/puppet-lint/plugins/check_whitespace/2sp_soft_tabs_spec.rb +8 -6
  98. data/spec/puppet-lint/plugins/check_whitespace/80chars_spec.rb +23 -29
  99. data/spec/puppet-lint/plugins/check_whitespace/arrow_alignment_spec.rb +588 -494
  100. data/spec/puppet-lint/plugins/check_whitespace/hard_tabs_spec.rb +1 -1
  101. data/spec/puppet-lint/plugins/check_whitespace/trailing_whitespace_spec.rb +27 -19
  102. data/spec/puppet-lint_spec.rb +2 -12
  103. data/spec/spec_helper.rb +35 -30
  104. metadata +6 -5
  105. data/lib/puppet-lint/monkeypatches.rb +0 -2
  106. data/lib/puppet-lint/monkeypatches/string_percent.rb +0 -52
  107. data/lib/puppet-lint/monkeypatches/string_prepend.rb +0 -13
@@ -14,5 +14,5 @@ describe PuppetLint::Lexer::Token do
14
14
  its(:value) { is_expected.to eq('foo') }
15
15
  its(:line) { is_expected.to eq(1) }
16
16
  its(:column) { is_expected.to eq(2) }
17
- its(:inspect) { is_expected.to eq("<Token :NAME (foo) @1:2>") }
17
+ its(:inspect) { is_expected.to eq('<Token :NAME (foo) @1:2>') }
18
18
  end
@@ -1,6 +1,8 @@
1
+ # encoding: utf-8
2
+
1
3
  require 'spec_helper'
2
4
 
3
- describe PuppetLint::Lexer do
5
+ describe PuppetLint::Lexer do # rubocop:disable Metrics/BlockLength
4
6
  before do
5
7
  @lexer = PuppetLint::Lexer.new
6
8
  end
@@ -18,25 +20,25 @@ describe PuppetLint::Lexer do
18
20
  end
19
21
 
20
22
  it 'should get correct line number after double quoted multi line string' do
21
- token = @lexer.new_token(:STRING, "test\ntest")
23
+ @lexer.new_token(:STRING, "test\ntest")
22
24
  token = @lexer.new_token(:TEST, 'test')
23
25
  expect(token.line).to eq(2)
24
26
  end
25
27
 
26
28
  it 'should get correct line number after a multi line comment' do
27
- token = @lexer.new_token(:MLCOMMENT, "test\ntest", :raw => "/*test\ntest*/")
29
+ @lexer.new_token(:MLCOMMENT, "test\ntest", :raw => "/*test\ntest*/")
28
30
  token = @lexer.new_token(:TEST, 'test')
29
31
  expect(token.line).to eq(2)
30
32
  end
31
33
 
32
34
  it 'should calculate the line number for a multi line string' do
33
- token = @lexer.new_token(:SSTRING, "test\ntest")
35
+ @lexer.new_token(:SSTRING, "test\ntest")
34
36
  token = @lexer.new_token(:TEST, 'test')
35
37
  expect(token.line).to eq(2)
36
38
  end
37
39
 
38
40
  it 'should calculate line number for string that ends with newline' do
39
- token = @lexer.new_token(:SSTRING, "test\n")
41
+ @lexer.new_token(:SSTRING, "test\n")
40
42
  token = @lexer.new_token(:TEST, 'test')
41
43
  expect(token.line).to eq(2)
42
44
  end
@@ -55,12 +57,20 @@ describe PuppetLint::Lexer do
55
57
  it 'should calculate the column number for a multi line string' do
56
58
  @lexer.instance_variable_set('@line_no', 4)
57
59
  @lexer.instance_variable_set('@column', 5)
58
- token = @lexer.new_token(:SSTRING, "test\ntest")
60
+ @lexer.new_token(:SSTRING, "test\ntest")
59
61
  token = @lexer.new_token(:TEST, 'test')
60
62
  expect(token.column).to eq(6)
61
63
  end
62
64
  end
63
65
 
66
+ describe '#slurp_string' do
67
+ it 'raises a LexerError if the string is not terminated' do
68
+ expect {
69
+ @lexer.slurp_string('unterminated string')
70
+ }.to raise_error(PuppetLint::LexerError)
71
+ end
72
+ end
73
+
64
74
  context '#get_string_segment' do
65
75
  it 'should get a segment with a single terminator' do
66
76
  data = StringScanner.new('foo"bar')
@@ -86,7 +96,7 @@ describe PuppetLint::Lexer do
86
96
 
87
97
  context '#interpolate_string' do
88
98
  it 'should handle a string with no variables' do
89
- @lexer.interpolate_string('foo bar baz"',1, 1)
99
+ @lexer.interpolate_string('foo bar baz"', 1, 1)
90
100
  token = @lexer.tokens.first
91
101
 
92
102
  expect(@lexer.tokens.length).to eq(1)
@@ -97,7 +107,7 @@ describe PuppetLint::Lexer do
97
107
  end
98
108
 
99
109
  it 'should handle a string with a newline' do
100
- @lexer.interpolate_string(%{foo\nbar"}, 1, 1)
110
+ @lexer.interpolate_string(%(foo\nbar"), 1, 1)
101
111
  token = @lexer.tokens.first
102
112
 
103
113
  expect(@lexer.tokens.length).to eq(1)
@@ -129,6 +139,196 @@ describe PuppetLint::Lexer do
129
139
  expect(tokens[2].column).to eq(8)
130
140
  end
131
141
 
142
+ it 'should handle a string with newline characters' do
143
+ # rubocop:disable Layout/TrailingWhitespace
144
+ manifest = <<END
145
+ exec {
146
+ 'do-something':
147
+ command => "echo > /home/bar/.token;
148
+ kdestroy;
149
+ kinit ${pseudouser}@EXAMPLE.COM -kt ${keytab_path};
150
+ test $(klist | egrep '^Default principal:' | sed 's/Default principal:\s//') = '${pseudouser}'@EXAMPLE.COM",
151
+ refreshonly => true;
152
+ }
153
+ END
154
+ # rubocop:enable Layout/TrailingWhitespace
155
+ tokens = @lexer.tokenise(manifest)
156
+
157
+ expect(tokens.length).to eq(36)
158
+
159
+ expect(tokens[0].type).to eq(:WHITESPACE)
160
+ expect(tokens[0].value).to eq(' ')
161
+ expect(tokens[0].line).to eq(1)
162
+ expect(tokens[0].column).to eq(1)
163
+ expect(tokens[1].type).to eq(:NAME)
164
+ expect(tokens[1].value).to eq('exec')
165
+ expect(tokens[1].line).to eq(1)
166
+ expect(tokens[1].column).to eq(3)
167
+ expect(tokens[2].type).to eq(:WHITESPACE)
168
+ expect(tokens[2].value).to eq(' ')
169
+ expect(tokens[2].line).to eq(1)
170
+ expect(tokens[2].column).to eq(7)
171
+ expect(tokens[3].type).to eq(:LBRACE)
172
+ expect(tokens[3].value).to eq('{')
173
+ expect(tokens[3].line).to eq(1)
174
+ expect(tokens[3].column).to eq(8)
175
+ expect(tokens[4].type).to eq(:NEWLINE)
176
+ expect(tokens[4].value).to eq("\n")
177
+ expect(tokens[4].line).to eq(1)
178
+ expect(tokens[4].column).to eq(9)
179
+ expect(tokens[5].type).to eq(:INDENT)
180
+ expect(tokens[5].value).to eq(' ')
181
+ expect(tokens[5].line).to eq(2)
182
+ expect(tokens[5].column).to eq(1)
183
+ expect(tokens[6].type).to eq(:SSTRING)
184
+ expect(tokens[6].value).to eq('do-something')
185
+ expect(tokens[6].line).to eq(2)
186
+ expect(tokens[6].column).to eq(5)
187
+ expect(tokens[7].type).to eq(:COLON)
188
+ expect(tokens[7].value).to eq(':')
189
+ expect(tokens[7].line).to eq(2)
190
+ expect(tokens[7].column).to eq(19)
191
+ expect(tokens[8].type).to eq(:NEWLINE)
192
+ expect(tokens[8].value).to eq("\n")
193
+ expect(tokens[8].line).to eq(2)
194
+ expect(tokens[8].column).to eq(20)
195
+ expect(tokens[9].type).to eq(:INDENT)
196
+ expect(tokens[9].value).to eq(' ')
197
+ expect(tokens[9].line).to eq(3)
198
+ expect(tokens[9].column).to eq(1)
199
+ expect(tokens[10].type).to eq(:NAME)
200
+ expect(tokens[10].value).to eq('command')
201
+ expect(tokens[10].line).to eq(3)
202
+ expect(tokens[10].column).to eq(7)
203
+ expect(tokens[11].type).to eq(:WHITESPACE)
204
+ expect(tokens[11].value).to eq(' ')
205
+ expect(tokens[11].line).to eq(3)
206
+ expect(tokens[11].column).to eq(14)
207
+ expect(tokens[12].type).to eq(:FARROW)
208
+ expect(tokens[12].value).to eq('=>')
209
+ expect(tokens[12].line).to eq(3)
210
+ expect(tokens[12].column).to eq(19)
211
+ expect(tokens[13].type).to eq(:WHITESPACE)
212
+ expect(tokens[13].value).to eq(' ')
213
+ expect(tokens[13].line).to eq(3)
214
+ expect(tokens[13].column).to eq(21)
215
+ expect(tokens[14].type).to eq(:DQPRE)
216
+ expect(tokens[14].value).to eq("echo > /home/bar/.token; \n kdestroy; \n kinit ")
217
+ expect(tokens[14].line).to eq(3)
218
+ expect(tokens[14].column).to eq(22)
219
+ expect(tokens[15].type).to eq(:VARIABLE)
220
+ expect(tokens[15].value).to eq('pseudouser')
221
+ expect(tokens[15].line).to eq(5)
222
+ expect(tokens[15].column).to eq(131)
223
+ expect(tokens[16].type).to eq(:DQMID)
224
+ expect(tokens[16].value).to eq('@EXAMPLE.COM -kt ')
225
+ expect(tokens[16].line).to eq(5)
226
+ expect(tokens[16].column).to eq(143)
227
+ expect(tokens[17].type).to eq(:VARIABLE)
228
+ expect(tokens[17].value).to eq('keytab_path')
229
+ expect(tokens[17].line).to eq(5)
230
+ expect(tokens[17].column).to eq(161)
231
+ expect(tokens[18].type).to eq(:DQMID)
232
+ expect(tokens[18].value).to eq("; \n test ")
233
+ expect(tokens[18].line).to eq(5)
234
+ expect(tokens[18].column).to eq(174)
235
+ expect(tokens[19].type).to eq(:DQMID)
236
+ expect(tokens[19].value).to eq('$')
237
+ expect(tokens[19].line).to eq(6)
238
+ expect(tokens[19].column).to eq(213)
239
+ expect(tokens[20].type).to eq(:DQMID)
240
+ expect(tokens[20].value).to eq("(klist | egrep '^Default principal:' | sed 's/Default principal: //') = '")
241
+ expect(tokens[20].line).to eq(6)
242
+ expect(tokens[20].column).to eq(215)
243
+ expect(tokens[21].type).to eq(:VARIABLE)
244
+ expect(tokens[21].value).to eq('pseudouser')
245
+ expect(tokens[21].line).to eq(6)
246
+ expect(tokens[21].column).to eq(289)
247
+ expect(tokens[22].type).to eq(:DQPOST)
248
+ expect(tokens[22].value).to eq("'@EXAMPLE.COM")
249
+ expect(tokens[22].line).to eq(6)
250
+ expect(tokens[22].column).to eq(301)
251
+ expect(tokens[23].type).to eq(:COMMA)
252
+ expect(tokens[23].value).to eq(',')
253
+ expect(tokens[23].line).to eq(6)
254
+ expect(tokens[23].column).to eq(315)
255
+ expect(tokens[24].type).to eq(:NEWLINE)
256
+ expect(tokens[24].value).to eq("\n")
257
+ expect(tokens[24].line).to eq(6)
258
+ expect(tokens[24].column).to eq(316)
259
+ expect(tokens[25].type).to eq(:INDENT)
260
+ expect(tokens[25].value).to eq(' ')
261
+ expect(tokens[25].line).to eq(7)
262
+ expect(tokens[25].column).to eq(1)
263
+ expect(tokens[26].type).to eq(:NAME)
264
+ expect(tokens[26].value).to eq('refreshonly')
265
+ expect(tokens[26].line).to eq(7)
266
+ expect(tokens[26].column).to eq(7)
267
+ expect(tokens[27].type).to eq(:WHITESPACE)
268
+ expect(tokens[27].value).to eq(' ')
269
+ expect(tokens[27].line).to eq(7)
270
+ expect(tokens[27].column).to eq(18)
271
+ expect(tokens[28].type).to eq(:FARROW)
272
+ expect(tokens[28].value).to eq('=>')
273
+ expect(tokens[28].line).to eq(7)
274
+ expect(tokens[28].column).to eq(19)
275
+ expect(tokens[29].type).to eq(:WHITESPACE)
276
+ expect(tokens[29].value).to eq(' ')
277
+ expect(tokens[29].line).to eq(7)
278
+ expect(tokens[29].column).to eq(21)
279
+ expect(tokens[30].type).to eq(:TRUE)
280
+ expect(tokens[30].value).to eq('true')
281
+ expect(tokens[30].line).to eq(7)
282
+ expect(tokens[30].column).to eq(22)
283
+ expect(tokens[31].type).to eq(:SEMIC)
284
+ expect(tokens[31].value).to eq(';')
285
+ expect(tokens[31].line).to eq(7)
286
+ expect(tokens[31].column).to eq(26)
287
+ expect(tokens[32].type).to eq(:NEWLINE)
288
+ expect(tokens[32].value).to eq("\n")
289
+ expect(tokens[32].line).to eq(7)
290
+ expect(tokens[32].column).to eq(27)
291
+ expect(tokens[33].type).to eq(:INDENT)
292
+ expect(tokens[33].value).to eq(' ')
293
+ expect(tokens[33].line).to eq(8)
294
+ expect(tokens[33].column).to eq(1)
295
+ expect(tokens[34].type).to eq(:RBRACE)
296
+ expect(tokens[34].value).to eq('}')
297
+ expect(tokens[34].line).to eq(8)
298
+ expect(tokens[34].column).to eq(3)
299
+ expect(tokens[35].type).to eq(:NEWLINE)
300
+ expect(tokens[35].value).to eq("\n")
301
+ expect(tokens[35].line).to eq(8)
302
+ expect(tokens[35].column).to eq(4)
303
+ end
304
+
305
+ it 'should handle a string with a single variable and newline characters' do
306
+ manifest = <<-END
307
+ foo
308
+ /bin/${foo} >>
309
+ /bar/baz"
310
+ END
311
+ @lexer.interpolate_string(manifest, 1, 1)
312
+ tokens = @lexer.tokens
313
+
314
+ expect(tokens.length).to eq(3)
315
+
316
+ expect(tokens[0].type).to eq(:DQPRE)
317
+ expect(tokens[0].value).to eq(" foo\n /bin/")
318
+ expect(tokens[0].line).to eq(1)
319
+ expect(tokens[0].column).to eq(1)
320
+
321
+ expect(tokens[1].type).to eq(:VARIABLE)
322
+ expect(tokens[1].value).to eq('foo')
323
+ expect(tokens[1].line).to eq(2)
324
+ expect(tokens[1].column).to eq(20)
325
+
326
+ expect(tokens[2].type).to eq(:DQPOST)
327
+ expect(tokens[2].value).to eq(" >>\n /bar/baz")
328
+ expect(tokens[2].line).to eq(2)
329
+ expect(tokens[2].column).to eq(25)
330
+ end
331
+
132
332
  it 'should handle a string with a single variable and surrounding text' do
133
333
  @lexer.interpolate_string('foo${bar}baz"', 1, 1)
134
334
  tokens = @lexer.tokens
@@ -198,12 +398,14 @@ describe PuppetLint::Lexer do
198
398
  expect(tokens[1].value).to eq('bar')
199
399
  expect(tokens[1].line).to eq(1)
200
400
  expect(tokens[1].column).to eq(3)
201
- expect(tokens[1].to_manifest).to eq("${bar}")
401
+ expect(tokens[1].to_manifest).to eq('bar')
202
402
 
203
403
  expect(tokens[2].type).to eq(:DQPOST)
204
404
  expect(tokens[2].value).to eq('')
205
405
  expect(tokens[2].line).to eq(1)
206
406
  expect(tokens[2].column).to eq(8)
407
+
408
+ expect(tokens.map(&:to_manifest).join('')).to eq('"${bar}"')
207
409
  end
208
410
 
209
411
  it 'should not remove the unnecessary $ from enclosed variables' do
@@ -221,12 +423,14 @@ describe PuppetLint::Lexer do
221
423
  expect(tokens[1].raw).to eq('$bar')
222
424
  expect(tokens[1].line).to eq(1)
223
425
  expect(tokens[1].column).to eq(4)
224
- expect(tokens[1].to_manifest).to eq("${$bar}")
426
+ expect(tokens[1].to_manifest).to eq('$bar')
225
427
 
226
428
  expect(tokens[2].type).to eq(:DQPOST)
227
429
  expect(tokens[2].value).to eq('')
228
430
  expect(tokens[2].line).to eq(1)
229
431
  expect(tokens[2].column).to eq(9)
432
+
433
+ expect(tokens.map(&:to_manifest).join('')).to eq('"${$bar}"')
230
434
  end
231
435
 
232
436
  it 'should handle a variable with an array reference' do
@@ -306,7 +510,7 @@ describe PuppetLint::Lexer do
306
510
  end
307
511
 
308
512
  it 'should handle a string with a nested string inside it' do
309
- @lexer.interpolate_string(%q{string with ${'a nested single quoted string'} inside it"}, 1, 1)
513
+ @lexer.interpolate_string(%q(string with ${'a nested single quoted string'} inside it"), 1, 1)
310
514
  tokens = @lexer.tokens
311
515
 
312
516
  expect(tokens.length).to eq(3)
@@ -328,7 +532,7 @@ describe PuppetLint::Lexer do
328
532
  end
329
533
 
330
534
  it 'should handle a string with nested math' do
331
- @lexer.interpolate_string(%q{string with ${(3+5)/4} nested math"}, 1, 1)
535
+ @lexer.interpolate_string('string with ${(3+5)/4} nested math"', 1, 1)
332
536
  tokens = @lexer.tokens
333
537
 
334
538
  expect(tokens.length).to eq(9)
@@ -376,7 +580,7 @@ describe PuppetLint::Lexer do
376
580
  end
377
581
 
378
582
  it 'should handle a string with a nested array' do
379
- @lexer.interpolate_string(%q{string with ${['an array ', $v2]} in it"}, 1, 1)
583
+ @lexer.interpolate_string(%q(string with ${['an array ', $v2]} in it"), 1, 1)
380
584
  tokens = @lexer.tokens
381
585
 
382
586
  expect(tokens.length).to eq(8)
@@ -420,7 +624,7 @@ describe PuppetLint::Lexer do
420
624
  end
421
625
 
422
626
  it 'should handle a string of $s' do
423
- @lexer.interpolate_string(%q{$$$$"}, 1, 1)
627
+ @lexer.interpolate_string('$$$$"', 1, 1)
424
628
  tokens = @lexer.tokens
425
629
 
426
630
  expect(tokens.length).to eq(1)
@@ -432,7 +636,7 @@ describe PuppetLint::Lexer do
432
636
  end
433
637
 
434
638
  it 'should handle "$foo$bar"' do
435
- @lexer.interpolate_string(%q{$foo$bar"}, 1, 1)
639
+ @lexer.interpolate_string('$foo$bar"', 1, 1)
436
640
  tokens = @lexer.tokens
437
641
 
438
642
  expect(tokens.length).to eq(5)
@@ -464,7 +668,7 @@ describe PuppetLint::Lexer do
464
668
  end
465
669
 
466
670
  it 'should handle "foo$bar$"' do
467
- @lexer.interpolate_string(%q{foo$bar$"}, 1, 1)
671
+ @lexer.interpolate_string('foo$bar$"', 1, 1)
468
672
  tokens = @lexer.tokens
469
673
 
470
674
  expect(tokens.length).to eq(3)
@@ -486,7 +690,7 @@ describe PuppetLint::Lexer do
486
690
  end
487
691
 
488
692
  it 'should handle "foo$$bar"' do
489
- @lexer.interpolate_string(%q{foo$$bar"}, 1, 1)
693
+ @lexer.interpolate_string('foo$$bar"', 1, 1)
490
694
  tokens = @lexer.tokens
491
695
 
492
696
  expect(tokens.length).to eq(3)
@@ -508,7 +712,7 @@ describe PuppetLint::Lexer do
508
712
  end
509
713
 
510
714
  it 'should handle an empty string' do
511
- @lexer.interpolate_string(%q{"}, 1, 1)
715
+ @lexer.interpolate_string('"', 1, 1)
512
716
  tokens = @lexer.tokens
513
717
 
514
718
  expect(tokens.length).to eq(1)
@@ -520,7 +724,7 @@ describe PuppetLint::Lexer do
520
724
  end
521
725
 
522
726
  it 'should handle "$foo::::bar"' do
523
- @lexer.interpolate_string(%q{$foo::::bar"}, 1, 1)
727
+ @lexer.interpolate_string('$foo::::bar"', 1, 1)
524
728
  tokens = @lexer.tokens
525
729
 
526
730
  expect(tokens.length).to eq(3)
@@ -565,26 +769,31 @@ describe PuppetLint::Lexer do
565
769
  expect(token.column).to eq(18)
566
770
  end
567
771
 
772
+ it 'should not enclose variable with a chained function call' do
773
+ manifest = '"This is ${a.test}"'
774
+ tokens = @lexer.tokenise(manifest)
775
+ expect(tokens.map(&:to_manifest).join('')).to eq(manifest)
776
+ end
568
777
  end
569
778
 
570
- [
571
- 'case',
572
- 'class',
573
- 'default',
574
- 'define',
575
- 'import',
576
- 'if',
577
- 'elsif',
578
- 'else',
579
- 'inherits',
580
- 'node',
581
- 'and',
582
- 'or',
583
- 'undef',
584
- 'true',
585
- 'false',
586
- 'in',
587
- 'unless',
779
+ %w[
780
+ case
781
+ class
782
+ default
783
+ define
784
+ import
785
+ if
786
+ elsif
787
+ else
788
+ inherits
789
+ node
790
+ and
791
+ or
792
+ undef
793
+ true
794
+ false
795
+ in
796
+ unless
588
797
  ].each do |keyword|
589
798
  it "should handle '#{keyword}' as a keyword" do
590
799
  token = @lexer.tokenise(keyword).first
@@ -640,7 +849,7 @@ describe PuppetLint::Lexer do
640
849
  [:NEWLINE, "\n"],
641
850
  [:NEWLINE, "\r\n"],
642
851
  ].each do |name, string|
643
- it "should have a token named '#{name.to_s}'" do
852
+ it "should have a token named '#{name}'" do
644
853
  token = @lexer.tokenise(string).first
645
854
  expect(token.type).to eq(name)
646
855
  expect(token.value).to eq(string)
@@ -675,7 +884,7 @@ describe PuppetLint::Lexer do
675
884
 
676
885
  context ':HEREDOC without interpolation' do
677
886
  it 'should parse a simple heredoc' do
678
- manifest = <<-END.gsub(/^ {6}/, '')
887
+ manifest = <<-END.gsub(%r{^ {6}}, '')
679
888
  $str = @(myheredoc)
680
889
  SOMETHING
681
890
  ELSE
@@ -686,7 +895,7 @@ describe PuppetLint::Lexer do
686
895
 
687
896
  expect(tokens.length).to eq(8)
688
897
  expect(tokens[0].type).to eq(:VARIABLE)
689
- expect(tokens[0].value).to eq("str")
898
+ expect(tokens[0].value).to eq('str')
690
899
  expect(tokens[0].line).to eq(1)
691
900
  expect(tokens[0].column).to eq(1)
692
901
  expect(tokens[1].type).to eq(:WHITESPACE)
@@ -720,7 +929,7 @@ describe PuppetLint::Lexer do
720
929
  end
721
930
 
722
931
  it 'should not interpolate the contents of the heredoc' do
723
- manifest = <<-END.gsub(/^ {6}/, '')
932
+ manifest = <<-END.gsub(%r{^ {6}}, '')
724
933
  $str = @(myheredoc)
725
934
  SOMETHING
726
935
  ${else}
@@ -766,7 +975,7 @@ describe PuppetLint::Lexer do
766
975
  end
767
976
 
768
977
  it 'should handle multiple heredoc declarations on a single line' do
769
- manifest = <<-END.gsub(/^ {6}/, '')
978
+ manifest = <<-END.gsub(%r{^ {6}}, '')
770
979
  $str = "${@(end1)} ${@(end2)}"
771
980
  foo
772
981
  |-end1
@@ -837,7 +1046,7 @@ describe PuppetLint::Lexer do
837
1046
  end
838
1047
 
839
1048
  it 'should handle a heredoc that specifies a syntax' do
840
- manifest = <<-END.gsub(/^ {6}/, '')
1049
+ manifest = <<-END.gsub(%r{^ {6}}, '')
841
1050
  $str = @("end":json/)
842
1051
  {
843
1052
  "foo": "bar"
@@ -849,7 +1058,7 @@ describe PuppetLint::Lexer do
849
1058
 
850
1059
  expect(tokens.length).to eq(8)
851
1060
  expect(tokens[0].type).to eq(:VARIABLE)
852
- expect(tokens[0].value).to eq("str")
1061
+ expect(tokens[0].value).to eq('str')
853
1062
  expect(tokens[0].line).to eq(1)
854
1063
  expect(tokens[0].column).to eq(1)
855
1064
  expect(tokens[1].type).to eq(:WHITESPACE)
@@ -886,7 +1095,7 @@ describe PuppetLint::Lexer do
886
1095
 
887
1096
  context ':HEREDOC with interpolation' do
888
1097
  it 'should parse a heredoc with no interpolated values as a :HEREDOC' do
889
- manifest = <<-END.gsub(/^ {6}/, '')
1098
+ manifest = <<-END.gsub(%r{^ {6}}, '')
890
1099
  $str = @("myheredoc"/)
891
1100
  SOMETHING
892
1101
  ELSE
@@ -896,7 +1105,7 @@ describe PuppetLint::Lexer do
896
1105
  tokens = @lexer.tokenise(manifest)
897
1106
 
898
1107
  expect(tokens[0].type).to eq(:VARIABLE)
899
- expect(tokens[0].value).to eq("str")
1108
+ expect(tokens[0].value).to eq('str')
900
1109
  expect(tokens[0].line).to eq(1)
901
1110
  expect(tokens[0].column).to eq(1)
902
1111
  expect(tokens[1].type).to eq(:WHITESPACE)
@@ -931,7 +1140,7 @@ describe PuppetLint::Lexer do
931
1140
  end
932
1141
 
933
1142
  it 'should parse a heredoc with interpolated values' do
934
- manifest = <<-END.gsub(/^ {6}/, '')
1143
+ manifest = <<-END.gsub(%r{^ {6}}, '')
935
1144
  $str = @("myheredoc"/)
936
1145
  SOMETHING
937
1146
  ${else}
@@ -942,6 +1151,7 @@ describe PuppetLint::Lexer do
942
1151
  END
943
1152
 
944
1153
  tokens = @lexer.tokenise(manifest)
1154
+ expect(tokens.map(&:to_manifest).join('')).to eq(manifest)
945
1155
 
946
1156
  expect(tokens[0].type).to eq(:VARIABLE)
947
1157
  expect(tokens[0].value).to eq('str')
@@ -972,19 +1182,20 @@ describe PuppetLint::Lexer do
972
1182
  expect(tokens[6].line).to eq(2)
973
1183
  expect(tokens[6].column).to eq(1)
974
1184
  expect(tokens[7].type).to eq(:VARIABLE)
975
- expect(tokens[7].value).to eq("else")
1185
+ expect(tokens[7].value).to eq('else')
976
1186
  expect(tokens[7].line).to eq(3)
977
- expect(tokens[7].column).to eq(3)
978
- expect(tokens[7].to_manifest).to eq("${else}")
1187
+ expect(tokens[7].column).to eq(5)
1188
+ expect(tokens[7].to_manifest).to eq('else')
979
1189
  expect(tokens[8].type).to eq(:HEREDOC_MID)
980
1190
  expect(tokens[8].value).to eq("\n AND :\n ")
981
1191
  expect(tokens[8].line).to eq(3)
982
- expect(tokens[8].column).to eq(10)
1192
+ expect(tokens[8].column).to eq(9)
1193
+ expect(tokens[8].to_manifest).to eq("}\n AND :\n ")
983
1194
  expect(tokens[9].type).to eq(:UNENC_VARIABLE)
984
- expect(tokens[9].value).to eq("another")
1195
+ expect(tokens[9].value).to eq('another')
985
1196
  expect(tokens[9].line).to eq(5)
986
1197
  expect(tokens[9].column).to eq(3)
987
- expect(tokens[9].to_manifest).to eq("$another")
1198
+ expect(tokens[9].to_manifest).to eq('$another')
988
1199
  expect(tokens[10].type).to eq(:HEREDOC_POST)
989
1200
  expect(tokens[10].value).to eq("\n THING\n ")
990
1201
  expect(tokens[10].raw).to eq("\n THING\n | myheredoc")
@@ -993,7 +1204,7 @@ describe PuppetLint::Lexer do
993
1204
  end
994
1205
 
995
1206
  it 'should not remove the unnecessary $ from enclosed variables' do
996
- manifest = <<-END.gsub(/^ {6}/, '')
1207
+ manifest = <<-END.gsub(%r{^ {6}}, '')
997
1208
  $str = @("myheredoc"/)
998
1209
  ${$myvar}
999
1210
  |-myheredoc
@@ -1005,7 +1216,9 @@ describe PuppetLint::Lexer do
1005
1216
  expect(tokens[7].type).to eq(:VARIABLE)
1006
1217
  expect(tokens[7].value).to eq('myvar')
1007
1218
  expect(tokens[7].raw).to eq('$myvar')
1008
- expect(tokens[7].to_manifest).to eq("${$myvar}")
1219
+ expect(tokens[7].to_manifest).to eq('$myvar')
1220
+
1221
+ expect(tokens.map(&:to_manifest).join('')).to eq(manifest)
1009
1222
  end
1010
1223
  end
1011
1224
 
@@ -1157,48 +1370,48 @@ describe PuppetLint::Lexer do
1157
1370
  end
1158
1371
 
1159
1372
  it "should match a single quoted string with an escaped '" do
1160
- token = @lexer.tokenise(%q{'single quoted string with "\\'"'}).first
1373
+ token = @lexer.tokenise(%q('single quoted string with "\\'"')).first
1161
1374
  expect(token.type).to eq(:SSTRING)
1162
1375
  expect(token.value).to eq('single quoted string with "\\\'"')
1163
1376
  end
1164
1377
 
1165
- it "should match a single quoted string with an escaped $" do
1166
- token = @lexer.tokenise(%q{'single quoted string with "\$"'}).first
1378
+ it 'should match a single quoted string with an escaped $' do
1379
+ token = @lexer.tokenise(%q('single quoted string with "\$"')).first
1167
1380
  expect(token.type).to eq(:SSTRING)
1168
1381
  expect(token.value).to eq('single quoted string with "\\$"')
1169
1382
  end
1170
1383
 
1171
- it "should match a single quoted string with an escaped ." do
1172
- token = @lexer.tokenise(%q{'single quoted string with "\."'}).first
1384
+ it 'should match a single quoted string with an escaped .' do
1385
+ token = @lexer.tokenise(%q('single quoted string with "\."')).first
1173
1386
  expect(token.type).to eq(:SSTRING)
1174
1387
  expect(token.value).to eq('single quoted string with "\\."')
1175
1388
  end
1176
1389
 
1177
- it "should match a single quoted string with an escaped \\n" do
1178
- token = @lexer.tokenise(%q{'single quoted string with "\n"'}).first
1390
+ it 'should match a single quoted string with an escaped \\n' do
1391
+ token = @lexer.tokenise(%q('single quoted string with "\n"')).first
1179
1392
  expect(token.type).to eq(:SSTRING)
1180
1393
  expect(token.value).to eq('single quoted string with "\\n"')
1181
1394
  end
1182
1395
 
1183
- it "should match a single quoted string with an escaped \\" do
1184
- token = @lexer.tokenise(%q{'single quoted string with "\\\\"'}).first
1396
+ it 'should match a single quoted string with an escaped \\' do
1397
+ token = @lexer.tokenise(%q('single quoted string with "\\\\"')).first
1185
1398
  expect(token.type).to eq(:SSTRING)
1186
1399
  expect(token.value).to eq('single quoted string with "\\\\"')
1187
1400
  end
1188
1401
 
1189
- it "should match an empty string" do
1402
+ it 'should match an empty string' do
1190
1403
  token = @lexer.tokenise("''").first
1191
1404
  expect(token.type).to eq(:SSTRING)
1192
1405
  expect(token.value).to eq('')
1193
1406
  end
1194
1407
 
1195
- it "should match an empty string ending with \\\\" do
1408
+ it 'should match an empty string ending with \\\\' do
1196
1409
  token = @lexer.tokenise("'foo\\\\'").first
1197
1410
  expect(token.type).to eq(:SSTRING)
1198
- expect(token.value).to eq(%{foo\\\\})
1411
+ expect(token.value).to eq(%(foo\\\\))
1199
1412
  end
1200
1413
 
1201
- it "should match single quoted string containing a line break" do
1414
+ it 'should match single quoted string containing a line break' do
1202
1415
  token = @lexer.tokenise("'\n'").first
1203
1416
  expect(token.type).to eq(:SSTRING)
1204
1417
  expect(token.value).to eq("\n")
@@ -1259,20 +1472,20 @@ describe PuppetLint::Lexer do
1259
1472
  end
1260
1473
 
1261
1474
  context ':STRING' do
1262
- it 'should parse strings with \\\\\\' do
1475
+ it 'should parse strings with embedded strings' do
1263
1476
  expect {
1264
- @lexer.tokenise("exec { \"/bin/echo \\\\\\\"${environment}\\\\\\\"\": }")
1477
+ @lexer.tokenise('exec { "/bin/echo \"${environment}\"": }')
1265
1478
  }.to_not raise_error
1266
1479
  end
1267
1480
 
1268
- it "should match double quoted string containing a line break" do
1269
- token = @lexer.tokenise(%Q{"\n"}).first
1481
+ it 'should match double quoted string containing a line break' do
1482
+ token = @lexer.tokenise(%("\n")).first
1270
1483
  expect(token.type).to eq(:STRING)
1271
1484
  expect(token.value).to eq("\n")
1272
1485
  end
1273
1486
 
1274
1487
  it 'should handle interpolated values that contain double quotes' do
1275
- manifest = %Q{"export bar=\\"${join(hiera('test'), "," )}\\""}
1488
+ manifest = %{"export bar=\\"${join(hiera('test'), "," )}\\""}
1276
1489
 
1277
1490
  tokens = @lexer.tokenise(manifest)
1278
1491
  expect(tokens[0].type).to eq(:DQPRE)
@@ -1298,4 +1511,24 @@ describe PuppetLint::Lexer do
1298
1511
  expect(tokens[12].value).to eq('\"')
1299
1512
  end
1300
1513
  end
1514
+
1515
+ context ':WHITESPACE' do
1516
+ it 'should parse spaces' do
1517
+ token = @lexer.tokenise(' ').first
1518
+ expect(token.type).to eq(:WHITESPACE)
1519
+ expect(token.value).to eq(' ')
1520
+ end
1521
+
1522
+ it 'should parse tabs' do
1523
+ token = @lexer.tokenise("\t").first
1524
+ expect(token.type).to eq(:WHITESPACE)
1525
+ expect(token.value).to eq("\t")
1526
+ end
1527
+
1528
+ it 'should parse unicode spaces' do
1529
+ token = @lexer.tokenise("\xc2\xa0").first
1530
+ expect(token.type).to eq(:WHITESPACE)
1531
+ expect(token.value).to eq("\xc2\xa0")
1532
+ end
1533
+ end
1301
1534
  end