reek 4.4.0 → 4.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -0
  3. data/CONTRIBUTING.md +41 -4
  4. data/README.md +15 -3
  5. data/defaults.reek +1 -1
  6. data/docs/Basic-Smell-Options.md +2 -2
  7. data/docs/Code-Smells.md +4 -0
  8. data/docs/How-To-Write-New-Detectors.md +116 -0
  9. data/docs/How-reek-works-internally.md +3 -4
  10. data/docs/Instance-Variable-Assumption.md +134 -0
  11. data/docs/Simulated-Polymorphism.md +1 -1
  12. data/docs/Smell-Suppression.md +6 -6
  13. data/docs/{style-guide.md → Style-Guide.md} +0 -0
  14. data/docs/Unused-Private-Method.md +1 -1
  15. data/docs/YAML-Reports.md +0 -18
  16. data/features/configuration_files/directory_specific_directives.feature +4 -4
  17. data/features/configuration_files/unused_private_method.feature +2 -2
  18. data/features/samples.feature +122 -117
  19. data/features/smells/subclassed_from_core_class.feature +1 -1
  20. data/lib/reek/code_comment.rb +13 -4
  21. data/lib/reek/context/code_context.rb +1 -0
  22. data/lib/reek/examiner.rb +24 -27
  23. data/lib/reek/smells/class_variable.rb +1 -1
  24. data/lib/reek/smells/control_parameter.rb +1 -1
  25. data/lib/reek/smells/data_clump.rb +1 -1
  26. data/lib/reek/smells/duplicate_method_call.rb +1 -1
  27. data/lib/reek/smells/feature_envy.rb +1 -1
  28. data/lib/reek/smells/instance_variable_assumption.rb +1 -1
  29. data/lib/reek/smells/prima_donna_method.rb +1 -1
  30. data/lib/reek/smells/repeated_conditional.rb +1 -1
  31. data/lib/reek/smells/smell_detector.rb +5 -14
  32. data/lib/reek/smells/smell_repository.rb +1 -5
  33. data/lib/reek/smells/smell_warning.rb +6 -8
  34. data/lib/reek/smells/subclassed_from_core_class.rb +1 -1
  35. data/lib/reek/smells/uncommunicative_variable_name.rb +22 -12
  36. data/lib/reek/smells/unused_private_method.rb +1 -1
  37. data/lib/reek/spec.rb +2 -2
  38. data/lib/reek/spec/should_reek_of.rb +12 -8
  39. data/lib/reek/version.rb +1 -1
  40. data/spec/reek/code_comment_spec.rb +13 -5
  41. data/spec/reek/examiner_spec.rb +2 -2
  42. data/spec/reek/smells/attribute_spec.rb +91 -78
  43. data/spec/reek/smells/boolean_parameter_spec.rb +72 -64
  44. data/spec/reek/smells/class_variable_spec.rb +81 -68
  45. data/spec/reek/smells/control_parameter_spec.rb +101 -141
  46. data/spec/reek/smells/data_clump_spec.rb +94 -149
  47. data/spec/reek/smells/duplicate_method_call_spec.rb +98 -85
  48. data/spec/reek/smells/feature_envy_spec.rb +164 -183
  49. data/spec/reek/smells/instance_variable_assumption_spec.rb +51 -147
  50. data/spec/reek/smells/irresponsible_module_spec.rb +153 -170
  51. data/spec/reek/smells/long_parameter_list_spec.rb +44 -88
  52. data/spec/reek/smells/long_yield_list_spec.rb +41 -41
  53. data/spec/reek/smells/manual_dispatch_spec.rb +36 -18
  54. data/spec/reek/smells/module_initialize_spec.rb +31 -33
  55. data/spec/reek/smells/nested_iterators_spec.rb +189 -183
  56. data/spec/reek/smells/nil_check_spec.rb +48 -37
  57. data/spec/reek/smells/prima_donna_method_spec.rb +41 -26
  58. data/spec/reek/smells/repeated_conditional_spec.rb +75 -87
  59. data/spec/reek/smells/smell_warning_spec.rb +7 -0
  60. data/spec/reek/smells/subclassed_from_core_class_spec.rb +37 -112
  61. data/spec/reek/smells/too_many_constants_spec.rb +109 -199
  62. data/spec/reek/smells/too_many_instance_variables_spec.rb +105 -128
  63. data/spec/reek/smells/too_many_methods_spec.rb +38 -62
  64. data/spec/reek/smells/too_many_statements_spec.rb +69 -45
  65. data/spec/reek/smells/uncommunicative_method_name_spec.rb +16 -29
  66. data/spec/reek/smells/uncommunicative_module_name_spec.rb +24 -37
  67. data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +55 -60
  68. data/spec/reek/smells/uncommunicative_variable_name_spec.rb +108 -95
  69. data/spec/reek/smells/unused_parameters_spec.rb +73 -49
  70. data/spec/reek/smells/unused_private_method_spec.rb +97 -50
  71. data/spec/reek/smells/utility_function_spec.rb +130 -188
  72. data/spec/reek/spec/should_reek_of_spec.rb +2 -2
  73. metadata +6 -7
  74. data/lib/reek/cli/warning_collector.rb +0 -27
  75. data/spec/reek/cli/warning_collector_spec.rb +0 -25
  76. data/spec/reek/smells/smell_detector_shared.rb +0 -29
