rspec-sidekiq_pro 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ab301b38f104fcdeda2a304b6f87f4d50e67ed15f01340b08c7d77643b35d98b
4
+ data.tar.gz: bdcf93f32eb2ec8040c286e864fa204ce01f066f88e76f6f0b5b9e61ec16cb11
5
+ SHA512:
6
+ metadata.gz: e86e8d44fcdad8b55dd826ae835fabc40b235dba13c90d471dbfef38e609d3d19a18a4ea4d6b9f65ec4c42db7a9f0690d97ad9ef582aed6303ebdad41ba5ecce
7
+ data.tar.gz: e682c9fe04fb2e49866a11af75d052d3003127e150444af0769332f983a3fe55f1f76e153db56beaca6bd4e6cb901117be42f5974016ddbcbfd17ea1780a02f6
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2022 Savater Sebastien
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,38 @@
1
+ # Rspec for Sidekiq Pro
2
+
3
+ ### Installation
4
+
5
+ ```bash
6
+ bundle add rspec-sidekiq_pro
7
+ ```
8
+
9
+ ### Usage
10
+
11
+ TODO
12
+
13
+ ## Contributing
14
+
15
+ 1. Don't hesitate to submit your feature/idea/fix in [issues](https://github.com/inkstak/rspec-sidekiq_pro)
16
+ 2. Fork the [repository](https://github.com/inkstak/rspec-sidekiq_pro)
17
+ 3. Create your feature branch
18
+ 4. Ensure RSpec & Rubocop are passing
19
+ 4. Create a pull request
20
+
21
+ ### Tests & lint
22
+
23
+ ```bash
24
+ bundle exec rspec
25
+ bundle exec rubocop
26
+ ```
27
+
28
+ Both can be run with:
29
+
30
+ ```bash
31
+ bundle exec rake
32
+ ```
33
+
34
+ ## License & credits
35
+
36
+ Please see [LICENSE](https://github.com/inkstak/rspec-sidekiq_pro/blob/main/LICENSE) for further details.
37
+
38
+ Contributors: [./graphs/contributors](https://github.com/inkstak/rspec-sidekiq_pro/graphs/contributors)
@@ -0,0 +1,204 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSpec
4
+ module SidekiqPro
5
+ module Batches
6
+ module Props
7
+ class << self
8
+ delegate :size, :first, :last, :each, :empty?, :any?, :none?, to: :batches_array
9
+ delegate :fetch, to: :batches_hash
10
+
11
+ def [](key)
12
+ if key.is_a?(Numeric)
13
+ batches_array[key]
14
+ else
15
+ batches_hash[key]
16
+ end
17
+ end
18
+
19
+ def []=(bid, batch)
20
+ batch["bid"] = bid
21
+ batches_array << batch
22
+ batches_hash[bid] = batch
23
+ end
24
+
25
+ def delete(bid)
26
+ batch = batches_hash.delete(bid)
27
+ batches_array.delete(batch)
28
+ end
29
+
30
+ def clear_all
31
+ batches_array.clear
32
+ batches_hash.clear
33
+ end
34
+
35
+ def to_a
36
+ batches_array
37
+ end
38
+
39
+ def to_h
40
+ batches_hash
41
+ end
42
+
43
+ private
44
+
45
+ def batches_array
46
+ @batches_array ||= []
47
+ end
48
+
49
+ def batches_hash
50
+ @batches_hash ||= {}
51
+ end
52
+ end
53
+ end
54
+
55
+ class << self
56
+ delegate :size, :delete, :clear_all, :empty?, :any?, :none?, to: Props
57
+ delegate_missing_to :each
58
+
59
+ def each
60
+ return to_enum(:each) unless block_given?
61
+
62
+ Props.each do |props|
63
+ yield Sidekiq::Batch.new(props["bid"])
64
+ end
65
+ end
66
+
67
+ def [](key)
68
+ Sidekiq::Batch.new(Props[key]["bid"])
69
+ end
70
+
71
+ def first
72
+ Sidekiq::Batch.new(Props.first["bid"])
73
+ end
74
+
75
+ def last
76
+ Sidekiq::Batch.new(Props.last["bid"])
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+
83
+ module Sidekiq
84
+ class Batch
85
+ def initialize(bid = nil)
86
+ if Sidekiq::Testing.disabled?
87
+ super
88
+ else
89
+ @bid = bid || SecureRandom.urlsafe_base64(10)
90
+ props = RSpec::SidekiqPro::Batches::Props.fetch(bid, {})
91
+
92
+ @created_at = props.fetch("created_at", Time.now.utc).to_f
93
+ @description = props["description"]
94
+ @parent_bid = props["parent"]
95
+ @callbacks = props.fetch("callbacks", {})
96
+ @jids = props.fetch("jids", [])
97
+ @mutable = props.empty?
98
+ end
99
+ end
100
+
101
+ def redis(bid, &block)
102
+ return super if Sidekiq::Testing.disabled?
103
+
104
+ raise "Redis unavailbale when Sidekiq::Testing is enable"
105
+ end
106
+
107
+ def jids
108
+ return super if Sidekiq::Testing.disabled?
109
+
110
+ @jids
111
+ end
112
+
113
+ def include?(jid)
114
+ return super if Sidekiq::Testing.disabled?
115
+
116
+ @jids.include?(jid)
117
+ end
118
+
119
+ def invalidate_all
120
+ return super if Sidekiq::Testing.disabled?
121
+
122
+ RSpec::SidekiqPro::Batches::Props[bid]["invalidated"] = true
123
+ Sidekiq::Queues.jobs_by_queue.each_value { |jobs| jobs.delete_if { |job| include?(job["jid"]) } }
124
+ Sidekiq::Queues.jobs_by_class.each_value { |jobs| jobs.delete_if { |job| include?(job["jid"]) } }
125
+ end
126
+
127
+ def invalidate_jids(*jids)
128
+ return super if Sidekiq::Testing.disabled?
129
+
130
+ # TODO
131
+ end
132
+
133
+ def invalidated?
134
+ return super if Sidekiq::Testing.disabled?
135
+
136
+ !!RSpec::SidekiqPro::Batches::Props[bid]["invalidated"]
137
+ end
138
+
139
+ def jobs(&block)
140
+ return super if Sidekiq::Testing.disabled?
141
+
142
+ raise ArgumentError, "Must specify a block" unless block
143
+
144
+ if mutable?
145
+ @parent_bid = Thread.current[:sidekiq_batch]&.bid
146
+
147
+ RSpec::SidekiqPro::Batches::Props[bid] = {
148
+ "created_at" => created_at,
149
+ "description" => description,
150
+ "parent" => parent_bid,
151
+ "callbacks" => callbacks,
152
+ "jids" => jids
153
+ }
154
+ end
155
+
156
+ @mutable = false
157
+
158
+ begin
159
+ parent = Thread.current[:sidekiq_batch]
160
+ Thread.current[:sidekiq_batch] = self
161
+ yield
162
+ ensure
163
+ Thread.current[:sidekiq_batch] = parent
164
+ end
165
+
166
+ RSpec::SidekiqPro::Batches::Props[bid]["jids"] = @jids
167
+ end
168
+
169
+ def register(jid)
170
+ return super if Sidekiq::Testing.disabled?
171
+
172
+ @jids << jid
173
+ end
174
+
175
+ def perform_callback(event)
176
+ raise NotImplementedError if Sidekiq::Testing.disabled?
177
+
178
+ callbacks[event.to_s]&.each do |callback|
179
+ callback.each do |target, options|
180
+ klass_name, method = target.to_s.split("#")
181
+ klass = klass_name.constantize
182
+ meth = method || "on_#{event}"
183
+ inst = klass.new
184
+ inst.jid = SecureRandom.hex(12) if inst.respond_to?(:jid)
185
+ inst.send(meth, status, options)
186
+ end
187
+ end
188
+ end
189
+
190
+ class Status
191
+ def initialize(bid)
192
+ if Sidekiq::Testing.disabled?
193
+ super
194
+ else
195
+ @bid = bid
196
+ @props = RSpec::SidekiqPro::Batches::Props.fetch(bid, {})
197
+ @pending = 0
198
+ @failures = 0
199
+ @total = @props.fetch("jids", []).size
200
+ end
201
+ end
202
+ end
203
+ end
204
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rspec/sidekiq_pro/matchers/job_matcher"
4
+
5
+ module RSpec
6
+ module SidekiqPro
7
+ module Matchers
8
+ class EnqueueSidekiqJobs
9
+ include JobMatcher
10
+
11
+ def initialize(worker_class)
12
+ @worker_class = worker_class
13
+ end
14
+
15
+ def supports_block_expectations?
16
+ true
17
+ end
18
+
19
+ def supports_value_expectations?
20
+ false
21
+ end
22
+
23
+ def matches?(block)
24
+ super(capture_actual_jobs(block))
25
+ end
26
+
27
+ def does_not_match?(block)
28
+ super(capture_actual_jobs(block))
29
+ end
30
+
31
+ def description
32
+ "enqueue #{expected_job_description}"
33
+ end
34
+
35
+ def failure_message
36
+ "expected to enqueue #{worker_class} job\n#{failure_message_diff}"
37
+ end
38
+
39
+ def failure_message_when_negated
40
+ "expected not to enqueue #{worker_class} job\n#{failure_message_diff}"
41
+ end
42
+
43
+ def capture_actual_jobs(block)
44
+ before = worker_class.jobs.dup
45
+ result = block.call
46
+
47
+ if @expected_arguments.is_a?(Proc)
48
+ arguments = @expected_arguments.call(result)
49
+ raise "arguments returned from a proc are expected to be an Array" unless arguments.is_a?(Array)
50
+
51
+ @expected_arguments = normalize_arguments(arguments)
52
+ end
53
+
54
+ worker_class.jobs - before
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rspec/sidekiq_pro/matchers/job_matcher"
4
+
5
+ module RSpec
6
+ module SidekiqPro
7
+ module Matchers
8
+ class HaveEnqueuedSidekiqJobs
9
+ include JobMatcher
10
+
11
+ def supports_block_expectations?
12
+ false
13
+ end
14
+
15
+ def supports_value_expectations?
16
+ true
17
+ end
18
+
19
+ def matches?(worker_class)
20
+ @worker_class = worker_class
21
+ super(worker_class.jobs)
22
+ end
23
+
24
+ def does_not_match?(worker_class)
25
+ @worker_class = worker_class
26
+ super(worker_class.jobs)
27
+ end
28
+
29
+ def description
30
+ "have enqueued #{expected_job_description}"
31
+ end
32
+
33
+ def failure_message
34
+ "expected to have enqueued #{worker_class} job\n#{failure_message_diff}"
35
+ end
36
+
37
+ def failure_message_when_negated
38
+ "expected not to have enqueued #{worker_class} job\n#{failure_message_diff}"
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,230 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSpec
4
+ module SidekiqPro
5
+ module Matchers
6
+ module JobMatcher
7
+ include ::RSpec::Matchers::Composable
8
+
9
+ attr_reader :worker_class,
10
+ :expected_arguments,
11
+ :expected_interval,
12
+ :expected_timestamp,
13
+ :expected_schedule,
14
+ :expected_count,
15
+ :expected_without_batch,
16
+ :expected_batch,
17
+ :actual_jobs
18
+
19
+ def with(*expected_arguments, &block)
20
+ if block
21
+ raise ArgumentError, "setting block to `with` is not supported for this matcher" if supports_value_expectations?
22
+ raise ArgumentError, "setting arguments and block together in `with` is not supported" if expected_arguments.any?
23
+
24
+ @expected_arguments = block
25
+ else
26
+ @expected_arguments = normalize_arguments(expected_arguments)
27
+ end
28
+
29
+ self
30
+ end
31
+
32
+ def in(interval)
33
+ raise "setting expecations with both `at` and `in` is not supported" if @expected_timestamp
34
+
35
+ @expected_interval = interval
36
+ @expected_schedule = interval.from_now.to_i
37
+ self
38
+ end
39
+
40
+ def at(timestamp)
41
+ raise "setting expecations with both `at` and `in` is not supported" if @expected_interval
42
+
43
+ @expected_timestamp = timestamp
44
+ @expected_schedule = timestamp.to_i
45
+ self
46
+ end
47
+
48
+ def once
49
+ exactly(1)
50
+ end
51
+
52
+ def twice
53
+ exactly(2)
54
+ end
55
+
56
+ def exactly(times)
57
+ @expected_count = times
58
+ self
59
+ end
60
+
61
+ def times
62
+ self
63
+ end
64
+ alias_method :time, :times
65
+
66
+ def without_batch
67
+ raise "setting expecations with both `without_batch` and `within_batch` is not supported" if @expected_batch
68
+
69
+ @expected_without_batch = true
70
+ self
71
+ end
72
+
73
+ def within_batch(batch_expectation = :__undef__, &block)
74
+ raise "setting expecations with both `without_batch` and `within_batch` is not supported" if @expected_without_batch
75
+
76
+ if block
77
+ raise ArgumentError, "setting arguments and block together in `with_batch` is not supported" if batch_expectation != :__undef__
78
+
79
+ @expected_batch = block
80
+ else
81
+ @expected_batch = batch_expectation
82
+ end
83
+
84
+ self
85
+ end
86
+
87
+ def matches?(jobs)
88
+ @actual_jobs = jobs
89
+ filtered_jobs = filter_jobs(actual_jobs)
90
+
91
+ if expected_count
92
+ filtered_jobs.count == expected_count
93
+ else
94
+ filtered_jobs.any?
95
+ end
96
+ end
97
+
98
+ def does_not_match?(jobs)
99
+ @actual_jobs = jobs
100
+ filtered_jobs = filter_jobs(actual_jobs)
101
+
102
+ if expected_count
103
+ filtered_jobs.count != expected_count
104
+ else
105
+ filtered_jobs.empty?
106
+ end
107
+ end
108
+
109
+ def normalize_arguments(arguments)
110
+ JSON.parse(JSON.dump(arguments))
111
+ end
112
+
113
+ def output_arguments(arguments)
114
+ arguments.map(&:inspect).join(", ")
115
+ end
116
+
117
+ def expected_job_description
118
+ description = "#{worker_class} job"
119
+
120
+ if expected_count == 1
121
+ description += " once"
122
+ elsif expected_count == 2
123
+ description += " twice"
124
+ elsif expected_count
125
+ description += " #{expected_count} times"
126
+ end
127
+
128
+ if expected_arguments.is_a?(Proc)
129
+ description += " with some arguments"
130
+ elsif expected_arguments
131
+ description += " with arguments #{expected_arguments}"
132
+ end
133
+
134
+ description
135
+ end
136
+
137
+ 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?
146
+
147
+ 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}"
151
+ 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
170
+ end
171
+ end
172
+ end
173
+
174
+ diff.join("\n")
175
+ end
176
+
177
+ def expected_interval_output
178
+ "#{expected_interval.inspect} (#{output_schedule(expected_schedule)})"
179
+ end
180
+
181
+ def output_schedule(timestamp)
182
+ Time.at(timestamp) if timestamp
183
+ end
184
+
185
+ def output_batch(value)
186
+ 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}>"
190
+ else
191
+ if value.respond_to?(:description)
192
+ value.description
193
+ else
194
+ value
195
+ end
196
+ end
197
+ end
198
+
199
+ def filter_jobs(jobs)
200
+ jobs.select do |job|
201
+ next if expected_arguments && !values_match?(expected_arguments, job["args"])
202
+ next if expected_schedule && !values_match?(expected_schedule.to_i, job["at"].to_i)
203
+ next if expected_without_batch && job["bid"]
204
+ next if expected_batch && !batch_match?(expected_batch, job["bid"])
205
+
206
+ true
207
+ end
208
+ end
209
+
210
+ def batch_match?(expected_batch, bid)
211
+ case expected_batch
212
+ when :__undef__
213
+ !bid.nil?
214
+ when String
215
+ expected_batch == bid
216
+
217
+ when ::Sidekiq::Batch
218
+ expected_batch.bid == bid
219
+
220
+ else
221
+ return unless bid
222
+
223
+ batch = ::Sidekiq::Batch.new(bid)
224
+ values_match?(expected_batch, batch)
225
+ end
226
+ end
227
+ end
228
+ end
229
+ end
230
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rspec/sidekiq_pro/matchers/enqueue_sidekiq_jobs"
4
+ require "rspec/sidekiq_pro/matchers/have_enqueued_sidekiq_jobs"
5
+
6
+ module RSpec
7
+ module SidekiqPro
8
+ module Matchers
9
+ # Checks if a certain job was enqueued.
10
+ #
11
+ # AwesomeWorker.perform_async
12
+ # expect(AwesomeWorker).to have_enqueued_sidekiq_job
13
+ #
14
+ # AwesomeWorker.perform_async(42, 'David')
15
+ # expect(AwesomeWorker).to have_enqueued_sidekiq_job.with(42, 'David')
16
+ #
17
+ # AwesomeWorker.perform_in(5.minutes)
18
+ # expect(AwesomeWorker).to have_enqueued_sidekiq_job.in(5.minutes)
19
+ #
20
+ def have_enqueued_sidekiq_job
21
+ HaveEnqueuedSidekiqJobs.new.once
22
+ end
23
+
24
+ def have_enqueued_sidekiq_jobs
25
+ HaveEnqueuedSidekiqJobs.new
26
+ end
27
+
28
+ # Checks if a certain job was enqueued in a block.
29
+ #
30
+ # expect { AwesomeWorker.perform_async }
31
+ # .to enqueue_sidekiq_job(AwesomeWorker)
32
+ #
33
+ # expect { AwesomeWorker.perform_async(42, 'David')
34
+ # .to enqueue_sidekiq_job(AwesomeWorker).with(42, 'David')
35
+ #
36
+ # expect { AwesomeWorker.perform_in(5.minutes) }
37
+ # .to enqueue_sidekiq_job(AwesomeWorker).in(5.minutes)
38
+ #
39
+ def enqueue_sidekiq_job(worker_class)
40
+ EnqueueSidekiqJobs.new(worker_class).once
41
+ end
42
+
43
+ def enqueue_sidekiq_jobs(worker_class)
44
+ EnqueueSidekiqJobs.new(worker_class)
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSpec
4
+ module SidekiqPro
5
+ VERSION = "0.0.0"
6
+ end
7
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rspec"
4
+ require "sidekiq"
5
+ require "sidekiq-pro"
6
+ require "sidekiq/testing"
7
+ require "active_support/duration"
8
+ require "active_support/core_ext/module/delegation"
9
+ require "rspec/sidekiq_pro/matchers"
10
+ require "rspec/sidekiq_pro/batches"
11
+
12
+ RSpec.configure do |config|
13
+ config.include RSpec::SidekiqPro::Matchers
14
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rspec-sidekiq_pro
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Savater Sebastien
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-08-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '6.0'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '8'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '6.0'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '8'
33
+ - !ruby/object:Gem::Dependency
34
+ name: rspec
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '3.11'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '3.11'
47
+ - !ruby/object:Gem::Dependency
48
+ name: sidekiq
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '6.5'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '6.5'
61
+ - !ruby/object:Gem::Dependency
62
+ name: sidekiq-pro
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '5.5'
68
+ type: :runtime
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '5.5'
75
+ description:
76
+ email: github.60k5k@simplelogin.co
77
+ executables: []
78
+ extensions: []
79
+ extra_rdoc_files: []
80
+ files:
81
+ - LICENSE
82
+ - README.md
83
+ - lib/rspec/sidekiq_pro.rb
84
+ - lib/rspec/sidekiq_pro/batches.rb
85
+ - lib/rspec/sidekiq_pro/matchers.rb
86
+ - lib/rspec/sidekiq_pro/matchers/enqueue_sidekiq_jobs.rb
87
+ - lib/rspec/sidekiq_pro/matchers/have_enqueued_sidekiq_jobs.rb
88
+ - lib/rspec/sidekiq_pro/matchers/job_matcher.rb
89
+ - lib/rspec/sidekiq_pro/version.rb
90
+ homepage: http://github.com/inkstak/rspec-sidekiq_pro
91
+ licenses:
92
+ - MIT
93
+ metadata: {}
94
+ post_install_message:
95
+ rdoc_options: []
96
+ require_paths:
97
+ - lib
98
+ required_ruby_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ requirements: []
109
+ rubygems_version: 3.3.7
110
+ signing_key:
111
+ specification_version: 4
112
+ summary: A collection of tools and matchers for Sidekiq Pro
113
+ test_files: []