require 'active_support' require 'active_support/testing/time_helpers' require 'gush' require 'json' require 'pry' ActiveJob::Base.queue_adapter = :test ActiveJob::Base.logger = nil class Prepare < Gush::Job; end class FetchFirstJob < Gush::Job; end class FetchSecondJob < Gush::Job; end class PersistFirstJob < Gush::Job; end class PersistSecondJob < Gush::Job; end class NormalizeJob < Gush::Job; end class BobJob < Gush::Job; end GUSHFILE = Pathname.new(__FILE__).parent.join("Gushfile") class TestWorkflow < Gush::Workflow def configure run Prepare run NormalizeJob run FetchFirstJob, after: Prepare run FetchSecondJob, after: Prepare, before: NormalizeJob run PersistFirstJob, after: FetchFirstJob, before: NormalizeJob end end class ParameterTestWorkflow < Gush::Workflow def configure(param, kwarg: false) run Prepare if param || kwarg end end class WaitableTestWorkflow < Gush::Workflow def configure run Prepare, wait: 5.minutes end end REDIS_URL = ENV["REDIS_URL"] || "redis://localhost:6379/12" module GushHelpers def redis @redis ||= Redis.new(url: REDIS_URL) end def perform_one job = ActiveJob::Base.queue_adapter.enqueued_jobs.first if job Gush::Worker.new.perform(*job[:args]) ActiveJob::Base.queue_adapter.performed_jobs << job ActiveJob::Base.queue_adapter.enqueued_jobs.shift end end def jobs_with_id(jobs_array) jobs_array.map {|job_name| job_with_id(job_name) } end def job_with_id(job_name) /#{job_name}|(?.*)/ end end RSpec::Matchers.define :have_jobs do |flow, jobs| match do |actual| expected = jobs.map do |job| hash_including(args: include(flow, job)) end expect(ActiveJob::Base.queue_adapter.enqueued_jobs).to match_array(expected) end failure_message do |actual| "expected queue to have #{jobs}, but instead has: #{ActiveJob::Base.queue_adapter.enqueued_jobs.map{ |j| j[:args][1]}}" end end RSpec::Matchers.define :have_no_jobs do |flow, jobs| match do |actual| expected = jobs.map do |job| hash_including(args: include(flow, job)) end expect(ActiveJob::Base.queue_adapter.enqueued_jobs).not_to match_array(expected) end failure_message do |actual| "expected queue to have no #{jobs}, but instead has: #{ActiveJob::Base.queue_adapter.enqueued_jobs.map{ |j| j[:args][1]}}" end end RSpec::Matchers.define :have_a_job_enqueued_at do |flow, job, at| expected_execution_timestamp = (Time.current.utc + at).to_i match do |actual| expected = hash_including(args: include(flow, job), at: expected_execution_timestamp) expect(ActiveJob::Base.queue_adapter.enqueued_jobs).to match_array(expected) end failure_message do |actual| "expected to have enqueued job #{job} to be executed at #{Time.current.utc + at}, but instead has: #{Time.at(enqueued_jobs.first[:at]).to_datetime.utc}" end end RSpec.configure do |config| config.include ActiveSupport::Testing::TimeHelpers config.include ActiveJob::TestHelper config.include GushHelpers config.mock_with :rspec do |mocks| mocks.verify_partial_doubles = true end config.before(:each) do clear_enqueued_jobs clear_performed_jobs Gush.configure do |c| c.redis_url = REDIS_URL c.gushfile = GUSHFILE c.locking_duration = defined?(locking_duration) ? locking_duration : 2 c.polling_interval = defined?(polling_interval) ? polling_interval : 0.3 end end config.after(:each) do clear_enqueued_jobs clear_performed_jobs redis.flushdb end end