module DelayedJobSupport
  # Process all pending Delayed jobs, keeping in mind jobs could spawn new 
  # delayed job (so things might be added to the queue while processing)
  def flush_jobs(options = {})
    options[:ignore_exceptions] ||= false
    
    Delayed::Worker.new.work_off(100)
    
    unless options[:ignore_exceptions]
      Delayed::Job.all.each do |job|
        if job.last_error.present?
          throw "There was an error in a delayed job: #{job.last_error}"
        end
      end
    end
  end

  def clear_jobs
    Delayed::Job.delete_all
  end


  # expect { foo }.to enqueue_job clazz: MyJob, field1: 'foo', field2: 'bar'
  RSpec::Matchers.define :enqueue_job do |options = {}|
    match do |event_proc|
      last_job_id_before = Delayed::Job.last.id

      event_proc.call

      @jobs_created = Delayed::Job.where('id > ?', last_job_id_before)

      @jobs_created.any? do |job|
        job = job.payload_object

        match = true
        match &= (job.class == options[:clazz]) if options.key? :clazz

        options.each_pair do |k, v|
          begin
            match &= (job[k] == v)
          rescue NameError
            match = false unless k == :clazz
          end
        end

        match
      end
    end

    failure_message_for_should do |event_proc|
      "expected job to be enqueued matching #{options.inspect} (#{@jobs_created.andand.count || '???'} others enqueued)"
    end

    failure_message_for_should_not do |event_proc|
      "expected job to not be enqueued matching #{options.inspect}"
    end
  end
end

Add delayed job testing support, original credit Mat Holroyd and Rohan Mitchell, from CERES Fairfood project
Add delayed job testing support, original credit Mat Holroyd and Rohan Mitchell, from CERES Fairfood project
