rubocop-rspec 1.42.0 → 1.43.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +17 -0
  3. data/config/default.yml +12 -2
  4. data/lib/rubocop-rspec.rb +2 -1
  5. data/lib/rubocop/cop/rspec/align_left_let_brace.rb +1 -1
  6. data/lib/rubocop/cop/rspec/align_right_let_brace.rb +1 -1
  7. data/lib/rubocop/cop/rspec/any_instance.rb +1 -1
  8. data/lib/rubocop/cop/rspec/around_block.rb +1 -1
  9. data/lib/rubocop/cop/rspec/base.rb +74 -0
  10. data/lib/rubocop/cop/rspec/be.rb +1 -1
  11. data/lib/rubocop/cop/rspec/be_eql.rb +1 -1
  12. data/lib/rubocop/cop/rspec/before_after_all.rb +1 -1
  13. data/lib/rubocop/cop/rspec/capybara/current_path_expectation.rb +1 -1
  14. data/lib/rubocop/cop/rspec/capybara/feature_methods.rb +6 -3
  15. data/lib/rubocop/cop/rspec/capybara/visibility_matcher.rb +1 -1
  16. data/lib/rubocop/cop/rspec/context_method.rb +2 -2
  17. data/lib/rubocop/cop/rspec/context_wording.rb +3 -3
  18. data/lib/rubocop/cop/rspec/cop.rb +2 -66
  19. data/lib/rubocop/cop/rspec/describe_class.rb +21 -30
  20. data/lib/rubocop/cop/rspec/describe_method.rb +14 -6
  21. data/lib/rubocop/cop/rspec/describe_symbol.rb +2 -2
  22. data/lib/rubocop/cop/rspec/described_class.rb +2 -2
  23. data/lib/rubocop/cop/rspec/described_class_module_wrapping.rb +1 -1
  24. data/lib/rubocop/cop/rspec/dialect.rb +1 -1
  25. data/lib/rubocop/cop/rspec/empty_example_group.rb +91 -7
  26. data/lib/rubocop/cop/rspec/empty_hook.rb +1 -1
  27. data/lib/rubocop/cop/rspec/empty_line_after_example.rb +4 -8
  28. data/lib/rubocop/cop/rspec/empty_line_after_example_group.rb +4 -8
  29. data/lib/rubocop/cop/rspec/empty_line_after_final_let.rb +7 -10
  30. data/lib/rubocop/cop/rspec/empty_line_after_hook.rb +4 -8
  31. data/lib/rubocop/cop/rspec/empty_line_after_subject.rb +5 -8
  32. data/lib/rubocop/cop/rspec/example_length.rb +1 -1
  33. data/lib/rubocop/cop/rspec/example_without_description.rb +1 -1
  34. data/lib/rubocop/cop/rspec/example_wording.rb +4 -4
  35. data/lib/rubocop/cop/rspec/expect_actual.rb +1 -1
  36. data/lib/rubocop/cop/rspec/expect_change.rb +1 -1
  37. data/lib/rubocop/cop/rspec/expect_in_hook.rb +1 -1
  38. data/lib/rubocop/cop/rspec/expect_output.rb +1 -1
  39. data/lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb +3 -3
  40. data/lib/rubocop/cop/rspec/factory_bot/create_list.rb +10 -6
  41. data/lib/rubocop/cop/rspec/factory_bot/factory_class_name.rb +1 -1
  42. data/lib/rubocop/cop/rspec/file_path.rb +25 -17
  43. data/lib/rubocop/cop/rspec/focus.rb +7 -11
  44. data/lib/rubocop/cop/rspec/hook_argument.rb +5 -6
  45. data/lib/rubocop/cop/rspec/hooks_before_examples.rb +1 -1
  46. data/lib/rubocop/cop/rspec/implicit_block_expectation.rb +1 -1
  47. data/lib/rubocop/cop/rspec/implicit_expect.rb +1 -1
  48. data/lib/rubocop/cop/rspec/implicit_subject.rb +8 -6
  49. data/lib/rubocop/cop/rspec/instance_spy.rb +1 -1
  50. data/lib/rubocop/cop/rspec/instance_variable.rb +1 -1
  51. data/lib/rubocop/cop/rspec/invalid_predicate_matcher.rb +1 -1
  52. data/lib/rubocop/cop/rspec/it_behaves_like.rb +1 -1
  53. data/lib/rubocop/cop/rspec/iterated_expectation.rb +1 -1
  54. data/lib/rubocop/cop/rspec/leading_subject.rb +20 -17
  55. data/lib/rubocop/cop/rspec/leaky_constant_declaration.rb +1 -1
  56. data/lib/rubocop/cop/rspec/let_before_examples.rb +1 -1
  57. data/lib/rubocop/cop/rspec/let_setup.rb +6 -3
  58. data/lib/rubocop/cop/rspec/message_chain.rb +1 -1
  59. data/lib/rubocop/cop/rspec/message_expectation.rb +1 -1
  60. data/lib/rubocop/cop/rspec/message_spies.rb +1 -1
  61. data/lib/rubocop/cop/rspec/missing_example_group_argument.rb +1 -1
  62. data/lib/rubocop/cop/rspec/multiple_describes.rb +11 -8
  63. data/lib/rubocop/cop/rspec/multiple_expectations.rb +7 -11
  64. data/lib/rubocop/cop/rspec/multiple_memoized_helpers.rb +148 -0
  65. data/lib/rubocop/cop/rspec/multiple_subjects.rb +1 -1
  66. data/lib/rubocop/cop/rspec/named_subject.rb +1 -1
  67. data/lib/rubocop/cop/rspec/nested_groups.rb +4 -4
  68. data/lib/rubocop/cop/rspec/not_to_not.rb +1 -1
  69. data/lib/rubocop/cop/rspec/overwriting_setup.rb +1 -1
  70. data/lib/rubocop/cop/rspec/pending.rb +1 -1
  71. data/lib/rubocop/cop/rspec/predicate_matcher.rb +7 -14
  72. data/lib/rubocop/cop/rspec/rails/http_status.rb +1 -1
  73. data/lib/rubocop/cop/rspec/receive_counts.rb +1 -1
  74. data/lib/rubocop/cop/rspec/receive_never.rb +2 -2
  75. data/lib/rubocop/cop/rspec/repeated_description.rb +1 -1
  76. data/lib/rubocop/cop/rspec/repeated_example.rb +2 -2
  77. data/lib/rubocop/cop/rspec/repeated_example_group_body.rb +1 -1
  78. data/lib/rubocop/cop/rspec/repeated_example_group_description.rb +1 -1
  79. data/lib/rubocop/cop/rspec/return_from_stub.rb +1 -1
  80. data/lib/rubocop/cop/rspec/scattered_let.rb +1 -1
  81. data/lib/rubocop/cop/rspec/scattered_setup.rb +1 -1
  82. data/lib/rubocop/cop/rspec/shared_context.rb +1 -1
  83. data/lib/rubocop/cop/rspec/shared_examples.rb +1 -1
  84. data/lib/rubocop/cop/rspec/single_argument_message_chain.rb +1 -1
  85. data/lib/rubocop/cop/rspec/subject_stub.rb +2 -2
  86. data/lib/rubocop/cop/rspec/unspecified_exception.rb +1 -1
  87. data/lib/rubocop/cop/rspec/variable_definition.rb +6 -6
  88. data/lib/rubocop/cop/rspec/variable_name.rb +28 -9
  89. data/lib/rubocop/cop/rspec/verified_doubles.rb +1 -1
  90. data/lib/rubocop/cop/rspec/void_expect.rb +1 -1
  91. data/lib/rubocop/cop/rspec/yield.rb +1 -1
  92. data/lib/rubocop/cop/rspec_cops.rb +1 -0
  93. data/lib/rubocop/rspec/corrector/move_node.rb +7 -5
  94. data/lib/rubocop/rspec/description_extractor.rb +1 -1
  95. data/lib/rubocop/rspec/{blank_line_separation.rb → empty_line_separation.rb} +13 -2
  96. data/lib/rubocop/rspec/example_group.rb +2 -2
  97. data/lib/rubocop/rspec/language.rb +6 -4
  98. data/lib/rubocop/rspec/language/node_pattern.rb +6 -1
  99. data/lib/rubocop/rspec/top_level_describe.rb +2 -2
  100. data/lib/rubocop/rspec/top_level_group.rb +24 -13
  101. data/lib/rubocop/rspec/variable.rb +1 -1
  102. data/lib/rubocop/rspec/version.rb +1 -1
  103. metadata +23 -7
