class RSpec::EnqueueSidekiqJob::Matcher

@private

Attributes

expected_arguments[R]
expected_at[R]
expected_count[R]
expected_in[R]
worker_class[R]

Public Class Methods

new(worker_class) click to toggle source
# File lib/rspec/enqueue_sidekiq_job.rb, line 32
def initialize(worker_class)
  @worker_class = worker_class
  @expected_count = nil
end

Public Instance Methods

at(timestamp) click to toggle source
# File lib/rspec/enqueue_sidekiq_job.rb, line 46
def at(timestamp)
  raise 'setting expecations with both `at` and `in` is not supported' if @expected_in

  @expected_at = timestamp
  self
end
does_not_match?(block) click to toggle source
# File lib/rspec/enqueue_sidekiq_job.rb, line 77
def does_not_match?(block)
  raise 'counts are not supported with negation' if expected_count

  filter(enqueued_in_block(block)).none?
end
exactly(times) click to toggle source
# File lib/rspec/enqueue_sidekiq_job.rb, line 64
def exactly(times)
  @expected_count = times
  self
end
failure_message() click to toggle source
# File lib/rspec/enqueue_sidekiq_job.rb, line 83
def failure_message
  message = ["expected to enqueue #{worker_class} job"]
  message << "  arguments: #{expected_arguments}" if expected_arguments
  message << "  in: #{expected_in.inspect}" if expected_in
  message << "  at: #{expected_at}" if expected_at
  message << "  exactly #{expected_count} times" if expected_count
  message.join("\n")
end
failure_message_when_negated() click to toggle source
# File lib/rspec/enqueue_sidekiq_job.rb, line 92
def failure_message_when_negated
  message = ["expected not to enqueue #{worker_class} job"]
  message << "  arguments: #{expected_arguments}" if expected_arguments
  message << "  in: #{expected_in.inspect}" if expected_in
  message << "  at: #{expected_at}" if expected_at
  message << "  exactly #{expected_count} times" if expected_count
  message.join("\n")
end
in(interval) click to toggle source
# File lib/rspec/enqueue_sidekiq_job.rb, line 53
def in(interval)
  raise 'setting expecations with both `at` and `in` is not supported' if @expected_at

  @expected_in = interval
  self
end
matches?(block) click to toggle source
# File lib/rspec/enqueue_sidekiq_job.rb, line 73
def matches?(block)
  filter(enqueued_in_block(block)).count == (expected_count || 1)
end
supports_block_expectations?() click to toggle source
# File lib/rspec/enqueue_sidekiq_job.rb, line 101
def supports_block_expectations?
  true
end
supports_value_expectations?() click to toggle source
# File lib/rspec/enqueue_sidekiq_job.rb, line 105
def supports_value_expectations?
  false
end
times() click to toggle source
# File lib/rspec/enqueue_sidekiq_job.rb, line 60
def times
  self
end
twice() click to toggle source
# File lib/rspec/enqueue_sidekiq_job.rb, line 69
def twice
  exactly(2).times
end
with(*expected_arguments) click to toggle source
# File lib/rspec/enqueue_sidekiq_job.rb, line 37
def with(*expected_arguments)
  if expected_arguments.last.is_a?(Hash)
    options = expected_arguments.pop
    expected_arguments.push(options.with_indifferent_access)
  end
  @expected_arguments = expected_arguments
  self
end

Private Instance Methods

enqueued_in_block(block) click to toggle source
# File lib/rspec/enqueue_sidekiq_job.rb, line 111
def enqueued_in_block(block)
  before = @worker_class.jobs.dup
  block.call
  @worker_class.jobs - before
end
filter(jobs) click to toggle source
# File lib/rspec/enqueue_sidekiq_job.rb, line 117
def filter(jobs)
  jobs = jobs.select { |job| timestamps_match_rounded_to_seconds?(job['at']) } if expected_at
  jobs = jobs.select { |job| intervals_match_rounded_to_seconds?(job['at']) } if expected_in
  jobs = jobs.select { |job| values_match?(expected_arguments, job['args']) } if expected_arguments
  jobs
end
intervals_match_rounded_to_seconds?(actual) click to toggle source
# File lib/rspec/enqueue_sidekiq_job.rb, line 136
def intervals_match_rounded_to_seconds?(actual)
  return false if actual.nil?

  actual_time = Time.at(actual)
  expected_in.from_now.to_i == actual_time.to_i
end
timestamps_match_rounded_to_seconds?(actual) click to toggle source

Due to zero nsec precision of `Time.now` (and therefore `5.minutes.from_now`) on some platforms, and lossy Sidekiq serialization that uses `.to_f` on timestamps, values won't match unless rounded. Rounding to whole seconds is sub-optimal but simple.

# File lib/rspec/enqueue_sidekiq_job.rb, line 128
def timestamps_match_rounded_to_seconds?(actual)
  return false if actual.nil?

  actual_time = Time.at(actual)
  values_match?(expected_at, actual_time) ||
    expected_at.to_i == actual_time.to_i
end