reek 1.2.7.3 → 1.2.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. data/History.txt +17 -0
  2. data/README.md +32 -48
  3. data/config/defaults.reek +7 -1
  4. data/features/api.feature +20 -0
  5. data/features/masking_smells.feature +41 -0
  6. data/features/options.feature +4 -0
  7. data/features/rake_task.feature +14 -0
  8. data/features/yaml.feature +8 -8
  9. data/lib/reek.rb +1 -1
  10. data/lib/reek/cli/command_line.rb +9 -2
  11. data/lib/reek/cli/reek_command.rb +5 -4
  12. data/lib/reek/cli/yaml_command.rb +2 -2
  13. data/lib/reek/core/code_context.rb +10 -1
  14. data/lib/reek/core/method_context.rb +2 -2
  15. data/lib/reek/core/sniffer.rb +3 -1
  16. data/lib/reek/core/stop_context.rb +4 -0
  17. data/lib/reek/examiner.rb +2 -2
  18. data/lib/reek/rake/task.rb +16 -0
  19. data/lib/reek/smell_warning.rb +3 -2
  20. data/lib/reek/smells/attribute.rb +13 -9
  21. data/lib/reek/smells/boolean_parameter.rb +14 -9
  22. data/lib/reek/smells/class_variable.rb +16 -5
  23. data/lib/reek/smells/control_couple.rb +11 -6
  24. data/lib/reek/smells/data_clump.rb +33 -30
  25. data/lib/reek/smells/duplication.rb +39 -8
  26. data/lib/reek/smells/feature_envy.rb +7 -8
  27. data/lib/reek/smells/irresponsible_module.rb +12 -3
  28. data/lib/reek/smells/large_class.rb +31 -15
  29. data/lib/reek/smells/long_method.rb +15 -5
  30. data/lib/reek/smells/long_parameter_list.rb +14 -7
  31. data/lib/reek/smells/long_yield_list.rb +12 -9
  32. data/lib/reek/smells/nested_iterators.rb +46 -11
  33. data/lib/reek/smells/simulated_polymorphism.rb +16 -8
  34. data/lib/reek/smells/smell_detector.rb +13 -13
  35. data/lib/reek/smells/uncommunicative_method_name.rb +12 -20
  36. data/lib/reek/smells/uncommunicative_module_name.rb +17 -19
  37. data/lib/reek/smells/uncommunicative_parameter_name.rb +22 -15
  38. data/lib/reek/smells/uncommunicative_variable_name.rb +24 -18
  39. data/lib/reek/smells/utility_function.rb +6 -6
  40. data/lib/reek/source/code_comment.rb +19 -1
  41. data/lib/reek/source/tree_dresser.rb +40 -22
  42. data/reek.gemspec +6 -4
  43. data/spec/matchers/smell_of_matcher.rb +58 -0
  44. data/spec/reek/core/code_context_spec.rb +4 -2
  45. data/spec/reek/core/code_parser_spec.rb +2 -1
  46. data/spec/reek/core/method_context_spec.rb +5 -5
  47. data/spec/reek/smells/attribute_spec.rb +2 -4
  48. data/spec/reek/smells/boolean_parameter_spec.rb +32 -42
  49. data/spec/reek/smells/class_variable_spec.rb +22 -6
  50. data/spec/reek/smells/control_couple_spec.rb +15 -14
  51. data/spec/reek/smells/data_clump_spec.rb +29 -111
  52. data/spec/reek/smells/duplication_spec.rb +79 -49
  53. data/spec/reek/smells/feature_envy_spec.rb +1 -2
  54. data/spec/reek/smells/irresponsible_module_spec.rb +43 -22
  55. data/spec/reek/smells/large_class_spec.rb +34 -59
  56. data/spec/reek/smells/long_method_spec.rb +15 -10
  57. data/spec/reek/smells/long_parameter_list_spec.rb +24 -24
  58. data/spec/reek/smells/long_yield_list_spec.rb +13 -14
  59. data/spec/reek/smells/nested_iterators_spec.rb +93 -76
  60. data/spec/reek/smells/smell_detector_shared.rb +4 -2
  61. data/spec/reek/smells/uncommunicative_method_name_spec.rb +10 -27
  62. data/spec/reek/smells/uncommunicative_module_name_spec.rb +22 -23
  63. data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +36 -26
  64. data/spec/reek/smells/uncommunicative_variable_name_spec.rb +45 -48
  65. data/spec/reek/smells/utility_function_spec.rb +14 -13
  66. data/spec/reek/source/code_comment_spec.rb +61 -3
  67. data/spec/reek/source/tree_dresser_spec.rb +96 -1
  68. data/spec/samples/config/allow_duplication.reek +3 -0
  69. data/spec/samples/config/deeper_nested_iterators.reek +3 -0
  70. data/spec/samples/demo/demo.rb +8 -0
  71. data/spec/samples/inline_config/dirty.rb +16 -0
  72. data/spec/samples/inline_config/masked.reek +7 -0
  73. data/spec/samples/mask_some/dirty.rb +8 -0
  74. data/spec/samples/mask_some/some.reek +8 -0
  75. data/spec/spec_helper.rb +2 -0
  76. metadata +15 -5
