puppet-lint 2.0.0 → 2.0.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 (32) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/.rspec +1 -0
  4. data/.travis.yml +11 -2
  5. data/CHANGELOG.md +657 -0
  6. data/Gemfile +19 -0
  7. data/README.md +6 -1
  8. data/lib/puppet-lint.rb +1 -1
  9. data/lib/puppet-lint/checks.rb +1 -5
  10. data/lib/puppet-lint/lexer.rb +4 -2
  11. data/lib/puppet-lint/optparser.rb +11 -2
  12. data/lib/puppet-lint/plugins/check_classes.rb +5 -1
  13. data/lib/puppet-lint/plugins/check_comments.rb +6 -8
  14. data/lib/puppet-lint/plugins/check_resources.rb +4 -3
  15. data/lib/puppet-lint/plugins/check_variables.rb +21 -3
  16. data/lib/puppet-lint/plugins/check_whitespace.rb +21 -1
  17. data/lib/puppet-lint/tasks/puppet-lint.rb +4 -0
  18. data/lib/puppet-lint/version.rb +1 -1
  19. data/puppet-lint.gemspec +1 -4
  20. data/spec/puppet-lint/bin_spec.rb +1 -1
  21. data/spec/puppet-lint/lexer_spec.rb +38 -0
  22. data/spec/puppet-lint/plugins/check_classes/parameter_order_spec.rb +51 -47
  23. data/spec/puppet-lint/plugins/check_comments/star_comments_spec.rb +22 -0
  24. data/spec/puppet-lint/plugins/check_resources/ensure_first_param_spec.rb +19 -0
  25. data/spec/puppet-lint/plugins/check_resources/file_mode_spec.rb +96 -0
  26. data/spec/puppet-lint/plugins/check_resources/unquoted_file_mode_spec.rb +28 -0
  27. data/spec/puppet-lint/plugins/check_strings/variables_not_enclosed_spec.rb +3 -3
  28. data/spec/puppet-lint/plugins/check_variables/variable_is_lowercase_spec.rb +25 -0
  29. data/spec/puppet-lint/plugins/check_whitespace/80chars_spec.rb +71 -0
  30. data/spec/puppet-lint/plugins/check_whitespace/arrow_alignment_spec.rb +37 -37
  31. data/spec/puppet-lint_spec.rb +6 -0
  32. metadata +13 -50
