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,100 +1,147 @@
1
1
  require_relative '../../spec_helper'
2
2
  require_lib 'reek/smells/unused_private_method'
3
- require_lib 'reek/examiner'
4
- require_relative 'smell_detector_shared'
5
3
 
6
4
  RSpec.describe Reek::Smells::UnusedPrivateMethod do
7
- let(:detector) { build(:smell_detector, smell_type: :UnusedPrivateMethod) }
5
+ it 'reports the right values' do
6
+ src = <<-EOS
7
+ class Alfa
8
+ private
8
9
 
9
- it_should_behave_like 'SmellDetector'
10
+ def charlie
11
+ end
12
+ end
13
+ EOS
14
+
15
+ expect(src).to reek_of(:UnusedPrivateMethod,
16
+ lines: [4],
17
+ context: 'Alfa',
18
+ message: "has the unused private instance method 'charlie'",
19
+ source: 'string',
20
+ name: :charlie)
21
+ end
22
+
23
+ it 'does count all occurences' do
24
+ src = <<-EOS
25
+ class Alfa
26
+ private
27
+
28
+ def charlie
29
+ end
30
+
31
+ def charlie
32
+ end
33
+ end
34
+ EOS
35
+
36
+ expect(src).to reek_of(:UnusedPrivateMethod,
37
+ lines: [4],
38
+ name: :charlie)
39
+ expect(src).to reek_of(:UnusedPrivateMethod,
40
+ lines: [7],
41
+ name: :charlie)
42
+ end
10
43
 
11
44
  context 'unused private methods' do
12
45
  it 'reports instance methods' do
13
46
  source = <<-EOF
14
- class Car
47
+ class Alfa
15
48
  private
16
- def start; end
17
- def drive; end
49
+ def bravo; end
50
+ def charlie; end
18
51
  end
19
52
  EOF
20
53
 
21
- expect(source).to reek_of(:UnusedPrivateMethod, name: :start)
22
- expect(source).to reek_of(:UnusedPrivateMethod, name: :drive)
54
+ expect(source).to reek_of(:UnusedPrivateMethod, name: :bravo)
55
+ expect(source).to reek_of(:UnusedPrivateMethod, name: :charlie)
23
56
  end
24
57
 
25
58
  it 'reports instance methods in the correct class' do
26
59
  source = <<-EOF
27
- class Car
28
- class Engine
60
+ class Alfa
61
+ class Bravo
29
62
  private
30
- def start; end
63
+ def charlie; end
31
64
  end
32
65
  end
33
66
  EOF
34
67
 
35
- expect(source).to reek_of(:UnusedPrivateMethod, context: 'Car::Engine', name: :start)
36
- expect(source).not_to reek_of(:UnusedPrivateMethod, context: 'Car', name: :start)
68
+ expect(source).to reek_of(:UnusedPrivateMethod,
69
+ context: 'Alfa::Bravo',
70
+ name: :charlie)
71
+ expect(source).not_to reek_of(:UnusedPrivateMethod,
72
+ context: 'Alfa',
73
+ name: :charlie)
37
74
  end
38
75
 
39
76
  it 'discounts calls to identically named methods in nested classes' do
40
77
  source = <<-EOF
41
- class Car
42
- class Engine
43
- def vroom
44
- start
78
+ class Alfa
79
+ class Bravo
80
+ def bravo
81
+ charlie
45
82
  end
83
+
46
84
  private
47
- def start; end
85
+ def charlie; end
48
86
  end
87
+
49
88
  private
50
- def start; end
89
+ def charlie; end
51
90
  end
52
91
  EOF
53
92
 
54
- expect(source).not_to reek_of(:UnusedPrivateMethod, context: 'Car::Engine', name: :start)
55
- expect(source).to reek_of(:UnusedPrivateMethod, context: 'Car', name: :start)
93
+ expect(source).not_to reek_of(:UnusedPrivateMethod,
94
+ context: 'Alfa::Bravo',
95
+ name: :charlie)
96
+ expect(source).to reek_of(:UnusedPrivateMethod,
97
+ context: 'Alfa',
98
+ name: :charlie)
56
99
  end
57
100
 
