reek 4.2.5 → 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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:
|