Skip to content

Commit e85969d

Browse files
authored
Merge pull request #2061 from lovro-bikic/provide-safety-reason-for-expect-change
Add explanation for ExpectChange unsafe autocorrection
2 parents fcbb360 + 1d47c3d commit e85969d

File tree

2 files changed

+44
-4
lines changed

2 files changed

+44
-4
lines changed

docs/modules/ROOT/pages/cops_rspec.adoc

+23-2
Original file line numberDiff line numberDiff line change
@@ -2125,11 +2125,32 @@ expect(false).to eq(true)
21252125
21262126
Checks for consistent style of change matcher.
21272127
2128-
Enforces either passing object and attribute as arguments to the matcher
2129-
or passing a block that reads the attribute value.
2128+
Enforces either passing a receiver and message as method arguments,
2129+
or a block.
21302130
21312131
This cop can be configured using the `EnforcedStyle` option.
21322132
2133+
[#safety-rspecexpectchange]
2134+
=== Safety
2135+
2136+
Autocorrection is unsafe because `method_call` style calls the
2137+
receiver *once* and sends the message to it before and after
2138+
calling the `expect` block, whereas `block` style calls the
2139+
expression *twice*, including the receiver.
2140+
2141+
If your receiver is dynamic (e.g., the result of a method call) and
2142+
you expect it to be called before and after the `expect` block,
2143+
changing from `block` to `method_call` style may break your test.
2144+
2145+
[source,ruby]
2146+
----
2147+
expect { run }.to change { my_method.message }
2148+
# `my_method` is called before and after `run`
2149+
2150+
expect { run }.to change(my_method, :message)
2151+
# `my_method` is called once, but `message` is called on it twice
2152+
----
2153+
21332154
[#examples-rspecexpectchange]
21342155
=== Examples
21352156

lib/rubocop/cop/rspec/expect_change.rb

+21-2
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,30 @@ module Cop
55
module RSpec
66
# Checks for consistent style of change matcher.
77
#
8-
# Enforces either passing object and attribute as arguments to the matcher
9-
# or passing a block that reads the attribute value.
8+
# Enforces either passing a receiver and message as method arguments,
9+
# or a block.
1010
#
1111
# This cop can be configured using the `EnforcedStyle` option.
1212
#
13+
# @safety
14+
# Autocorrection is unsafe because `method_call` style calls the
15+
# receiver *once* and sends the message to it before and after
16+
# calling the `expect` block, whereas `block` style calls the
17+
# expression *twice*, including the receiver.
18+
#
19+
# If your receiver is dynamic (e.g., the result of a method call) and
20+
# you expect it to be called before and after the `expect` block,
21+
# changing from `block` to `method_call` style may break your test.
22+
#
23+
# [source,ruby]
24+
# ----
25+
# expect { run }.to change { my_method.message }
26+
# # `my_method` is called before and after `run`
27+
#
28+
# expect { run }.to change(my_method, :message)
29+
# # `my_method` is called once, but `message` is called on it twice
30+
# ----
31+
#
1332
# @example `EnforcedStyle: method_call` (default)
1433
# # bad
1534
# expect { run }.to change { Foo.bar }

0 commit comments

Comments
 (0)