@@ -1,178 +1,123 @@
1
1
  require_relative '../../spec_helper'
2
2
  require_lib 'reek/smells/data_clump'
3
- require_relative 'smell_detector_shared'
4
3
 
5
- RSpec.shared_examples_for 'a data clump detector' do
6
- it 'does not report small parameter sets' do
4
+ RSpec.describe Reek::Smells::DataClump do
5
+ it 'reports the right values' do
7
6
  src = <<-EOS
8
- # test module
9
- #{context} Scrunch
10
- def first(pa) @field == :sym ? 0 : 3; end
11
- def second(pa) @field == :sym; end
12
- def third(pa) pa - pb + @fred; end
7
+ class Alfa
8
+ def bravo (echo, foxtrot); end
9
+ def charlie(echo, foxtrot); end
10
+ def delta (echo, foxtrot); end
13
11
  end
14
12
  EOS
15
- expect(src).not_to reek_of(:DataClump)
16
- end
17
-
18
- context 'with 3 identical pairs' do
19
- let(:module_name) { 'Scrunch' }
20
- let(:smells) do
21
- src = <<-EOS
22
- #{context} #{module_name}
23
- def first(pa, pb) @field == :sym ? 0 : 3; end
24
- def second(pa, pb) @field == :sym; end
25
- def third(pa, pb) pa - pb + @fred; end
26
- end
27
- EOS
28
- ctx = Reek::Context::ModuleContext.new(nil, Reek::Source::SourceCode.from(src).syntax_tree)
29
- build(:smell_detector, smell_type: :DataClump).sniff(ctx)
30
- end
31
-
32
- it 'records only the one smell' do
33
- expect(smells.length).to eq(1)
34
- end
35
-
36
- it 'reports all parameters' do
37
- expect(smells[0].parameters[:parameters]).to eq(['pa', 'pb'])
38
- end
39
13
 
40
- it 'reports the number of occurrences' do
41
- expect(smells[0].parameters[:count]).to eq(3)
42
- end
43
-
44
- it 'reports the declaration line numbers' do
45
- expect(smells[0].lines).to eq([2, 3, 4])
46
- end
47
-
48
- it 'reports the correct smell type' do
49
- expect(smells[0].smell_type).to eq(Reek::Smells::DataClump.smell_type)
50
- end
51
-
52
- it 'reports the context fq name' do
53
- expect(smells[0].context).to eq(module_name)
54
- end
55
-
56
- it 'has the right message' do
57
- expect(smells[0].message).to eq('takes parameters [pa, pb] to 3 methods')
58
- end
59
- end
60
-
61
- it 'reports 3 swapped pairs' do
62
- src = <<-EOS
63
- #{context} Scrunch
64
- def one(pa, pb) @field == :sym ? 0 : 3; end
65
- def two(pb, pa) @field == :sym; end
66
- def tri(pa, pb) pa - pb + @fred; end
67
- end
68
- EOS
69
14
  expect(src).to reek_of(:DataClump,
70
- count: 3,
71
- parameters: ['pa', 'pb'])
15
+ lines: [2, 3, 4],
16
+ context: 'Alfa',
17
+ message: "takes parameters ['echo', 'foxtrot'] to 3 methods",
18
+ source: 'string',
19
+ parameters: ['echo', 'foxtrot'],
20
+ count: 3)
72
21
  end
