reek 6.0.0 → 6.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|