58
101
  it 'creates warnings correctly' do
59
102
  source = <<-EOF
60
- class Car
103
+ class Alfa
61
104
  private
62
- def start; end
63
- def drive; end
105
+ def bravo; end
106
+ def charlie; end
64
107
  end
65
108
  EOF
66
109
 
67
- expect(source).to reek_of(:UnusedPrivateMethod, name: :drive, lines: [4])
68
- expect(source).to reek_of(:UnusedPrivateMethod, name: :start, lines: [3])
110
+ expect(source).to reek_of(:UnusedPrivateMethod,
111
+ name: :bravo,
112
+ lines: [3])
113
+ expect(source).to reek_of(:UnusedPrivateMethod,
114
+ name: :charlie,
115
+ lines: [4])
69
116
  end
70
117
  end
71
118
 
72
119
  describe 'configuring the detector via source code comment' do
73
120
  it 'does not report methods we excluded' do
74
121
  source = <<-EOF
75
- # :reek:UnusedPrivateMethod: { exclude: [ start ] }
76
- class Car
122
+ # :reek:UnusedPrivateMethod: { exclude: [ bravo ] }
123
+ class Alfa
77
124
  private
78
- def start; end
79
- def drive; end
125
+ def bravo; end
126
+ def charlie; end
80
127
  end
81
128
  EOF
82
129
 
83
- expect(source).to reek_of(:UnusedPrivateMethod, name: :drive)
84
- expect(source).not_to reek_of(:UnusedPrivateMethod, name: :start)
130
+ expect(source).to reek_of(:UnusedPrivateMethod, name: :charlie)
131
+ expect(source).not_to reek_of(:UnusedPrivateMethod, name: :bravo)
85
132
  end
86
133
  end
87
134
 
88
135
  context 'used private methods' do
89
136
  it 'are not reported' do
90
137
  source = <<-EOF
91
- class Car
92
- def drive
93
- start
138
+ class Alfa
139
+ def bravo
140
+ charlie
94
141
  end
95
142
 
96
143
  private
97
- def start; end
144
+ def charlie; end
98
145
  end
99
146
  EOF
100
147
 
@@ -105,9 +152,9 @@ RSpec.describe Reek::Smells::UnusedPrivateMethod do
105
152
  context 'unused protected methods' do
106
153
  it 'are not reported' do
107
154
  source = <<-EOF
108
- class Car
155
+ class Alfa
109
156
  protected
110
- def start; end
157
+ def bravo; end
111
158
  end
112
159
  EOF
113
160
 
@@ -118,8 +165,8 @@ RSpec.describe Reek::Smells::UnusedPrivateMethod do
118
165
  context 'unused public methods' do
119
166
  it 'are not reported' do
120
167
  source = <<-EOF
121
- class Car
122
- def start; end
168
+ class Alfa
169
+ def bravo; end
123
170
  end
124
171
  EOF
125
172
 
@@ -130,26 +177,26 @@ RSpec.describe Reek::Smells::UnusedPrivateMethod do
130
177
  describe 'prevent methods from being reported' do
131
178
  let(:source) do
132
179
  <<-EOF
133
- class Car
180
+ class Alfa
134
181
  private
135
- def start; end
136
- def drive; end
182
+ def bravo; end
183
+ def charlie; end
137
184
  end
138
185
  EOF
139
186
  end
140
187
 
141
188
  it 'excludes them via direct match in the app configuration' do
142
- config = { Reek::Smells::SmellDetector::EXCLUDE_KEY => ['Car#drive'] }
189
+ config = { Reek::Smells::SmellDetector::EXCLUDE_KEY => ['Alfa#charlie'] }
143
190
 
144
- expect(source).to reek_of(:UnusedPrivateMethod, name: :start).with_config(config)
145
- expect(source).not_to reek_of(:UnusedPrivateMethod, name: :drive).with_config(config)
191
+ expect(source).to reek_of(:UnusedPrivateMethod, name: :bravo).with_config(config)
192
+ expect(source).not_to reek_of(:UnusedPrivateMethod, name: :charlie).with_config(config)
146
193
  end
147
194
 
148
195
  it 'excludes them via regex in the app configuration' do
