Skip to content

Commit cada3e0

Browse files
committed
Add new RSpec/IdenticalEqualityAssertion cop
Closes #1130
1 parent cb5c0dc commit cada3e0

File tree

7 files changed

+135
-0
lines changed

7 files changed

+135
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
* Add missing documentation for `single_statement_only` style of `RSpec/ImplicitSubject` cop. ([@tejasbubane][])
66
* Fix an exception in `DescribedClass` when accessing a constant on a variable in a spec that is nested in a namespace. ([@rrosenblum][])
7+
* Add new `RSpec/IdenticalEqualityAssertion` cop. ([@tejasbubane][])
78

89
## 2.3.0 (2021-04-28)
910

config/default.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,12 @@ RSpec/HooksBeforeExamples:
351351
VersionAdded: '1.29'
352352
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/HooksBeforeExamples
353353

354+
RSpec/IdenticalEqualityAssertion:
355+
Description: Checks for equality assertions with identical expressions on both sides.
356+
Enabled: pending
357+
VersionAdded: '2.4'
358+
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/IdenticalEqualityAssertion
359+
354360
RSpec/ImplicitBlockExpectation:
355361
Description: Check that implicit block expectation syntax is not used.
356362
Enabled: true

docs/modules/ROOT/pages/cops.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
* xref:cops_rspec.adoc#rspecfocus[RSpec/Focus]
3636
* xref:cops_rspec.adoc#rspechookargument[RSpec/HookArgument]
3737
* xref:cops_rspec.adoc#rspechooksbeforeexamples[RSpec/HooksBeforeExamples]
38+
* xref:cops_rspec.adoc#rspecidenticalequalityassertion[RSpec/IdenticalEqualityAssertion]
3839
* xref:cops_rspec.adoc#rspecimplicitblockexpectation[RSpec/ImplicitBlockExpectation]
3940
* xref:cops_rspec.adoc#rspecimplicitexpect[RSpec/ImplicitExpect]
4041
* xref:cops_rspec.adoc#rspecimplicitsubject[RSpec/ImplicitSubject]

docs/modules/ROOT/pages/cops_rspec.adoc

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1720,6 +1720,37 @@ end
17201720

17211721
* https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/HooksBeforeExamples
17221722

1723+
== RSpec/IdenticalEqualityAssertion
1724+
1725+
|===
1726+
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
1727+
1728+
| Pending
1729+
| Yes
1730+
| No
1731+
| 2.4
1732+
| -
1733+
|===
1734+
1735+
Checks for equality assertions with identical expressions on both sides.
1736+
1737+
=== Examples
1738+
1739+
[source,ruby]
1740+
----
1741+
# bad
1742+
expect(foo.bar).to eq(foo.bar)
1743+
expect(foo.bar).to eql(foo.bar)
1744+
1745+
# good
1746+
expect(foo.bar).to eq(2)
1747+
expect(foo.bar).to eql(2)
1748+
----
1749+
1750+
=== References
1751+
1752+
* https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/IdenticalEqualityAssertion
1753+
17231754
== RSpec/ImplicitBlockExpectation
17241755

17251756
|===
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# frozen_string_literal: true
2+
3+
module RuboCop
4+
module Cop
5+
module RSpec
6+
# Checks for equality assertions with identical expressions on both sides.
7+
#
8+
# @example
9+
#
10+
# # bad
11+
# expect(foo.bar).to eq(foo.bar)
12+
# expect(foo.bar).to eql(foo.bar)
13+
#
14+
# # good
15+
# expect(foo.bar).to eq(2)
16+
# expect(foo.bar).to eql(2)
17+
#
18+
class IdenticalEqualityAssertion < Base
19+
MSG = 'Identical expressions on both sides of the equality ' \
20+
'may indicate a flawed test.'
21+
RESTRICT_ON_SEND = %i[to].freeze
22+
23+
# @!method equality_check?(node)
24+
def_node_matcher :equality_check?, <<~PATTERN
25+
(send (send nil? :expect $_) :to
26+
{(send nil? {:eql :eq :be} $_)
27+
(send (send nil? :be) :== $_)})
28+
PATTERN
29+
30+
def on_send(node)
31+
equality_check?(node) do |left, right|
32+
add_offense(node) if left == right
33+
end
34+
end
35+
end
36+
end
37+
end
38+
end

lib/rubocop/cop/rspec_cops.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
require_relative 'rspec/focus'
4848
require_relative 'rspec/hook_argument'
4949
require_relative 'rspec/hooks_before_examples'
50+
require_relative 'rspec/identical_equality_assertion'
5051
require_relative 'rspec/implicit_block_expectation'
5152
require_relative 'rspec/implicit_expect'
5253
require_relative 'rspec/implicit_subject'
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# frozen_string_literal: true
2+
3+
RSpec.describe RuboCop::Cop::RSpec::IdenticalEqualityAssertion do
4+
it 'registers an offense when using identical expressions with `eq`' do
5+
expect_offense(<<~RUBY)
6+
expect(foo.bar).to eq(foo.bar)
7+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Identical expressions on both sides of the equality may indicate a flawed test.
8+
RUBY
9+
end
10+
11+
it 'registers an offense when using identical expressions with `eql`' do
12+
expect_offense(<<~RUBY)
13+
expect(foo.bar.baz).to eql(foo.bar.baz)
14+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Identical expressions on both sides of the equality may indicate a flawed test.
15+
RUBY
16+
end
17+
18+
it 'registers an offense for trivial constants' do
19+
expect_offense(<<~RUBY)
20+
expect(42).to eq(42)
21+
^^^^^^^^^^^^^^^^^^^^ Identical expressions on both sides of the equality may indicate a flawed test.
22+
RUBY
23+
end
24+
25+
it 'registers an offense for complex constants' do
26+
expect_offense(<<~RUBY)
27+
expect({a: 1, b: :b}).to eql({a: 1, b: :b})
28+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Identical expressions on both sides of the equality may indicate a flawed test.
29+
RUBY
30+
end
31+
32+
it 'registers an offense for identical expression with be' do
33+
expect_offense(<<~RUBY)
34+
expect(foo.bar).to be(foo.bar)
35+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Identical expressions on both sides of the equality may indicate a flawed test.
36+
RUBY
37+
end
38+
39+
it 'registers an offense for identical expression with be ==' do
40+
expect_offense(<<~RUBY)
41+
expect(foo.bar).to be == foo.bar
42+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Identical expressions on both sides of the equality may indicate a flawed test.
43+
RUBY
44+
end
45+
46+
it 'does not register offense for different expressions' do
47+
expect_no_offenses(<<~RUBY)
48+
expect(foo.bar).to eq(bar.foo)
49+
RUBY
50+
end
51+
52+
it 'checks for whole expression' do
53+
expect_no_offenses(<<~RUBY)
54+
expect(Foo.new(1).foo).to eql(Foo.new(2).bar)
55+
RUBY
56+
end
57+
end

0 commit comments

Comments
 (0)