Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
7 changes: 7 additions & 0 deletions lib/rspec/rails/matchers/active_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ def arguments_match?(job)
end

def detect_args_signature_mismatch(jobs)
return if skip_signature_verification?

jobs.each do |job|
args = deserialize_arguments(job)

Expand All @@ -189,6 +191,11 @@ def detect_args_signature_mismatch(jobs)
nil
end

def skip_signature_verification?
!RSpec::Mocks.configuration.verify_partial_doubles? ||
RSpec::Mocks.configuration.temporarily_suppress_partial_double_verification
end

def check_args_signature_mismatch(job_class, job_method, args)
signature = Support::MethodSignature.new(job_class.public_instance_method(job_method))
verifier = Support::StrictSignatureVerifier.new(signature, args)
Expand Down
1 change: 1 addition & 0 deletions lib/rspec/rails/matchers/have_enqueued_mail.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ def arguments_match?(job)

def detect_args_signature_mismatch(jobs)
return if @method_name.nil?
return if skip_signature_verification?

mailer_class = mailer_class_name.constantize

Expand Down
88 changes: 66 additions & 22 deletions spec/rspec/rails/matchers/active_job_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require "rspec/rails/feature_check"
require "support/temporary_assignment"

if RSpec::Rails::FeatureCheck.has_active_job?
require "rspec/rails/matchers/active_job"
Expand Down Expand Up @@ -34,6 +35,7 @@ def self.find(_id)

RSpec.describe "ActiveJob matchers", skip: !RSpec::Rails::FeatureCheck.has_active_job? do
include ActiveSupport::Testing::TimeHelpers
include TemporaryAssignment

around do |example|
original_logger = ActiveJob::Base.logger
Expand Down Expand Up @@ -372,20 +374,40 @@ def perform; raise StandardError; end
}.to have_enqueued_job.with(42, "David")
end

it "fails if the arguments do not match the job's signature" do
expect {
describe "verifying the arguments passed match the job's signature" do
it "fails if there is an arity mismatch" do
expect {
two_args_job.perform_later(1)
}.to have_enqueued_job.with(1)
}.to fail_with(/Incorrect arguments passed to TwoArgsJob: Wrong number of arguments/)
end
expect {
two_args_job.perform_later(1)
}.to have_enqueued_job.with(1)
}.to fail_with(/Incorrect arguments passed to TwoArgsJob: Wrong number of arguments/)
end

it "fails if the job's signature/arguments are mismatched keyword/positional arguments" do
expect {
it "fails if there is a keyword/positional arguments mismatch" do
expect {
keyword_args_job.perform_later(1, 2)
}.to have_enqueued_job.with(1, 2)
}.to fail_with(/Incorrect arguments passed to KeywordArgsJob: Missing required keyword arguments/)
expect {
keyword_args_job.perform_later(1, 2)
}.to have_enqueued_job.with(1, 2)
}.to fail_with(/Incorrect arguments passed to KeywordArgsJob: Missing required keyword arguments/)
end

context "with partial double verification disabled" do
it "skips signature checks" do
with_temporary_assignment(RSpec::Mocks.configuration, :verify_partial_doubles, false) {
expect { two_args_job.perform_later(1) }.to have_enqueued_job.with(1)
}
end
end

context "when partial double verification is temporarily suspended" do
it "skips signature checks" do
without_partial_double_verification {
expect {
two_args_job.perform_later(1)
}.to have_enqueued_job.with(1)
}
end
end
end

it "passes with provided arguments containing global id object" do
Expand Down Expand Up @@ -521,20 +543,42 @@ def perform; raise StandardError; end
}.to fail_with(/expected to enqueue exactly 1 jobs, but enqueued 0/)
end

it "fails if the arguments do not match the job's signature" do
two_args_job.perform_later(1)
describe "verifying the arguments passed match the job's signature" do
it "fails if there is an arity mismatch" do
two_args_job.perform_later(1)

