class RuboCop::Cop::RSpec::ImplicitSubject

Checks for usage of implicit subject (‘is_expected` / `should`).

This cop can be configured using the ‘EnforcedStyle` option

@example ‘EnforcedStyle: single_line_only` (default)

# bad
it do
  is_expected.to be_truthy
end

# good
it { is_expected.to be_truthy }
it do
  expect(subject).to be_truthy
end

@example ‘EnforcedStyle: single_statement_only`

# bad
it do
  foo = 1
  is_expected.to be_truthy
end

# good
it do
  foo = 1
  expect(subject).to be_truthy
end
it do
  is_expected.to be_truthy
end

@example ‘EnforcedStyle: disallow`

# bad
it { is_expected.to be_truthy }

# good
it { expect(subject).to be_truthy }

@example ‘EnforcedStyle: require_implicit`

# bad
it { expect(subject).to be_truthy }

# good
it { is_expected.to be_truthy }

# bad
it do
  expect(subject).to be_truthy
end

# good
it do
  is_expected.to be_truthy
end

# good
it { expect(named_subject).to be_truthy }

Constants

MSG_REQUIRE_EXPLICIT
MSG_REQUIRE_IMPLICIT
RESTRICT_ON_SEND

Public Instance Methods

on_send(node) click to toggle source
# File lib/rubocop/cop/rspec/implicit_subject.rb, line 90
def on_send(node)
  return unless invalid?(node)

  add_offense(node) do |corrector|
    autocorrect(corrector, node)
  end
end

Private Instance Methods

autocorrect(corrector, node) click to toggle source
# File lib/rubocop/cop/rspec/implicit_subject.rb, line 100
def autocorrect(corrector, node)
  case node.method_name
  when :expect
    corrector.replace(node, 'is_expected')
  when :is_expected
    corrector.replace(node.location.selector, 'expect(subject)')
  when :should
    corrector.replace(node.location.selector, 'expect(subject).to')
  when :should_not
    corrector.replace(node.location.selector, 'expect(subject).not_to')
  end
end
example_of(node) click to toggle source
# File lib/rubocop/cop/rspec/implicit_subject.rb, line 159
def example_of(node)
  node.each_ancestor.find do |ancestor|
    example?(ancestor)
  end
end
implicit_subject_in_non_its?(node) click to toggle source
# File lib/rubocop/cop/rspec/implicit_subject.rb, line 135
def implicit_subject_in_non_its?(node)
  implicit_subject?(node) && !its?(node)
end
implicit_subject_in_non_its_and_non_single_line?(node) click to toggle source
# File lib/rubocop/cop/rspec/implicit_subject.rb, line 139
def implicit_subject_in_non_its_and_non_single_line?(node)
  implicit_subject_in_non_its?(node) && !single_line?(node)
end
implicit_subject_in_non_its_and_non_single_statement?(node) click to toggle source
# File lib/rubocop/cop/rspec/implicit_subject.rb, line 143
def implicit_subject_in_non_its_and_non_single_statement?(node)
  implicit_subject_in_non_its?(node) && !single_statement?(node)
end
invalid?(node) click to toggle source
# File lib/rubocop/cop/rspec/implicit_subject.rb, line 122
def invalid?(node)
  case style
  when :require_implicit
    explicit_unnamed_subject?(node)
  when :disallow
    implicit_subject_in_non_its?(node)
  when :single_line_only
    implicit_subject_in_non_its_and_non_single_line?(node)
  when :single_statement_only
    implicit_subject_in_non_its_and_non_single_statement?(node)
  end
end
its?(node) click to toggle source
# File lib/rubocop/cop/rspec/implicit_subject.rb, line 147
def its?(node)
  example_of(node)&.method?(:its)
end
message(_node) click to toggle source
# File lib/rubocop/cop/rspec/implicit_subject.rb, line 113
def message(_node)
  case style
  when :require_implicit
    MSG_REQUIRE_IMPLICIT
  else
    MSG_REQUIRE_EXPLICIT
  end
end
single_line?(node) click to toggle source
# File lib/rubocop/cop/rspec/implicit_subject.rb, line 151
def single_line?(node)
  example_of(node)&.single_line?
end
single_statement?(node) click to toggle source
# File lib/rubocop/cop/rspec/implicit_subject.rb, line 155
def single_statement?(node)
  !example_of(node)&.body&.begin_type?
end