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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c782c9f7772d236e5608adea55c1dbef8ab620b8
4
- data.tar.gz: 7851ccc5dd286f7488b4460a021179e35698429d
3
+ metadata.gz: 5e3c2e9cc70f29c322ad9284d8412aafc7d1dba9
4
+ data.tar.gz: b2bbee88bc846020a28cb27214d0ea09a1fbb1c7
5
5
  SHA512:
6
- metadata.gz: 6147cba71db38cd92ca1c99ad7cfb9e002c7287bc114d8d318f99650d6ca4f3f06765f07d2f291dfedddfb394a3d84433a3f37b8bbea25c701e0d0bcaae7304b
7
- data.tar.gz: 3f26e46e871f05bebe920624c33d12154fc7b773b426d263c2a6f2d14f247bc93d4d35683a150e8878636b5f729cc1fc0a96cecd7de2adaa99787652434f7946
6
+ metadata.gz: cc8a77b31dcbc0be82506493b24654f299cd21c5f8ecf2484d962a73363072c372d09d8d9e58223197c6fb9934a0de0f42481bf131146297d3f653194219110c
7
+ data.tar.gz: 5fca779e7aa91f5a7e6b943fd3923f4cada5a50364e3952ed30def4a16dd112b3267bcca1fde743e627008cc534c9c82ba223dd4a4f8502bfb346a7b2da5154f
@@ -1,5 +1,9 @@
1
1
  # Change log
2
2
 
3
+ ## 4.3.0 (2016-08-23)
4
+
5
+ * (backus) Add ManualDispatch smell.
6
+
3
7
  ## 4.2.5 (2016-08-23)
4
8
 
5
9
  * (mvz) Detect safe navigation operator and report on it.
@@ -38,6 +38,9 @@ LongYieldList:
38
38
  enabled: true
39
39
  exclude: []
40
40
  max_params: 3
41
+ ManualDispatch:
42
+ enabled: true
43
+ exclude: []
41
44
  ModuleInitialize:
42
45
  enabled: true
43
46
  exclude: []
@@ -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).
@@ -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 -- 120 warnings:
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 -- 104 warnings:
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
- 272 total warnings
294
+ 277 total warnings
290
295
  """
@@ -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
@@ -7,6 +7,6 @@ module Reek
7
7
  # @public
8
8
  module Version
9
9
  # @public
10
- STRING = '4.2.5'.freeze
10
+ STRING = '4.3.0'.freeze
11
11
  end
12
12
  end
@@ -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.2.5
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: