Skip to content

Commit b1e27e2

Browse files
committed
Support composable matchers in have_enqueued_*
Fixes #2205 Time.at seems to be quite fine as pert://github.com/rails/rails/blob/a707072/activejob/lib/active_job/test_helper.rb#L679
1 parent e50def6 commit b1e27e2

File tree

4 files changed

+45
-11
lines changed

4 files changed

+45
-11
lines changed

Changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Enhancements:
1414
* Improve path parsing in view specs render options. (John Hawthorn, #2115)
1515
* Add routing spec template as an option for generating controller specs.
1616
(David Revelo, #2134)
17+
* Add argument matcher support to `have_enqueued_*` matchers. (Phil Pirozhkov, #2206)
1718

1819
Bug Fixes:
1920

lib/rspec/rails/matchers/active_job.rb

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ def supports_block_expectations?
9797

9898
def check(jobs)
9999
@matching_jobs, @unmatching_jobs = jobs.partition do |job|
100-
if job_match?(job) && arguments_match?(job) && other_attributes_match?(job)
100+
if job_match?(job) && arguments_match?(job) && queue_match?(job) && at_match?(job)
101101
args = deserialize_arguments(job)
102102
@block.call(*args)
103103
true
@@ -148,19 +148,18 @@ def arguments_match?(job)
148148
end
149149
end
150150

151-
def other_attributes_match?(job)
152-
serialized_attributes.all? { |key, value| value == job[key] }
153-
end
151+
def queue_match?(job)
152+
return true unless @queue
154153

155-
def serialized_attributes
156-
{}.tap do |attributes|
157-
attributes[:at] = serialized_at if @at
158-
attributes[:queue] = @queue if @queue
159-
end
154+
@queue == job[:queue]
160155
end
161156

162-
def serialized_at
163-
@at == :no_wait ? nil : @at.to_f
157+
def at_match?(job)
158+
return true unless @at
159+
return job[:at].nil? if @at == :no_wait
160+
return false unless job[:at]
161+
162+
values_match?(@at, Time.at(job[:at]))
164163
end
165164

166165
def set_expected_number(relativity, count)

spec/rspec/rails/matchers/active_job_spec.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,12 +211,29 @@ def self.name; "LoggingJob"; end
211211
}.to have_enqueued_job.at(date)
212212
end
213213

214+
it "accepts composable matchers as an at date" do
215+
future = 1.minute.from_now
216+
slightly_earlier = 58.seconds.from_now
217+
expect {
218+
hello_job.set(:wait_until => slightly_earlier).perform_later
219+
}.to have_enqueued_job.at(a_value_within(5.seconds).of(future))
220+
end
221+
214222
it "has an enqueued job when providing at of :no_wait and there is no wait" do
215223
expect {
216224
hello_job.perform_later
217225
}.to have_enqueued_job.at(:no_wait)
218226
end
219227

228+
it "has an enqueued job when providing at and there is no wait" do
229+
date = Date.tomorrow.noon
230+
expect {
231+
expect {
232+
hello_job.perform_later
233+
}.to have_enqueued_job.at(date)
234+
}.to raise_error(/expected to enqueue exactly 1 jobs, at .+ but enqueued 0/)
235+
end
236+
220237
it "has an enqueued job when not providing at and there is a wait" do
221238
date = Date.tomorrow.noon
222239
expect {
@@ -379,5 +396,13 @@ def self.name; "LoggingJob"; end
379396
expect(heavy_lifting_job).not_to have_been_enqueued
380397
}.to raise_error(/expected not to enqueue at least 1 jobs, but enqueued 2/)
381398
end
399+
400+
it "accepts composable matchers as an at date" do
401+
future = 1.minute.from_now
402+
slightly_earlier = 58.seconds.from_now
403+
heavy_lifting_job.set(:wait_until => slightly_earlier).perform_later
404+
expect(heavy_lifting_job)
405+
.to have_been_enqueued.at(a_value_within(5.seconds).of(future))
406+
end
382407
end
383408
end

spec/rspec/rails/matchers/have_enqueued_mail_spec.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,15 @@ def email_with_args(arg1, arg2); end
254254
}.to raise_error(/expected to enqueue TestMailer.test_email exactly 1 time at #{send_time.strftime('%F %T')}/)
255255
end
256256

257+
it "accepts composable matchers as an at date" do
258+
future = 1.minute.from_now
259+
slightly_earlier = 58.seconds.from_now
260+
261+
expect {
262+
TestMailer.test_email.deliver_later(:wait_until => slightly_earlier)
263+
}.to have_enqueued_email(TestMailer, :test_email).at(a_value_within(5.seconds).of(future))
264+
end
265+
257266
it "passes when deliver_later is called with a queue argument" do
258267
expect {
259268
TestMailer.test_email.deliver_later(:queue => 'urgent_mail')

0 commit comments

Comments
 (0)