@@ -17,32 +17,48 @@ describe UncommunicativeVariableName do
17
17
 
18
18
  context "field name" do
19
19
  it 'does not report use of one-letter fieldname' do
20
- 'class Thing; def simple(fred) @x end end'.should_not reek_of(:UncommunicativeVariableName, /@x/, /Thing/, /variable name/)
20
+ src = 'class Thing; def simple(fred) @x end end'
21
+ src.should_not smell_of(UncommunicativeVariableName)
21
22
  end
22
23
  it 'reports one-letter fieldname in assignment' do
23
- 'class Thing; def simple(fred) @x = fred end end'.should reek_of(:UncommunicativeVariableName, /@x/, /Thing/, /variable name/)
24
+ src = 'class Thing; def simple(fred) @x = fred end end'
25
+ src.should reek_of(:UncommunicativeVariableName, /@x/, /Thing/, /variable name/)
24
26
  end
25
27
  end
26
28
 
27
29
  context "local variable name" do
28
30
  it 'does not report one-word variable name' do
29
- 'def help(fred) simple = jim(45) end'.should_not reek
31
+ 'def help(fred) simple = jim(45) end'.should_not smell_of(UncommunicativeVariableName)
30
32
  end
31
33
  it 'reports one-letter variable name' do
32
- 'def simple(fred) x = jim(45) end'.should reek_only_of(:UncommunicativeVariableName, /x/, /variable name/)
34
+ src = 'def simple(fred) x = jim(45) end'
35
+ src.should smell_of(UncommunicativeVariableName,
36
+ {UncommunicativeVariableName::VARIABLE_NAME_KEY => 'x'})
33
37
  end
34
38
  it 'reports name of the form "x2"' do
35
- 'def simple(fred) x2 = jim(45) end'.should reek_only_of(:UncommunicativeVariableName, /x2/, /variable name/)
39
+ src = 'def simple(fred) x2 = jim(45) end'
40
+ src.should smell_of(UncommunicativeVariableName,
41
+ {UncommunicativeVariableName::VARIABLE_NAME_KEY => 'x2'})
36
42
  end
37
43
  it 'reports long name ending in a number' do
38
- 'def simple(fred) var123 = jim(45) end'.should reek_only_of(:UncommunicativeVariableName, /var123/, /variable name/)
44
+ @bad_var = 'var123'
45
+ src = "def simple(fred) #{@bad_var} = jim(45) end"
46
+ src.should smell_of(UncommunicativeVariableName,
47
+ {UncommunicativeVariableName::VARIABLE_NAME_KEY => @bad_var})
39
48
  end
40
49
  it 'reports variable name only once' do
41
- 'def simple(fred) x = jim(45); x = y end'.should reek_only_of(:UncommunicativeVariableName, /x/)
50
+ src = 'def simple(fred) x = jim(45); x = y end'
51
+ ctx = CodeContext.new(nil, src.to_reek_source.syntax_tree)
52
+ smells = @detector.examine_context(ctx)
53
+ smells.length.should == 1
54
+ smells[0].subclass.should == UncommunicativeVariableName::SMELL_SUBCLASS
55
+ smells[0].smell[UncommunicativeVariableName::VARIABLE_NAME_KEY].should == 'x'
56
+ smells[0].lines.should == [1,1]
42
57
  end
43
58
  it 'reports a bad name inside a block' do
44
59
  src = 'def clean(text) text.each { q2 = 3 } end'
