Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "immediately" matcher #210

Merged
merged 3 commits into from
Sep 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ expect(AwesomeJob).to have_enqueued_sidekiq_job(hash_excluding("bad_stuff" => an

#### Testing scheduled jobs

*Use chainable matchers `#at` and `#in`*
*Use chainable matchers `#at`, `#in` and `#immediately`*

```ruby
time = 5.minutes.from_now
Expand All @@ -113,6 +113,13 @@ AwesomeJob.perform_in 5.minutes, 'Awesome', true
expect(AwesomeJob).to have_enqueued_sidekiq_job('Awesome', true).in(5.minutes)
```

```ruby
# Job scheduled for a date in the past are enqueued immediately.
AwesomeJob.perform_later 5.minutes.ago, 'Awesome', true # equivalent to: AwesomeJob.perform_async 'Awesome', true
# test with...
expect(AwesomeJob).to have_enqueued_sidekiq_job('Awesome', true).immediately
```

#### Testing queue set for job

Use the chainable `#on` matcher
Expand Down
7 changes: 6 additions & 1 deletion lib/rspec/sidekiq/matchers/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def matches?(options)
private

def at_evaluator(value)
return false if job["at"].to_s.empty?
return value.nil? if job["at"].to_s.empty?
value == Time.at(job["at"]).to_i
end

Expand Down Expand Up @@ -185,6 +185,11 @@ def in(interval)
self
end

def immediately
@expected_options["at"] = nil
self
end

def on(queue)
@expected_options["queue"] = queue
self
Expand Down
7 changes: 6 additions & 1 deletion lib/rspec/sidekiq/matchers/enqueue_sidekiq_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def supports_block_expectations?
#
# Passes if a Job is enqueued as the result of a block. Chainable `with`
# for arguments, `on` for queue, `at` for queued for a specific time, and
# `in` for a specific interval delay to being queued
# `in` for a specific interval delay to being queued, `immediately` for queued without delay.
#
# @example
#
Expand All @@ -79,6 +79,11 @@ def supports_block_expectations?
# freeze_time do
# expect { AwesomeJob.perform_in(1.hour) }.to enqueue_sidekiq_job.in(1.hour)
# end
#
# # Without any delay
# expect { AwesomeJob.perform_async }.to enqueue_sidekiq_job.immediately
# expect { AwesomeJob.perform_at(1.hour.ago) }.to enqueue_sidekiq_job.immediately
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙇 Thanks for adding the docs too.


def enqueue_sidekiq_job(job_class = nil)
EnqueueSidekiqJob.new(job_class)
end
Expand Down
20 changes: 20 additions & 0 deletions spec/rspec/sidekiq/matchers/enqueue_sidekiq_job_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,26 @@
end
end

context "immediately" do
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😻 Great!

it "passes if the job is enqueued immediately" do
expect { worker.perform_async }.to enqueue_sidekiq_job.immediately
expect { worker.perform_at(1.hour.ago) }.to enqueue_sidekiq_job.immediately
end

it "fails if the job is scheduled" do
specific_time = 1.hour.from_now
expect do
expect { worker.perform_at(specific_time) }.to enqueue_sidekiq_job.immediately
end.to raise_error { |error|
lines = error.message.split("\n")
expect(lines).to include(
match(/expected to have an enqueued .* job/),
match(/-{"at"=>nil}/)
)
}
end
end

describe "chainable" do
it "can chain expectations on the job" do
specific_time = 1.hour.from_now
Expand Down
29 changes: 29 additions & 0 deletions spec/rspec/sidekiq/matchers/have_enqueued_sidekiq_job_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

RSpec.describe RSpec::Sidekiq::Matchers::HaveEnqueuedSidekiqJob do
let(:tomorrow) { DateTime.now + 1 }
let(:yesterday) { DateTime.now - 1 }
let(:interval) { 3.minutes }
let(:argument_subject) { described_class.new worker_args }
let(:matcher_subject) { described_class.new [be_a(String), be_a(Integer), true, be_a(Hash)] }
Expand Down Expand Up @@ -223,6 +224,20 @@
expect(matcher_subject.at(tomorrow + 1).matches? worker).to be false
end
end

context 'and past timestamp matches' do
it 'returns true' do
worker.perform_at(yesterday, *worker_args)
expect(matcher_subject.immediately.matches? worker).to be true
end
end

context 'and past timestamp does not match' do
it 'returns true' do
worker.perform_at(tomorrow, *worker_args)
expect(matcher_subject.immediately.matches? worker).to be false
end
end
end

context 'with #perform_in' do
Expand All @@ -239,6 +254,20 @@
expect(matcher_subject.in(interval + 1.minute).matches? worker).to be false
end
end

context 'and past interval matches' do
it 'returns true' do
worker.perform_in(-1, *worker_args)
expect(matcher_subject.immediately.matches? worker).to be true
end
end

context 'and interval does not match' do
it 'returns false' do
worker.perform_in(1, *worker_args)
expect(matcher_subject.immediately.matches? worker).to be false
end
end
end
end
end
Expand Down