data/Gemfile CHANGED
@@ -1,3 +1,22 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
+
5
+ group :test do
6
+ gem 'rake', '~> 10.0'
7
+ gem 'rspec', '~> 3.0'
8
+ gem 'rspec-its', '~> 1.0'
9
+ gem 'rspec-collection_matchers', '~> 1.0'
10
+ gem 'rack', '~> 1.0'
11
+
12
+ if RUBY_VERSION < '2.0'
13
+ # json 2.x requires ruby 2.0. Lock to 1.8
14
+ gem 'json', '~> 1.8'
15
+ # json_pure 2.0.2 requires ruby 2.0. Lock to 2.0.1
16
+ gem 'json_pure', '= 2.0.1'
17
+ # addressable 2.4.0 requires ruby 1.9.0. Lock to 2.3.8.
18
+ gem 'addressable', '= 2.3.8'
19
+ else
20
+ gem 'json'
21
+ end
22
+ end
data/README.md CHANGED
@@ -174,6 +174,11 @@ If you find a bug in puppet-lint or its results, please create an issue in the
174
174
  [repo issues tracker](https://github.com/rodjek/puppet-lint/issues/). Bonus
175
175
  points will be awarded if you also include a patch that fixes the issue.
176
176
 
177
+ ## Executing puppet-lint tests suite
178
+
179
+ bundle exec rspec [spec/puppet-lint/a_single_test.rb]
180
+
181
+
177
182
  ## Thank You
178
183
 
179
184
  Many thanks to the following people for contributing to puppet-lint
@@ -187,7 +192,7 @@ As well as the many people who have reported the issues they've had!
187
192
 
188
193
  ## License
189
194
 
190
- Copyright (c) 2011 Tim Sharpe
195
+ Copyright (c) 2011-2016 Tim Sharpe
191
196
 
192
197
  Permission is hereby granted, free of charge, to any person obtaining
193
198
  a copy of this software and associated documentation files (the
@@ -166,7 +166,7 @@ class PuppetLint
166
166
 
167
167
  if @code.empty?
168
168
  @problems = []
169
- @manifest = []
169
+ @manifest = ''
170
170
  return
171
171
  end
172
172
 
@@ -58,16 +58,12 @@ class PuppetLint::Checks
58
58
  problems = klass.run
59
59
 
60
60
  if PuppetLint.configuration.fix
61
- checks_run << klass
61
+ @problems.concat(klass.fix_problems)
62
62
  else
63
63
  @problems.concat(problems)
64
64
  end
65
65
  end
66
66
 
67
- checks_run.each do |check|
68
- @problems.concat(check.fix_problems)
69
- end
70
-
71
67
  @problems
72
68
  end
73
69
 
@@ -62,6 +62,7 @@ class PuppetLint
62
62
  :MATCH => true,
63
63
  :NOMATCH => true,
64
64
  :COMMA => true,
65
+ :LBRACK => true,
65
66
  }
66
67
 
67
68
  # Internal: An Array of Arrays containing tokens that can be described by
@@ -69,6 +70,7 @@ class PuppetLint
69
70
  # name of the token as a Symbol and a regular expression describing the
70
71
  # value of the token.
71
72
  KNOWN_TOKENS = [
73
+ [:TYPE, /\A(Integer|Float|Boolean|Regexp|String|Array|Hash|Resource|Class|Collection|Scalar|Numeric|CatalogEntry|Data|Tuple|Struct|Optional|NotUndef|Variant|Enum|Pattern|Any|Callable|Type|Runtime|Undef|Default)/],
72
74
  [:CLASSREF, /\A(((::){0,1}[A-Z][-\w]*)+)/],
73
75
  [:NUMBER, /\A\b((?:0[xX][0-9A-Fa-f]+|0?\d+(?:\.\d+)?(?:[eE]-?\d+)?))\b/],
74
76
  [:NAME, /\A(((::)?[a-z0-9][-\w]*)(::[a-z0-9][-\w]*)*)/],
@@ -168,7 +170,7 @@ class PuppetLint
168
170
  end
169
171
 
170
172
  unless found
171
- if var_name = chunk[/\A\$((::)?([\w-]+::)*[\w-]+(\[.+?\])*)/, 1]
173
+ if var_name = chunk[/\A\$((::)?([\w]+::)*[\w]+(\[.+?\])*)/, 1]
172
174
  length = var_name.size + 1
173
175
  tokens << new_token(:VARIABLE, var_name, length)
174
176
 
@@ -344,7 +346,7 @@ class PuppetLint
344
346
  tokens << new_token(:DQMID, value, value.size, :line => line, :column => token_column)
345
347
  end
346
348
  if ss.scan(/\{/).nil?
347
- var_name = ss.scan(/(::)?([\w-]+::)*[\w-]+/)
349
+ var_name = ss.scan(/(::)?([\w]+::)*[\w]+/)
348
350
  if var_name.nil?
349
351
  token_column = column + ss.pos - 1
350
352
  tokens << new_token(:DQMID, "$", 1, :line => line, :column => token_column)
@@ -94,8 +94,12 @@ class PuppetLint::OptParser
94
94
 
95
95
  opts.on('--only-checks CHECKS', 'A comma separated list of checks that should be run') do |checks|
96
96
  enable_checks = checks.split(',').map(&:to_sym)
97
- (PuppetLint.configuration.checks - enable_checks).each do |check|
98
- PuppetLint.configuration.send("disable_#{check}")
97
+ (PuppetLint.configuration.checks).each do |check|
98
+ if enable_checks.include? check
99
+ PuppetLint.configuration.send("enable_#{check}")
100
+ else
101
+ PuppetLint.configuration.send("disable_#{check}")
102
+ end
99
103
  end
100
104
  end
101
105
 
@@ -103,6 +107,11 @@ class PuppetLint::OptParser
103
107
  opts.on("--no-#{check}-check", "Skip the #{check} check.") do
104
108
  PuppetLint.configuration.send("disable_#{check}")
105
109
  end
110
+ unless PuppetLint.configuration.send("#{check}_enabled?")
111
+ opts.on("--#{check}-check", "Enable the #{check} check.") do
112
+ PuppetLint.configuration.send("enable_#{check}")
113
+ end
114
+ end
106
115
  end
107
116
 
108
117
  opts.load('/etc/puppet-lint.rc')
@@ -83,13 +83,14 @@ PuppetLint.new_check(:class_inherits_from_params_class) do
83
83
  end
84
84
  end
85
85
  end
86
+ PuppetLint.configuration.send('disable_class_inherits_from_params_class')
86
87
 
87
88
  # Public: Test the manifest tokens for any parameterised classes or defined
88
89
  # types that take parameters and record a warning if there are any optional
89
90
  # parameters listed before required parameters.
90
91
  PuppetLint.new_check(:parameter_order) do
91
92
  def check
92
- defined_type_indexes.each do |class_idx|
93
+ (class_indexes + defined_type_indexes).each do |class_idx|
93
94
  unless class_idx[:param_tokens].nil?
94
95
  paren_stack = []
95
96
  class_idx[:param_tokens].each_with_index do |token, i|
@@ -197,6 +198,9 @@ PuppetLint.new_check(:variable_scope) do
197
198
  'stage',
198
199
  'subscribe',
199
200
  'tag',
201
+ 'facts',
202
+ 'trusted',
203
+ 'server_facts',
200
204
  ]
201
205
  POST_VAR_TOKENS = Set[:COMMA, :EQUALS, :RPAREN]
202
206
 
@@ -37,19 +37,17 @@ PuppetLint.new_check(:star_comments) do
37
37
 
38
38
  def fix(problem)
39
39
  comment_lines = problem[:token].value.strip.split("\n").map(&:strip)
40
+
40
41
  first_line = comment_lines.shift
41
42
  problem[:token].type = :COMMENT
42
43
  problem[:token].value = " #{first_line}"
43
44
 
44
- index = tokens.index(problem[:token].next_token)
45
+ index = tokens.index(problem[:token].next_token) || 1
45
46
  comment_lines.reverse.each do |line|
46
- [
47
- PuppetLint::Lexer::Token.new(:COMMENT, " #{line}", 0, 0),
48
- PuppetLint::Lexer::Token.new(:INDENT, problem[:token].prev_token.value.dup, 0, 0),
49
- PuppetLint::Lexer::Token.new(:NEWLINE, "\n", 0, 0),
50
- ].each do |new_token|
51
- tokens.insert(index, new_token)
52
- end
47
+ indent = problem[:token].prev_token.nil? ? nil : problem[:token].prev_token.value.dup
48
+ tokens.insert(index, PuppetLint::Lexer::Token.new(:COMMENT, " #{line}", 0, 0))
49
+ tokens.insert(index, PuppetLint::Lexer::Token.new(:INDENT, indent, 0, 0)) if indent
50
+ tokens.insert(index, PuppetLint::Lexer::Token.new(:NEWLINE, "\n", 0, 0))
53
51
  end
54
52
  end
55
53
  end
@@ -25,6 +25,7 @@ end
25
25
  PuppetLint.new_check(:ensure_first_param) do
26
26
  def check
27
27
  resource_indexes.each do |resource|
28
+ next if [:CLASS].include? resource[:type].type
28
29
  ensure_attr_index = resource[:param_tokens].index { |param_token|
29
30
  param_token.value == 'ensure'
30
31
  }
@@ -87,7 +88,7 @@ PuppetLint.new_check(:unquoted_file_mode) do
87
88
 
88
89
  def check
89
90
  resource_indexes.each do |resource|
90
- if resource[:type].value == "file"
91
+ if resource[:type].value == "file" or resource[:type].value == "concat"
91
92
  resource[:param_tokens].select { |param_token|
92
93
  param_token.value == 'mode' &&
93
94
  TOKEN_TYPES.include?(param_token.next_code_token.next_code_token.type)
@@ -120,7 +121,7 @@ PuppetLint.new_check(:file_mode) do
120
121
 
121
122
  def check
122
123
  resource_indexes.each do |resource|
123
- if resource[:type].value == "file"
124
+ if resource[:type].value == "file" or resource[:type].value == "concat"
124
125
  resource[:param_tokens].select { |param_token|
125
126
  param_token.value == 'mode'
126
127
  }.each do |param_token|
@@ -184,7 +185,7 @@ PuppetLint.new_check(:ensure_not_symlink_target) do
184
185
  PuppetLint::Lexer::Token.new(:NEWLINE, "\n", 0, 0),
185
186
  PuppetLint::Lexer::Token.new(:INDENT, problem[:param_token].prev_token.value.dup, 0, 0),
186
187
  PuppetLint::Lexer::Token.new(:NAME, 'target', 0, 0),
187
- PuppetLint::Lexer::Token.new(:WHITESPACE, problem[:param_token].next_token.value.dup, 0, 0),
188
+ PuppetLint::Lexer::Token.new(:WHITESPACE, ' ', 0, 0),
188
189
  PuppetLint::Lexer::Token.new(:FARROW, '=>', 0, 0),
189
190
  PuppetLint::Lexer::Token.new(:WHITESPACE, ' ', 0, 0),
190
191
  ].reverse.each do |new_token|
@@ -1,13 +1,13 @@
1
1
  # Public: Test the manifest tokens for variables that contain a dash and
2
2
  # record a warning for each instance found.
3
3
  PuppetLint.new_check(:variable_contains_dash) do
4
- VARIABLE_TYPES = Set[:VARIABLE, :UNENC_VARIABLE]
4
+ VARIABLE_DASH_TYPES = Set[:VARIABLE, :UNENC_VARIABLE]
5
5
 
6
6
  def check
7
7
  tokens.select { |r|
8
- VARIABLE_TYPES.include? r.type
8
+ VARIABLE_DASH_TYPES.include? r.type
9
9
  }.each do |token|
10
- if token.value.gsub(/\[.+?\]/, '').match(/-/)
10
+ if not token.next_token.nil? and Set[:DQMID, :DQPOST, :MINUS].include? token.next_token.type and token.next_token.value.start_with? '-'
11
11
  notify :warning, {
12
12
  :message => 'variable contains a dash',
13
13
  :line => token.line,
@@ -17,3 +17,21 @@ PuppetLint.new_check(:variable_contains_dash) do
17
17
  end
18
18
  end
19
19
  end
20
+
21
+ PuppetLint.new_check(:variable_is_lowercase) do
22
+ VARIABLE_LOWERCASE_TYPES = Set[:VARIABLE, :UNENC_VARIABLE]
23
+
24
+ def check
25
+ tokens.select { |r|
26
+ VARIABLE_LOWERCASE_TYPES.include? r.type
27
+ }.each do |token|
28
+ if token.value.gsub(/\[.+?\]/, '').match(/[A-Z]/)
29
+ notify :warning, {
30
+ :message => 'variable contains an uppercase letter',
31
+ :line => token.line,
32
+ :column => token.column,
33
+ }
34
+ end
35
+ end
36
+ end
37
+ end
@@ -68,6 +68,26 @@ PuppetLint.new_check(:'140chars') do
68
68
  end
69
69
  end
70
70
 
71
+ # Public: Test the raw manifest string for lines containing more than 80
72
+ # characters. This is DISABLED by default and behaves like the default
73
+ # 140chars check by excepting URLs and template() calls.
74
+ PuppetLint.new_check(:'80chars') do
75
+ def check
76
+ manifest_lines.each_with_index do |line, idx|
77
+ unless line =~ /:\/\// || line =~ /template\(/
78
+ if line.scan(/./mu).size > 80
79
+ notify :warning, {
80
+ :message => 'line has more than 80 characters',
81
+ :line => idx + 1,
82
+ :column => 80,
83
+ }
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
89
+ PuppetLint.configuration.send("disable_80chars")
90
+
71
91
  # Public: Check the manifest tokens for any indentation not using 2 space soft
72
92
  # tabs and record an error for each instance found.
73
93
  PuppetLint.new_check(:'2sp_soft_tabs') do
@@ -128,7 +148,7 @@ PuppetLint.new_check(:arrow_alignment) do
128
148
  unless arrow_tok.column == indent_depth[indent_depth_idx] || level_tokens[indent_depth_idx].size == 1
129
149
  arrows_on_line = level_tokens[indent_depth_idx].select { |t| t.line == arrow_tok.line }
130
150
  notify :warning, {
131
- :message => 'indentation of => is not properly aligned',
151
+ :message => "indentation of => is not properly aligned (expected in column #{indent_depth[indent_depth_idx]}, but found it in column #{arrow_tok.column})",
132
152
  :line => arrow_tok.line,
133
153
  :column => arrow_tok.column,
134
154
  :token => arrow_tok,
@@ -78,6 +78,10 @@ class PuppetLint
78
78
  linter.file = puppet_file
79
79
  linter.run
80
80
  linter.print_problems
81
+
82
+ if PuppetLint.configuration.fix && !linter.problems.any? { |e| e[:check] == :syntax }
83
+ IO.write(puppet_file, linter.manifest)
84
+ end
81
85
  end
82
86
  abort if linter.errors? || (
83
87
  linter.warnings? && PuppetLint.configuration.fail_on_warnings
@@ -1,3 +1,3 @@
1
1
  class PuppetLint
2
- VERSION = '2.0.0'
2
+ VERSION = '2.0.1'
3
3
  end
@@ -14,10 +14,7 @@ Gem::Specification.new do |s|
14
14
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
15
15
  s.require_paths = ["lib"]
16
16
 
17
- s.add_development_dependency 'rake', '~> 10.0'
18
- s.add_development_dependency 'rspec', '~> 3.0'
19
- s.add_development_dependency 'rspec-its', '~> 1.0'
20
- s.add_development_dependency 'rspec-collection_matchers', '~> 1.0'
17
+ s.add_development_dependency 'github_changelog_generator'
21
18
 
22
19
  s.authors = ['Tim Sharpe']
23
20
  s.email = 'tim@sharpe.id.au'
@@ -99,7 +99,7 @@ describe PuppetLint::Bin do
99
99
 
100
100
  context 'when specifying a specific check to run' do
101
101
  let(:args) { [
102
- '--only-check', 'parameter_order',
102
+ '--only-checks', 'parameter_order',
103
103
  'spec/fixtures/test/manifests/warning.pp',
104
104
  'spec/fixtures/test/manifests/fail.pp',
105
105
  ] }
@@ -579,6 +579,32 @@ describe PuppetLint::Lexer do
579
579
  end
580
580
  end
581
581
 
582
+ context ':TYPE' do
583
+ it 'should match Data Types' do
584
+ token = @lexer.tokenise('Integer').first
585
+ expect(token.type).to eq(:TYPE)
586
+ expect(token.value).to eq('Integer')
587
+ end
588
+
589
+ it 'should match Catalog Types' do
590
+ token = @lexer.tokenise('Resource').first
591
+ expect(token.type).to eq(:TYPE)
592
+ expect(token.value).to eq('Resource')
593
+ end
594
+
595
+ it 'should match Abstract Types' do
596
+ token = @lexer.tokenise('Collection').first
597
+ expect(token.type).to eq(:TYPE)
598
+ expect(token.value).to eq('Collection')
599
+ end
600
+
601
+ it 'should match Platform Types' do
602
+ token = @lexer.tokenise('Callable').first
603
+ expect(token.type).to eq(:TYPE)
604
+ expect(token.value).to eq('Callable')
605
+ end
606
+ end
607
+
582
608
  context ':CLASSREF' do
583
609
  it 'should match single capitalised alphanumeric term' do
584
610
  token = @lexer.tokenise('One').first
@@ -767,6 +793,18 @@ describe PuppetLint::Lexer do
767
793
  expect(token.value).to eq('this is \\/ a regex')
768
794
  end
769
795
 
796
+ it 'should be allowed as a param to a data type' do
797
+ tokens = @lexer.tokenise('Foo[/bar/]')
798
+ expect(tokens[2].type).to eq(:REGEX)
799
+ expect(tokens[2].value).to eq('bar')
800
+ end
801
+
802
+ it 'should be allowed as a param to an optional data type' do
803
+ tokens = @lexer.tokenise('Optional[Regexp[/^puppet/]]')
804
+ expect(tokens[4].type).to eq(:REGEX)
805
+ expect(tokens[4].value).to eq('^puppet')
806
+ end
807
+
770
808
  it 'should not match chained division' do
771
809
  tokens = @lexer.tokenise('$x = $a/$b/$c')
772
810
  expect(tokens.select { |r| r.type == :REGEX }).to be_empty
@@ -3,71 +3,75 @@ require 'spec_helper'
3
3
  describe 'parameter_order' do
4
4
  let(:msg) { 'optional parameter listed before required parameter' }
5
5
 
6
- context 'define with attrs in order' do
7
- let(:code) { "define foo($bar, $baz='gronk') { }" }
6
+ ['define', 'class'].each do |type|
7
+ context "#{type} with attrs in order" do
8
+ let(:code) { "#{type} foo($bar, $baz='gronk') { }" }
8
9
 
9
- it 'should not detect any problems' do
10
- expect(problems).to have(0).problems
10
+ it 'should not detect any problems' do
11
+ expect(problems).to have(0).problems
12
+ end
11
13
  end
12
- end
13
14
 
14
- context 'define with parameter that calls a function' do
15
- let(:code) { "define foo($bar=extlookup($name)) {}" }
15
+ context "#{type} with parameter that calls a function" do
16
+ let(:code) { "#{type} foo($bar=extlookup($name)) {}" }
16
17
 
17
- it 'should not detect any problems' do
18
- expect(problems).to have(0).problems
18
+ it 'should not detect any problems' do
19
+ expect(problems).to have(0).problems
20
+ end
19
21
  end
20
- end
21
22
 
22
- context 'define with attrs out of order' do
23
- let(:code) { "define foo($bar='baz', $gronk) { }" }
23
+ context "#{type} with attrs out of order" do
24
+ let(:code) { "#{type} foo($bar='baz', $gronk) { }" }
24
25
 
25
- it 'should only detect a single problem' do
26
- expect(problems).to have(1).problem
27
- end
26
+ it 'should only detect a single problem' do
27
+ expect(problems).to have(1).problem
28
+ end
28
29
 
29
- it 'should create a warning' do
30
- expect(problems).to contain_warning(msg).on_line(1).in_column(24)
30
+ col = (type == "class" ? 23 : 24)
31
+ it 'should create a warning' do
32
+ expect(problems).to contain_warning(msg).on_line(1).in_column(col)
33
+ end
31
34
  end
32
- end
33
35
 
34
- context 'class/define parameter set to another variable' do
35
- let(:code) { "
36
- define foo($bar, $baz = $name, $gronk=$::fqdn) {
37
- }"
38
- }
36
+ context "#{type} parameter set to another variable" do
37
+ let(:code) { "
38
+ #{type} foo($bar, $baz = $name, $gronk=$::fqdn) {
39
+ }"
40
+ }
39
41
 
40
- it 'should not detect any problems' do
41
- expect(problems).to have(0).problems
42
+ it 'should not detect any problems' do
43
+ expect(problems).to have(0).problems
44
+ end
42
45
  end
43
- end
44
46
 
45
- context 'class/define parameter set to another variable with incorrect order' do
46
- let(:code) { "
47
- define foo($baz = $name, $bar, $gronk=$::fqdn) {
48
- }"
49
- }
47
+ context "#{type} parameter set to another variable with incorrect order" do
48
+ let(:code) { "
49
+ #{type} foo($baz = $name, $bar, $gronk=$::fqdn) {
50
+ }"
51
+ }
50
52
 
51
- it 'should only detect a single problem' do
52
- expect(problems).to have(1).problem
53
- end
53
+ it 'should only detect a single problem' do
54
+ expect(problems).to have(1).problem
55
+ end
54
56
 
55
- it 'should create a warning' do
56
- expect(problems).to contain_warning(msg).on_line(2).in_column(32)
57
+ col = (type == "class" ? 33 : 34)
58
+ it 'should create a warning' do
59
+ expect(problems).to contain_warning(msg).on_line(2).in_column(col)
60
+ end
57
61
  end
58
- end
59
62
 
60
- context 'issue-101' do
61
- let(:code) { "
62
- define b (
63
- $foo,
64
- $bar='',
65
- $baz={}
66
- ) { }
67
- " }
63
+ context 'issue-101' do
64
+ let(:code) { "
65
+ #{type} b (
66
+ $foo,
67
+ $bar='',
68
+ $baz={}
69
+ ) { }
70
+ " }
68
71
 
69
- it 'should not detect any problems' do
70
- expect(problems).to have(0).problems
72
+ it 'should not detect any problems' do
73
+ expect(problems).to have(0).problems
74
+ end
71
75
  end
72
76
  end
73
77
  end