reek 4.7.2 → 4.7.3

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 (77) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +18 -4
  3. data/.travis.yml +0 -5
  4. data/CHANGELOG.md +8 -0
  5. data/CONTRIBUTING.md +1 -1
  6. data/Gemfile +4 -4
  7. data/docs/How-To-Write-New-Detectors.md +6 -5
  8. data/docs/Unused-Private-Method.md +1 -1
  9. data/features/configuration_via_source_comments/erroneous_source_comments.feature +1 -1
  10. data/features/locales.feature +32 -0
  11. data/features/rake_task/rake_task.feature +46 -6
  12. data/features/rspec_matcher.feature +32 -0
  13. data/features/step_definitions/reek_steps.rb +0 -4
  14. data/features/support/env.rb +0 -9
  15. data/lib/reek/ast/builder.rb +1 -1
  16. data/lib/reek/ast/sexp_extensions/send.rb +0 -4
  17. data/lib/reek/cli/options.rb +2 -2
  18. data/lib/reek/configuration/app_configuration.rb +3 -2
  19. data/lib/reek/configuration/configuration_file_finder.rb +3 -3
  20. data/lib/reek/context/ghost_context.rb +0 -2
  21. data/lib/reek/context/module_context.rb +0 -3
  22. data/lib/reek/context_builder.rb +2 -4
  23. data/lib/reek/errors/bad_detector_configuration_key_in_comment_error.rb +2 -2
  24. data/lib/reek/errors/bad_detector_in_comment_error.rb +2 -2
  25. data/lib/reek/errors/encoding_error.rb +38 -0
  26. data/lib/reek/errors/garbage_detector_configuration_in_comment_error.rb +3 -3
  27. data/lib/reek/errors/incomprehensible_source_error.rb +4 -4
  28. data/lib/reek/examiner.rb +15 -11
  29. data/lib/reek/rake/task.rb +5 -1
  30. data/lib/reek/smell_detectors/attribute.rb +6 -11
  31. data/lib/reek/smell_detectors/base_detector.rb +9 -1
  32. data/lib/reek/smell_detectors/boolean_parameter.rb +4 -5
  33. data/lib/reek/smell_detectors/class_variable.rb +5 -6
  34. data/lib/reek/smell_detectors/control_parameter.rb +3 -3
  35. data/lib/reek/smell_detectors/data_clump.rb +13 -6
  36. data/lib/reek/smell_detectors/duplicate_method_call.rb +18 -11
  37. data/lib/reek/smell_detectors/feature_envy.rb +9 -7
  38. data/lib/reek/smell_detectors/instance_variable_assumption.rb +14 -14
  39. data/lib/reek/smell_detectors/irresponsible_module.rb +6 -12
  40. data/lib/reek/smell_detectors/long_parameter_list.rb +10 -6
  41. data/lib/reek/smell_detectors/long_yield_list.rb +9 -5
  42. data/lib/reek/smell_detectors/manual_dispatch.rb +3 -4
  43. data/lib/reek/smell_detectors/module_initialize.rb +4 -5
  44. data/lib/reek/smell_detectors/nested_iterators.rb +11 -19
  45. data/lib/reek/smell_detectors/nil_check.rb +9 -15
  46. data/lib/reek/smell_detectors/prima_donna_method.rb +17 -16
  47. data/lib/reek/smell_detectors/repeated_conditional.rb +11 -8
  48. data/lib/reek/smell_detectors/subclassed_from_core_class.rb +8 -8
  49. data/lib/reek/smell_detectors/too_many_constants.rb +10 -8
  50. data/lib/reek/smell_detectors/too_many_instance_variables.rb +10 -5
  51. data/lib/reek/smell_detectors/too_many_methods.rb +11 -6
  52. data/lib/reek/smell_detectors/too_many_statements.rb +10 -5
  53. data/lib/reek/smell_detectors/uncommunicative_method_name.rb +8 -8
  54. data/lib/reek/smell_detectors/uncommunicative_module_name.rb +12 -15
  55. data/lib/reek/smell_detectors/uncommunicative_parameter_name.rb +10 -13
  56. data/lib/reek/smell_detectors/uncommunicative_variable_name.rb +23 -23
  57. data/lib/reek/smell_detectors/unused_parameters.rb +5 -6
  58. data/lib/reek/smell_detectors/unused_private_method.rb +11 -18
  59. data/lib/reek/smell_detectors/utility_function.rb +12 -15
  60. data/lib/reek/source/source_code.rb +27 -6
  61. data/lib/reek/source/source_locator.rb +1 -1
  62. data/lib/reek/spec.rb +1 -1
  63. data/lib/reek/version.rb +1 -1
  64. data/reek.gemspec +0 -2
  65. data/spec/reek/ast/sexp_extensions_spec.rb +12 -32
  66. data/spec/reek/cli/application_spec.rb +4 -6
  67. data/spec/reek/configuration/configuration_file_finder_spec.rb +0 -2
  68. data/spec/reek/examiner_spec.rb +38 -1
  69. data/spec/reek/rake/task_spec.rb +25 -2
  70. data/spec/reek/smell_detectors/base_detector_spec.rb +4 -5
  71. data/spec/reek/smell_detectors/prima_donna_method_spec.rb +3 -3
  72. data/spec/reek/source/source_code_spec.rb +28 -1
  73. data/spec/reek/spec/should_reek_of_spec.rb +18 -18
  74. data/spec/reek/spec/should_reek_spec.rb +5 -5
  75. data/spec/reek/spec/smell_matcher_spec.rb +20 -20
  76. data/spec/spec_helper.rb +1 -1
  77. metadata +6 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a57753b0b855d7182054e7551940eac44cf57f60
