Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support argument matchers in have_enqueued_* #2206

Merged
merged 1 commit into from Nov 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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]))
pirj marked this conversation as resolved.
Show resolved Hide resolved
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