mock_redis 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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