45
- src.should reek_of(:UncommunicativeVariableName, /q2/)
60
+ src.should smell_of(UncommunicativeVariableName,
61
+ {UncommunicativeVariableName::VARIABLE_NAME_KEY => 'q2'})
46
62
  end
47
63
  it 'reports variable name outside any method' do
48
64
  'class Simple; x = jim(45); end'.should reek_of(:UncommunicativeVariableName, /x/)
@@ -50,9 +66,6 @@ describe UncommunicativeVariableName do
50
66
  end
51
67
 
52
68
  context "block parameter name" do
53
- it "reports parameter's name" do
54
- 'def help() @stuff.each {|x|} end'.should reek_only_of(:UncommunicativeVariableName, /x/, /variable name/)
55
- end
56
69
  it "reports deep block parameter" do
57
70
  src = <<EOS
58
71
  def bad
@@ -61,20 +74,8 @@ describe UncommunicativeVariableName do
61
74
  end
62
75
  end
63
76
  EOS
64
- src.should reek_only_of(:UncommunicativeVariableName, /'x'/)
65
- end
66
- it 'reports all bad block parameters' do
67
- source =<<EOS
68
- class Thing
69
- def bad(fred)
70
- @fred.each {|x| 4 - x }
71
- @jim.each {|y| y - 4 }
72
- end
73
- end
74
- EOS
75
-
76
- source.should reek_of(:UncommunicativeVariableName, /'x'/)
77
- source.should reek_of(:UncommunicativeVariableName, /'y'/)
77
+ src.should smell_of(UncommunicativeVariableName,
78
+ {UncommunicativeVariableName::VARIABLE_NAME_KEY => 'x'})
78
79
  end
79
80
  end
80
81
 
@@ -89,35 +90,31 @@ def bad
89
90
  end
90
91
  end
91
92
  EOS
92
- source = src.to_reek_source
93
- sniffer = Core::Sniffer.new(source)
94
- mctx = Core::CodeParser.new(sniffer).process_defn(source.syntax_tree)
95
- @detector.examine(mctx)
96
- @warning = @detector.smells_found.to_a[0] # SMELL: too cumbersome!
97
- end
98
- it 'reports the source' do
99
- @warning.source.should == @source_name
100
- end
101
- it 'reports the class' do
102
- @warning.smell_class.should == 'UncommunicativeName'
93
+ ctx = CodeContext.new(nil, src.to_reek_source.syntax_tree)
94
+ @smells = @detector.examine_context(ctx)
95
+ @warning = @smells[0]
103
96
  end
104
- it 'reports the subclass' do
105
- @warning.subclass.should == 'UncommunicativeVariableName'
106
- end
107
- it 'reports the variable name' do
97
+
98
+ it_should_behave_like 'common fields set correctly'
99
+
100
+ it 'reports the correct values' do
108
101
  @warning.smell['variable_name'].should == 'x2'
109
- end
110
- it 'reports all line numbers' do
111
102
  @warning.lines.should == [3,5]
112
103
  end
113
104
  end
114
105
 
115
- context "several names" do
116
- it 'should report all bad names' do
117
- ruby = 'class Oof; def y(x) @z = x end end'
118
- ruby.should reek_of(:UncommunicativeParameterName, /'x'/)
119
- ruby.should reek_of(:UncommunicativeMethodName, /'y'/)
120
- ruby.should reek_of(:UncommunicativeVariableName, /'@z'/)
106
+ context 'when a smell is reported in a singleton method' do
107
+ before :each do
108
+ src = 'def self.bad() x2 = 4; end'
109
+ ctx = CodeContext.new(nil, src.to_reek_source.syntax_tree)
110
+ @smells = @detector.examine_context(ctx)
111
+ @warning = @smells[0]
112
+ end
113
+
114
+ it_should_behave_like 'common fields set correctly'
115
+
116
+ it 'reports the fq context' do
117
+ @warning.context.should == 'self.bad'
121
118
  end
122
119
  end
123
120
  end
@@ -6,16 +6,27 @@ include Reek
6
6
  include Reek::Smells
7
7
 
8
8
  describe UtilityFunction do
9
+ before(:each) do
10
+ @source_name = 'loser'
11
+ @detector = UtilityFunction.new(@source_name)
12
+ end
13
+
14
+ it_should_behave_like 'SmellDetector'
15
+
9
16
  context 'with a singleton method' do
10
17
  ['self', 'local_call', '$global'].each do |receiver|
11
18
  it 'ignores the receiver' do
