Skip to content

Commit 160a517

Browse files
committed
Compatibility with compound matchers
1 parent 3fdd967 commit 160a517

File tree

2 files changed

+100
-21
lines changed

2 files changed

+100
-21
lines changed

lib/rspec/rails/matchers/send_email.rb

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,20 @@ module Matchers
99
#
1010
# @see RSpec::Rails::Matchers#send_email
1111
class SendEmail < RSpec::Rails::Matchers::BaseMatcher
12+
# @api private
13+
# Define the email attributes that should be included in the inspection output.
1214
INSPECT_EMAIL_ATTRIBUTES = %i[subject from to cc bcc].freeze
1315

1416
def initialize(criteria)
1517
@criteria = criteria
1618
end
1719

18-
# @private
20+
# @api private
1921
def supports_value_expectations?
2022
false
2123
end
2224

23-
# @private
25+
# @api private
2426
def supports_block_expectations?
2527
true
2628
end
@@ -31,17 +33,8 @@ def matches?(block)
3133
@matched_emails.one?
3234
end
3335

34-
private
35-
36-
def diffable?
37-
true
38-
end
39-
40-
def match_when_negated(block)
41-
define_matched_emails(block)
42-
@matched_emails.empty?
43-
end
44-
36+
# @api private
37+
# @return [String]
4538
def failure_message
4639
result =
4740
if multiple_match?
@@ -52,10 +45,18 @@ def failure_message
5245
"#{result}#{sent_emails_message}"
5346
end
5447

48+
# @api private
49+
# @return [String]
5550
def failure_message_when_negated
5651
"Expected not to send an email but it was sent."
5752
end
5853

54+
private
55+
56+
def diffable?
57+
true
58+
end
59+
5960
def deliveries
6061
ActionMailer::Base.deliveries
6162
end
@@ -68,11 +69,7 @@ def define_matched_emails(block)
6869
after = deliveries
6970

7071
@diff = after - before
71-
@matched_emails = select_matching(@diff)
72-
end
73-
74-
def select_matching(emails)
75-
@criteria.empty? ? emails : emails.select(&method(:matched_email?))
72+
@matched_emails = @diff.select(&method(:matched_email?))
7673
end
7774

7875
def matched_email?(email)

spec/rspec/rails/matchers/send_email_spec.rb

Lines changed: 85 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
# frozen_string_literal: true
2-
31
RSpec.describe "send_email" do
42
let(:mailer) do
53
Class.new(ActionMailer::Base) do
@@ -37,7 +35,7 @@ def test_email
3735
}.to send_email
3836
end
3937

40-
it "has a negated version" do
38+
it "with with to_not" do
4139
expect {
4240
mailer.test_email.deliver_now
4341
}.to_not send_email(
@@ -83,4 +81,88 @@ def test_email
8381
- subject: Test email, from: ["[email protected]"], to: ["[email protected]"], cc: ["[email protected]"], bcc: ["[email protected]"]
8482
MSG
8583
end
84+
85+
context "with compound matching" do
86+
it "works when both matchings pass" do
87+
expect {
88+
expect {
89+
mailer.test_email.deliver_now
90+
}.to send_email(to: "[email protected]").and send_email(from: "[email protected]")
91+
}.to_not raise_error
92+
end
93+
94+
it "works when first matching fails" do
95+
expect {
96+
expect {
97+
mailer.test_email.deliver_now
98+
}.to send_email(to: "[email protected]").and send_email(to: "[email protected]")
99+
}.to raise_error(RSpec::Expectations::ExpectationNotMetError, <<~MSG.strip)
100+
No matching emails were sent.
101+
102+
The following emails were sent:
103+
- subject: Test email, from: ["[email protected]"], to: ["[email protected]"], cc: ["[email protected]"], bcc: ["[email protected]"]
104+
MSG
105+
end
106+
107+
it "works when second matching fails" do
108+
expect {
109+
expect {
110+
mailer.test_email.deliver_now
111+
}.to send_email(to: "[email protected]").and send_email(to: "[email protected]")
112+
}.to raise_error(RSpec::Expectations::ExpectationNotMetError, <<~MSG.strip)
113+
No matching emails were sent.
114+
115+
The following emails were sent:
116+
- subject: Test email, from: ["[email protected]"], to: ["[email protected]"], cc: ["[email protected]"], bcc: ["[email protected]"]
117+
MSG
118+
end
119+
end
120+
121+
context "with a custom negated version defined" do
122+
before { RSpec::Matchers.define_negated_matcher :not_send_email, :send_email }
123+
124+
it "works with a negated version" do
125+
expect {
126+
mailer.test_email.deliver_now
127+
}.to not_send_email(
128+
129+
)
130+
end
131+
132+
it "fails with a clear message" do
133+
expect {
134+
expect { mailer.test_email.deliver_now }.to not_send_email(from: "[email protected]")
135+
}.to raise_error(RSpec::Expectations::ExpectationNotMetError, "Expected not to send an email but it was sent.")
136+
end
137+
138+
context "with a compound negated version" do
139+
it "works when both matchings pass" do
140+
expect {
141+
expect {
142+
mailer.test_email.deliver_now
143+
}.to not_send_email(to: "[email protected]").and not_send_email(from: "[email protected]")
144+
}.to_not raise_error
145+
end
146+
147+
it "works when first matching fails" do
148+
expect {
149+
expect {
150+
mailer.test_email.deliver_now
151+
}.to not_send_email(to: "[email protected]").and send_email(to: "[email protected]")
152+
}.to raise_error(RSpec::Expectations::ExpectationNotMetError, a_string_including(<<~MSG.strip))
153+
Expected not to send an email but it was sent.
154+
MSG
155+
end
156+
157+
it "works when second matching fails" do
158+
expect {
159+
expect {
160+
mailer.test_email.deliver_now
161+
}.to send_email(to: "[email protected]").and not_send_email(to: "[email protected]")
162+
}.to raise_error(RSpec::Expectations::ExpectationNotMetError, a_string_including(<<~MSG.strip))
163+
Expected not to send an email but it was sent.
164+
MSG
165+
end
166+
end
167+
end
86168
end

0 commit comments

Comments
 (0)