mock_redis 0.4.1 → 0.5.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.
Files changed (54) hide show
  1. data/CHANGELOG.md +11 -0
  2. data/Gemfile +1 -1
  3. data/lib/mock_redis/assertions.rb +2 -2
  4. data/lib/mock_redis/database.rb +16 -8
  5. data/lib/mock_redis/expire_wrapper.rb +2 -2
  6. data/lib/mock_redis/hash_methods.rb +12 -6
  7. data/lib/mock_redis/list_methods.rb +10 -8
  8. data/lib/mock_redis/multi_db_wrapper.rb +3 -3
  9. data/lib/mock_redis/pipelined_wrapper.rb +45 -0
  10. data/lib/mock_redis/set_methods.rb +14 -5
  11. data/lib/mock_redis/string_methods.rb +6 -6
  12. data/lib/mock_redis/transaction_wrapper.rb +13 -8
  13. data/lib/mock_redis/version.rb +1 -1
  14. data/lib/mock_redis/zset_methods.rb +52 -22
  15. data/lib/mock_redis.rb +92 -5
  16. data/mock_redis.gemspec +1 -1
  17. data/spec/cloning_spec.rb +1 -1
  18. data/spec/commands/blpop_spec.rb +3 -3
  19. data/spec/commands/brpop_spec.rb +3 -3
  20. data/spec/commands/brpoplpush_spec.rb +3 -3
  21. data/spec/commands/hdel_spec.rb +5 -0
  22. data/spec/commands/lpush_spec.rb +7 -0
  23. data/spec/commands/mapped_hmset_spec.rb +7 -1
  24. data/spec/commands/move_spec.rb +2 -2
  25. data/spec/commands/msetnx_spec.rb +2 -2
  26. data/spec/commands/pipelined_spec.rb +12 -0
  27. data/spec/commands/rename_spec.rb +7 -0
  28. data/spec/commands/renamenx_spec.rb +7 -0
  29. data/spec/commands/rpush_spec.rb +7 -0
  30. data/spec/commands/sadd_spec.rb +1 -1
  31. data/spec/commands/sdiff_spec.rb +1 -1
  32. data/spec/commands/sdiffstore_spec.rb +3 -3
  33. data/spec/commands/sinterstore_spec.rb +2 -2
  34. data/spec/commands/smembers_spec.rb +4 -4
  35. data/spec/commands/srem_spec.rb +5 -0
  36. data/spec/commands/sunion_spec.rb +2 -2
  37. data/spec/commands/sunionstore_spec.rb +3 -3
  38. data/spec/commands/watch_spec.rb +2 -2
  39. data/spec/commands/zadd_spec.rb +6 -1
  40. data/spec/commands/zcount_spec.rb +8 -0
  41. data/spec/commands/zincrby_spec.rb +4 -4
  42. data/spec/commands/zinterstore_spec.rb +7 -7
  43. data/spec/commands/zrange_spec.rb +6 -2
  44. data/spec/commands/zrangebyscore_spec.rb +2 -2
  45. data/spec/commands/zrem_spec.rb +5 -0
  46. data/spec/commands/zrevrange_spec.rb +2 -2
  47. data/spec/commands/zrevrangebyscore_spec.rb +2 -2
  48. data/spec/commands/zscore_spec.rb +2 -2
  49. data/spec/commands/zunionstore_spec.rb +9 -9
  50. data/spec/mock_redis_spec.rb +21 -0
  51. data/spec/support/redis_multiplexer.rb +23 -19
  52. data/spec/transactions_spec.rb +17 -0
  53. metadata +67 -84
  54. data/lib/mock_redis/distributed.rb +0 -6
data/CHANGELOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ ### 0.5.0
2
+ * Support `redis-rb` >= 3.0
3
+ * Support Redis::Distributed
4
+ * Support ruby 1.9.3 in spec suite
5
+ * Support subsecond timeouts
6
+ * Support `-inf`, `+inf` in #zcount
7
+ * Return array of results from pipelined calls
8
+ * Use `debugger` instead of the deprecated `ruby-debug19`
9
+ * Fix exception handling in transaction wrappers
10
+ * Fix rename error behaviour for nonexistant keys
11
+
1
12
  ### 0.4.1
2
13
  * bugfixes: teach various methods to correctly handle non-string values
3
14
 
data/Gemfile CHANGED
@@ -5,5 +5,5 @@ gemspec
5
5
 
6
6
  group :test do