149
- config = { Reek::Smells::SmellDetector::EXCLUDE_KEY => [/drive/] }
196
+ config = { Reek::Smells::SmellDetector::EXCLUDE_KEY => [/charlie/] }
150
197
 
151
- expect(source).to reek_of(:UnusedPrivateMethod, name: :start).with_config(config)
152
- expect(source).not_to reek_of(:UnusedPrivateMethod, name: :drive).with_config(config)
198
+ expect(source).to reek_of(:UnusedPrivateMethod, name: :bravo).with_config(config)
199
+ expect(source).not_to reek_of(:UnusedPrivateMethod, name: :charlie).with_config(config)
153
200
  end
154
201
  end
155
202
  end
@@ -1,123 +1,146 @@
1
1
  require_relative '../../spec_helper'
2
2
  require_lib 'reek/smells/utility_function'
3
- require_lib 'reek/examiner'
4
- require_relative 'smell_detector_shared'
5
3
 
6
4
  RSpec.describe Reek::Smells::UtilityFunction do
7
- describe 'a detector' do
8
- let(:detector) { build(:smell_detector, smell_type: :UtilityFunction) }
5
+ it 'reports the right values' do
6
+ src = <<-EOS
7
+ def alfa(bravo)
8
+ bravo.charlie.delta
9
+ end
10
+ EOS
9
11
 
10
- it_should_behave_like 'SmellDetector'
12
+ expect(src).to reek_of(:UtilityFunction,
13
+ lines: [1],
14
+ context: 'alfa',
15
+ message: "doesn't depend on instance state (maybe move it to another class?)",
16
+ source: 'string')
17
+ end
11
18
 
12
- context 'when a smells is reported' do
13
- let(:warning) do
14
- src = <<-EOS
15
- def simple(arga)
16
- arga.b.c
19
+ it 'counts a local call in a param initializer' do
20
+ expect('def alfa(bravo = charlie) bravo.to_s end').not_to reek_of(:UtilityFunction)
21
+ end
22
+
23
+ it 'counts usages of self' do
24
+ expect('def alfa(bravo); alfa.bravo(self); end').not_to reek_of(:UtilityFunction)
25
+ end
26
+
27
+ it 'counts self reference within a dstr' do
28
+ expect('def alfa(bravo); "#{self} #{bravo}"; end').not_to reek_of(:UtilityFunction)
29
+ end
30
+
31
+ it 'counts calls to self within a dstr' do
32
+ expect('def alfa(bravo); "#{self.gsub(/charlie/, /delta/)}"; end').
33
+ not_to reek_of(:UtilityFunction)
34
+ end
35
+
36
+ it 'does not report a method that calls super' do
37
+ expect('def alfa(bravo) super; bravo.to_s; end').not_to reek_of(:UtilityFunction)
38
+ end
39
+
40
+ it 'does not report a method that calls super with arguments' do
41
+ expect('def alfa(bravo) super(bravo); bravo.to_s; end').not_to reek_of(:UtilityFunction)
42
+ end
43
+
44
+ it 'should recognise a deep call' do
45
+ src = <<-EOS
46
+ class Alfa
47
+ def bravo(charlie)
48
+ charlie.each { |delta| foxtrot(delta) }
17
49
  end
18
- EOS
19
- Reek::Examiner.new(src, filter_by_smells: ['UtilityFunction']).smells[0]
20
- end
21
50
 
22
- it_should_behave_like 'common fields set correctly'
51
+ def foxtrot(golf)
52
+ @india << golf
53
+ end
54
+ end
55
+ EOS
23
56
 
24
- it 'reports the line number of the method' do
25
- expect(warning.lines).to eq([1])
26
- end
57
+ expect(src).not_to reek_of(:UtilityFunction)
58
+ end
27
59
 
28
- it 'has the right message' do
29
- expect(warning.message).to eq("doesn't depend on instance state (maybe move it to another class?)")
30
- end
31
- end
60
+ it 'does not report empty method' do
61
+ expect('def alfa(bravo); end').not_to reek_of(:UtilityFunction)
32
62
  end
33
63
 
