rubocop-petal 1.5.0 → 1.7.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: 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