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