gitlab-styles 7.0.0 → 9.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +11 -0
  3. data/Gemfile +3 -3
  4. data/gitlab-styles.gemspec +6 -6
  5. data/lib/gitlab/styles/common/banned_constants.rb +28 -0
  6. data/lib/gitlab/styles/rubocop/model_helpers.rb +1 -1
  7. data/lib/gitlab/styles/rubocop.rb +2 -2
  8. data/lib/gitlab/styles/version.rb +1 -1
  9. data/lib/rubocop/cop/active_record_dependent.rb +32 -0
  10. data/lib/rubocop/cop/active_record_serialize.rb +20 -0
  11. data/lib/rubocop/cop/avoid_return_from_blocks.rb +79 -0
  12. data/lib/rubocop/cop/code_reuse/active_record.rb +80 -0
  13. data/lib/rubocop/cop/custom_error_class.rb +67 -0
  14. data/lib/rubocop/cop/fips/md5.rb +27 -0
  15. data/lib/rubocop/cop/fips/open_ssl.rb +31 -0
  16. data/lib/rubocop/cop/fips/sha1.rb +27 -0
  17. data/lib/rubocop/cop/gem_fetcher.rb +37 -0
  18. data/lib/rubocop/cop/in_batches.rb +18 -0
  19. data/lib/rubocop/cop/internal_affairs/deprecate_cop_helper.rb +42 -0
  20. data/lib/rubocop/cop/line_break_after_guard_clauses.rb +101 -0
  21. data/lib/rubocop/cop/line_break_around_conditional_block.rb +127 -0
  22. data/lib/rubocop/cop/migration/update_large_table.rb +61 -0
  23. data/lib/rubocop/cop/performance/rubyzip.rb +36 -0
  24. data/lib/rubocop/cop/polymorphic_associations.rb +25 -0
  25. data/lib/rubocop/cop/rails/include_url_helper.rb +28 -0
  26. data/lib/rubocop/cop/redirect_with_status.rb +46 -0
  27. data/lib/rubocop/cop/rspec/base.rb +12 -0
  28. data/lib/rubocop/cop/rspec/empty_line_after_let_block.rb +61 -0
  29. data/lib/rubocop/cop/rspec/empty_line_after_shared_example.rb +63 -0
  30. data/lib/rubocop/cop/rspec/example_starting_character.rb +122 -0
  31. data/lib/rubocop/cop/rspec/have_link_parameters.rb +45 -0
  32. data/lib/rubocop/cop/rspec/single_line_hook.rb +43 -0
  33. data/lib/rubocop/cop/rspec/verbose_include_metadata.rb +73 -0
  34. data/lib/rubocop/cop/style/hash_transformation.rb +81 -0
  35. data/lib/rubocop/cop/style/open_struct_use.rb +40 -0
  36. data/lib/rubocop/cop/without_reactive_cache.rb +16 -0
  37. data/rubocop-default.yml +1 -0
  38. data/rubocop-fips.yml +15 -0
  39. data/rubocop-layout.yml +1 -1
  40. data/rubocop-rspec.yml +13 -5
  41. metadata +44 -47
  42. data/lib/gitlab/styles/rubocop/cop/active_record_dependent.rb +0 -36
  43. data/lib/gitlab/styles/rubocop/cop/active_record_serialize.rb +0 -24
  44. data/lib/gitlab/styles/rubocop/cop/avoid_return_from_blocks.rb +0 -81
  45. data/lib/gitlab/styles/rubocop/cop/code_reuse/active_record.rb +0 -84
  46. data/lib/gitlab/styles/rubocop/cop/custom_error_class.rb +0 -73
  47. data/lib/gitlab/styles/rubocop/cop/gem_fetcher.rb +0 -41
  48. data/lib/gitlab/styles/rubocop/cop/in_batches.rb +0 -22
  49. data/lib/gitlab/styles/rubocop/cop/internal_affairs/deprecate_cop_helper.rb +0 -43
  50. data/lib/gitlab/styles/rubocop/cop/line_break_after_guard_clauses.rb +0 -104
  51. data/lib/gitlab/styles/rubocop/cop/line_break_around_conditional_block.rb +0 -132
  52. data/lib/gitlab/styles/rubocop/cop/migration/update_large_table.rb +0 -64
  53. data/lib/gitlab/styles/rubocop/cop/performance/rubyzip.rb +0 -39
  54. data/lib/gitlab/styles/rubocop/cop/polymorphic_associations.rb +0 -29
  55. data/lib/gitlab/styles/rubocop/cop/rails/include_url_helper.rb +0 -31
  56. data/lib/gitlab/styles/rubocop/cop/redirect_with_status.rb +0 -50
  57. data/lib/gitlab/styles/rubocop/cop/rspec/base.rb +0 -18
  58. data/lib/gitlab/styles/rubocop/cop/rspec/empty_line_after_final_let_it_be.rb +0 -51
  59. data/lib/gitlab/styles/rubocop/cop/rspec/empty_line_after_let_block.rb +0 -65
  60. data/lib/gitlab/styles/rubocop/cop/rspec/empty_line_after_shared_example.rb +0 -65
  61. data/lib/gitlab/styles/rubocop/cop/rspec/example_starting_character.rb +0 -124
  62. data/lib/gitlab/styles/rubocop/cop/rspec/have_link_parameters.rb +0 -48
  63. data/lib/gitlab/styles/rubocop/cop/rspec/single_line_hook.rb +0 -45
  64. data/lib/gitlab/styles/rubocop/cop/rspec/verbose_include_metadata.rb +0 -75
  65. data/lib/gitlab/styles/rubocop/cop/style/hash_transformation.rb +0 -87
  66. data/lib/gitlab/styles/rubocop/cop/style/open_struct_use.rb +0 -43
  67. data/lib/gitlab/styles/rubocop/cop/without_reactive_cache.rb +0 -20
  68. data/lib/gitlab/styles/rubocop/rspec/helpers.rb +0 -18
@@ -1,29 +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
- # Cop that prevents the use of polymorphic associations
10
- class PolymorphicAssociations < RuboCop::Cop::Cop
11
- include ModelHelpers
12
-
13
- MSG = 'Do not use polymorphic associations, use separate tables instead'
14
-
15
- def on_send(node)
16
- return unless in_model?(node)
17
- return unless node.children[1] == :belongs_to
18
-
19
- node.children.last.each_node(:pair) do |pair|
20
- key_name = pair.children[0].children[0]
21
-
22
- add_offense(pair) if key_name == :polymorphic
23
- end
24
- end
25
- end
26
- end
27
- end
28
- end
29
- end
@@ -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