sevencop 0.12.1 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: adcb3382c32455ca63651bf5593974e773cf00dfd0b3d14955541c6ce219c6c7
4
- data.tar.gz: d6f50b292bb6f56c0f6ec36fc4271c931af4c1c46cef9b8c14a2505cf984f8ed
3
+ metadata.gz: 5b95d5ba5dafb534e8e3a9e5c49bd9724db92840e1ca00543251c48a6b0f74f5
4
+ data.tar.gz: c6f7822017c94416417238387b5e16b76b00e401a8819a27c0d6df40ac1373c2
5
5
  SHA512:
6
- metadata.gz: 552d6582fc4aa3baa550afd6d27477c822e4f098b470c0c038a36380c6ab74f9962a27e8f04be05cc60586be43376de1ec20a0a5b56587d71b24d3fa36e8e4cb
7
- data.tar.gz: 05df622c8de515879b816077ba5fc40cd47858c1666390beac8d2ac29e86c1983921d5d8964b8b7de64106e789f3217032b6338a9988442207dbe5aeb62a8031
6
+ metadata.gz: 131bb0495d50ebd37c0c03aa81b22d79d3488d8428697cd3af4263342f884b1857363920c40fa6794ba99e1de3e118bf94cf205cee96cc0aad77525f040072ee
7
+ data.tar.gz: f49be306dde9d6fda9db8d79a653c7814a4b43059265ceaf42fb4bbad2eee61fe112cb0ad56cdb152f626c26da9b54302f89f51f98652aa5ef37574ffcb06d45
data/.rubocop.yml CHANGED
@@ -3,6 +3,7 @@ require:
3
3
  - rubocop-performance
4
4
  - rubocop-rake
5
5
  - rubocop-rspec
6
+ - sevencop
6
7
 
7
8
  AllCops:
8
9
  NewCops: enable
@@ -25,5 +26,11 @@ RSpec/ExampleLength:
25
26
  RSpec/MultipleExpectations:
26
27
  Enabled: false
27
28
 
29
+ Sevencop/MethodDefinitionOrdered:
30
+ Enabled: true
31
+
28
32
  Style/Documentation:
29
33
  Enabled: false
34
+
35
+ Style/MultilineBlockChain:
36
+ Enabled: false
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sevencop (0.12.1)
4
+ sevencop (0.14.0)
5
5
  rubocop
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -1,7 +1,6 @@
1
1
  # sevencop
2
2
 
