reek 6.0.0 → 6.0.1
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/.rubocop.yml +20 -0
- data/CHANGELOG.md +4 -0
- data/Gemfile +2 -3
- data/README.md +9 -3
- data/features/command_line_interface/options.feature +2 -2
- data/features/reports/json.feature +3 -3
- data/features/reports/reports.feature +4 -4
- data/features/reports/yaml.feature +3 -3
- data/features/support/env.rb +0 -1
- data/lib/reek/configuration/configuration_converter.rb +2 -2
- data/lib/reek/configuration/directory_directives.rb +7 -1
- data/lib/reek/smell_detectors/base_detector.rb +1 -0
- data/lib/reek/spec/smell_matcher.rb +2 -1
- data/lib/reek/version.rb +1 -1
- data/spec/reek/code_comment_spec.rb +20 -23
- data/spec/reek/configuration/directory_directives_spec.rb +6 -0
- data/spec/reek/report/code_climate/code_climate_configuration_spec.rb +1 -3
- data/spec/reek/report/code_climate/code_climate_fingerprint_spec.rb +26 -26
- data/spec/reek/report/code_climate/code_climate_formatter_spec.rb +6 -6
- data/spec/reek/report/location_formatter_spec.rb +3 -3
- data/spec/reek/smell_detectors/base_detector_spec.rb +3 -3
- data/spec/reek/smell_warning_spec.rb +12 -12
- data/spec/reek/spec/should_reek_of_spec.rb +0 -1
- data/spec/reek/spec/should_reek_only_of_spec.rb +6 -6
- data/spec/reek/spec/smell_matcher_spec.rb +1 -1
- data/spec/spec_helper.rb +18 -5
- metadata +9 -11
- data/spec/factories/factories.rb +0 -37
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 107593e309020bb2745d630599f8bf33bde2c9f708877895465cd12360267f82
|
4
|
+
data.tar.gz: 61290a2608c069e4c5977720e5a1d99fe8d4e716dfaa8503c0491b226790a8a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '09025ee922070bcb0c415f82fd5591e6658610a661ae4fc24abb472f16df6c3ed222fcfd84f81500a1951cadfabfb33b5c9414e26164f67cc140699774a9d2e7'
|
7
|
+
data.tar.gz: 7b9af8e1a09c5722fbedd946389411dee5aa7a5b98f03f48330a9d7f76d4c126bf170fff94955af6abe7a3a6c2e4b1b046c1fd1b8e304ee678a0fbecb52919f1
|
data/.rubocop.yml
CHANGED
@@ -130,3 +130,23 @@ Style/WordArray:
|
|
130
130
|
Metrics/ClassLength:
|
131
131
|
Exclude:
|
132
132
|
- 'lib/reek/cli/options.rb'
|
133
|
+
|
134
|
+
# Activate new cops from RuboCop 0.80 - 0.83
|
135
|
+
Lint/RaiseException:
|
136
|
+
Enabled: true
|
137
|
+
Lint/StructNewOverride:
|
138
|
+
Enabled: true
|
139
|
+
Layout/EmptyLinesAroundAttributeAccessor:
|
140
|
+
Enabled: true
|
141
|
+
Layout/SpaceAroundMethodCallOperator:
|
142
|
+
Enabled: true
|
143
|
+
Style/ExponentialNotation:
|
144
|
+
Enabled: true
|
145
|
+
Style/HashEachMethods:
|
146
|
+
Enabled: true
|
147
|
+
Style/HashTransformKeys:
|
148
|
+
Enabled: true
|
149
|
+
Style/HashTransformValues:
|
150
|
+
Enabled: true
|
151
|
+
Style/SlicingWithRange:
|
152
|
+
Enabled: true
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
@@ -8,15 +8,14 @@ group :development do
|
|
8
8
|
gem 'aruba', '~> 1.0'
|
9
9
|
gem 'codeclimate-engine-rb', '~> 0.4.0'
|
10
10
|
gem 'cucumber', '~> 3.0'
|
11
|
-
gem 'factory_bot', '~> 5.0', '!= 5.1.0'
|
12
11
|
gem 'kramdown', '~> 2.1'
|
13
12
|
gem 'kramdown-parser-gfm', '~> 1.0'
|
14
13
|
gem 'rake', '~> 13.0'
|
15
14
|
gem 'rspec', '~> 3.0'
|
16
15
|
gem 'rspec-benchmark', '~> 0.6.0'
|
17
|
-
gem 'rubocop', '~> 0.
|
16
|
+
gem 'rubocop', '~> 0.83.0'
|
18
17
|
gem 'rubocop-performance', '~> 1.5.0'
|
19
|
-
gem 'rubocop-rspec', '~> 1.
|
18
|
+
gem 'rubocop-rspec', '~> 1.39.0'
|
20
19
|
gem 'simplecov', '~> 0.18.1'
|
21
20
|
gem 'yard', '~> 0.9.5'
|
22
21
|
|
data/README.md
CHANGED
@@ -286,7 +286,7 @@ detectors:
|
|
286
286
|
# You can disable smells completely
|
287
287
|
IrresponsibleModule:
|
288
288
|
enabled: false
|
289
|
-
|
289
|
+
|
290
290
|
# You can use filters to silence Reek warnings.
|
291
291
|
# Either because you simply disagree with Reek (we are not the police) or
|
292
292
|
# because you want to fix this at a later point in time.
|
@@ -294,7 +294,7 @@ detectors:
|
|
294
294
|
exclude:
|
295
295
|
- "MyWorker#self.class_method" # should be refactored
|
296
296
|
- "AnotherWorker#instance_method" # should be refactored as well
|
297
|
-
|
297
|
+
|
298
298
|
# A lot of smells allow fine tuning their configuration. You can look up all available options
|
299
299
|
# in the corresponding smell documentation in /docs. In most cases you probably can just go
|
300
300
|
# with the defaults as documented in defaults.reek.yml.
|
@@ -349,9 +349,14 @@ This configuration for instance:
|
|
349
349
|
detectors:
|
350
350
|
IrresponsibleModule:
|
351
351
|
enabled: false
|
352
|
-
|
352
|
+
|
353
353
|
TooManyStatements:
|
354
354
|
max_statements: 5
|
355
|
+
|
356
|
+
directories:
|
357
|
+
"app/controllers":
|
358
|
+
TooManyStatements:
|
359
|
+
max_statements: 10
|
355
360
|
```
|
356
361
|
|
357
362
|
translates to:
|
@@ -607,6 +612,7 @@ Be careful though, Reek does not merge your configuration entries, so if you alr
|
|
607
612
|
Reek
|
608
613
|
* [ruby-critic](https://github.com/whitesmith/rubycritic) - gem that wraps around static analysis gems such as Reek, [flay](https://github.com/seattlerb/flay) and [flog](https://github.com/seattlerb/flog)
|
609
614
|
* [pronto-reek](https://github.com/mmozuras/pronto-reek) - Reek integration for [pronto](https://github.com/mmozuras/pronto)
|
615
|
+
* [action-reek](https://github.com/reviewdog/action-reek) - GitHub Action to run reek with [reviewdog](https://github.com/reviewdog/reviewdog) 🐶
|
610
616
|
|
611
617
|
### Misc
|
612
618
|
|
@@ -43,7 +43,7 @@ Feature: Reek can be controlled using command-line options
|
|
43
43
|
-c, --config FILE Read configuration options from FILE
|
44
44
|
--smell SMELL Only look for a specific smell.
|
45
45
|
Call it like this: reek --smell MissingSafeMethod source.rb
|
46
|
-
Check out https://github.com/troessner/reek/blob/v6.0.
|
46
|
+
Check out https://github.com/troessner/reek/blob/v6.0.1/docs/Code-Smells.md for a list of smells
|
47
47
|
--stdin-filename FILE When passing code in via pipe, assume this filename when checking file or directory rules in the config.
|
48
48
|
|
49
49
|
Generate a todo list:
|
@@ -119,5 +119,5 @@ Feature: Reek can be controlled using command-line options
|
|
119
119
|
UnusedPrivateMethod
|
120
120
|
UtilityFunction
|
121
121
|
|
122
|
-
Check out https://github.com/troessner/reek/blob/v6.0.
|
122
|
+
Check out https://github.com/troessner/reek/blob/v6.0.1/docs/Code-Smells.md for a details on each detector
|
123
123
|
"""
|
@@ -24,7 +24,7 @@ Feature: Report smells using simple JSON layout
|
|
24
24
|
"context": "Smelly#x",
|
25
25
|
"lines": [ 4 ],
|
26
26
|
"message": "has the name 'x'",
|
27
|
-
"documentation_link": "https://github.com/troessner/reek/blob/v6.0.
|
27
|
+
"documentation_link": "https://github.com/troessner/reek/blob/v6.0.1/docs/Uncommunicative-Method-Name.md",
|
28
28
|
"name": "x"
|
29
29
|
},
|
30
30
|
{
|
@@ -33,7 +33,7 @@ Feature: Report smells using simple JSON layout
|
|
33
33
|
"context": "Smelly#x",
|
34
34
|
"lines": [ 5 ],
|
35
35
|
"message": "has the variable name 'y'",
|
36
|
-
"documentation_link": "https://github.com/troessner/reek/blob/v6.0.
|
36
|
+
"documentation_link": "https://github.com/troessner/reek/blob/v6.0.1/docs/Uncommunicative-Variable-Name.md",
|
37
37
|
"name": "y"
|
38
38
|
}
|
39
39
|
]
|
@@ -53,7 +53,7 @@ Feature: Report smells using simple JSON layout
|
|
53
53
|
1
|
54
54
|
],
|
55
55
|
"message": "has no descriptive comment",
|
56
|
-
"documentation_link": "https://github.com/troessner/reek/blob/v6.0.
|
56
|
+
"documentation_link": "https://github.com/troessner/reek/blob/v6.0.1/docs/Irresponsible-Module.md"
|
57
57
|
}
|
58
58
|
]
|
59
59
|
"""
|
@@ -182,8 +182,8 @@ Feature: Correctly formatted reports
|
|
182
182
|
And it reports:
|
183
183
|
"""
|
184
184
|
smelly.rb -- 2 warnings:
|
185
|
-
[4]:UncommunicativeMethodName: Smelly#x has the name 'x' [https://github.com/troessner/reek/blob/v6.0.
|
186
|
-
[5]:UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/v6.0.
|
185
|
+
[4]:UncommunicativeMethodName: Smelly#x has the name 'x' [https://github.com/troessner/reek/blob/v6.0.1/docs/Uncommunicative-Method-Name.md]
|
186
|
+
[5]:UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/v6.0.1/docs/Uncommunicative-Variable-Name.md]
|
187
187
|
"""
|
188
188
|
|
189
189
|
Examples:
|
@@ -209,8 +209,8 @@ Feature: Correctly formatted reports
|
|
209
209
|
And it reports:
|
210
210
|
"""
|
211
211
|
smelly.rb -- 2 warnings:
|
212
|
-
UncommunicativeMethodName: Smelly#x has the name 'x' [https://github.com/troessner/reek/blob/v6.0.
|
213
|
-
UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/v6.0.
|
212
|
+
UncommunicativeMethodName: Smelly#x has the name 'x' [https://github.com/troessner/reek/blob/v6.0.1/docs/Uncommunicative-Method-Name.md]
|
213
|
+
UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/v6.0.1/docs/Uncommunicative-Variable-Name.md]
|
214
214
|
"""
|
215
215
|
|
216
216
|
Examples:
|
@@ -25,7 +25,7 @@ Feature: Report smells using simple YAML layout
|
|
25
25
|
smell_type: UncommunicativeMethodName
|
26
26
|
source: smelly.rb
|
27
27
|
name: x
|
28
|
-
documentation_link: https://github.com/troessner/reek/blob/v6.0.
|
28
|
+
documentation_link: https://github.com/troessner/reek/blob/v6.0.1/docs/Uncommunicative-Method-Name.md
|
29
29
|
- context: Smelly#x
|
30
30
|
lines:
|
31
31
|
- 5
|
@@ -33,7 +33,7 @@ Feature: Report smells using simple YAML layout
|
|
33
33
|
smell_type: UncommunicativeVariableName
|
34
34
|
source: smelly.rb
|
35
35
|
name: y
|
36
|
-
documentation_link: https://github.com/troessner/reek/blob/v6.0.
|
36
|
+
documentation_link: https://github.com/troessner/reek/blob/v6.0.1/docs/Uncommunicative-Variable-Name.md
|
37
37
|
"""
|
38
38
|
|
39
39
|
Scenario: Indicate smells and print them as yaml when using STDIN
|
@@ -48,5 +48,5 @@ Feature: Report smells using simple YAML layout
|
|
48
48
|
lines:
|
49
49
|
- 1
|
50
50
|
message: has no descriptive comment
|
51
|
-
documentation_link: https://github.com/troessner/reek/blob/v6.0.
|
51
|
+
documentation_link: https://github.com/troessner/reek/blob/v6.0.1/docs/Irresponsible-Module.md
|
52
52
|
"""
|
data/features/support/env.rb
CHANGED
@@ -74,7 +74,7 @@ module Reek
|
|
74
74
|
return unless configuration[DETECTORS_KEY]
|
75
75
|
|
76
76
|
configuration[DETECTORS_KEY].tap do |detectors|
|
77
|
-
detectors.
|
77
|
+
detectors.each_key do |detector|
|
78
78
|
convertible_attributes(detectors[detector]).each do |attribute|
|
79
79
|
detectors[detector][attribute] = detectors[detector][attribute].map do |item|
|
80
80
|
to_regex item
|
@@ -94,7 +94,7 @@ module Reek
|
|
94
94
|
return unless configuration[DIRECTORIES_KEY]
|
95
95
|
|
96
96
|
configuration[DIRECTORIES_KEY].tap do |directories|
|
97
|
-
directories.
|
97
|
+
directories.each_key do |directory|
|
98
98
|
directories[directory].each do |detector, configuration|
|
99
99
|
convertible_attributes(configuration).each do |attribute|
|
100
100
|
directories[directory][detector][attribute] = directories[directory][detector][attribute].map do |item|
|
@@ -53,10 +53,16 @@ module Reek
|
|
53
53
|
# @quality :reek:FeatureEnvy
|
54
54
|
def best_match_for(source_base_dir)
|
55
55
|
keys.
|
56
|
-
select
|
56
|
+
select do |pathname|
|
57
|
+
match?(source_base_dir, pathname) || match?(source_base_dir, pathname.expand_path)
|
58
|
+
end.
|
57
59
|
max_by { |pathname| pathname.to_s.length }
|
58
60
|
end
|
59
61
|
|
62
|
+
def match?(source_base_dir, pathname)
|
63
|
+
source_base_dir.to_s.match(glob_to_regexp(pathname.to_s))
|
64
|
+
end
|
65
|
+
|
60
66
|
# Transform a glob pattern to a regexp.
|
61
67
|
#
|
62
68
|
# It changes:
|
@@ -19,6 +19,7 @@ module Reek
|
|
19
19
|
# @quality :reek:TooManyMethods { max_methods: 18 }
|
20
20
|
class BaseDetector
|
21
21
|
attr_reader :config
|
22
|
+
|
22
23
|
# The name of the config field that lists the names of code contexts
|
23
24
|
# that should not be checked. Add this field to the config for each
|
24
25
|
# smell that should ignore this code element.
|
@@ -43,8 +43,9 @@ module Reek
|
|
43
43
|
raise ArgumentError, "The attribute '#{extra_keys.first}' is not available for comparison"
|
44
44
|
end
|
45
45
|
|
46
|
+
# :reek:FeatureEnvy
|
46
47
|
def common_parameters_equal?(other_parameters)
|
47
|
-
smell_warning.parameters.
|
48
|
+
smell_warning.parameters.values_at(*other_parameters.keys) == other_parameters.values
|
48
49
|
end
|
49
50
|
|
50
51
|
def common_attributes_equal?(attributes)
|
data/lib/reek/version.rb
CHANGED
@@ -3,7 +3,7 @@ require_lib 'reek/code_comment'
|
|
3
3
|
|
4
4
|
RSpec.describe Reek::CodeComment do
|
5
5
|
context 'with an empty comment' do
|
6
|
-
let(:comment) {
|
6
|
+
let(:comment) { build_code_comment(comment: '') }
|
7
7
|
|
8
8
|
it 'is not descriptive' do
|
9
9
|
expect(comment).not_to be_descriptive
|
@@ -16,22 +16,22 @@ RSpec.describe Reek::CodeComment do
|
|
16
16
|
|
17
17
|
describe '#descriptive' do
|
18
18
|
it 'rejects an empty comment' do
|
19
|
-
comment =
|
19
|
+
comment = build_code_comment(comment: '#')
|
20
20
|
expect(comment).not_to be_descriptive
|
21
21
|
end
|
22
22
|
|
23
23
|
it 'rejects a 1-word comment' do
|
24
|
-
comment =
|
24
|
+
comment = build_code_comment(comment: "# alpha\n# ")
|
25
25
|
expect(comment).not_to be_descriptive
|
26
26
|
end
|
27
27
|
|
28
28
|
it 'accepts a 2-word comment' do
|
29
|
-
comment =
|
29
|
+
comment = build_code_comment(comment: '# alpha bravo ')
|
30
30
|
expect(comment).to be_descriptive
|
31
31
|
end
|
32
32
|
|
33
33
|
it 'accepts a multi-word comment' do
|
34
|
-
comment =
|
34
|
+
comment = build_code_comment(comment: "# alpha bravo \n# charlie \n # delta ")
|
35
35
|
expect(comment).to be_descriptive
|
36
36
|
end
|
37
37
|
end
|
@@ -39,8 +39,7 @@ RSpec.describe Reek::CodeComment do
|
|
39
39
|
describe 'good comment config' do
|
40
40
|
it 'parses hashed options' do
|
41
41
|
comment = '# :reek:DuplicateMethodCall { max_calls: 3 }'
|
42
|
-
config =
|
43
|
-
comment: comment).config
|
42
|
+
config = build_code_comment(comment: comment).config
|
44
43
|
|
45
44
|
expect(config).to include('DuplicateMethodCall')
|
46
45
|
expect(config['DuplicateMethodCall']).to have_key 'max_calls'
|
@@ -52,7 +51,7 @@ RSpec.describe Reek::CodeComment do
|
|
52
51
|
# :reek:DuplicateMethodCall { max_calls: 3 }
|
53
52
|
# :reek:NestedIterators { enabled: true }
|
54
53
|
RUBY
|
55
|
-
config =
|
54
|
+
config = build_code_comment(comment: comment).config
|
56
55
|
|
57
56
|
expect(config).to include('DuplicateMethodCall', 'NestedIterators')
|
58
57
|
expect(config['DuplicateMethodCall']['max_calls']).to eq 3
|
@@ -63,7 +62,7 @@ RSpec.describe Reek::CodeComment do
|
|
63
62
|
comment = <<-RUBY
|
64
63
|
#:reek:DuplicateMethodCall { max_calls: 3 } and :reek:NestedIterators { enabled: true }
|
65
64
|
RUBY
|
66
|
-
config =
|
65
|
+
config = build_code_comment(comment: comment).config
|
67
66
|
|
68
67
|
expect(config).to include('DuplicateMethodCall', 'NestedIterators')
|
69
68
|
expect(config['DuplicateMethodCall']['max_calls']).to eq 3
|
@@ -73,7 +72,7 @@ RSpec.describe Reek::CodeComment do
|
|
73
72
|
|
74
73
|
it 'parses multiple unhashed options on the same line' do
|
75
74
|
comment = '# :reek:DuplicateMethodCall and :reek:NestedIterators'
|
76
|
-
config =
|
75
|
+
config = build_code_comment(comment: comment).config
|
77
76
|
|
78
77
|
expect(config).to include('DuplicateMethodCall', 'NestedIterators')
|
79
78
|
expect(config['DuplicateMethodCall']).to include('enabled')
|
@@ -84,7 +83,7 @@ RSpec.describe Reek::CodeComment do
|
|
84
83
|
|
85
84
|
it 'disables the smell if no options are specifed' do
|
86
85
|
comment = '# :reek:DuplicateMethodCall'
|
87
|
-
config =
|
86
|
+
config = build_code_comment(comment: comment).config
|
88
87
|
|
89
88
|
expect(config).to include('DuplicateMethodCall')
|
90
89
|
expect(config['DuplicateMethodCall']).to include('enabled')
|
@@ -93,14 +92,13 @@ RSpec.describe Reek::CodeComment do
|
|
93
92
|
|
94
93
|
it 'does not disable the smell if options are specifed' do
|
95
94
|
comment = '# :reek:DuplicateMethodCall { max_calls: 3 }'
|
96
|
-
config =
|
95
|
+
config = build_code_comment(comment: comment).config
|
97
96
|
|
98
97
|
expect(config['DuplicateMethodCall']).not_to include('enabled')
|
99
98
|
end
|
100
99
|
|
101
100
|
it 'ignores smells after a space' do
|
102
|
-
config =
|
103
|
-
comment: '# :reek: DuplicateMethodCall').config
|
101
|
+
config = build_code_comment(comment: '# :reek: DuplicateMethodCall').config
|
104
102
|
expect(config).not_to include('DuplicateMethodCall')
|
105
103
|
end
|
106
104
|
|
@@ -111,7 +109,7 @@ RSpec.describe Reek::CodeComment do
|
|
111
109
|
# :reek:NestedIterators { enabled: true }
|
112
110
|
# comment
|
113
111
|
RUBY
|
114
|
-
comment =
|
112
|
+
comment = build_code_comment(comment: original_comment)
|
115
113
|
|
116
114
|
expect(comment.send(:sanitized_comment)).to eq('Actual comment')
|
117
115
|
end
|
@@ -122,8 +120,7 @@ RSpec.describe Reek::CodeComment::CodeCommentValidator do
|
|
122
120
|
context 'when the comment contains an unknown detector name' do
|
123
121
|
it 'raises BadDetectorInCommentError' do
|
124
122
|
expect do
|
125
|
-
|
126
|
-
comment: '# :reek:DoesNotExist')
|
123
|
+
build_code_comment(comment: '# :reek:DoesNotExist')
|
127
124
|
end.to raise_error(Reek::Errors::BadDetectorInCommentError)
|
128
125
|
end
|
129
126
|
end
|
@@ -132,7 +129,7 @@ RSpec.describe Reek::CodeComment::CodeCommentValidator do
|
|
132
129
|
it 'raises GarbageDetectorConfigurationInCommentError' do
|
133
130
|
expect do
|
134
131
|
comment = '# :reek:UncommunicativeMethodName { thats: a: bad: config }'
|
135
|
-
|
132
|
+
build_code_comment(comment: comment)
|
136
133
|
end.to raise_error(Reek::Errors::GarbageDetectorConfigurationInCommentError)
|
137
134
|
end
|
138
135
|
end
|
@@ -140,7 +137,7 @@ RSpec.describe Reek::CodeComment::CodeCommentValidator do
|
|
140
137
|
context 'when the legacy comment format was used' do
|
141
138
|
it 'raises LegacyCommentSeparatorError' do
|
142
139
|
comment = '# :reek:DuplicateMethodCall:'
|
143
|
-
expect {
|
140
|
+
expect { build_code_comment(comment: comment) }.
|
144
141
|
to raise_error Reek::Errors::LegacyCommentSeparatorError
|
145
142
|
end
|
146
143
|
end
|
@@ -151,7 +148,7 @@ RSpec.describe Reek::CodeComment::CodeCommentValidator do
|
|
151
148
|
expect do
|
152
149
|
# exclude -> exlude and enabled -> nabled
|
153
150
|
comment = '# :reek:UncommunicativeMethodName { exlude: alfa, nabled: true }'
|
154
|
-
|
151
|
+
build_code_comment(comment: comment)
|
155
152
|
end.to raise_error(Reek::Errors::BadDetectorConfigurationKeyInCommentError)
|
156
153
|
end
|
157
154
|
end
|
@@ -160,7 +157,7 @@ RSpec.describe Reek::CodeComment::CodeCommentValidator do
|
|
160
157
|
it 'does not raise' do
|
161
158
|
expect do
|
162
159
|
comment = '# :reek:UncommunicativeMethodName { exclude: alfa, enabled: true }'
|
163
|
-
|
160
|
+
build_code_comment(comment: comment)
|
164
161
|
end.not_to raise_error
|
165
162
|
end
|
166
163
|
end
|
@@ -170,7 +167,7 @@ RSpec.describe Reek::CodeComment::CodeCommentValidator do
|
|
170
167
|
expect do
|
171
168
|
# max_copies -> mx_copies and min_clump_size -> mn_clump_size
|
172
169
|
comment = '# :reek:DataClump { mx_copies: 4, mn_clump_size: 3 }'
|
173
|
-
|
170
|
+
build_code_comment(comment: comment)
|
174
171
|
end.to raise_error(Reek::Errors::BadDetectorConfigurationKeyInCommentError)
|
175
172
|
end
|
176
173
|
end
|
@@ -179,7 +176,7 @@ RSpec.describe Reek::CodeComment::CodeCommentValidator do
|
|
179
176
|
it 'does not raise' do
|
180
177
|
expect do
|
181
178
|
comment = '# :reek:DataClump { max_copies: 4, min_clump_size: 3 }'
|
182
|
-
|
179
|
+
build_code_comment(comment: comment)
|
183
180
|
end.not_to raise_error
|
184
181
|
end
|
185
182
|
end
|
@@ -89,6 +89,12 @@ RSpec.describe Reek::Configuration::DirectoryDirectives do
|
|
89
89
|
expect(hit.to_s).to eq('bar/**/.spec/*')
|
90
90
|
end
|
91
91
|
|
92
|
+
it 'returns the corresponding directory when source_base_dir is an absolute_path' do
|
93
|
+
source_base_dir = Pathname.new('foo/bar').expand_path
|
94
|
+
hit = directives.send :best_match_for, source_base_dir
|
95
|
+
expect(hit.to_s).to eq('foo/bar')
|
96
|
+
end
|
97
|
+
|
92
98
|
it 'does not match an arbitrary directory when source_base_dir contains a character that could match the .' do
|
93
99
|
source_base_dir = 'bar/something/aspec/direct'
|
94
100
|
hit = directives.send :best_match_for, source_base_dir
|
@@ -3,9 +3,7 @@ require_lib 'reek/report/code_climate/code_climate_configuration'
|
|
3
3
|
|
4
4
|
RSpec.describe Reek::Report::CodeClimateConfiguration do
|
5
5
|
yml = described_class.load
|
6
|
-
smell_types = Reek::SmellDetectors::BaseDetector.descendants.map
|
7
|
-
descendant.name.demodulize
|
8
|
-
end
|
6
|
+
smell_types = Reek::SmellDetectors::BaseDetector.descendants.map(&:smell_type)
|
9
7
|
|
10
8
|
smell_types.each do |name|
|
11
9
|
config = yml.fetch(name)
|
@@ -8,12 +8,12 @@ RSpec.describe Reek::Report::CodeClimateFingerprint do
|
|
8
8
|
context 'when fingerprinting a warning with no parameters' do
|
9
9
|
let(:expected_fingerprint) { 'e68badd29db51c92363a7c6a2438d722' }
|
10
10
|
let(:warning) do
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
Reek::SmellWarning.new(
|
12
|
+
'UtilityFunction',
|
13
|
+
context: 'alfa',
|
14
|
+
message: "doesn't depend on instance state (maybe move it to another class?)",
|
15
|
+
lines: lines,
|
16
|
+
source: 'a/ruby/source/file.rb')
|
17
17
|
end
|
18
18
|
|
19
19
|
context 'with code at a specific location' do
|
@@ -35,12 +35,12 @@ RSpec.describe Reek::Report::CodeClimateFingerprint do
|
|
35
35
|
|
36
36
|
context 'when the fingerprint should not be computed' do
|
37
37
|
let(:warning) do
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
38
|
+
Reek::SmellWarning.new(
|
39
|
+
'ManualDispatch',
|
40
|
+
context: 'Alfa#bravo',
|
41
|
+
message: 'manually dispatches method call',
|
42
|
+
lines: [4],
|
43
|
+
source: 'a/ruby/source/file.rb')
|
44
44
|
end
|
45
45
|
|
46
46
|
it 'returns nil' do
|
@@ -50,13 +50,13 @@ RSpec.describe Reek::Report::CodeClimateFingerprint do
|
|
50
50
|
|
51
51
|
context 'when the smell warning has only identifying parameters' do
|
52
52
|
let(:warning) do
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
53
|
+
Reek::SmellWarning.new(
|
54
|
+
'ClassVariable',
|
55
|
+
context: 'Alfa',
|
56
|
+
message: "declares the class variable '@@#{name}'",
|
57
|
+
lines: [4],
|
58
|
+
parameters: { name: "@@#{name}" },
|
59
|
+
source: 'a/ruby/source/file.rb')
|
60
60
|
end
|
61
61
|
|
62
62
|
context 'when the name is one thing' do
|
@@ -80,13 +80,13 @@ RSpec.describe Reek::Report::CodeClimateFingerprint do
|
|
80
80
|
|
81
81
|
context 'when the smell warning has identifying and non-identifying parameters' do
|
82
82
|
let(:warning) do
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
83
|
+
Reek::SmellWarning.new(
|
84
|
+
'DuplicateMethodCall',
|
85
|
+
context: "Alfa##{name}",
|
86
|
+
message: "calls '#{name}' #{count} times",
|
87
|
+
lines: lines,
|
88
|
+
parameters: { name: "@@#{name}", count: count },
|
89
|
+
source: 'a/ruby/source/file.rb')
|
90
90
|
end
|
91
91
|
|
92
92
|
context 'when the parameters are provided' do
|
@@ -4,12 +4,12 @@ require_lib 'reek/report/code_climate/code_climate_formatter'
|
|
4
4
|
RSpec.describe Reek::Report::CodeClimateFormatter do
|
5
5
|
describe '#render' do
|
6
6
|
let(:warning) do
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
Reek::SmellWarning.new(
|
8
|
+
'UtilityFunction',
|
9
|
+
context: 'context foo',
|
10
|
+
message: 'message bar',
|
11
|
+
lines: [1, 2],
|
12
|
+
source: 'a/ruby/source/file.rb')
|
13
13
|
end
|
14
14
|
let(:rendered) { described_class.new(warning).render }
|
15
15
|
let(:json) { JSON.parse rendered.chop }
|
@@ -2,7 +2,7 @@ require_relative '../../spec_helper'
|
|
2
2
|
require_lib 'reek/report/location_formatter'
|
3
3
|
|
4
4
|
RSpec.describe Reek::Report::BlankLocationFormatter do
|
5
|
-
let(:warning) {
|
5
|
+
let(:warning) { build_smell_warning(lines: [11, 9, 250, 100]) }
|
6
6
|
|
7
7
|
describe '.format' do
|
8
8
|
it 'returns a blank String regardless of the warning' do
|
@@ -12,7 +12,7 @@ RSpec.describe Reek::Report::BlankLocationFormatter do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
RSpec.describe Reek::Report::DefaultLocationFormatter do
|
15
|
-
let(:warning) {
|
15
|
+
let(:warning) { build_smell_warning(lines: [11, 9, 250, 100]) }
|
16
16
|
|
17
17
|
describe '.format' do
|
18
18
|
it 'returns a prefix with sorted line numbers' do
|
@@ -22,7 +22,7 @@ RSpec.describe Reek::Report::DefaultLocationFormatter do
|
|
22
22
|
end
|
23
23
|
|
24
24
|
RSpec.describe Reek::Report::SingleLineLocationFormatter do
|
25
|
-
let(:warning) {
|
25
|
+
let(:warning) { build_smell_warning(lines: [11, 9, 250, 100]) }
|
26
26
|
|
27
27
|
describe '.format' do
|
28
28
|
it 'returns the first line where the smell was found' do
|
@@ -5,13 +5,13 @@ require_lib 'reek/smell_detectors/duplicate_method_call'
|
|
5
5
|
RSpec.describe Reek::SmellDetectors::BaseDetector do
|
6
6
|
describe '.todo_configuration_for' do
|
7
7
|
it 'returns exclusion configuration for the given smells' do
|
8
|
-
smell =
|
8
|
+
smell = build_smell_warning(smell_type: 'Foo', context: 'Foo#bar')
|
9
9
|
result = described_class.todo_configuration_for([smell])
|
10
10
|
expect(result).to eq('BaseDetector' => { 'exclude' => ['Foo#bar'] })
|
11
11
|
end
|
12
12
|
|
13
13
|
it 'merges identical contexts' do
|
14
|
-
smell =
|
14
|
+
smell = build_smell_warning(smell_type: 'Foo', context: 'Foo#bar')
|
15
15
|
result = described_class.todo_configuration_for([smell, smell])
|
16
16
|
expect(result).to eq('BaseDetector' => { 'exclude' => ['Foo#bar'] })
|
17
17
|
end
|
@@ -20,7 +20,7 @@ RSpec.describe Reek::SmellDetectors::BaseDetector do
|
|
20
20
|
let(:subclass) { Reek::SmellDetectors::TooManyStatements }
|
21
21
|
|
22
22
|
it 'includes default exclusions' do
|
23
|
-
smell =
|
23
|
+
smell = build_smell_warning(smell_type: 'TooManyStatements', context: 'Foo#bar')
|
24
24
|
result = subclass.todo_configuration_for([smell])
|
25
25
|
|
26
26
|
aggregate_failures do
|
@@ -24,23 +24,23 @@ RSpec.describe Reek::SmellWarning do
|
|
24
24
|
end
|
25
25
|
|
26
26
|
context 'when smells differ only by detector' do
|
27
|
-
let(:first) {
|
28
|
-
let(:second) {
|
27
|
+
let(:first) { build_smell_warning(smell_type: 'DuplicateMethodCall') }
|
28
|
+
let(:second) { build_smell_warning(smell_type: 'FeatureEnvy') }
|
29
29
|
|
30
30
|
it_behaves_like 'first sorts ahead of second'
|
31
31
|
end
|
32
32
|
|
33
33
|
context 'when smells differ only by lines' do
|
34
|
-
let(:first) {
|
35
|
-
let(:second) {
|
34
|
+
let(:first) { build_smell_warning(smell_type: 'FeatureEnvy', lines: [2]) }
|
35
|
+
let(:second) { build_smell_warning(smell_type: 'FeatureEnvy', lines: [3]) }
|
36
36
|
|
37
37
|
it_behaves_like 'first sorts ahead of second'
|
38
38
|
end
|
39
39
|
|
40
40
|
context 'when smells differ only by context' do
|
41
|
-
let(:first) {
|
41
|
+
let(:first) { build_smell_warning(smell_type: 'DuplicateMethodCall', context: 'first') }
|
42
42
|
let(:second) do
|
43
|
-
|
43
|
+
build_smell_warning(smell_type: 'DuplicateMethodCall', context: 'second')
|
44
44
|
end
|
45
45
|
|
46
46
|
it_behaves_like 'first sorts ahead of second'
|
@@ -48,11 +48,11 @@ RSpec.describe Reek::SmellWarning do
|
|
48
48
|
|
49
49
|
context 'when smells differ only by message' do
|
50
50
|
let(:first) do
|
51
|
-
|
51
|
+
build_smell_warning(smell_type: 'DuplicateMethodCall',
|
52
52
|
context: 'ctx', message: 'first message')
|
53
53
|
end
|
54
54
|
let(:second) do
|
55
|
-
|
55
|
+
build_smell_warning(smell_type: 'DuplicateMethodCall',
|
56
56
|
context: 'ctx', message: 'second message')
|
57
57
|
end
|
58
58
|
|
@@ -61,10 +61,10 @@ RSpec.describe Reek::SmellWarning do
|
|
61
61
|
|
62
62
|
context 'when smells differ by name and message' do
|
63
63
|
let(:first) do
|
64
|
-
|
64
|
+
build_smell_warning(smell_type: 'FeatureEnvy', message: 'second message')
|
65
65
|
end
|
66
66
|
let(:second) do
|
67
|
-
|
67
|
+
build_smell_warning(smell_type: 'UtilityFunction', message: 'first message')
|
68
68
|
end
|
69
69
|
|
70
70
|
it_behaves_like 'first sorts ahead of second'
|
@@ -72,13 +72,13 @@ RSpec.describe Reek::SmellWarning do
|
|
72
72
|
|
73
73
|
context 'when smells differ everywhere' do
|
74
74
|
let(:first) do
|
75
|
-
|
75
|
+
build_smell_warning(smell_type: 'DuplicateMethodCall',
|
76
76
|
context: 'Dirty#a',
|
77
77
|
message: 'calls @s.title twice')
|
78
78
|
end
|
79
79
|
|
80
80
|
let(:second) do
|
81
|
-
|
81
|
+
build_smell_warning(smell_type: 'UncommunicativeVariableName',
|
82
82
|
context: 'Dirty',
|
83
83
|
message: "has the variable name '@s'")
|
84
84
|
end
|
@@ -40,7 +40,7 @@ RSpec.describe Reek::Spec::ShouldReekOnlyOf do
|
|
40
40
|
end
|
41
41
|
|
42
42
|
context 'with 1 non-matching smell' do
|
43
|
-
let(:smells) { [
|
43
|
+
let(:smells) { [build_smell_warning(smell_type: 'ControlParameter')] }
|
44
44
|
|
45
45
|
it_behaves_like 'no match'
|
46
46
|
end
|
@@ -48,8 +48,8 @@ RSpec.describe Reek::Spec::ShouldReekOnlyOf do
|
|
48
48
|
context 'with 2 non-matching smells' do
|
49
49
|
let(:smells) do
|
50
50
|
[
|
51
|
-
|
52
|
-
|
51
|
+
build_smell_warning(smell_type: 'ControlParameter'),
|
52
|
+
build_smell_warning(smell_type: 'FeatureEnvy')
|
53
53
|
]
|
54
54
|
end
|
55
55
|
|
@@ -59,8 +59,8 @@ RSpec.describe Reek::Spec::ShouldReekOnlyOf do
|
|
59
59
|
context 'with 1 non-matching and 1 matching smell' do
|
60
60
|
let(:smells) do
|
61
61
|
[
|
62
|
-
|
63
|
-
|
62
|
+
build_smell_warning(smell_type: 'ControlParameter'),
|
63
|
+
build_smell_warning(smell_type: expected_smell_type.to_s,
|
64
64
|
message: "message mentioning #{expected_context_name}")
|
65
65
|
]
|
66
66
|
end
|
@@ -70,7 +70,7 @@ RSpec.describe Reek::Spec::ShouldReekOnlyOf do
|
|
70
70
|
|
71
71
|
context 'with 1 matching smell' do
|
72
72
|
let(:smells) do
|
73
|
-
[
|
73
|
+
[build_smell_warning(smell_type: expected_smell_type.to_s,
|
74
74
|
message: "message mentioning #{expected_context_name}")]
|
75
75
|
end
|
76
76
|
|
@@ -3,7 +3,7 @@ require_lib 'reek/spec/smell_matcher'
|
|
3
3
|
|
4
4
|
RSpec.describe Reek::Spec::SmellMatcher do
|
5
5
|
let(:smell_warning) do
|
6
|
-
|
6
|
+
build_smell_warning(smell_type: 'UncommunicativeVariableName',
|
7
7
|
message: "has the variable name '@s'",
|
8
8
|
parameters: { test: 'something' })
|
9
9
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'pathname'
|
2
2
|
require 'timeout'
|
3
|
-
require 'active_support/core_ext/string/strip'
|
4
3
|
require 'rspec-benchmark'
|
5
4
|
require_relative '../lib/reek'
|
6
5
|
require_relative '../lib/reek/spec'
|
@@ -14,9 +13,6 @@ begin
|
|
14
13
|
rescue LoadError # rubocop:disable Lint/SuppressedException
|
15
14
|
end
|
16
15
|
|
17
|
-
require 'factory_bot'
|
18
|
-
FactoryBot.find_definitions
|
19
|
-
|
20
16
|
# Simple helpers for our specs.
|
21
17
|
module Helpers
|
22
18
|
def test_configuration_for(config)
|
@@ -70,12 +66,29 @@ module Helpers
|
|
70
66
|
@klass_map ||= Reek::AST::ASTNodeClassMap.new
|
71
67
|
@klass_map.klass_for(type).new(type, children)
|
72
68
|
end
|
69
|
+
|
70
|
+
def build_smell_warning(smell_type: 'FeatureEnvy',
|
71
|
+
context: 'self',
|
72
|
+
lines: [42],
|
73
|
+
message: 'smell warning message',
|
74
|
+
source: 'dummy_file',
|
75
|
+
parameters: {})
|
76
|
+
Reek::SmellWarning.new(smell_type,
|
77
|
+
context: context,
|
78
|
+
lines: lines,
|
79
|
+
message: message,
|
80
|
+
source: source,
|
81
|
+
parameters: parameters)
|
82
|
+
end
|
83
|
+
|
84
|
+
def build_code_comment(comment: '', line: 1, source: 'string')
|
85
|
+
Reek::CodeComment.new(comment: comment, line: line, source: source)
|
86
|
+
end
|
73
87
|
end
|
74
88
|
|
75
89
|
RSpec.configure do |config|
|
76
90
|
config.filter_run :focus
|
77
91
|
config.run_all_when_everything_filtered = true
|
78
|
-
config.include FactoryBot::Syntax::Methods
|
79
92
|
config.include Helpers
|
80
93
|
config.include RSpec::Benchmark::Matchers
|
81
94
|
config.example_status_persistence_file_path = 'spec/examples.txt'
|
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: 6.0.
|
4
|
+
version: 6.0.1
|
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: 2020-
|
14
|
+
date: 2020-05-26 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: kwalify
|
@@ -31,28 +31,28 @@ dependencies:
|
|
31
31
|
name: parser
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
33
33
|
requirements:
|
34
|
-
- - "<"
|
35
|
-
- !ruby/object:Gem::Version
|
36
|
-
version: '2.8'
|
37
34
|
- - ">="
|
38
35
|
- !ruby/object:Gem::Version
|
39
36
|
version: 2.5.0.0
|
40
37
|
- - "!="
|
41
38
|
- !ruby/object:Gem::Version
|
42
39
|
version: 2.5.1.1
|
40
|
+
- - "<"
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '2.8'
|
43
43
|
type: :runtime
|
44
44
|
prerelease: false
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
|
-
- - "<"
|
48
|
-
- !ruby/object:Gem::Version
|
49
|
-
version: '2.8'
|
50
47
|
- - ">="
|
51
48
|
- !ruby/object:Gem::Version
|
52
49
|
version: 2.5.0.0
|
53
50
|
- - "!="
|
54
51
|
- !ruby/object:Gem::Version
|
55
52
|
version: 2.5.1.1
|
53
|
+
- - "<"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '2.8'
|
56
56
|
- !ruby/object:Gem::Dependency
|
57
57
|
name: psych
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
@@ -372,7 +372,6 @@ files:
|
|
372
372
|
- samples/source_with_non_ruby_files/gibberish
|
373
373
|
- samples/source_with_non_ruby_files/python_source.py
|
374
374
|
- samples/source_with_non_ruby_files/ruby.rb
|
375
|
-
- spec/factories/factories.rb
|
376
375
|
- spec/performance/reek/smell_detectors/runtime_speed_spec.rb
|
377
376
|
- spec/quality/documentation_spec.rb
|
378
377
|
- spec/quality/reek_source_spec.rb
|
@@ -486,8 +485,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
486
485
|
- !ruby/object:Gem::Version
|
487
486
|
version: '0'
|
488
487
|
requirements: []
|
489
|
-
|
490
|
-
rubygems_version: 2.7.7
|
488
|
+
rubygems_version: 3.0.3
|
491
489
|
signing_key:
|
492
490
|
specification_version: 4
|
493
491
|
summary: Code smell detector for Ruby
|
data/spec/factories/factories.rb
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
require_relative '../../lib/reek/smell_detectors'
|
2
|
-
require_relative '../../lib/reek/smell_detectors/base_detector'
|
3
|
-
require_relative '../../lib/reek/smell_warning'
|
4
|
-
require_relative '../../lib/reek/cli/options'
|
5
|
-
|
6
|
-
FactoryBot.define do
|
7
|
-
factory :smell_warning, class: 'Reek::SmellWarning' do
|
8
|
-
skip_create
|
9
|
-
|
10
|
-
smell_type { 'FeatureEnvy' }
|
11
|
-
source { 'dummy_file' }
|
12
|
-
lines { [42] }
|
13
|
-
message { 'smell warning message' }
|
14
|
-
parameters { {} }
|
15
|
-
context { 'self' }
|
16
|
-
|
17
|
-
initialize_with do
|
18
|
-
new(smell_type,
|
19
|
-
source: source,
|
20
|
-
context: context,
|
21
|
-
lines: lines,
|
22
|
-
message: message,
|
23
|
-
parameters: parameters)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
factory :code_comment, class: 'Reek::CodeComment' do
|
28
|
-
comment { '' }
|
29
|
-
line { 1 }
|
30
|
-
source { 'string' }
|
31
|
-
initialize_with do
|
32
|
-
new comment: comment,
|
33
|
-
line: line,
|
34
|
-
source: source
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|