Skip to content

Commit e0b14e7

Browse files
author
Joel Lubrano
committed
Refactor HaveEnqueuedMail matcher to be a subclass of the HaveEnqueuedJob matcher
Implementing as a subclass resulted in DRYer code IMO. There was no longer a need to reimplement once, twice, thrice and other duplicated methods that were basically just delegating to the job_matcher instance variable anyways.
1 parent 1e89f41 commit e0b14e7

File tree

2 files changed

+21
-68
lines changed

2 files changed

+21
-68
lines changed

lib/rspec/rails/matchers/active_job.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ module ActiveJob
1111
# rubocop: disable Style/ClassLength
1212
# @private
1313
class Base < RSpec::Matchers::BuiltIn::BaseMatcher
14-
attr_reader :matching_jobs, :unmatching_jobs
15-
1614
def initialize
1715
@args = []
1816
@queue = nil

lib/rspec/rails/matchers/have_enqueued_mail.rb

Lines changed: 21 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -9,65 +9,30 @@ module Matchers
99
# rubocop: disable Style/ClassLength
1010
# @private
1111
# @see RSpec::Rails::Matchers#have_enqueued_mail
12-
class HaveEnqueuedMail < RSpec::Matchers::BuiltIn::BaseMatcher
12+
class HaveEnqueuedMail < ActiveJob::HaveEnqueuedJob
1313
include RSpec::Mocks::ExampleMethods
1414

1515
def initialize(mailer_class, method_name)
16+
super(mailer_job)
1617
@mailer_class = mailer_class
1718
@method_name = method_name
18-
@args = []
19-
@at = nil
20-
@queue = nil
21-
@job_matcher = ActiveJob::HaveEnqueuedJob.new(ActionMailer::DeliveryJob)
22-
set_expected_count(:exactly, 1)
19+
@mail_args = []
20+
@args = mailer_args
2321
end
2422

2523
def description
2624
"enqueues #{@mailer_class.name}.#{@method_name}"
2725
end
2826

29-
def matches?(block)
30-
raise ArgumentError, 'have_enqueued_mail and enqueue_mail only work with block arguments' unless block.respond_to?(:call)
31-
check_active_job_adapter
32-
33-
@job_matcher.with(*mailer_args)
34-
@job_matcher.matches?(block)
35-
end
36-
3727
def with(*args)
38-
@args = args
39-
self
40-
end
41-
42-
def at(send_time)
43-
@at = send_time
44-
@job_matcher.at(send_time)
45-
self
46-
end
47-
48-
def on_queue(queue)
49-
@queue = queue
50-
@job_matcher.on_queue(queue)
51-
self
52-
end
53-
54-
[:exactly, :at_least, :at_most].each do |method|
55-
define_method(method) do |count|
56-
@job_matcher.public_send(method, count)
57-
set_expected_count(method, count)
58-
self
59-
end
28+
@mail_args = args
29+
super(*mailer_args)
6030
end
6131

62-
[:once, :twice, :thrice].each do |method|
63-
define_method(method) do
64-
@job_matcher.public_send(method)
65-
exactly(method)
66-
end
67-
end
68-
69-
def times
70-
self
32+
def matches?(block)
33+
raise ArgumentError, 'have_enqueued_mail and enqueue_mail only work with block arguments' unless block.respond_to?(:call)
34+
check_active_job_adapter
35+
super
7136
end
7237

7338
def failure_message
@@ -80,31 +45,27 @@ def failure_message_when_negated
8045
"expected not to enqueue #{base_message}"
8146
end
8247

83-
def supports_block_expectations?
84-
true
85-
end
86-
8748
private
8849

8950
def base_message
9051
"#{@mailer_class.name}.#{@method_name}".tap do |msg|
9152
msg << " #{expected_count_message}"
92-
msg << " with #{@args}," if @args.any?
53+
msg << " with #{@mail_args}," if @mail_args.any?
9354
msg << " on queue #{@queue}," if @queue
9455
msg << " at #{@at.inspect}," if @at
95-
msg << " but enqueued #{@job_matcher.matching_jobs.size}"
56+
msg << " but enqueued #{@matching_jobs.size}"
9657
end
9758
end
9859

9960
def expected_count_message
100-
"#{@expected_count_type.to_s.tr('_', ' ')} #{@expected_count} #{@expected_count == 1 ? 'time' : 'times'}"
61+
"#{message_expectation_modifier} #{@expected_number} #{@expected_number == 1 ? 'time' : 'times'}"
10162
end
10263

10364
def mailer_args
10465
base_args = [@mailer_class.name, @method_name.to_s, 'deliver_now']
10566

106-
if @args.any?
107-
base_args + @args
67+
if @mail_args.any?
68+
base_args + @mail_args
10869
else
10970
mailer_method_arity = @mailer_class.instance_method(@method_name).arity
11071

@@ -123,19 +84,9 @@ def check_active_job_adapter
12384
raise StandardError, "To use HaveEnqueuedMail matcher set `ActiveJob::Base.queue_adapter = :test`"
12485
end
12586

126-
def set_expected_count(relativity, count)
127-
@expected_count_type = relativity
128-
@expected_count = case count
129-
when :once then 1
130-
when :twice then 2
131-
when :thrice then 3
132-
else Integer(count)
133-
end
134-
end
135-
13687
def unmatching_mail_jobs
137-
@job_matcher.unmatching_jobs.select do |job|
138-
job[:job] == ActionMailer::DeliveryJob
88+
@unmatching_jobs.select do |job|
89+
job[:job] == mailer_job
13990
end
14091
end
14192

@@ -160,6 +111,10 @@ def mail_job_message(job)
160111

161112
"#{mailer_method} #{msg_parts.join(', ')}".strip
162113
end
114+
115+
def mailer_job
116+
ActionMailer::DeliveryJob
117+
end
163118
end
164119
# rubocop: enable Style/ClassLength
165120

0 commit comments

Comments
 (0)