rspec-sidekiq_pro 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +18 -4
- data/lib/rspec/sidekiq_pro/batches.rb +12 -12
- data/lib/rspec/sidekiq_pro/matchers/job_matcher.rb +115 -42
- data/lib/rspec/sidekiq_pro/matchers.rb +4 -8
- data/lib/rspec/sidekiq_pro/version.rb +1 -1
- metadata +34 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a19307da8e27eaf43f2ec679fde1ce55961ad0f61c48b01d13b086b408af6a71
|
4
|
+
data.tar.gz: 50db6bdf022a1fa024e527e7a0fa65bcbf52566a6b28e603ecf5626f4ecfa94d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c36f3fa7655fef1b047eb84b8148cd40a7eee3bf131d8966469f03bae2ce214e065d21c36088e00c170717eb737bf0265206d8ddaea4a0ca1cde307bf91c7aa2
|
7
|
+
data.tar.gz: cc0fc1156ebb0b69aa95e82c7e83f9b3079a6b80fe7a7b920f026a7300c66661f9aaee440a566de5ca91a9e7b1463bc3b2e42482fc01b73a1efa013c347f8e9e
|
data/README.md
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
-
#
|
1
|
+
# RSpec for Sidekiq Pro
|
2
2
|
|
3
3
|
[](https://rubygems.org/gems/rspec-sidekiq_pro)
|
4
4
|
[](https://github.com/inkstak/rspec-sidekiq_pro/actions/workflows/ci.yml)
|
5
|
-
[](https://github.com/testdouble/standard)
|
6
|
+
[](https://codeclimate.com/github/inkstak/rspec-sidekiq_pro/maintainability)
|
6
7
|
[](https://codeclimate.com/github/inkstak/rspec-sidekiq_pro/test_coverage)
|
7
8
|
|
8
9
|
### Installation
|
@@ -54,7 +55,11 @@ Both matchers provide the same chainable methods:
|
|
54
55
|
* `.with`
|
55
56
|
* `.once`
|
56
57
|
* `.twice`
|
57
|
-
* `.exactly().times`
|
58
|
+
* `.exactly(n).times`
|
59
|
+
* `.more_than(n).times`
|
60
|
+
* `.less_than(n).times`
|
61
|
+
* `.at_least(n).times`
|
62
|
+
* `.at_most(n).times`
|
58
63
|
* `.in`
|
59
64
|
* `.at`
|
60
65
|
* `.within_batch`
|
@@ -102,6 +107,14 @@ it do
|
|
102
107
|
end
|
103
108
|
```
|
104
109
|
|
110
|
+
```ruby
|
111
|
+
it do
|
112
|
+
expect {
|
113
|
+
10.times { SampleJob.perform_async }
|
114
|
+
}.to enqueue_sidekiq_job(SampleJob).more_than(5).times
|
115
|
+
end
|
116
|
+
```
|
117
|
+
|
105
118
|
Be careful when checking both counts and arguments:
|
106
119
|
|
107
120
|
```ruby
|
@@ -191,9 +204,10 @@ end
|
|
191
204
|
```bash
|
192
205
|
bundle exec rspec
|
193
206
|
bundle exec rubocop
|
207
|
+
bundle exec standardrb
|
194
208
|
```
|
195
209
|
|
196
|
-
|
210
|
+
All of them can be run with:
|
197
211
|
|
198
212
|
```bash
|
199
213
|
bundle exec rake
|
@@ -86,15 +86,15 @@ module Sidekiq
|
|
86
86
|
if Sidekiq::Testing.disabled?
|
87
87
|
super
|
88
88
|
else
|
89
|
-
@bid
|
89
|
+
@bid = bid || SecureRandom.urlsafe_base64(10)
|
90
90
|
props = RSpec::SidekiqPro::Batches::Props.fetch(bid, {})
|
91
91
|
|
92
|
-
@created_at
|
92
|
+
@created_f = @created_at = props.fetch("created_at", Time.now.utc).to_f
|
93
93
|
@description = props["description"]
|
94
|
-
@parent_bid
|
95
|
-
@callbacks
|
96
|
-
@jids
|
97
|
-
@mutable
|
94
|
+
@parent_bid = props["parent"]
|
95
|
+
@callbacks = props.fetch("callbacks", {})
|
96
|
+
@jids = props.fetch("jids", [])
|
97
|
+
@mutable = props.empty?
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
@@ -179,8 +179,8 @@ module Sidekiq
|
|
179
179
|
callback.each do |target, options|
|
180
180
|
klass_name, method = target.to_s.split("#")
|
181
181
|
klass = klass_name.constantize
|
182
|
-
meth
|
183
|
-
inst
|
182
|
+
meth = method || "on_#{event}"
|
183
|
+
inst = klass.new
|
184
184
|
inst.jid = SecureRandom.hex(12) if inst.respond_to?(:jid)
|
185
185
|
inst.send(meth, status, options)
|
186
186
|
end
|
@@ -192,11 +192,11 @@ module Sidekiq
|
|
192
192
|
if Sidekiq::Testing.disabled?
|
193
193
|
super
|
194
194
|
else
|
195
|
-
@bid
|
196
|
-
@props
|
197
|
-
@pending
|
195
|
+
@bid = bid
|
196
|
+
@props = RSpec::SidekiqPro::Batches::Props.fetch(bid, {})
|
197
|
+
@pending = 0
|
198
198
|
@failures = 0
|
199
|
-
@total
|
199
|
+
@total = @props.fetch("jids", []).size
|
200
200
|
end
|
201
201
|
end
|
202
202
|
end
|
@@ -12,6 +12,10 @@ module RSpec
|
|
12
12
|
:expected_timestamp,
|
13
13
|
:expected_schedule,
|
14
14
|
:expected_count,
|
15
|
+
:expected_least_count,
|
16
|
+
:expected_most_count,
|
17
|
+
:expected_more_count,
|
18
|
+
:expected_less_count,
|
15
19
|
:expected_without_batch,
|
16
20
|
:expected_batch,
|
17
21
|
:actual_jobs
|
@@ -20,7 +24,6 @@ module RSpec
|
|
20
24
|
if block
|
21
25
|
raise ArgumentError, "setting block to `with` is not supported for this matcher" if supports_value_expectations?
|
22
26
|
raise ArgumentError, "setting arguments and block together in `with` is not supported" if expected_arguments.any?
|
23
|
-
|
24
27
|
@expected_arguments = block
|
25
28
|
else
|
26
29
|
@expected_arguments = normalize_arguments(expected_arguments)
|
@@ -41,7 +44,7 @@ module RSpec
|
|
41
44
|
raise "setting expecations with both `at` and `in` is not supported" if @expected_interval
|
42
45
|
|
43
46
|
@expected_timestamp = timestamp
|
44
|
-
@expected_schedule
|
47
|
+
@expected_schedule = timestamp.to_i
|
45
48
|
self
|
46
49
|
end
|
47
50
|
|
@@ -53,8 +56,28 @@ module RSpec
|
|
53
56
|
exactly(2)
|
54
57
|
end
|
55
58
|
|
56
|
-
def exactly(
|
57
|
-
@expected_count =
|
59
|
+
def exactly(count)
|
60
|
+
@expected_count = count
|
61
|
+
self
|
62
|
+
end
|
63
|
+
|
64
|
+
def at_least(count)
|
65
|
+
@expected_least_count = count
|
66
|
+
self
|
67
|
+
end
|
68
|
+
|
69
|
+
def at_most(count)
|
70
|
+
@expected_most_count = count
|
71
|
+
self
|
72
|
+
end
|
73
|
+
|
74
|
+
def more_than(count)
|
75
|
+
@expected_more_count = count
|
76
|
+
self
|
77
|
+
end
|
78
|
+
|
79
|
+
def less_than(count)
|
80
|
+
@expected_less_count = count
|
58
81
|
self
|
59
82
|
end
|
60
83
|
|
@@ -85,22 +108,38 @@ module RSpec
|
|
85
108
|
end
|
86
109
|
|
87
110
|
def matches?(jobs)
|
88
|
-
@actual_jobs
|
111
|
+
@actual_jobs = jobs
|
89
112
|
filtered_jobs = filter_jobs(actual_jobs)
|
90
113
|
|
91
114
|
if expected_count
|
92
115
|
filtered_jobs.count == expected_count
|
116
|
+
elsif expected_least_count
|
117
|
+
filtered_jobs.count >= expected_least_count
|
118
|
+
elsif expected_most_count
|
119
|
+
filtered_jobs.count <= expected_most_count
|
120
|
+
elsif expected_more_count
|
121
|
+
filtered_jobs.count > expected_more_count
|
122
|
+
elsif expected_less_count
|
123
|
+
filtered_jobs.count < expected_less_count
|
93
124
|
else
|
94
125
|
filtered_jobs.any?
|
95
126
|
end
|
96
127
|
end
|
97
128
|
|
98
129
|
def does_not_match?(jobs)
|
99
|
-
@actual_jobs
|
130
|
+
@actual_jobs = jobs
|
100
131
|
filtered_jobs = filter_jobs(actual_jobs)
|
101
132
|
|
102
133
|
if expected_count
|
103
134
|
filtered_jobs.count != expected_count
|
135
|
+
elsif expected_least_count
|
136
|
+
raise ArgumentError, "ambiguous `at_least` matcher used with negative form"
|
137
|
+
elsif expected_most_count
|
138
|
+
raise ArgumentError, "ambiguous `at_most` matcher used with negative form"
|
139
|
+
elsif expected_more_count
|
140
|
+
filtered_jobs.count < expected_more_count
|
141
|
+
elsif expected_less_count
|
142
|
+
filtered_jobs.count > expected_less_count
|
104
143
|
else
|
105
144
|
filtered_jobs.empty?
|
106
145
|
end
|
@@ -123,6 +162,14 @@ module RSpec
|
|
123
162
|
description += " twice"
|
124
163
|
elsif expected_count
|
125
164
|
description += " #{expected_count} times"
|
165
|
+
elsif expected_least_count
|
166
|
+
description += " at least #{expected_least_count} times"
|
167
|
+
elsif expected_most_count
|
168
|
+
description += " at most #{expected_most_count} times"
|
169
|
+
elsif expected_more_count
|
170
|
+
description += " more than #{expected_more_count} times"
|
171
|
+
elsif expected_less_count
|
172
|
+
description += " less than #{expected_less_count} times"
|
126
173
|
end
|
127
174
|
|
128
175
|
if expected_arguments.is_a?(Proc)
|
@@ -135,45 +182,70 @@ module RSpec
|
|
135
182
|
end
|
136
183
|
|
137
184
|
def failure_message_diff
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
185
|
+
message = []
|
186
|
+
message += expectations_in_failure_message
|
187
|
+
message << "" if message.any?
|
188
|
+
message << actual_jobs_size_in_failure_message
|
189
|
+
|
190
|
+
if expected_arguments || expected_schedule || expected_without_batch || expected_batch
|
191
|
+
message[-1] = "#{message[-1]}:"
|
192
|
+
message += actual_jobs_details_in_failure_message
|
193
|
+
end
|
194
|
+
|
195
|
+
message.join("\n")
|
196
|
+
end
|
146
197
|
|
198
|
+
def actual_jobs_size_in_failure_message
|
147
199
|
if actual_jobs.empty?
|
148
|
-
|
149
|
-
elsif !expected_arguments && !expected_schedule && !expected_without_batch && !expected_batch
|
150
|
-
diff << "found #{actual_jobs.size} #{worker_class}"
|
200
|
+
"no #{worker_class} found"
|
151
201
|
else
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
202
|
+
"found #{actual_jobs.size} #{worker_class}"
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
# rubocop:disable Layout/ExtraSpacing
|
207
|
+
# It becomes unreadable when not allowing alignement
|
208
|
+
def expectations_in_failure_message
|
209
|
+
message = []
|
210
|
+
message << " exactly: #{expected_count} time(s)" if expected_count
|
211
|
+
message << " at least: #{expected_least_count} time(s)" if expected_least_count
|
212
|
+
message << " at most: #{expected_most_count} time(s)" if expected_most_count
|
213
|
+
message << " more than: #{expected_more_count} time(s)" if expected_more_count
|
214
|
+
message << " less than: #{expected_less_count} time(s)" if expected_less_count
|
215
|
+
message << " arguments: #{expected_arguments}" if expected_arguments
|
216
|
+
message << " in: #{expected_interval_output}" if expected_interval
|
217
|
+
message << " at: #{expected_timestamp}" if expected_timestamp
|
218
|
+
message << " batch: #{output_batch(expected_batch)}" if expected_batch
|
219
|
+
message << " batch: no batch" if expected_without_batch
|
220
|
+
message
|
221
|
+
end
|
222
|
+
|
223
|
+
def job_details_in_failure_message(job)
|
224
|
+
message = []
|
225
|
+
message << " arguments: #{job["args"]}" if expected_arguments
|
226
|
+
message << " at: #{output_schedule(job["at"])}" if expected_schedule && job["at"]
|
227
|
+
message << " at: no schedule" if expected_schedule && !job["at"]
|
228
|
+
message << " batch: #{output_batch(job["bid"])}" if (expected_without_batch || expected_batch) && job["bid"]
|
229
|
+
message << " batch: no batch" if (expected_without_batch || expected_batch) && !job["bid"]
|
230
|
+
message
|
231
|
+
end
|
232
|
+
|
233
|
+
def actual_jobs_details_in_failure_message
|
234
|
+
actual_jobs.flat_map do |job|
|
235
|
+
job_details_in_failure_message(job).map.with_index do |line, index|
|
236
|
+
if actual_jobs.size > 1
|
237
|
+
indent = " "
|
238
|
+
indent = " - " if index.zero?
|
239
|
+
line = "#{indent}#{line[2..]}"
|
170
240
|
end
|
241
|
+
|
242
|
+
line
|
171
243
|
end
|
172
244
|
end
|
173
|
-
|
174
|
-
diff.join("\n")
|
175
245
|
end
|
176
246
|
|
247
|
+
# rubocop:enable Layout/ExtraSpacing
|
248
|
+
|
177
249
|
def expected_interval_output
|
178
250
|
"#{expected_interval.inspect} (#{output_schedule(expected_schedule)})"
|
179
251
|
end
|
@@ -184,9 +256,12 @@ module RSpec
|
|
184
256
|
|
185
257
|
def output_batch(value)
|
186
258
|
case value
|
187
|
-
when :__undef__
|
188
|
-
|
189
|
-
when
|
259
|
+
when :__undef__
|
260
|
+
"to be present"
|
261
|
+
when String
|
262
|
+
"<Sidekiq::Batch bid: #{value.inspect}>"
|
263
|
+
when Sidekiq::Batch
|
264
|
+
"<Sidekiq::Batch bid: #{value.bid.inspect}>"
|
190
265
|
else
|
191
266
|
if value.respond_to?(:description)
|
192
267
|
value.description
|
@@ -213,10 +288,8 @@ module RSpec
|
|
213
288
|
!bid.nil?
|
214
289
|
when String
|
215
290
|
expected_batch == bid
|
216
|
-
|
217
291
|
when ::Sidekiq::Batch
|
218
292
|
expected_batch.bid == bid
|
219
|
-
|
220
293
|
else
|
221
294
|
return unless bid
|
222
295
|
|
@@ -18,13 +18,11 @@ module RSpec
|
|
18
18
|
# expect(AwesomeWorker).to have_enqueued_sidekiq_job.in(5.minutes)
|
19
19
|
#
|
20
20
|
def have_enqueued_sidekiq_job
|
21
|
-
HaveEnqueuedSidekiqJobs.new.once
|
22
|
-
end
|
23
|
-
|
24
|
-
def have_enqueued_sidekiq_jobs
|
25
21
|
HaveEnqueuedSidekiqJobs.new
|
26
22
|
end
|
27
23
|
|
24
|
+
alias_method :have_enqueued_sidekiq_jobs, :have_enqueued_sidekiq_job
|
25
|
+
|
28
26
|
# Checks if a certain job was enqueued in a block.
|
29
27
|
#
|
30
28
|
# expect { AwesomeWorker.perform_async }
|
@@ -37,12 +35,10 @@ module RSpec
|
|
37
35
|
# .to enqueue_sidekiq_job(AwesomeWorker).in(5.minutes)
|
38
36
|
#
|
39
37
|
def enqueue_sidekiq_job(worker_class)
|
40
|
-
EnqueueSidekiqJobs.new(worker_class).once
|
41
|
-
end
|
42
|
-
|
43
|
-
def enqueue_sidekiq_jobs(worker_class)
|
44
38
|
EnqueueSidekiqJobs.new(worker_class)
|
45
39
|
end
|
40
|
+
|
41
|
+
alias_method :enqueue_sidekiq_jobs, :enqueue_sidekiq_job
|
46
42
|
end
|
47
43
|
end
|
48
44
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-sidekiq_pro
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Savater Sebastien
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-05-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -48,31 +48,57 @@ dependencies:
|
|
48
48
|
name: sidekiq
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
50
50
|
requirements:
|
51
|
-
- - "
|
51
|
+
- - ">="
|
52
52
|
- !ruby/object:Gem::Version
|
53
53
|
version: '6.5'
|
54
|
+
- - "<"
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '8'
|
54
57
|
type: :runtime
|
55
58
|
prerelease: false
|
56
59
|
version_requirements: !ruby/object:Gem::Requirement
|
57
60
|
requirements:
|
58
|
-
- - "
|
61
|
+
- - ">="
|
59
62
|
- !ruby/object:Gem::Version
|
60
63
|
version: '6.5'
|
64
|
+
- - "<"
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '8'
|
61
67
|
- !ruby/object:Gem::Dependency
|
62
68
|
name: sidekiq-pro
|
63
69
|
requirement: !ruby/object:Gem::Requirement
|
64
70
|
requirements:
|
65
|
-
- - "
|
71
|
+
- - ">="
|
66
72
|
- !ruby/object:Gem::Version
|
67
73
|
version: '5.5'
|
74
|
+
- - "<"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '8'
|
68
77
|
type: :runtime
|
69
78
|
prerelease: false
|
70
79
|
version_requirements: !ruby/object:Gem::Requirement
|
71
80
|
requirements:
|
72
|
-
- - "
|
81
|
+
- - ">="
|
73
82
|
- !ruby/object:Gem::Version
|
74
83
|
version: '5.5'
|
75
|
-
|
84
|
+
- - "<"
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '8'
|
87
|
+
- !ruby/object:Gem::Dependency
|
88
|
+
name: zeitwerk
|
89
|
+
requirement: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - "~>"
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '2.6'
|
94
|
+
type: :runtime
|
95
|
+
prerelease: false
|
96
|
+
version_requirements: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - "~>"
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '2.6'
|
101
|
+
description: A collection of RSpec matchers for Sidekiq Pro
|
76
102
|
email: github.60k5k@simplelogin.co
|
77
103
|
executables: []
|
78
104
|
extensions: []
|
@@ -109,5 +135,5 @@ requirements: []
|
|
109
135
|
rubygems_version: 3.3.7
|
110
136
|
signing_key:
|
111
137
|
specification_version: 4
|
112
|
-
summary: A collection of
|
138
|
+
summary: A collection of RSpec matchers for Sidekiq Pro
|
113
139
|
test_files: []
|