73
22
 
74
- it 'reports 3 identical parameter sets' do
23
+ it 'does count all occurences' do
75
24
  src = <<-EOS
76
- #{context} Scrunch
77
- def first(pa, pb, pc) @field == :sym ? 0 : 3; end
78
- def second(pa, pb, pc) @field == :sym; end
79
- def third(pa, pb, pc) pa - pb + @fred; end
25
+ class Alfa
26
+ def bravo (echo, foxtrot); end
27
+ def charlie(echo, foxtrot); end
28
+ def delta (echo, foxtrot); end
29
+
30
+ def golf (juliett, kilo); end
31
+ def hotel(juliett, kilo); end
32
+ def india(juliett, kilo); end
80
33
  end
81
34
  EOS
82
- expect(src).to reek_of(:DataClump,
83
- count: 3,
84
- parameters: ['pa', 'pb', 'pc'])
85
- end
86
35
 
87
- it 'reports re-ordered identical parameter sets' do
88
- src = <<-EOS
89
- #{context} Scrunch
90
- def first(pb, pa, pc) @field == :sym ? 0 : 3; end
91
- def second(pc, pb, pa) @field == :sym; end
92
- def third(pa, pb, pc) pa - pb + @fred; end
93
- end
94
- EOS
95
36
  expect(src).to reek_of(:DataClump,
96
- count: 3,
97
- parameters: ['pa', 'pb', 'pc'])
37
+ lines: [2, 3, 4],
38
+ parameters: ['echo', 'foxtrot'])
39
+ expect(src).to reek_of(:DataClump,
40
+ lines: [6, 7, 8],
41
+ parameters: ['juliett', 'kilo'])
98
42
  end
99
43
 
100
- it 'counts only identical parameter sets' do
101
- src = <<-EOS
102
- #{context} RedCloth
103
- def fa(p1, p2, p3, conten) end
104
- def fb(p1, p2, p3, conten) end
105
- def fc(name, windowW, windowH) end
106
- end
107
- EOS
108
- expect(src).not_to reek_of(:DataClump)
109
- end
44
+ %w(class module).each do |scope|
45
+ it "does not report parameter sets < 2 for #{scope}" do
46
+ src = <<-EOS
47
+ #{scope} Alfa
48
+ def bravo (echo); end
49
+ def charlie(echo); end
50
+ def delta (echo); end
51
+ end
52
+ EOS
110
53
 
111
- it 'gets a real example right' do
112
- src = <<-EOS
113
- #{context} Inline
114
- def generate(src, options) end
115
- def c (src, options) end
116
- def c_singleton (src, options) end
117
- def c_raw (src, options) end
118
- def c_raw_singleton (src, options) end
119
- end
120
- EOS
121
- expect(src).to reek_of(:DataClump, count: 5)
122
- end
54
+ expect(src).not_to reek_of(:DataClump)
55
+ end
123
56
 
124
- it 'correctly checks number of occurences' do
125
- src = <<-EOS
126
- #{context} Smelly
127
- def fa(p1, p2, p3) end
128
- def fb(p2, p3, p4) end
129
- def fc(p3, p4, p5) end
130
- def fd(p4, p5, p1) end
131
- def fe(p5, p1, p2) end
132
- end
133
- EOS
134
- expect(src).not_to reek_of(:DataClump)
135
- end
57
+ it "does not report less than 3 methods for #{scope}" do
58
+ src = <<-EOS
59
+ #{scope} Alfa
60
+ def bravo (echo, foxtrot); end
61
+ def charlie(echo, foxtrot); end
62
+ end
63
+ EOS
136
64
 