34
- context 'with a singleton method' do
35
- ['self', 'local_call', '$global'].each do |receiver|
36
- it 'ignores the receiver' do
37
- src = "def #{receiver}.simple(arga) arga.to_s + arga.to_i end"
38
- expect(src).not_to reek_of(:UtilityFunction)
39
- end
40
- end
64
+ it 'does not report literal' do
65
+ expect('def alfa; 3; end').not_to reek_of(:UtilityFunction)
41
66
  end
42
67
 
43
- context 'Singleton methods' do
44
- it 'for classes with `class << self` notation should not report UtilityFunction' do
45
- src = 'class C; class << self; def m(a) a.to_s; end; end; end'
46
- expect(src).not_to reek_of(:UtilityFunction)
47
- end
68
+ it 'does not report instance variable reference' do
69
+ expect('def alfa; @bravo; end').not_to reek_of(:UtilityFunction)
70
+ end
48
71
 
49
- it 'for classes with `self.` notation should not report UtilityFunction' do
50
- src = 'class C; def self.m(a) a.to_s; end; end'
51
- expect(src).not_to reek_of(:UtilityFunction)
52
- end
72
+ it 'does not report vcall' do
73
+ expect('def alfa; bravo; end').not_to reek_of(:UtilityFunction)
74
+ end
53
75
 
54
- it 'for modules with `class << self` notation should not report UtilityFunction' do
55
- src = 'module M; class << self; def self.m(a) a.to_s; end; end; end'
56
- expect(src).not_to reek_of(:UtilityFunction)
57
- end
76
+ it 'does not report references to self' do
77
+ expect('def alfa; self; end').not_to reek_of(:UtilityFunction)
78
+ end
58
79
 
59
- it 'for modules with `self.` notation should not report UtilityFunction' do
60
- src = 'module M; def self.simple(a) a.to_s; end; end'
61
- expect(src).not_to reek_of(:UtilityFunction)
62
- end
80
+ it 'recognises an ivar reference within a block' do
81
+ expect('def alfa(bravo) bravo.each { @charlie = 3} end').not_to reek_of(:UtilityFunction)
82
+ end
63
83
 
64
- context 'by using `module_function`' do
65
- it 'should not report UtilityFunction' do
66
- src = 'class C; def m(a) a.to_s; end; module_function :m; end'
84
+ it 'reports a call to a constant' do
85
+ expect('def simple(arga) FIELDS[arga] end').to reek_of(:UtilityFunction, context: 'simple')
86
+ end
87
+
88
+ context 'Singleton methods' do
89
+ ['class', 'module'].each do |scope|
90
+ it "does not report for #{scope} with `class << self` notation" do
91
+ src = "#{scope} Alfa; class << self; def bravo(charlie) charlie.to_s; end; end; end"
92
+ expect(src).not_to reek_of(:UtilityFunction)
93
+ end
94
+
95
+ it "does not report for #{scope} with `self.` notation" do
96
+ src = "#{scope} Alfa; def self.bravo(charlie) charlie.to_s; end; end"
67
97
  expect(src).not_to reek_of(:UtilityFunction)
68
98
  end
99
+ end
69
100
 
70
- it 'should not report UtilityFunction also when using multiple arguments' do
101
+ context 'by using `module_function`' do
102
+ it 'does not report UtilityFunction also when using multiple arguments' do
71
103
  src = <<-EOS
72
- class C
73
- def m1(a) a.to_s; end
74
- def m2(a) a.to_s; end
75
- module_function :m1, :m2
104
+ class Alfa
105
+ def bravo(charlie) charlie.to_s; end
106
+ def delta(echo) echo.to_s; end
107
+ module_function :bravo, :delta
76
108
  end
77
- EOS
109
+ EOS
110
+
78
111
  expect(src).not_to reek_of(:UtilityFunction)
79
112
  end
80
113
 
81
114
  it 'does not report module functions defined by earlier modifier' do
82
115
  src = <<-EOF
83
- module M
116
+ module Alfa
84
117
  module_function
85
- def simple(a) a.to_s; end
118
+ def bravo(charlie) charlie.to_s; end
86
119
  end
87
120
  EOF
