gitlab-styles 6.6.0 → 8.0.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/.gitlab/changelog_config.yml +13 -0
- data/.gitlab/merge_request_templates/Release.md +9 -31
- data/.gitlab-ci.yml +3 -1
- data/Dangerfile +5 -0
- data/gitlab-styles.gemspec +1 -0
- data/lib/gitlab/styles/common/banned_constants.rb +28 -0
- 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
- data/rubocop-default.yml +1 -0
- data/rubocop-fips.yml +15 -0
- data/rubocop-rspec.yml +3 -2
- metadata +49 -27
- data/lib/gitlab/styles/rubocop/cop/active_record_dependent.rb +0 -32
- data/lib/gitlab/styles/rubocop/cop/active_record_serialize.rb +0 -24
- data/lib/gitlab/styles/rubocop/cop/code_reuse/active_record.rb +0 -130
- data/lib/gitlab/styles/rubocop/cop/custom_error_class.rb +0 -73
- 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,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative '../../model_helpers'
|
4
|
-
|
5
|
-
module Gitlab
|
6
|
-
module Styles
|
7
|
-
module Rubocop
|
8
|
-
module Cop
|
9
|
-
module Rails
|
10
|
-
class IncludeUrlHelper < RuboCop::Cop::Cop
|
11
|
-
MSG = <<~MSG
|
12
|
-
Avoid including `ActionView::Helpers::UrlHelper`.
|
13
|
-
It adds/overrides ~40 methods while usually only one is needed.
|
14
|
-
Instead, use the `Gitlab::Routing.url_helpers`/`Application.routes.url_helpers`(outside of gitlab)
|
15
|
-
and `ActionController::Base.helpers.link_to`.
|
16
|
-
See https://gitlab.com/gitlab-org/gitlab/-/issues/340567.
|
17
|
-
MSG
|
18
|
-
|
19
|
-
def_node_matcher :include_url_helpers_node?, <<~PATTERN
|
20
|
-
(send nil? :include (const (const (const {nil? cbase} :ActionView) :Helpers) :UrlHelper))
|
21
|
-
PATTERN
|
22
|
-
|
23
|
-
def on_send(node)
|
24
|
-
add_offense(node) if include_url_helpers_node?(node)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,50 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Gitlab
|
4
|
-
module Styles
|
5
|
-
module Rubocop
|
6
|
-
module Cop
|
7
|
-
# This cop prevents usage of 'redirect_to' in actions 'destroy' without specifying 'status'.
|
8
|
-
# See https://gitlab.com/gitlab-org/gitlab-ce/issues/31840
|
9
|
-
class RedirectWithStatus < RuboCop::Cop::Cop
|
10
|
-
MSG = 'Do not use "redirect_to" without "status" in "destroy" action'
|
11
|
-
|
12
|
-
def on_def(node)
|
13
|
-
return unless in_controller?(node)
|
14
|
-
return unless destroy?(node) || destroy_all?(node)
|
15
|
-
|
16
|
-
node.each_descendant(:send) do |def_node|
|
17
|
-
next unless redirect_to?(def_node)
|
18
|
-
|
19
|
-
methods = []
|
20
|
-
|
21
|
-
def_node.children.last.each_node(:pair) do |pair|
|
22
|
-
methods << pair.children.first.children.first
|
23
|
-
end
|
24
|
-
|
25
|
-
add_offense(def_node, location: :selector) unless methods.include?(:status)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
|
31
|
-
def in_controller?(node)
|
32
|
-
node.location.expression.source_buffer.name.end_with?('_controller.rb')
|
33
|
-
end
|
34
|
-
|
35
|
-
def destroy?(node)
|
36
|
-
node.children.first == :destroy
|
37
|
-
end
|
38
|
-
|
39
|
-
def destroy_all?(node)
|
40
|
-
node.children.first == :destroy_all
|
41
|
-
end
|
42
|
-
|
43
|
-
def redirect_to?(node)
|
44
|
-
node.children[1] == :redirect_to
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rubocop-rspec'
|
4
|
-
require_relative '../../rspec/helpers'
|
5
|
-
|
6
|
-
module Gitlab
|
7
|
-
module Styles
|
8
|
-
module Rubocop
|
9
|
-
module Cop
|
10
|
-
module RSpec
|
11
|
-
class Base < RuboCop::Cop::RSpec::Base
|
12
|
-
include Rubocop::Rspec::Helpers
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
@@ -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
|