mock_redis 0.14.1 → 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.overcommit.yml +1 -1
- data/.rubocop.yml +91 -0
- data/.simplecov +4 -0
- data/.travis.yml +14 -2
- data/CHANGELOG.md +4 -0
- data/Gemfile +4 -2
- data/README.md +1 -0
- data/Rakefile +2 -2
- data/lib/mock_redis.rb +25 -26
- data/lib/mock_redis/assertions.rb +0 -1
- data/lib/mock_redis/database.rb +35 -28
- data/lib/mock_redis/expire_wrapper.rb +1 -1
- data/lib/mock_redis/future.rb +1 -1
- data/lib/mock_redis/hash_methods.rb +18 -17
- data/lib/mock_redis/indifferent_hash.rb +4 -0
- data/lib/mock_redis/info_method.rb +109 -108
- data/lib/mock_redis/list_methods.rb +17 -16
- data/lib/mock_redis/multi_db_wrapper.rb +5 -4
- data/lib/mock_redis/pipelined_wrapper.rb +3 -3
- data/lib/mock_redis/set_methods.rb +10 -9
- data/lib/mock_redis/sort_method.rb +11 -12
- data/lib/mock_redis/string_methods.rb +26 -29
- data/lib/mock_redis/transaction_wrapper.rb +7 -8
- data/lib/mock_redis/utility_methods.rb +9 -12
- data/lib/mock_redis/version.rb +1 -1
- data/lib/mock_redis/zset.rb +22 -23
- data/lib/mock_redis/zset_methods.rb +25 -25
- data/spec/cloning_spec.rb +17 -18
- data/spec/commands/append_spec.rb +4 -4
- data/spec/commands/auth_spec.rb +1 -1
- data/spec/commands/bgrewriteaof_spec.rb +2 -2
- data/spec/commands/bgsave_spec.rb +2 -2
- data/spec/commands/bitcount_spec.rb +3 -3
- data/spec/commands/blpop_spec.rb +10 -10
- data/spec/commands/brpop_spec.rb +10 -10
- data/spec/commands/brpoplpush_spec.rb +9 -9
- data/spec/commands/connected_spec.rb +2 -2
- data/spec/commands/dbsize_spec.rb +3 -3
- data/spec/commands/decr_spec.rb +7 -7
- data/spec/commands/decrby_spec.rb +7 -7
- data/spec/commands/del_spec.rb +4 -4
- data/spec/commands/disconnect_spec.rb +2 -2
- data/spec/commands/echo_spec.rb +4 -4
- data/spec/commands/exists_spec.rb +3 -3
- data/spec/commands/expire_spec.rb +13 -13
- data/spec/commands/expireat_spec.rb +6 -7
- data/spec/commands/flushall_spec.rb +5 -5
- data/spec/commands/flushdb_spec.rb +5 -5
- data/spec/commands/future_spec.rb +2 -2
- data/spec/commands/get_spec.rb +7 -7
- data/spec/commands/getbit_spec.rb +6 -6
- data/spec/commands/getrange_spec.rb +9 -9
- data/spec/commands/getset_spec.rb +7 -7
- data/spec/commands/hash_operator_spec.rb +5 -5
- data/spec/commands/hdel_spec.rb +12 -12
- data/spec/commands/hexists_spec.rb +7 -7
- data/spec/commands/hget_spec.rb +7 -7
- data/spec/commands/hgetall_spec.rb +6 -6
- data/spec/commands/hincrby_spec.rb +14 -14
- data/spec/commands/hincrbyfloat_spec.rb +14 -14
- data/spec/commands/hkeys_spec.rb +5 -5
- data/spec/commands/hlen_spec.rb +5 -5
- data/spec/commands/hmget_spec.rb +8 -8
- data/spec/commands/hmset_spec.rb +10 -10
- data/spec/commands/hset_spec.rb +11 -11
- data/spec/commands/hsetnx_spec.rb +14 -14
- data/spec/commands/hvals_spec.rb +5 -5
- data/spec/commands/incr_spec.rb +7 -7
- data/spec/commands/incrby_spec.rb +11 -11
- data/spec/commands/incrbyfloat_spec.rb +11 -11
- data/spec/commands/info_spec.rb +30 -30
- data/spec/commands/keys_spec.rb +42 -43
- data/spec/commands/lastsave_spec.rb +2 -2
- data/spec/commands/lindex_spec.rb +15 -15
- data/spec/commands/linsert_spec.rb +13 -13
- data/spec/commands/llen_spec.rb +4 -4
- data/spec/commands/lpop_spec.rb +6 -6
- data/spec/commands/lpush_spec.rb +16 -16
- data/spec/commands/lpushx_spec.rb +13 -13
- data/spec/commands/lrange_spec.rb +12 -12
- data/spec/commands/lrem_spec.rb +15 -15
- data/spec/commands/lset_spec.rb +12 -12
- data/spec/commands/ltrim_spec.rb +9 -9
- data/spec/commands/mapped_hmget_spec.rb +8 -8
- data/spec/commands/mapped_hmset_spec.rb +12 -12
- data/spec/commands/mapped_mget_spec.rb +4 -4
- data/spec/commands/mapped_mset_spec.rb +1 -1
- data/spec/commands/mget_spec.rb +11 -11
- data/spec/commands/move_spec.rb +29 -29
- data/spec/commands/mset_spec.rb +4 -4
- data/spec/commands/msetnx_spec.rb +10 -10
- data/spec/commands/persist_spec.rb +9 -10
- data/spec/commands/pexpire_spec.rb +12 -13
- data/spec/commands/pexpireat_spec.rb +6 -6
- data/spec/commands/ping_spec.rb +1 -1
- data/spec/commands/pipelined_spec.rb +5 -5
- data/spec/commands/pttl_spec.rb +5 -5
- data/spec/commands/randomkey_spec.rb +3 -3
- data/spec/commands/rename_spec.rb +9 -9
- data/spec/commands/renamenx_spec.rb +10 -10
- data/spec/commands/rpop_spec.rb +6 -6
- data/spec/commands/rpoplpush_spec.rb +7 -7
- data/spec/commands/rpush_spec.rb +16 -16
- data/spec/commands/rpushx_spec.rb +13 -13
- data/spec/commands/sadd_spec.rb +8 -9
- data/spec/commands/scan_spec.rb +6 -7
- data/spec/commands/scard_spec.rb +3 -3
- data/spec/commands/sdiff_spec.rb +10 -10
- data/spec/commands/sdiffstore_spec.rb +10 -10
- data/spec/commands/select_spec.rb +7 -7
- data/spec/commands/setbit_spec.rb +13 -13
- data/spec/commands/setex_spec.rb +4 -4
- data/spec/commands/setnx_spec.rb +4 -4
- data/spec/commands/setrange_spec.rb +12 -12
- data/spec/commands/sinter_spec.rb +8 -10
- data/spec/commands/sinterstore_spec.rb +9 -9
- data/spec/commands/sismember_spec.rb +5 -5
- data/spec/commands/smembers_spec.rb +5 -5
- data/spec/commands/smove_spec.rb +7 -7
- data/spec/commands/sort_list_spec.rb +3 -3
- data/spec/commands/sort_set_spec.rb +3 -3
- data/spec/commands/sort_zset_spec.rb +3 -3
- data/spec/commands/spop_spec.rb +4 -4
- data/spec/commands/srandmember_spec.rb +8 -8
- data/spec/commands/srem_spec.rb +9 -9
- data/spec/commands/strlen_spec.rb +4 -4
- data/spec/commands/sunion_spec.rb +7 -9
- data/spec/commands/sunionstore_spec.rb +9 -9
- data/spec/commands/ttl_spec.rb +5 -5
- data/spec/commands/type_spec.rb +1 -1
- data/spec/commands/zadd_spec.rb +10 -10
- data/spec/commands/zcard_spec.rb +4 -4
- data/spec/commands/zcount_spec.rb +14 -14
- data/spec/commands/zincrby_spec.rb +6 -6
- data/spec/commands/zinterstore_spec.rb +17 -17
- data/spec/commands/zrange_spec.rb +12 -12
- data/spec/commands/zrangebyscore_spec.rb +26 -26
- data/spec/commands/zrank_spec.rb +4 -4
- data/spec/commands/zrem_spec.rb +9 -9
- data/spec/commands/zremrangebyrank_spec.rb +5 -5
- data/spec/commands/zremrangebyscore_spec.rb +9 -7
- data/spec/commands/zrevrange_spec.rb +10 -10
- data/spec/commands/zrevrangebyscore_spec.rb +14 -14
- data/spec/commands/zrevrank_spec.rb +4 -4
- data/spec/commands/zscore_spec.rb +5 -5
- data/spec/commands/zunionstore_spec.rb +18 -18
- data/spec/mock_redis_spec.rb +11 -1
- data/spec/spec_helper.rb +13 -4
- data/spec/support/redis_multiplexer.rb +39 -31
- data/spec/support/shared_examples/only_operates_on_hashes.rb +2 -2
- data/spec/support/shared_examples/only_operates_on_lists.rb +2 -2
- data/spec/support/shared_examples/only_operates_on_sets.rb +2 -2
- data/spec/support/shared_examples/only_operates_on_strings.rb +3 -3
- data/spec/support/shared_examples/only_operates_on_zsets.rb +12 -12
- data/spec/support/shared_examples/sorts_enumerables.rb +12 -12
- data/spec/transactions_spec.rb +18 -18
- metadata +5 -3
@@ -9,11 +9,11 @@ class MockRedis
|
|
9
9
|
|
10
10
|
@prototype_db = db.clone
|
11
11
|
|
12
|
-
@databases = Hash.new {|h,k| h[k] = @prototype_db.clone}
|
12
|
+
@databases = Hash.new { |h, k| h[k] = @prototype_db.clone }
|
13
13
|
@databases[@db_index] = db
|
14
14
|
end
|
15
15
|
|
16
|
-
def respond_to?(method, include_private=false)
|
16
|
+
def respond_to?(method, include_private = false)
|
17
17
|
super || current_db.respond_to?(method, include_private)
|
18
18
|
end
|
19
19
|
|
@@ -44,7 +44,7 @@ class MockRedis
|
|
44
44
|
else
|
45
45
|
case current_db.type(key)
|
46
46
|
when 'hash'
|
47
|
-
dest.hmset(key, *(src.hgetall(key).map{|k,v| [k,v]}.flatten))
|
47
|
+
dest.hmset(key, *(src.hgetall(key).map { |k, v| [k, v] }.flatten))
|
48
48
|
when 'list'
|
49
49
|
while value = src.rpop(key)
|
50
50
|
dest.lpush(key, value)
|
@@ -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 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
|
@@ -75,6 +75,7 @@ class MockRedis
|
|
75
75
|
end
|
76
76
|
|
77
77
|
private
|
78
|
+
|
78
79
|
def current_db
|
79
80
|
@databases[@db_index]
|
80
81
|
end
|
@@ -2,7 +2,7 @@ class MockRedis
|
|
2
2
|
class PipelinedWrapper
|
3
3
|
include UndefRedisMethods
|
4
4
|
|
5
|
-
def respond_to?(method, include_private=false)
|
5
|
+
def respond_to?(method, include_private = false)
|
6
6
|
super || @db.respond_to?(method)
|
7
7
|
end
|
8
8
|
|
@@ -28,14 +28,14 @@ class MockRedis
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
def pipelined(
|
31
|
+
def pipelined(_options = {})
|
32
32
|
@in_pipeline = true
|
33
33
|
yield self
|
34
34
|
@in_pipeline = false
|
35
35
|
responses = @pipelined_futures.map do |future|
|
36
36
|
begin
|
37
37
|
result = send(*future.command)
|
38
|
-
future.
|
38
|
+
future.store_result(result)
|
39
39
|
result
|
40
40
|
rescue => e
|
41
41
|
e
|
@@ -13,7 +13,7 @@ class MockRedis
|
|
13
13
|
with_set_at(key) do |s|
|
14
14
|
if members.size > 1
|
15
15
|
size_before = s.size
|
16
|
-
members.
|
16
|
+
members.reverse_each { |m| s << m }
|
17
17
|
s.size - size_before
|
18
18
|
else
|
19
19
|
!!s.add?(members.first)
|
@@ -22,12 +22,12 @@ class MockRedis
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def scard(key)
|
25
|
-
with_set_at(key) {|s| s.length}
|
25
|
+
with_set_at(key) { |s| s.length }
|
26
26
|
end
|
27
27
|
|
28
28
|
def sdiff(*keys)
|
29
29
|
assert_has_args(keys, 'sdiff')
|
30
|
-
with_sets_at(*keys) {|*sets| sets.reduce(&:-)}.to_a
|
30
|
+
with_sets_at(*keys) { |*sets| sets.reduce(&:-) }.to_a
|
31
31
|
end
|
32
32
|
|
33
33
|
def sdiffstore(destination, *keys)
|
@@ -55,7 +55,7 @@ class MockRedis
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def sismember(key, member)
|
58
|
-
with_set_at(key) {|s| s.include?(member.to_s)}
|
58
|
+
with_set_at(key) { |s| s.include?(member.to_s) }
|
59
59
|
end
|
60
60
|
|
61
61
|
def smembers(key)
|
@@ -110,7 +110,7 @@ class MockRedis
|
|
110
110
|
|
111
111
|
def sunion(*keys)
|
112
112
|
assert_has_args(keys, 'sunion')
|
113
|
-
with_sets_at(*keys) {|*sets| sets.reduce(&:+).to_a}
|
113
|
+
with_sets_at(*keys) { |*sets| sets.reduce(&:+).to_a }
|
114
114
|
end
|
115
115
|
|
116
116
|
def sunionstore(destination, *keys)
|
@@ -122,8 +122,9 @@ class MockRedis
|
|
122
122
|
end
|
123
123
|
|
124
124
|
private
|
125
|
+
|
125
126
|
def with_set_at(key, &blk)
|
126
|
-
with_thing_at(key, :assert_sety, proc {Set.new}, &blk)
|
127
|
+
with_thing_at(key, :assert_sety, proc { Set.new }, &blk)
|
127
128
|
end
|
128
129
|
|
129
130
|
def with_sets_at(*keys, &blk)
|
@@ -140,15 +141,15 @@ class MockRedis
|
|
140
141
|
end
|
141
142
|
|
142
143
|
def sety?(key)
|
143
|
-
data[key].nil? || data[key].
|
144
|
+
data[key].nil? || data[key].is_a?(Set)
|
144
145
|
end
|
145
146
|
|
146
147
|
def assert_sety(key)
|
147
148
|
unless sety?(key)
|
148
149
|
# Not the most helpful error, but it's what redis-rb barfs up
|
149
|
-
raise Redis::CommandError,
|
150
|
+
raise Redis::CommandError,
|
151
|
+
'WRONGTYPE Operation against a key holding the wrong kind of value'
|
150
152
|
end
|
151
153
|
end
|
152
|
-
|
153
154
|
end
|
154
155
|
end
|
@@ -4,7 +4,7 @@ class MockRedis
|
|
4
4
|
module SortMethod
|
5
5
|
include Assertions
|
6
6
|
|
7
|
-
def sort(key, options={})
|
7
|
+
def sort(key, options = {})
|
8
8
|
return [] if key.nil?
|
9
9
|
|
10
10
|
enumerable = data[key]
|
@@ -15,7 +15,7 @@ class MockRedis
|
|
15
15
|
limit = options[:limit] || []
|
16
16
|
store = options[:store]
|
17
17
|
get_patterns = Array(options[:get])
|
18
|
-
order = options[:order] ||
|
18
|
+
order = options[:order] || 'ASC'
|
19
19
|
direction = order.split.first
|
20
20
|
|
21
21
|
projected = project(enumerable, by, get_patterns)
|
@@ -27,8 +27,8 @@ class MockRedis
|
|
27
27
|
|
28
28
|
private
|
29
29
|
|
30
|
-
ASCENDING_SORT =
|
31
|
-
DESCENDING_SORT =
|
30
|
+
ASCENDING_SORT = proc { |a, b| a.first <=> b.first }
|
31
|
+
DESCENDING_SORT = proc { |a, b| b.first <=> a.first }
|
32
32
|
|
33
33
|
def project(enumerable, by, get_patterns)
|
34
34
|
enumerable.map do |*elements|
|
@@ -38,7 +38,7 @@ class MockRedis
|
|
38
38
|
|
39
39
|
if get_patterns.length > 0
|
40
40
|
value = get_patterns.map do |pattern|
|
41
|
-
pattern ==
|
41
|
+
pattern == '#' ? element : lookup_from_pattern(pattern, element)
|
42
42
|
end
|
43
43
|
value = value.first if value.length == 1
|
44
44
|
end
|
@@ -50,12 +50,12 @@ class MockRedis
|
|
50
50
|
def sort_by(projected, direction)
|
51
51
|
sorter =
|
52
52
|
case direction.upcase
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
53
|
+
when 'DESC'
|
54
|
+
DESCENDING_SORT
|
55
|
+
when 'ASC', 'ALPHA'
|
56
|
+
ASCENDING_SORT
|
57
|
+
else
|
58
|
+
raise "Invalid direction '#{direction}'"
|
59
59
|
end
|
60
60
|
|
61
61
|
projected.sort(&sorter).map(&:last)
|
@@ -77,6 +77,5 @@ class MockRedis
|
|
77
77
|
get key
|
78
78
|
end
|
79
79
|
end
|
80
|
-
|
81
80
|
end
|
82
81
|
end
|
@@ -6,7 +6,7 @@ class MockRedis
|
|
6
6
|
|
7
7
|
def append(key, value)
|
8
8
|
assert_stringy(key)
|
9
|
-
data[key] ||=
|
9
|
+
data[key] ||= ''
|
10
10
|
data[key] << value
|
11
11
|
data[key].length
|
12
12
|
end
|
@@ -35,7 +35,7 @@ class MockRedis
|
|
35
35
|
offset_within_byte = offset % 8
|
36
36
|
|
37
37
|
# String#getbyte would be lovely, but it's not in 1.8.7.
|
38
|
-
byte = (data[key] ||
|
38
|
+
byte = (data[key] || '').each_byte.drop(offset_of_byte).first
|
39
39
|
|
40
40
|
if byte
|
41
41
|
(byte & (2**7 >> offset_within_byte)) > 0 ? 1 : 0
|
@@ -46,7 +46,7 @@ class MockRedis
|
|
46
46
|
|
47
47
|
def getrange(key, start, stop)
|
48
48
|
assert_stringy(key)
|
49
|
-
(data[key] ||
|
49
|
+
(data[key] || '')[start..stop]
|
50
50
|
end
|
51
51
|
|
52
52
|
def getset(key, value)
|
@@ -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 Redis::CommandError,
|
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 Redis::CommandError,
|
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
|
@@ -78,11 +78,11 @@ class MockRedis
|
|
78
78
|
def incrbyfloat(key, n)
|
79
79
|
assert_stringy(key)
|
80
80
|
unless can_incr_float?(data[key])
|
81
|
-
raise Redis::CommandError,
|
81
|
+
raise Redis::CommandError, 'ERR value is not a valid float'
|
82
82
|
end
|
83
83
|
|
84
84
|
unless looks_like_float?(n.to_s)
|
85
|
-
raise Redis::CommandError,
|
85
|
+
raise Redis::CommandError, 'ERR value is not a valid float'
|
86
86
|
end
|
87
87
|
|
88
88
|
new_value = data[key].to_f + n.to_f
|
@@ -106,14 +106,14 @@ class MockRedis
|
|
106
106
|
def mset(*kvpairs)
|
107
107
|
assert_has_args(kvpairs, 'mset')
|
108
108
|
if kvpairs.length.odd?
|
109
|
-
raise Redis::CommandError,
|
109
|
+
raise Redis::CommandError, 'ERR wrong number of arguments for MSET'
|
110
110
|
end
|
111
111
|
|
112
|
-
kvpairs.each_slice(2) do |(k,v)|
|
113
|
-
set(k,v)
|
112
|
+
kvpairs.each_slice(2) do |(k, v)|
|
113
|
+
set(k, v)
|
114
114
|
end
|
115
115
|
|
116
|
-
|
116
|
+
'OK'
|
117
117
|
end
|
118
118
|
|
119
119
|
def mapped_mset(hash)
|
@@ -123,7 +123,7 @@ class MockRedis
|
|
123
123
|
def msetnx(*kvpairs)
|
124
124
|
assert_has_args(kvpairs, 'msetnx')
|
125
125
|
|
126
|
-
if kvpairs.each_slice(2).any? {|(k,_)| exists(k)}
|
126
|
+
if kvpairs.each_slice(2).any? { |(k, _)| exists(k) }
|
127
127
|
false
|
128
128
|
else
|
129
129
|
mset(*kvpairs)
|
@@ -171,16 +171,16 @@ class MockRedis
|
|
171
171
|
end
|
172
172
|
|
173
173
|
def setbit(key, offset, value)
|
174
|
-
assert_stringy(key,
|
174
|
+
assert_stringy(key, 'ERR bit is not an integer or out of range')
|
175
175
|
retval = getbit(key, offset)
|
176
176
|
|
177
|
-
str = data[key] ||
|
177
|
+
str = data[key] || ''
|
178
178
|
|
179
179
|
offset_of_byte = offset / 8
|
180
180
|
offset_within_byte = offset % 8
|
181
181
|
|
182
182
|
if offset_of_byte >= str.bytesize
|
183
|
-
str = zero_pad(str, offset_of_byte+1)
|
183
|
+
str = zero_pad(str, offset_of_byte + 1)
|
184
184
|
end
|
185
185
|
|
186
186
|
char_index = byte_index = offset_within_char = 0
|
@@ -219,7 +219,7 @@ class MockRedis
|
|
219
219
|
def bitcount(key, start = 0, stop = -1)
|
220
220
|
assert_stringy(key)
|
221
221
|
|
222
|
-
str = data[key] ||
|
222
|
+
str = data[key] || ''
|
223
223
|
count = 0
|
224
224
|
m1 = 0x5555555555555555
|
225
225
|
m2 = 0x3333333333333333
|
@@ -231,10 +231,10 @@ class MockRedis
|
|
231
231
|
str.bytes.to_a[start..stop].each do |byte|
|
232
232
|
# Naive Hamming weight
|
233
233
|
c = byte
|
234
|
-
c = (c & m1)
|
235
|
-
c = (c & m2)
|
236
|
-
c = (c & m4)
|
237
|
-
c = (c & m8)
|
234
|
+
c = (c & m1) + ((c >> 1) & m1)
|
235
|
+
c = (c & m2) + ((c >> 2) & m2)
|
236
|
+
c = (c & m4) + ((c >> 4) & m4)
|
237
|
+
c = (c & m8) + ((c >> 8) & m8)
|
238
238
|
c = (c & m16) + ((c >> 16) & m16)
|
239
239
|
c = (c & m32) + ((c >> 32) & m32)
|
240
240
|
count += c
|
@@ -261,32 +261,29 @@ class MockRedis
|
|
261
261
|
def setrange(key, offset, value)
|
262
262
|
assert_stringy(key)
|
263
263
|
value = value.to_s
|
264
|
-
old_value = (data[key] ||
|
264
|
+
old_value = (data[key] || '')
|
265
265
|
|
266
266
|
prefix = zero_pad(old_value[0...offset], offset)
|
267
|
-
data[key] = prefix + value + (old_value[(offset + value.length)..-1] ||
|
267
|
+
data[key] = prefix + value + (old_value[(offset + value.length)..-1] || '')
|
268
268
|
data[key].length
|
269
269
|
end
|
270
270
|
|
271
271
|
def strlen(key)
|
272
272
|
assert_stringy(key)
|
273
|
-
(data[key] ||
|
273
|
+
(data[key] || '').bytesize
|
274
274
|
end
|
275
275
|
|
276
|
-
|
277
|
-
|
278
|
-
|
279
276
|
private
|
277
|
+
|
280
278
|
def stringy?(key)
|
281
|
-
data[key].nil? || data[key].
|
279
|
+
data[key].nil? || data[key].is_a?(String)
|
282
280
|
end
|
283
281
|
|
284
282
|
def assert_stringy(key,
|
285
|
-
message=
|
283
|
+
message = 'WRONGTYPE Operation against a key holding the wrong kind of value')
|
286
284
|
unless stringy?(key)
|
287
285
|
raise Redis::CommandError, message
|
288
286
|
end
|
289
287
|
end
|
290
|
-
|
291
288
|
end
|
292
289
|
end
|
@@ -4,7 +4,7 @@ class MockRedis
|
|
4
4
|
class TransactionWrapper
|
5
5
|
include UndefRedisMethods
|
6
6
|
|
7
|
-
def respond_to?(method, include_private=false)
|
7
|
+
def respond_to?(method, include_private = false)
|
8
8
|
super || @db.respond_to?(method)
|
9
9
|
end
|
10
10
|
|
@@ -39,7 +39,7 @@ class MockRedis
|
|
39
39
|
|
40
40
|
def discard
|
41
41
|
unless @in_multi
|
42
|
-
raise Redis::CommandError,
|
42
|
+
raise Redis::CommandError, 'ERR DISCARD without MULTI'
|
43
43
|
end
|
44
44
|
@in_multi = false
|
45
45
|
@multi_block_given = false
|
@@ -49,7 +49,7 @@ class MockRedis
|
|
49
49
|
|
50
50
|
def exec
|
51
51
|
unless @in_multi
|
52
|
-
raise Redis::CommandError,
|
52
|
+
raise Redis::CommandError, 'ERR EXEC without MULTI'
|
53
53
|
end
|
54
54
|
@in_multi = false
|
55
55
|
@multi_block_given = false
|
@@ -57,7 +57,7 @@ class MockRedis
|
|
57
57
|
responses = @transaction_futures.map do |future|
|
58
58
|
begin
|
59
59
|
result = send(*future.command)
|
60
|
-
future.
|
60
|
+
future.store_result(result)
|
61
61
|
result
|
62
62
|
rescue => e
|
63
63
|
e
|
@@ -70,16 +70,16 @@ class MockRedis
|
|
70
70
|
|
71
71
|
def multi
|
72
72
|
if @in_multi
|
73
|
-
raise Redis::CommandError,
|
73
|
+
raise Redis::CommandError, 'ERR MULTI calls can not be nested'
|
74
74
|
end
|
75
75
|
@in_multi = true
|
76
76
|
if block_given?
|
77
77
|
@multi_block_given = true
|
78
78
|
begin
|
79
79
|
yield(self)
|
80
|
-
|
80
|
+
exec
|
81
81
|
rescue StandardError => e
|
82
|
-
|
82
|
+
discard
|
83
83
|
raise e
|
84
84
|
end
|
85
85
|
else
|
@@ -98,6 +98,5 @@ class MockRedis
|
|
98
98
|
'OK'
|
99
99
|
end
|
100
100
|
end
|
101
|
-
|
102
101
|
end
|
103
102
|
end
|
@@ -3,20 +3,18 @@ class MockRedis
|
|
3
3
|
private
|
4
4
|
|
5
5
|
def with_thing_at(key, assertion, empty_thing_generator)
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
clean_up_empties_at(key)
|
15
|
-
end
|
6
|
+
send(assertion, key)
|
7
|
+
data[key] ||= empty_thing_generator.call
|
8
|
+
data_key_ref = data[key]
|
9
|
+
ret = yield data[key]
|
10
|
+
data[key] = data_key_ref if data[key].nil?
|
11
|
+
primitive?(ret) ? ret.dup : ret
|
12
|
+
ensure
|
13
|
+
clean_up_empties_at(key)
|
16
14
|
end
|
17
15
|
|
18
16
|
def primitive?(value)
|
19
|
-
value.
|
17
|
+
value.is_a?(::Array) || value.is_a?(::Hash) || value.is_a?(::String)
|
20
18
|
end
|
21
19
|
|
22
20
|
def clean_up_empties_at(key)
|
@@ -24,6 +22,5 @@ class MockRedis
|
|
24
22
|
del(key)
|
25
23
|
end
|
26
24
|
end
|
27
|
-
|
28
25
|
end
|
29
26
|
end
|