reek 4.8.1 → 4.8.2

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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/README.md +3 -3
  4. data/docs/Instance-Variable-Assumption.md +1 -1
  5. data/docs/Uncommunicative-Method-Name.md +2 -2
  6. data/docs/Uncommunicative-Module-Name.md +1 -1
  7. data/docs/Uncommunicative-Parameter-Name.md +1 -1
  8. data/features/command_line_interface/basic_usage.feature +2 -2
  9. data/features/command_line_interface/options.feature +1 -1
  10. data/features/command_line_interface/show_progress.feature +4 -4
  11. data/features/command_line_interface/smell_selection.feature +1 -1
  12. data/features/command_line_interface/smells_count.feature +6 -6
  13. data/features/command_line_interface/stdin.feature +5 -5
  14. data/features/configuration_files/accept_setting.feature +6 -6
  15. data/features/configuration_files/directory_specific_directives.feature +20 -20
  16. data/features/configuration_files/exclude_directives.feature +3 -3
  17. data/features/configuration_files/exclude_paths_directives.feature +4 -4
  18. data/features/configuration_files/masking_smells.feature +4 -4
  19. data/features/configuration_files/mix_accept_reject_setting.feature +7 -7
  20. data/features/configuration_files/reject_setting.feature +12 -12
  21. data/features/configuration_files/unused_private_method.feature +4 -4
  22. data/features/configuration_loading.feature +3 -3
  23. data/features/configuration_via_source_comments/erroneous_source_comments.feature +2 -2
  24. data/features/configuration_via_source_comments/well_formed_source_comments.feature +2 -2
  25. data/features/locales.feature +2 -2
  26. data/features/rake_task/rake_task.feature +15 -15
  27. data/features/reports/json.feature +1 -4
  28. data/features/reports/reports.feature +26 -26
  29. data/features/reports/yaml.feature +0 -3
  30. data/features/samples.feature +287 -287
  31. data/features/support/env.rb +2 -2
  32. data/features/todo_list.feature +10 -10
  33. data/lib/reek/cli/options.rb +2 -1
  34. data/lib/reek/documentation_link.rb +28 -0
  35. data/lib/reek/errors/bad_detector_configuration_key_in_comment_error.rb +3 -2
  36. data/lib/reek/errors/bad_detector_in_comment_error.rb +3 -2
  37. data/lib/reek/errors/garbage_detector_configuration_in_comment_error.rb +3 -2
  38. data/lib/reek/report/code_climate/code_climate_configuration.yml +1 -1
  39. data/lib/reek/report/formatter/wiki_link_warning_formatter.rb +2 -15
  40. data/lib/reek/smell_detectors/feature_envy.rb +1 -0
  41. data/lib/reek/smell_warning.rb +5 -0
  42. data/lib/reek/version.rb +1 -1
  43. data/spec/reek/documentation_link_spec.rb +20 -0
  44. data/spec/reek/report/json_report_spec.rb +2 -2
  45. data/spec/reek/report/yaml_report_spec.rb +2 -2
  46. data/spec/reek/smell_detectors/feature_envy_spec.rb +45 -0
  47. metadata +4 -2
@@ -13,11 +13,11 @@ end
13
13
  #
14
14
  class ReekWorld
15
15
  def reek(args)
16
- run_simple("reek --no-color #{args}", false)
16
+ run_simple("reek --no-color --no-wiki-links #{args}", false)
17
17
  end
18
18
 
19
19
  def reek_with_pipe(stdin, args)
20
- run "reek --no-color #{args}"
20
+ run "reek --no-color --no-wiki-links #{args}"
21
21
  type(stdin)
22
22
  close_input
23
23
  end
@@ -15,8 +15,8 @@ Feature: Auto-generate a todo file
15
15
  And it reports:
16
16
  """
17
17
  smelly.rb -- 2 warnings:
18
- [4]:UncommunicativeMethodName: Smelly#x has the name 'x' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Method-Name.md]
19
- [5]:UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Variable-Name.md]
18
+ [4]:UncommunicativeMethodName: Smelly#x has the name 'x'
19
+ [5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'
20
20
  """
21
21
  When I run reek --todo smelly.rb
22
22
  Then it succeeds
@@ -59,15 +59,15 @@ Feature: Auto-generate a todo file
59
59
  UncommunicativeMethodName:
60
60
  enabled: false
61
61
  """
62
- When I run `reek -c .todo.reek smelly.rb`
62
+ When I run reek -c .todo.reek smelly.rb
63
63
  Then it reports:
64
64
  """
65
65
  smelly.rb -- 1 warning:
