class RuboCop::Cop::RSpec::MultipleSubjects
a ‘before` hook on their own
This is enough of an edge case that people can just move this to
- If subjects are defined with `subject!` then we don’t autocorrect.
be dead code and we remove the overwritten subject definitions.
- If multiple unnamed subjects are defined though then this can only
case they are replaced with ‘let`.
definition) are effectively being used to define helpers. In this
that the overwritten subjects (all subjects except the last
- If multiple named subjects are defined then this probably indicates
duplication:
The autocorrect behavior for this cop depends on the type of
This cop does not support autocorrection in some cases.
end
end
Post.new
User.new
before do
describe Foo do
# good
end
subject!(:post) { Post.new }
subject!(:user) { User.new }
describe Foo do
# bad (does not support autocorrection)
end
subject(:post) { Post.new }
let(:user) { User.new }
describe Foo do
# good
end
subject(:post) { Post.new }
subject(:user) { User.new }
describe Foo do
# bad
@example
Checks if an example group defines `subject` multiple times.
def autocorrect(corrector, subject)
def autocorrect(corrector, subject) return unless subject.method_name.equal?(:subject) # Ignore `subject!` if named_subject?(subject) rename_autocorrect(corrector, subject) else remove_autocorrect(corrector, subject) end end
def named_subject?(node)
def named_subject?(node) node.send_node.arguments? end
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler return unless example_group?(node) subjects = RuboCop::RSpec::ExampleGroup.new(node).subjects subjects[0...-1].each do |subject| add_offense(subject) do |corrector| autocorrect(corrector, subject) end end end
def remove_autocorrect(corrector, node)
def remove_autocorrect(corrector, node) range = range_by_whole_lines(node.source_range, include_final_newline: true) corrector.remove(range) end
def rename_autocorrect(corrector, node)
def rename_autocorrect(corrector, node) corrector.replace(node.send_node.loc.selector, 'let') end