7
7
  gem "ruby-debug", :platforms => :mri_18
8
- gem "ruby-debug19", :platforms => :mri_19
8
+ gem "debugger", :platforms => :mri_19
9
9
  end
@@ -4,10 +4,10 @@ class MockRedis
4
4
 
5
5
  def assert_has_args(args, command)
6
6
  unless args.any?
7
- raise RuntimeError,
7
+ raise Redis::CommandError,
8
8
  "ERR wrong number of arguments for '#{command}' command"
9
9
  end
10
10
  end
11
-
11
+
12
12
  end
13
13
  end
@@ -57,7 +57,7 @@ class MockRedis
57
57
 
58
58
  def expireat(key, timestamp)
59
59
  unless looks_like_integer?(timestamp.to_s)
60
- raise RuntimeError, "ERR value is not an integer or out of range"
60
+ raise Redis::CommandError, "ERR value is not an integer or out of range"
61
61
  end
62
62
 
63
63
  if exists(key)
@@ -304,16 +304,20 @@ class MockRedis
304
304
  end
305
305
 
306
306
  def rename(key, newkey)
307
- if key == newkey
308
- raise RuntimeError, "ERR source and destination objects are the same"
307
+ if !data.include?(key)
308
+ raise Redis::CommandError, "ERR no such key"
309
+ elsif key == newkey
310
+ raise Redis::CommandError, "ERR source and destination objects are the same"
309
311
  end
310
312
  data[newkey] = data.delete(key)
311
313
  'OK'
312
314
  end
313
315
 
314
316
  def renamenx(key, newkey)
315
- if key == newkey
316
- raise RuntimeError, "ERR source and destination objects are the same"
317
+ if !data.include?(key)
318
+ raise Redis::CommandError, "ERR no such key"
319
+ elsif key == newkey
320
+ raise Redis::CommandError, "ERR source and destination objects are the same"
317
321
  end
318
322
  if exists(newkey)
319
323
  false
@@ -356,10 +360,10 @@ class MockRedis
356
360
  private
357
361
 
358
362
  def assert_valid_timeout(timeout)
359
- if !looks_like_integer?(timeout.to_s)
360
- raise RuntimeError, "ERR timeout is not an integer or out of range"
363
+ if !looks_like_float?(timeout.to_s)
364
+ raise Redis::CommandError, "ERR timeout is not a float or out of range"
361
365
  elsif timeout < 0
362
- raise RuntimeError, "ERR timeout is negative"
366
+ raise Redis::CommandError, "ERR timeout is negative"
363
367
  end
364
368
  timeout
365
369
  end
@@ -385,6 +389,10 @@ class MockRedis
385
389
  str =~ /^-?\d+$/
386
390
  end
387
391
 
392
+ def looks_like_float?(str)
393
+ !!Float(str) rescue false
394
+ end
395
+
388
396
  def redis_pattern_to_ruby_regex(pattern)
