Module: RSpec::SidekiqPro::Matchers::JobMatcher

Includes:
Matchers::Composable
Included in:
EnqueueSidekiqJobs, HaveEnqueuedSidekiqJobs
Defined in:
lib/rspec/sidekiq_pro/matchers/job_matcher.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#actual_jobsObject (readonly)

Returns the value of attribute actual_jobs.



9
10
11
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 9

def actual_jobs
  @actual_jobs
end

#expected_argumentsObject (readonly)

Returns the value of attribute expected_arguments.



9
10
11
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 9

def expected_arguments
  @expected_arguments
end

#expected_batchObject (readonly)

Returns the value of attribute expected_batch.



9
10
11
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 9

def expected_batch
  @expected_batch
end

#expected_countObject (readonly)

Returns the value of attribute expected_count.



9
10
11
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 9

def expected_count
  @expected_count
end

#expected_intervalObject (readonly)

Returns the value of attribute expected_interval.



9
10
11
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 9

def expected_interval
  @expected_interval
end

#expected_least_countObject (readonly)

Returns the value of attribute expected_least_count.



9
10
11
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 9

def expected_least_count
  @expected_least_count
end

#expected_less_countObject (readonly)

Returns the value of attribute expected_less_count.



9
10
11
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 9

def expected_less_count
  @expected_less_count
end

#expected_more_countObject (readonly)

Returns the value of attribute expected_more_count.



9
10
11
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 9

def expected_more_count
  @expected_more_count
end

#expected_most_countObject (readonly)

Returns the value of attribute expected_most_count.



9
10
11
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 9

def expected_most_count
  @expected_most_count
end

#expected_scheduleObject (readonly)

Returns the value of attribute expected_schedule.



9
10
11
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 9

def expected_schedule
  @expected_schedule
end

#expected_timestampObject (readonly)

Returns the value of attribute expected_timestamp.



9
10
11
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 9

def expected_timestamp
  @expected_timestamp
end

#expected_without_argumentObject (readonly)

Returns the value of attribute expected_without_argument.



9
10
11
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 9

def expected_without_argument
  @expected_without_argument
end

#expected_without_batchObject (readonly)

Returns the value of attribute expected_without_batch.



9
10
11
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 9

def expected_without_batch
  @expected_without_batch
end

#worker_classObject (readonly)

Returns the value of attribute worker_class.



9
10
11
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 9

def worker_class
  @worker_class
end

Instance Method Details

#actual_jobs_details_in_failure_messageObject



247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 247

def actual_jobs_details_in_failure_message
  actual_jobs.flat_map do |job|
    job_details_in_failure_message(job).map.with_index do |line, index|
      if actual_jobs.size > 1
        indent = "    "
        indent = "  - " if index.zero?
        line = "#{indent}#{line[2..]}"
      end

      line
    end
  end
end

#actual_jobs_size_in_failure_messageObject



210
211
212
213
214
215
216
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 210

def actual_jobs_size_in_failure_message
  if actual_jobs.empty?
    "no #{worker_class} found"
  else
    "found #{actual_jobs.size} #{worker_class}"
  end
end

#at(timestamp) ⇒ Object



53
54
55
56
57
58
59
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 53

def at(timestamp)
  raise "setting expecations with both `at` and `in` is not supported" if @expected_interval

  @expected_timestamp = timestamp
  @expected_schedule = timestamp.to_i
  self
end

#at_least(count) ⇒ Object



74
75
76
77
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 74

def at_least(count)
  @expected_least_count = count
  self
end

#at_most(count) ⇒ Object



79
80
81
82
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 79

def at_most(count)
  @expected_most_count = count
  self
end

#batch_match?(expected_batch, bid) ⇒ Boolean

Returns:

  • (Boolean)


300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 300

def batch_match?(expected_batch, bid)
  case expected_batch
  when :__undef__
    !bid.nil?
  when String
    expected_batch == bid
  when ::Sidekiq::Batch
    expected_batch.bid == bid
  else
    return unless bid

    batch = ::Sidekiq::Batch.new(bid)
    values_match?(expected_batch, batch)
  end
end