121
+
88
122
  expect(src).not_to reek_of(:UtilityFunction)
89
123
  end
90
124
 
91
125
  it 'reports functions preceded by canceled modifier' do
92
126
  src = <<-EOF
93
- module M
127
+ module Alfa
94
128
  module_function
95
129
  public
96
- def simple(a) a.to_s; end
130
+ def bravo(charlie) charlie.to_s; end
97
131
  end
98
132
  EOF
99
- expect(src).to reek_of(:UtilityFunction, context: 'M#simple')
100
- end
101
133
 
102
- it 'does not report when module_function is called in separate scope' do
103
- src = <<-EOF
104
- class C
105
- def m(a) a.to_s; end
106
- begin
107
- module_function :m
108
- end
109
- end
110
- EOF
111
- expect(src).not_to reek_of(:UtilityFunction)
134
+ expect(src).to reek_of(:UtilityFunction, context: 'Alfa#bravo')
112
135
  end
113
136
 
114
- it 'does not report when module_function modifier is called in separate scope' do
137
+ it 'does not report when module_function is called in separate scope' do
115
138
  src = <<-EOF
116
- class C
139
+ class Alfa
140
+ def bravo(charlie) charlie.to_s; end
117
141
  begin
118
- module_function
142
+ module_function :bravo
119
143
  end
120
- def m(a) a.to_s; end
121
144
  end
122
145
  EOF
123
146
  expect(src).not_to reek_of(:UtilityFunction)
@@ -125,121 +148,31 @@ RSpec.describe Reek::Smells::UtilityFunction do
125
148
  end
126
149
  end
127
150
 
128
- context 'with no calls' do
129
- it 'does not report empty method' do
130
- expect('def simple(arga) end').not_to reek_of(:UtilityFunction)
131
- end
132
-
133
- it 'does not report literal' do
134
- expect('def simple() 3; end').not_to reek_of(:UtilityFunction)
135
- end
136
-
137
- it 'does not report instance variable reference' do
138
- expect('def simple() @yellow end').not_to reek_of(:UtilityFunction)
139
- end
140
-
141
- it 'does not report vcall' do
142
- expect('def simple() y end').not_to reek_of(:UtilityFunction)
143
- end
144
-
145
- it 'does not report references to self' do
146
- expect('def into; self; end').not_to reek_of(:UtilityFunction)
147
- end
148
-
149
- it 'recognises an ivar reference within a block' do
150
- expect('def clean(text) text.each { @fred = 3} end').not_to reek_of(:UtilityFunction)
151
- end
152
-
153
- it 'copes with nil superclass' do
154
- expect('class Object; def is_maybe?() false end end').not_to reek_of(:UtilityFunction)
155
- end
156
- end
157
-
158
- context 'with only one call' do
159
- it 'reports a call to a parameter' do
160
- expect('def simple(arga) arga.to_s end').to reek_of(:UtilityFunction, context: 'simple')
161
- end
162
-
163
- it 'reports a call to a constant' do
164
- expect('def simple(arga) FIELDS[arga] end').to reek_of(:UtilityFunction, context: 'simple')
165
- end
166
- end
167
-
168
- context 'with two or more calls' do
169
- it 'reports two calls' do
170
- src = 'def simple(arga) arga.to_s + arga.to_i end'
171
- expect(src).to reek_of(:UtilityFunction, context: 'simple')
172
- expect(src).not_to reek_of(:FeatureEnvy)
173
- end
174
-
175
- it 'counts a local call in a param initializer' do
176
- expect('def simple(arga=local) arga.to_s end').not_to reek_of(:UtilityFunction)
177
- end
178
-
179
- it 'should count usages of self' do
180
- expect('def <=>(other) Options[:sort_order].compare(self, other) end').
181
- not_to reek_of(:UtilityFunction)
182
- end
183
-
184
- it 'should count self reference within a dstr' do
185
- expect('def as(alias_name); "#{self} as #{alias_name}".to_sym; end').
186
- not_to reek_of(:UtilityFunction)
187
- end
188
-
189
- it 'should count calls to self within a dstr' do
190
- expect('def to_sql; "\'#{self.gsub(/\'/, "\'\'")}\'"; end').
191
- not_to reek_of(:UtilityFunction)
192
- end
193
-
194
- it 'should report message chain' do
195
- src = 'def simple(arga) arga.b.c end'
196
- expect(src).to reek_of(:UtilityFunction, context: 'simple')
197
- expect(src).not_to reek_of(:FeatureEnvy)
198
- end
199
-
200
- it 'does not report a method that calls super' do
201
- expect('def child(arg) super; arg.to_s; end').not_to reek_of(:UtilityFunction)
202
- end
203
-
204
- it 'does not report a method that calls super with arguments' do
205
- expect('def child(arg) super(arg * 2); arg.to_s; end').not_to reek_of(:UtilityFunction)
206
- end
207
-
208
- it 'should recognise a deep call' do
151
+ describe 'method visibility' do
152
+ it 'reports private methods' do
209
153
  src = <<-EOS
