lib/active_job/test_helper.rb in activejob-6.0.6.1 vs lib/active_job/test_helper.rb in activejob-6.1.0.rc1
- old
+ new
@@ -115,21 +115,21 @@
# assert_enqueued_jobs 2, queue: 'default' do
# LoggingJob.perform_later
# HelloJob.perform_later('elfassy')
# end
# end
- def assert_enqueued_jobs(number, only: nil, except: nil, queue: nil)
+ def assert_enqueued_jobs(number, only: nil, except: nil, queue: nil, &block)
if block_given?
- original_count = enqueued_jobs_with(only: only, except: except, queue: queue)
+ original_jobs = enqueued_jobs_with(only: only, except: except, queue: queue)
- yield
+ assert_nothing_raised(&block)
- new_count = enqueued_jobs_with(only: only, except: except, queue: queue)
+ new_jobs = enqueued_jobs_with(only: only, except: except, queue: queue)
- actual_count = new_count - original_count
+ actual_count = (new_jobs - original_jobs).count
else
- actual_count = enqueued_jobs_with(only: only, except: except, queue: queue)
+ actual_count = enqueued_jobs_with(only: only, except: except, queue: queue).count
end
assert_equal number, actual_count, "#{number} jobs expected, but #{actual_count} were enqueued"
end
@@ -277,11 +277,11 @@
new_count = performed_jobs.size
performed_jobs_size = new_count - original_count
else
- performed_jobs_size = performed_jobs_with(only: only, except: except, queue: queue)
+ performed_jobs_size = performed_jobs_with(only: only, except: except, queue: queue).count
end
assert_equal number, performed_jobs_size, "#{number} jobs expected, but #{performed_jobs_size} were performed"
end
@@ -343,146 +343,145 @@
# Asserts that the job has been enqueued with the given arguments.
#
# def test_assert_enqueued_with
# MyJob.perform_later(1,2,3)
- # assert_enqueued_with(job: MyJob, args: [1,2,3], queue: 'low')
+ # assert_enqueued_with(job: MyJob, args: [1,2,3])
#
- # MyJob.set(wait_until: Date.tomorrow.noon).perform_later
- # assert_enqueued_with(job: MyJob, at: Date.tomorrow.noon)
+ # MyJob.set(wait_until: Date.tomorrow.noon, queue: "my_queue").perform_later
+ # assert_enqueued_with(at: Date.tomorrow.noon, queue: "my_queue")
# end
#
- # The +at+ and +args+ arguments also accept a proc.
+ # The given arguments may also be specified as matcher procs that return a
+ # boolean value indicating whether a job's attribute meets certain criteria.
#
- # To the +at+ proc, it will get passed the actual job's at argument.
+ # For example, a proc can be used to match a range of times:
#
# def test_assert_enqueued_with
- # expected_time = ->(at) do
- # (Date.yesterday..Date.tomorrow).cover?(at)
- # end
+ # at_matcher = ->(job_at) { (Date.yesterday..Date.tomorrow).cover?(job_at) }
#
- # MyJob.set(at: Date.today.noon).perform_later
- # assert_enqueued_with(job: MyJob, at: expected_time)
+ # MyJob.set(wait_until: Date.today.noon).perform_later
+ #
+ # assert_enqueued_with(job: MyJob, at: at_matcher)
# end
#
- # To the +args+ proc, it will get passed the actual job's arguments
- # Your proc needs to return a boolean value determining if
- # the job's arguments matches your expectation. This is useful to check only
- # for a subset of arguments.
+ # A proc can also be used to match a subset of a job's args:
#
# def test_assert_enqueued_with
- # expected_args = ->(job_args) do
- # assert job_args.first.key?(:foo)
- # end
+ # args_matcher = ->(job_args) { job_args[0].key?(:foo) }
#
- # MyJob.perform_later(foo: 'bar', other_arg: 'No need to check in the test')
- # assert_enqueued_with(job: MyJob, args: expected_args, queue: 'low')
+ # MyJob.perform_later(foo: "bar", other_arg: "No need to check in the test")
+ #
+ # assert_enqueued_with(job: MyJob, args: args_matcher)
# end
#
# If a block is passed, asserts that the block will cause the job to be
# enqueued with the given arguments.
#
# def test_assert_enqueued_with
- # assert_enqueued_with(job: MyJob, args: [1,2,3], queue: 'low') do
+ # assert_enqueued_with(job: MyJob, args: [1,2,3]) do
# MyJob.perform_later(1,2,3)
# end
#
# assert_enqueued_with(job: MyJob, at: Date.tomorrow.noon) do
# MyJob.set(wait_until: Date.tomorrow.noon).perform_later
# end
# end
- def assert_enqueued_with(job: nil, args: nil, at: nil, queue: nil)
+ def assert_enqueued_with(job: nil, args: nil, at: nil, queue: nil, &block)
expected = { job: job, args: args, at: at, queue: queue }.compact
expected_args = prepare_args_for_assertion(expected)
+ potential_matches = []
if block_given?
- original_enqueued_jobs_count = enqueued_jobs.count
+ original_enqueued_jobs = enqueued_jobs.dup
- yield
+ assert_nothing_raised(&block)
- jobs = enqueued_jobs.drop(original_enqueued_jobs_count)
+ jobs = enqueued_jobs - original_enqueued_jobs
else
jobs = enqueued_jobs
end
matching_job = jobs.find do |enqueued_job|
deserialized_job = deserialize_args_for_assertion(enqueued_job)
+ potential_matches << deserialized_job
expected_args.all? do |key, value|
if value.respond_to?(:call)
value.call(deserialized_job[key])
else
value == deserialized_job[key]
end
end
end
- assert matching_job, "No enqueued job found with #{expected}"
+ message = +"No enqueued job found with #{expected}"
+ message << "\n\nPotential matches: #{potential_matches.join("\n")}" if potential_matches.present?
+ assert matching_job, message
instantiate_job(matching_job)
end
# Asserts that the job has been performed with the given arguments.
#
# def test_assert_performed_with
# MyJob.perform_later(1,2,3)
#
# perform_enqueued_jobs
#
- # assert_performed_with(job: MyJob, args: [1,2,3], queue: 'high')
+ # assert_performed_with(job: MyJob, args: [1,2,3])
#
- # MyJob.set(wait_until: Date.tomorrow.noon).perform_later
+ # MyJob.set(wait_until: Date.tomorrow.noon, queue: "my_queue").perform_later
#
# perform_enqueued_jobs
#
- # assert_performed_with(job: MyJob, at: Date.tomorrow.noon)
+ # assert_performed_with(at: Date.tomorrow.noon, queue: "my_queue")
# end
#
- # The +at+ and +args+ arguments also accept a proc.
+ # The given arguments may also be specified as matcher procs that return a
+ # boolean value indicating whether a job's attribute meets certain criteria.
#
- # To the +at+ proc, it will get passed the actual job's at argument.
+ # For example, a proc can be used to match a range of times:
#
- # def test_assert_enqueued_with
- # expected_time = ->(at) do
- # (Date.yesterday..Date.tomorrow).cover?(at)
- # end
+ # def test_assert_performed_with
+ # at_matcher = ->(job_at) { (Date.yesterday..Date.tomorrow).cover?(job_at) }
#
- # MyJob.set(at: Date.today.noon).perform_later
- # assert_enqueued_with(job: MyJob, at: expected_time)
+ # MyJob.set(wait_until: Date.today.noon).perform_later
+ #
+ # perform_enqueued_jobs
+ #
+ # assert_performed_with(job: MyJob, at: at_matcher)
# end
#
- # To the +args+ proc, it will get passed the actual job's arguments
- # Your proc needs to return a boolean value determining if
- # the job's arguments matches your expectation. This is useful to check only
- # for a subset of arguments.
+ # A proc can also be used to match a subset of a job's args:
#
# def test_assert_performed_with
- # expected_args = ->(job_args) do
- # assert job_args.first.key?(:foo)
- # end
- # MyJob.perform_later(foo: 'bar', other_arg: 'No need to check in the test')
+ # args_matcher = ->(job_args) { job_args[0].key?(:foo) }
#
+ # MyJob.perform_later(foo: "bar", other_arg: "No need to check in the test")
+ #
# perform_enqueued_jobs
#
- # assert_performed_with(job: MyJob, args: expected_args, queue: 'high')
+ # assert_performed_with(job: MyJob, args: args_matcher)
# end
#
# If a block is passed, that block performs all of the jobs that were
# enqueued throughout the duration of the block and asserts that
# the job has been performed with the given arguments in the block.
#
# def test_assert_performed_with
- # assert_performed_with(job: MyJob, args: [1,2,3], queue: 'high') do
+ # assert_performed_with(job: MyJob, args: [1,2,3]) do
# MyJob.perform_later(1,2,3)
# end
#
# assert_performed_with(job: MyJob, at: Date.tomorrow.noon) do
# MyJob.set(wait_until: Date.tomorrow.noon).perform_later
# end
# end
def assert_performed_with(job: nil, args: nil, at: nil, queue: nil, &block)
expected = { job: job, args: args, at: at, queue: queue }.compact
expected_args = prepare_args_for_assertion(expected)
+ potential_matches = []
if block_given?
original_performed_jobs_count = performed_jobs.count
perform_enqueued_jobs(&block)
@@ -492,21 +491,25 @@
jobs = performed_jobs
end
matching_job = jobs.find do |enqueued_job|
deserialized_job = deserialize_args_for_assertion(enqueued_job)
+ potential_matches << deserialized_job
expected_args.all? do |key, value|
if value.respond_to?(:call)
value.call(deserialized_job[key])
else
value == deserialized_job[key]
end
end
end
- assert matching_job, "No performed job found with #{expected}"
+ message = +"No performed job found with #{expected}"
+ message << "\n\nPotential matches: #{potential_matches.join("\n")}" if potential_matches.present?
+ assert matching_job, message
+
instantiate_job(matching_job)
end
# Performs all enqueued jobs. If a block is given, performs all of the jobs
# that were enqueued throughout the duration of the block. If a block is
@@ -561,35 +564,40 @@
# HelloJob.set(queue: :other_queue).perform_later(1, 2, 3) # will not be performed
# end
# assert_performed_jobs 1
# end
#
- def perform_enqueued_jobs(only: nil, except: nil, queue: nil)
- return flush_enqueued_jobs(only: only, except: except, queue: queue) unless block_given?
+ # If the +:at+ option is specified, then only run jobs enqueued to run
+ # immediately or before the given time
+ def perform_enqueued_jobs(only: nil, except: nil, queue: nil, at: nil, &block)
+ return flush_enqueued_jobs(only: only, except: except, queue: queue, at: at) unless block_given?
validate_option(only: only, except: except)
old_perform_enqueued_jobs = queue_adapter.perform_enqueued_jobs
old_perform_enqueued_at_jobs = queue_adapter.perform_enqueued_at_jobs
old_filter = queue_adapter.filter
old_reject = queue_adapter.reject
old_queue = queue_adapter.queue
+ old_at = queue_adapter.at
begin
queue_adapter.perform_enqueued_jobs = true
queue_adapter.perform_enqueued_at_jobs = true
queue_adapter.filter = only
queue_adapter.reject = except
queue_adapter.queue = queue
+ queue_adapter.at = at
- yield
+ assert_nothing_raised(&block)
ensure
queue_adapter.perform_enqueued_jobs = old_perform_enqueued_jobs
queue_adapter.perform_enqueued_at_jobs = old_perform_enqueued_at_jobs
queue_adapter.filter = old_filter
queue_adapter.reject = old_reject
queue_adapter.queue = old_queue
+ queue_adapter.at = old_at
end
end
# Accesses the queue_adapter set by ActiveJob::Base.
#
@@ -607,14 +615,14 @@
def clear_performed_jobs
performed_jobs.clear
end
- def jobs_with(jobs, only: nil, except: nil, queue: nil)
+ def jobs_with(jobs, only: nil, except: nil, queue: nil, at: nil)
validate_option(only: only, except: except)
- jobs.count do |job|
+ jobs.dup.select do |job|
job_class = job.fetch(:job)
if only
next false unless filter_as_proc(only).call(job)
elsif except
@@ -623,10 +631,14 @@
if queue
next false unless queue.to_s == job.fetch(:queue, job_class.queue_name)
end
+ if at && job[:at]
+ next false if job[:at] > at.to_f
+ end
+
yield job if block_given?
true
end
end
@@ -635,44 +647,31 @@
return filter if filter.is_a?(Proc)
->(job) { Array(filter).include?(job.fetch(:job)) }
end
- def enqueued_jobs_with(only: nil, except: nil, queue: nil, &block)
- jobs_with(enqueued_jobs, only: only, except: except, queue: queue, &block)
+ def enqueued_jobs_with(only: nil, except: nil, queue: nil, at: nil, &block)
+ jobs_with(enqueued_jobs, only: only, except: except, queue: queue, at: at, &block)
end
def performed_jobs_with(only: nil, except: nil, queue: nil, &block)
jobs_with(performed_jobs, only: only, except: except, queue: queue, &block)
end
- def flush_enqueued_jobs(only: nil, except: nil, queue: nil)
- enqueued_jobs_with(only: only, except: except, queue: queue) do |payload|
- instantiate_job(payload).perform_now
+ def flush_enqueued_jobs(only: nil, except: nil, queue: nil, at: nil)
+ enqueued_jobs_with(only: only, except: except, queue: queue, at: at) do |payload|
+ queue_adapter.enqueued_jobs.delete(payload)
queue_adapter.performed_jobs << payload
- end
+ instantiate_job(payload).perform_now
+ end.count
end
def prepare_args_for_assertion(args)
args.dup.tap do |arguments|
- if arguments[:at] && !arguments[:at].respond_to?(:call)
+ if arguments[:at].acts_like?(:time)
at_range = arguments[:at] - 1..arguments[:at] + 1
arguments[:at] = ->(at) { at_range.cover?(at) }
end
- arguments[:args] = round_time_arguments(arguments[:args]) if arguments[:args]
- end
- end
-
- def round_time_arguments(argument)
- case argument
- when Time, ActiveSupport::TimeWithZone, DateTime
- argument.change(usec: 0)
- when Hash
- argument.transform_values { |value| round_time_arguments(value) }
- when Array
- argument.map { |element| round_time_arguments(element) }
- else
- argument
end
end
def deserialize_args_for_assertion(job)
job.dup.tap do |new_job|