#does_not_match?(jobs) ⇒ Boolean

Returns:

  • (Boolean)


139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 139

def does_not_match?(jobs)
  @actual_jobs = jobs
  filtered_jobs = filter_jobs(actual_jobs)

  if expected_count
    filtered_jobs.count != expected_count
  elsif expected_least_count
    raise ArgumentError, "ambiguous `at_least` matcher used with negative form"
  elsif expected_most_count
    raise ArgumentError, "ambiguous `at_most` matcher used with negative form"
  elsif expected_more_count
    filtered_jobs.count < expected_more_count
  elsif expected_less_count
    filtered_jobs.count > expected_less_count
  else
    filtered_jobs.empty?
  end
end

#exactly(count) ⇒ Object



69
70
71
72
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 69

def exactly(count)
  @expected_count = count
  self
end

#expectations_in_failure_messageObject

rubocop:disable Layout/ExtraSpacing It becomes unreadable when not allowing alignement



220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 220

def expectations_in_failure_message
  message = []
  message << "  exactly:   #{expected_count} time(s)"       if expected_count
  message << "  at least:  #{expected_least_count} time(s)" if expected_least_count
  message << "  at most:   #{expected_most_count} time(s)"  if expected_most_count
  message << "  more than: #{expected_more_count} time(s)"  if expected_more_count
  message << "  less than: #{expected_less_count} time(s)"  if expected_less_count
  message << "  arguments: #{expected_arguments}"           if expected_arguments
  message << "  arguments: no arguments"                    if expected_without_argument
  message << "  in:        #{expected_interval_output}"     if expected_interval
  message << "  at:        #{expected_timestamp}"           if expected_timestamp
  message << "  batch:     #{output_batch(expected_batch)}" if expected_batch
  message << "  batch:     no batch"                        if expected_without_batch
  message
end

#expected_interval_outputObject

rubocop:enable Layout/ExtraSpacing



263
264
265
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 263

def expected_interval_output
  "#{expected_interval.inspect} (#{output_schedule(expected_schedule)})"
end

#expected_job_descriptionObject



166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 166

def expected_job_description
  description = "#{worker_class} job"

  if expected_count == 1
    description += " once"
  elsif expected_count == 2
    description += " twice"
  elsif expected_count
    description += " #{expected_count} times"
  elsif expected_least_count
    description += " at least #{expected_least_count} times"
  elsif expected_most_count
    description += " at most #{expected_most_count} times"
  elsif expected_more_count
    description += " more than #{expected_more_count} times"
  elsif expected_less_count
    description += " less than #{expected_less_count} times"
  end

  if expected_without_argument
    description += " without arguments"
  elsif expected_arguments.is_a?(Proc)
    description += " with some arguments"
  elsif expected_arguments
    description += " with arguments #{expected_arguments}"
  end

  description
end

#failure_message_diffObject



196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 196

def failure_message_diff
  message = []
  message += expectations_in_failure_message
  message << "" if message.any?
  message << actual_jobs_size_in_failure_message

  if expected_arguments || expected_without_argument || expected_schedule || expected_without_batch || expected_batch
    message[-1] = "#{message[-1]}:"
    message += actual_jobs_details_in_failure_message
  end

  message.join("\n")
end

#filter_jobs(jobs) ⇒ Object



288
289
290
291
292
293
294
295
296
297
298
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 288

def filter_jobs(jobs)
  jobs.select do |job|
    next if expected_arguments && !values_match?(expected_arguments, job["args"])
    next if expected_without_argument && job["args"].any?
    next if expected_schedule && !values_match?(expected_schedule.to_i, job["at"].to_i)
    next if expected_without_batch && job["bid"]
    next if expected_batch && !batch_match?(expected_batch, job["bid"])

    true
  end
end

#in(interval) ⇒ Object



45
46
47
48
49
50
51
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 45

def in(interval)
  raise "setting expecations with both `at` and `in` is not supported" if @expected_timestamp

  @expected_interval = interval
  @expected_schedule = interval.from_now.to_i
  self
end

#job_details_in_failure_message(job) ⇒ Object



236
237
238
239
240
241
242
243
244
245
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 236

