mock_redis 0.22.0 → 0.23.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/lib/mock_redis.rb +0 -7
- data/lib/mock_redis/database.rb +25 -2
- data/lib/mock_redis/string_methods.rb +8 -4
- data/lib/mock_redis/version.rb +1 -1
- data/lib/mock_redis/zset_methods.rb +34 -9
- data/spec/commands/dump_spec.rb +19 -0
- data/spec/commands/pipelined_spec.rb +20 -0
- data/spec/commands/restore_spec.rb +47 -0
- data/spec/commands/set_spec.rb +4 -2
- data/spec/commands/setex_spec.rb +16 -0
- data/spec/commands/zinterstore_spec.rb +34 -0
- data/spec/commands/zunionstore_spec.rb +33 -0
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dd9fd0d5b4ccad106eee03697d49082baa7e34065ff76f67b7e18da9991847a9
|
4
|
+
data.tar.gz: 11f940cdee40f2646c3e6087faac7ac1c70e0aae5eaff7ddfc8839f0fb50e1b6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 347930a11a59575cd3a4bbc48cb689d46d25b27c6cfbdc28c28b6bfdfa1d833c317dd5ce7566ba016aae7b13b909629d078486bd95dee68f4e7e6b5cfc7e1e44
|
7
|
+
data.tar.gz: 689b8dc84b58c38201bf3220641f467cd56b3ef2d6c4efc12829ec08c3a84f6dbc1e2c8207fdb18808c10bdb71f878cc571d21df2548a9d240881fff8b9ddd68
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
# MockRedis Changelog
|
2
2
|
|
3
|
+
### 0.23.0
|
4
|
+
|
5
|
+
* Raise error when `setex` called with negative timeout ([#174](https://github.com/sds/mock_redis/pull/174))
|
6
|
+
* Add support for `dump`/`restore` between MockRedis instances ([#176](https://github.com/sds/mock_redis/pull/176))
|
7
|
+
* Fix warnings for ZSET methods on Ruby 2.7 ([#177](https://github.com/sds/mock_redis/pull/177))
|
8
|
+
* Add support for returning time in pipelines ([#179](https://github.com/sds/mock_redis/pull/179))
|
9
|
+
* Fix SET methods to correct set milliseconds with `px` ([#180](https://github.com/sds/mock_redis/pull/180))
|
10
|
+
* Add support for unsorted sets within `zinterstore`/`zunionstore`([#182](https://github.com/sds/mock_redis/pull/182))
|
11
|
+
|
3
12
|
### 0.22.0
|
4
13
|
|
5
14
|
* Gracefully handle cursors larger than the collection size in scan commands ([#171](https://github.com/sds/mock_redis/pull/171))
|
data/lib/mock_redis.rb
CHANGED
@@ -64,13 +64,6 @@ class MockRedis
|
|
64
64
|
options[:db]
|
65
65
|
end
|
66
66
|
|
67
|
-
def now
|
68
|
-
current_time = options[:time_class].now
|
69
|
-
miliseconds = (current_time.to_r - current_time.to_i) * 1_000
|
70
|
-
[current_time.to_i, miliseconds.to_i]
|
71
|
-
end
|
72
|
-
alias time now
|
73
|
-
|
74
67
|
def time_at(timestamp)
|
75
68
|
options[:time_class].at(timestamp)
|
76
69
|
end
|
data/lib/mock_redis/database.rb
CHANGED
@@ -124,6 +124,22 @@ class MockRedis
|
|
124
124
|
'OK'
|
125
125
|
end
|
126
126
|
|
127
|
+
def dump(key)
|
128
|
+
value = data[key]
|
129
|
+
value ? Marshal.dump(value) : nil
|
130
|
+
end
|
131
|
+
|
132
|
+
def restore(key, ttl, value, replace: false)
|
133
|
+
if !replace && exists(key)
|
134
|
+
raise Redis::CommandError, 'BUSYKEY Target key name already exists.'
|
135
|
+
end
|
136
|
+
data[key] = Marshal.load(value) # rubocop:disable Security/MarshalLoad
|
137
|
+
if ttl > 0
|
138
|
+
pexpire(key, ttl)
|
139
|
+
end
|
140
|
+
'OK'
|
141
|
+
end
|
142
|
+
|
127
143
|
def keys(format = '*')
|
128
144
|
data.keys.grep(redis_pattern_to_ruby_regex(format))
|
129
145
|
end
|
@@ -143,7 +159,7 @@ class MockRedis
|
|
143
159
|
end
|
144
160
|
|
145
161
|
def lastsave
|
146
|
-
|
162
|
+
now.first
|
147
163
|
end
|
148
164
|
|
149
165
|
def persist(key)
|
@@ -224,6 +240,13 @@ class MockRedis
|
|
224
240
|
end
|
225
241
|
end
|
226
242
|
|
243
|
+
def now
|
244
|
+
current_time = @base.options[:time_class].now
|
245
|
+
miliseconds = (current_time.to_r - current_time.to_i) * 1_000
|
246
|
+
[current_time.to_i, miliseconds.to_i]
|
247
|
+
end
|
248
|
+
alias time now
|
249
|
+
|
227
250
|
def type(key)
|
228
251
|
if !exists(key)
|
229
252
|
'none'
|
@@ -328,7 +351,7 @@ class MockRedis
|
|
328
351
|
# This method isn't private, but it also isn't a Redis command, so
|
329
352
|
# it doesn't belong up above with all the Redis commands.
|
330
353
|
def expire_keys
|
331
|
-
now, miliseconds =
|
354
|
+
now, miliseconds = self.now
|
332
355
|
now_ms = now * 1_000 + miliseconds
|
333
356
|
|
334
357
|
to_delete = expire_times.take_while do |(time, _key)|
|
@@ -233,7 +233,7 @@ class MockRedis
|
|
233
233
|
if duration == 0
|
234
234
|
raise Redis::CommandError, 'ERR invalid expire time in set'
|
235
235
|
end
|
236
|
-
|
236
|
+
pexpire(key, duration)
|
237
237
|
end
|
238
238
|
|
239
239
|
return_true ? true : 'OK'
|
@@ -313,9 +313,13 @@ class MockRedis
|
|
313
313
|
end
|
314
314
|
|
315
315
|
def setex(key, seconds, value)
|
316
|
-
|
317
|
-
|
318
|
-
|
316
|
+
if seconds <= 0
|
317
|
+
raise Redis::CommandError, 'ERR invalid expire time in setex'
|
318
|
+
else
|
319
|
+
set(key, value)
|
320
|
+
expire(key, seconds)
|
321
|
+
'OK'
|
322
|
+
end
|
319
323
|
end
|
320
324
|
|
321
325
|
def setnx(key, value)
|
data/lib/mock_redis/version.rb
CHANGED
@@ -26,7 +26,7 @@ class MockRedis
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def zadd_one_member(key, score, member, zadd_options = {})
|
29
|
-
assert_scorey(score) unless score =~ /(\+|\-)inf/
|
29
|
+
assert_scorey(score) unless score.to_s =~ /(\+|\-)inf/
|
30
30
|
|
31
31
|
with_zset_at(key) do |zset|
|
32
32
|
if zadd_options[:incr]
|
@@ -282,7 +282,7 @@ class MockRedis
|
|
282
282
|
raise Redis::CommandError, 'ERR syntax error'
|
283
283
|
end
|
284
284
|
|
285
|
-
with_zsets_at(*keys) do |*zsets|
|
285
|
+
with_zsets_at(*keys, coercible: true) do |*zsets|
|
286
286
|
zsets.zip(weights).map do |(zset, weight)|
|
287
287
|
zset.reduce(Zset.new) do |acc, (score, member)|
|
288
288
|
acc.add(score * weight, member)
|
@@ -293,16 +293,30 @@ class MockRedis
|
|
293
293
|
end
|
294
294
|
end
|
295
295
|
|
296
|
-
def
|
297
|
-
|
296
|
+
def coerce_to_zset(set)
|
297
|
+
zset = Zset.new
|
298
|
+
set.each do |member|
|
299
|
+
zset.add(1.0, member)
|
300
|
+
end
|
301
|
+
zset
|
298
302
|
end
|
299
303
|
|
300
|
-
def
|
304
|
+
def with_zset_at(key, coercible: false, &blk)
|
305
|
+
if coercible
|
306
|
+
with_thing_at(key, :assert_coercible_zsety, proc { Zset.new }) do |value|
|
307
|
+
blk.call value.is_a?(Set) ? coerce_to_zset(value) : value
|
308
|
+
end
|
309
|
+
else
|
310
|
+
with_thing_at(key, :assert_zsety, proc { Zset.new }, &blk)
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
def with_zsets_at(*keys, coercible: false, &blk)
|
301
315
|
if keys.length == 1
|
302
|
-
with_zset_at(keys.first, &blk)
|
316
|
+
with_zset_at(keys.first, coercible: coercible, &blk)
|
303
317
|
else
|
304
|
-
with_zset_at(keys.first) do |set|
|
305
|
-
with_zsets_at(*(keys[1..-1])) do |*sets|
|
318
|
+
with_zset_at(keys.first, coercible: coercible) do |set|
|
319
|
+
with_zsets_at(*(keys[1..-1]), coercible: coercible) do |*sets|
|
306
320
|
yield(*([set] + sets))
|
307
321
|
end
|
308
322
|
end
|
@@ -313,6 +327,10 @@ class MockRedis
|
|
313
327
|
data[key].nil? || data[key].is_a?(Zset)
|
314
328
|
end
|
315
329
|
|
330
|
+
def coercible_zsety?(key)
|
331
|
+
zsety?(key) || data[key].is_a?(Set)
|
332
|
+
end
|
333
|
+
|
316
334
|
def assert_zsety(key)
|
317
335
|
unless zsety?(key)
|
318
336
|
raise Redis::CommandError,
|
@@ -320,13 +338,20 @@ class MockRedis
|
|
320
338
|
end
|
321
339
|
end
|
322
340
|
|
341
|
+
def assert_coercible_zsety(key)
|
342
|
+
unless coercible_zsety?(key)
|
343
|
+
raise Redis::CommandError,
|
344
|
+
'WRONGTYPE Operation against a key holding the wrong kind of value'
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
323
348
|
def looks_like_float?(x)
|
324
349
|
# ugh, exceptions for flow control.
|
325
350
|
!!Float(x) rescue false
|
326
351
|
end
|
327
352
|
|
328
353
|
def assert_scorey(value, message = 'ERR value is not a valid float')
|
329
|
-
return if value =~ /\(?(\-|\+)inf/
|
354
|
+
return if value.to_s =~ /\(?(\-|\+)inf/
|
330
355
|
|
331
356
|
value = $1 if value.to_s =~ /\((.*)/
|
332
357
|
unless looks_like_float?(value)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe '#dump(key)' do
|
4
|
+
before do
|
5
|
+
@key = 'mock-redis-test:45794'
|
6
|
+
# These are mock-only, since our dump/restore implementations
|
7
|
+
# aren't compatible with real redis.
|
8
|
+
@mock = @redises.mock
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'returns nil for keys that do not exist' do
|
12
|
+
@mock.dump(@key).should be_nil
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'returns a serialized value for keys that do exist' do
|
16
|
+
@mock.set(@key, '2')
|
17
|
+
@mock.dump(@key).should == Marshal.dump('2')
|
18
|
+
end
|
19
|
+
end
|
@@ -66,6 +66,26 @@ describe '#pipelined' do
|
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
+
context 'with redis time return value' do
|
70
|
+
let(:time_stub) { double 'Time', :now => Time.new(2019, 1, 2, 3, 4, 6, '+00:00') }
|
71
|
+
let(:options) { { :time_class => time_stub } }
|
72
|
+
|
73
|
+
subject { MockRedis.new(options) }
|
74
|
+
|
75
|
+
it 'returns the time value' do
|
76
|
+
subject.set('foo', 'bar')
|
77
|
+
|
78
|
+
results = subject.pipelined do
|
79
|
+
subject.get('foo')
|
80
|
+
subject.host # defined on MockRedis, so not captured
|
81
|
+
subject.time
|
82
|
+
subject.echo('baz')
|
83
|
+
end
|
84
|
+
|
85
|
+
expect(results).to eq(['bar', [1_546_398_246, 0], 'baz'])
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
69
89
|
context 'with nested pipelines' do
|
70
90
|
let(:key1) { 'hello' }
|
71
91
|
let(:key2) { 'world' }
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe '#restore(key, ttl, value)' do
|
4
|
+
before do
|
5
|
+
@key = 'mock-redis-test:45794'
|
6
|
+
@src = MockRedis.new
|
7
|
+
@src.set(@key, '123')
|
8
|
+
@dumped_value = @src.dump(@key)
|
9
|
+
@dst = MockRedis.new
|
10
|
+
@now = Time.now.round
|
11
|
+
Time.stub(:now).and_return(@now)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'allows dump/restoring values between two redis instances' do
|
15
|
+
expect(@dst.restore(@key, 0, @dumped_value)).to eq('OK')
|
16
|
+
expect(@dst.get(@key)).to eq('123')
|
17
|
+
expect(@dst.pttl(@key)).to eq(-1)
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'when the key being restored to already exists' do
|
21
|
+
before do
|
22
|
+
@dst.set(@key, '456')
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'raises an error by default' do
|
26
|
+
expect { @dst.restore(@key, 0, @dumped_value) }.to raise_error(Redis::CommandError)
|
27
|
+
expect(@dst.get(@key)).to eq('456')
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'allows replacing the key if replace==true' do
|
31
|
+
expect(@dst.restore(@key, 0, @dumped_value, replace: true)).to eq('OK')
|
32
|
+
expect(@dst.get(@key)).to eq('123')
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'sets ttl in ms' do
|
37
|
+
@dst.restore(@key, 500, @dumped_value)
|
38
|
+
expect(@dst.pttl(@key)).to eq(500)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'can dump/restore more complex data types' do
|
42
|
+
key = 'a_hash'
|
43
|
+
@src.mapped_hmset(key, foo: 'bar')
|
44
|
+
@dst.restore(key, 0, @src.dump(key))
|
45
|
+
expect(@dst.hgetall(key)).to eq('foo' => 'bar')
|
46
|
+
end
|
47
|
+
end
|
data/spec/commands/set_spec.rb
CHANGED
@@ -59,9 +59,11 @@ describe '#set(key, value)' do
|
|
59
59
|
|
60
60
|
it 'accepts PX milliseconds' do
|
61
61
|
key = 'mock-redis-test'
|
62
|
-
@mock.set(key, 1, px:
|
62
|
+
@mock.set(key, 1, px: 500).should == 'OK'
|
63
63
|
@mock.get(key).should_not be_nil
|
64
|
-
Time.stub(:now).and_return(@now +
|
64
|
+
Time.stub(:now).and_return(@now + 300 / 1000.to_f)
|
65
|
+
@mock.get(key).should_not be_nil
|
66
|
+
Time.stub(:now).and_return(@now + 600 / 1000.to_f)
|
65
67
|
@mock.get(key).should be_nil
|
66
68
|
end
|
67
69
|
end
|
data/spec/commands/setex_spec.rb
CHANGED
@@ -19,4 +19,20 @@ describe '#setex(key, seconds, value)' do
|
|
19
19
|
@redises.real.ttl(@key).should > 0
|
20
20
|
@redises.mock.ttl(@key).should > 0
|
21
21
|
end
|
22
|
+
|
23
|
+
context 'when expiration time is zero' do
|
24
|
+
it 'raises Redis::CommandError' do
|
25
|
+
expect do
|
26
|
+
@redises.setex(@key, 0, 'value')
|
27
|
+
end.to raise_error(Redis::CommandError, 'ERR invalid expire time in setex')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'when expiration time is negative' do
|
32
|
+
it 'raises Redis::CommandError' do
|
33
|
+
expect do
|
34
|
+
@redises.setex(@key, -2, 'value')
|
35
|
+
end.to raise_error(Redis::CommandError, 'ERR invalid expire time in setex')
|
36
|
+
end
|
37
|
+
end
|
22
38
|
end
|
@@ -42,6 +42,40 @@ describe '#zinterstore(destination, keys, [:weights => [w,w,], [:aggregate => :s
|
|
42
42
|
end.should raise_error(Redis::CommandError)
|
43
43
|
end
|
44
44
|
|
45
|
+
context 'when used with a set' do
|
46
|
+
before do
|
47
|
+
@primes_text = 'mock-redis-test:zinterstore:primes-text'
|
48
|
+
|
49
|
+
@redises.sadd(@primes_text, 'two')
|
50
|
+
@redises.sadd(@primes_text, 'three')
|
51
|
+
@redises.sadd(@primes_text, 'five')
|
52
|
+
@redises.sadd(@primes_text, 'seven')
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'returns the number of elements in the new set' do
|
56
|
+
@redises.zinterstore(@dest, [@odds, @primes_text]).should == 3
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'sums the scores, substituting 1.0 for set values' do
|
60
|
+
@redises.zinterstore(@dest, [@odds, @primes_text])
|
61
|
+
@redises.zrange(@dest, 0, -1, :with_scores => true).should ==
|
62
|
+
[['three', 4.0], ['five', 6.0], ['seven', 8.0]]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'when used with a non-coercible structure' do
|
67
|
+
before do
|
68
|
+
@non_set = 'mock-redis-test:zinterstore:non-set'
|
69
|
+
|
70
|
+
@redises.set(@non_set, 'one')
|
71
|
+
end
|
72
|
+
it 'raises an error for wrong value type' do
|
73
|
+
lambda do
|
74
|
+
@redises.zinterstore(@dest, [@odds, @non_set])
|
75
|
+
end.should raise_error(Redis::CommandError)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
45
79
|
context 'the :weights argument' do
|
46
80
|
it 'multiplies the scores by the weights while aggregating' do
|
47
81
|
@redises.zinterstore(@dest, [@odds, @primes], :weights => [2, 3])
|
@@ -41,6 +41,39 @@ describe '#zunionstore(destination, keys, [:weights => [w,w,], [:aggregate => :s
|
|
41
41
|
end.should raise_error(Redis::CommandError)
|
42
42
|
end
|
43
43
|
|
44
|
+
context 'when used with a set' do
|
45
|
+
before do
|
46
|
+
@set4 = 'mock-redis-test:zunionstore4'
|
47
|
+
|
48
|
+
@redises.sadd(@set4, 'two')
|
49
|
+
@redises.sadd(@set4, 'three')
|
50
|
+
@redises.sadd(@set4, 'four')
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'returns the number of elements in the new set' do
|
54
|
+
@redises.zunionstore(@dest, [@set3, @set4]).should == 4
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'sums the scores, substituting 1.0 for set values' do
|
58
|
+
@redises.zunionstore(@dest, [@set3, @set4])
|
59
|
+
@redises.zrange(@dest, 0, -1, :with_scores => true).should ==
|
60
|
+
[['four', 1.0], ['one', 1.0], ['two', 3.0], ['three', 4.0]]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'when used with a non-coercible structure' do
|
65
|
+
before do
|
66
|
+
@non_set = 'mock-redis-test:zunionstore4'
|
67
|
+
|
68
|
+
@redises.set(@non_set, 'one')
|
69
|
+
end
|
70
|
+
it 'raises an error for wrong value type' do
|
71
|
+
lambda do
|
72
|
+
@redises.zunionstore(@dest, [@set1, @non_set])
|
73
|
+
end.should raise_error(Redis::CommandError)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
44
77
|
context 'the :weights argument' do
|
45
78
|
it 'multiplies the scores by the weights while aggregating' do
|
46
79
|
@redises.zunionstore(@dest, [@set1, @set2, @set3], :weights => [2, 3, 5])
|
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.
|
4
|
+
version: 0.23.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:
|
12
|
+
date: 2020-04-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: redis
|
@@ -131,6 +131,7 @@ files:
|
|
131
131
|
- spec/commands/decrby_spec.rb
|
132
132
|
- spec/commands/del_spec.rb
|
133
133
|
- spec/commands/disconnect_spec.rb
|
134
|
+
- spec/commands/dump_spec.rb
|
134
135
|
- spec/commands/echo_spec.rb
|
135
136
|
- spec/commands/eval_spec.rb
|
136
137
|
- spec/commands/evalsha_spec.rb
|
@@ -198,6 +199,7 @@ files:
|
|
198
199
|
- spec/commands/randomkey_spec.rb
|
199
200
|
- spec/commands/rename_spec.rb
|
200
201
|
- spec/commands/renamenx_spec.rb
|
202
|
+
- spec/commands/restore_spec.rb
|
201
203
|
- spec/commands/rpop_spec.rb
|
202
204
|
- spec/commands/rpoplpush_spec.rb
|
203
205
|
- spec/commands/rpush_spec.rb
|
@@ -291,7 +293,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
291
293
|
- !ruby/object:Gem::Version
|
292
294
|
version: '0'
|
293
295
|
requirements: []
|
294
|
-
rubygems_version: 3.
|
296
|
+
rubygems_version: 3.1.1
|
295
297
|
signing_key:
|
296
298
|
specification_version: 4
|
297
299
|
summary: Redis mock that just lives in memory; useful for testing.
|
@@ -313,6 +315,7 @@ test_files:
|
|
313
315
|
- spec/commands/decrby_spec.rb
|
314
316
|
- spec/commands/del_spec.rb
|
315
317
|
- spec/commands/disconnect_spec.rb
|
318
|
+
- spec/commands/dump_spec.rb
|
316
319
|
- spec/commands/echo_spec.rb
|
317
320
|
- spec/commands/eval_spec.rb
|
318
321
|
- spec/commands/evalsha_spec.rb
|
@@ -380,6 +383,7 @@ test_files:
|
|
380
383
|
- spec/commands/randomkey_spec.rb
|
381
384
|
- spec/commands/rename_spec.rb
|
382
385
|
- spec/commands/renamenx_spec.rb
|
386
|
+
- spec/commands/restore_spec.rb
|
383
387
|
- spec/commands/rpop_spec.rb
|
384
388
|
- spec/commands/rpoplpush_spec.rb
|
385
389
|
- spec/commands/rpush_spec.rb
|