mock_redis 0.21.0 → 0.26.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +26 -5
- data/.rubocop_todo.yml +1 -1
- data/.travis.yml +3 -3
- data/CHANGELOG.md +33 -0
- data/Gemfile +2 -2
- data/LICENSE.md +21 -0
- data/README.md +37 -13
- data/lib/mock_redis.rb +0 -7
- data/lib/mock_redis/database.rb +42 -14
- data/lib/mock_redis/future.rb +1 -1
- data/lib/mock_redis/geospatial_methods.rb +4 -4
- data/lib/mock_redis/hash_methods.rb +18 -6
- data/lib/mock_redis/info_method.rb +2 -2
- data/lib/mock_redis/multi_db_wrapper.rb +2 -2
- data/lib/mock_redis/stream.rb +25 -2
- data/lib/mock_redis/stream/id.rb +1 -1
- data/lib/mock_redis/stream_methods.rb +16 -1
- data/lib/mock_redis/string_methods.rb +17 -9
- data/lib/mock_redis/transaction_wrapper.rb +2 -2
- data/lib/mock_redis/utility_methods.rb +6 -3
- data/lib/mock_redis/version.rb +1 -1
- data/lib/mock_redis/zset_methods.rb +52 -9
- data/mock_redis.gemspec +1 -2
- data/spec/commands/blpop_spec.rb +0 -6
- data/spec/commands/brpop_spec.rb +6 -5
- data/spec/commands/del_spec.rb +15 -0
- data/spec/commands/dump_spec.rb +19 -0
- data/spec/commands/exists_spec.rb +34 -5
- data/spec/commands/future_spec.rb +11 -1
- data/spec/commands/geoadd_spec.rb +1 -1
- data/spec/commands/hmset_spec.rb +26 -0
- data/spec/commands/hset_spec.rb +6 -6
- data/spec/commands/keys_spec.rb +17 -0
- data/spec/commands/mget_spec.rb +6 -0
- data/spec/commands/move_spec.rb +5 -5
- data/spec/commands/pipelined_spec.rb +20 -0
- data/spec/commands/restore_spec.rb +47 -0
- data/spec/commands/scan_spec.rb +9 -0
- data/spec/commands/set_spec.rb +8 -4
- data/spec/commands/setbit_spec.rb +1 -0
- data/spec/commands/setex_spec.rb +16 -0
- data/spec/commands/srandmember_spec.rb +1 -1
- data/spec/commands/xadd_spec.rb +20 -0
- data/spec/commands/xrange_spec.rb +13 -0
- data/spec/commands/xread_spec.rb +66 -0
- data/spec/commands/xtrim_spec.rb +6 -0
- data/spec/commands/zinterstore_spec.rb +34 -0
- data/spec/commands/zpopmax_spec.rb +60 -0
- data/spec/commands/zpopmin_spec.rb +60 -0
- data/spec/commands/zrange_spec.rb +1 -1
- data/spec/commands/zrangebyscore_spec.rb +1 -1
- data/spec/commands/zrevrange_spec.rb +1 -1
- data/spec/commands/zrevrangebyscore_spec.rb +1 -1
- data/spec/commands/zunionstore_spec.rb +33 -0
- data/spec/spec_helper.rb +4 -2
- data/spec/support/redis_multiplexer.rb +1 -0
- data/spec/transactions_spec.rb +16 -0
- metadata +16 -26
- data/LICENSE +0 -19
@@ -1,14 +1,43 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe '#exists(
|
4
|
-
before { @
|
3
|
+
describe '#exists(*keys)' do
|
4
|
+
before { @key1 = 'mock-redis-test:exists1' }
|
5
|
+
before { @key2 = 'mock-redis-test:exists2' }
|
6
|
+
|
7
|
+
it 'returns 0 for keys that do not exist' do
|
8
|
+
@redises.exists(@key1).should == 0
|
9
|
+
@redises.exists(@key1, @key2).should == 0
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'returns 1 for keys that do exist' do
|
13
|
+
@redises.set(@key1, 1)
|
14
|
+
@redises.exists(@key1).should == 1
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'returns the count of all keys that exist' do
|
18
|
+
@redises.set(@key1, 1)
|
19
|
+
@redises.set(@key2, 1)
|
20
|
+
@redises.exists(@key1, @key2).should == 2
|
21
|
+
@redises.exists(@key1, @key2, 'does-not-exist').should == 2
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#exists?(*keys)' do
|
26
|
+
before { @key1 = 'mock-redis-test:exists1' }
|
27
|
+
before { @key2 = 'mock-redis-test:exists2' }
|
5
28
|
|
6
29
|
it 'returns false for keys that do not exist' do
|
7
|
-
@redises.exists(@
|
30
|
+
@redises.exists?(@key1).should == false
|
31
|
+
@redises.exists?(@key1, @key2).should == false
|
8
32
|
end
|
9
33
|
|
10
34
|
it 'returns true for keys that do exist' do
|
11
|
-
@redises.set(@
|
12
|
-
@redises.exists(@
|
35
|
+
@redises.set(@key1, 1)
|
36
|
+
@redises.exists?(@key1).should == true
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'returns true if any keys exist' do
|
40
|
+
@redises.set(@key2, 1)
|
41
|
+
@redises.exists?(@key1, @key2).should == true
|
13
42
|
end
|
14
43
|
end
|
@@ -3,7 +3,12 @@ require 'spec_helper'
|
|
3
3
|
describe MockRedis::Future do
|
4
4
|
let(:command) { [:get, 'foo'] }
|
5
5
|
let(:result) { 'bar' }
|
6
|
-
|
6
|
+
let(:block) { ->(value) { value.upcase } }
|
7
|
+
|
8
|
+
before do
|
9
|
+
@future = MockRedis::Future.new(command)
|
10
|
+
@future2 = MockRedis::Future.new(command, block)
|
11
|
+
end
|
7
12
|
|
8
13
|
it 'remembers the command' do
|
9
14
|
@future.command.should eq(command)
|
@@ -17,4 +22,9 @@ describe MockRedis::Future do
|
|
17
22
|
@future.store_result(result)
|
18
23
|
@future.value.should eq(result)
|
19
24
|
end
|
25
|
+
|
26
|
+
it 'executes the block on the value if block is passed in' do
|
27
|
+
@future2.store_result(result)
|
28
|
+
@future2.value.should eq('BAR')
|
29
|
+
end
|
20
30
|
end
|
@@ -33,7 +33,7 @@ describe '#geoadd' do
|
|
33
33
|
context 'when coordinates are not in allowed range' do
|
34
34
|
let(:coords) { [181, 86] }
|
35
35
|
let(:message) do
|
36
|
-
formatted_coords = coords.map { |c| format('
|
36
|
+
formatted_coords = coords.map { |c| format('%<coords>.6f', coords: c) }
|
37
37
|
"ERR invalid longitude,latitude pair #{formatted_coords.join(',')}"
|
38
38
|
end
|
39
39
|
|
data/spec/commands/hmset_spec.rb
CHANGED
@@ -39,5 +39,31 @@ describe '#hmset(key, field, value [, field, value ...])' do
|
|
39
39
|
end.should raise_error(Redis::CommandError)
|
40
40
|
end
|
41
41
|
|
42
|
+
# The following tests address https://github.com/sds/mock_redis/issues/170
|
43
|
+
context 'keys are stored as strings' do
|
44
|
+
before do
|
45
|
+
@redises.hmset(1, :foo, :bar)
|
46
|
+
@redises.hmset(:a_sym, :boo, :bas)
|
47
|
+
end
|
48
|
+
|
49
|
+
it { expect(@redises.hgetall('1')).to eq @redises.hgetall(1) }
|
50
|
+
it { expect(@redises.hgetall('a_sym')).to eq @redises.hgetall(:a_sym) }
|
51
|
+
it { expect(@redises.del('1')).to eq 1 }
|
52
|
+
it { expect(@redises.del(1)).to eq 1 }
|
53
|
+
it { expect(@redises.del('a_sym')).to eq 1 }
|
54
|
+
it { expect(@redises.del(:a_sym)).to eq 1 }
|
55
|
+
|
56
|
+
after do
|
57
|
+
@redises.del(1)
|
58
|
+
@redises.del(:a_sym)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# The following tests address https://github.com/sds/mock_redis/issues/134
|
63
|
+
context 'hmset accepts an array as its only argument' do
|
64
|
+
it { expect(@redises.hmset([@key, :bar, :bas])).to eq 'OK' }
|
65
|
+
it { lambda { @redises.hmset([:foo, :bar]) }.should raise_error(Redis::CommandError) }
|
66
|
+
end
|
67
|
+
|
42
68
|
it_should_behave_like 'a hash-only command'
|
43
69
|
end
|
data/spec/commands/hset_spec.rb
CHANGED
@@ -5,18 +5,18 @@ describe '#hset(key, field)' do
|
|
5
5
|
@key = 'mock-redis-test:hset'
|
6
6
|
end
|
7
7
|
|
8
|
-
it 'returns
|
9
|
-
@redises.hset(@key, 'k1', 'v1').should ==
|
8
|
+
it 'returns 1 if the key does not exist' do
|
9
|
+
@redises.hset(@key, 'k1', 'v1').should == 1
|
10
10
|
end
|
11
11
|
|
12
|
-
it 'returns
|
12
|
+
it 'returns 1 if the key exists but the field does not' do
|
13
13
|
@redises.hset(@key, 'k1', 'v1')
|
14
|
-
@redises.hset(@key, 'k2', 'v2').should ==
|
14
|
+
@redises.hset(@key, 'k2', 'v2').should == 1
|
15
15
|
end
|
16
16
|
|
17
|
-
it 'returns
|
17
|
+
it 'returns 0 if the field already exists' do
|
18
18
|
@redises.hset(@key, 'k1', 'v1')
|
19
|
-
@redises.hset(@key, 'k1', 'v1').should ==
|
19
|
+
@redises.hset(@key, 'k1', 'v1').should == 0
|
20
20
|
end
|
21
21
|
|
22
22
|
it 'creates a hash there is no such field' do
|
data/spec/commands/keys_spec.rb
CHANGED
@@ -29,6 +29,7 @@ describe '#keys()' do
|
|
29
29
|
|
30
30
|
@redises.set('mock-redis-test:special-key?', 'true')
|
31
31
|
@redises.set('mock-redis-test:special-key*', 'true')
|
32
|
+
@redises.set('mock-redis-test:special-key-!?*', 'true')
|
32
33
|
end
|
33
34
|
|
34
35
|
describe 'the ? character' do
|
@@ -53,6 +54,22 @@ describe '#keys()' do
|
|
53
54
|
'mock-redis-test:special-key?',
|
54
55
|
]
|
55
56
|
end
|
57
|
+
|
58
|
+
context 'multiple ? characters' do
|
59
|
+
it "properly handles multiple consequtive '?' characters" do
|
60
|
+
@redises.keys('mock-redis-test:special-key-???').sort.should == [
|
61
|
+
'mock-redis-test:special-key-!?*',
|
62
|
+
]
|
63
|
+
end
|
64
|
+
|
65
|
+
context '\\? as a literal ' do
|
66
|
+
it 'handles multiple ? as both literal and special character' do
|
67
|
+
@redises.keys('mock-redis-test:special-key-?\??').sort.should == [
|
68
|
+
'mock-redis-test:special-key-!?*',
|
69
|
+
]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
56
73
|
end
|
57
74
|
|
58
75
|
describe 'the * character' do
|
data/spec/commands/mget_spec.rb
CHANGED
@@ -49,5 +49,11 @@ describe '#mget(key [, key, ...])' do
|
|
49
49
|
@redises.mget
|
50
50
|
end.should raise_error(Redis::CommandError)
|
51
51
|
end
|
52
|
+
|
53
|
+
it 'raises an error if you pass it empty array' do
|
54
|
+
lambda do
|
55
|
+
@redises.mget([])
|
56
|
+
end.should raise_error(Redis::CommandError)
|
57
|
+
end
|
52
58
|
end
|
53
59
|
end
|
data/spec/commands/move_spec.rb
CHANGED
@@ -64,7 +64,7 @@ describe '#move(key, db)' do
|
|
64
64
|
end
|
65
65
|
|
66
66
|
it 'removes key from srcdb' do
|
67
|
-
@redises.exists(@key).should == false
|
67
|
+
@redises.exists?(@key).should == false
|
68
68
|
end
|
69
69
|
|
70
70
|
it 'copies key to destdb' do
|
@@ -81,7 +81,7 @@ describe '#move(key, db)' do
|
|
81
81
|
end
|
82
82
|
|
83
83
|
it 'removes key from srcdb' do
|
84
|
-
@redises.exists(@key).should == false
|
84
|
+
@redises.exists?(@key).should == false
|
85
85
|
end
|
86
86
|
|
87
87
|
it 'copies key to destdb' do
|
@@ -99,7 +99,7 @@ describe '#move(key, db)' do
|
|
99
99
|
end
|
100
100
|
|
101
101
|
it 'removes key from srcdb' do
|
102
|
-
@redises.exists(@key).should == false
|
102
|
+
@redises.exists?(@key).should == false
|
103
103
|
end
|
104
104
|
|
105
105
|
it 'copies key to destdb' do
|
@@ -117,7 +117,7 @@ describe '#move(key, db)' do
|
|
117
117
|
end
|
118
118
|
|
119
119
|
it 'removes key from srcdb' do
|
120
|
-
@redises.exists(@key).should == false
|
120
|
+
@redises.exists?(@key).should == false
|
121
121
|
end
|
122
122
|
|
123
123
|
it 'copies key to destdb' do
|
@@ -135,7 +135,7 @@ describe '#move(key, db)' do
|
|
135
135
|
end
|
136
136
|
|
137
137
|
it 'removes key from srcdb' do
|
138
|
-
@redises.exists(@key).should == false
|
138
|
+
@redises.exists?(@key).should == false
|
139
139
|
end
|
140
140
|
|
141
141
|
it 'copies key to destdb' do
|
@@ -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/scan_spec.rb
CHANGED
@@ -42,6 +42,15 @@ describe '#scan' do
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
+
context 'when cursor is greater than collection size' do
|
46
|
+
let(:collection) { Array.new(count) { |i| "mock:key#{i}" } }
|
47
|
+
let(:expected) { ['0', []] }
|
48
|
+
|
49
|
+
it 'returns a 0 cursor and empty collection' do
|
50
|
+
expect(subject.scan(20, count: count, match: match)).to eq(expected)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
45
54
|
context 'when giving a custom match filter' do
|
46
55
|
let(:match) { 'mock:key*' }
|
47
56
|
let(:collection) { %w[mock:key mock:key2 mock:otherkey] }
|
data/spec/commands/set_spec.rb
CHANGED
@@ -33,10 +33,12 @@ describe '#set(key, value)' do
|
|
33
33
|
@redises.set(key, 1, xx: true).should == true
|
34
34
|
end
|
35
35
|
|
36
|
-
it '
|
36
|
+
it 'raises on unknown options' do
|
37
37
|
key = 'mock-redis-test'
|
38
38
|
@redises.del(key)
|
39
|
-
|
39
|
+
expect do
|
40
|
+
@redises.set(key, 1, logger: :something)
|
41
|
+
end.to raise_error(ArgumentError, 'unknown keyword: logger')
|
40
42
|
end
|
41
43
|
|
42
44
|
context '[mock only]' do
|
@@ -59,9 +61,11 @@ describe '#set(key, value)' do
|
|
59
61
|
|
60
62
|
it 'accepts PX milliseconds' do
|
61
63
|
key = 'mock-redis-test'
|
62
|
-
@mock.set(key, 1, px:
|
64
|
+
@mock.set(key, 1, px: 500).should == 'OK'
|
63
65
|
@mock.get(key).should_not be_nil
|
64
|
-
Time.stub(:now).and_return(@now +
|
66
|
+
Time.stub(:now).and_return(@now + 300 / 1000.to_f)
|
67
|
+
@mock.get(key).should_not be_nil
|
68
|
+
Time.stub(:now).and_return(@now + 600 / 1000.to_f)
|
65
69
|
@mock.get(key).should be_nil
|
66
70
|
end
|
67
71
|
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
|
@@ -37,7 +37,7 @@ describe '#srandmember(key)' do
|
|
37
37
|
@redises.send_without_checking(:srandmember, @key, 2).size.should == 2
|
38
38
|
end
|
39
39
|
|
40
|
-
it 'returns random members up to count from the set when count is negative even if count.abs is greater than the set size' do # rubocop:disable
|
40
|
+
it 'returns random members up to count from the set when count is negative even if count.abs is greater than the set size' do # rubocop:disable Layout/LineLength
|
41
41
|
@redises.send_without_checking(:srandmember, @key, -5).size.should == 5
|
42
42
|
end
|
43
43
|
|
data/spec/commands/xadd_spec.rb
CHANGED
@@ -54,6 +54,8 @@ describe '#xadd("mystream", { f1: "v1", f2: "v2" }, id: "0-0", maxlen: 1000, app
|
|
54
54
|
Redis::CommandError,
|
55
55
|
'ERR The ID specified in XADD is equal or smaller than the target ' \
|
56
56
|
'stream top item'
|
57
|
+
# TOOD: Redis version 6.0.4, w redis 4.2.1 generates the following error message:
|
58
|
+
# 'ERR The ID specified in XADD must be greater than 0-0'
|
57
59
|
)
|
58
60
|
end
|
59
61
|
|
@@ -99,4 +101,22 @@ describe '#xadd("mystream", { f1: "v1", f2: "v2" }, id: "0-0", maxlen: 1000, app
|
|
99
101
|
]
|
100
102
|
)
|
101
103
|
end
|
104
|
+
|
105
|
+
it 'supports a maxlen greater than the current size' do
|
106
|
+
@redises.xadd(@key, { key1: 'value1' }, id: '1234567891234-0')
|
107
|
+
@redises.xadd(@key, { key2: 'value2' }, id: '1234567891245-0', maxlen: 1000)
|
108
|
+
expect(@redises.xrange(@key, '-', '+')).to eq(
|
109
|
+
[
|
110
|
+
['1234567891234-0', { 'key1' => 'value1' }],
|
111
|
+
['1234567891245-0', { 'key2' => 'value2' }],
|
112
|
+
]
|
113
|
+
)
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'creates an empty stream with maxlen of 0' do
|
117
|
+
@redises.xadd(@key, { key: 'value' }, maxlen: 0)
|
118
|
+
expect(@redises.xlen(@key)).to eq 0
|
119
|
+
expect(@redises.xrange(@key, '-', '+')).to eq([])
|
120
|
+
expect(@redises.exists?(@key)).to eq true
|
121
|
+
end
|
102
122
|
end
|
@@ -54,6 +54,19 @@ describe '#xrange("mystream", first: "0-1", last: "0-3", count: 10)' do
|
|
54
54
|
)
|
55
55
|
end
|
56
56
|
|
57
|
+
it 'returns all entries with a lower limit of 0-0' do
|
58
|
+
expect(@redises.xrange(@key, '0-0', '+')).to eq(
|
59
|
+
[
|
60
|
+
['1234567891234-0', { 'key1' => 'value1' }],
|
61
|
+
['1234567891245-0', { 'key2' => 'value2' }],
|
62
|
+
['1234567891245-1', { 'key3' => 'value3' }],
|
63
|
+
['1234567891278-0', { 'key4' => 'value4' }],
|
64
|
+
['1234567891278-1', { 'key5' => 'value5' }],
|
65
|
+
['1234567891299-0', { 'key6' => 'value6' }]
|
66
|
+
]
|
67
|
+
)
|
68
|
+
end
|
69
|
+
|
57
70
|
it 'returns entries with an upper limit' do
|
58
71
|
expect(@redises.xrange(@key, '-', '1234567891285-0')).to eq(
|
59
72
|
[
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe '#xread(keys, ids)' do
|
4
|
+
before :all do
|
5
|
+
sleep 1 - (Time.now.to_f % 1)
|
6
|
+
@key = 'mock-redis-test:xread'
|
7
|
+
@key1 = 'mock-redis-test:xread1'
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'reads a single entry' do
|
11
|
+
@redises.xadd(@key, { key: 'value' }, id: '1234567891234-0')
|
12
|
+
expect(@redises.xread(@key, '0-0'))
|
13
|
+
.to eq({ @key => [['1234567891234-0', { 'key' => 'value' }]] })
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'reads multiple entries from the beginning of the stream' do
|
17
|
+
@redises.xadd(@key, { key0: 'value0' }, id: '1234567891234-0')
|
18
|
+
@redises.xadd(@key, { key1: 'value1' }, id: '1234567891234-1')
|
19
|
+
expect(@redises.xread(@key, '0-0'))
|
20
|
+
.to eq({ @key => [['1234567891234-0', { 'key0' => 'value0' }],
|
21
|
+
['1234567891234-1', { 'key1' => 'value1' }]] })
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'reads entries greater than the ID passed' do
|
25
|
+
@redises.xadd(@key, { key0: 'value0' }, id: '1234567891234-0')
|
26
|
+
@redises.xadd(@key, { key1: 'value1' }, id: '1234567891234-1')
|
27
|
+
expect(@redises.xread(@key, '1234567891234-0'))
|
28
|
+
.to eq({ @key => [['1234567891234-1', { 'key1' => 'value1' }]] })
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'reads from multiple streams' do
|
32
|
+
@redises.xadd(@key, { key: 'value' }, id: '1234567891234-0')
|
33
|
+
@redises.xadd(@key1, { key1: 'value1' }, id: '1234567891234-0')
|
34
|
+
expect(@redises.xread([@key, @key1], %w[0-0 0-0]))
|
35
|
+
.to eq({ @key => [['1234567891234-0', { 'key' => 'value' }]],
|
36
|
+
@key1 => [['1234567891234-0', { 'key1' => 'value1' }]] })
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'reads from multiple streams at the given IDs' do
|
40
|
+
@redises.xadd(@key, { key: 'value0' }, id: '1234567891234-0')
|
41
|
+
@redises.xadd(@key, { key: 'value1' }, id: '1234567891234-1')
|
42
|
+
@redises.xadd(@key, { key: 'value2' }, id: '1234567891234-2')
|
43
|
+
@redises.xadd(@key1, { key1: 'value0' }, id: '1234567891234-0')
|
44
|
+
@redises.xadd(@key1, { key1: 'value1' }, id: '1234567891234-1')
|
45
|
+
@redises.xadd(@key1, { key1: 'value2' }, id: '1234567891234-2')
|
46
|
+
# The first stream won't return anything since we specify the last ID
|
47
|
+
expect(@redises.xread([@key, @key1], %w[1234567891234-2 1234567891234-1]))
|
48
|
+
.to eq({ @key1 => [['1234567891234-2', { 'key1' => 'value2' }]] })
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'supports the block parameter' do
|
52
|
+
@redises.xadd(@key, { key: 'value' }, id: '1234567891234-0')
|
53
|
+
expect(@redises.xread(@key, '0-0', block: 1000))
|
54
|
+
.to eq({ @key => [['1234567891234-0', { 'key' => 'value' }]] })
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'limits results with count' do
|
58
|
+
@redises.xadd(@key, { key: 'value' }, id: '1234567891234-0')
|
59
|
+
@redises.xadd(@key, { key: 'value' }, id: '1234567891234-1')
|
60
|
+
@redises.xadd(@key, { key: 'value' }, id: '1234567891234-2')
|
61
|
+
expect(@redises.xread(@key, '0-0', count: 1))
|
62
|
+
.to eq({ @key => [['1234567891234-0', { 'key' => 'value' }]] })
|
63
|
+
expect(@redises.xread(@key, '1234567891234-0', count: 1))
|
64
|
+
.to eq({ @key => [['1234567891234-1', { 'key' => 'value' }]] })
|
65
|
+
end
|
66
|
+
end
|