66
- [5]:UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Variable-Name.md]
66
+ [5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'
67
67
  """
68
- When I run `reek --todo smelly.rb`
68
+ When I run reek --todo smelly.rb
69
69
  Then it succeeds
70
- When I run `reek -c .todo.reek smelly.rb`
70
+ When I run reek -c .todo.reek smelly.rb
71
71
  Then it reports nothing
72
72
 
73
73
  Scenario: Ignore existing other configuration files that are passed explicitly
@@ -80,13 +80,13 @@ Feature: Auto-generate a todo file
80
80
  UncommunicativeMethodName:
81
81
  enabled: false
82
82
  """
83
- When I run `reek -c config.reek smelly.rb`
83
+ When I run reek -c config.reek smelly.rb
84
84
  Then it reports:
85
85
  """
86
86
  smelly.rb -- 1 warning:
87
- [5]:UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Variable-Name.md]
87
+ [5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'
88
88
  """
89
- When I run `reek -c config.reek --todo smelly.rb`
89
+ When I run reek -c config.reek --todo smelly.rb
90
90
  Then it succeeds
91
- When I run `reek -c .todo.reek smelly.rb`
91
+ When I run reek -c .todo.reek smelly.rb
92
92
  Then it reports nothing
@@ -4,6 +4,7 @@ require 'optparse'
4
4
  require 'rainbow'
5
5
  require_relative '../version'
6
6
  require_relative 'status'
7
+ require_relative '../documentation_link'
7
8
 
8
9
  module Reek
9
10
  module CLI
@@ -105,7 +106,7 @@ module Reek
105
106
  parser.on('--smell SMELL',
106
107
  'Only look for a specific smell.',
107
108
  'Call it like this: reek --smell PrimaDonnaMethod source.rb',
108
- 'Check out https://github.com/troessner/reek/blob/master/docs/Code-Smells.md '\
109
+ "Check out #{DocumentationLink.build('Code Smells')} "\
109
110
  'for a list of smells') do |smell|
110
111
  smells_to_detect << smell
111
112
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Reek
4
+ # Generate versioned links to our documentation
5
+ module DocumentationLink
6
+ HELP_LINK_TEMPLATE = 'https://github.com/troessner/reek/blob/v%<version>s/docs/%<item>s.md'.freeze
7
+
8
+ module_function
9
+
10
+ # Build link to the documentation about the given subject for the current
11
+ # version of Reek. The subject can be either a smell type like
12
+ # 'FeatureEnvy' or a general subject like 'Rake Task'.
13
+ #
14
+ # @param subject [String]
15
+ # @return [String] - the full URL for the relevant documentation
16
+ def build(subject)
17
+ Kernel.format(HELP_LINK_TEMPLATE, version: Version::STRING, item: name_to_param(subject))
18
+ end
19
+
20
+ # Convert the given subject name to a form that is acceptable in a URL.
21
+ def name_to_param(name)
22
+ # Splits the subject on the start of capitalized words, optionally
23
+ # preceded by a space. The space is discarded, the start of the word is
24
+ # not.
25
+ name.split(/ *(?=[A-Z][a-z])/).join('-')
26
+ end
27
+ end
28
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'base_error'
4
+ require_relative '../documentation_link'
4
5
 
5
6
  module Reek
6
7
  module Errors
@@ -17,8 +18,8 @@ module Reek
17
18
  %<comment>s
18
19
 
19
20
  Please see the Reek docs for:
20
- * how to configure Reek via source code comments: https://github.com/troessner/reek/blob/master/docs/Smell-Suppression.md
21
- * what basic options are available: https://github.com/troessner/reek/blob/master/docs/Basic-Smell-Options.md
21
+ * how to configure Reek via source code comments: #{DocumentationLink.build('Smell Suppression')}
22
+ * what basic options are available: #{DocumentationLink.build('Basic Smell Options')}
22
23
  * what custom options are available by checking the detector specific documentation in /docs
23
24
  Update the offensive comment (or remove it if no longer applicable) and re-run Reek.
24
25
 
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'base_error'
4
+ require_relative '../documentation_link'
4
5
 
5
6
  module Reek
6
7
  module Errors
@@ -18,8 +19,8 @@ module Reek
18
19
  %<comment>s
19
20
 
20
21
  Please see the Reek docs for:
21
- * how to configure Reek via source code comments: https://github.com/troessner/reek/blob/master/docs/Smell-Suppression.md
22
- * what smell detectors are available: https://github.com/troessner/reek/blob/master/docs/Code-Smells.md
22
+ * how to configure Reek via source code comments: #{DocumentationLink.build('Smell Suppression')}
23
+ * what smell detectors are available: #{DocumentationLink.build('Code Smells')}
23
24
  Update the offensive comment (or remove it if no longer applicable) and re-run Reek.
24
25
 
25
26
  MESSAGE
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'base_error'
4
+ require_relative '../documentation_link'
4
5
 
5
6
  module Reek
6
7
  module Errors
@@ -17,8 +18,8 @@ module Reek
17
18
  %<comment>s
18
19
 
19
20
  Please see the Reek docs for:
20
- * how to configure Reek via source code comments: https://github.com/troessner/reek/blob/master/docs/Smell-Suppression.md
21
- * what smell detectors are available: https://github.com/troessner/reek/blob/master/docs/Code-Smells.md
21
+ * how to configure Reek via source code comments: #{DocumentationLink.build('Smell Suppression')}
22
+ * what smell detectors are available: #{DocumentationLink.build('Code Smells')}
22
23
  Update the offensive comment (or remove it if no longer applicable) and re-run Reek.
23
24
 
24
25
  MESSAGE
@@ -284,7 +284,7 @@ InstanceVariableAssumption:
284
284
  would report:
285
285
 
286
286
  ```Bash
287
- [1]:InstanceVariableAssumption: Dummy assumes too much for instance variable @ivar [https://github.com/troessner/reek/blob/master/docs/Instance-Variable-Assumption.md]
287
+ [1]:InstanceVariableAssumption: Dummy assumes too much for instance variable @ivar
288
288
  ```
289
289
 
290
290
  Note that this example would trigger this smell warning as well:
@@ -10,25 +10,12 @@ module Reek
10
10
  # SimpleWarningFormatter.
11
11
  #
12
12
  class WikiLinkWarningFormatter < SimpleWarningFormatter
13
- BASE_URL_FOR_HELP_LINK = 'https://github.com/troessner/reek/blob/master/docs/'.freeze
14
-
15
13
  def format(warning)
16
- "#{super} [#{explanatory_link(warning)}]"
14
+ "#{super} [#{warning.explanatory_link}]"
17
15
  end
18
16
 
19
17
  def format_hash(warning)
20
- super.merge('wiki_link' => explanatory_link(warning))
21
- end
22
-
23
- private
24
-
25
- def explanatory_link(warning)
26
- "#{BASE_URL_FOR_HELP_LINK}#{class_name_to_param(warning.smell_type)}.md"
27
- end
28
-
29
- # :reek:UtilityFunction
30
- def class_name_to_param(name)
31
- name.split(/(?=[A-Z])/).join('-')
18
+ super.merge('wiki_link' => warning.explanatory_link)
32
19
  end
33
20
  end
34
21
  end
@@ -43,6 +43,7 @@ module Reek
43
43
  # @return [Array<SmellWarning>]
44
44
  #
45
45
  def sniff
46
+ return [] if context.singleton_method? || context.module_function?
46
47
  return [] unless context.references_self?
47
48
  envious_receivers.map do |name, lines|
48
49
  smell_warning(
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'forwardable'
4
+ require_relative 'documentation_link'
4
5
 
5
6
  module Reek
6
7
  #
@@ -65,6 +66,10 @@ module Reek
65
66
  smell_detector.class
66
67
  end
67
68
 
69
+ def explanatory_link
70
+ DocumentationLink.build(smell_type)
71
+ end
72
+
68
73
  protected
69
74
 
70
75
  def identifying_values
@@ -8,6 +8,6 @@ module Reek
8
8
  # @public
9
9
  module Version
10
10
  # @public
11
- STRING = '4.8.1'.freeze
11
+ STRING = '4.8.2'.freeze
12
12
  end
13
13
  end
@@ -0,0 +1,20 @@
1
+ require_relative '../spec_helper'
2
+
3
+ RSpec.describe Reek::DocumentationLink do
4
+ describe '.build' do
5
+ it 'returns the correct link for a smell type' do
6
+ expect(described_class.build('FeatureEnvy')).
7
+ to eq "https://github.com/troessner/reek/blob/v#{Reek::Version::STRING}/docs/Feature-Envy.md"
8
+ end
9
+
10
+ it 'returns the correct link for general documentation' do
11
+ expect(described_class.build('Rake Task')).
12
+ to eq "https://github.com/troessner/reek/blob/v#{Reek::Version::STRING}/docs/Rake-Task.md"
13
+ end
14
+
15
+ it 'returns the correct link for subjects with abbreviations' do
16
+ expect(described_class.build('YAML Report')).
17
+ to eq "https://github.com/troessner/reek/blob/v#{Reek::Version::STRING}/docs/YAML-Report.md"
18
+ end
19
+ end
20
+ end
@@ -71,7 +71,7 @@ RSpec.describe Reek::Report::JSONReport do
71
71
  "smell_type": "UncommunicativeParameterName",
72
72
  "source": "string",
73
73
  "name": "a",
74
- "wiki_link": "https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Parameter-Name.md"
74
+ "wiki_link": "https://github.com/troessner/reek/blob/v#{Reek::Version::STRING}/docs/Uncommunicative-Parameter-Name.md"
75
75
  },
76
76
  {
77
77
  "context": "simple",
@@ -79,7 +79,7 @@ RSpec.describe Reek::Report::JSONReport do
79
79
  "message": "doesn't depend on instance state (maybe move it to another class?)",
80
80
  "smell_type": "UtilityFunction",
81
81
  "source": "string",
82
- "wiki_link": "https://github.com/troessner/reek/blob/master/docs/Utility-Function.md"
82
+ "wiki_link": "https://github.com/troessner/reek/blob/v#{Reek::Version::STRING}/docs/Utility-Function.md"
83
83
  }
84
84
  ]