137
- it 'detects clumps smaller than the total number of arguments' do
138
- src = <<-EOS
139
- #{context} Smelly
140
- def fa(p1, p2, p3) end
141
- def fb(p1, p3, p2) end
142
- def fc(p4, p1, p2) end
143
- end
144
- EOS
145
- expect(src).to reek_of(:DataClump,
146
- parameters: %w(p1 p2))
147
- end
65
+ expect(src).not_to reek_of(:DataClump)
66
+ end
148
67
 
149
- it 'ignores anonymous parameters' do
150
- src = <<-EOS
151
- #{context} Smelly
152
- def fa(p1, p2, *) end
153
- def fb(p1, p2, *) end
154
- def fc(p1, p2, *) end
155
- end
156
- EOS
157
- expect(src).to reek_of(:DataClump,
158
- parameters: %w(p1 p2))
159
- end
160
- end
68
+ it 'does not care about the order of arguments' do
69
+ src = <<-EOS
70
+ #{scope} Alfa
71
+ def bravo (echo, foxtrot); end
72
+ def charlie(foxtrot, echo); end # <- This is the swapped one!
73
+ def delta (echo, foxtrot); end
74
+ end
75
+ EOS
161
76
 
162
- RSpec.describe Reek::Smells::DataClump do
163
- let(:detector) { build(:smell_detector, smell_type: :DataClump) }
77
+ expect(src).to reek_of(:DataClump,
78
+ count: 3,
79
+ parameters: ['echo', 'foxtrot'])
80
+ end
81
+
82
+ it 'reports parameter sets that are > 2' do
83
+ src = <<-EOS
84
+ #{scope} Alfa
85
+ def bravo (echo, foxtrot, golf); end
86
+ def charlie(echo, foxtrot, golf); end
87
+ def delta (echo, foxtrot, golf); end
88
+ end
89
+ EOS
164
90
 
165
- it_should_behave_like 'SmellDetector'
91
+ expect(src).to reek_of(:DataClump,
92
+ count: 3,
93
+ parameters: ['echo', 'foxtrot', 'golf'])
94
+ end
166
95
 
167
- context 'in a class' do
168
- let(:context) { 'class' }
96
+ it 'detects clumps smaller than the total number of parameters' do
97
+ src = <<-EOS
98
+ # Total number of parameters is 3 but the clump size is 2.
99
+ #{scope} Alfa
100
+ def bravo (echo, foxtrot, golf); end
101
+ def charlie(echo, golf, foxtrot); end
102
+ def delta (hotel, echo, foxtrot); end
103
+ end
104
+ EOS
169
105
 
170
- it_should_behave_like 'a data clump detector'
171
- end
106
+ expect(src).to reek_of(:DataClump,
107
+ parameters: ['echo', 'foxtrot'])
108
+ end
172
109
 
173
- context 'in a module' do
174
- let(:context) { 'module' }
110
+ it 'ignores anonymous parameters' do
111
+ src = <<-EOS
112
+ #{scope} Alfa
113
+ def bravo (echo, foxtrot, *); end
114
+ def charlie(echo, foxtrot, *); end
115
+ def delta (echo, foxtrot, *); end
116
+ end
117
+ EOS
175
118
 
176
- it_should_behave_like 'a data clump detector'
119
+ expect(src).to reek_of(:DataClump,
120
+ parameters: ['echo', 'foxtrot'])
121
+ end
177
122
  end
178
123
  end
@@ -1,63 +1,70 @@
1
1
  require_relative '../../spec_helper'
2
2
  require_lib 'reek/smells/duplicate_method_call'
3
- require_lib 'reek/context/code_context'
4
- require_lib 'reek/context_builder'
5
- require_relative 'smell_detector_shared'
6
3
 
7
4
  RSpec.describe Reek::Smells::DuplicateMethodCall do