4
- data.tar.gz: 245074bd6e150589a1bc7a69830a34e3db600a83
3
+ metadata.gz: a71c30d4b1f39eee7c330e391cb1e80afa0a2d3b
4
+ data.tar.gz: fad4cfa8b8d369ff2e5c6ac5a22f3be8abc03891
5
5
  SHA512:
6
- metadata.gz: 4c422c0a25421d8d0abc337766f7b2defae5f7044137c3e5fb7c34fffea7ee409d165f56922f433565fa8643d716cdbb3e9a3c7cec568bfa50bf15b2eed8b254
7
- data.tar.gz: d4b77922d2745ab3d7f6f053931193b543f646e605a0b3a7f7a444ddf24d3462df4bf7732a248f14fd49f9253925afbf441d3fda578df736b130bfbf80db5096
6
+ metadata.gz: 15725dcd429906aba55b5dd379f01b1bf5e6eb08dd8df814a8403752c1356481137e0804618a449010c1b6dbb90da5543f21cf9401d2faaacbb6254734b01f68
7
+ data.tar.gz: 4a7a38b3b04059de3f93bb90ee14354fc0052f6c8a23ff3f96b8f456643087aa9f51aca3ff22758ef118f4c3fc05c741892a9658c512c0f0f171ee7cbbbfbd9a
@@ -36,6 +36,15 @@ Layout/MultilineOperationIndentation:
36
36
  Lint/AmbiguousBlockAssociation:
37
37
  Enabled: false
38
38
 
39
+ # Some of our source examples include interpolation explicitely.
40
+ Lint/InterpolationCheck:
41
+ Exclude:
42
+ - 'spec/**/*'
43
+
44
+ # We use :true and :false as AST node types.
45
+ Lint/BooleanSymbol:
46
+ Enabled: false
47
+
39
48
  Lint/HandleExceptions:
40
49
  Exclude:
41
50
  - 'spec/reek/configuration/configuration_file_finder_spec.rb'
@@ -63,6 +72,15 @@ Metrics/LineLength:
63
72
  Metrics/ParameterLists:
64
73
  CountKeywordArgs: false
65
74
 
75
+ Naming/AccessorMethodName:
76
+ Exclude:
77
+ - 'lib/reek/context/visibility_tracker.rb'
78
+
79
+ # EOS is a fine name to use in our specs
80
+ Naming/HeredocDelimiterNaming:
81
+ Exclude:
82
+ - 'spec/**/*'
83
+
66
84
  # FIXME: Update specs to avoid offenses
67
85
  RSpec/AnyInstance:
68
86
  Exclude:
