rubocop-petal 1.5.0 → 1.7.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: cdc12661793d2fbaa5d5634b86c23eb3e249a884ec4902406d66d969565fccd7
4
- data.tar.gz: 8b1b59059300e38b056fab5b4c1d342ae3bf61dcd0db1204f140586c15dc889a
3
+ metadata.gz: b251a6179c5a736bae1a6cf26c2dbf68057acd2640d4fcf8c34c8dd258ee1da6
4
+ data.tar.gz: 234f960f5ea66302e1d32dc265a7cb19c9eda1757c5417fae2f9dec81c8cc047
5
5
  SHA512:
6
- metadata.gz: 5c1494de93b6053ecac07431001234072212e9f62f9130b3dcc6ccefd3218cb3b454e5ace6de2c1e0d6d6aa91adf651d5454ebcfbca346b707579d45e855e77f
7
- data.tar.gz: adb3d03f9419b9629ae7db9b7b1b4e811ce9d27a6a3b209f6ad6feaa4ca7edce47da7c698d3e9074cf25c3d452f022a2abebf0c80bb9b1b9764178614a571133
6
+ metadata.gz: ae6a1f7cd5f6389bdf766715b5802ebdaf9268da780e78863dc3d040cac9845308f76aa4a875eefde4ea5be7923cd0e5e5ec02b6c3ad9421ce35c7865144675b
7
+ data.tar.gz: 4cb53383bc8a1fa6b062395d0d5f6665320d470d11b7890ff2bee96d912c15329435ad87cd2e409b7db76663ef364150754859765a2991dab15d88e94e4f4ac2
data/config/default.yml CHANGED
@@ -157,3 +157,4 @@ Sidekiq/PerformInline:
157
157
  Sidekiq/SymbolArgument:
158
158
  Description: "Prevent passing keywords arguments in worker's perform method"
159
159
  Enabled: true
160
+ SafeAutoCorrect: false
@@ -5,7 +5,7 @@ module RuboCop
5
5
  module Rails
6
6
  # Disallow ActiveRecord calls that pass interpolated or added strings as an argument.
7
7
  # https://github.com/airbnb/ruby/blob/12435e8136d2adf710de999bc0f6bef01215df2c/rubocop-airbnb/lib/rubocop/cop/airbnb/risky_activerecord_invocation.rb