3
3
  [![test](https://github.com/r7kamura/sevencop/actions/workflows/test.yml/badge.svg)](https://github.com/r7kamura/sevencop/actions/workflows/test.yml)
4
- [![Gem Version](https://badge.fury.io/rb/sevencop.svg)](https://rubygems.org/gems/sevencop)
5
4
 
6
5
  Custom cops for [RuboCop](https://github.com/rubocop/rubocop).
7
6
 
@@ -45,193 +44,16 @@ Sevencop/BelongsToOptional:
45
44
 
46
45
  ## Cops
47
46
 
48
- All cops are `Enabled: false` by default.
47
+ See YARD comments in each cop class for details:
49
48
 
50
- ### Sevencop/AutoloadOrdered
49
+ - [Sevencop/BelongsToOptional](lib/rubocop/cop/sevencop/belongs_to_optional.rb)
50
+ - [Sevencop/HashElementOrdered](lib/rubocop/cop/sevencop/hash_element_ordered.rb)
51
+ - [Sevencop/InferredSpecType](lib/rubocop/cop/sevencop/inferred_spec_type.rb)
52
+ - [Sevencop/MethodDefinitionArgumentsMultiline](lib/rubocop/cop/sevencop/method_definition_arguments_multiline.rb)
53
+ - [Sevencop/MethodDefinitionKeywordArgumentsOrdered](lib/rubocop/cop/sevencop/method_definition_keyword_arguments_ordered.rb)
54
+ - [Sevencop/MethodDefinitionOrdered](lib/rubocop/cop/sevencop/method_definition_ordered.rb)
55
+ - [Sevencop/OrderField](lib/rubocop/cop/sevencop/order_field.rb)
56
+ - [Sevencop/UniquenessValidatorExplicitCaseSensitivity](lib/rubocop/cop/sevencop/uniqueness_validator_explicit_case_sensitivity.rb)
57
+ - [Sevencop/WhereNot](lib/rubocop/cop/sevencop/where_not.rb)
51
58
 
52
- Sort `autoload` in alphabetical order within their section.
53
-
54
- ```ruby
55
- # bad
56
- autoload :B, 'b'
57
- autoload :A, 'a'
58
-
59
- # good
60
- autoload :A, 'a'
61
- autoload :B, 'b'
62
-
63
- # good
64
- autoload :B, 'b'
65
- autoload :D, 'd'
66
-
67
- autoload :A, 'a'
68
- autoload :C, 'a'
69
- ```
70
-
71
- ### Sevencop/BelongsToOptional
72
-
73
- Force `belongs_to` with `optional: true` option.
74
-
75
- ```ruby
76
- # bad
77
- belongs_to :group
78
-
79
- # good
80
- belongs_to :group, optional: true
81
-
82
- # good
83
- belongs_to :group, optional: false
84
-
85
- # good
86
- belongs_to :group, options
87
- ```
88
-
89
- This is useful for migration of `config.active_record.belongs_to_required_by_default`.
90
-
91
- ### Sevencop/FactoryBotCreateList
92
-
93
- Finds possible substitutions for `FactoryBot.create_list`.
94
-
95
- ```ruby
96
- # bad
97
- Array.new(2) do
98
- create(:user)
99
- end
100
-
101
- # good
102
- create_list(:user, 2)
103
-
104
- # good
105
- Array.new(2) do |i|
106
- create(:user, order: i)
107
- end
108
- ```
109
-
110
- ### Sevencop/HashLiteralOrder
111
-
112
- Sort Hash literal entries by key.
113
-
114
- ```ruby
115
- # bad
116
- {
117
- b: 1,
118
- a: 1,
119
- c: 1
120
- }
121
-
122
- # good
123
- {
124
- a: 1,
125
- b: 1,
126
- c: 1
127
- }
128
- ```
129
-
130
- ### Sevencop/InferredSpecType
131
-
132
- Identifies redundant spec type.
133
-
134
- ```ruby
135
- # bad
136
- # spec/models/user_spec.rb
137
- RSpec.describe User, type: :model
138
-
139
- # good
140
- # spec/models/user_spec.rb
141
- RSpec.describe User
142
-
143
- # good
144
- # spec/models/user_spec.rb
145
- RSpec.describe User, type: :request
146
- ```
147
-
148
- ### Sevencop/MethodDefinitionMultilineArguments
149
-
150
- Inserts new lines between method definition parameters.
151
-
152
- ```ruby
153
- # bad
154
- def foo(a, b)
155
- end
156
-
157
- # good
158
- def foo(
159
- a,
160
- b
161
- )
162
-
163
- # good
164
- def foo(a)
165
- end
166
- ```
167
-
168
- ### Sevencop/OrderField
169
-
170
- Identifies a String including "field" is passed to `order` or `reorder`.
171
-
172
- ```ruby
173
- # bad
174
- articles.order('field(id, ?)', a)
175
-
176
- # good
177
- articles.order(Arel.sql('field(id, ?)'), a)
178
-
179
- # bad
180
- reorder('field(id, ?)', a)
181
-
182
- # good
183
- reorder(Arel.sql('field(id, ?)'), a)
184
- ```
185
-
186
- ### Sevencop/RedundantExistenceCheck
187
-
188
- Identifies redundant existent check before file operation.
189
-
190
- ```ruby
191
- # bad
192
- FileUtils.mkdir(a) unless FileTest.exist?(a)
193
-
194
- # good
195
- FileUtils.mkdir_p(a)
196
-
197
- # bad
198
- FileUtils.rm(a) if FileTest.exist?(a)
199
-
200
- # good
201
- FileUtils.rm_f(a)
202
- ```
203
-
204
- ### Sevencop/UniquenessValidatorExplicitCaseSensitivity
205
-
206
- Identifies use of UniquenessValidator without :case_sensitive option.
207
-
208
- ```ruby
209
- # bad
210
- validates :name, uniqueness: true
211
-
212
- # good
213
- validates :name, uniqueness: { case_sensitive: true }
214
-
215
- # good
216
- validates :name, uniqueness: { case_sensitive: false }
217
-
218
- # bad
219
- validates :name, uniqueness: { allow_nil: true, scope: :user_id }
220
-
221
- # good
222
- validates :name, uniqueness: { allow_nil: true, scope: :user_id, case_sensitive: true }
223
- ```
224
-
225
- Useful to keep the same behavior between Rails 6.0 and 6.1 where case insensitive collation is used in MySQL.
226
-
227
- ### Sevencop/WhereNot
228
-
229
- Identifies passing multi-elements Hash literal to `where.not`.
230
-
231
- ```ruby
232
- # bad
233
- where.not(key1: value1, key2: value2)
234
-
235
- # good
236
- where.not(key1: value1).where.not(key2: value2)
237
- ```
59
+ Note that all cops are `Enabled: false` by default.
data/config/default.yml CHANGED
@@ -2,7 +2,7 @@ Sevencop/AutoloadOrdered:
2
2
  Description: |
3
3
  Sort `autoload` in alphabetical order.
4
4
  Enabled: false
5
- VersionAdded: '0.12.0'
5
+ VersionAdded: '0.12'
6
6
 
7
7
  Sevencop/BelongsToOptional:
8
8
  Description: |
@@ -11,15 +11,9 @@ Sevencop/BelongsToOptional:
11
11
  Safe: false
12
12
  VersionAdded: '0.5'
13
13
 
14
- Sevencop/FactoryBotCreateList:
14
+ Sevencop/HashElementOrdered:
15
15
  Description: |
16
- Finds possible substitutions for `FactoryBot.create_list`.
17
- Enabled: false
18
- VersionAdded: '0.10'
19
-
20
- Sevencop/HashLiteralOrder:
21
- Description: |
22
- Sort Hash literal entries by key.
16
+ Sort Hash elements by key.
23
17
  Enabled: false
24
18
  VersionAdded: '0.6'
25
19
 
@@ -29,32 +23,30 @@ Sevencop/InferredSpecType:
29
23
  Enabled: false
30
24
  VersionAdded: '0.9'
31
25
 
32
- Sevencop/MethodDefinitionMultilineArguments:
26
+ Sevencop/MethodDefinitionArgumentsMultiline:
33
27
  Description: |
34
- Inserts new lines between method definition parameters.
28
+ Inserts new lines between method definition arguments.
35
29
  Enabled: false
36
30
  VersionAdded: '0.11'
37
31
 
38
- Sevencop/OrderField:
32
+ Sevencop/MethodDefinitionOrdered:
39
33
  Description: |
40
- Wrap safe SQL String by `Arel.sql`.
34
+ Sort method definitions in alphabetical order.
41
35
  Enabled: false
42
- Safe: false
43
- VersionAdded: '0.4'
36
+ VersionAdded: '0.14'
44
37
 
45
- Sevencop/RedundantExistenceCheck:
38
+ Sevencop/MethodDefinitionKeywordArgumentsOrdered:
46
39
  Description: |
47
- Avoid redundant existent check before file operation.
40
+ Sort method definition keyword arguments in alphabetical order.
48
41
  Enabled: false
49
- Safe: false
50
- VersionAdded: '0.1'
42
+ VersionAdded: '0.13'
51
43
 
52
- Sevencop/ToSWithArgument:
44
+ Sevencop/OrderField:
53
45
  Description: |
54
- Identifies passing any argument to `#to_s`.
46
+ Wrap safe SQL String by `Arel.sql`.
55
47
  Enabled: false
56
48
  Safe: false
57
- VersionAdded: '0.8'
49
+ VersionAdded: '0.4'
58
50
 
59
51
  Sevencop/UniquenessValidatorExplicitCaseSensitivity:
60
52
  Description: |
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Sevencop
6
- # Sort `autoload` in alphabetical order within their section.
6
+ # Sort `autoload` in alphabetical order.
7
7
  #
8
8
  # @example
9
9
  # # bad
@@ -25,7 +25,7 @@ module RuboCop
25
25
 
26
26
  include RangeHelp
27
27
 
28
- MSG = 'Sort `autoload` in alphabetical order within their section.'
28
+ MSG = 'Sort `autoload` in alphabetical order.'
29
29
 
30
30
  RESTRICT_ON_SEND = %i[
31
31
  autoload
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Sevencop
6
- # Sort Hash literal entries by key.
6
+ # Sort Hash elements by key.
7
7
  #
8
8
  # @example
9
9
  #
@@ -21,10 +21,10 @@ module RuboCop
21
21
  # c: 1
22
22
  # }
23
23
  #
24
- class HashLiteralOrder < Base
24
+ class HashElementOrdered < Base
25
25
  extend AutoCorrector
26
26
 
27
- MSG = 'Sort Hash literal entries by key.'
27
+ MSG = 'Sort Hash elements by key.'
28
28
 
29
29
  # @!method hash_literal?(node)
30
30
  def_node_matcher :hash_literal?, <<~PATTERN
@@ -64,6 +64,16 @@ module RuboCop
64
64
  parts.join
65
65
  end
66
66
 
67
+ # @param [RuboCop::AST::HashNode] node
68
+ # @return [Integer]
69
+ def offset_for(node)
70
+ if node.braces?
71
+ 1
72
+ else
73
+ 0
74
+ end
75
+ end
76
+
67
77
  # @param [Array<RuboCop::AST::PairNode>] pairs
68
78
  # @return [Array<RuboCop::AST::PairNode>]
69
79
  def sort(pairs)
@@ -95,32 +105,22 @@ module RuboCop
95
105
  # @param [RuboCop::AST::HashNode] node
96
106
  # @return [String]
97
107
  # { a: 1, b: 1 }
98
- # ^^
99
- def whitespace_trailing(node)
108
+ # ^^^^
109
+ def whitespace_leading(node)
100
110
  processed_source.raw_source[
101
- node.pairs[-1].location.expression.end_pos...node.location.expression.end.begin_pos - offset_for(node)
111
+ node.location.expression.begin.end_pos + offset_for(node)...node.pairs[0].location.expression.begin_pos
102
112
  ]
103
113
  end
104
114
 
105
115
  # @param [RuboCop::AST::HashNode] node
106
116
  # @return [String]
107
117
  # { a: 1, b: 1 }
108
- # ^^^^
109
- def whitespace_leading(node)
118
+ # ^^
119
+ def whitespace_trailing(node)
110
120
  processed_source.raw_source[
111
- node.location.expression.begin.end_pos + offset_for(node)...node.pairs[0].location.expression.begin_pos
121
+ node.pairs[-1].location.expression.end_pos...node.location.expression.end.begin_pos - offset_for(node)
112
122
  ]
113
123
  end
114
-
115
- # @param [RuboCop::AST::HashNode] node
116
- # @return [Integer]
117
- def offset_for(node)
118
- if node.braces?
119
- 1
120
- else
121
- 0
122
- end
123
- end
124
124
  end
125
125
  end
126
126
  end
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Sevencop
6
- # Inserts new lines between method definition parameters.
6
+ # Inserts new lines between method definition arguments.
7
7
  #
8
8
  # @example
9
9
  # # bad
@@ -19,10 +19,10 @@ module RuboCop
19
19
  # # good
20
20
  # def foo(a)
21
21
  # end
22
- class MethodDefinitionMultilineArguments < Base
22
+ class MethodDefinitionArgumentsMultiline < Base
23
23
  extend AutoCorrector
24
24
 
25
- MSG = 'Insert new lines between method definition parameters.'
25
+ MSG = 'Insert new lines between method definition arguments.'
26
26
 
27
27
  # @param node [RuboCop::AST::ArgsNode]
28
28
  def on_args(node)
@@ -54,6 +54,11 @@ module RuboCop
54
54
  )
55
55
  end
56
56
 
57
+ # @return [Boolean]
58
+ def method_args?(node)
59
+ !node.parent.nil? && node.parent.def_type?
60
+ end
61
+
57
62
  # @param node [RuboCop::AST::ArgsNode]
58
63
  # @return [Boolean]
59
64
  def multilined?(node)
@@ -61,11 +66,6 @@ module RuboCop
61
66
  child.location.expression.line
62
67
  end.uniq.length == node.children.length
63
68
  end
64
-
65
- # @return [Boolean]
66
- def method_args?(node)
67
- !node.parent.nil? && node.parent.def_type?
68
- end
69
69
  end
70
70
  end
71
71
  end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Sevencop
6
+ # Sort method definition keyword arguments in alphabetical order.
7
+ #
8
+ # @example
9
+ # # bad
10
+ # def foo(b:, a:); end
11
+ #
12
+ # # good
13
+ # def foo(a:, b:); end
14
+ #
15
+ # # bad
16
+ # def foo(c:, d:, b: 1, a: 2); end
17
+ #
18
+ # # good
19
+ # def foo(c:, d:, a: 2, b: 1); end
20
+ class MethodDefinitionKeywordArgumentsOrdered < Base
21
+ extend AutoCorrector
22
+
23
+ MSG = 'Sort method definition keyword arguments in alphabetical order.'
24
+
25
+ # @param node [RuboCop::AST::ArgNode]
26
+ def on_kwarg(node)
27
+ previous_older_kwarg = find_previous_older_sibling(node)
28
+ return unless previous_older_kwarg
29
+
30
+ add_offense(node) do |corrector|
31
+ corrector.insert_before(
32
+ previous_older_kwarg,
33
+ "#{node.source}, "
34
+ )
35
+ corrector.remove(
36
+ node.location.expression.with(
37
+ begin_pos: node.left_sibling.location.expression.end_pos
38
+ )
39
+ )
40
+ end
41
+ end
42
+ alias on_kwoptarg on_kwarg
43
+
44
+ private
45
+
46
+ # @param node [RuboCop::AST::ArgNode]
47
+ # @return [RuboCop::AST::ArgNode]
48
+ def find_previous_older_sibling(node)
49
+ node.left_siblings.find do |sibling|
50
+ next if sibling.type != node.type
51
+
52
+ sibling.name > node.name
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Sevencop
6
+ # Sort method definition in alphabetical order.
7
+ #
8
+ # @example
9
+ # # bad
10
+ # def b; end
11
+ # def a; end
12
+ #
13
+ # # good
14
+ # def a; end
15
+ # def b; end
16
+ #
17
+ # # good
18
+ # def b; end
19
+ # def c; end
20
+ # private
21
+ # def a; end
22
+ # def d; end
23
+ #
24
+ # # good
25
+ # def initialize; end
26
+ # def a; end
27
+ class MethodDefinitionOrdered < Base
28
+ extend AutoCorrector
29
+
30
+ include RangeHelp
31
+ include VisibilityHelp
32
+
33
+ MSG = 'Sort method definition in alphabetical order.'
34
+
35
+ # @param node [RuboCop::AST::DefNode]
36
+ def on_def(node)
37
+ previous_older_sibling = find_previous_older_sibling(node)
38
+ return unless previous_older_sibling
39
+
40
+ add_offense(node) do |corrector|
41
+ swap(
42
+ range_by_whole_lines(
43
+ range_with_comments(previous_older_sibling),
44
+ include_final_newline: true
45
+ ),
46
+ range_by_whole_lines(
47
+ range_with_comments(node),
48
+ include_final_newline: true
49
+ ),
50
+ corrector: corrector
51
+ )
52
+ end
53
+ end
54
+ alias on_defs on_def
55
+
56
+ private
57
+
58
+ # @param node [RuboCop::AST::DefNode]
59
+ # @return [RuboCop::AST::DefNode]
60
+ def find_previous_older_sibling(node)
61
+ previous_siblings_in_same_section_of(node).find do |sibling|
62
+ next if sibling.type != node.type
63
+
64
+ (sort_key_of(sibling) <=> sort_key_of(node)) == 1
65
+ end
66
+ end
67
+
68
+ # @param node [RuboCop::AST::Node]
69
+ # @return [Array<RuboCop::AST::Node>]
70
+ def previous_siblings_in_same_section_of(node)
71
+ return node.left_siblings if node.defs_type?
72
+
73
+ node.left_siblings.reverse.take_while do |sibling|
74
+ !visibility_block?(sibling)
75
+ end.reverse
76
+ end
77
+
78
+ # @param node [RuboCop::AST::Node]
79
+ # @return [Paresr::Source::Range]
80
+ def range_with_comments(node)
81
+ comment = processed_source.ast_with_comments[node].first
82
+ if comment
83
+ node.location.expression.with(begin_pos: comment.location.expression.begin_pos)
84
+ else
85
+ node.location.expression
86
+ end
87
+ end
88
+
89
+ # @param node [RuboCop::AST::DefNode]
90
+ # @return [#<=>]
91
+ def sort_key_of(node)
92
+ [
93
+ node.method?(:initialize) ? 0 : 1,
94
+ node.method_name
95
+ ]
96
+ end
97
+
98
+ # @param range1 [Paresr::Source::Range]
99
+ # @param range2 [Paresr::Source::Range]
100
+ # @param corrector [RuboCop::AST::Corrector]
101
+ def swap(range1, range2, corrector:)
102
+ corrector.insert_before(
103
+ range1,
104
+ "#{range2.source}\n"
105
+ )
106
+ corrector.remove(range2)
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
@@ -65,6 +65,11 @@ module RuboCop
65
65
  )
66
66
  PATTERN
67
67
 
68
+ # @param [RuboCop::AST::SendNode] node
69
+ def find_uniqueness_value(node)
70
+ node.arguments[1].pairs.find { |pair| pair.key.value == :uniqueness }.value
71
+ end
72
+
68
73
  # @param [RuboCop::AST::SendNode] node
69
74
  def on_send(node)
70
75
  return unless validates_uniqueness?(node) && !validates_uniqueness_with_case_sensitivity?(node)
@@ -84,11 +89,6 @@ module RuboCop
84
89
  end
85
90
  end
86
91
  end
87
-
88
- # @param [RuboCop::AST::SendNode] node
89
- def find_uniqueness_value(node)
90
- node.arguments[1].pairs.find { |pair| pair.key.value == :uniqueness }.value
91
- end
92
92
  end
93
93
  end
94
94
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sevencop
4
- VERSION = '0.12.1'
4
+ VERSION = '0.14.0'
5
5
  end
data/lib/sevencop.rb CHANGED
@@ -5,12 +5,11 @@ require_relative 'sevencop/version'
5
5
 
6
6
  require_relative 'rubocop/cop/sevencop/autoload_ordered'
7
7
  require_relative 'rubocop/cop/sevencop/belongs_to_optional'
8
- require_relative 'rubocop/cop/sevencop/factory_bot_create_list'
9
- require_relative 'rubocop/cop/sevencop/hash_literal_order'
8
+ require_relative 'rubocop/cop/sevencop/hash_element_ordered'
10
9
  require_relative 'rubocop/cop/sevencop/inferred_spec_type'
11
- require_relative 'rubocop/cop/sevencop/method_definition_multiline_arguments'
10
+ require_relative 'rubocop/cop/sevencop/method_definition_arguments_multiline'
11
+ require_relative 'rubocop/cop/sevencop/method_definition_keyword_arguments_ordered'
12
+ require_relative 'rubocop/cop/sevencop/method_definition_ordered'
12
13
  require_relative 'rubocop/cop/sevencop/order_field'
13
- require_relative 'rubocop/cop/sevencop/redundant_existence_check'
14
- require_relative 'rubocop/cop/sevencop/to_s_with_argument'
15
14
  require_relative 'rubocop/cop/sevencop/uniqueness_validator_explicit_case_sensitivity'
16
15
  require_relative 'rubocop/cop/sevencop/where_not'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sevencop
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.1
4
+ version: 0.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryo Nakamura
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-09-23 00:00:00.000000000 Z
11
+ date: 2022-09-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubocop
@@ -43,13 +43,12 @@ files:
43
43
  - config/default.yml
44
44
  - lib/rubocop/cop/sevencop/autoload_ordered.rb
45
45
  - lib/rubocop/cop/sevencop/belongs_to_optional.rb
46
- - lib/rubocop/cop/sevencop/factory_bot_create_list.rb
47
- - lib/rubocop/cop/sevencop/hash_literal_order.rb
46
+ - lib/rubocop/cop/sevencop/hash_element_ordered.rb
48
47
  - lib/rubocop/cop/sevencop/inferred_spec_type.rb
49
- - lib/rubocop/cop/sevencop/method_definition_multiline_arguments.rb
48
+ - lib/rubocop/cop/sevencop/method_definition_arguments_multiline.rb
49
+ - lib/rubocop/cop/sevencop/method_definition_keyword_arguments_ordered.rb
50
+ - lib/rubocop/cop/sevencop/method_definition_ordered.rb
50
51
  - lib/rubocop/cop/sevencop/order_field.rb
51
- - lib/rubocop/cop/sevencop/redundant_existence_check.rb
52
- - lib/rubocop/cop/sevencop/to_s_with_argument.rb
53
52
  - lib/rubocop/cop/sevencop/uniqueness_validator_explicit_case_sensitivity.rb
54
53
  - lib/rubocop/cop/sevencop/where_not.rb
55
54
  - lib/sevencop.rb
@@ -1,95 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module Sevencop
6
- # Finds possible substitutions for `FactoryBot.create_list`.
7
- #
8
- # @example
9
- #
10
- # # bad
11
- # Array.new(2) do
12
- # create(:user)
13
- # end
14
- #
15
- # # good
16
- # create_list(:user, 2)
17
- #
18
- # # good
19
- # Array.new(2) do |i|
20
- # create(:user, order: i)
21
- # end
22
- #
23
- # @note
24
- # This cop does not support `Integer#times` intentionally because it
25
- # should be treated by `Performance/TimesMap` cop.
26
- #
27
- class FactoryBotCreateList < Base
28
- extend AutoCorrector
29
-
30
- MSG = 'Use `create_list` instead.'
31
-
32
- # @param node [RuboCop::AST::BlockNode]
33
- # @return [void]
34
- def on_block(node)
35
- count_node, factory_name_node, extra_argument_nodes = extract(node)
36
- return unless count_node
37
-
38
- add_offense(node) do |corrector|
39
- corrector.replace(
40
- node,
41
- format(
42
- 'create_list(%<arguments>s)',
43
- arguments: [
44
- factory_name_node,
45
- count_node,
46
- *extra_argument_nodes
47
- ].map(&:source).join(', ')
48
- )
49
- )
50
- end
51
- end
52
- alias on_numblock on_block
53
-
54
- private
55
-
56
- # @!method extract(node)
57
- # @param node [RuboCop::AST::BlockNode]
58
- # @return [Array(Integer, RuboCop::AST::SendNode)]
59
- def_node_matcher :extract, <<~PATTERN
60
- (block
61
- (send
62
- (const {nil? | cbase} :Array)
63
- :new
64
- $(int _)
65
- )
66
- (args)
67
- (send
68
- nil?
69
- :create
70
- $(sym _) $(...)?
71
- )
72
- )
73
- PATTERN
74
-
75
- # @param corrector [RuboCop::Cop::Corrector]
76
- # @param node [RuboCop::AST::BlockNode]
77
- # @return [void]
78
- def autocorrect(corrector, node)
79
- count_node, factory_name_node, extra_argument_nodes = extract(node)
80
- corrector.replace(
81
- node,
82
- format(
83
- 'create_list(%<arguments>s)',
84
- arguments: [
85
- factory_name_node,
86
- count_node,
87
- *extra_argument_nodes
88
- ].map(&:source).join(', ')
89
- )
90
- )
91
- end
92
- end
93
- end
94
- end
95
- end
@@ -1,188 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module Sevencop
6
- # Identifies redundant existent check before file operation.
7
- #
8
- # @safety
9
- # This cop is unsafe because it can register a false positive where the check is truly needed.
10
- #
11
- # @example
12
- #
13
- # # bad
14
- # FileUtils.mkdir(a) unless FileTest.exist?(a)
15
- #
16
- # # good
17
- # FileUtils.mkdir_p(a)
18
- #
19
- # # bad
20
- # FileUtils.rm(a) if File.exist?(a)
21
- #
22
- # # good
23
- # FileUtils.rm_f(a)
24
- #
25
- class RedundantExistenceCheck < Base
26
- extend AutoCorrector
27
-
28
- CLASS_NAMES_FOR_EXIST = ::Set[
29
- :File,
30
- :FileTest,
31
- ]
32
-
33
- CLASS_NAMES_FOR_OPERATION = ::Set[
34
- :File,
35
- :FileUtils,
36
- ]
37
-
38
- METHOD_NAMES_FOR_MAKE = ::Set[
39
- :makedirs,
40
- :mkdir,
41
- :mkdir_p,
42
- :mkpath,
43
- :touch,
44
- ]
45
-
46
- METHOD_NAMES_FOR_REMOVE = ::Set[
47
- :delete,
48
- :remove,
49
- :remove_dir,
50
- :remove_entry,
51
- :remove_entry_secure,
52
- :remove_file,
53
- :rm,
54
- :rm_f,
55
- :rm_r,
56
- :rm_rf,
57
- :rmdir,
58
- :rmtree,
59
- :safe_unlink,
60
- :unlink,
61
- ]
62
-
63
- METHOD_NAMES_FOR_EXIST = ::Set[
64
- :exist?,
65
- :exists?,
66
- ]
67
-
68
- METHOD_NAMES_FOR_FORCE_OPERATION = ::Set[
69
- :makedirs,
70
- :mkdir_p,
71
- :mkpath,
72
- :rm_f,
73
- :rm_rf,
74
- :rm_tree,
75
- :safe_unlink,
76
- :touch,
77
- ]
78
-
79
- METHOD_MAPPING_FOR_FORCE_REPLACEMENT = {
80
- 'FileUtils.mkdir' => 'FileUtils.mkdir_p',
81
- 'File.delete' => 'FileUtils.rm_f',
82
- 'File.unlink' => 'FileUtils.rm_f'
83
- }.freeze
84
-
85
- MSG = 'Avoid redundant existent check before file operation.'
86
-
87
- # @!method make_unless_exist?(node)
88
- def_node_matcher :make_unless_exist?, <<~PATTERN
89
- (if
90
- (send (const nil? CLASS_NAMES_FOR_EXIST) METHOD_NAMES_FOR_EXIST _)
91
- nil?
92
- (send (const nil? CLASS_NAMES_FOR_OPERATION) METHOD_NAMES_FOR_MAKE ...)
93
- )
94
- PATTERN
95
-
96
- # @!method remove_if_exist?(node)
97
- def_node_matcher :remove_if_exist?, <<~PATTERN
98
- (if
99
- (send (const nil? CLASS_NAMES_FOR_EXIST) METHOD_NAMES_FOR_EXIST _)
100
- (send (const nil? CLASS_NAMES_FOR_OPERATION) METHOD_NAMES_FOR_REMOVE ...)
101
- nil?
102
- )
103
- PATTERN
104
-
105
- def on_if(node)
106
- return unless redundant_on_if(node) || redundant_on_unless(node)
107
-
108
- add_offense(node) do |corrector|
109
- corrector.replace(
110
- node.location.expression,
111
- enforce(node)
112
- )
113
- end
114
- end
115
-
116
- private
117
-
118
- def enforce(node)
119
- if force_operation?(node)
120
- node.if_branch.source
121
- elsif force_replaceable_method?(node)
122
- enforce_by_replacement(node)
123
- else
124
- enforce_by_force_option(node)
125
- end
126
- end
127
-
128
- def enforce_by_force_option(node)
129
- arguments = node.if_branch.arguments.map(&:source)
130
- arguments << 'force: true' unless force_operation?(node)
131
- format(
132
- '%<receiver>s.%<method_name>s(%<arguments>s)',
133
- arguments: arguments.join(', '),
134
- method_name: node.if_branch.method_name,
135
- receiver: node.if_branch.receiver.source
136
- )
137
- end
138
-
139
- def enforce_by_replacement(node)
140
- format(
141
- '%<signature>s(%<arguments>s)',
142
- arguments: node.if_branch.arguments.map(&:source).join(', '),
143
- signature: METHOD_MAPPING_FOR_FORCE_REPLACEMENT[operation_method_signature(node)]
144
- )
145
- end
146
-
147
- def force_operation?(node)
148
- force_operation_method_name?(node) || force_operation_argument?(node)
149
- end
150
-
151
- def force_operation_argument?(node)
152
- node.if_branch.last_argument.hash_type? &&
153
- node.if_branch.last_argument.pairs.any? do |pair|
154
- pair.key.value == :force && pair.value.true_type?
155
- end
156
- end
157
-
158
- def force_operation_method_name?(node)
159
- METHOD_NAMES_FOR_FORCE_OPERATION.include?(node.if_branch.method_name)
160
- end
161
-
162
- def redundant_on_if(node)
163
- remove_if_exist?(node) && same_argument?(node)
164
- end
165
-
166
- def redundant_on_unless(node)
167
- make_unless_exist?(node) && same_argument?(node)
168
- end
169
-
170
- def force_replaceable_method?(node)
171
- METHOD_MAPPING_FOR_FORCE_REPLACEMENT.key?(operation_method_signature(node))
172
- end
173
-
174
- def operation_method_signature(node)
175
- format(
176
- '%<receiver>s.%<method_name>s',
177
- method_name: node.if_branch.method_name,
178
- receiver: node.if_branch.receiver.source
179
- )
180
- end
181
-
182
- def same_argument?(node)
183
- node.condition.first_argument == node.if_branch.first_argument
184
- end
185
- end
186
- end
187
- end
188
- end
@@ -1,42 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module Sevencop
6
- # Identifies passing any argument to `#to_s`.
7
- #
8
- # @example
9
- #
10
- # # bad
11
- # to_s(:delimited)
12
- #
13
- # # good
14
- # to_formatted_s(:delimited)
15
- #
16
- class ToSWithArgument < Base
17
- extend AutoCorrector
18
-
19
- MSG = 'Use `to_formatted_s(...)` instead of `to_s(...)`.'
20
-
21
- RESTRICT_ON_SEND = %i[to_s].freeze
22
-
23
- # @!method to_s_with_any_argument?(node)
24
- def_node_matcher :to_s_with_any_argument?, <<~PATTERN
25
- (call _ :to_s _+)
26
- PATTERN
27
-
28
- def on_send(node)
29
- return unless to_s_with_any_argument?(node)
30
-
31
- add_offense(node) do |rewriter|
32
- rewriter.replace(
33
- node.loc.selector,
34
- 'to_formatted_s'
35
- )
36
- end
37
- end
38
- alias on_csend on_send
39
- end
40
- end
41
- end
42
- end