210
- class Red
211
- def deep(text)
212
- text.each { |mod| atts = shelve(mod) }
213
- end
214
-
215
- def shelve(val)
216
- @shelf << val
154
+ class Alfa
155
+ private
156
+ def bravo(charlie)
157
+ charlie.delta.echo
217
158
  end
218
159
  end
219
160
  EOS
220
- expect(src).not_to reek_of(:UtilityFunction)
221
- end
222
- end
223
161
 
224
- context 'with the default configuration' do
225
- it 'reports private methods' do
226
- src = <<-EOS
227
- class C
228
- private
229
- def m1(a) a.to_s; end
230
- end
231
- EOS
232
- expect(src).to reek_of(:UtilityFunction, context: 'C#m1')
162
+ expect(src).to reek_of(:UtilityFunction, context: 'Alfa#bravo')
233
163
  end
234
164
 
235
165
  it 'reports protected methods' do
236
166
  src = <<-EOS
237
- class C
238
- protected
239
- def m1(a) a.to_s; end
167
+ class Alfa
168
+ protected
169
+ def bravo(charlie)
170
+ charlie.delta.echo
240
171
  end
172
+ end
241
173
  EOS
242
- expect(src).to reek_of(:UtilityFunction, context: 'C#m1')
174
+
175
+ expect(src).to reek_of(:UtilityFunction, context: 'Alfa#bravo')
243
176
  end
244
177
  end
245
178
 
@@ -249,36 +182,45 @@ RSpec.describe Reek::Smells::UtilityFunction do
249
182
  end
250
183
 
251
184
  context 'public methods' do
252
- it 'should still report UtilityFunction' do
185
+ it 'still reports UtilityFunction' do
253
186
  src = <<-EOS
254
- class C
255
- def m1(a) a.to_s; end
187
+ class Alfa
188
+ def bravo(charlie)
189
+ charlie.delta.echo
190
+ end
256
191
  end
257
192
  EOS
258
- expect(src).to reek_of(:UtilityFunction, context: 'C#m1').with_config(config)
193
+
194
+ expect(src).to reek_of(:UtilityFunction, context: 'Alfa#bravo').with_config(config)
259
195
  end
260
196
  end
261
197
 
262
198
  context 'private methods' do
263
- it 'should not report UtilityFunction' do
199
+ it 'does not report UtilityFunction' do
264
200
  src = <<-EOS
265
- class C
201
+ class Alfa
266
202
  private
267
- def m1(a) a.to_s; end
203
+ def bravo(charlie)
204
+ charlie.delta.echo
205
+ end
268
206
  end
269
207
  EOS
208
+
270
209
  expect(src).not_to reek_of(:UtilityFunction).with_config(config)
271
210
  end
272
211
  end
273
212
 
274
213
  context 'protected methods' do
275
- it 'should not report UtilityFunction' do
214
+ it 'does not report UtilityFunction' do
276
215
  src = <<-EOS
277
- class C
216
+ class Alfa
278
217
  protected
279
- def m1(a) a.to_s; end
218
+ def bravo(charlie)
219
+ charlie.delta.echo
220
+ end
280
221
  end
281
222
  EOS
223
+
282
224
  expect(src).not_to reek_of(:UtilityFunction).with_config(config)
283
225
  end
284
226
  end