8
- class RiskyActiverecordInvocation < Cop
8
+ class RiskyActiverecordInvocation < Base
9
9
  VULNERABLE_AR_METHODS = %i[
10
10
  delete_all
11
11
  destroy_all
@@ -6,7 +6,7 @@ module RuboCop
6
6
  module Cop
7
7
  module RSpec
8
8
  # RSpec public API methods that are commonly used in cops
9
- class AggregateExamples < ::RuboCop::Cop::Cop
9
+ class AggregateExamples < Base
10
10
  module Language
11
11
  RSPEC = '{(const {nil? cbase} :RSpec) nil?}'
12
12
 
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module RSpec
6
- class AggregateExamples < ::RuboCop::Cop::Cop
6
+ class AggregateExamples < Base
7
7
  # @internal Support methods for keeping newlines around examples.
8
8
  module LineRangeHelpers
9
9
  include RangeHelp
@@ -5,7 +5,7 @@ require_relative 'language'
5
5
  module RuboCop
6
6
  module Cop
7
7
  module RSpec
8
- class AggregateExamples < ::RuboCop::Cop::Cop
8
+ class AggregateExamples < Base
9
9
  # When aggregated, the expectations will fail when not supposed to or
10
10
  # have a risk of not failing when expected to. One example is
11
11
  # `validate_presence_of :comment` as it leaves an empty comment after
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module RSpec
6
- class AggregateExamples < ::RuboCop::Cop::Cop
6
+ class AggregateExamples < Base
7
7
  # @internal
8
8
  # Support methods for example metadata.
9
9
  # Examples with similar metadata are grouped.
@@ -5,7 +5,7 @@ require_relative 'language'
5
5
  module RuboCop
6
6
  module Cop
7
7
  module RSpec
8
- class AggregateExamples < ::RuboCop::Cop::Cop
8
+ class AggregateExamples < Base
9
9
  # @internal
10
10
  # Node matchers and searchers.
11
11
  module NodeMatchers
@@ -109,10 +109,11 @@ module RuboCop
109
109
  # expect(number).to be_odd
110
110
  # end
111
111
  #
112
- class AggregateExamples < ::RuboCop::Cop::Cop
112
+ class AggregateExamples < Base
113
113
  include LineRangeHelpers
114
114
  include MetadataHelpers
115
115
  include NodeMatchers
116
+ extend AutoCorrector
116
117
 
117
118
  # Methods from the following modules override and extend methods of this
118
119
  # class, extracting specific behavior.
@@ -124,25 +125,21 @@ module RuboCop
124
125
  example_group_with_several_examples(node) do |all_examples|
125
126
  example_clusters(all_examples).each_value do |examples|
126
127
  examples[1..].each do |example|
127
- add_offense(example,
128
- location: :expression,
129
- message: message_for(example, examples[0]))
128
+ add_offense(example, message: message_for(example, examples[0])) do |corrector|
129
+ clusters = example_clusters_for_autocorrect(example)
130
+ autocorrect(corrector, clusters)
131
+ end
130
132
  end
131
133
  end
132
134
  end
133
135
  end
134
136
 
135
- def autocorrect(example_node)
136
- clusters = example_clusters_for_autocorrect(example_node)
137
- return if clusters.empty?
138
-
139
- lambda do |corrector|
140
- clusters.each do |metadata, examples|
141
- range = range_for_replace(examples)
142
- replacement = aggregated_example(examples, metadata)
143
- corrector.replace(range, replacement)
144
- examples[1..].map { |example| drop_example(corrector, example) }
145
- end
137
+ def autocorrect(corrector, clusters)
138
+ clusters.each do |metadata, examples|
139
+ range = range_for_replace(examples)
140
+ replacement = aggregated_example(examples, metadata)
141
+ corrector.replace(range, replacement)
142
+ examples[1..].map { |example| drop_example(corrector, example) }
146
143
  end
147
144
  end
148
145
 
@@ -25,8 +25,8 @@ module RuboCop
25
25
 
26
26
  include Helpers
27
27
 
28
- MSG = 'Objects are not Sidekiq-serializable.'
29
- MSG_SELF = '`self` is not Sidekiq-serializable.'
28
+ MSG = 'Objects are not native JSON types.'
29
+ MSG_SELF = '`self` is not a native JSON type.'
30
30
 
31
31
  def_node_matcher :initializer?, <<~PATTERN
32
32
  (send const :new)
@@ -34,7 +34,7 @@ module RuboCop
34
34
  # # good
35
35
  # MyWorker.perform_async(Time.now.mday)
36
36
  #
37
- class DateTimeArgument < ::RuboCop::Cop::Cop
37
+ class DateTimeArgument < Base
38
38
  DURATION_METHODS = %i[
39
39
  second
40
40
  seconds
@@ -61,8 +61,8 @@ module RuboCop
61
61
 
62
62
  include Helpers
63
63
 
64
- DURATION_MSG = 'Durations are not Sidekiq-serializable; use the integer instead.'
65
- MSG = 'Date/Time objects are not Sidekiq-serializable; convert to integers or strings instead.'
64
+ DURATION_MSG = 'Durations are not native JSON types; use the integer instead.'
65
+ MSG = 'Date/Time objects are not native JSON types; convert to integers or strings instead.'
66
66
  ALLOWED_METHODS = %i[to_i to_s].freeze
67
67
 
68
68
  def_node_matcher :rational_literal?, <<~PATTERN
@@ -50,20 +50,49 @@ module RuboCop
50
50
  node.each_ancestor(:class, :block).detect { |anc| sidekiq_worker?(anc) }
51
51
  end
52
52
 
53
- def sidekiq_arguments(node)
53
+ def sidekiq_arguments(node, &block)
54
54
  return [] unless node.send_type? && (method_name = sidekiq_perform?(node))
55
+ return enum_for(:sidekiq_arguments, node) unless block
55
56
 
56
57
  # Drop the first argument for perform_at and perform_in
57
- expand_arguments(method_name == :perform_async ? node.arguments : node.arguments[1..])
58
+ expand_nodes(method_name == :perform_async ? node.arguments : node.arguments[1..], &block)
58
59
  end
59
60
 
60
- def expand_arguments(arguments)
61
- arguments.flat_map do |argument|
62
- if argument.array_type? || argument.hash_type?
63
- expand_arguments(argument.values)
64
- else
65
- argument
66
- end
61
+ def expand_nodes(nodes, &block)
62
+ return enum_for(:expand_nodes, nodes) unless block
63
+
64
+ nodes.each { |node| expand_node(node, &block) }
65
+ end
66
+
67
+ def expand_node(node, &block)
68
+ return enum_for(:expand_node, node) unless block
69
+
70
+ expand_hash_array_node(node, &block) || yield(node)
71
+ end
72
+
73
+ def expand_hash_array_node(node, &block)
74
+ expand_hash_node(node, &block) || expand_array_node(node, &block)
75
+ end
76
+
77
+ def expand_hash_node(node, &block)
78
+ return unless node.hash_type?
79
+ return enum_for(:expand_hash_node, node) unless block
80
+
81
+ node.pairs.each do |pair_node|
82
+ expand_hash_array_node(pair_node.key, &block) ||
83
+ expand_hash_array_node(pair_node.value, &block) ||
84
+ yield(pair_node)
85
+ end
86
+ end
87
+
88
+ def expand_array_node(node, &block)
89
+ return unless node.array_type?
90
+ return enum_for(:expand_array_node, node) unless block
91
+
92
+ if node.square_brackets?
93
+ expand_nodes(node.values, &block)
94
+ else
95
+ yield node
67
96
  end
68
97
  end
69
98
 
@@ -14,17 +14,129 @@ module RuboCop
14
14
  # MyWorker.perform_async(:foo)
15
15
  #
16
16
  # # good
17
- # MyWorker.perform_async('foo')
17
+ # MyWorker.perform_async("foo")
18
+ #
19
+ # # bad
20
+ # MyWorker.perform_async(%i(foo))
21
+ #
22
+ # # good
23
+ # MyWorker.perform_async(%w(foo))
24
+ #
25
+ # # bad
26
+ # MyWorker.perform_async([:foo])
27
+ #
28
+ # # good
29
+ # MyWorker.perform_async(["foo"]))
30
+ #
31
+ # # bad
32
+ # MyWorker.perform_async(foo: 1)
33
+ #
34
+ # # good
35
+ # MyWorker.perform_async('foo' => 1)
36
+ #
37
+ # # bad
38
+ # MyWorker.perform_async('foo' => :baz)
39
+ #
40
+ # # good
41
+ # MyWorker.perform_async('foo' => "baz")
42
+ #
43
+ # # bad
44
+ # MyWorker.perform_async('foo' => [:bar]
45
+ #
46
+ # # good
47
+ # MyWorker.perform_async('foo' => ["baz"])
48
+ #
49
+ # # bad
50
+ # MyWorker.perform_async('foo' => %i(baz)
51
+ #
52
+ # # good
53
+ # MyWorker.perform_async('foo' => %w(baz))
54
+ #
55
+ # # bad
56
+ # MyWorker.perform_async('foo' => { bar: %i(baz) })
57
+ #
58
+ # # good
59
+ # MyWorker.perform_async('foo' => { bar: %w(baz) })
60
+ #
61
+ # # bad
62
+ # MyWorker.perform_async('foo' => { bar: [:baz]) })
63
+ #
64
+ # # good
65
+ # MyWorker.perform_async('foo' => { bar: ["baz"] })
66
+ #
18
67
  class SymbolArgument < Base
68
+ extend AutoCorrector
69
+
19
70
  include Helpers
20
71
 
21
- MSG = 'Symbols are not Sidekiq-serializable; use strings instead.'
72
+ MSG = 'Symbols are not native JSON types; use strings instead.'
22
73
 
23
74
  def on_send(node)
24
- sidekiq_arguments(node).select(&:sym_type?).each do |argument|
25
- add_offense(argument)
75
+ sidekiq_arguments(node)
76
+ .lazy
77
+ .select { |n| node_contains_symbol?(n) }
78
+ .each do |selected_node|
79
+ offense_data(selected_node) do |offense_node, replace_node, replace_value|
80
+ add_offense(offense_node) do |corrector|
81
+ corrector.replace(replace_node, replace_value)
82
+ end
83
+ end
26
84
  end
27
85
  end
86
+
87
+ private
88
+
89
+ def node_contains_symbol?(node)
90
+ node.sym_type? || symbol_percent_literal?(node) || pair_with_symbol?(node)
91
+ end
92
+
93
+ def symbol_percent_literal?(node)
94
+ node.array_type? && node.percent_literal?(:symbol)
95
+ end
96
+
97
+ def pair_with_symbol?(node)
98
+ node.pair_type? && (node.key.sym_type? || node.value.sym_type?)
99
+ end
100
+
101
+ def offense_data(node)
102
+ yield sym_replace_value(node) || array_replace_value(node) || pair_replace_value(node)
103
+ end
104
+
105
+ def sym_replace_value(node)
106
+ return unless node.sym_type?
107
+
108
+ [node, node, %("#{node.value}")]
109
+ end
110
+
111
+ def array_replace_value(node)
112
+ return unless node.array_type?
113
+
114
+ [node, node, "%w(#{node.values.map(&:value).join(' ')})"]
115
+ end
116
+
117
+ def pair_replace_value(node)
118
+ return unless node.pair_type?
119
+
120
+ pair_both_symbol(node) || pair_only_key_symbol(node) || pair_only_value_symbol(node)
121
+ end
122
+
123
+ def pair_both_symbol(node)
124
+ return unless node.key.sym_type? && node.value.sym_type?
125
+
126
+ [node, node, %("#{node.key.value}" => "#{node.value.value}")]
127
+ end
128
+
129
+ def pair_only_key_symbol(node)
130
+ return unless node.key.sym_type?
131
+
132
+ [node.key, node, %("#{node.key.value}" => #{node.value.source})]
133
+ end
134
+
135
+ def pair_only_value_symbol(node)
136
+ return unless node.value.sym_type?
137
+
138
+ [node.value, node.value, %("#{node.value.value}")]
139
+ end
28
140
  end
29
141
  end
30
142
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RuboCop
4
4
  module Petal
5
- VERSION = '1.5.0'
5
+ VERSION = '1.7.0'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-petal
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jean-Francis Bastien
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-12-11 00:00:00.000000000 Z
11
+ date: 2025-01-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubocop
@@ -16,70 +16,84 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.59'
19
+ version: '1.70'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.59'
26
+ version: '1.70'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rubocop-factory_bot
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '2.24'
33
+ version: '2.26'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '2.24'
40
+ version: '2.26'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rubocop-performance
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '1.20'
47
+ version: '1.23'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '1.20'
54
+ version: '1.23'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rubocop-rails
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '2.23'
61
+ version: '2.28'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '2.23'
68
+ version: '2.28'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rubocop-rspec
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '2.25'
75
+ version: '3.3'
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '2.25'
82
+ version: '3.3'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop-rspec_rails
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '2.30'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '2.30'
83
97
  description:
84
98
  email:
85
99
  - jfbastien@petalmd.com