@@ -16,17 +16,25 @@ module RuboCop
16
16
  #
17
17
  # describe MyClass, '.my_class_method' do
18
18
  # end
19
- class DescribeMethod < Cop
20
- include RuboCop::RSpec::TopLevelDescribe
19
+ class DescribeMethod < Base
20
+ include RuboCop::RSpec::TopLevelGroup
21
21
 
22
22
  MSG = 'The second argument to describe should be the method '\
23
23
  "being tested. '#instance' or '.class'."
24
24
 
25
- def on_top_level_describe(_node, (_, second_arg))
26
- return unless second_arg&.str_type?
27
- return if second_arg.str_content.start_with?('#', '.')
25
+ def_node_matcher :second_argument, <<~PATTERN
26
+ (block
27
+ (send #rspec? :describe _first_argument $(str _) ...) ...
28
+ )
29
+ PATTERN
28
30
 
29
- add_offense(second_arg)
31
+ def on_top_level_group(node)
32
+ second_argument = second_argument(node)
33
+
34
+ return unless second_argument
35
+ return if second_argument.str_content.start_with?('#', '.')
36
+
37
+ add_offense(second_argument)
30
38
  end
31
39
  end
32
40
  end
@@ -17,11 +17,11 @@ module RuboCop
17
17
  # end
18
18
  #
19
19
  # @see https://github.com/rspec/rspec-core/issues/1610
20
- class DescribeSymbol < Cop
20
+ class DescribeSymbol < Base
21
21
  MSG = 'Avoid describing symbols.'
22
22
 
23
23
  def_node_matcher :describe_symbol?, <<-PATTERN
24
- (send #{RSPEC} :describe $sym ...)
24
+ (send #rspec? :describe $sym ...)
25
25
  PATTERN
26
26
 
27
27
  def on_send(node)
@@ -54,7 +54,7 @@ module RuboCop
54
54
  # end
55
55
  # end
56
56
  #
57
- class DescribedClass < Cop
57
+ class DescribedClass < Base
58
58
  extend AutoCorrector
59
59
  include ConfigurableEnforcedStyle
60
60
 
@@ -142,7 +142,7 @@ module RuboCop
142
142
  if style == :described_class
143
143
  offensive_described_class?(node)
144
144
  else
145
- node.send_type? && node.method_name == :described_class
145
+ node.send_type? && node.method?(:described_class)
146
146
  end
147
147
  end
148
148
 
@@ -19,7 +19,7 @@ module RuboCop
19
19
  # end
20
20
  #
21
21
  # @see https://github.com/rubocop-hq/rubocop-rspec/issues/735
22
- class DescribedClassModuleWrapping < Cop
22
+ class DescribedClassModuleWrapping < Base
23
23
  MSG = 'Avoid opening modules and defining specs within them.'
24
24
 
25
25
  def_node_search :find_rspec_blocks,
@@ -41,7 +41,7 @@ module RuboCop
41
41
  # describe 'display name presence' do
42
42
  # # ...
43
43
  # end
44
- class Dialect < Cop
44
+ class Dialect < Base
45
45
  extend AutoCorrector
46
46
  include MethodPreference
47
47
 
@@ -57,20 +57,104 @@ module RuboCop
57
57
  # end
58
58
  # end
59
59
  #
60
- class EmptyExampleGroup < Cop
60
+ class EmptyExampleGroup < Base
61
61
  MSG = 'Empty example group detected.'
62
62
 
63
- def_node_search :contains_example?, <<-PATTERN
63
+ # @!method example_group_body(node)
64
+ # Match example group blocks and yield their body
65
+ #
66
+ # @example source that matches
67
+ # describe 'example group' do
68
+ # it { is_expected.to be }
69
+ # end
70
+ #
71
+ # @param node [RuboCop::AST::Node]
72
+ # @yield [RuboCop::AST::Node] example group body
73
+ def_node_matcher :example_group_body, <<~PATTERN
74
+ (block #{ExampleGroups::ALL.send_pattern} args $_)
75
+ PATTERN
76
+
77
+ # @!method example_or_group_or_include?(node)
78
+ # Match examples, example groups and includes
79
+ #
80
+ # @example source that matches
81
+ # it { is_expected.to fly }
82
+ # describe('non-empty example groups too') { }
83
+ # it_behaves_like 'an animal'
84
+ # it_behaves_like('a cat') { let(:food) { 'milk' } }
85
+ # it_has_root_access
86
+ #
87
+ # @param node [RuboCop::AST::Node]
88
+ # @return [Array<RuboCop::AST::Node>] matching nodes
89
+ def_node_matcher :example_or_group_or_include?, <<~PATTERN
64
90
  {
65
- #{(Examples::ALL + Includes::ALL).send_pattern}
66
- (send _ #custom_include? ...)
91
+ #{Examples::ALL.block_pattern}
92
+ #{ExampleGroups::ALL.block_pattern}
93
+ #{Includes::ALL.send_pattern}
94
+ #{Includes::ALL.block_pattern}
95
+ (send nil? #custom_include? ...)
67
96
  }
68
97
  PATTERN
69
98
 
70
- def on_block(node)
71
- return unless example_group?(node) && !contains_example?(node)
99
+ # @!method examples_inside_block?(node)
100
+ # Match examples defined inside a block which is not a hook
101
+ #
102
+ # @example source that matches
103
+ # %w(r g b).each do |color|
104
+ # it { is_expected.to have_color(color) }
105
+ # end
106
+ #
107
+ # @example source that does not match
108
+ # before do
109
+ # it { is_expected.to fall_into_oblivion }
110
+ # end
111
+ #
112
+ # @param node [RuboCop::AST::Node]
113
+ # @return [Array<RuboCop::AST::Node>] matching nodes
114
+ def_node_matcher :examples_inside_block?, <<~PATTERN
115
+ (block !#{Hooks::ALL.send_pattern} _ #examples?)
116
+ PATTERN
72
117
 
73
- add_offense(node.send_node)
118
+ # @!method examples_directly_or_in_block?(node)
119
+ # Match examples or examples inside blocks
120
+ #
121
+ # @example source that matches
122
+ # it { expect(drink).to be_cold }
123
+ # context('when winter') { it { expect(drink).to be_hot } }
124
+ # (1..5).each { |divisor| it { is_expected.to divide_by(divisor) } }
125
+ #
126
+ # @param node [RuboCop::AST::Node]
127
+ # @return [Array<RuboCop::AST::Node>] matching nodes
128
+ def_node_matcher :examples_directly_or_in_block?, <<~PATTERN
129
+ {
130
+ #example_or_group_or_include?
131
+ #examples_inside_block?
132
+ }
133
+ PATTERN
134
+
135
+ # @!method examples?(node)
136
+ # Matches examples defined in scopes where they could run
137
+ #
138
+ # @example source that matches
139
+ # it { expect(myself).to be_run }
140
+ # describe { it { i_run_as_well } }
141
+ #
142
+ # @example source that does not match
143
+ # before { it { whatever here wont run anyway } }
144
+ #
145
+ # @param node [RuboCop::AST::Node]
146
+ # @return [Array<RuboCop::AST::Node>] matching nodes
147
+ def_node_matcher :examples?, <<~PATTERN
148
+ {
149
+ #examples_directly_or_in_block?
150
+ (begin <#examples_directly_or_in_block? ...>)
151
+ }
152
+ PATTERN
153
+
154
+ def on_block(node)
155
+ example_group_body(node) do |body|
156
+ add_offense(node.send_node) unless examples?(body)
157
+ end
74
158
  end
75
159
 
76
160
  private
@@ -22,7 +22,7 @@ module RuboCop
22
22
  # create_feed
23
23
  # end
24
24
  # after(:all) { cleanup_feed }
25
- class EmptyHook < Cop
25
+ class EmptyHook < Base
26
26
  extend AutoCorrector
27
27
  include RuboCop::Cop::RangeHelp
28
28
 
@@ -41,22 +41,18 @@ module RuboCop
41
41
  # it { two }
42
42
  # end
43
43
  #
44
- class EmptyLineAfterExample < Cop
44
+ class EmptyLineAfterExample < Base
45
45
  extend AutoCorrector
46
- include RuboCop::RSpec::BlankLineSeparation
46
+ include RuboCop::RSpec::EmptyLineSeparation
47
47
 
48
48
  MSG = 'Add an empty line after `%<example>s`.'
49
49
 
50
50
  def on_block(node)
51
51
  return unless example?(node)
52
- return if last_child?(node)
53
52
  return if allowed_one_liner?(node)
54
53
 
55
- missing_separating_line(node) do |location|
56
- msg = format(MSG, example: node.method_name)
57
- add_offense(location, message: msg) do |corrector|
58
- corrector.insert_after(location.end, "\n")
59
- end
54
+ missing_separating_line_offense(node) do |method|
55
+ format(MSG, example: method)
60
56
  end
61
57
  end
62
58
 
@@ -23,21 +23,17 @@ module RuboCop
23
23
  # end
24
24
  # end
25
25
  #
26
- class EmptyLineAfterExampleGroup < Cop
26
+ class EmptyLineAfterExampleGroup < Base
27
27
  extend AutoCorrector
28
- include RuboCop::RSpec::BlankLineSeparation
28
+ include RuboCop::RSpec::EmptyLineSeparation
29
29
 
30
30
  MSG = 'Add an empty line after `%<example_group>s`.'
31
31
 
32
32
  def on_block(node)
33
33
  return unless example_group?(node)
34
- return if last_child?(node)
35
34
 
36
- missing_separating_line(node) do |location|
37
- msg = format(MSG, example_group: node.method_name)
38
- add_offense(location, message: msg) do |corrector|
39
- corrector.insert_after(location.end, "\n")
40
- end
35
+ missing_separating_line_offense(node) do |method|
36
+ format(MSG, example_group: method)
41
37
  end
42
38
  end
43
39
  end
@@ -16,24 +16,21 @@ module RuboCop
16
16
  # let(:something) { other }
17
17
  #
18
18
  # it { does_something }
19
- class EmptyLineAfterFinalLet < Cop
19
+ class EmptyLineAfterFinalLet < Base
20
20
  extend AutoCorrector
21
- include RuboCop::RSpec::BlankLineSeparation
21
+ include RuboCop::RSpec::EmptyLineSeparation
22
22
 
23
- MSG = 'Add an empty line after the last `let` block.'
23
+ MSG = 'Add an empty line after the last `%<let>s`.'
24
24
 
25
25
  def on_block(node)
26
26
  return unless example_group_with_body?(node)
27
27
 
28
- latest_let = node.body.child_nodes.select { |child| let?(child) }.last
28
+ final_let = node.body.child_nodes.reverse.find { |child| let?(child) }
29
29
 
30
- return if latest_let.nil?
31
- return if last_child?(latest_let)
30
+ return if final_let.nil?
32
31
 
33
- missing_separating_line(latest_let) do |location|
34
- add_offense(location) do |corrector|
35
- corrector.insert_after(location.end, "\n")
36
- end
32
+ missing_separating_line_offense(final_let) do |method|
33
+ format(MSG, let: method)
37
34
  end
38
35
  end
39
36
  end
@@ -33,21 +33,17 @@ module RuboCop
33
33
  #
34
34
  # it { does_something }
35
35
  #
36
- class EmptyLineAfterHook < Cop
36
+ class EmptyLineAfterHook < Base
37
37
  extend AutoCorrector
38
- include RuboCop::RSpec::BlankLineSeparation
38
+ include RuboCop::RSpec::EmptyLineSeparation
39
39
 
40
40
  MSG = 'Add an empty line after `%<hook>s`.'
41
41
 
42
42
  def on_block(node)
43
43
  return unless hook?(node)
44
- return if last_child?(node)
45
44
 
46
- missing_separating_line(node) do |location|
47
- msg = format(MSG, hook: node.method_name)
48
- add_offense(location, message: msg) do |corrector|
49
- corrector.insert_after(location.end, "\n")
50
- end
45
+ missing_separating_line_offense(node) do |method|
46
+ format(MSG, hook: method)
51
47
  end
52
48
  end
53
49
  end
@@ -14,20 +14,17 @@ module RuboCop
14
14
  # subject(:obj) { described_class }
15
15
  #
16
16
  # let(:foo) { bar }
17
- class EmptyLineAfterSubject < Cop
17
+ class EmptyLineAfterSubject < Base
18
18
  extend AutoCorrector
19
- include RuboCop::RSpec::BlankLineSeparation
19
+ include RuboCop::RSpec::EmptyLineSeparation
20
20
 
21
- MSG = 'Add empty line after `subject`.'
21
+ MSG = 'Add an empty line after `%<subject>s`.'
22
22
 
23
23
  def on_block(node)
24
24
  return unless subject?(node) && !in_spec_block?(node)
25
- return if last_child?(node)
26
25
 
27
- missing_separating_line(node) do |location|
28
- add_offense(location) do |corrector|
29
- corrector.insert_after(location.end, "\n")
30
- end
26
+ missing_separating_line_offense(node) do |method|
27
+ format(MSG, subject: method)
31
28
  end
32
29
  end
33
30
 
@@ -25,7 +25,7 @@ module RuboCop
25
25
  # result = service.call
26
26
  # expect(result).to be(true)
27
27
  # end
28
- class ExampleLength < Cop
28
+ class ExampleLength < Base
29
29
  include CodeLength
30
30
 
31
31
  MSG = 'Example has too many lines [%<total>d/%<max>d].'
@@ -47,7 +47,7 @@ module RuboCop
47
47
  # result = service.call
48
48
  # expect(result).to be(true)
49
49
  # end
50
- class ExampleWithoutDescription < Cop
50
+ class ExampleWithoutDescription < Base
51
51
  include ConfigurableEnforcedStyle
52
52
 
53
53
  MSG_DEFAULT_ARGUMENT = 'Omit the argument when you want to ' \
@@ -29,7 +29,7 @@ module RuboCop
29
29
  # # good
30
30
  # it 'does things' do
31
31
  # end
32
- class ExampleWording < Cop
32
+ class ExampleWording < Base
33
33
  extend AutoCorrector
34
34
 
35
35
  MSG_SHOULD = 'Do not use should when describing your tests.'
@@ -47,9 +47,9 @@ module RuboCop
47
47
 
48
48
  def on_block(node)
49
49
  it_description(node) do |description_node, message|
50
- if message =~ SHOULD_PREFIX
50
+ if message.match?(SHOULD_PREFIX)
51
51
  add_wording_offense(description_node, MSG_SHOULD)
52
- elsif message =~ IT_PREFIX
52
+ elsif message.match?(IT_PREFIX)
53
53
  add_wording_offense(description_node, MSG_IT)
54
54
  end
55
55
  end
@@ -77,7 +77,7 @@ module RuboCop
77
77
  def replacement_text(node)
78
78
  text = text(node)
79
79
 
80
- if text =~ SHOULD_PREFIX
80
+ if text.match?(SHOULD_PREFIX)
81
81
  RuboCop::RSpec::Wording.new(
82
82
  text,
83
83
  ignore: ignored_words,
@@ -16,7 +16,7 @@ module RuboCop
16
16
  # expect(pattern).to eq(/foo/)
17
17
  # expect(name).to eq("John")
18
18
  #
19
- class ExpectActual < Cop
19
+ class ExpectActual < Base
20
20
  extend AutoCorrector
21
21
 
22
22
  MSG = 'Provide the actual you are testing to `expect(...)`.'
@@ -29,7 +29,7 @@ module RuboCop
29
29
  # expect { run }.to change { Foo.bar(:count) }
30
30
  # expect { run }.to change { user.reload.name }
31
31
  #
32
- class ExpectChange < Cop
32
+ class ExpectChange < Base
33
33
  extend AutoCorrector
34
34
  include ConfigurableEnforcedStyle
35
35
 
@@ -20,7 +20,7 @@ module RuboCop
20
20
  # it do
21
21
  # expect(something).to eq 'foo'
22
22
  # end
23
- class ExpectInHook < Cop
23
+ class ExpectInHook < Base
24
24
  MSG = 'Do not use `%<expect>s` in `%<hook>s` hook'
25
25
 
26
26
  def_node_search :expectation, Expectations::ALL.send_pattern
@@ -14,7 +14,7 @@ module RuboCop
14
14
  #
15
15
  # # good
16
16
  # expect { my_app.print_report }.to output('Hello World').to_stdout
17
- class ExpectOutput < Cop
17
+ class ExpectOutput < Base
18
18
  MSG = 'Use `expect { ... }.to output(...).to_%<name>s` '\
19
19
  'instead of mutating $%<name>s.'
20
20
 
@@ -24,7 +24,7 @@ module RuboCop
24
24
  #
25
25
  # # good
26
26
  # count { 1 }
27
- class AttributeDefinedStatically < Cop
27
+ class AttributeDefinedStatically < Base
28
28
  extend AutoCorrector
29
29
 
30
30
  MSG = 'Use a block to declare attribute values.'
@@ -39,7 +39,7 @@ module RuboCop
39
39
 
40
40
  def on_block(node)
41
41
  attributes = factory_attributes(node) || []
42
- attributes = [attributes] unless attributes.is_a?(Array)
42
+ attributes = [attributes] unless attributes.is_a?(Array) # rubocop:disable Style/ArrayCoercion, Lint/RedundantCopDisableDirective
43
43
 
44
44
  attributes.each do |attribute|
45
45
  next unless offensive_receiver?(attribute.receiver, node)
@@ -84,7 +84,7 @@ module RuboCop
84
84
  def autocorrect_replacing_parens(corrector, node)
85
85
  left_braces, right_braces = braces(node)
86
86
 
87
- corrector.replace(node.location.begin, ' ' + left_braces)
87
+ corrector.replace(node.location.begin, " #{left_braces}")
88
88
  corrector.replace(node.location.end, right_braces)
89
89
  end
90
90