Skip to content

Commit

Permalink
Merge pull request #195 from wspurgin/show_each_enqueued_job_on_its_o…
Browse files Browse the repository at this point in the history
…wn_line

Update failure message to list out actual jobs line-by-line
  • Loading branch information
wspurgin authored Jul 26, 2023
2 parents 80a086e + 3e5f318 commit 4520dbd
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 25 deletions.
59 changes: 39 additions & 20 deletions lib/rspec/sidekiq/matchers/have_enqueued_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,29 +74,39 @@ def active_job_original_args
end
end

class EnqueuedJob
extend Forwardable
attr_reader :job
delegate :[] => :@job

def initialize(job)
@job = job
end

def jid
job["jid"]
end

def args
@actual_arguments ||= JobArguments.new(job).unwrapped_arguments
end

def context
@actual_options ||= job.except("args")
end
end

class EnqueuedJobs
attr_reader :jobs

def initialize(klass)
@jobs = unwrap_jobs(klass.jobs)
@jobs = unwrap_jobs(klass.jobs).map { |job| EnqueuedJob.new(job) }
end

def includes?(arguments, options)
!!jobs.find { |job| matches?(job, arguments, options) }
end

def actual_arguments
@actual_arguments ||= jobs.map { |job| JobArguments.new(job).unwrapped_arguments }
end

def actual_options
@actual_options ||= if jobs.is_a?(Hash)
jobs.values
else
jobs.flatten.map { |j| {"at" => j["at"]} }
end
end

private

def matches?(job, arguments, options)
Expand Down Expand Up @@ -124,21 +134,18 @@ def unwrap_jobs(jobs)
end

class HaveEnqueuedJob
attr_reader :klass, :expected_arguments, :actual_arguments, :expected_options, :actual_options
attr_reader :klass, :expected_arguments, :expected_options, :actual_jobs

def initialize(expected_arguments)
@expected_arguments = expected_arguments
@expected_options = {}
end


def matches?(klass)
@klass = klass

enqueued_jobs = EnqueuedJobs.new(klass)

@actual_arguments = enqueued_jobs.actual_arguments
@actual_options = enqueued_jobs.actual_options
@actual_jobs = enqueued_jobs.jobs

enqueued_jobs.includes?(jsonified_expected_arguments, expected_options)
end
Expand All @@ -164,8 +171,20 @@ def failure_message
message << " with options:" if expected_options.any?
message << " -#{expected_options}" if expected_options.any?
message << "but have enqueued only jobs"
message.concat([" with arguments:"], actual_arguments.sort_by { |a| a[0].to_s }.map { |a| " -#{a}" }) if expected_arguments
message.concat([" with options:"], actual_options.sort_by { |a| a.to_a[0].to_s }.map { |o| " -#{o}" }) if expected_options.any?
if expected_arguments
job_messages = actual_jobs.map do |job|
base = " -JID:#{job.jid} with arguments:"
base << "\n -#{job.args}"
if expected_options.any?
base << "\n with options: #{job.context.inspect}"
end

base
end

message << job_messages.join("\n")
end

message.join("\n")
end

Expand Down
30 changes: 25 additions & 5 deletions spec/rspec/sidekiq/matchers/have_enqueued_job_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -114,17 +114,37 @@

describe '#failure_message' do
it 'returns message' do
worker.perform_async *worker_args
jid = worker.perform_async *worker_args
argument_subject.matches? worker
expect(argument_subject.failure_message).to eq <<-eos.gsub(/^ {6}/, '').strip
expect(argument_subject.failure_message).to eq <<~eos.strip
expected to have an enqueued #{worker} job
with arguments:
-[\"string\", 1, true, {\"key\"=>\"value\", \"bar\"=>\"foo\", \"nested\"=>[{\"hash\"=>true}]}]
-["string", 1, true, {"key"=>"value", "bar"=>"foo", "nested"=>[{"hash"=>true}]}]
but have enqueued only jobs
with arguments:
-[\"string\", 1, true, {\"key\"=>\"value\", \"bar\"=>\"foo\", \"nested\"=>[{\"hash\"=>true}]}]
-JID:#{jid} with arguments:
-["string", 1, true, {"key"=>"value", "bar"=>"foo", "nested"=>[{"hash"=>true}]}]
eos
end

context "when expected arguments is an array and multiple jobs enqueued" do
let(:wrapped_args) { [worker_args] }
let(:argument_subject) { RSpec::Sidekiq::Matchers::HaveEnqueuedJob.new wrapped_args }

it "returns a message showing the wrapped array in expectations but each job on its own line" do
jids = 2.times.map { worker.perform_async *worker_args }
argument_subject.matches? worker
expect(argument_subject.failure_message).to eq <<~eos.strip
expected to have an enqueued #{worker} job
with arguments:
-[["string", 1, true, {"key"=>"value", "bar"=>"foo", "nested"=>[{"hash"=>true}]}]]
but have enqueued only jobs
-JID:#{jids[0]} with arguments:
-["string", 1, true, {"key"=>"value", "bar"=>"foo", "nested"=>[{"hash"=>true}]}]
-JID:#{jids[1]} with arguments:
-["string", 1, true, {"key"=>"value", "bar"=>"foo", "nested"=>[{"hash"=>true}]}]
eos
end
end
end

describe '#failure_message_when_negated' do
Expand Down

0 comments on commit 4520dbd

Please sign in to comment.