gitlab-styles 7.1.0 → 8.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/gitlab/styles/rubocop/model_helpers.rb +1 -1
- data/lib/gitlab/styles/rubocop.rb +2 -2
- data/lib/gitlab/styles/version.rb +1 -1
- data/lib/rubocop/cop/active_record_dependent.rb +32 -0
- data/lib/rubocop/cop/active_record_serialize.rb +20 -0
- data/lib/rubocop/cop/avoid_return_from_blocks.rb +77 -0
- data/lib/rubocop/cop/code_reuse/active_record.rb +80 -0
- data/lib/rubocop/cop/custom_error_class.rb +69 -0
- data/lib/rubocop/cop/fips/md5.rb +27 -0
- data/lib/rubocop/cop/fips/open_ssl.rb +31 -0
- data/lib/rubocop/cop/fips/sha1.rb +27 -0
- data/lib/rubocop/cop/gem_fetcher.rb +37 -0
- data/lib/rubocop/cop/in_batches.rb +18 -0
- data/lib/rubocop/cop/internal_affairs/deprecate_cop_helper.rb +39 -0
- data/lib/rubocop/cop/line_break_after_guard_clauses.rb +100 -0
- data/lib/rubocop/cop/line_break_around_conditional_block.rb +128 -0
- data/lib/rubocop/cop/migration/update_large_table.rb +60 -0
- data/lib/rubocop/cop/performance/rubyzip.rb +35 -0
- data/lib/rubocop/cop/polymorphic_associations.rb +25 -0
- data/lib/rubocop/cop/rails/include_url_helper.rb +27 -0
- data/lib/rubocop/cop/redirect_with_status.rb +46 -0
- data/lib/rubocop/cop/rspec/base.rb +14 -0
- data/lib/rubocop/cop/rspec/empty_line_after_final_let_it_be.rb +47 -0
- data/lib/rubocop/cop/rspec/empty_line_after_let_block.rb +61 -0
- data/lib/rubocop/cop/rspec/empty_line_after_shared_example.rb +61 -0
- data/lib/rubocop/cop/rspec/example_starting_character.rb +120 -0
- data/lib/rubocop/cop/rspec/have_link_parameters.rb +44 -0
- data/lib/rubocop/cop/rspec/single_line_hook.rb +41 -0
- data/lib/rubocop/cop/rspec/verbose_include_metadata.rb +71 -0
- data/lib/rubocop/cop/style/hash_transformation.rb +83 -0
- data/lib/rubocop/cop/style/open_struct_use.rb +39 -0
- data/lib/rubocop/cop/without_reactive_cache.rb +16 -0
- metadata +31 -31
- data/lib/gitlab/styles/rubocop/cop/active_record_dependent.rb +0 -36
- data/lib/gitlab/styles/rubocop/cop/active_record_serialize.rb +0 -24
- data/lib/gitlab/styles/rubocop/cop/avoid_return_from_blocks.rb +0 -81
- data/lib/gitlab/styles/rubocop/cop/code_reuse/active_record.rb +0 -84
- data/lib/gitlab/styles/rubocop/cop/custom_error_class.rb +0 -73
- data/lib/gitlab/styles/rubocop/cop/fips/md5.rb +0 -31
- data/lib/gitlab/styles/rubocop/cop/fips/open_ssl.rb +0 -35
- data/lib/gitlab/styles/rubocop/cop/fips/sha1.rb +0 -31
- data/lib/gitlab/styles/rubocop/cop/gem_fetcher.rb +0 -41
- data/lib/gitlab/styles/rubocop/cop/in_batches.rb +0 -22
- data/lib/gitlab/styles/rubocop/cop/internal_affairs/deprecate_cop_helper.rb +0 -43
- data/lib/gitlab/styles/rubocop/cop/line_break_after_guard_clauses.rb +0 -104
- data/lib/gitlab/styles/rubocop/cop/line_break_around_conditional_block.rb +0 -132
- data/lib/gitlab/styles/rubocop/cop/migration/update_large_table.rb +0 -64
- data/lib/gitlab/styles/rubocop/cop/performance/rubyzip.rb +0 -39
- data/lib/gitlab/styles/rubocop/cop/polymorphic_associations.rb +0 -29
- data/lib/gitlab/styles/rubocop/cop/rails/include_url_helper.rb +0 -31
- data/lib/gitlab/styles/rubocop/cop/redirect_with_status.rb +0 -50
- data/lib/gitlab/styles/rubocop/cop/rspec/base.rb +0 -18
- data/lib/gitlab/styles/rubocop/cop/rspec/empty_line_after_final_let_it_be.rb +0 -51
- data/lib/gitlab/styles/rubocop/cop/rspec/empty_line_after_let_block.rb +0 -65
- data/lib/gitlab/styles/rubocop/cop/rspec/empty_line_after_shared_example.rb +0 -65
- data/lib/gitlab/styles/rubocop/cop/rspec/example_starting_character.rb +0 -124
- data/lib/gitlab/styles/rubocop/cop/rspec/have_link_parameters.rb +0 -48
- data/lib/gitlab/styles/rubocop/cop/rspec/single_line_hook.rb +0 -45
- data/lib/gitlab/styles/rubocop/cop/rspec/verbose_include_metadata.rb +0 -75
- data/lib/gitlab/styles/rubocop/cop/style/hash_transformation.rb +0 -87
- data/lib/gitlab/styles/rubocop/cop/style/open_struct_use.rb +0 -43
- data/lib/gitlab/styles/rubocop/cop/without_reactive_cache.rb +0 -20
@@ -1,51 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rubocop-rspec'
|
4
|
-
require_relative 'base'
|
5
|
-
|
6
|
-
module Gitlab
|
7
|
-
module Styles
|
8
|
-
module Rubocop
|
9
|
-
module Cop
|
10
|
-
module RSpec
|
11
|
-
# Checks if there is an empty line after the last `let_it_be` block.
|
12
|
-
#
|
13
|
-
# @example
|
14
|
-
# # bad
|
15
|
-
# let_it_be(:foo) { bar }
|
16
|
-
# let_it_be(:something) { other }
|
17
|
-
# it { does_something }
|
18
|
-
#
|
19
|
-
# # good
|
20
|
-
# let_it_be(:foo) { bar }
|
21
|
-
# let_it_be(:something) { other }
|
22
|
-
#
|
23
|
-
# it { does_something }
|
24
|
-
class EmptyLineAfterFinalLetItBe < Base
|
25
|
-
extend RuboCop::Cop::AutoCorrector
|
26
|
-
include RuboCop::RSpec::EmptyLineSeparation
|
27
|
-
|
28
|
-
MSG = 'Add an empty line after the last `let_it_be`.'
|
29
|
-
|
30
|
-
def_node_matcher :let_it_be?, <<-PATTERN
|
31
|
-
{
|
32
|
-
(block (send #rspec? {:let_it_be :let_it_be_with_refind :let_it_be_with_reload} ...) ...)
|
33
|
-
(send #rspec? {:let_it_be :let_it_be_with_refind :let_it_be_with_reload} _ block_pass)
|
34
|
-
}
|
35
|
-
PATTERN
|
36
|
-
|
37
|
-
def on_block(node)
|
38
|
-
return unless example_group_with_body?(node)
|
39
|
-
|
40
|
-
final_let_it_be = node.body.child_nodes.reverse.find { |child| let_it_be?(child) }
|
41
|
-
|
42
|
-
return if final_let_it_be.nil?
|
43
|
-
|
44
|
-
missing_separating_line_offense(final_let_it_be) { MSG }
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
@@ -1,65 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rubocop-rspec'
|
4
|
-
require_relative 'base'
|
5
|
-
|
6
|
-
module Gitlab
|
7
|
-
module Styles
|
8
|
-
module Rubocop
|
9
|
-
module Cop
|
10
|
-
module RSpec
|
11
|
-
# Checks if there is an empty line after let blocks.
|
12
|
-
#
|
13
|
-
# @example
|
14
|
-
# # bad
|
15
|
-
# RSpec.describe Foo do
|
16
|
-
# let(:something) { 'something' }
|
17
|
-
# let(:another_thing) do
|
18
|
-
# end
|
19
|
-
# let(:something_else) do
|
20
|
-
# end
|
21
|
-
# let(:last_thing) { 'last thing' }
|
22
|
-
# end
|
23
|
-
#
|
24
|
-
# # good
|
25
|
-
# RSpec.describe Foo do
|
26
|
-
# let(:something) { 'something' }
|
27
|
-
# let(:another_thing) do
|
28
|
-
# end
|
29
|
-
#
|
30
|
-
# let(:something_else) do
|
31
|
-
# end
|
32
|
-
#
|
33
|
-
# let(:last_thing) { 'last thing' }
|
34
|
-
# end
|
35
|
-
#
|
36
|
-
# # good - it's ok to have non-separated without do/end blocks
|
37
|
-
# RSpec.describe Foo do
|
38
|
-
# let(:something) { 'something' }
|
39
|
-
# let(:last_thing) { 'last thing' }
|
40
|
-
# end
|
41
|
-
#
|
42
|
-
class EmptyLineAfterLetBlock < Base
|
43
|
-
extend RuboCop::Cop::AutoCorrector
|
44
|
-
include RuboCop::RSpec::EmptyLineSeparation
|
45
|
-
|
46
|
-
MSG = 'Add an empty line after `%<let>s` block.'
|
47
|
-
|
48
|
-
def_node_matcher :lets, LET.block_pattern
|
49
|
-
|
50
|
-
def on_block(node)
|
51
|
-
lets(node) do
|
52
|
-
break if last_child?(node)
|
53
|
-
next if node.single_line?
|
54
|
-
|
55
|
-
missing_separating_line_offense(node) do |method|
|
56
|
-
format(MSG, let: method)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
@@ -1,65 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rubocop-rspec'
|
4
|
-
require_relative 'base'
|
5
|
-
|
6
|
-
module Gitlab
|
7
|
-
module Styles
|
8
|
-
module Rubocop
|
9
|
-
module Cop
|
10
|
-
module RSpec
|
11
|
-
# Checks if there is an empty line after shared example blocks.
|
12
|
-
#
|
13
|
-
# @example
|
14
|
-
# # bad
|
15
|
-
# RSpec.describe Foo do
|
16
|
-
# it_behaves_like 'do this first'
|
17
|
-
# it_behaves_like 'does this' do
|
18
|
-
# end
|
19
|
-
# it_behaves_like 'does that' do
|
20
|
-
# end
|
21
|
-
# it_behaves_like 'do some more'
|
22
|
-
# end
|
23
|
-
#
|
24
|
-
# # good
|
25
|
-
# RSpec.describe Foo do
|
26
|
-
# it_behaves_like 'do this first'
|
27
|
-
# it_behaves_like 'does this' do
|
28
|
-
# end
|
29
|
-
#
|
30
|
-
# it_behaves_like 'does that' do
|
31
|
-
# end
|
32
|
-
#
|
33
|
-
# it_behaves_like 'do some more'
|
34
|
-
# end
|
35
|
-
#
|
36
|
-
# # fair - it's ok to have non-separated without blocks
|
37
|
-
# RSpec.describe Foo do
|
38
|
-
# it_behaves_like 'do this first'
|
39
|
-
# it_behaves_like 'does this'
|
40
|
-
# end
|
41
|
-
#
|
42
|
-
class EmptyLineAfterSharedExample < Base
|
43
|
-
extend RuboCop::Cop::AutoCorrector
|
44
|
-
include RuboCop::RSpec::EmptyLineSeparation
|
45
|
-
|
46
|
-
MSG = 'Add an empty line after `%<example>s` block.'
|
47
|
-
|
48
|
-
def_node_matcher :shared_examples,
|
49
|
-
(SharedGroups::ALL + Includes::ALL).block_pattern
|
50
|
-
|
51
|
-
def on_block(node)
|
52
|
-
shared_examples(node) do
|
53
|
-
break if last_child?(node)
|
54
|
-
|
55
|
-
missing_separating_line_offense(node) do |method|
|
56
|
-
format(MSG, example: method)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
@@ -1,124 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rubocop-rspec'
|
4
|
-
require_relative 'base'
|
5
|
-
|
6
|
-
module Gitlab
|
7
|
-
module Styles
|
8
|
-
module Rubocop
|
9
|
-
module Cop
|
10
|
-
module RSpec
|
11
|
-
# Checks for common mistakes in example descriptions.
|
12
|
-
#
|
13
|
-
# This cop will correct docstrings that begin/end with space or words that start with a capital letter.
|
14
|
-
#
|
15
|
-
# @see https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46336#note_442669518
|
16
|
-
#
|
17
|
-
# @example
|
18
|
-
# # bad
|
19
|
-
# it 'Does something' do
|
20
|
-
# end
|
21
|
-
#
|
22
|
-
# # good
|
23
|
-
# it 'does nothing' do
|
24
|
-
# end
|
25
|
-
#
|
26
|
-
# @example
|
27
|
-
# # bad
|
28
|
-
# it ' does something' do
|
29
|
-
# end
|
30
|
-
#
|
31
|
-
# # good
|
32
|
-
# it 'does something' do
|
33
|
-
# end
|
34
|
-
#
|
35
|
-
# @example
|
36
|
-
# # bad
|
37
|
-
# it 'does something ' do
|
38
|
-
# end
|
39
|
-
#
|
40
|
-
# # good
|
41
|
-
# it 'does something' do
|
42
|
-
# end
|
43
|
-
#
|
44
|
-
# @example
|
45
|
-
# # bad
|
46
|
-
# it ' does something ' do
|
47
|
-
# end
|
48
|
-
#
|
49
|
-
# # good
|
50
|
-
# it 'does something' do
|
51
|
-
# end
|
52
|
-
class ExampleStartingCharacter < Base
|
53
|
-
extend RuboCop::Cop::AutoCorrector
|
54
|
-
|
55
|
-
MSG = 'Only start words with lowercase alpha with no leading/trailing spaces when describing your tests.'
|
56
|
-
|
57
|
-
def_node_matcher :it_description, <<-PATTERN
|
58
|
-
(block (send _ :it ${
|
59
|
-
(str $_)
|
60
|
-
(dstr (str $_ ) ...)
|
61
|
-
} ...) ...)
|
62
|
-
PATTERN
|
63
|
-
|
64
|
-
def on_block(node)
|
65
|
-
it_description(node) do |description_node, _message|
|
66
|
-
add_wording_offense(description_node, MSG) if invalid_description?(text(description_node))
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
private
|
71
|
-
|
72
|
-
def add_wording_offense(node, message)
|
73
|
-
docstring = docstring(node)
|
74
|
-
add_offense(docstring, message: message) do |corrector|
|
75
|
-
corrector.replace(docstring, replacement_text(node))
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
def docstring(node)
|
80
|
-
expr = node.loc.expression
|
81
|
-
|
82
|
-
Parser::Source::Range.new(
|
83
|
-
expr.source_buffer,
|
84
|
-
expr.begin_pos + 1,
|
85
|
-
expr.end_pos - 1
|
86
|
-
)
|
87
|
-
end
|
88
|
-
|
89
|
-
def invalid_description?(message)
|
90
|
-
message.match?(/(^([A-Z]{1}[a-z]+\s|\s)|\s$)/)
|
91
|
-
end
|
92
|
-
|
93
|
-
def replacement_text(node)
|
94
|
-
text = text(node)
|
95
|
-
|
96
|
-
text.strip!
|
97
|
-
|
98
|
-
text = downcase_first_letter(text) if invalid_description?(text)
|
99
|
-
|
100
|
-
text
|
101
|
-
end
|
102
|
-
|
103
|
-
# Recursive processing is required to process nested dstr nodes
|
104
|
-
# that is the case for \-separated multiline strings with interpolation.
|
105
|
-
def text(node)
|
106
|
-
case node.type
|
107
|
-
when :dstr
|
108
|
-
node.node_parts.map { |child_node| text(child_node) }.join
|
109
|
-
when :str
|
110
|
-
node.value
|
111
|
-
when :begin
|
112
|
-
node.source
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
def downcase_first_letter(str)
|
117
|
-
str[0].downcase + str[1..]
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
@@ -1,48 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rubocop-rspec'
|
4
|
-
require_relative 'base'
|
5
|
-
|
6
|
-
module Gitlab
|
7
|
-
module Styles
|
8
|
-
module Rubocop
|
9
|
-
module Cop
|
10
|
-
module RSpec
|
11
|
-
# This cop checks for unused parameters to the `have_link` matcher.
|
12
|
-
#
|
13
|
-
# @example
|
14
|
-
#
|
15
|
-
# # bad
|
16
|
-
# expect(page).to have_link('Link', 'https://example.com')
|
17
|
-
#
|
18
|
-
# # good
|
19
|
-
# expect(page).to have_link('Link', href: 'https://example.com')
|
20
|
-
# expect(page).to have_link('Example')
|
21
|
-
class HaveLinkParameters < Base
|
22
|
-
extend RuboCop::Cop::AutoCorrector
|
23
|
-
|
24
|
-
MESSAGE = "The second argument to `have_link` should be a Hash."
|
25
|
-
|
26
|
-
def_node_matcher :unused_parameters?, <<~PATTERN
|
27
|
-
(send nil? :have_link
|
28
|
-
_ !{hash nil}
|
29
|
-
)
|
30
|
-
PATTERN
|
31
|
-
|
32
|
-
def on_send(node)
|
33
|
-
return unless unused_parameters?(node)
|
34
|
-
|
35
|
-
location = node.arguments[1..]
|
36
|
-
.map(&:source_range)
|
37
|
-
.reduce(:join)
|
38
|
-
|
39
|
-
add_offense(location, message: MESSAGE) do |corrector|
|
40
|
-
corrector.insert_after(location.end, "\n")
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rubocop-rspec'
|
4
|
-
require_relative 'base'
|
5
|
-
|
6
|
-
module Gitlab
|
7
|
-
module Styles
|
8
|
-
module Rubocop
|
9
|
-
module Cop
|
10
|
-
module RSpec
|
11
|
-
# This cop checks for single-line hook blocks
|
12
|
-
#
|
13
|
-
# @example
|
14
|
-
#
|
15
|
-
# # bad
|
16
|
-
# before { do_something }
|
17
|
-
# after(:each) { undo_something }
|
18
|
-
#
|
19
|
-
# # good
|
20
|
-
# before do
|
21
|
-
# do_something
|
22
|
-
# end
|
23
|
-
#
|
24
|
-
# after(:each) do
|
25
|
-
# undo_something
|
26
|
-
# end
|
27
|
-
class SingleLineHook < Base
|
28
|
-
MESSAGE = "Don't use single-line hook blocks."
|
29
|
-
|
30
|
-
def_node_search :rspec_hook?, <<~PATTERN
|
31
|
-
(send nil? {:after :around :before} ...)
|
32
|
-
PATTERN
|
33
|
-
|
34
|
-
def on_block(node)
|
35
|
-
return unless node.single_line?
|
36
|
-
return unless rspec_hook?(node)
|
37
|
-
|
38
|
-
add_offense(node, message: MESSAGE)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
@@ -1,75 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rubocop-rspec'
|
4
|
-
require_relative 'base'
|
5
|
-
|
6
|
-
module Gitlab
|
7
|
-
module Styles
|
8
|
-
module Rubocop
|
9
|
-
module Cop
|
10
|
-
module RSpec
|
11
|
-
# Checks for verbose include metadata used in the specs.
|
12
|
-
#
|
13
|
-
# @example
|
14
|
-
# # bad
|
15
|
-
# describe MyClass, js: true do
|
16
|
-
# end
|
17
|
-
#
|
18
|
-
# # good
|
19
|
-
# describe MyClass, :js do
|
20
|
-
# end
|
21
|
-
class VerboseIncludeMetadata < Base
|
22
|
-
extend RuboCop::Cop::AutoCorrector
|
23
|
-
|
24
|
-
MSG = 'Use `%s` instead of `%s`.'
|
25
|
-
|
26
|
-
SELECTORS = %i[describe context feature example_group it specify example scenario its].freeze
|
27
|
-
|
28
|
-
def_node_matcher :include_metadata, <<-PATTERN
|
29
|
-
(send {(const nil? :RSpec) nil?} {#{SELECTORS.map(&:inspect).join(' ')}}
|
30
|
-
!const
|
31
|
-
...
|
32
|
-
(hash $...))
|
33
|
-
PATTERN
|
34
|
-
|
35
|
-
def_node_matcher :invalid_metadata?, <<-PATTERN
|
36
|
-
(pair
|
37
|
-
(sym $...)
|
38
|
-
(true))
|
39
|
-
PATTERN
|
40
|
-
|
41
|
-
def on_send(node)
|
42
|
-
invalid_metadata_matches(node) do |match|
|
43
|
-
add_offense(node, message: format(MSG, good(match), bad(match))) do |corrector|
|
44
|
-
invalid_metadata_matches(node) do |match|
|
45
|
-
corrector.replace(match.loc.expression, good(match))
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
private
|
52
|
-
|
53
|
-
def invalid_metadata_matches(node, &block)
|
54
|
-
include_metadata(node) do |matches|
|
55
|
-
matches.select { |match| invalid_metadata?(match) }.each(&block)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def bad(match)
|
60
|
-
"#{metadata_key(match)}: true"
|
61
|
-
end
|
62
|
-
|
63
|
-
def good(match)
|
64
|
-
":#{metadata_key(match)}"
|
65
|
-
end
|
66
|
-
|
67
|
-
def metadata_key(match)
|
68
|
-
match.children[0].source
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
@@ -1,87 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Gitlab
|
4
|
-
module Styles
|
5
|
-
module Rubocop
|
6
|
-
module Cop
|
7
|
-
module Style
|
8
|
-
# This cop identifies places where `map { ... }.to_h` or
|
9
|
-
# `Hash[map { ... }]` can be replaced with `to_h { ... }`,
|
10
|
-
# saving an intermediate array allocation.
|
11
|
-
#
|
12
|
-
# @example
|
13
|
-
# # bad
|
14
|
-
# hash.map { |k, v| [v.upcase, k.downcase] }.to_h
|
15
|
-
# hash.collect { |k, v| [v.upcase, k.downcase] }.to_h
|
16
|
-
# Hash[hash.map { |k, v| [v.upcase, k.downcase] }]
|
17
|
-
# Hash[hash.collect { |k, v| [v.upcase, k.downcase] }]
|
18
|
-
# array.map { |x| [x, x + 1] }.to_h
|
19
|
-
#
|
20
|
-
# # good
|
21
|
-
# hash.to_h { |k, v| [v.upcase, k.downcase] }
|
22
|
-
# array.to_h { |x| [x, x + 1] }
|
23
|
-
#
|
24
|
-
# Full credit: https://github.com/eugeneius/rubocop-performance/blob/hash_transformation/lib/rubocop/cop/performance/hash_transformation.rb
|
25
|
-
class HashTransformation < RuboCop::Cop::Cop
|
26
|
-
include RuboCop::Cop::RangeHelp
|
27
|
-
|
28
|
-
MSG = 'Use `to_h { ... }` instead of `%<current>s`.'
|
29
|
-
|
30
|
-
def_node_matcher :to_h_candidate?, <<~PATTERN
|
31
|
-
{
|
32
|
-
[(send
|
33
|
-
$(block $(send _ {:map :collect}) ...) :to_h) !block_literal?]
|
34
|
-
(send (const nil? :Hash) :[]
|
35
|
-
$(block $(send _ {:map :collect}) ...))
|
36
|
-
}
|
37
|
-
PATTERN
|
38
|
-
|
39
|
-
def on_send(node)
|
40
|
-
to_h_candidate?(node) do |_block, call|
|
41
|
-
range = offense_range(node, call)
|
42
|
-
message = message(node, call)
|
43
|
-
add_offense(node, location: range, message: message)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def autocorrect(node)
|
48
|
-
block, call = to_h_candidate?(node)
|
49
|
-
|
50
|
-
lambda do |corrector|
|
51
|
-
corrector.remove(after_block(node, block))
|
52
|
-
corrector.replace(call.loc.selector, 'to_h')
|
53
|
-
corrector.remove(before_block(node, block))
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
private
|
58
|
-
|
59
|
-
def offense_range(node, call)
|
60
|
-
return node.source_range if node.children.first.const_type?
|
61
|
-
|
62
|
-
range_between(call.loc.selector.begin_pos, node.loc.selector.end_pos)
|
63
|
-
end
|
64
|
-
|
65
|
-
def message(node, call)
|
66
|
-
current = if node.children.first.const_type?
|
67
|
-
"Hash[#{call.method_name} { ... }]"
|
68
|
-
else
|
69
|
-
"#{call.method_name} { ... }.to_h"
|
70
|
-
end
|
71
|
-
|
72
|
-
format(MSG, current: current)
|
73
|
-
end
|
74
|
-
|
75
|
-
def after_block(node, block)
|
76
|
-
block.source_range.end.join(node.source_range.end)
|
77
|
-
end
|
78
|
-
|
79
|
-
def before_block(node, block)
|
80
|
-
node.source_range.begin.join(block.source_range.begin)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
@@ -1,43 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Gitlab
|
4
|
-
module Styles
|
5
|
-
module Rubocop
|
6
|
-
module Cop
|
7
|
-
module Style
|
8
|
-
# This cop flags uses of OpenStruct, as it is now officially discouraged
|
9
|
-
# to be used for performance, version compatibility, and potential security issues.
|
10
|
-
#
|
11
|
-
# See also:
|
12
|
-
# - https://rubyreferences.github.io/rubychanges/3.0.html#standard-library
|
13
|
-
# - https://docs.ruby-lang.org/en/3.0.0/OpenStruct.html#class-OpenStruct-label-Caveats
|
14
|
-
# - https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67855
|
15
|
-
class OpenStructUse < RuboCop::Cop::Cop
|
16
|
-
MSG = 'Avoid using `OpenStruct`. It is officially discouraged. ' \
|
17
|
-
'Replace it with `Struct`, `Hash`, or RSpec doubles. ' \
|
18
|
-
'See https://docs.ruby-lang.org/en/3.0.0/OpenStruct.html#class-OpenStruct-label-Caveats'
|
19
|
-
|
20
|
-
def_node_matcher :uses_open_struct?, <<-PATTERN
|
21
|
-
(const {nil? (cbase)} :OpenStruct)
|
22
|
-
PATTERN
|
23
|
-
|
24
|
-
def on_const(node)
|
25
|
-
return unless uses_open_struct?(node)
|
26
|
-
return if custom_class_or_module_definition?(node)
|
27
|
-
|
28
|
-
add_offense(node)
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
33
|
-
def custom_class_or_module_definition?(node)
|
34
|
-
parent = node.parent
|
35
|
-
|
36
|
-
(parent.class_type? || parent.module_type?) && node.left_siblings.empty?
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Gitlab
|
4
|
-
module Styles
|
5
|
-
module Rubocop
|
6
|
-
module Cop
|
7
|
-
# Cop that prevents the use of `without_reactive_cache`
|
8
|
-
class WithoutReactiveCache < RuboCop::Cop::Cop
|
9
|
-
MSG = 'without_reactive_cache is for debugging purposes only. Please use with_reactive_cache.'
|
10
|
-
|
11
|
-
def on_send(node)
|
12
|
-
return unless node.children[1] == :without_reactive_cache
|
13
|
-
|
14
|
-
add_offense(node, location: :selector)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|