sevencop 0.12.1 → 0.14.0

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 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