389
397
  Regexp.new(
390
398
  "^#{pattern}$".
@@ -12,9 +12,9 @@ class MockRedis
12
12
  @db = db
13
13
  end
14
14
 
15
- def method_missing(method, *args)
15
+ def method_missing(method, *args, &block)
16
16
  @db.expire_keys
17
- @db.send(method, *args)
17
+ @db.send(method, *args, &block)
18
18
  end
19
19
 
20
20
  def initialize_copy(source)
@@ -8,7 +8,13 @@ class MockRedis
8
8
 
9
9
  def hdel(key, field)
10
10
  with_hash_at(key) do |hash|
11
- hash.delete(field.to_s) ? 1 : 0
11
+ if field.is_a?(Array)
12
+ orig_size = hash.size
13
+ hash.delete_if { |k,v| field.include?(k) }
14
+ orig_size - hash.size
15
+ else
16
+ hash.delete(field.to_s) ? 1 : 0
17
+ end
12
18
  end
13
19
  end
14
20
 
@@ -28,10 +34,10 @@ class MockRedis
28
34
  with_hash_at(key) do |hash|
29
35
  field = field.to_s
30
36
  unless can_incr?(data[key][field])
31
- raise RuntimeError, "ERR hash value is not an integer"
37
+ raise Redis::CommandError, "ERR hash value is not an integer"
32
38
  end
33
39
  unless looks_like_integer?(increment.to_s)
34
- raise RuntimeError, "ERR value is not an integer or out of range"
40
+ raise Redis::CommandError, "ERR value is not an integer or out of range"
35
41
  end
36
42
 
37
43
  new_value = (hash[field] || "0").to_i + increment.to_i
@@ -61,7 +67,7 @@ class MockRedis
61
67
  def hmset(key, *kvpairs)
62
68
  assert_has_args(kvpairs, 'hmset')
63
69
  if kvpairs.length.odd?
64
- raise RuntimeError, "ERR wrong number of arguments for HMSET"
70
+ raise Redis::CommandError, "ERR wrong number of arguments for HMSET"
65
71
  end
66
72
 
67
73
  kvpairs.each_slice(2) do |(k,v)|
@@ -74,7 +80,7 @@ class MockRedis
74
80
  kvpairs = hash.to_a.flatten
75
81
  assert_has_args(kvpairs, 'hmset')
76
82
  if kvpairs.length.odd?
77
- raise RuntimeError, "ERR wrong number of arguments for 'hmset' command"
83
+ raise Redis::CommandError, "ERR wrong number of arguments for 'hmset' command"
78
84
  end
79
85
 
80
86
  hmset(key, *kvpairs)
@@ -110,7 +116,7 @@ class MockRedis
110
116
 
111
117
  def assert_hashy(key)
112
118
  unless hashy?(key)
113
- raise RuntimeError, "ERR Operation against a key holding the wrong kind of value"
119
+ raise Redis::CommandError, "ERR Operation against a key holding the wrong kind of value"
114
120
  end
115
121
  end
116
122
 
@@ -50,7 +50,7 @@ class MockRedis
50
50
 
51
51
  def linsert(key, position, pivot, value)
52
52
  unless %w[before after].include?(position.to_s)
53
- raise RuntimeError, "ERR syntax error"
53
+ raise Redis::CommandError, "ERR syntax error"
54
54
  end
55
55
 
56
56
  assert_listy(key)
@@ -80,8 +80,9 @@ class MockRedis
80
80
  with_list_at(key, &:shift)
81
81
  end
82
82
 
83
- def lpush(key, value)
84
- with_list_at(key) {|l| l.unshift(value.to_s)}
83
+ def lpush(key, values)
84
+ values = [values] unless values.is_a?(Array)
85
+ with_list_at(key) {|l| values.each {|v| l.unshift(v.to_s)}}
85
86
  llen(key)
86
87
  end
87
88
 
@@ -120,11 +121,11 @@ class MockRedis
120
121
  assert_listy(key)
121
122
 
122
123
  unless list_at?(key)
123
- raise RuntimeError, "ERR no such key"
124
+ raise Redis::CommandError, "ERR no such key"
124
125
  end
125
126
 
126
127
  unless (0...llen(key)).include?(index)
127
- raise RuntimeError, "ERR index out of range"
128
+ raise Redis::CommandError, "ERR index out of range"
128
129
  end
129
130
 
130
131
  data[key][index] = value.to_s
@@ -148,8 +149,9 @@ class MockRedis
148
149
  value
149
150
  end
150
151
 
151
- def rpush(key, value)
152
- with_list_at(key) {|l| l.push(value.to_s)}
152
+ def rpush(key, values)
153
+ values = [values] unless values.is_a?(Array)
154
+ with_list_at(key) {|l| values.each {|v| l.push(v.to_s)}}
153
155
  llen(key)
154
156
  end
155
157
 
@@ -175,7 +177,7 @@ class MockRedis
175
177
  def assert_listy(key)
176
178
  unless listy?(key)
177
179
  # Not the most helpful error, but it's what redis-rb barfs up
178
- raise RuntimeError, "ERR Operation against a key holding the wrong kind of value"
180
+ raise Redis::CommandError, "ERR Operation against a key holding the wrong kind of value"
179
181
  end
180
182
  end
181
183
 
@@ -17,8 +17,8 @@ class MockRedis
17
17
  super || current_db.respond_to?(method, include_private)
18
18
  end
19
19
 
20
- def method_missing(method, *args)
21
- current_db.send(method, *args)
20
+ def method_missing(method, *args, &block)
21
+ current_db.send(method, *args, &block)
22
22
  end
23
23
 
24
24
  def initialize_copy(source)
@@ -56,7 +56,7 @@ class MockRedis
56
56
  when 'string'
57
57
  dest.set(key, src.get(key))
58
58
  when 'zset'
59
- src.zrange(key, 0, -1, :with_scores => true).each_slice(2) do |(m,s)|
59
+ src.zrange(key, 0, -1, :with_scores => true).each do |(m,s)|
60
60
  dest.zadd(key, s, m)
61
61
  end
62
62
  else
@@ -0,0 +1,45 @@
1
+ class MockRedis
2
+ class PipelinedWrapper
3
+ include UndefRedisMethods
4
+
5
+ def respond_to?(method, include_private=false)
6
+ super || @db.respond_to?(method)
7
+ end
8
+
9
+ def initialize(db)
10
+ @db = db
11
+ @pipelined_commands = []
12
+ @in_pipeline = false
13
+ end
14
+
15
+ def initialize_copy(source)
16
+ super
17
+ @db = @db.clone
18
+ @pipelined_commands = @pipelined_commands.clone
19
+ end
20
+
21
+ def method_missing(method, *args, &block)
22
+ if @in_pipeline
23
+ @pipelined_commands << [method, *args]
24
+ nil
25
+ else
26
+ @db.send(method, *args, &block)
27
+ end
28
+ end
29
+
30
+ def pipelined(options = {})
31
+ @in_pipeline = true
32
+ yield
33
+ @in_pipeline = false
34
+ responses = @pipelined_commands.map do |cmd|
35
+ begin
36
+ send(*cmd)
37
+ rescue => e
38
+ e
39
+ end
40
+ end
41
+ @pipelined_commands = []
42
+ responses
43
+ end
44
+ end
45
+ end
@@ -48,7 +48,7 @@ class MockRedis
48
48
  end
49
49
 
50
50
  def smembers(key)
51
- with_set_at(key, &:to_a)
51
+ with_set_at(key, &:to_a).reverse
52
52
  end
53
53
 
54
54
  def smove(src, dest, member)
@@ -73,11 +73,20 @@ class MockRedis
73
73
  end
74
74
 
75
75
  def srandmember(key)
76
- with_set_at(key, &:first)
76
+ members = with_set_at(key, &:to_a)
77
+ members[rand(members.length)]
77
78
  end
78
79
 
79
- def srem(key, member)
80
- with_set_at(key) {|s| !!s.delete?(member.to_s)}
80
+ def srem(key, members)
81
+ with_set_at(key) do |s|
82
+ if members.is_a?(Array)
83
+ orig_size = s.size
84
+ s.delete_if { |m| members.include?(m) }
85
+ orig_size - s.size
86
+ else
87
+ !!s.delete?(members.to_s)
88
+ end
89
+ end
81
90
  end
82
91
 
83
92
  def sunion(*keys)
@@ -117,7 +126,7 @@ class MockRedis
117
126
  def assert_sety(key)
118
127
  unless sety?(key)
119
128
  # Not the most helpful error, but it's what redis-rb barfs up
120
- raise RuntimeError, "ERR Operation against a key holding the wrong kind of value"
129
+ raise Redis::CommandError, "ERR Operation against a key holding the wrong kind of value"
121
130
  end
122
131
  end
123
132
 
@@ -62,11 +62,11 @@ class MockRedis
62
62
  def incrby(key, n)
63
63
  assert_stringy(key)
64
64
  unless can_incr?(data[key])
65
- raise RuntimeError, "ERR value is not an integer or out of range"
65
+ raise Redis::CommandError, "ERR value is not an integer or out of range"
66
66
  end
67
67
 
68
68
  unless looks_like_integer?(n.to_s)
69
- raise RuntimeError, "ERR value is not an integer or out of range"
69
+ raise Redis::CommandError, "ERR value is not an integer or out of range"
70
70
  end
71
71
 
72
72
  new_value = data[key].to_i + n.to_i
@@ -86,7 +86,7 @@ class MockRedis
86
86
  def mset(*kvpairs)
87
87
  assert_has_args(kvpairs, 'mset')
88
88
  if kvpairs.length.odd?
89
- raise RuntimeError, "ERR wrong number of arguments for MSET"
89
+ raise Redis::CommandError, "ERR wrong number of arguments for MSET"
90
90
  end
91
91
 
92
92
  kvpairs.each_slice(2) do |(k,v)|
@@ -100,10 +100,10 @@ class MockRedis
100
100
  assert_has_args(kvpairs, 'msetnx')
101
101
 
102
102
  if kvpairs.each_slice(2).any? {|(k,v)| exists(k)}
103
- 0
103
+ false
104
104
  else
105
105
  mset(*kvpairs)
106
- 1
106
+ true
107
107
  end
108
108
  end
109
109
 
@@ -195,7 +195,7 @@ class MockRedis
195
195
  def assert_stringy(key,
196
196
  message="ERR Operation against a key holding the wrong kind of value")
197
197
  unless stringy?(key)
198
- raise RuntimeError, message
198
+ raise Redis::CommandError, message
199
199
  end
200
200
  end
201
201
 
@@ -14,13 +14,13 @@ class MockRedis
14
14
  @in_multi = false
15
15
  end
16
16
 
17
- def method_missing(method, *args)
17
+ def method_missing(method, *args, &block)
18
18
  if @in_multi
19
19
  @queued_commands << [method, *args]
20
20
  'QUEUED'
21
21
  else
22
22
  @db.expire_keys
23
- @db.send(method, *args)
23
+ @db.send(method, *args, &block)
24
24
  end
25
25
  end
26
26
 
@@ -32,7 +32,7 @@ class MockRedis
32
32
 
33
33
  def discard
34
34
  unless @in_multi
35
- raise RuntimeError, "ERR DISCARD without MULTI"
35
+ raise Redis::CommandError, "ERR DISCARD without MULTI"
36
36
  end
37
37
  @in_multi = false
38
38
  @queued_commands = []
@@ -41,7 +41,7 @@ class MockRedis
41
41
 
42
42
  def exec
43
43
  unless @in_multi
44
- raise RuntimeError, "ERR EXEC without MULTI"
44
+ raise Redis::CommandError, "ERR EXEC without MULTI"
45
45
  end
46
46
  @in_multi = false
47
47
  responses = @queued_commands.map do |cmd|
@@ -57,12 +57,17 @@ class MockRedis
57
57
 
58
58
  def multi
59
59
  if @in_multi
60
- raise RuntimeError, "ERR MULTI calls can not be nested"
60
+ raise Redis::CommandError, "ERR MULTI calls can not be nested"
61
61
  end
62
62
  @in_multi = true
63
63
  if block_given?
64
- yield(self)
65
- self.exec
64
+ begin
65
+ yield(self)
66
+ self.exec
67
+ rescue StandardError => e
68
+ self.discard
69
+ raise e
70
+ end
66
71
  else
67
72
  'OK'
68
73
  end
@@ -73,7 +78,7 @@ class MockRedis
73
78
  end
74
79
 
75
80
  def watch(_)
76
- 'OK'
81
+ nil
77
82
  end
78
83
 
79
84
  end
@@ -1,3 +1,3 @@
1
1
  class MockRedis
2
- VERSION = '0.4.1'
2
+ VERSION = '0.5.0'
3
3
  end
@@ -7,11 +7,33 @@ class MockRedis
7
7
  include Assertions
8
8
  include UtilityMethods
9
9
 
10
- def zadd(key, score, member)
11
- assert_scorey(score)
10
+ def zadd(key, *args)
11
+ if !args.first.is_a?(Array)
12
+ if args.size < 2
13
+ raise Redis::CommandError, "ERR wrong number of arguments for 'zadd' command"
14
+ elsif args.size.odd?
15
+ raise Redis::CommandError, "ERR syntax error"
16
+ end
17
+ else
18
+ unless args.all? {|pair| pair.size == 2 }
19
+ raise(Redis::CommandError, "ERR syntax error")
20
+ end
21
+ end
22
+
23
+ if args.size == 2
24
+ score, member = args
25
+ assert_scorey(score)
26
+ retval = !zscore(key, member)
27
+ with_zset_at(key) {|z| z.add(score, member.to_s)}
28
+ else
29
+ args = args.first
30
+ args = args.each_slice(2).to_a unless args.first.is_a?(Array)
31
+ retval = args.map(&:last).map { |member| !!zscore(key, member.to_s) }.count(false)
32
+ with_zset_at(key) do |z|
33
+ args.each { |score, member| z.add(score, member.to_s) }
34
+ end
35
+ end
12
36
 
13
- retval = !zscore(key, member)
14
- with_zset_at(key) {|z| z.add(score, member.to_s)}
15
37
  retval
16
38
  end
17
39
 
@@ -20,13 +42,11 @@ class MockRedis
20
42
  end
21
43
 
22
44
  def zcount(key, min, max)
23
- assert_scorey(min, 'min or max')
24
- assert_scorey(max, 'min or max')
45
+ assert_scorey(min, 'min or max') unless min == '-inf'
46
+ assert_scorey(max, 'min or max') unless max == '+inf'
25
47
 
26
- with_zset_at(key) do |z|
27
- z.count do |score, _|
28
- score >= min && score <= max
29
- end
48
+ with_zset_at(key) do |zset|
49
+ zset.in_range(min, max).size
30
50
  end
31
51
  end
32
52
 
@@ -37,7 +57,7 @@ class MockRedis
37
57
  old_score = z.include?(member) ? z.score(member) : 0
38
58
  new_score = old_score + increment
39
59
  z.add(new_score, member)
40
- new_score.to_s
60
+ new_score.to_f
41
61
  end
42
62
  end
43
63
 
@@ -50,7 +70,7 @@ class MockRedis
50
70
 
51
71
  def zrange(key, start, stop, options={})
52
72
  with_zset_at(key) do |z|
53
- to_response(z.sorted[start..stop] || [], options)
73
+ to_response(z.sorted[start.to_i..stop.to_i] || [], options)
54
74
  end
55
75
  end
56
76
 
@@ -65,8 +85,18 @@ class MockRedis
65
85
  with_zset_at(key) {|z| z.sorted_members.index(member.to_s) }
66
86
  end
67
87
 
68
- def zrem(key, member)
69
- with_zset_at(key) {|z| !!z.delete?(member.to_s)}
88
+ def zrem(key, *args)
89
+ if !args.first.is_a?(Array)
90
+ retval = with_zset_at(key) {|z| !!z.delete?(args.first.to_s)}
91
+ else
92
+ args = args.first
93
+ retval = args.map { |member| !!zscore(key, member.to_s) }.count(true)
94
+ with_zset_at(key) do |z|
95
+ args.each { |member| z.delete?(member) }
96
+ end
97
+ end
98
+
99
+ retval
70
100
  end
71
101
 
72
102
  def zrevrange(key, start, stop, options={})
@@ -104,7 +134,7 @@ class MockRedis
104
134
  def zscore(key, member)
105
135
  with_zset_at(key) do |z|
106
136
  score = z.score(member.to_s)
107
- score.to_s if score
137
+ score.to_f if score
108
138
  end
109
139
  end
110
140
 
@@ -122,7 +152,7 @@ class MockRedis
122
152
  offset, count = limit
123
153
  collection.drop(offset).take(count)
124
154
  else
125
- raise RuntimeError, "ERR syntax error"
155
+ raise Redis::CommandError, "ERR syntax error"
126
156
  end
127
157
  else
128
158
  collection
@@ -132,17 +162,17 @@ class MockRedis
132
162
  def to_response(score_member_pairs, options)
133
163
  score_member_pairs.map do |(score,member)|
134
164
  if options[:with_scores] || options[:withscores]
135
- [member, score.to_s]
165
+ [member, score.to_f]
136
166
  else
137
167
  member
138
168
  end
139
- end.flatten
169
+ end
140
170
  end
141
171
 
142
172
  def combine_weighted_zsets(keys, options, how)
143
173
  weights = options.fetch(:weights, keys.map { 1 })
144
174
  if weights.length != keys.length
145
- raise RuntimeError, "ERR syntax error"
175
+ raise Redis::CommandError, "ERR syntax error"
146
176
  end
147
177
 
148
178
  aggregator = case options.fetch(:aggregate, :sum).to_s.downcase.to_sym
@@ -153,7 +183,7 @@ class MockRedis
153
183
  when :max
154
184
  proc {|a,b| [a,b].compact.max}
155
185
  else
156
- raise RuntimeError, "ERR syntax error"
186
+ raise Redis::CommandError, "ERR syntax error"
157
187
  end
158
188
 
159
189
  with_zsets_at(*keys) do |*zsets|
@@ -190,7 +220,7 @@ class MockRedis
190
220
 
191
221
  def assert_zsety(key)
192
222
  unless zsety?(key)
193
- raise RuntimeError,
223
+ raise Redis::CommandError,
194
224
  "ERR Operation against a key holding the wrong kind of value"
195
225
  end
196
226
  end
@@ -202,7 +232,7 @@ class MockRedis
202
232
 
203
233
  def assert_scorey(value, what='value')
204
234
  unless looks_like_float?(value)
205
- raise RuntimeError, "ERR #{what} is not a double"
235
+ raise Redis::CommandError, "ERR #{what} is not a double"
206
236
  end
207
237
  end
208
238