class RuboCop::Cop::RSpec::LeadingSubject

Enforce that subject is the first definition in the test.

@example

# bad
  let(:params) { blah }
  subject { described_class.new(params) }

  before { do_something }
  subject { described_class.new(params) }

  it { expect_something }
  subject { described_class.new(params) }
  it { expect_something_else }

# good
  subject { described_class.new(params) }
  let(:params) { blah }

# good
  subject { described_class.new(params) }
  before { do_something }

# good
  subject { described_class.new(params) }
  it { expect_something }
  it { expect_something_else }

Constants

MSG

Public Instance Methods

check_previous_nodes(node) click to toggle source
# File lib/rubocop/cop/rspec/leading_subject.rb, line 45
def check_previous_nodes(node)
  offending_node(node) do |offender|
    msg = format(MSG, offending: offender.method_name)
    add_offense(node, message: msg) do |corrector|
      autocorrect(corrector, node, offender)
    end
  end
end
on_block(node) click to toggle source
# File lib/rubocop/cop/rspec/leading_subject.rb, line 39
def on_block(node)
  return unless subject?(node) && !in_spec_block?(node)

  check_previous_nodes(node)
end

Private Instance Methods

autocorrect(corrector, node, sibling) click to toggle source
# File lib/rubocop/cop/rspec/leading_subject.rb, line 68
def autocorrect(corrector, node, sibling)
  RuboCop::RSpec::Corrector::MoveNode.new(
    node, corrector, processed_source
  ).move_before(sibling)
end
in_spec_block?(node) click to toggle source
# File lib/rubocop/cop/rspec/leading_subject.rb, line 82
def in_spec_block?(node)
  node.each_ancestor(:block).any? do |ancestor|
    example?(ancestor)
  end
end
offending?(node) click to toggle source
# File lib/rubocop/cop/rspec/leading_subject.rb, line 74
def offending?(node)
  let?(node) ||
    hook?(node) ||
    example?(node) ||
    spec_group?(node) ||
    include?(node)
end
offending_node(node) { |sibling| ... } click to toggle source
# File lib/rubocop/cop/rspec/leading_subject.rb, line 56
def offending_node(node)
  parent(node).each_child_node.find do |sibling|
    break if sibling.equal?(node)

    yield sibling if offending?(sibling)
  end
end
parent(node) click to toggle source
# File lib/rubocop/cop/rspec/leading_subject.rb, line 64
def parent(node)
  node.each_ancestor(:block).first.body
end