mock_redis 0.53.0 → 0.55.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: bc774e7b8052b25ca3ca059f197038b854da5cd7d82cae73d5b786cd94fdd318
4
- data.tar.gz: 674f66037a10dbae4fc547e402931d689a9a1603ffa20335e394c0b9d37db90d
3
+ metadata.gz: f61c25ac91aa99558a90e5035269dbabc36c565d7aec85e78356a2178c5aa1a6
4
+ data.tar.gz: bdb253307125c9dc1418bc11ea5884e36d4d0e425b8243c3619816b3cc91cd48
5
5
  SHA512:
6
- metadata.gz: 4934a3233fc0f9bae10f33ced22aac334038f9d7e11563105b19ea4f591980242f16c06c73503342791415af09633189a9f7c57788cd6cf050cdda50374436a4
7
- data.tar.gz: 166130d7f1cb05e56eaff5be78b52a388bf8eeed60552d95b64884b14139d931323fae97bbcc879f204a61e96e0be833f8f7d3f4d8a7712af2df8adbafe1b68b
6
+ metadata.gz: 40e400a1c118712a11c638e26cdc1ce0e10cb70e34c8a390c94e904a94d1141cd152167fa465ff5e78f8c4cf31e9eeb02efc568211dbd83ae4c18a87917d61ba
7
+ data.tar.gz: d68b5609c754e1c1dc0a90433e25d22466cf1a88f9733a90e8aa3daa2abe2a389b80ed32ef0daa27fd8952d2ce6c0baa80e0f28c2edb887d4e749d6b6a258689
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # MockRedis Changelog
2
2
 
3
+ ### 0.55.0
4
+
5
+ * Add `GT` option support to `ZADD`
6
+
7
+ ### 0.54.0
8
+
9
+ * Add `(B)ZMPOP`, `BZPOPMIN`, and `BZPOPMAX` commands
10
+
3
11
  ### 0.53.0
4
12
 
5
13
  * Fix `redis.call("info")`
@@ -2,5 +2,5 @@
2
2
 
3
3
  # Defines the gem version.
4
4
  class MockRedis
5
- VERSION = '0.53.0'
5
+ VERSION = '0.55.0'
6
6
  end
@@ -18,6 +18,13 @@ class MockRedis
18
18
  )
19
19
  end
20
20
 
21
+ if zadd_options&.include?(:gt) && zadd_options&.include?(:nx)
22
+ raise Error.command_error(
23
+ 'ERR GT, LT, and/or NX options at the same time are not compatible',
24
+ self
25
+ )
26
+ end
27
+
21
28
  if args.size == 1 && args[0].is_a?(Array)
22
29
  zadd_multiple_members(key, args.first, zadd_options)
23
30
  elsif args.size == 2
@@ -33,6 +40,24 @@ class MockRedis
33
40
 
34
41
  with_zset_at(key) do |zset|
35
42
  if zadd_options[:incr]
43
+ if zadd_options[:gt]
44
+ current_score = zset.score(member.to_s)
45
+
46
+ # NOTE: does nothing if the member doesn't exist and XX option is set.
47
+ return nil if current_score.nil? && zadd_options[:xx]
48
+
49
+ # NOTE: zincrby add the increment if the member doesn't exist and XX option is not set.
50
+ return zincrby(key, score, member) if current_score.nil? && !zadd_options[:xx]
51
+
52
+ new_score = current_score + score.to_f
53
+
54
+ # NOTE: does nothing if the new score is not greater than the current score.
55
+ return nil if current_score && new_score <= current_score
56
+
57
+ # NOTE: zincrby update the score if the new score is greater than the current score.
58
+ return zincrby(key, score, member)
59
+ end
60
+
36
61
  if zadd_options[:xx]
37
62
  member_present = zset.include?(member)
38
63
  return member_present ? zincrby(key, score, member) : nil
@@ -44,7 +69,21 @@ class MockRedis
44
69
  end
45
70
 
46
71
  zincrby(key, score, member)
72
+ elsif zadd_options[:gt]
73
+ current_score = zset.score(member.to_s)
74
+ new_score = score.to_f
75
+
76
+ if current_score.nil?
77
+ return false if zadd_options[:xx]
78
+
79
+ zset.add(new_score, member.to_s)
80
+ true
81
+ else
82
+ zset.add(new_score, member.to_s) if new_score > current_score
83
+ false
84
+ end
47
85
  elsif zadd_options[:xx]
86
+ # NOTE: gt and xx options are handled at the gt branch above, so its not handled here.
48
87
  zset.add(score, member.to_s) if zset.include?(member)
49
88
  false
50
89
  elsif zadd_options[:nx]
@@ -67,6 +106,20 @@ class MockRedis
67
106
  'ERR INCR option supports a single increment-element pair',
68
107
  self
69
108
  )