@@ -109,10 +127,6 @@ RSpec/FilePath:
109
127
  - 'spec/reek/report/code_climate/code_climate_formatter_spec.rb'
110
128
  - 'spec/reek/report/code_climate/code_climate_report_spec.rb'
111
129
 
112
- Style/AccessorMethodName:
113
- Exclude:
114
- - 'lib/reek/context/visibility_tracker.rb'
115
-
116
130
  # Allow and/or for control flow only
117
131
  Style/AndOr:
118
132
  EnforcedStyle: conditionals
@@ -20,11 +20,6 @@ matrix:
20
20
  - rvm: ruby-head
21
21
  - rvm: rubinius-3
22
22
  fast_finish: true
23
- before_install:
24
- - rvm use @global
25
- - gem uninstall bundler -x
26
- - gem install bundler --version=1.13.7
27
- - bundler --version
28
23
  notifications:
29
24
  email:
30
25
  - timo.roessner@googlemail.com
@@ -1,5 +1,13 @@
1
1
  # Change log
2
2
 
3
+ ## 4.7.3 (2017-11-05)
4
+
5
+ * (mvz) Handle UTF-8 files in all locales
6
+ * (troessner) Handle encoding and other errors when parsing the source
7
+ * (mvz) Report method source line in PrimaDonnaMethod
8
+ * (mvz) Pick up config file in reek matcher
9
+ * (mvz) Let REEK_SRC override set values in rake task
10
+
3
11
  ## 4.7.2 (2017-07-24)
4
12
 
5
13
  * (mvz) Also report unused uncommunicative parameter names
@@ -111,7 +111,7 @@ regard than if it were run in a terminal.
111
111
 
112
112
  #### Failing Cucumber Scenarios
113
113
 
114
- If there is a failing scenario and you can not figure out why it is failing,
114
+ If there is a failing scenario and you cannot figure out why it is failing,
115
115
  just run the failing scenario: `bundle exec cucumber
116
116
  features/failing_scenario.feature:line`. By doing so Aruba will leave its set
117
117
  up in the `tmp/aruba` directory. You can then `cd` into this directory and run
data/Gemfile CHANGED
@@ -8,16 +8,16 @@ group :development do
8
8
  gem 'activesupport', '>= 4.2'
9
9
  gem 'aruba', '~> 0.14.0'
10
10
  gem 'ataru', '~> 0.2.0'
11
- gem 'cucumber', '~> 2.0'
11
+ gem 'cucumber', '~> 3.0'
12
12
  gem 'factory_girl', '~> 4.0'
13
13
  gem 'rake', '~> 12.0'
14
14
  gem 'rspec', '~> 3.0'
15
- gem 'simplecov', '~> 0.14.0'
15
+ gem 'simplecov', '~> 0.15.0'
16
16
  gem 'yard', '~> 0.9.5'
17
17
 
18
18
  if RUBY_VERSION >= '2.3'
19
- gem 'rubocop', '~> 0.49.1'
20
- gem 'rubocop-rspec', '~> 1.15.0'
19
+ gem 'rubocop', '~> 0.51.0'
20
+ gem 'rubocop-rspec', '~> 1.19.0'
21
21
  end
22
22
 
23
23
  platforms :mri do
@@ -27,20 +27,21 @@ module Reek
27
27
  end
28
28
 
29
29
  #
30
- # Here you should document what you expect "ctx" to look like.
30
+ # Here you should document what you expect the detector's context to look
31
+ # like.
31
32
  #
32
33
  # @return [Array<SmellWarning>]
33
34
  #
34
- def sniff(ctx)
35
+ def sniff
35
36
  # "found_smells" below is just an abstraction for
36
- # "find the smells in question" and iteratore over them.
37
+ # "find the smells in question" and iterate over them.
37
38
  # This can just be a method but it can also be a more sophisticated set up.
38
39
  # Check out other smell detectors to get a feeling for what to do here.
39
- found_smells(ctx).map do |smell|
40
+ found_smells.map do |smell|
40
41
  # "smell_warning" is defined in BaseDetector and should be used by you
41
42
  # to construct smell warnings