expect {
expect(two_args_job).to have_been_enqueued.with(1)
}.to fail_with(/Incorrect arguments passed to TwoArgsJob: Wrong number of arguments/)
end
expect {
expect(two_args_job).to have_been_enqueued.with(1)
}.to fail_with(/Incorrect arguments passed to TwoArgsJob: Wrong number of arguments/)
end

it "fails if the job's signature/arguments are mismatched keyword/positional arguments" do
keyword_args_job.perform_later(1, 2)
it "fails if there is a keyword/positional arguments mismatch" do
keyword_args_job.perform_later(1, 2)

expect {
expect(keyword_args_job).to have_been_enqueued.with(1, 2)
}.to fail_with(/Incorrect arguments passed to KeywordArgsJob: Missing required keyword arguments/)
expect {
expect(keyword_args_job).to have_been_enqueued.with(1, 2)
}.to fail_with(/Incorrect arguments passed to KeywordArgsJob: Missing required keyword arguments/)
end

context "with partial double verification disabled" do
it "skips signature checks" do
keyword_args_job.perform_later(1, 2)

with_temporary_assignment(RSpec::Mocks.configuration, :verify_partial_doubles, false) {
expect(keyword_args_job).to have_been_enqueued.with(1, 2)
}
end
end

context "when partial double verification is temporarily suspended" do
it "skips signature checks" do
keyword_args_job.perform_later(1, 2)

without_partial_double_verification {
expect(keyword_args_job).to have_been_enqueued.with(1, 2)
}
end
end
end

it "fails when negated and several jobs enqueued" do
Expand Down
35 changes: 30 additions & 5 deletions spec/rspec/rails/matchers/have_enqueued_mail_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require "rspec/rails/feature_check"
require "support/temporary_assignment"

if RSpec::Rails::FeatureCheck.has_active_job?
require "action_mailer"
Expand Down Expand Up @@ -49,6 +50,8 @@ def test_email; end
end

RSpec.describe "HaveEnqueuedMail matchers", skip: !RSpec::Rails::FeatureCheck.has_active_job? do
include TemporaryAssignment

before do
ActiveJob::Base.queue_adapter = :test
end
Expand Down Expand Up @@ -251,12 +254,34 @@ def test_email; end
}.not_to have_enqueued_mail(TestMailer, :email_with_args).with(3, 4)
end

it "fails if the arguments do not match the mailer method's signature" do
expect {
describe "verifying the arguments passed match the mailer's signature" do
it "fails if there is a mismatch" do
expect {
TestMailer.email_with_args(1).deliver_later
}.to have_enqueued_mail(TestMailer, :email_with_args).with(1)
}.to fail_with(/Incorrect arguments passed to TestMailer: Wrong number of arguments/)
expect {
TestMailer.email_with_args(1).deliver_later
}.to have_enqueued_mail(TestMailer, :email_with_args).with(1)
}.to fail_with(/Incorrect arguments passed to TestMailer: Wrong number of arguments/)
end

context "with partial double verification disabled" do
it "skips signature checks" do
with_temporary_assignment(RSpec::Mocks.configuration, :verify_partial_doubles, false) {
expect {
TestMailer.email_with_args(1).deliver_later
}.to have_enqueued_mail(TestMailer, :email_with_args).with(1)
}
end
end

context "when partial double verification is temporarily suspended" do
it "skips signature checks" do
without_partial_double_verification {
expect {
TestMailer.email_with_args(1).deliver_later
}.to have_enqueued_mail(TestMailer, :email_with_args).with(1)
}
end
end
end

it "generates a failure message" do
Expand Down
15 changes: 15 additions & 0 deletions spec/support/temporary_assignment.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

module TemporaryAssignment
def with_temporary_assignment(assignee, attribute, temporary_value)
predicate = "#{attribute}?"
attribute_reader = assignee.respond_to?(predicate) ? predicate : attribute
attribute_writer = "#{attribute}="

original_value = assignee.public_send(attribute_reader)
assignee.public_send(attribute_writer, temporary_value)
yield
ensure
assignee.public_send(attribute_writer, original_value)
end
end