reek 4.2.5 → 4.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/defaults.reek +3 -0
- data/docs/Manual-Dispatch.md +30 -0
- data/features/samples.feature +8 -3
- data/lib/reek/smells.rb +1 -0
- data/lib/reek/smells/manual_dispatch.rb +32 -0
- data/lib/reek/version.rb +1 -1
- data/spec/reek/smells/manual_dispatch_spec.rb +47 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5e3c2e9cc70f29c322ad9284d8412aafc7d1dba9
|
4
|
+
data.tar.gz: b2bbee88bc846020a28cb27214d0ea09a1fbb1c7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cc8a77b31dcbc0be82506493b24654f299cd21c5f8ecf2484d962a73363072c372d09d8d9e58223197c6fb9934a0de0f42481bf131146297d3f653194219110c
|
7
|
+
data.tar.gz: 5fca779e7aa91f5a7e6b943fd3923f4cada5a50364e3952ed30def4a16dd112b3267bcca1fde743e627008cc534c9c82ba223dd4a4f8502bfb346a7b2da5154f
|
data/CHANGELOG.md
CHANGED
data/defaults.reek
CHANGED
@@ -0,0 +1,30 @@
|
|
1
|
+
## Introduction
|
2
|
+
|
3
|
+
Reek reports a _Manual Dispatch_ smell if it finds source code that manually checks whether an object responds to a method before that method is called. Manual dispatch is a type of [Simulated Polymorphism](Simulated-Polymorphism.md) which leads to code that is harder to reason about, debug, and refactor.
|
4
|
+
|
5
|
+
## Example
|
6
|
+
|
7
|
+
```Ruby
|
8
|
+
class MyManualDispatcher
|
9
|
+
attr_reader :foo
|
10
|
+
|
11
|
+
def initialize(foo)
|
12
|
+
@foo = foo
|
13
|
+
end
|
14
|
+
|
15
|
+
def call
|
16
|
+
foo.bar if foo.respond_to?(:bar)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
```
|
20
|
+
|
21
|
+
Reek would emit the following warning:
|
22
|
+
|
23
|
+
```
|
24
|
+
test.rb -- 1 warning:
|
25
|
+
[9]: MyManualDispatcher manually dispatches method call (ManualDispatch)
|
26
|
+
```
|
27
|
+
|
28
|
+
## Configuration
|
29
|
+
|
30
|
+
_Manual Dispatch_ offers the [Basic Smell Options](Basic-Smell-Options.md).
|
data/features/samples.feature
CHANGED
@@ -60,7 +60,7 @@ Feature: Basic smell detection
|
|
60
60
|
UncommunicativeVariableName: Inline::C#module_name has the variable name 'x' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Variable-Name.md]
|
61
61
|
UncommunicativeVariableName: Inline::C#parse_signature has the variable name 'x' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Variable-Name.md]
|
62
62
|
UtilityFunction: Inline::C#strip_comments doesn't depend on instance state (maybe move it to another class?) [https://github.com/troessner/reek/blob/master/docs/Utility-Function.md]
|
63
|
-
optparse.rb --
|
63
|
+
optparse.rb -- 124 warnings:
|
64
64
|
Attribute: OptionParser#banner is a writable attribute [https://github.com/troessner/reek/blob/master/docs/Attribute.md]
|
65
65
|
Attribute: OptionParser#default_argv is a writable attribute [https://github.com/troessner/reek/blob/master/docs/Attribute.md]
|
66
66
|
Attribute: OptionParser#program_name is a writable attribute [https://github.com/troessner/reek/blob/master/docs/Attribute.md]
|
@@ -121,6 +121,10 @@ Feature: Basic smell detection
|
|
121
121
|
LongParameterList: OptionParser::List#update has 5 parameters [https://github.com/troessner/reek/blob/master/docs/Long-Parameter-List.md]
|
122
122
|
LongParameterList: OptionParser::Switch#initialize has 7 parameters [https://github.com/troessner/reek/blob/master/docs/Long-Parameter-List.md]
|
123
123
|
LongParameterList: OptionParser::Switch#summarize has 5 parameters [https://github.com/troessner/reek/blob/master/docs/Long-Parameter-List.md]
|
124
|
+
ManualDispatch: OptionParser#make_switch manually dispatches method call [https://github.com/troessner/reek/blob/master/docs/Manual-Dispatch.md]
|
125
|
+
ManualDispatch: OptionParser::List#accept manually dispatches method call [https://github.com/troessner/reek/blob/master/docs/Manual-Dispatch.md]
|
126
|
+
ManualDispatch: OptionParser::List#add_banner manually dispatches method call [https://github.com/troessner/reek/blob/master/docs/Manual-Dispatch.md]
|
127
|
+
ManualDispatch: OptionParser::List#summarize manually dispatches method call [https://github.com/troessner/reek/blob/master/docs/Manual-Dispatch.md]
|
124
128
|
ModuleInitialize: OptionParser::Arguable has initialize method [https://github.com/troessner/reek/blob/master/docs/Module-Initialize.md]
|
125
129
|
NestedIterators: OptionParser#make_switch contains iterators nested 2 deep [https://github.com/troessner/reek/blob/master/docs/Nested-Iterators.md]
|
126
130
|
NilCheck: OptionParser#make_switch performs a nil-check [https://github.com/troessner/reek/blob/master/docs/Nil-Check.md]
|
@@ -181,7 +185,7 @@ Feature: Basic smell detection
|
|
181
185
|
UnusedParameters: OptionParser::Completion#convert has unused parameter 'opt' [https://github.com/troessner/reek/blob/master/docs/Unused-Parameters.md]
|
182
186
|
UnusedParameters: OptionParser::Switch::NoArgument#parse has unused parameter 'argv' [https://github.com/troessner/reek/blob/master/docs/Unused-Parameters.md]
|
183
187
|
UnusedParameters: OptionParser::Switch::OptionalArgument#parse has unused parameter 'argv' [https://github.com/troessner/reek/blob/master/docs/Unused-Parameters.md]
|
184
|
-
redcloth.rb --
|
188
|
+
redcloth.rb -- 105 warnings:
|
185
189
|
Attribute: RedCloth#filter_html is a writable attribute [https://github.com/troessner/reek/blob/master/docs/Attribute.md]
|
186
190
|
Attribute: RedCloth#filter_styles is a writable attribute [https://github.com/troessner/reek/blob/master/docs/Attribute.md]
|
187
191
|
Attribute: RedCloth#hard_breaks is a writable attribute [https://github.com/troessner/reek/blob/master/docs/Attribute.md]
|
@@ -219,6 +223,7 @@ Feature: Basic smell detection
|
|
219
223
|
LongParameterList: RedCloth#textile_bq has 4 parameters [https://github.com/troessner/reek/blob/master/docs/Long-Parameter-List.md]
|
220
224
|
LongParameterList: RedCloth#textile_fn_ has 5 parameters [https://github.com/troessner/reek/blob/master/docs/Long-Parameter-List.md]
|
221
225
|
LongParameterList: RedCloth#textile_p has 4 parameters [https://github.com/troessner/reek/blob/master/docs/Long-Parameter-List.md]
|
226
|
+
ManualDispatch: RedCloth#block_textile_prefix manually dispatches method call [https://github.com/troessner/reek/blob/master/docs/Manual-Dispatch.md]
|
222
227
|
NestedIterators: RedCloth#block_textile_lists contains iterators nested 3 deep [https://github.com/troessner/reek/blob/master/docs/Nested-Iterators.md]
|
223
228
|
NestedIterators: RedCloth#block_textile_table contains iterators nested 2 deep [https://github.com/troessner/reek/blob/master/docs/Nested-Iterators.md]
|
224
229
|
NestedIterators: RedCloth#block_textile_table contains iterators nested 3 deep [https://github.com/troessner/reek/blob/master/docs/Nested-Iterators.md]
|
@@ -286,5 +291,5 @@ Feature: Basic smell detection
|
|
286
291
|
UtilityFunction: RedCloth#lT doesn't depend on instance state (maybe move it to another class?) [https://github.com/troessner/reek/blob/master/docs/Utility-Function.md]
|
287
292
|
UtilityFunction: RedCloth#no_textile doesn't depend on instance state (maybe move it to another class?) [https://github.com/troessner/reek/blob/master/docs/Utility-Function.md]
|
288
293
|
UtilityFunction: RedCloth#v_align doesn't depend on instance state (maybe move it to another class?) [https://github.com/troessner/reek/blob/master/docs/Utility-Function.md]
|
289
|
-
|
294
|
+
277 total warnings
|
290
295
|
"""
|
data/lib/reek/smells.rb
CHANGED
@@ -9,6 +9,7 @@ require_relative 'smells/feature_envy'
|
|
9
9
|
require_relative 'smells/irresponsible_module'
|
10
10
|
require_relative 'smells/long_parameter_list'
|
11
11
|
require_relative 'smells/long_yield_list'
|
12
|
+
require_relative 'smells/manual_dispatch'
|
12
13
|
require_relative 'smells/module_initialize'
|
13
14
|
require_relative 'smells/nested_iterators'
|
14
15
|
require_relative 'smells/nil_check'
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_relative 'smell_detector'
|
3
|
+
require_relative 'smell_warning'
|
4
|
+
|
5
|
+
module Reek
|
6
|
+
module Smells
|
7
|
+
#
|
8
|
+
# A Manual Dispatch occurs when a method is only called after a
|
9
|
+
# manual check that the method receiver is of the correct type.
|
10
|
+
#
|
11
|
+
# The +ManualDispatch+ checker reports any invocation of +respond_to?+
|
12
|
+
#
|
13
|
+
# See {file:docs/Manual-Dispatch.md} for details.
|
14
|
+
class ManualDispatch < SmellDetector
|
15
|
+
MESSAGE = 'manually dispatches method call'.freeze
|
16
|
+
|
17
|
+
#
|
18
|
+
# Checks for +respond_to?+ usage within the given method
|
19
|
+
#
|
20
|
+
# @return [Array<SmellWarning>]
|
21
|
+
#
|
22
|
+
# :reek:FeatureEnvy
|
23
|
+
def sniff(ctx)
|
24
|
+
ctx.each_node(:send).flat_map do |node|
|
25
|
+
next unless node.name.equal?(:respond_to?)
|
26
|
+
|
27
|
+
smell_warning(context: ctx, lines: [node.line], message: MESSAGE)
|
28
|
+
end.compact
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/reek/version.rb
CHANGED
@@ -0,0 +1,47 @@
|
|
1
|
+
require_relative '../../spec_helper'
|
2
|
+
require_lib 'reek/smells/too_many_constants'
|
3
|
+
require_relative 'smell_detector_shared'
|
4
|
+
|
5
|
+
RSpec.describe Reek::Smells::ManualDispatch do
|
6
|
+
it 'reports manual dispatch smell when using #respond_to?' do
|
7
|
+
src = <<-EOS
|
8
|
+
class Dummy
|
9
|
+
def call
|
10
|
+
fail if unrelated_guard_clause?
|
11
|
+
|
12
|
+
if foo.respond_to?(:bar, true)
|
13
|
+
hello
|
14
|
+
foo.baz
|
15
|
+
foo.bar
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
EOS
|
20
|
+
|
21
|
+
expect(src).to reek_of(:ManualDispatch, message: 'manually dispatches method call', lines: [5])
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'reports manual dispatch smell when using #respond_to? on implicit self' do
|
25
|
+
src = <<-EOS
|
26
|
+
class Dummy
|
27
|
+
def call
|
28
|
+
bar if respond_to?(:bar)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
EOS
|
32
|
+
|
33
|
+
expect(src).to reek_of(:ManualDispatch)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'reports manual dispatch within a conditional' do
|
37
|
+
src = <<-EOS
|
38
|
+
class Dummy
|
39
|
+
def call
|
40
|
+
foo.respond_to?(:bar) && foo.bar
|
41
|
+
end
|
42
|
+
end
|
43
|
+
EOS
|
44
|
+
|
45
|
+
expect(src).to reek_of(:ManualDispatch)
|
46
|
+
end
|
47
|
+
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.
|
4
|
+
version: 4.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Rutherford
|
@@ -108,6 +108,7 @@ files:
|
|
108
108
|
- docs/Large-Class.md
|
109
109
|
- docs/Long-Parameter-List.md
|
110
110
|
- docs/Long-Yield-List.md
|
111
|
+
- docs/Manual-Dispatch.md
|
111
112
|
- docs/Module-Initialize.md
|
112
113
|
- docs/Nested-Iterators.md
|
113
114
|
- docs/Nil-Check.md
|
@@ -238,6 +239,7 @@ files:
|
|
238
239
|
- lib/reek/smells/irresponsible_module.rb
|
239
240
|
- lib/reek/smells/long_parameter_list.rb
|
240
241
|
- lib/reek/smells/long_yield_list.rb
|
242
|
+
- lib/reek/smells/manual_dispatch.rb
|
241
243
|
- lib/reek/smells/module_initialize.rb
|
242
244
|
- lib/reek/smells/nested_iterators.rb
|
243
245
|
- lib/reek/smells/nil_check.rb
|
@@ -346,6 +348,7 @@ files:
|
|
346
348
|
- spec/reek/smells/irresponsible_module_spec.rb
|
347
349
|
- spec/reek/smells/long_parameter_list_spec.rb
|
348
350
|
- spec/reek/smells/long_yield_list_spec.rb
|
351
|
+
- spec/reek/smells/manual_dispatch_spec.rb
|
349
352
|
- spec/reek/smells/module_initialize_spec.rb
|
350
353
|
- spec/reek/smells/nested_iterators_spec.rb
|
351
354
|
- spec/reek/smells/nil_check_spec.rb
|
@@ -412,4 +415,3 @@ signing_key:
|
|
412
415
|
specification_version: 4
|
413
416
|
summary: Code smell detector for Ruby
|
414
417
|
test_files: []
|
415
|
-
has_rdoc:
|