sevencop 0.9.1 → 0.10.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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +19 -0
- data/config/default.yml +12 -0
- data/lib/rubocop/cop/sevencop/factory_bot_create_list.rb +94 -0
- data/lib/rubocop/cop/sevencop/hash_literal_order.rb +24 -8
- data/lib/sevencop/config_loader.rb +48 -0
- data/lib/sevencop/rubocop_extension.rb +10 -0
- data/lib/sevencop/version.rb +1 -1
- data/lib/sevencop.rb +2 -16
- metadata +5 -3
- data/lib/sevencop/inject.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ee9785d463d0e83d3f55dc1554e250e826a9cbd5aa6aacb510f11a4bdfb1947a
|
4
|
+
data.tar.gz: 9ca8456b525226ba8a599c4ef87f08ea208000268fa73ccf9f1501531682d294
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: edc7f9620eaa81224e47c8e8785df67bc29c51a0c6969f30bd24a3d6869a64be26686ccce7c3b43c89bc89f06b9283b67030587c86eb0b7ef5598d42ee1dc90b
|
7
|
+
data.tar.gz: 9a3bf2ecc2eed54ae8dd6207d0f0cd93c13f577bbcab69cdc9992e42f87687e416d9612136f1483952cfb51bdf22890727b14d6d66653e9294732dcb1da8d389
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -67,6 +67,25 @@ belongs_to :group, options
|
|
67
67
|
|
68
68
|
This is useful for migration of `config.active_record.belongs_to_required_by_default`.
|
69
69
|
|
70
|
+
### Sevencop/FactoryBotCreateList
|
71
|
+
|
72
|
+
Finds possible substitutions for `FactoryBot.create_list`.
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
# bad
|
76
|
+
Array.new(2) do
|
77
|
+
create(:user)
|
78
|
+
end
|
79
|
+
|
80
|
+
# good
|
81
|
+
create_list(:user, 2)
|
82
|
+
|
83
|
+
# good
|
84
|
+
Array.new(2) do |i|
|
85
|
+
create(:user, order: i)
|
86
|
+
end
|
87
|
+
```
|
88
|
+
|
70
89
|
### Sevencop/HashLiteralOrder
|
71
90
|
|
72
91
|
Sort Hash literal entries by key.
|
data/config/default.yml
CHANGED
@@ -5,12 +5,24 @@ Sevencop/BelongsToOptional:
|
|
5
5
|
Safe: false
|
6
6
|
VersionAdded: '0.5'
|
7
7
|
|
8
|
+
Sevencop/FactoryBotCreateList:
|
9
|
+
Description: |
|
10
|
+
Finds possible substitutions for `FactoryBot.create_list`.
|
11
|
+
Enabled: false
|
12
|
+
VersionAdded: '0.10'
|
13
|
+
|
8
14
|
Sevencop/HashLiteralOrder:
|
9
15
|
Description: |
|
10
16
|
Sort Hash literal entries by key.
|
11
17
|
Enabled: false
|
12
18
|
VersionAdded: '0.6'
|
13
19
|
|
20
|
+
Sevencop/InferredSpecType:
|
21
|
+
Description: |
|
22
|
+
Identifies redundant spec type.
|
23
|
+
Enabled: false
|
24
|
+
VersionAdded: '0.9'
|
25
|
+
|
14
26
|
Sevencop/OrderField:
|
15
27
|
Description: |
|
16
28
|
Wrap safe SQL String by `Arel.sql`.
|
@@ -0,0 +1,94 @@
|
|
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
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
# @!method extract(node)
|
56
|
+
# @param node [RuboCop::AST::BlockNode]
|
57
|
+
# @return [Array(Integer, RuboCop::AST::SendNode)]
|
58
|
+
def_node_matcher :extract, <<~PATTERN
|
59
|
+
(block
|
60
|
+
(send
|
61
|
+
(const {nil? | cbase} :Array)
|
62
|
+
:new
|
63
|
+
$(int _)
|
64
|
+
)
|
65
|
+
(args)
|
66
|
+
(send
|
67
|
+
nil?
|
68
|
+
:create
|
69
|
+
$(sym _) $(...)?
|
70
|
+
)
|
71
|
+
)
|
72
|
+
PATTERN
|
73
|
+
|
74
|
+
# @param corrector [RuboCop::Cop::Corrector]
|
75
|
+
# @param node [RuboCop::AST::BlockNode]
|
76
|
+
# @return [void]
|
77
|
+
def autocorrect(corrector, node)
|
78
|
+
count_node, factory_name_node, extra_argument_nodes = extract(node)
|
79
|
+
corrector.replace(
|
80
|
+
node,
|
81
|
+
format(
|
82
|
+
'create_list(%<arguments>s)',
|
83
|
+
arguments: [
|
84
|
+
factory_name_node,
|
85
|
+
count_node,
|
86
|
+
*extra_argument_nodes
|
87
|
+
].map(&:source).join(', ')
|
88
|
+
)
|
89
|
+
)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -55,13 +55,13 @@ module RuboCop
|
|
55
55
|
# @param [RuboCop::AST::HashNode] node
|
56
56
|
# @return [String]
|
57
57
|
def autocorrect(node)
|
58
|
-
[
|
59
|
-
'{',
|
58
|
+
parts = [
|
60
59
|
whitespace_leading(node),
|
61
60
|
sort(node.pairs).map(&:source).join(",#{whitespace_between(node)}"),
|
62
|
-
whitespace_trailing(node)
|
63
|
-
|
64
|
-
].
|
61
|
+
whitespace_trailing(node)
|
62
|
+
]
|
63
|
+
parts = ['{', *parts, '}'] if node.braces?
|
64
|
+
parts.join
|
65
65
|
end
|
66
66
|
|
67
67
|
# @param [Array<RuboCop::AST::PairNode>] pairs
|
@@ -84,7 +84,9 @@ module RuboCop
|
|
84
84
|
# ^^^
|
85
85
|
def whitespace_between(node)
|
86
86
|
if node.pairs.length >= 2
|
87
|
-
|
87
|
+
processed_source.raw_source[
|
88
|
+
node.pairs[0].location.expression.end_pos + 1...node.pairs[1].location.expression.begin_pos
|
89
|
+
]
|
88
90
|
else
|
89
91
|
' '
|
90
92
|
end
|
@@ -95,7 +97,9 @@ module RuboCop
|
|
95
97
|
# { a: 1, b: 1 }
|
96
98
|
# ^^
|
97
99
|
def whitespace_trailing(node)
|
98
|
-
|
100
|
+
processed_source.raw_source[
|
101
|
+
node.pairs[-1].location.expression.end_pos...node.location.expression.end.begin_pos - offset_for(node)
|
102
|
+
]
|
99
103
|
end
|
100
104
|
|
101
105
|
# @param [RuboCop::AST::HashNode] node
|
@@ -103,7 +107,19 @@ module RuboCop
|
|
103
107
|
# { a: 1, b: 1 }
|
104
108
|
# ^^^^
|
105
109
|
def whitespace_leading(node)
|
106
|
-
|
110
|
+
processed_source.raw_source[
|
111
|
+
node.location.expression.begin.end_pos + offset_for(node)...node.pairs[0].location.expression.begin_pos
|
112
|
+
]
|
113
|
+
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
|
107
123
|
end
|
108
124
|
end
|
109
125
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rubocop'
|
4
|
+
|
5
|
+
module Sevencop
|
6
|
+
# Merge default RuboCop config with plugin config.
|
7
|
+
class ConfigLoader
|
8
|
+
PLUGIN_CONFIG_PATH = ::File.expand_path(
|
9
|
+
'../../config/default.yml',
|
10
|
+
__dir__
|
11
|
+
)
|
12
|
+
|
13
|
+
class << self
|
14
|
+
# @return [RuboCop::Config]
|
15
|
+
def call
|
16
|
+
new.call
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [RuboCop::Config]
|
21
|
+
def call
|
22
|
+
::RuboCop::ConfigLoader.merge_with_default(
|
23
|
+
plugin_config,
|
24
|
+
PLUGIN_CONFIG_PATH
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
# @return [RuboCop::Config]
|
31
|
+
def plugin_config
|
32
|
+
config = ::RuboCop::Config.new(
|
33
|
+
plugin_config_hash,
|
34
|
+
PLUGIN_CONFIG_PATH
|
35
|
+
)
|
36
|
+
config.make_excludes_absolute
|
37
|
+
config
|
38
|
+
end
|
39
|
+
|
40
|
+
# @return [Hash]
|
41
|
+
def plugin_config_hash
|
42
|
+
::RuboCop::ConfigLoader.send(
|
43
|
+
:load_yaml_configuration,
|
44
|
+
PLUGIN_CONFIG_PATH
|
45
|
+
)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/sevencop/version.rb
CHANGED
data/lib/sevencop.rb
CHANGED
@@ -1,12 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
require 'yaml'
|
5
|
-
|
6
|
-
require_relative 'sevencop/inject'
|
3
|
+
require_relative 'sevencop/rubocop_extension'
|
7
4
|
require_relative 'sevencop/version'
|
8
5
|
|
9
6
|
require_relative 'rubocop/cop/sevencop/belongs_to_optional'
|
7
|
+
require_relative 'rubocop/cop/sevencop/factory_bot_create_list'
|
10
8
|
require_relative 'rubocop/cop/sevencop/hash_literal_order'
|
11
9
|
require_relative 'rubocop/cop/sevencop/inferred_spec_type'
|
12
10
|
require_relative 'rubocop/cop/sevencop/order_field'
|
@@ -14,15 +12,3 @@ require_relative 'rubocop/cop/sevencop/redundant_existence_check'
|
|
14
12
|
require_relative 'rubocop/cop/sevencop/to_s_with_argument'
|
15
13
|
require_relative 'rubocop/cop/sevencop/uniqueness_validator_explicit_case_sensitivity'
|
16
14
|
require_relative 'rubocop/cop/sevencop/where_not'
|
17
|
-
|
18
|
-
module Sevencop
|
19
|
-
PROJECT_ROOT = ::Pathname.new(__dir__).parent.expand_path.freeze
|
20
|
-
|
21
|
-
CONFIG_DEFAULT = PROJECT_ROOT.join('config', 'default.yml').freeze
|
22
|
-
|
23
|
-
CONFIG = ::YAML.safe_load(CONFIG_DEFAULT.read).freeze
|
24
|
-
|
25
|
-
private_constant(:CONFIG_DEFAULT, :PROJECT_ROOT)
|
26
|
-
end
|
27
|
-
|
28
|
-
Sevencop::Inject.defaults!
|
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.
|
4
|
+
version: 0.10.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-08-
|
11
|
+
date: 2022-08-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubocop
|
@@ -42,6 +42,7 @@ files:
|
|
42
42
|
- Rakefile
|
43
43
|
- config/default.yml
|
44
44
|
- lib/rubocop/cop/sevencop/belongs_to_optional.rb
|
45
|
+
- lib/rubocop/cop/sevencop/factory_bot_create_list.rb
|
45
46
|
- lib/rubocop/cop/sevencop/hash_literal_order.rb
|
46
47
|
- lib/rubocop/cop/sevencop/inferred_spec_type.rb
|
47
48
|
- lib/rubocop/cop/sevencop/order_field.rb
|
@@ -50,7 +51,8 @@ files:
|
|
50
51
|
- lib/rubocop/cop/sevencop/uniqueness_validator_explicit_case_sensitivity.rb
|
51
52
|
- lib/rubocop/cop/sevencop/where_not.rb
|
52
53
|
- lib/sevencop.rb
|
53
|
-
- lib/sevencop/
|
54
|
+
- lib/sevencop/config_loader.rb
|
55
|
+
- lib/sevencop/rubocop_extension.rb
|
54
56
|
- lib/sevencop/version.rb
|
55
57
|
- sevencop.gemspec
|
56
58
|
homepage: https://github.com/r7kamura/sevencop
|
data/lib/sevencop/inject.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rubocop'
|
4
|
-
|
5
|
-
# The original code is from https://github.com/rubocop/rubocop-rspec/blob/main/lib/rubocop/rspec/inject.rb
|
6
|
-
# See https://github.com/rubocop/rubocop-rspec/blob/main/MIT-LICENSE.md
|
7
|
-
module Sevencop
|
8
|
-
module Inject
|
9
|
-
def self.defaults!
|
10
|
-
path = CONFIG_DEFAULT.to_s
|
11
|
-
hash = ::RuboCop::ConfigLoader.send(:load_yaml_configuration, path)
|
12
|
-
config = ::RuboCop::Config.new(hash, path).tap(&:make_excludes_absolute)
|
13
|
-
puts "configuration from #{path}" if ::RuboCop::ConfigLoader.debug?
|
14
|
-
config = ::RuboCop::ConfigLoader.merge_with_default(config, path)
|
15
|
-
::RuboCop::ConfigLoader.instance_variable_set(:@default_configuration, config)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|