puppet-lint 2.3.0 → 2.3.1

Sign up to get free protection for your applications and to get access to all the features.
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