def job_details_in_failure_message(job)
  message = []
  message << "  arguments: #{job["args"]}"                if (expected_arguments || expected_without_argument) && job["args"].any?
  message << "  arguments: no arguments"                  if (expected_arguments || expected_without_argument) && job["args"].empty?
  message << "  at:        #{output_schedule(job["at"])}" if expected_schedule && job["at"]
  message << "  at:        no schedule"                   if expected_schedule && !job["at"]
  message << "  batch:     #{output_batch(job["bid"])}"   if (expected_without_batch || expected_batch) && job["bid"]
  message << "  batch:     no batch"                      if (expected_without_batch || expected_batch) && !job["bid"]
  message
end

#less_than(count) ⇒ Object



89
90
91
92
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 89

def less_than(count)
  @expected_less_count = count
  self
end

#matches?(jobs) ⇒ Boolean

Returns:

  • (Boolean)


120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 120

def matches?(jobs)
  @actual_jobs = jobs
  filtered_jobs = filter_jobs(actual_jobs)

  if expected_count
    filtered_jobs.count == expected_count
  elsif expected_least_count
    filtered_jobs.count >= expected_least_count
  elsif expected_most_count
    filtered_jobs.count <= expected_most_count
  elsif expected_more_count
    filtered_jobs.count > expected_more_count
  elsif expected_less_count
    filtered_jobs.count < expected_less_count
  else
    filtered_jobs.any?
  end
end

#more_than(count) ⇒ Object



84
85
86
87
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 84

def more_than(count)
  @expected_more_count = count
  self
end

#normalize_arguments(arguments) ⇒ Object



158
159
160
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 158

def normalize_arguments(arguments)
  JSON.parse(JSON.dump(arguments))
end

#onceObject



61
62
63
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 61

def once
  exactly(1)
end

#output_arguments(arguments) ⇒ Object



162
163
164
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 162

def output_arguments(arguments)
  arguments.map(&:inspect).join(", ")
end

#output_batch(value) ⇒ Object



271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 271

def output_batch(value)
  case value
  when :__undef__
    "to be present"
  when String
    "<Sidekiq::Batch bid: #{value.inspect}>"
  when Sidekiq::Batch
    "<Sidekiq::Batch bid: #{value.bid.inspect}>"
  else
    if value.respond_to?(:description)
      value.description
    else
      value
    end
  end
end

#output_schedule(timestamp) ⇒ Object



267
268
269
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 267

def output_schedule(timestamp)
  Time.at(timestamp) if timestamp
end

#timesObject Also known as: time



94
95
96
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 94

def times
  self
end

#twiceObject



65
66
67
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 65

def twice
  exactly(2)
end

#with(*expected_arguments, &block) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 24

def with(*expected_arguments, &block)
  raise "setting expecations with both `with` and `without_argument` is not supported" if @expected_without_argument

  if block
    raise ArgumentError, "setting block to `with` is not supported for this matcher" if supports_value_expectations?
    raise ArgumentError, "setting arguments and block together in `with` is not supported" if expected_arguments.any?
    @expected_arguments = block
  else
    @expected_arguments = normalize_arguments(expected_arguments)
  end

  self
end

#within_batch(batch_expectation = :__undef__, &block) ⇒ Object



106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 106

def within_batch(batch_expectation = :__undef__, &block)
  raise "setting expecations with both `without_batch` and `within_batch` is not supported" if @expected_without_batch

  if block
    raise ArgumentError, "setting arguments and block together in `with_batch` is not supported" if batch_expectation != :__undef__

    @expected_batch = block
  else
    @expected_batch = batch_expectation
  end

  self
end

#without_argumentObject



38
39
40
41
42
43
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 38

def without_argument
  raise "setting expecations with both `with` and `without_argument` is not supported" if @expected_arguments

  @expected_without_argument = true
  self
end

#without_batchObject



99
100
101
102
103
104
# File 'lib/rspec/sidekiq_pro/matchers/job_matcher.rb', line 99

def without_batch
  raise "setting expecations with both `without_batch` and `within_batch` is not supported" if @expected_batch

  @expected_without_batch = true
  self
end