8
- context 'when a smell is reported' do
9
- let(:detector) { build(:smell_detector, smell_type: :DuplicateMethodCall) }
10
-
11
- let(:warning) do
12
- src = <<-EOS
13
- def double_thing(other)
14
- other[@thing]
15
- not_the_sam(at = all)
16
- other[@thing]
5
+ it 'reports the right values' do
6
+ src = <<-EOS
7
+ class Alfa
8
+ def bravo(charlie)
9
+ charlie.delta
10
+ charlie.delta
17
11
  end
18
- EOS
19
- ctx = Reek::Context::CodeContext.new(nil, Reek::Source::SourceCode.from(src).syntax_tree)
20
- smells = detector.sniff(ctx)
21
- expect(smells.length).to eq(1)
22
- smells.first
23
- end
24
-
25
- it_should_behave_like 'SmellDetector'
26
- it_should_behave_like 'common fields set correctly'
12
+ end
13
+ EOS
14
+
15
+ expect(src).to reek_of(:DuplicateMethodCall,
16
+ lines: [3, 4],
17
+ context: 'Alfa#bravo',
18
+ message: "calls 'charlie.delta' 2 times",
19
+ source: 'string',
20
+ name: 'charlie.delta',
21
+ count: 2)
22
+ end
27
23
 
28
- it 'reports the call' do
29
- expect(warning.parameters[:name]).to eq('other[@thing]')
30
- end
24
+ it 'does count all occurences' do
25
+ src = <<-EOS
26
+ class Alfa
27
+ def bravo(charlie)
28
+ charlie.delta
29
+ charlie.delta
30
+ end
31
31
 
32
- it 'reports the correct lines' do
33
- expect(warning.lines).to eq([2, 4])
34
- end
32
+ def echo(foxtrot)
33
+ foxtrot.golf
34
+ foxtrot.golf
35
+ end
36
+ end
37
+ EOS
38
+
39
+ expect(src).to reek_of(:DuplicateMethodCall,
40
+ lines: [3, 4],
41
+ name: 'charlie.delta',
42
+ count: 2)
43
+ expect(src).to reek_of(:DuplicateMethodCall,
44
+ lines: [8, 9],
45
+ name: 'foxtrot.golf',
46
+ count: 2)
35
47
  end
36
48
 
37
49
  context 'with repeated method calls' do
38
- it 'reports repeated call' do
39
- src = 'def double_thing() @other.thing + @other.thing end'
40
- expect(src).to reek_of(:DuplicateMethodCall, name: '@other.thing')
41
- end
42
-
43
50
  it 'reports repeated call to lvar' do
44
- src = 'def double_thing(other) other[@thing] + other[@thing] end'
45
- expect(src).to reek_of(:DuplicateMethodCall, name: 'other[@thing]')
51
+ src = 'def alfa(bravo); bravo.charlie + bravo.charlie; end'
52
+ expect(src).to reek_of(:DuplicateMethodCall, name: 'bravo.charlie')
46
53
  end
47
54
 
48
55
  it 'reports call parameters' do
49
- src = 'def double_thing() @other.thing(2,3) + @other.thing(2,3) end'
50
- expect(src).to reek_of(:DuplicateMethodCall, name: '@other.thing(2,3)')
56
+ src = 'def alfa; @bravo.charlie(2, 3) + @bravo.charlie(2, 3); end'
57
+ expect(src).to reek_of(:DuplicateMethodCall, name: '@bravo.charlie(2, 3)')
51
58
  end
52
59
 
53
60
  it 'should report nested calls' do
54
- src = 'def double_thing() @other.thing.foo + @other.thing.foo end'
55
- expect(src).to reek_of(:DuplicateMethodCall, name: '@other.thing')
56
- expect(src).to reek_of(:DuplicateMethodCall, name: '@other.thing.foo')
61
+ src = 'def alfa; @bravo.charlie.delta + @bravo.charlie.delta; end'
62
+ expect(src).to reek_of(:DuplicateMethodCall, name: '@bravo.charlie')
63
+ expect(src).to reek_of(:DuplicateMethodCall, name: '@bravo.charlie.delta')
57
64
  end
58
65
 