42
43
  smell_warning(
43
- context: ctx,
44
+ context: context,
44
45
  lines: [], # lines on which the smell was detected
45
46
  message: "...", # the message that is printed on STDOUT
46
47
  # whatever you interpolate into the "message" should go into
@@ -78,7 +78,7 @@ end
78
78
  ## Known limitations
79
79
 
80
80
  * Method calls via dynamic dispatch (e.g. via `send`) is something Reek (or any other
81
- static tool for that matter) can not detect.
81
+ static tool for that matter) cannot detect.
82
82
  * Method calls via callback like [Rails filters](http://guides.rubyonrails.org/action_controller_overview.html#filters)
83
83
  will trigger this as well, e.g.:
84
84
 
@@ -48,7 +48,7 @@ Feature: Erroneous source comments are handled properly
48
48
  """
49
49
  When I run reek bad_comment.rb
50
50
  Then it reports the error "Error: You are trying to configure the smell detector 'UncommunicativeMethodName'"
51
- And it reports the error "Unfortunately we can not parse the configuration you have given."
51
+ And it reports the error "Unfortunately we cannot parse the configuration you have given."
52
52
  And it reports the error "The source is 'bad_comment.rb'"
53
53
  And it reports the error "the comment belongs to the expression starting in line 3"
54
54
 
@@ -0,0 +1,32 @@
1
+ Feature: Handling different locales
2
+ In order to work in a variety of environments
3
+ As a developer
4
+ I want Reek to work properly in any locale
5
+
6
+ Scenario: Running Reek in an UTF-8 locale
7
+ Given I set the environment variable "LANG" to "en_US.utf8"
8
+ And a file "konnichiwa.rb" with:
9
+ """
10
+ puts 'こんにちは世界'
11
+ """
12
+ When I run `reek -V konnichiwa.rb`
13
+ Then it succeeds
14
+ And it reports no errors
15
+ And it reports:
16
+ """
17
+ konnichiwa.rb -- 0 warnings
18
+ """
19
+
20
+ Scenario: Running Reek in the POSIX locale
21
+ Given I set the environment variable "LANG" to "POSIX"
22
+ And a file "konnichiwa.rb" with:
23
+ """
24
+ puts 'こんにちは世界'
25
+ """
26
+ When I run `reek -V konnichiwa.rb`
27
+ Then it succeeds
28
+ And it reports no errors
29
+ And it reports:
30
+ """
31
+ konnichiwa.rb -- 0 warnings
32
+ """
@@ -4,13 +4,16 @@ Feature: Reek can be driven through its Task
4
4
 
5
5
  Scenario: source_files points at the desired files
6
6
  Given the smelly file 'smelly.rb'
7
- When I run rake reek with:
7
+ And a file "Rakefile" with:
8
8
  """
9
+ require 'reek/rake/task'
10
+
9
11
  Reek::Rake::Task.new do |t|
10
12
  t.source_files = 'smelly.rb'
11
13
  t.reek_opts = '--no-color'
12
14
  end
13
15
  """
16
+ When I run `rake reek`
14
17
  Then the exit status indicates an error
15
18
  And it reports:
16
19
  """
@@ -21,13 +24,16 @@ Feature: Reek can be driven through its Task
21
24
 
22
25
  Scenario: source_files using a FileList instead of a String
23
26
  Given the smelly file 'smelly.rb'
24
- When I run rake reek with:
27
+ And a file "Rakefile" with:
25
28
  """
29
+ require 'reek/rake/task'
30
+
26
31
  Reek::Rake::Task.new do |t|
27
32
  t.source_files = FileList['smelly.*']
28
33
  t.reek_opts = '--no-color'
29
34
  end
30
35
  """
36
+ When I run `rake reek`
31
37
  Then the exit status indicates an error
32
38
  And it reports:
33
39
  """
@@ -38,13 +44,16 @@ Feature: Reek can be driven through its Task
38
44
 
39
45
  Scenario: name changes the task name
40
46
  Given the smelly file 'smelly.rb'
41
- When I run rake silky with:
47
+ And a file "Rakefile" with:
42
48
  """
49
+ require 'reek/rake/task'
50
+
43
51
  Reek::Rake::Task.new('silky') do |t|
44
52
  t.source_files = 'smelly.rb'
45
53
  t.reek_opts = '--no-color'
46
54
  end
47
55
  """
56
+ When I run `rake silky`
48
57
  Then the exit status indicates an error
49
58
  And it reports:
50
59
  """
@@ -55,26 +64,32 @@ Feature: Reek can be driven through its Task
55
64
 
56
65
  Scenario: verbose prints the reek command
57
66
  Given the smelly file 'smelly.rb'
58
- When I run rake reek with:
67
+ And a file "Rakefile" with:
59
68
  """
69
+ require 'reek/rake/task'
70
+
60
71
  Reek::Rake::Task.new do |t|
61
72
  t.source_files = 'smelly.rb'
62
73
  t.verbose = true
63
74
  end
64
75
  """
76
+ When I run `rake reek`
65
77
  Then the exit status indicates an error
66
78
  And stdout includes "Running 'reek' rake command"
67
79
 
68
80
  Scenario: fail_on_error can hide the error status
69
81
  Given the smelly file 'smelly.rb'
70
- When I run rake reek with:
82
+ And a file "Rakefile" with:
71
83
  """
84
+ require 'reek/rake/task'
85
+
72
86
  Reek::Rake::Task.new do |t|
73
87
  t.fail_on_error = false
74
88
  t.source_files = 'smelly.rb'
75
89
  t.reek_opts = '--no-color'
76
90
  end
77
91
  """
92
+ When I run `rake reek`
78
93
  Then it reports no errors
79
94
  And it succeeds
80
95
  And it reports:
@@ -87,12 +102,37 @@ Feature: Reek can be driven through its Task
87
102
  Scenario: can be configured with config_file
88
103
  Given the smelly file 'smelly.rb'
89
104
  And a configuration file 'full_mask.reek'
90
- When I run rake reek with:
105
+ And a file "Rakefile" with:
91
106
  """
107
+ require 'reek/rake/task'
108
+
92
109
  Reek::Rake::Task.new do |t|
93
110
  t.config_file = 'full_mask.reek'
94
111
  t.source_files = 'smelly.rb'
95
112
  end
96
113
  """
114
+ When I run `rake reek`
97
115
  Then it succeeds
98
116
  And it reports nothing
117
+
118
+ Scenario: REEK_SRC overrides the files to check
119
+ Given the smelly file 'smelly.rb'
120
+ And the clean file 'clean.rb'
121
+ And a file "Rakefile" with:
122
+ """
123
+ require 'reek/rake/task'
124
+
125
+ Reek::Rake::Task.new do |t|
126
+ t.source_files = 'clean.rb'
127
+ t.reek_opts = '--no-color'
128
+ end
129
+ """
130
+ When I set the environment variable "REEK_SRC" to "smelly.rb"
131
+ And I run `rake reek`
132
+ Then the exit status indicates an error
133
+ And it reports:
134
+ """
135
+ smelly.rb -- 2 warnings:
136
+ [4]:UncommunicativeMethodName: Smelly#x has the name 'x' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Method-Name.md]
137
+ [5]:UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Variable-Name.md]
138
+ """
@@ -0,0 +1,32 @@
1
+ Feature: Use reek_of matcher
2
+ As a developer
3
+ In order to check code quality as part of my spec suite
4
+ I want to assert that my code doesn't smell
5
+
6
+ Background:
7
+ Given the smelly file 'smelly.rb'
8
+ And a file "reek_spec.rb" with:
9
+ """
10
+ require 'reek/spec'
11
+
12
+ describe 'smelly.rb' do
13
+ it 'is clean' do
14
+ expect(Pathname.new('smelly.rb')).not_to reek
15
+ end
16
+ end
17
+ """
18
+
19
+ Scenario: Failing on a smelly file
20
+ When I run `rspec reek_spec.rb`
21
+ Then stdout should contain:
22
+ """
23
+ Failure/Error: expect(Pathname.new('smelly.rb')).not_to reek
24
+ """
25
+
26
+ Scenario: Masking smells with a configuration file
27
+ Given a configuration file 'full_mask.reek'
28
+ When I run `rspec reek_spec.rb`
29
+ Then stdout should contain:
30
+ """
31
+ 1 example, 0 failures
32
+ """
@@ -6,10 +6,6 @@ When /^I pass "([^\"]*)" to reek *(.*)$/ do |stdin, args|
6
6
  reek_with_pipe(stdin, args)
7
7
  end
8
8
 
9
- When /^I run rake (\w*) with:$/ do |name, task_def|
10
- rake(name, task_def)
11
- end
12
-
13
9
  Then /^it reports nothing$/ do
14
10
  expect(last_command_started).to have_output_on_stdout('')
15
11
  end
@@ -21,15 +21,6 @@ class ReekWorld
21
21
  type(stdin)
22
22
  close_input
23
23
  end
24
-
25
- def rake(name, task_def)
26
- header = <<-EOS.strip_heredoc
27
- require 'reek/rake/task'
28
-
29
- EOS
30
- write_file 'Rakefile', header + task_def
31
- run_simple("rake #{name}", false)
32
- end
33
24
  end
34
25
 
35
26
  World do
@@ -6,7 +6,7 @@ module Reek
6
6
  # An AST Builder for ruby parser.
7
7
  #
8
8
  class Builder < ::Parser::Builders::Default
9
- # This is a work around for parsing ruby code that has a string with invliad sequence as UTF-8.
9
+ # This is a work around for parsing ruby code that has a string with invalid sequence as UTF-8.
10
10
  # See. https://github.com/whitequark/parser/issues/283
11
11
  def string_value(token)
12
12
  value(token)
@@ -23,10 +23,6 @@ module Reek
23
23
  ([receiver] + args).compact
24
24
  end
25
25
 
26
- def arg_names
27
- args.map { |arg| arg.children.first }
28
- end
29
-
30
26
  def module_creation_call?
31
27
  object_creation_call? && module_creation_receiver?
32
28
  end
@@ -82,7 +82,7 @@ module Reek
82
82
 
83
83
  def set_banner
84
84
  program_name = parser.program_name
85
- parser.banner = <<-EOB.gsub(/^[ ]+/, '')
85
+ parser.banner = <<-BANNER.gsub(/^[ ]+/, '')
86
86
  Usage: #{program_name} [options] [files]
87
87
 
88
88
  Examples:
@@ -93,7 +93,7 @@ module Reek
93
93
 
94
94
  See https://wiki.github.com/troessner/reek for detailed help.
95
95
 
96
- EOB
96
+ BANNER
97
97
  end
98
98
 
99
99
  # :reek:TooManyStatements: { max_statements: 6 }
@@ -17,9 +17,10 @@ module Reek
17
17
  include ConfigurationValidator
18
18
  EXCLUDE_PATHS_KEY = 'exclude_paths'.freeze
19
19
 
20
- # Instantiate a configuration via given path.
20
+ # Instantiate a configuration via given path, or the default path.
21
21
  #
22
- # @param path [Pathname] the path to the config file
22
+ # @param path [Pathname] the path to the config file, or nil to use the
23
+ # default path.
23
24
  #
24
25
  # @return [AppConfiguration]
25
26
  #
@@ -18,7 +18,7 @@ module Reek
18
18
  # The order in which ConfigurationFileFinder tries to find such a
19
19
  # configuration file is exactly like above.
20
20
  module ConfigurationFileFinder
21
- TOO_MANY_CONFIGURATION_FILES_MESSAGE = <<-EOS.freeze
21
+ TOO_MANY_CONFIGURATION_FILES_MESSAGE = <<-MESSAGE.freeze
22
22
 
23
23
  Error: Found multiple configuration files %s
24
24
  while scanning directory %s.
@@ -27,7 +27,7 @@ module Reek
27
27
  1) Remove all offending files.
28
28
  2) Be specific about which one you want to load via the -c switch.
29
29
 
30
- EOS
30
+ MESSAGE
31
31
 
32
32
  class << self
33
33
  #
@@ -64,7 +64,7 @@ module Reek
64
64
  return {} unless path
65
65
  begin
66
66
  configuration = YAML.load_file(path) || {}
67
- rescue => error
67
+ rescue StandardError => error
68
68
  raise ConfigFileException, "Invalid configuration file #{path}, error is #{error}"
69
69
  end
70
70