class RuboCop::Cop::RSpec::LeadingSubject

Checks for `subject` definitions that come after `let` definitions.

@example

# bad
RSpec.describe User do
  let(:params) { blah }
  subject { described_class.new(params) }

  it 'is valid' do
    expect(subject.valid?).to be(true)
  end
end

# good
RSpec.describe User do
  subject { described_class.new(params) }

  let(:params) { blah }

  it 'is valid' do
    expect(subject.valid?).to be(true)
  end
end

Constants

MSG

Public Instance Methods

autocorrect(node) click to toggle source
# File lib/rubocop/cop/rspec/leading_subject.rb, line 43
def autocorrect(node)
  lambda do |corrector|
    first_let = find_first_let(node)
    first_let_position = first_let.loc.expression
    indent = "\n" + ' ' * first_let.loc.column
    corrector.insert_before(first_let_position, node.source + indent)
    corrector.remove(node_range(node))
  end
end
on_block(node) click to toggle source
# File lib/rubocop/cop/rspec/leading_subject.rb, line 33
def on_block(node)
  return unless subject?(node) && !in_spec_block?(node)

  node.parent.each_child_node do |sibling|
    break if sibling.equal?(node)

    break add_offense(node, location: :expression) if let?(sibling)
  end
end

Private Instance Methods

find_first_let(node) click to toggle source
# File lib/rubocop/cop/rspec/leading_subject.rb, line 59
def find_first_let(node)
  node.parent.children.find { |sibling| let?(sibling) }
end
in_spec_block?(node) click to toggle source
# File lib/rubocop/cop/rspec/leading_subject.rb, line 70
def in_spec_block?(node)
  node.each_ancestor(:block).any? do |ancestor|
    Examples::ALL.include?(ancestor.method_name)
  end
end
let?(node) click to toggle source
# File lib/rubocop/cop/rspec/leading_subject.rb, line 55
def let?(node)
  %i[let let!].include?(node.method_name)
end
node_range(node) click to toggle source
# File lib/rubocop/cop/rspec/leading_subject.rb, line 63
def node_range(node)
  range = node.source_range
  range = range_with_surrounding_space(range, :left, false)
  range = range_with_surrounding_space(range, :right, true)
  range
end