59
66
  it 'should ignore calls to new' do
60
- src = 'def double_thing() @other.new + @other.new end'
67
+ src = 'def alfa; @bravo.new + @bravo.new; end'
61
68
  expect(src).not_to reek_of(:DuplicateMethodCall)
62
69
  end
63
70
  end
@@ -65,15 +72,12 @@ RSpec.describe Reek::Smells::DuplicateMethodCall do
65
72
  context 'with repeated simple method calls' do
66
73
  it 'reports no smell' do
67
74
  src = <<-EOS
68
- def foo
69
- case bar
70
- when :baz
71
- :qux
72
- else
73
- bar
74
- end
75
+ def alfa
76
+ bravo
77
+ bravo
75
78
  end
76
79
  EOS
80
+
77
81
  expect(src).not_to reek_of(:DuplicateMethodCall)
78
82
  end
79
83
  end
@@ -81,21 +85,23 @@ RSpec.describe Reek::Smells::DuplicateMethodCall do
81
85
  context 'with repeated simple method calls with blocks' do
82
86
  it 'reports a smell if the blocks are identical' do
83
87
  src = <<-EOS
84
- def foo
85
- bar { baz }
86
- bar { baz }
88
+ def alfa
89
+ bravo { charlie }
90
+ bravo { charlie }
87
91
  end
88
92
  EOS
93
+
89
94
  expect(src).to reek_of(:DuplicateMethodCall)
90
95
  end
91
96
 
92
97
  it 'reports no smell if the blocks are different' do
93
98
  src = <<-EOS
94
- def foo
95
- bar { baz }
96
- bar { qux }
99
+ def alfa
100
+ bravo { charlie }
101
+ bravo { delta }
97
102
  end
98
103
  EOS
104
+
99
105
  expect(src).not_to reek_of(:DuplicateMethodCall)
100
106
  end
101
107
  end
@@ -103,49 +109,59 @@ RSpec.describe Reek::Smells::DuplicateMethodCall do
103
109
  context 'with repeated method calls with receivers with blocks' do
104
110
  it 'reports a smell if the blocks are identical' do
105
111
  src = <<-EOS
106
- def foo
107
- bar.qux { baz }
108
- bar.qux { baz }
112
+ def alfa
113
+ bravo.charlie { delta }
114
+ bravo.charlie { delta }
109
115
  end
110
116
  EOS
117
+
111
118
  expect(src).to reek_of(:DuplicateMethodCall)
112
119
  end
113
120
 
114
121
  it 'reports a smell if the blocks are different' do
115
122
  src = <<-EOS
116
- def foo
117
- bar.qux { baz }
118
- bar.qux { qux }
123
+ def alfa
124
+ bravo.charlie { delta }
125
+ bravo.charlie { echo }
119
126
  end
120
127
  EOS
128
+
121
129
  expect(src).to reek_of(:DuplicateMethodCall)
122
130
  end
123
131
  end
124
132
 
125
133
  context 'with repeated attribute assignment' do
126
134
  it 'reports repeated assignment' do
127
- src = 'def double_thing(thing) @other[thing] = true; @other[thing] = true; end'
128
- expect(src).to reek_of(:DuplicateMethodCall, name: '@other[thing] = true')
135
+ src = <<-EOS
136
+ def alfa(bravo)
137
+ @charlie[bravo] = true
138
+ @charlie[bravo] = true
139
+ end
140
+ EOS
141
+
142
+ expect(src).to reek_of(:DuplicateMethodCall)
129
143
  end
144
+
130
145
  it 'does not report multi-assignments' do
131
146
  src = <<-EOS
132
- def _parse ctxt
133
- ctxt.index, result = @ind, @result
134
- error, ctxt.index = @err, @err_ind
147
+ def alfa
148
+ bravo, charlie = delta, echo
149
+ charlie, bravo = delta, echo
135
150
  end
136
151
  EOS
152
+
137
153
  expect(src).not_to reek_of(:DuplicateMethodCall)
138
154
  end
139
155
  end
140
156
 
141
157
  context 'non-repeated method calls' do
