1
1
require "active_job/base"
2
+ require "active_job/arguments"
2
3
3
4
module RSpec
4
5
module Rails
@@ -11,23 +12,45 @@ module ActiveJob
11
12
class HaveEnqueuedJob < RSpec ::Matchers ::BuiltIn ::BaseMatcher
12
13
def initialize ( job )
13
14
@job = job
15
+ @args = [ ]
16
+ @queue = nil
17
+ @at = nil
14
18
set_expected_number ( :exactly , 1 )
15
19
end
16
20
17
21
def matches? ( proc )
18
22
raise ArgumentError , "have_enqueued_jobs only supports block expectations" unless Proc === proc
19
23
20
- before_block_jobs_size = enqueued_jobs_size ( @job )
24
+ original_enqueued_jobs_count = queue_adapter . enqueued_jobs . count
21
25
proc . call
22
- @in_block_jobs_size = enqueued_jobs_size ( @job ) - before_block_jobs_size
26
+ in_block_jobs = queue_adapter . enqueued_jobs . drop ( original_enqueued_jobs_count )
27
+
28
+ @matching_jobs_count = in_block_jobs . count do |job |
29
+ serialized_attributes . all? { |key , value | value == job [ key ] }
30
+ end
23
31
24
32
case @expectation_type
25
- when :exactly then @expected_number == @in_block_jobs_size
26
- when :at_most then @expected_number >= @in_block_jobs_size
27
- when :at_least then @expected_number <= @in_block_jobs_size
33
+ when :exactly then @expected_number == @matching_jobs_count
34
+ when :at_most then @expected_number >= @matching_jobs_count
35
+ when :at_least then @expected_number <= @matching_jobs_count
28
36
end
29
37
end
30
38
39
+ def with ( *args )
40
+ @args = args
41
+ self
42
+ end
43
+
44
+ def on_queue ( queue )
45
+ @queue = queue
46
+ self
47
+ end
48
+
49
+ def at ( date )
50
+ @at = date
51
+ self
52
+ end
53
+
31
54
def exactly ( count )
32
55
set_expected_number ( :exactly , count )
33
56
self
@@ -48,11 +71,11 @@ def times
48
71
end
49
72
50
73
def failure_message
51
- "expected to enqueue #{ message_expectation_modifier } #{ @expected_number } jobs, but enqueued #{ @in_block_jobs_size } "
74
+ "expected to enqueue #{ base_message } "
52
75
end
53
76
54
77
def failure_message_when_negated
55
- "expected not to enqueue #{ message_expectation_modifier } #{ @expected_number } jobs, but enqueued #{ @in_block_jobs_size } "
78
+ "expected not to enqueue #{ base_message } "
56
79
end
57
80
58
81
def message_expectation_modifier
@@ -69,11 +92,21 @@ def supports_block_expectations?
69
92
70
93
private
71
94
72
- def enqueued_jobs_size ( job )
73
- if job
74
- queue_adapter . enqueued_jobs . count { |enqueued_job | job == enqueued_job . fetch ( :job ) }
75
- else
76
- queue_adapter . enqueued_jobs . count
95
+ def base_message
96
+ "#{ message_expectation_modifier } #{ @expected_number } jobs," . tap do |msg |
97
+ msg << " with #{ @args } ," if @args . any?
98
+ msg << " on queue #{ @queue } ," if @queue
99
+ msg << " at #{ @at } ," if @at
100
+ msg << " but enqueued #{ @matching_jobs_count } "
101
+ end
102
+ end
103
+
104
+ def serialized_attributes
105
+ { } . tap do |attributes |
106
+ attributes [ :args ] = ::ActiveJob ::Arguments . serialize ( @args ) if @args . any?
107
+ attributes [ :at ] = @at . to_f if @at
108
+ attributes [ :queue ] = @queue if @queue
109
+ attributes [ :job ] = @job if @job
77
110
end
78
111
end
79
112
@@ -120,6 +153,10 @@ def queue_adapter
120
153
# HelloJob.perform_later
121
154
# HeavyLiftingJob.perform_later
122
155
# }.to have_enqueued_job(HelloJob).and have_enqueued_job(HeavyLiftingJob)
156
+ #
157
+ # expect {
158
+ # HelloJob.set(wait_until: Date.tomorrow.noon, queue: "low").perform_later(42)
159
+ # }.to have_enqueued_job.with(42).on_queue("low").at(Date.tomorrow.noon)
123
160
def have_enqueued_job ( job = nil )
124
161
ActiveJob ::HaveEnqueuedJob . new ( job )
125
162
end
0 commit comments