Class: RuboCop::Cop::RSpec::BeEql

Inherits:
Base
  • Object
show all
Extended by:
AutoCorrector
Defined in:
lib/rubocop/cop/rspec/be_eql.rb

Overview

Check for expectations where be(...) can replace eql(...).

The be matcher compares by identity while the eql matcher compares using eql?. Integers, floats, booleans, symbols, and nil can be compared by identity and therefore the be matcher is preferable as it is a more strict test.

This cop only looks for instances of expect(...).to eql(...). We do not check to_not or not_to since !eql? is more strict than !equal?. We also do not try to flag eq because if a == b, and b is comparable by identity, a is still not necessarily the same type as b since the #== operator can coerce objects for comparison.

Examples:

# bad
expect(foo).to eql(1)
expect(foo).to eql(1.0)
expect(foo).to eql(true)
expect(foo).to eql(false)
expect(foo).to eql(:bar)
expect(foo).to eql(nil)

# good
expect(foo).to be(1)
expect(foo).to be(1.0)
expect(foo).to be(true)
expect(foo).to be(false)
expect(foo).to be(:bar)
expect(foo).to be(nil)

Constant Summary collapse

MSG =
'Prefer `be` over `eql`.'
RESTRICT_ON_SEND =
%i[to].freeze

Instance Method Summary collapse

Methods inherited from Base

inherited, #on_new_investigation

Methods included from RSpec::Language

#example?, #example_group?, #example_group_with_body?, #explicit_rspec?, #hook?, #include?, #let?, #rspec?, #shared_group?, #spec_group?, #subject?

Instance Method Details

#eql_type_with_identity(node) ⇒ Object



47
48
49
# File 'lib/rubocop/cop/rspec/be_eql.rb', line 47

def_node_matcher :eql_type_with_identity, <<~PATTERN
  (send _ :to $(send nil? :eql {boolean int float sym nil}))
PATTERN

#on_send(node) ⇒ Object



51
52
53
54
55
56
57
# File 'lib/rubocop/cop/rspec/be_eql.rb', line 51

def on_send(node)
  eql_type_with_identity(node) do |eql|
    add_offense(eql.loc.selector) do |corrector|
      corrector.replace(eql.loc.selector, 'be')
    end
  end
end