12
- "def #{receiver}.simple(arga) arga.to_s + arga.to_i end".should_not reek
19
+ src = "def #{receiver}.simple(arga) arga.to_s + arga.to_i end"
20
+ ctx = MethodContext.new(nil, src.to_reek_source.syntax_tree)
21
+ @detector.examine_context(ctx).should be_empty
13
22
  end
14
23
  end
15
24
  end
16
25
  context 'with no calls' do
17
26
  it 'does not report empty method' do
18
- 'def simple(arga) end'.should_not reek
27
+ src = 'def simple(arga) end'
28
+ ctx = MethodContext.new(nil, src.to_reek_source.syntax_tree)
29
+ @detector.examine_context(ctx).should be_empty
19
30
  end
20
31
  it 'does not report literal' do
21
32
  'def simple(arga) 3; end'.should_not reek
@@ -87,15 +98,6 @@ EOS
87
98
  src.should_not reek
88
99
  end
89
100
  end
90
- end
91
-
92
- describe UtilityFunction do
93
- before(:each) do
94
- @source_name = 'loser'
95
- @detector = UtilityFunction.new(@source_name)
96
- end
97
-
98
- it_should_behave_like 'SmellDetector'
99
101
 
100
102
  context 'when a smells is reported' do
101
103
  before :each do
@@ -107,8 +109,7 @@ EOS
107
109
  source = src.to_reek_source
108
110
  sniffer = Sniffer.new(source)
109
111
  mctx = CodeParser.new(sniffer).process_defn(source.syntax_tree)
110
- @detector.examine_context(mctx)
111
- @warning = @detector.smells_found.to_a[0] # SMELL: too cumbersome!
112
+ @warning = @detector.examine_context(mctx)[0] # SMELL: too cumbersome!
112
113
  end
113
114
 
114
115
  it_should_behave_like 'common fields set correctly'
