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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c0209fc3fe2a82f7cd7355cd0514da771926c8557b68fd4ea23680d0b5cc95e6
4
- data.tar.gz: bea903392cd28942099eb2b70e6ee0111df93842c569d7a5ccba113e4e9fdb4f
3
+ metadata.gz: a19307da8e27eaf43f2ec679fde1ce55961ad0f61c48b01d13b086b408af6a71
4
+ data.tar.gz: 50db6bdf022a1fa024e527e7a0fa65bcbf52566a6b28e603ecf5626f4ecfa94d
5
5
  SHA512:
6
- metadata.gz: fddfe519ba229d75f3c6bcd1f1a68eade0e7c23babb04ebe377484a3704857bb47feb12d6f9de213cdf0fe9a037b874bfb78692c5a69359f5cf270bb0a28f020
7
- data.tar.gz: f1177195cf806d86619f027255619fdd5b47f370aba696a4d3931cccf8498197f758895c7fb7cee1a10320fe5cea94d48cc7e044a7250d9a767bcfd5252c0d2a
6
+ metadata.gz: c36f3fa7655fef1b047eb84b8148cd40a7eee3bf131d8966469f03bae2ce214e065d21c36088e00c170717eb737bf0265206d8ddaea4a0ca1cde307bf91c7aa2
7
+ data.tar.gz: cc0fc1156ebb0b69aa95e82c7e83f9b3079a6b80fe7a7b920f026a7300c66661f9aaee440a566de5ca91a9e7b1463bc3b2e42482fc01b73a1efa013c347f8e9e
data/README.md CHANGED
@@ -1,8 +1,9 @@
1
- # Rspec for Sidekiq Pro
1
+ # RSpec for Sidekiq Pro
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/rspec-sidekiq_pro.svg)](https://rubygems.org/gems/rspec-sidekiq_pro)
4
4
  [![CI Status](https://github.com/inkstak/rspec-sidekiq_pro/actions/workflows/ci.yml/badge.svg)](https://github.com/inkstak/rspec-sidekiq_pro/actions/workflows/ci.yml)
5
- [![Maintainability](https://api.codeclimate.com/v1/badges/9bb8b75ea8c66b1a9c94/maintainability)](https://codeclimate.com/github/inkstak/rspec-sidekiq_pro/maintainability)
5
+ [![Ruby Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://github.com/testdouble/standard)
6
+ [![Maintainability](https://api.codeclimate.com/v1/badges/3de8ad4b1787cdb9ca20/maintainability)](https://codeclimate.com/github/inkstak/rspec-sidekiq_pro/maintainability)
6
7
  [![Test Coverage](https://api.codeclimate.com/v1/badges/3de8ad4b1787cdb9ca20/test_coverage)](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
- Both can be run with:
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 = bid || SecureRandom.urlsafe_base64(10)
89
+ @bid = bid || SecureRandom.urlsafe_base64(10)
90
90
  props = RSpec::SidekiqPro::Batches::Props.fetch(bid, {})
91
91
 
92
- @created_at = props.fetch("created_at", Time.now.utc).to_f
92
+ @created_f = @created_at = props.fetch("created_at", Time.now.utc).to_f
93
93
  @description = props["description"]
94
- @parent_bid = props["parent"]
95
- @callbacks = props.fetch("callbacks", {})
96
- @jids = props.fetch("jids", [])
97
- @mutable = props.empty?
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 = method || "on_#{event}"
183
- inst = klass.new
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 = bid
196
- @props = RSpec::SidekiqPro::Batches::Props.fetch(bid, {})
197
- @pending = 0
195
+ @bid = bid
196
+ @props = RSpec::SidekiqPro::Batches::Props.fetch(bid, {})
197
+ @pending = 0
198
198
  @failures = 0
199
- @total = @props.fetch("jids", []).size
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 = timestamp.to_i
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(times)
57
- @expected_count = times
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 = 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 = 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
- diff = []
139
- diff << " exactly: #{expected_count} time(s)" if expected_count
140
- diff << " arguments: #{expected_arguments}" if expected_arguments
141
- diff << " in: #{expected_interval_output}" if expected_interval
142
- diff << " at: #{expected_timestamp}" if expected_timestamp
143
- diff << " batch: #{output_batch(expected_batch)}" if expected_batch
144
- diff << " batch: no batch" if expected_without_batch
145
- diff << "" if diff.any?
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
- diff << "no #{worker_class} found"
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
- diff << "found #{actual_jobs.size} #{worker_class}:"
153
-
154
- actual_jobs.each do |job|
155
- job_message = []
156
- job_message << "arguments: #{job["args"]}" if expected_arguments
157
- job_message << "at: #{output_schedule(job["at"])}" if expected_schedule && job["at"]
158
- job_message << "at: no schedule" if expected_schedule && !job["at"]
159
- job_message << "batch: #{output_batch(job["bid"])}" if (expected_without_batch || expected_batch) && job["bid"]
160
- job_message << "batch: no batch" if (expected_without_batch || expected_batch) && !job["bid"]
161
-
162
- diff += job_message.map.with_index do |line, index|
163
- if actual_jobs.size == 1
164
- " #{line}"
165
- elsif index.zero?
166
- " - #{line}"
167
- else
168
- " #{line}"
169
- end
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__ then "to be present"
188
- when String then "<Sidekiq::Batch bid: #{value.inspect}>"
189
- when Sidekiq::Batch then "<Sidekiq::Batch bid: #{value.bid.inspect}>"
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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RSpec
4
4
  module SidekiqPro
5
- VERSION = "1.0.0"
5
+ VERSION = "1.2.0"
6
6
  end
7
7
  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.0.0
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: 2022-09-22 00:00:00.000000000 Z
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
- description:
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 tools and matchers for Sidekiq Pro
138
+ summary: A collection of RSpec matchers for Sidekiq Pro
113
139
  test_files: []