Class: RuboCop::Cop::Vicenzo::RSpec::ConditionalInSpec

Inherits:
RSpec::Base
  • Object
show all
Defined in:
lib/rubocop/cop/vicenzo/rspec/conditional_in_spec.rb

Overview

Do not use conditional logic in spec files.

Any if, unless, or ternary expression in a spec represents a hidden context. Each branch should be an explicit context block so that the conditions and expectations are always clear and unconditional.

Examples:

# bad — hidden context inside an example

it 'grants or denies access' do
  if user.admin?
    expect(result).to eq(:granted)
  else
    expect(result).to eq(:denied)
  end
end

# bad — hidden context inside a let

let(:user) { admin? ? create(:admin) : create(:client) }

# bad — hidden context inside a before hook

before { setup_thing if feature_enabled? }

# bad — hidden context at the example group level using unless

unless legacy_mode?
  it 'uses the new behaviour' do
    ...
  end
end

# good

context 'when user is admin' do
  let(:user) { create(:admin) }

  it 'grants access' do
    expect(result).to eq(:granted)
  end
end

context 'when user is not admin' do
  let(:user) { create(:client) }

  it 'denies access' do
    expect(result).to eq(:denied)
  end
end

Constant Summary collapse

MSG =
'Do not use conditional logic in specs. ' \
'Extract each branch into an explicit context instead.'

Instance Method Summary collapse

Instance Method Details

#on_if(node) ⇒ Object

Both if and unless are represented as if nodes in the AST, so this single hook covers all conditional forms: if, unless, modifier if/unless, and ternary ?:.



64
65
66
67
# File 'lib/rubocop/cop/vicenzo/rspec/conditional_in_spec.rb', line 64

def on_if(node)
  offense_location = node.ternary? ? node : node.loc.keyword
  add_offense(offense_location)
end