@@ -4,10 +4,19 @@ require File.join(File.dirname(File.dirname(File.dirname(File.dirname(File.expan
4
4
  include Reek::Source
5
5
 
6
6
  describe CodeComment do
7
- context 'comment checks' do
8
- it 'rejects no comment' do
9
- CodeComment.new('').is_descriptive?.should be_false
7
+ context 'with an empty comment' do
8
+ before :each do
9
+ @comment = CodeComment.new('')
10
+ end
11
+ it 'is not descriptive' do
12
+ @comment.is_descriptive?.should be_false
10
13
  end
14
+ it 'has an empty config' do
15
+ @comment.config.should be_empty
16
+ end
17
+ end
18
+
19
+ context 'comment checks' do
11
20
  it 'rejects an empty comment' do
12
21
  CodeComment.new('#').is_descriptive?.should be_false
13
22
  end
@@ -21,4 +30,53 @@ describe CodeComment do
21
30
  CodeComment.new("# fred here \n# with \n # biscuits ").is_descriptive?.should be_true
22
31
  end
23
32
  end
33
+
34
+ context 'comment config' do
35
+ it 'parses hashed options' do
36
+ config = CodeComment.new("# :reek:Duplication: { enabled: false }").config
37
+ config.should include('Duplication')
38
+ config['Duplication'].should include('enabled')
39
+ config['Duplication']['enabled'].should be_false
40
+ end
41
+ it 'parses hashed options with ruby names' do
42
+ config = CodeComment.new("# :reek:nested_iterators: { enabled: true }").config
43
+ config.should include('NestedIterators')
44
+ config['NestedIterators'].should include('enabled')
45
+ config['NestedIterators']['enabled'].should be_true
46
+ end
47
+ it 'parses multiple hashed options' do
48
+ config = CodeComment.new("# :reek:Duplication: { enabled: false }\n:reek:nested_iterators: { enabled: true }").config
49
+ config.should include('Duplication','NestedIterators')
50
+ config['Duplication'].should include('enabled')
51
+ config['Duplication']['enabled'].should be_false
52
+ config['NestedIterators'].should include('enabled')
53
+ config['NestedIterators']['enabled'].should be_true
54
+ end
55
+ it 'parses multiple hashed options on the same line' do
56
+ config = CodeComment.new("# :reek:Duplication: { enabled: false } and :reek:nested_iterators: { enabled: true }").config
57
+ config.should include('Duplication','NestedIterators')
58
+ config['Duplication'].should include('enabled')
59
+ config['Duplication']['enabled'].should be_false
60
+ config['NestedIterators'].should include('enabled')
61
+ config['NestedIterators']['enabled'].should be_true
62
+ end
63
+ it 'parses multiple unhashed options on the same line' do
64
+ config = CodeComment.new("# :reek:Duplication and :reek:nested_iterators").config
65
+ config.should include('Duplication','NestedIterators')
66
+ config['Duplication'].should include('enabled')
67
+ config['Duplication']['enabled'].should be_false
68
+ config['NestedIterators'].should include('enabled')
69
+ config['NestedIterators']['enabled'].should be_false
70
+ end
71
+ it 'disables the smell if no options are specifed' do
72
+ config = CodeComment.new("# :reek:Duplication").config
73
+ config.should include('Duplication')
74
+ config['Duplication'].should include('enabled')
75
+ config['Duplication']['enabled'].should be_false
76
+ end
77
+ it 'ignores smells after a space' do
78
+ config = CodeComment.new("# :reek: Duplication").config
79
+ config.should_not include('Duplication')
80
+ end
81
+ end
24
82
  end
@@ -20,7 +20,20 @@ describe SexpNode do
20
20
  it 'formats self' do
21
21
  @node = s(:self)
22
22
  @node.extend(SexpNode)
23
- @node.format.should == 'self'
23
+ @node.format_ruby.should == 'self'
24
+ end
25
+ end
26
+
27
+ context 'hash' do
28
+ it 'hashes equal for equal sexps' do
29
+ node1 = ast(:defn, s(:const2, :Fred, :jim), s(:call, :+, s(:lit, 4), :fred))
30
+ node2 = ast(:defn, s(:const2, :Fred, :jim), s(:call, :+, s(:lit, 4), :fred))
31
+ node1.hash.should == node2.hash
32
+ end
33
+ it 'hashes diferent for diferent sexps' do
34
+ node1 = ast(:defn, s(:const2, :Fred, :jim), s(:call, :+, s(:lit, 4), :fred))
35
+ node2 = ast(:defn, s(:const2, :Fred, :jim), s(:call, :+, s(:lit, 3), :fred))
36
+ node1.hash.should_not == node2.hash
24
37
  end
25
38
  end
26
39
  end
@@ -37,6 +50,12 @@ describe SexpExtensions::DefnNode do
37
50
  it 'has no parameter names' do
38
51
  @node.parameter_names.should == s()
39
52
  end
53
+ it 'includes outer scope in its full name' do
54
+ @node.full_name('Fred').should == 'Fred#hello'
55
+ end
56
+ it 'includes no marker in its full name with empty outer scope' do
57
+ @node.full_name('').should == 'hello'
58
+ end
40
59
  end
41
60
 
42
61
  context 'with 1 parameter' do
@@ -50,6 +69,12 @@ describe SexpExtensions::DefnNode do
50
69
  it 'has 1 parameter name' do
51
70
  @node.parameter_names.should == s(:param)
52
71
  end
72
+ it 'includes outer scope in its full name' do
73
+ @node.full_name('Fred').should == 'Fred#hello'
74
+ end
75
+ it 'includes no marker in its full name with empty outer scope' do
76
+ @node.full_name('').should == 'hello'
77
+ end
53
78
  end
54
79
 
55
80
  context 'with a block' do
@@ -63,6 +88,12 @@ describe SexpExtensions::DefnNode do
63
88
  it 'has 1 parameter name' do
64
89
  @node.parameter_names.should == s(:param, :"&blk")
65
90
  end
91
+ it 'includes outer scope in its full name' do
92
+ @node.full_name('Fred').should == 'Fred#hello'
93
+ end
94
+ it 'includes no marker in its full name with empty outer scope' do
95
+ @node.full_name('').should == 'hello'
96
+ end
66
97
  end
67
98
 
68
99
  context 'with 1 defaulted parameter' do
@@ -76,6 +107,12 @@ describe SexpExtensions::DefnNode do
76
107
  it 'has 1 parameter name' do
77
108
  @node.parameter_names.should == s(:param)
78
109
  end
110
+ it 'includes outer scope in its full name' do
111
+ @node.full_name('Fred').should == 'Fred#hello'
112
+ end
113
+ it 'includes no marker in its full name with empty outer scope' do
114
+ @node.full_name('').should == 'hello'
115
+ end
79
116
  end
80
117
  end
81
118
 
@@ -91,6 +128,12 @@ describe SexpExtensions::DefsNode do
91
128
  it 'has no parameter names' do
92
129
  @node.parameter_names.should == s()
93
130
  end
131
+ it 'includes outer scope in its full name' do
132
+ @node.full_name('Fred').should == 'Fred#obj.hello'
133
+ end
134
+ it 'includes no marker in its full name with empty outer scope' do
135
+ @node.full_name('').should == 'obj.hello'
136
+ end
94
137
  end
95
138
 
96
139
  context 'with 1 parameter' do
@@ -104,6 +147,12 @@ describe SexpExtensions::DefsNode do
104
147
  it 'has 1 parameter name' do
105
148
  @node.parameter_names.should == s(:param)
106
149
  end
150
+ it 'includes outer scope in its full name' do
151
+ @node.full_name('Fred').should == 'Fred#obj.hello'
152
+ end
153
+ it 'includes no marker in its full name with empty outer scope' do
154
+ @node.full_name('').should == 'obj.hello'
155
+ end
107
156
  end
108
157
 
109
158
  context 'with a block' do
@@ -117,6 +166,12 @@ describe SexpExtensions::DefsNode do
117
166
  it 'has 1 parameter name' do
118
167
  @node.parameter_names.should == s(:param, :"&blk")
119
168
  end
169
+ it 'includes outer scope in its full name' do
170
+ @node.full_name('Fred').should == 'Fred#obj.hello'
171
+ end
172
+ it 'includes no marker in its full name with empty outer scope' do
173
+ @node.full_name('').should == 'obj.hello'
174
+ end
120
175
  end
121
176
 
122
177
  context 'with 1 defaulted parameter' do
@@ -130,6 +185,12 @@ describe SexpExtensions::DefsNode do
130
185
  it 'has 1 parameter name' do
131
186
  @node.parameter_names.should == s(:param)
132
187
  end
188
+ it 'includes outer scope in its full name' do
189
+ @node.full_name('Fred').should == 'Fred#obj.hello'
190
+ end
191
+ it 'includes no marker in its full name with empty outer scope' do
192
+ @node.full_name('').should == 'obj.hello'
193
+ end
133
194
  end
134
195
  end
135
196
 
@@ -173,3 +234,37 @@ describe SexpExtensions::IterNode do
173
234
  end
174
235
  end
175
236
  end
237
+
238
+ describe SexpExtensions::ModuleNode do
239
+ context 'with a simple name' do
240
+ subject do
241
+ mod = ast(:module, :Fred, nil)
242
+ mod
243
+ end
244
+ its(:name) { should == :Fred }
245
+ its(:simple_name) { should == :Fred }
246
+ its(:text_name) { should == 'Fred' }
247
+ it 'has a simple full_name' do
248
+ subject.full_name('').should == 'Fred'
249
+ end
250
+ it 'has a fq full_name' do
251
+ subject.full_name('Blimey::O::Reilly').should == 'Blimey::O::Reilly::Fred'
252
+ end
253
+ end
254
+
255
+ context 'with a scoped name' do
256
+ subject do
257
+ mod = ast(:module, s(:colon2, s(:const, :Foo), :Bar), nil)
258
+ mod
259
+ end
260
+ its(:name) { should == s(:colon2, s(:const, :Foo), :Bar) }
261
+ its(:simple_name) { should == :Bar }
262
+ its(:text_name) { should == 'Foo::Bar' }
263
+ it 'has a simple full_name' do
264
+ subject.full_name('').should == 'Foo::Bar'
265
+ end
266
+ it 'has a fq full_name' do
267
+ subject.full_name('Blimey::O::Reilly').should == 'Blimey::O::Reilly::Foo::Bar'
268
+ end
269
+ end
270
+ end
@@ -0,0 +1,3 @@
1
+ ---
2
+ Duplication:
3
+ enabled: false
@@ -0,0 +1,3 @@
1
+ ---
2
+ NestedIterators:
3
+ max_allowed_nesting: 3
@@ -0,0 +1,8 @@
1
+ class Dirty
2
+ # This method smells of :reek:NestedIterators but ignores them
3
+ def awful(x, y, offset = 0, log = false)
4
+ puts @screen.title
5
+ @screen = widgets.map {|w| w.each {|key| key += 3}}
6
+ puts @screen.contents
7
+ end
8
+ end