142
158
  it 'should not report similar calls' do
143
- src = 'def equals(other) other.thing == self.thing end'
159
+ src = 'def alfa(bravo) bravo.charlie == self.charlie end'
144
160
  expect(src).not_to reek_of(:DuplicateMethodCall)
145
161
  end
146
162
 
147
163
  it 'should respect call parameters' do
148
- src = 'def double_thing() @other.thing(3) + @other.thing(2) end'
164
+ src = 'def alfa; @bravo.charlie(3) + @bravo.charlie(2) end'
149
165
  expect(src).not_to reek_of(:DuplicateMethodCall)
150
166
  end
151
167
  end
@@ -156,47 +172,44 @@ RSpec.describe Reek::Smells::DuplicateMethodCall do
156
172
  end
157
173
 
158
174
  it 'does not report double calls' do
159
- src = 'def double_thing() @other.thing + @other.thing end'
175
+ src = 'def alfa(bravo); bravo.charlie + bravo.charlie; end'
160
176
  expect(src).not_to reek_of(:DuplicateMethodCall).with_config(config)
161
177
  end
162
178
 
163
179
  it 'does not report triple calls' do
164
- src = 'def double_thing() @other.thing + @other.thing + @other.thing end'
180
+ src = 'def alfa(bravo); bravo.charlie + bravo.charlie + bravo.charlie; end'
165
181
  expect(src).not_to reek_of(:DuplicateMethodCall).with_config(config)
166
182
  end
167
183
 
168
184
  it 'reports quadruple calls' do
169
- src = '
170
- def double_thing()
171
- @other.thing + @other.thing + @other.thing + @other.thing
185
+ src = <<-EOS
186
+ def alfa
187
+ bravo.charlie + bravo.charlie + bravo.charlie + bravo.charlie
172
188
  end
173
- '
189
+ EOS
190
+
174
191
  expect(src).to reek_of(:DuplicateMethodCall,
175
- name: '@other.thing', count: 4).with_config(config)
192
+ count: 4).with_config(config)
176
193
  end
177
194
  end
178
195
 
179
196
  context 'allowing calls to some methods' do
180
- let(:config) do
181
- { Reek::Smells::DuplicateMethodCall::ALLOW_CALLS_KEY => ['@some.thing', /puts/] }
182
- end
183
-
184
197
  it 'does not report calls to some methods' do
185
- src = 'def double_some_thing() @some.thing + @some.thing end'
186
-
198
+ config = { Reek::Smells::DuplicateMethodCall::ALLOW_CALLS_KEY => ['@bravo.charlie'] }
199
+ src = 'def alfa; @bravo.charlie + @bravo.charlie; end'
187
200
  expect(src).not_to reek_of(:DuplicateMethodCall).with_config(config)
188
201
  end
189
202
 
190
203
  it 'reports calls to other methods' do
191
- src = 'def double_other_thing() @other.thing + @other.thing end'
192
-
193
- expect(src).to reek_of(:DuplicateMethodCall, name: '@other.thing').with_config(config)
204
+ config = { Reek::Smells::DuplicateMethodCall::ALLOW_CALLS_KEY => ['@delta.charlie'] }
205
+ src = 'def alfa; @bravo.charlie + @bravo.charlie; end'
206
+ expect(src).to reek_of(:DuplicateMethodCall, name: '@bravo.charlie').with_config(config)
194
207
  end
195
208
 
196
209
  it 'does not report calls to methods specifed with a regular expression' do
197
- src = 'def double_puts() puts @other.thing; puts @other.thing end'
198
-
199
- expect(src).to reek_of(:DuplicateMethodCall, name: '@other.thing').with_config(config)
210
+ config = { Reek::Smells::DuplicateMethodCall::ALLOW_CALLS_KEY => [/charlie/] }
211
+ src = 'def alfa; puts @bravo.charlie; puts @bravo.charlie; end'
212
+ expect(src).not_to reek_of(:DuplicateMethodCall, name: '@bravo.charlie').with_config(config)
200
213
  end
201
214
  end
202
215
  end