rubocop-petal 0.4.1 → 0.5.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: 27cd3572987b7a6238883f593b73622d58c578dd2c3c71b242b218dc2acabba9
4
- data.tar.gz: 28eaba65472713af02487e2b2d7c058cd6cd0442a023347d29d02d55684d1329
3
+ metadata.gz: aa2179fb3df37d962557546e94f204ee9a8789d2850cda31a53e7375b47edb50
4
+ data.tar.gz: dfeedd44694e75eab2c78f7205d93701a356378d147d6dca9e5adf68bf1e805f
5
5
  SHA512:
6
- metadata.gz: 9634d631a31346febfa80b63603c46865866502b9bfbbc7db6e6ef7136fba7e0fd1a44b226fde3cb680521d94a6d9d61cf427d57cb76712688b1f0f0c95a0864
7
- data.tar.gz: 80d383f97fe9f0b3a7bb2c8df6c1be422168fc3a5a025e4c8c0c810931871dd929216a0624a3d377b5d2c72534984675ba009e3aaaf1175eee93504a5aabd42b
6
+ metadata.gz: df124d64a0b69c1311c86e47393fd94379f89fac39d5f6752ec8af6f97df783764fcf581de9c5e11d79d5245bba37f8f07464d29d86f102c9b07056c610ffb8c
7
+ data.tar.gz: dec1a550aa7fbfdfeae58457bd668d671b21a0db0933685d253c18408b913bde81ccbf0e7fbb6ab1b5966741a6d4b3590956fc2641a11a0fda40d55c9980bc9a
data/CHANGELOG.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  # main
4
4
 
5
+ #v0.5.0
6
+
7
+ * Added cop `Rails/ValidateUniquenessCase` ([#20](https://github.com/petalmd/rubocop-petal/pull/20))
8
+
5
9
  #v0.4.1
6
10
 
7
11
  * Fix typo default config SafeAutoCorrect RSpec/StubProducts ([#19](https://github.com/petalmd/rubocop-petal/pull/19))
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rubocop-petal (0.4.1)
4
+ rubocop-petal (0.5.0)
5
5
  rubocop (>= 1.7.0, < 2.0)
6
6
  rubocop-rails (~> 2.10)
7
7
 
data/config/default.yml CHANGED
@@ -70,3 +70,11 @@ Rails/TableName:
70
70
  Chewy/ResetOnType:
71
71
  Description: 'Prevent using reset! methods on Chewy type class'
72
72
  Enabled: true
73
+
74
+ Rails/ValidateUniquenessCase:
75
+ Description: 'Enforce setting uniqueness case sensitive option.'
76
+ Enabled: true
77
+ SafeAutoCorrect: false
78
+ StyleGuide: 'https://guides.rubyonrails.org/6_1_release_notes.html#active-record-notable-changes'
79
+ Include:
80
+ - app/models/**/*
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Rails
6
+ # Enforces to specify a case sensitive or case insensitive option
7
+ # to the uniqueness validation.
8
+ #
9
+ # The default value in Rails 5 is `case_sensitive: true`. Which does not
10
+ # reflect MySQL's default behavior. In Rails 6.1 the default value will be
11
+ # `case_sensitive: false` to reflect MySQL's default behavior
12
+ # (https://guides.rubyonrails.org/6_1_release_notes.html#active-record-notable-changes).
13
+ #
14
+ # # bad
15
+ # validates :name, uniqueness: true
16
+ # validates :name, uniqueness: { scope: :user_id }
17
+ #
18
+ # # good
19
+ # validates :name, uniqueness: { case_sensitive: true }
20
+ # validates :name, uniqueness: { scope: :user_id, case_sensitive: false }
21
+ #
22
+ class ValidateUniquenessCase < Base
23
+ extend AutoCorrector
24
+
25
+ # Don't force to add the `case_sensitive` option when
26
+ # the default value is already `false` in Rails 6.
27
+ MAXIMUM_RAILS_VERSION = 6.1
28
+ MSG = 'Pass `case_sensitive: true|false` to uniqueness options.'
29
+ RESTRICT_ON_SEND = %i[validates].freeze
30
+
31
+ def_node_search :uniqueness?, <<~PATTERN
32
+ (sym :uniqueness)
33
+ PATTERN
34
+
35
+ def_node_matcher :have_case_sensitive_options?, <<~PATTERN
36
+ (pair (sym :case_sensitive) ${true false})
37
+ PATTERN
38
+
39
+ def on_send(node)
40
+ return unless support_target_rails_version?
41
+
42
+ uniqueness_options = match_uniqueness_options(node)
43
+ return unless uniqueness_options
44
+
45
+ uniqueness_child_options = uniqueness_options.children.last
46
+
47
+ # When it's just `uniqueness: true`
48
+ if uniqueness_child_options.boolean_type?
49
+ boolean_uniqueness(uniqueness_options)
50
+ return
51
+ end
52
+
53
+ case_sensitive_options = uniqueness_child_options.pairs.detect { |c| have_case_sensitive_options?(c) }
54
+ hash_uniqueness_offense(uniqueness_options, case_sensitive_options)
55
+ end
56
+
57
+ private
58
+
59
+ def match_uniqueness_options(node)
60
+ node.children.last.children.detect do |c|
61
+ # Skip if not a hash
62
+ next if c.is_a?(Symbol)
63
+
64
+ uniqueness?(c)
65
+ end
66
+ end
67
+
68
+ def boolean_uniqueness(node)
69
+ # When it's just `uniqueness: true`
70
+ add_offense(node) do |corrector|
71
+ corrector.replace(node, 'uniqueness: { case_sensitive: false }')
72
+ end
73
+ end
74
+
75
+ def hash_uniqueness_offense(node, sensitive_options)
76
+ return if sensitive_options
77
+
78
+ add_offense(node) do |corrector|
79
+ corrector.insert_after(node.loc.expression.adjust(end_pos: -2), ', case_sensitive: false')
80
+ end
81
+ end
82
+
83
+ def support_target_rails_version?
84
+ target_rails_version < MAXIMUM_RAILS_VERSION
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RuboCop
4
4
  module Petal
5
- VERSION = '0.4.1'
5
+ VERSION = '0.5.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: 0.4.1
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jean-Francis Bastien
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-04-12 00:00:00.000000000 Z
11
+ date: 2022-04-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubocop
@@ -75,6 +75,7 @@ files:
75
75
  - lib/rubocop/cop/rails/enum_prefix.rb
76
76
  - lib/rubocop/cop/rails/risky_activerecord_invocation.rb
77
77
  - lib/rubocop/cop/rails/table_name.rb
78
+ - lib/rubocop/cop/rails/validate_uniqueness_case.rb
78
79
  - lib/rubocop/cop/rspec/authenticated_as.rb
79
80
  - lib/rubocop/cop/rspec/create_list_max.rb
80
81
  - lib/rubocop/cop/rspec/stub_products.rb