reek 4.7.1 → 4.7.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/features/configuration_files/directory_specific_directives.feature +4 -4
- data/lib/reek/ast/node.rb +0 -3
- data/lib/reek/context/attribute_context.rb +2 -2
- data/lib/reek/context/code_context.rb +39 -32
- data/lib/reek/context/method_context.rb +16 -4
- data/lib/reek/context/module_context.rb +1 -2
- data/lib/reek/context/root_context.rb +0 -4
- data/lib/reek/context/send_context.rb +2 -2
- data/lib/reek/context_builder.rb +34 -33
- data/lib/reek/detector_repository.rb +5 -11
- data/lib/reek/smell_detectors/base_detector.rb +13 -14
- data/lib/reek/smell_detectors/uncommunicative_parameter_name.rb +11 -12
- data/lib/reek/smell_detectors/unused_private_method.rb +1 -0
- data/lib/reek/tree_dresser.rb +3 -3
- data/lib/reek/version.rb +1 -1
- data/spec/reek/context/code_context_spec.rb +14 -14
- data/spec/reek/context/ghost_context_spec.rb +8 -8
- data/spec/reek/context/method_context_spec.rb +2 -2
- data/spec/reek/context/module_context_spec.rb +3 -3
- data/spec/reek/context_builder_spec.rb +20 -0
- data/spec/reek/smell_detectors/irresponsible_module_spec.rb +0 -11
- data/spec/reek/smell_detectors/uncommunicative_parameter_name_spec.rb +30 -11
- data/spec/reek/smell_detectors/unused_private_method_spec.rb +11 -0
- data/spec/reek/smell_detectors/utility_function_spec.rb +52 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a57753b0b855d7182054e7551940eac44cf57f60
|
4
|
+
data.tar.gz: 245074bd6e150589a1bc7a69830a34e3db600a83
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4c422c0a25421d8d0abc337766f7b2defae5f7044137c3e5fb7c34fffea7ee409d165f56922f433565fa8643d716cdbb3e9a3c7cec568bfa50bf15b2eed8b254
|
7
|
+
data.tar.gz: d4b77922d2745ab3d7f6f053931193b543f646e605a0b3a7f7a444ddf24d3462df4bf7732a248f14fd49f9253925afbf441d3fda578df736b130bfbf80db5096
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Change log
|
2
2
|
|
3
|
+
## 4.7.2 (2017-07-24)
|
4
|
+
|
5
|
+
* (mvz) Also report unused uncommunicative parameter names
|
6
|
+
* (mvz) Track visibility correctly when using method definition visibility modifiers
|
7
|
+
* (mvz) Handle method comments when using method definition visibility modifiers
|
8
|
+
|
3
9
|
## 4.7.1 (2017-06-12)
|
4
10
|
|
5
11
|
* (mvz) Improve IrresponsibleModule and fix some bugs along
|
@@ -41,7 +41,7 @@ Feature: Directory directives
|
|
41
41
|
And a file named "web_app/app/models/user.rb" with:
|
42
42
|
"""
|
43
43
|
class User < ActiveRecord::Base
|
44
|
-
def logged_in_with_role(
|
44
|
+
def logged_in_with_role(role)
|
45
45
|
true
|
46
46
|
end
|
47
47
|
end
|
@@ -53,7 +53,7 @@ Feature: Directory directives
|
|
53
53
|
[1]:InstanceVariableAssumption: UsersController assumes too much for instance variable '@user' [https://github.com/troessner/reek/blob/master/docs/Instance-Variable-Assumption.md]
|
54
54
|
web_app/app/models/user.rb -- 2 warnings:
|
55
55
|
[1]:IrresponsibleModule: User has no descriptive comment [https://github.com/troessner/reek/blob/master/docs/Irresponsible-Module.md]
|
56
|
-
[2]:UnusedParameters: User#logged_in_with_role has unused parameter '
|
56
|
+
[2]:UnusedParameters: User#logged_in_with_role has unused parameter 'role' [https://github.com/troessner/reek/blob/master/docs/Unused-Parameters.md]
|
57
57
|
3 total warnings
|
58
58
|
"""
|
59
59
|
|
@@ -112,7 +112,7 @@ Feature: Directory directives
|
|
112
112
|
And a file named "web_app/app/models/user.rb" with:
|
113
113
|
"""
|
114
114
|
class User < ActiveRecord::Base
|
115
|
-
def logged_in_with_role(
|
115
|
+
def logged_in_with_role(role)
|
116
116
|
true
|
117
117
|
end
|
118
118
|
end
|
@@ -125,7 +125,7 @@ Feature: Directory directives
|
|
125
125
|
[1]:IrresponsibleModule: UsersController has no descriptive comment [https://github.com/troessner/reek/blob/master/docs/Irresponsible-Module.md]
|
126
126
|
[4]:NestedIterators: UsersController#show contains iterators nested 2 deep [https://github.com/troessner/reek/blob/master/docs/Nested-Iterators.md]
|
127
127
|
web_app/app/models/user.rb -- 1 warning:
|
128
|
-
[2]:UnusedParameters: User#logged_in_with_role has unused parameter '
|
128
|
+
[2]:UnusedParameters: User#logged_in_with_role has unused parameter 'role' [https://github.com/troessner/reek/blob/master/docs/Unused-Parameters.md]
|
129
129
|
4 total warnings
|
130
130
|
"""
|
131
131
|
|
data/lib/reek/ast/node.rb
CHANGED
@@ -12,11 +12,8 @@ module Reek
|
|
12
12
|
# methods to ease the transition from Sexp to AST::Node.
|
13
13
|
#
|
14
14
|
class Node < ::Parser::AST::Node
|
15
|
-
attr_reader :parent
|
16
|
-
|
17
15
|
def initialize(type, children = [], options = {})
|
18
16
|
@comments = options.fetch(:comments, [])
|
19
|
-
@parent = options.fetch(:parent, nil)
|
20
17
|
super
|
21
18
|
end
|
22
19
|
|
@@ -11,10 +11,10 @@ module Reek
|
|
11
11
|
class AttributeContext < CodeContext
|
12
12
|
attr_accessor :visibility
|
13
13
|
|
14
|
-
def initialize(
|
14
|
+
def initialize(exp, send_expression)
|
15
15
|
@visibility = :public
|
16
16
|
@send_expression = send_expression
|
17
|
-
super
|
17
|
+
super exp
|
18
18
|
end
|
19
19
|
|
20
20
|
def full_comment
|
@@ -26,39 +26,8 @@ module Reek
|
|
26
26
|
|
27
27
|
# Initializes a new CodeContext.
|
28
28
|
#
|
29
|
-
# @param _parent [CodeContext, nil] The parent context
|
30
29
|
# @param exp [Reek::AST::Node] The code described by this context
|
31
|
-
|
32
|
-
# For example, given the following code:
|
33
|
-
#
|
34
|
-
# class Omg
|
35
|
-
# def foo(x)
|
36
|
-
# puts x
|
37
|
-
# end
|
38
|
-
# end
|
39
|
-
#
|
40
|
-
# The {ContextBuilder} object first instantiates a {RootContext}, which has no parent.
|
41
|
-
#
|
42
|
-
# Next, it instantiates a {ModuleContext}, with +parent+ being the
|
43
|
-
# {RootContext} just created, and +exp+ looking like this:
|
44
|
-
#
|
45
|
-
# (class
|
46
|
-
# (const nil :Omg) nil
|
47
|
-
# (def :foo
|
48
|
-
# (args
|
49
|
-
# (arg :x))
|
50
|
-
# (send nil :puts
|
51
|
-
# (lvar :x))))
|
52
|
-
#
|
53
|
-
# Finally, {ContextBuilder} will instantiate a {MethodContext}. This time,
|
54
|
-
# +parent+ is the {ModuleContext} created above, and +exp+ is:
|
55
|
-
#
|
56
|
-
# (def :foo
|
57
|
-
# (args
|
58
|
-
# (arg :x))
|
59
|
-
# (send nil :puts
|
60
|
-
# (lvar :x)))
|
61
|
-
def initialize(_parent, exp)
|
30
|
+
def initialize(exp)
|
62
31
|
@exp = exp
|
63
32
|
@children = []
|
64
33
|
@statement_counter = StatementCounter.new
|
@@ -91,6 +60,44 @@ module Reek
|
|
91
60
|
end
|
92
61
|
end
|
93
62
|
|
63
|
+
# Link the present context to its parent.
|
64
|
+
#
|
65
|
+
# @param parent [Reek::AST::Node] The parent context of the code described by this context
|
66
|
+
#
|
67
|
+
# For example, given the following code:
|
68
|
+
#
|
69
|
+
# class Omg
|
70
|
+
# def foo(x)
|
71
|
+
# puts x
|
72
|
+
# end
|
73
|
+
# end
|
74
|
+
#
|
75
|
+
# The {ContextBuilder} object first instantiates a {RootContext}, which has no parent.
|
76
|
+
#
|
77
|
+
# Next, it instantiates a {ModuleContext}, with +exp+ looking like this:
|
78
|
+
#
|
79
|
+
# (class
|
80
|
+
# (const nil :Omg) nil
|
81
|
+
# (def :foo
|
82
|
+
# (args
|
83
|
+
# (arg :x))
|
84
|
+
# (send nil :puts
|
85
|
+
# (lvar :x))))
|
86
|
+
#
|
87
|
+
# It will then call #register_with_parent on the {ModuleContext}, passing
|
88
|
+
# in the parent {RootContext}.
|
89
|
+
#
|
90
|
+
# Finally, {ContextBuilder} will instantiate a {MethodContext}. This time,
|
91
|
+
# +exp+ is:
|
92
|
+
#
|
93
|
+
# (def :foo
|
94
|
+
# (args
|
95
|
+
# (arg :x))
|
96
|
+
# (send nil :puts
|
97
|
+
# (lvar :x)))
|
98
|
+
#
|
99
|
+
# Then it will call #register_with_parent on the {MethodContext}, passing
|
100
|
+
# in the parent {ModuleContext}.
|
94
101
|
def register_with_parent(parent)
|
95
102
|
@parent = parent.append_child_context(self) if parent
|
96
103
|
end
|
@@ -12,9 +12,10 @@ module Reek
|
|
12
12
|
attr_accessor :visibility
|
13
13
|
attr_reader :refs
|
14
14
|
|
15
|
-
def initialize(
|
15
|
+
def initialize(exp, parent_exp)
|
16
|
+
@parent_exp = parent_exp
|
16
17
|
@visibility = :public
|
17
|
-
super
|
18
|
+
super exp
|
18
19
|
end
|
19
20
|
|
20
21
|
def references_self?
|
@@ -36,7 +37,7 @@ module Reek
|
|
36
37
|
# stop at the `lvasgn` and not detect the contained `lvar`.
|
37
38
|
# Hence we first get all `lvar` nodes followed by all `lvasgn` nodes.
|
38
39
|
#
|
39
|
-
(local_nodes(:lvar) + local_nodes(:lvasgn)).find { |node| node.var_name == param.
|
40
|
+
(local_nodes(:lvar) + local_nodes(:lvasgn)).find { |node| node.var_name == param.name }
|
40
41
|
end
|
41
42
|
|
42
43
|
# :reek:FeatureEnvy
|
@@ -44,7 +45,7 @@ module Reek
|
|
44
45
|
exp.arguments.reject do |param|
|
45
46
|
param.anonymous_splat? ||
|
46
47
|
param.marked_unused? ||
|
47
|
-
uses_param?(param
|
48
|
+
uses_param?(param)
|
48
49
|
end
|
49
50
|
end
|
50
51
|
|
@@ -80,6 +81,17 @@ module Reek
|
|
80
81
|
def non_public_visibility?
|
81
82
|
visibility != :public
|
82
83
|
end
|
84
|
+
|
85
|
+
def full_comment
|
86
|
+
own = super
|
87
|
+
return own unless own.empty?
|
88
|
+
return parent_exp.full_comment if parent_exp
|
89
|
+
''
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
attr_reader :parent_exp
|
83
95
|
end
|
84
96
|
end
|
85
97
|
end
|
data/lib/reek/context_builder.rb
CHANGED
@@ -22,6 +22,7 @@ module Reek
|
|
22
22
|
#
|
23
23
|
# :reek:TooManyMethods: { max_methods: 31 }
|
24
24
|
# :reek:UnusedPrivateMethod: { exclude: [ !ruby/regexp /process_/ ] }
|
25
|
+
# :reek:DataClump
|
25
26
|
class ContextBuilder
|
26
27
|
attr_reader :context_tree
|
27
28
|
|
@@ -58,10 +59,10 @@ module Reek
|
|
58
59
|
# RootContext -> children: 1 ModuleContext -> children: 1 MethodContext
|
59
60
|
#
|
60
61
|
# @return [Reek::Context::RootContext] tree of nested contexts
|
61
|
-
def build(exp)
|
62
|
+
def build(exp, parent_exp = nil)
|
62
63
|
context_processor = "process_#{exp.type}"
|
63
64
|
if context_processor_exists?(context_processor)
|
64
|
-
send(context_processor, exp)
|
65
|
+
send(context_processor, exp, parent_exp)
|
65
66
|
else
|
66
67
|
process exp
|
67
68
|
end
|
@@ -71,12 +72,12 @@ module Reek
|
|
71
72
|
# Handles every node for which we have no context_processor.
|
72
73
|
#
|
73
74
|
def process(exp)
|
74
|
-
exp.children.grep(AST::Node).each(
|
75
|
+
exp.children.grep(AST::Node).each { |child| build(child, exp) }
|
75
76
|
end
|
76
77
|
|
77
78
|
# Handles `module` and `class` nodes.
|
78
79
|
#
|
79
|
-
def process_module(exp)
|
80
|
+
def process_module(exp, _parent)
|
80
81
|
inside_new_context(Context::ModuleContext, exp) do
|
81
82
|
process(exp)
|
82
83
|
end
|
@@ -91,7 +92,7 @@ module Reek
|
|
91
92
|
# class << self
|
92
93
|
# end
|
93
94
|
#
|
94
|
-
def process_sclass(exp)
|
95
|
+
def process_sclass(exp, _parent)
|
95
96
|
inside_new_context(Context::GhostContext, exp) do
|
96
97
|
process(exp)
|
97
98
|
end
|
@@ -103,9 +104,9 @@ module Reek
|
|
103
104
|
#
|
104
105
|
# Foo = Class.new Bar
|
105
106
|
#
|
106
|
-
def process_casgn(exp)
|
107
|
+
def process_casgn(exp, parent)
|
107
108
|
if exp.defines_module?
|
108
|
-
process_module(exp)
|
109
|
+
process_module(exp, parent)
|
109
110
|
else
|
110
111
|
process(exp)
|
111
112
|
end
|
@@ -119,8 +120,8 @@ module Reek
|
|
119
120
|
#
|
120
121
|
# Given the above example we would count 2 statements overall.
|
121
122
|
#
|
122
|
-
def process_def(exp)
|
123
|
-
inside_new_context(current_context.method_context_class, exp) do
|
123
|
+
def process_def(exp, parent)
|
124
|
+
inside_new_context(current_context.method_context_class, exp, parent) do
|
124
125
|
increase_statement_count_by(exp.body)
|
125
126
|
process(exp)
|
126
127
|
end
|
@@ -134,8 +135,8 @@ module Reek
|
|
134
135
|
#
|
135
136
|
# Given the above example we would count 2 statements overall.
|
136
137
|
#
|
137
|
-
def process_defs(exp)
|
138
|
-
inside_new_context(Context::SingletonMethodContext, exp) do
|
138
|
+
def process_defs(exp, parent)
|
139
|
+
inside_new_context(Context::SingletonMethodContext, exp, parent) do
|
139
140
|
increase_statement_count_by(exp.body)
|
140
141
|
process(exp)
|
141
142
|
end
|
@@ -151,14 +152,14 @@ module Reek
|
|
151
152
|
# we also record to what the method call is referring to
|
152
153
|
# which we later use for smell detectors like FeatureEnvy.
|
153
154
|
#
|
154
|
-
def process_send(exp)
|
155
|
+
def process_send(exp, _parent)
|
156
|
+
process(exp)
|
155
157
|
case current_context
|
156
158
|
when Context::ModuleContext
|
157
159
|
handle_send_for_modules exp
|
158
160
|
when Context::MethodContext
|
159
161
|
handle_send_for_methods exp
|
160
162
|
end
|
161
|
-
process(exp)
|
162
163
|
end
|
163
164
|
|
164
165
|
# Handles `op_asgn` nodes a.k.a. Ruby's assignment operators.
|
@@ -173,7 +174,7 @@ module Reek
|
|
173
174
|
#
|
174
175
|
# We record one reference to `x` given the example above.
|
175
176
|
#
|
176
|
-
def process_op_asgn(exp)
|
177
|
+
def process_op_asgn(exp, _parent)
|
177
178
|
current_context.record_call_to(exp)
|
178
179
|
process(exp)
|
179
180
|
end
|
@@ -192,7 +193,7 @@ module Reek
|
|
192
193
|
#
|
193
194
|
# We record one reference to `self`.
|
194
195
|
#
|
195
|
-
def process_ivar(exp)
|
196
|
+
def process_ivar(exp, _parent)
|
196
197
|
current_context.record_use_of_self
|
197
198
|
process(exp)
|
198
199
|
end
|
@@ -205,7 +206,7 @@ module Reek
|
|
205
206
|
#
|
206
207
|
# def self.foo; end
|
207
208
|
#
|
208
|
-
def process_self(_)
|
209
|
+
def process_self(_, _parent)
|
209
210
|
current_context.record_use_of_self
|
210
211
|
end
|
211
212
|
|
@@ -225,7 +226,7 @@ module Reek
|
|
225
226
|
#
|
226
227
|
# We record one reference to `self`.
|
227
228
|
#
|
228
|
-
def process_zsuper(_)
|
229
|
+
def process_zsuper(_, _parent)
|
229
230
|
current_context.record_use_of_self
|
230
231
|
end
|
231
232
|
|
@@ -249,7 +250,7 @@ module Reek
|
|
249
250
|
#
|
250
251
|
# We record one reference to `self`.
|
251
252
|
#
|
252
|
-
def process_super(exp)
|
253
|
+
def process_super(exp, _parent)
|
253
254
|
current_context.record_use_of_self
|
254
255
|
process(exp)
|
255
256
|
end
|
@@ -262,7 +263,7 @@ module Reek
|
|
262
263
|
#
|
263
264
|
# Counts non-empty blocks as one statement.
|
264
265
|
#
|
265
|
-
def process_block(exp)
|
266
|
+
def process_block(exp, _parent)
|
266
267
|
increase_statement_count_by(exp.block)
|
267
268
|
process(exp)
|
268
269
|
end
|
@@ -282,7 +283,7 @@ module Reek
|
|
282
283
|
# At the end we subtract one statement because the surrounding context was already counted
|
283
284
|
# as one (e.g. via `process_def`).
|
284
285
|
#
|
285
|
-
def process_begin(exp)
|
286
|
+
def process_begin(exp, _parent)
|
286
287
|
increase_statement_count_by(exp.children)
|
287
288
|
decrease_statement_count
|
288
289
|
process(exp)
|
@@ -308,7 +309,7 @@ module Reek
|
|
308
309
|
# `children[1]` refers to the `if` body (so `puts 'bingo'` from above) and
|
309
310
|
# `children[2]` to the `else` body (so `3` from above), which might be nil.
|
310
311
|
#
|
311
|
-
def process_if(exp)
|
312
|
+
def process_if(exp, _parent)
|
312
313
|
children = exp.children
|
313
314
|
increase_statement_count_by(children[1])
|
314
315
|
increase_statement_count_by(children[2])
|
@@ -331,7 +332,7 @@ module Reek
|
|
331
332
|
#
|
332
333
|
# `children[1]` below refers to the `while` body (so `puts 'bingo'` from above)
|
333
334
|
#
|
334
|
-
def process_while(exp)
|
335
|
+
def process_while(exp, _parent)
|
335
336
|
increase_statement_count_by(exp.children[1])
|
336
337
|
decrease_statement_count
|
337
338
|
process(exp)
|
@@ -354,7 +355,7 @@ module Reek
|
|
354
355
|
#
|
355
356
|
# `children[2]` below refers to the `while` body (so `puts i` from above)
|
356
357
|
#
|
357
|
-
def process_for(exp)
|
358
|
+
def process_for(exp, _parent)
|
358
359
|
increase_statement_count_by(exp.children[2])
|
359
360
|
decrease_statement_count
|
360
361
|
process(exp)
|
@@ -384,7 +385,7 @@ module Reek
|
|
384
385
|
# `exp` would be the whole method body wrapped under a `rescue` node.
|
385
386
|
# See `process_resbody` for additional reference.
|
386
387
|
#
|
387
|
-
def process_rescue(exp)
|
388
|
+
def process_rescue(exp, _parent)
|
388
389
|
increase_statement_count_by(exp.children.first)
|
389
390
|
decrease_statement_count
|
390
391
|
process(exp)
|
@@ -412,7 +413,7 @@ module Reek
|
|
412
413
|
# `exp` would be the whole `rescue` body.
|
413
414
|
# See `process_rescue` for additional reference.
|
414
415
|
#
|
415
|
-
def process_resbody(exp)
|
416
|
+
def process_resbody(exp, _parent)
|
416
417
|
increase_statement_count_by(exp.children[1..-1].compact)
|
417
418
|
process(exp)
|
418
419
|
end
|
@@ -434,7 +435,7 @@ module Reek
|
|
434
435
|
# At the end we subtract one statement because the surrounding context was already counted
|
435
436
|
# as one (e.g. via `process_def`).
|
436
437
|
#
|
437
|
-
def process_case(exp)
|
438
|
+
def process_case(exp, _parent)
|
438
439
|
increase_statement_count_by(exp.else_body)
|
439
440
|
decrease_statement_count
|
440
441
|
process(exp)
|
@@ -460,7 +461,7 @@ module Reek
|
|
460
461
|
#
|
461
462
|
# Counts the `when` body.
|
462
463
|
#
|
463
|
-
def process_when(exp)
|
464
|
+
def process_when(exp, _parent)
|
464
465
|
increase_statement_count_by(exp.body)
|
465
466
|
process(exp)
|
466
467
|
end
|
@@ -482,19 +483,19 @@ module Reek
|
|
482
483
|
# yields to the given block and then restores the previous context.
|
483
484
|
#
|
484
485
|
# @param klass [Context::*Context] - context class
|
485
|
-
# @param
|
486
|
+
# @param args - arguments for the class initializer
|
486
487
|
# @yield block
|
487
488
|
#
|
488
|
-
def inside_new_context(klass,
|
489
|
-
new_context = append_new_context(klass,
|
489
|
+
def inside_new_context(klass, *args)
|
490
|
+
new_context = append_new_context(klass, *args)
|
490
491
|
|
491
492
|
orig, self.current_context = current_context, new_context
|
492
493
|
yield
|
493
494
|
self.current_context = orig
|
494
495
|
end
|
495
496
|
|
496
|
-
#
|
497
|
-
# current context.
|
497
|
+
# Appends a new child context to the current context but does not change
|
498
|
+
# the current context.
|
498
499
|
#
|
499
500
|
# @param klass [Context::*Context] - context class
|
500
501
|
# @param args - arguments for the class initializer
|
@@ -502,7 +503,7 @@ module Reek
|
|
502
503
|
# @return [Context::*Context] - the context that was appended
|
503
504
|
#
|
504
505
|
def append_new_context(klass, *args)
|
505
|
-
klass.new(
|
506
|
+
klass.new(*args).tap do |new_context|
|
506
507
|
new_context.register_with_parent(current_context)
|
507
508
|
end
|
508
509
|
end
|
@@ -35,31 +35,25 @@ module Reek
|
|
35
35
|
configuration: {})
|
36
36
|
@configuration = configuration
|
37
37
|
@smell_types = smell_types
|
38
|
-
@detectors = smell_types.map { |klass| klass.new configuration_for(klass) }
|
39
38
|
end
|
40
39
|
|
41
40
|
def examine(context)
|
42
|
-
smell_detectors_for(context.type).flat_map do |
|
43
|
-
detector.
|
41
|
+
smell_detectors_for(context.type).flat_map do |klass|
|
42
|
+
detector = klass.new configuration: configuration_for(klass), context: context
|
43
|
+
detector.run
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
47
|
private
|
48
48
|
|
49
|
-
attr_reader :configuration, :smell_types
|
49
|
+
attr_reader :configuration, :smell_types
|
50
50
|
|
51
51
|
def configuration_for(klass)
|
52
52
|
configuration.fetch klass, {}
|
53
53
|
end
|
54
54
|
|
55
55
|
def smell_detectors_for(type)
|
56
|
-
|
57
|
-
detector.contexts.include? type
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def enabled_detectors
|
62
|
-
detectors.select { |detector| detector.config.enabled? }
|
56
|
+
smell_types.select { |detector| detector.contexts.include? type }
|
63
57
|
end
|
64
58
|
end
|
65
59
|
end
|
@@ -28,29 +28,22 @@ module Reek
|
|
28
28
|
# in any configuration file.
|
29
29
|
DEFAULT_EXCLUDE_SET = [].freeze
|
30
30
|
|
31
|
-
def initialize(
|
32
|
-
@config = SmellConfiguration.new self.class.default_config.merge(
|
31
|
+
def initialize(configuration: {}, context: nil)
|
32
|
+
@config = SmellConfiguration.new self.class.default_config.merge(configuration)
|
33
|
+
@context = context
|
33
34
|
end
|
34
35
|
|
35
36
|
def smell_type
|
36
37
|
self.class.smell_type
|
37
38
|
end
|
38
39
|
|
39
|
-
def
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
def run_for(context)
|
44
|
-
return [] unless enabled_for?(context)
|
45
|
-
return [] if exception?(context)
|
40
|
+
def run
|
41
|
+
return [] unless enabled?
|
42
|
+
return [] if exception?
|
46
43
|
|
47
44
|
sniff(context)
|
48
45
|
end
|
49
46
|
|
50
|
-
def exception?(context)
|
51
|
-
context.matches?(value(EXCLUDE_KEY, context))
|
52
|
-
end
|
53
|
-
|
54
47
|
def self.todo_configuration_for(smells)
|
55
48
|
default_exclusions = default_config.fetch 'exclude'
|
56
49
|
exclusions = default_exclusions + smells.map(&:context)
|
@@ -59,7 +52,13 @@ module Reek
|
|
59
52
|
|
60
53
|
private
|
61
54
|
|
62
|
-
|
55
|
+
attr_reader :context
|
56
|
+
|
57
|
+
def exception?
|
58
|
+
context.matches?(value(EXCLUDE_KEY, context))
|
59
|
+
end
|
60
|
+
|
61
|
+
def enabled?
|
63
62
|
config.enabled? && config_for(context)[SmellConfiguration::ENABLED_KEY] != false
|
64
63
|
end
|
65
64
|
|
@@ -40,10 +40,12 @@ module Reek
|
|
40
40
|
#
|
41
41
|
def sniff(context)
|
42
42
|
expression = context.exp
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
end
|
43
|
+
|
44
|
+
params = expression.parameters.select do |param|
|
45
|
+
uncommunicative_parameter?(parameter: param, context: context)
|
46
|
+
end
|
47
|
+
|
48
|
+
params.map(&:name).map do |name|
|
47
49
|
smell_warning(
|
48
50
|
context: context,
|
49
51
|
lines: [expression.line],
|
@@ -54,11 +56,13 @@ module Reek
|
|
54
56
|
|
55
57
|
private
|
56
58
|
|
57
|
-
def
|
58
|
-
!acceptable_name?(
|
59
|
+
def uncommunicative_parameter?(parameter:, context:)
|
60
|
+
!acceptable_name?(parameter: parameter, context: context) &&
|
61
|
+
(context.uses_param?(parameter) || !parameter.marked_unused?)
|
59
62
|
end
|
60
63
|
|
61
|
-
def acceptable_name?(
|
64
|
+
def acceptable_name?(parameter:, context:)
|
65
|
+
name = parameter.plain_name
|
62
66
|
accept_patterns(context).any? { |accept_pattern| name.match accept_pattern } ||
|
63
67
|
reject_patterns(context).none? { |reject_pattern| name.match reject_pattern }
|
64
68
|
end
|
@@ -70,11 +74,6 @@ module Reek
|
|
70
74
|
def accept_patterns(context)
|
71
75
|
Array value(ACCEPT_KEY, context)
|
72
76
|
end
|
73
|
-
|
74
|
-
# :reek:UtilityFunction
|
75
|
-
def sanitize(name)
|
76
|
-
name.to_s.gsub(/^[@\*\&]*/, '')
|
77
|
-
end
|
78
77
|
end
|
79
78
|
end
|
80
79
|
end
|
data/lib/reek/tree_dresser.rb
CHANGED
@@ -39,13 +39,13 @@ module Reek
|
|
39
39
|
#
|
40
40
|
# :reek:FeatureEnvy
|
41
41
|
# :reek:TooManyStatements: { max_statements: 6 }
|
42
|
-
def dress(sexp, comment_map
|
42
|
+
def dress(sexp, comment_map)
|
43
43
|
return sexp unless sexp.is_a? ::Parser::AST::Node
|
44
44
|
type = sexp.type
|
45
|
-
children = sexp.children.map { |child| dress(child, comment_map
|
45
|
+
children = sexp.children.map { |child| dress(child, comment_map) }
|
46
46
|
comments = comment_map[sexp]
|
47
47
|
klass_map.klass_for(type).new(type, children,
|
48
|
-
location: sexp.loc, comments: comments
|
48
|
+
location: sexp.loc, comments: comments)
|
49
49
|
end
|
50
50
|
|
51
51
|
private
|
data/lib/reek/version.rb
CHANGED
@@ -4,7 +4,7 @@ require_lib 'reek/context/module_context'
|
|
4
4
|
|
5
5
|
RSpec.describe Reek::Context::CodeContext do
|
6
6
|
context 'name recognition' do
|
7
|
-
let(:ctx) { described_class.new(
|
7
|
+
let(:ctx) { described_class.new(exp) }
|
8
8
|
let(:exp) { instance_double('Reek::AST::SexpExtensions::ModuleNode') }
|
9
9
|
let(:exp_name) { 'random_name' }
|
10
10
|
let(:full_name) { "::::::::::::::::::::#{exp_name}" }
|
@@ -43,9 +43,9 @@ RSpec.describe Reek::Context::CodeContext do
|
|
43
43
|
end
|
44
44
|
|
45
45
|
context 'when there is an outer' do
|
46
|
-
let(:ctx) { described_class.new(
|
46
|
+
let(:ctx) { described_class.new(exp) }
|
47
47
|
let(:outer_name) { 'another_random sting' }
|
48
|
-
let(:outer) { described_class.new(
|
48
|
+
let(:outer) { described_class.new(instance_double('Reek::AST::Node')) }
|
49
49
|
|
50
50
|
before do
|
51
51
|
ctx.register_with_parent outer
|
@@ -71,7 +71,7 @@ RSpec.describe Reek::Context::CodeContext do
|
|
71
71
|
let(:ctx) do
|
72
72
|
src = 'module Emptiness; end'
|
73
73
|
ast = Reek::Source::SourceCode.from(src).syntax_tree
|
74
|
-
described_class.new(
|
74
|
+
described_class.new(ast)
|
75
75
|
end
|
76
76
|
|
77
77
|
it 'yields no calls' do
|
@@ -99,7 +99,7 @@ RSpec.describe Reek::Context::CodeContext do
|
|
99
99
|
let(:ctx) do
|
100
100
|
src = "module Loneliness; def calloo; puts('hello') end; end"
|
101
101
|
ast = Reek::Source::SourceCode.from(src).syntax_tree
|
102
|
-
described_class.new(
|
102
|
+
described_class.new(ast)
|
103
103
|
end
|
104
104
|
|
105
105
|
it 'yields no ifs' do
|
@@ -149,7 +149,7 @@ RSpec.describe Reek::Context::CodeContext do
|
|
149
149
|
end
|
150
150
|
EOS
|
151
151
|
ast = Reek::Source::SourceCode.from(src).syntax_tree
|
152
|
-
ctx = described_class.new(
|
152
|
+
ctx = described_class.new(ast)
|
153
153
|
expect(ctx.each_node(:if, []).length).to eq(3)
|
154
154
|
end
|
155
155
|
end
|
@@ -166,7 +166,7 @@ RSpec.describe Reek::Context::CodeContext do
|
|
166
166
|
end
|
167
167
|
let(:expression) { Reek::Source::SourceCode.from(src).syntax_tree }
|
168
168
|
let(:outer) { nil }
|
169
|
-
let(:context) { described_class.new(
|
169
|
+
let(:context) { described_class.new(expression) }
|
170
170
|
let(:sniffer) { class_double('Reek::SmellDetectors::BaseDetector') }
|
171
171
|
|
172
172
|
before do
|
@@ -181,7 +181,7 @@ RSpec.describe Reek::Context::CodeContext do
|
|
181
181
|
end
|
182
182
|
|
183
183
|
context 'when there is an outer context' do
|
184
|
-
let(:outer) { described_class.new(
|
184
|
+
let(:outer) { described_class.new(instance_double('Reek::AST::Node')) }
|
185
185
|
|
186
186
|
before do
|
187
187
|
allow(outer).to receive(:config_for).with(sniffer).and_return(
|
@@ -196,9 +196,9 @@ RSpec.describe Reek::Context::CodeContext do
|
|
196
196
|
end
|
197
197
|
|
198
198
|
describe '#register_with_parent' do
|
199
|
-
let(:context) { described_class.new(
|
200
|
-
let(:first_child) { described_class.new(
|
201
|
-
let(:second_child) { described_class.new(
|
199
|
+
let(:context) { described_class.new(instance_double('Reek::AST::Node')) }
|
200
|
+
let(:first_child) { described_class.new(instance_double('Reek::AST::Node')) }
|
201
|
+
let(:second_child) { described_class.new(instance_double('Reek::AST::Node')) }
|
202
202
|
|
203
203
|
it "appends the element to the parent context's list of children" do
|
204
204
|
first_child.register_with_parent context
|
@@ -209,9 +209,9 @@ RSpec.describe Reek::Context::CodeContext do
|
|
209
209
|
end
|
210
210
|
|
211
211
|
describe '#each' do
|
212
|
-
let(:context) { described_class.new(
|
213
|
-
let(:first_child) { described_class.new(
|
214
|
-
let(:second_child) { described_class.new(
|
212
|
+
let(:context) { described_class.new(instance_double('Reek::AST::Node')) }
|
213
|
+
let(:first_child) { described_class.new(instance_double('Reek::AST::Node')) }
|
214
|
+
let(:second_child) { described_class.new(instance_double('Reek::AST::Node')) }
|
215
215
|
|
216
216
|
it 'yields each child' do
|
217
217
|
first_child.register_with_parent context
|
@@ -4,53 +4,53 @@ require_lib 'reek/context/ghost_context'
|
|
4
4
|
|
5
5
|
RSpec.describe Reek::Context::GhostContext do
|
6
6
|
let(:exp) { instance_double('Reek::AST::Node') }
|
7
|
-
let(:parent) { Reek::Context::CodeContext.new(
|
7
|
+
let(:parent) { Reek::Context::CodeContext.new(exp) }
|
8
8
|
|
9
9
|
describe '#register_with_parent' do
|
10
10
|
it 'does not append itself to its parent' do
|
11
|
-
ghost = described_class.new(
|
11
|
+
ghost = described_class.new(nil)
|
12
12
|
ghost.register_with_parent(parent)
|
13
13
|
expect(parent.children).not_to include ghost
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
17
|
describe '#append_child_context' do
|
18
|
-
let(:ghost) { described_class.new(
|
18
|
+
let(:ghost) { described_class.new(nil) }
|
19
19
|
|
20
20
|
before do
|
21
21
|
ghost.register_with_parent(parent)
|
22
22
|
end
|
23
23
|
|
24
24
|
it 'appends the child to the grandparent context' do
|
25
|
-
child = Reek::Context::CodeContext.new(
|
25
|
+
child = Reek::Context::CodeContext.new(sexp(:foo))
|
26
26
|
child.register_with_parent(ghost)
|
27
27
|
|
28
28
|
expect(parent.children).to include child
|
29
29
|
end
|
30
30
|
|
31
31
|
it "sets the child's parent to the grandparent context" do
|
32
|
-
child = Reek::Context::CodeContext.new(
|
32
|
+
child = Reek::Context::CodeContext.new(sexp(:foo))
|
33
33
|
child.register_with_parent(ghost)
|
34
34
|
|
35
35
|
expect(child.parent).to eq parent
|
36
36
|
end
|
37
37
|
|
38
38
|
it 'appends the child to the list of children' do
|
39
|
-
child = Reek::Context::CodeContext.new(
|
39
|
+
child = Reek::Context::CodeContext.new(sexp(:foo))
|
40
40
|
child.register_with_parent(ghost)
|
41
41
|
|
42
42
|
expect(ghost.children).to include child
|
43
43
|
end
|
44
44
|
|
45
45
|
context 'if the grandparent is also a ghost' do
|
46
|
-
let(:child_ghost) { described_class.new(
|
46
|
+
let(:child_ghost) { described_class.new(nil) }
|
47
47
|
|
48
48
|
before do
|
49
49
|
child_ghost.register_with_parent(ghost)
|
50
50
|
end
|
51
51
|
|
52
52
|
it 'sets the childs parent to its remote ancestor' do
|
53
|
-
child = Reek::Context::CodeContext.new(
|
53
|
+
child = Reek::Context::CodeContext.new(sexp(:foo))
|
54
54
|
child.register_with_parent(child_ghost)
|
55
55
|
|
56
56
|
expect(child.parent).to eq parent
|
@@ -2,7 +2,7 @@ require_relative '../../spec_helper'
|
|
2
2
|
require_lib 'reek/context/method_context'
|
3
3
|
|
4
4
|
RSpec.describe Reek::Context::MethodContext do
|
5
|
-
let(:method_context) { described_class.new(
|
5
|
+
let(:method_context) { described_class.new(exp, nil) }
|
6
6
|
|
7
7
|
describe '#matches?' do
|
8
8
|
let(:exp) { instance_double('Reek::AST::SexpExtensions::ModuleNode').as_null_object }
|
@@ -31,7 +31,7 @@ RSpec.describe Reek::Context::MethodContext do
|
|
31
31
|
describe '#default_assignments' do
|
32
32
|
def assignments_from(src)
|
33
33
|
exp = Reek::Source::SourceCode.from(src).syntax_tree
|
34
|
-
ctx = Reek::Context::MethodContext.new(
|
34
|
+
ctx = Reek::Context::MethodContext.new(exp, nil)
|
35
35
|
ctx.default_assignments
|
36
36
|
end
|
37
37
|
|
@@ -32,9 +32,9 @@ RSpec.describe Reek::Context::ModuleContext do
|
|
32
32
|
let(:first_def) { instance_double('Reek::AST::SexpExtensions::DefNode', name: :foo) }
|
33
33
|
let(:second_def) { instance_double('Reek::AST::SexpExtensions::DefNode') }
|
34
34
|
|
35
|
-
let(:context) { described_class.new(
|
36
|
-
let(:first_child) { Reek::Context::MethodContext.new(
|
37
|
-
let(:second_child) { Reek::Context::MethodContext.new(
|
35
|
+
let(:context) { described_class.new(main_exp) }
|
36
|
+
let(:first_child) { Reek::Context::MethodContext.new(first_def, main_exp) }
|
37
|
+
let(:second_child) { Reek::Context::MethodContext.new(second_def, main_exp) }
|
38
38
|
|
39
39
|
it 'sets visibility on subsequent child contexts' do
|
40
40
|
context.append_child_context first_child
|
@@ -220,6 +220,26 @@ RSpec.describe Reek::ContextBuilder do
|
|
220
220
|
described_class.new(syntax_tree(code)).context_tree
|
221
221
|
end
|
222
222
|
|
223
|
+
it 'marks instance methods when using a def modifier' do
|
224
|
+
code = <<-EOS
|
225
|
+
class Foo
|
226
|
+
private def bar
|
227
|
+
end
|
228
|
+
|
229
|
+
def baz
|
230
|
+
end
|
231
|
+
end
|
232
|
+
EOS
|
233
|
+
|
234
|
+
root = context_tree_for(code)
|
235
|
+
module_context = root.children.first
|
236
|
+
method_contexts = module_context.children
|
237
|
+
aggregate_failures do
|
238
|
+
expect(method_contexts[0].visibility).to eq :private
|
239
|
+
expect(method_contexts[1].visibility).to eq :public
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
223
243
|
it 'does not mark class methods with instance visibility' do
|
224
244
|
code = <<-EOS
|
225
245
|
class Foo
|
@@ -49,17 +49,6 @@ RSpec.describe Reek::SmellDetectors::IrresponsibleModule do
|
|
49
49
|
expect(src).not_to reek_of(:IrresponsibleModule)
|
50
50
|
end
|
51
51
|
|
52
|
-
it "does not report re-opened #{scope} in the same file" do
|
53
|
-
src = <<-EOS
|
54
|
-
# This comment describes Alfa
|
55
|
-
#{scope} Alfa; end
|
56
|
-
|
57
|
-
#{scope} Alfa; def bravo; end; end
|
58
|
-
EOS
|
59
|
-
|
60
|
-
expect(src).not_to reek_of(:IrresponsibleModule)
|
61
|
-
end
|
62
|
-
|
63
52
|
it "reports a #{scope} with an empty comment" do
|
64
53
|
src = <<-EOS
|
65
54
|
#
|
@@ -32,15 +32,6 @@ RSpec.describe Reek::SmellDetectors::UncommunicativeParameterName do
|
|
32
32
|
{ 'alfa.' => 'with a receiver',
|
33
33
|
'' => 'without a receiver' }.each do |host, description|
|
34
34
|
context "in a method definition #{description}" do
|
35
|
-
it 'does not recognise *' do
|
36
|
-
expect("def #{host}bravo(*); end").not_to reek_of(:UncommunicativeParameterName)
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'does not report unused parameters' do
|
40
|
-
src = "def #{host}bravo(x); charlie; end"
|
41
|
-
expect(src).not_to reek_of(:UncommunicativeParameterName)
|
42
|
-
end
|
43
|
-
|
44
35
|
it 'does not report two-letter parameter names' do
|
45
36
|
src = "def #{host}bravo(ab); charlie(ab); end"
|
46
37
|
expect(src).not_to reek_of(:UncommunicativeParameterName)
|
@@ -56,6 +47,26 @@ RSpec.describe Reek::SmellDetectors::UncommunicativeParameterName do
|
|
56
47
|
expect(src).to reek_of(:UncommunicativeParameterName, name: 'param2')
|
57
48
|
end
|
58
49
|
|
50
|
+
it 'reports unused parameters' do
|
51
|
+
src = "def #{host}bravo(x); charlie; end"
|
52
|
+
expect(src).to reek_of(:UncommunicativeParameterName)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'reports splat parameters' do
|
56
|
+
expect("def #{host}bravo(*a); charlie(a); end").
|
57
|
+
to reek_of(:UncommunicativeParameterName, name: 'a')
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'reports double splat parameters' do
|
61
|
+
expect("def #{host}bravo(**a); charlie(a); end").
|
62
|
+
to reek_of(:UncommunicativeParameterName, name: 'a')
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'reports block parameters' do
|
66
|
+
expect("def #{host}bravo(&a); charlie(a); end").
|
67
|
+
to reek_of(:UncommunicativeParameterName, name: 'a')
|
68
|
+
end
|
69
|
+
|
59
70
|
it 'does not report unused anonymous parameter' do
|
60
71
|
src = "def #{host}bravo(_); charlie; end"
|
61
72
|
expect(src).not_to reek_of(:UncommunicativeParameterName)
|
@@ -63,12 +74,20 @@ RSpec.describe Reek::SmellDetectors::UncommunicativeParameterName do
|
|
63
74
|
|
64
75
|
it 'reports used anonymous parameter' do
|
65
76
|
src = "def #{host}bravo(_); charlie(_) end"
|
66
|
-
expect(src).to reek_of(:UncommunicativeParameterName)
|
77
|
+
expect(src).to reek_of(:UncommunicativeParameterName, name: '_')
|
67
78
|
end
|
68
79
|
|
69
80
|
it 'reports used parameters marked as unused' do
|
70
81
|
src = "def #{host}bravo(_unused) charlie(_unused) end"
|
71
|
-
expect(src).to reek_of(:UncommunicativeParameterName)
|
82
|
+
expect(src).to reek_of(:UncommunicativeParameterName, name: '_unused')
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'does not report anonymous splat' do
|
86
|
+
expect("def #{host}bravo(*); end").not_to reek_of(:UncommunicativeParameterName)
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'does not report anonymous double splat' do
|
90
|
+
expect("def #{host}bravo(**); end").not_to reek_of(:UncommunicativeParameterName)
|
72
91
|
end
|
73
92
|
|
74
93
|
it 'reports names inside array decomposition' do
|
@@ -103,6 +103,17 @@ RSpec.describe Reek::SmellDetectors::UnusedPrivateMethod do
|
|
103
103
|
to reek_of(:UnusedPrivateMethod, name: 'bravo', lines: [3]).
|
104
104
|
and reek_of(:UnusedPrivateMethod, name: 'charlie', lines: [4])
|
105
105
|
end
|
106
|
+
|
107
|
+
it 'reports instance methods defined as private with a modifier' do
|
108
|
+
source = <<-EOF
|
109
|
+
class Alfa
|
110
|
+
private def bravo; end
|
111
|
+
end
|
112
|
+
EOF
|
113
|
+
|
114
|
+
expect(source).
|
115
|
+
to reek_of(:UnusedPrivateMethod, name: 'bravo')
|
116
|
+
end
|
106
117
|
end
|
107
118
|
|
108
119
|
describe 'configuring the detector via source code comment' do
|
@@ -221,6 +221,18 @@ RSpec.describe Reek::SmellDetectors::UtilityFunction do
|
|
221
221
|
|
222
222
|
expect(src).not_to reek_of(:UtilityFunction).with_config(config)
|
223
223
|
end
|
224
|
+
|
225
|
+
it 'does not report UtilityFunction when private is used as a def modifier' do
|
226
|
+
src = <<-EOS
|
227
|
+
class Alfa
|
228
|
+
private def bravo(charlie)
|
229
|
+
charlie.delta.echo
|
230
|
+
end
|
231
|
+
end
|
232
|
+
EOS
|
233
|
+
|
234
|
+
expect(src).not_to reek_of(:UtilityFunction).with_config(config)
|
235
|
+
end
|
224
236
|
end
|
225
237
|
|
226
238
|
context 'protected methods' do
|
@@ -236,6 +248,46 @@ RSpec.describe Reek::SmellDetectors::UtilityFunction do
|
|
236
248
|
|
237
249
|
expect(src).not_to reek_of(:UtilityFunction).with_config(config)
|
238
250
|
end
|
251
|
+
|
252
|
+
it 'does not report UtilityFunction when protected is used as a def modifier' do
|
253
|
+
src = <<-EOS
|
254
|
+
class Alfa
|
255
|
+
protected def bravo(charlie)
|
256
|
+
charlie.delta.echo
|
257
|
+
end
|
258
|
+
end
|
259
|
+
EOS
|
260
|
+
|
261
|
+
expect(src).not_to reek_of(:UtilityFunction).with_config(config)
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
describe 'disabling with a comment' do
|
267
|
+
it 'disables the method following the comment' do
|
268
|
+
src = <<-EOS
|
269
|
+
class Alfa
|
270
|
+
# :reek:UtilityFunction
|
271
|
+
def bravo(charlie)
|
272
|
+
charlie.delta.echo
|
273
|
+
end
|
274
|
+
end
|
275
|
+
EOS
|
276
|
+
|
277
|
+
expect(src).not_to reek_of(:UtilityFunction)
|
278
|
+
end
|
279
|
+
|
280
|
+
it 'disables a method when it has a visibility modifier' do
|
281
|
+
src = <<-EOS
|
282
|
+
class Alfa
|
283
|
+
# :reek:UtilityFunction
|
284
|
+
private def bravo(charlie)
|
285
|
+
charlie.delta.echo
|
286
|
+
end
|
287
|
+
end
|
288
|
+
EOS
|
289
|
+
|
290
|
+
expect(src).not_to reek_of(:UtilityFunction)
|
239
291
|
end
|
240
292
|
end
|
241
293
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reek
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.7.
|
4
|
+
version: 4.7.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Rutherford
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2017-
|
14
|
+
date: 2017-07-24 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: codeclimate-engine-rb
|
@@ -443,7 +443,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
443
443
|
version: '0'
|
444
444
|
requirements: []
|
445
445
|
rubyforge_project:
|
446
|
-
rubygems_version: 2.
|
446
|
+
rubygems_version: 2.6.12
|
447
447
|
signing_key:
|
448
448
|
specification_version: 4
|
449
449
|
summary: Code smell detector for Ruby
|