109
+ elsif zadd_options[:gt]
110
+ args.reduce(0) do |retval, (score, member)|
111
+ current_score = zset.score(member.to_s)
112
+ if current_score.nil?
113
+ unless zadd_options[:xx]
114
+ zset.add(score.to_f, member.to_s)
115
+ retval += 1
116
+ end
117
+ else
118
+ score_f = score.to_f
119
+ zset.add(score_f, member.to_s) if score_f > current_score
120
+ end
121
+ retval
122
+ end
70
123
  elsif zadd_options[:xx]
71
124
  args.each { |score, member| zset.include?(member) && zset.add(score, member.to_s) }
72
125
  0
@@ -253,6 +306,92 @@ class MockRedis
253
306
  zcard(destination)
254
307
  end
255
308
 
309
+ def bzpopmin(*args)
310
+ keys, timeout = extract_timeout(args)
311
+ nonempty_zset = first_nonempty_zset(keys)
312
+
313
+ if nonempty_zset
314
+ member, score = zpopmin(nonempty_zset)
315
+ [nonempty_zset, member, score]
316
+ elsif timeout > 0
317
+ nil
318
+ else
319
+ raise MockRedis::WouldBlock, "Can't block forever"
320
+ end
321
+ end
322
+
323
+ def bzpopmax(*args)
324
+ keys, timeout = extract_timeout(args)
325
+ nonempty_zset = first_nonempty_zset(keys)
326
+
327
+ if nonempty_zset
328
+ member, score = zpopmax(nonempty_zset)
329
+ [nonempty_zset, member, score]
330
+ elsif timeout > 0
331
+ nil
332
+ else
333
+ raise MockRedis::WouldBlock, "Can't block forever"
334
+ end
335
+ end
336
+
337
+ def zmpop(*keys, **options)
338
+ keys.each do |key|
339
+ assert_zsety(key)
340
+ end
341
+
342
+ modifier = options.is_a?(Hash) && options[:modifier]&.to_s&.downcase || 'min'
343
+ count = (options.is_a?(Hash) && options[:count]) || 1
344
+
345
+ unless %w[min max].include?(modifier)
346
+ raise ArgumentError, 'Pick either MIN or MAX'
347
+ end
348
+
349
+ keys.each do |key|
350
+ record_count = zcard(key)
351
+ next if record_count.zero?
352
+
353
+ values = [count, record_count].min.times.map do
354
+ modifier == 'min' ? zpopmin(key) : zpopmax(key)
355
+ end
356
+
357
+ return [key, values]
358
+ end
359
+
360
+ nil
361
+ end
362
+
363
+ def bzmpop(timeout, *keys, **options)
364
+ timeout = assert_valid_timeout(timeout)
365
+
366
+ keys.each do |key|
367
+ assert_zsety(key)
368
+ end
369
+
370
+ modifier = options.is_a?(Hash) && options[:modifier]&.to_s&.downcase || 'min'
371
+ count = (options.is_a?(Hash) && options[:count]) || 1
372
+
373
+ unless %w[min max].include?(modifier)
374
+ raise ArgumentError, 'Pick either MIN or MAX'
375
+ end
376
+
377
+ keys.each do |key|
378
+ record_count = zcard(key)
379
+ next if record_count.zero?
380
+
381
+ values = [count, record_count].min.times.map do
382
+ modifier == 'min' ? zpopmin(key) : zpopmax(key)
383
+ end
384
+
385
+ return [key, values]
386
+ end
387
+
388
+ if timeout > 0
389
+ nil
390
+ else
391
+ raise MockRedis::WouldBlock, "Can't block forever"
392
+ end
393
+ end
394
+
256
395
  private
257
396
 
258
397
  def apply_limit(collection, limit)
@@ -376,5 +515,9 @@ class MockRedis
376
515
  assert_scorey(value, 'ERR min or max is not a float')
377
516
  end
378
517
  end
518
+
519
+ def first_nonempty_zset(keys)
520
+ keys.find { |k| zcard(k) > 0 }
521
+ end
379
522
  end
380
523
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mock_redis
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.53.0
4
+ version: 0.55.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shane da Silva
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2025-11-08 00:00:00.000000000 Z
12
+ date: 2026-06-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: redis
@@ -125,10 +125,10 @@ licenses:
125
125
  - MIT
126
126
  metadata:
127
127
  bug_tracker_uri: https://github.com/sds/mock_redis/issues
128
- changelog_uri: https://github.com/sds/mock_redis/blob/v0.53.0/CHANGELOG.md
129
- documentation_uri: https://www.rubydoc.info/gems/mock_redis/0.53.0
128
+ changelog_uri: https://github.com/sds/mock_redis/blob/v0.55.0/CHANGELOG.md
129
+ documentation_uri: https://www.rubydoc.info/gems/mock_redis/0.55.0
130
130
  homepage_uri: https://github.com/sds/mock_redis
131
- source_code_uri: https://github.com/sds/mock_redis/tree/v0.53.0
131
+ source_code_uri: https://github.com/sds/mock_redis/tree/v0.55.0
132
132
  post_install_message:
133
133
  rdoc_options: []
134
134
  require_paths: