Skip to content

Commit

Permalink
Merge pull request #2206 from rspec/composable-at-in-have_enqueued-ma…
Browse files Browse the repository at this point in the history
…tchers

Support argument matchers in have_enqueued_*
  • Loading branch information
pirj committed Nov 21, 2019
2 parents 9805cae + b1e27e2 commit d0f81df
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 11 deletions.
1 change: 1 addition & 0 deletions Changelog.md
Expand Up @@ -14,6 +14,7 @@ Enhancements:
* Improve path parsing in view specs render options. (John Hawthorn, #2115)
* Add routing spec template as an option for generating controller specs.
(David Revelo, #2134)
* Add argument matcher support to `have_enqueued_*` matchers. (Phil Pirozhkov, #2206)

Bug Fixes:

Expand Down
21 changes: 10 additions & 11 deletions lib/rspec/rails/matchers/active_job.rb
Expand Up @@ -97,7 +97,7 @@ def supports_block_expectations?

def check(jobs)
@matching_jobs, @unmatching_jobs = jobs.partition do |job|
if job_match?(job) && arguments_match?(job) && other_attributes_match?(job)
if job_match?(job) && arguments_match?(job) && queue_match?(job) && at_match?(job)
args = deserialize_arguments(job)
@block.call(*args)
true
Expand Down Expand Up @@ -148,19 +148,18 @@ def arguments_match?(job)
end
end

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

def serialized_attributes
{}.tap do |attributes|
attributes[:at] = serialized_at if @at
attributes[:queue] = @queue if @queue
end
@queue == job[:queue]
end

def serialized_at
@at == :no_wait ? nil : @at.to_f
def at_match?(job)
return true unless @at
return job[:at].nil? if @at == :no_wait
return false unless job[:at]

values_match?(@at, Time.at(job[:at]))
end

def set_expected_number(relativity, count)
Expand Down
25 changes: 25 additions & 0 deletions spec/rspec/rails/matchers/active_job_spec.rb
Expand Up @@ -211,12 +211,29 @@ def self.name; "LoggingJob"; end
}.to have_enqueued_job.at(date)
end

it "accepts composable matchers as an at date" do
future = 1.minute.from_now
slightly_earlier = 58.seconds.from_now
expect {
hello_job.set(:wait_until => slightly_earlier).perform_later
}.to have_enqueued_job.at(a_value_within(5.seconds).of(future))
end

it "has an enqueued job when providing at of :no_wait and there is no wait" do
expect {
hello_job.perform_later
}.to have_enqueued_job.at(:no_wait)
end

it "has an enqueued job when providing at and there is no wait" do
date = Date.tomorrow.noon
expect {
expect {
hello_job.perform_later
}.to have_enqueued_job.at(date)
}.to raise_error(/expected to enqueue exactly 1 jobs, at .+ but enqueued 0/)
end

it "has an enqueued job when not providing at and there is a wait" do
date = Date.tomorrow.noon
expect {
Expand Down Expand Up @@ -379,5 +396,13 @@ def self.name; "LoggingJob"; end
expect(heavy_lifting_job).not_to have_been_enqueued
}.to raise_error(/expected not to enqueue at least 1 jobs, but enqueued 2/)
end

it "accepts composable matchers as an at date" do
future = 1.minute.from_now
slightly_earlier = 58.seconds.from_now
heavy_lifting_job.set(:wait_until => slightly_earlier).perform_later
expect(heavy_lifting_job)
.to have_been_enqueued.at(a_value_within(5.seconds).of(future))
end
end
end
9 changes: 9 additions & 0 deletions spec/rspec/rails/matchers/have_enqueued_mail_spec.rb
Expand Up @@ -254,6 +254,15 @@ def email_with_args(arg1, arg2); end
}.to raise_error(/expected to enqueue TestMailer.test_email exactly 1 time at #{send_time.strftime('%F %T')}/)
end

it "accepts composable matchers as an at date" do
future = 1.minute.from_now
slightly_earlier = 58.seconds.from_now

expect {
TestMailer.test_email.deliver_later(:wait_until => slightly_earlier)
}.to have_enqueued_email(TestMailer, :test_email).at(a_value_within(5.seconds).of(future))
end

it "passes when deliver_later is called with a queue argument" do
expect {
TestMailer.test_email.deliver_later(:queue => 'urgent_mail')
Expand Down

0 comments on commit d0f81df

Please sign in to comment.