85
85
  EOS
@@ -67,14 +67,14 @@ RSpec.describe Reek::Report::YAMLReport do
67
67
  smell_type: "UncommunicativeParameterName"
68
68
  source: "string"
69
69
  name: "a"
70
- wiki_link: "https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Parameter-Name.md"
70
+ wiki_link: "https://github.com/troessner/reek/blob/v#{Reek::Version::STRING}/docs/Uncommunicative-Parameter-Name.md"
71
71
  - context: "simple"
72
72
  lines:
73
73
  - 1
74
74
  message: "doesn't depend on instance state (maybe move it to another class?)"
75
75
  smell_type: "UtilityFunction"
76
76
  source: "string"
77
- wiki_link: "https://github.com/troessner/reek/blob/master/docs/Utility-Function.md"
77
+ wiki_link: "https://github.com/troessner/reek/blob/v#{Reek::Version::STRING}/docs/Utility-Function.md"
78
78
  EOS
79
79
 
80
80
  expect(result).to eq expected
@@ -247,4 +247,49 @@ RSpec.describe Reek::SmellDetectors::FeatureEnvy do
247
247
 
248
248
  expect(src).not_to reek_of(:FeatureEnvy)
249
249
  end
250
+
251
+ it 'does not report on class methods defined by opening the metaclass' do
252
+ src = <<-EOS
253
+ class Alfa
254
+ class << self
255
+ def bravo(charlie)
256
+ delta = new(charlie)
257
+ delta.echo
258
+ delta.echo
259
+ end
260
+ end
261
+ end
262
+ EOS
263
+
264
+ expect(src).not_to reek_of(:FeatureEnvy)
265
+ end
266
+
267
+ it 'does not report on class methods defined with an explicit receiver' do
268
+ src = <<-EOS
269
+ class Alfa
270
+ def self.bravo(charlie)
271
+ delta = new(charlie)
272
+ delta.echo
273
+ delta.echo
274
+ end
275
+ end
276
+ EOS
277
+
278
+ expect(src).not_to reek_of(:FeatureEnvy)
279
+ end
280
+
281
+ it 'does not report module functions' do
282
+ src = <<-EOF
283
+ module Alfa
284
+ module_function
285
+ def bravo(charlie)
286
+ echo = delta(charlie)
287
+ echo.foxtrot
288
+ echo.foxtrot
289
+ end
290
+ end
291
+ EOF
292
+
293
+ expect(src).not_to reek_of(:FeatureEnvy)
294
+ end
250
295
  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.8.1
4
+ version: 4.8.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: 2018-04-12 00:00:00.000000000 Z
14
+ date: 2018-06-26 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: codeclimate-engine-rb
@@ -235,6 +235,7 @@ files:
235
235
  - lib/reek/context/visibility_tracker.rb
236
236
  - lib/reek/context_builder.rb
237
237
  - lib/reek/detector_repository.rb
238
+ - lib/reek/documentation_link.rb
238
239
  - lib/reek/errors/bad_detector_configuration_key_in_comment_error.rb
239
240
  - lib/reek/errors/bad_detector_in_comment_error.rb
240
241
  - lib/reek/errors/base_error.rb
@@ -366,6 +367,7 @@ files:
366
367
  - spec/reek/context/statement_counter_spec.rb
367
368
  - spec/reek/context_builder_spec.rb
368
369
  - spec/reek/detector_repository_spec.rb
370
+ - spec/reek/documentation_link_spec.rb
369
371
  - spec/reek/errors/base_error_spec.rb
370
372
  - spec/reek/examiner_spec.rb
371
373
  - spec/reek/logging_error_handler_spec.rb