mock_redis 0.15.4 → 0.16.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -3
- data/.travis.yml +2 -0
- data/CHANGELOG.md +6 -0
- data/Gemfile +2 -2
- data/README.md +2 -0
- data/lib/mock_redis.rb +3 -3
- data/lib/mock_redis/database.rb +21 -7
- data/lib/mock_redis/hash_methods.rb +15 -0
- data/lib/mock_redis/info_method.rb +10 -10
- data/lib/mock_redis/list_methods.rb +1 -1
- data/lib/mock_redis/multi_db_wrapper.rb +1 -1
- data/lib/mock_redis/set_methods.rb +16 -2
- data/lib/mock_redis/utility_methods.rb +16 -0
- data/lib/mock_redis/version.rb +3 -1
- data/lib/mock_redis/zset.rb +6 -5
- data/lib/mock_redis/zset_methods.rb +17 -2
- data/spec/commands/eval_spec.rb +7 -0
- data/spec/commands/evalsha_spec.rb +10 -0
- data/spec/commands/hscan_each_spec.rb +48 -0
- data/spec/commands/hscan_spec.rb +27 -0
- data/spec/commands/keys_spec.rb +3 -3
- data/spec/commands/scan_each_spec.rb +39 -0
- data/spec/commands/scan_spec.rb +10 -5
- data/spec/commands/script_spec.rb +9 -0
- data/spec/commands/sscan_each_spec.rb +48 -0
- data/spec/commands/sscan_spec.rb +39 -0
- data/spec/commands/zscan_each_spec.rb +48 -0
- data/spec/commands/zscan_spec.rb +26 -0
- metadata +22 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cfac83d82686c7ae7355880b0ecc9263b44f0b2a
|
4
|
+
data.tar.gz: 65edf9e01b7cdc5da7f02bc88cf4703b12d4e043
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d6e80d56dfcbad007f71b0c58f1de1f056592880f0d10516224f3d91e0e1ef3bfb405d4b5a482668146bfee978d8c7a4307ee25951960ebd18a8d9d19c0eff0a
|
7
|
+
data.tar.gz: 43900cd389c65597930932a4c95de2469909131396840a2a693ddbe77b7dbae024546c21dfae487e2b73c5fb8fa3e568b58af6503f1c7e18a24f8a0888fb76a7
|
data/.rubocop.yml
CHANGED
@@ -83,9 +83,10 @@ Style/SignalException:
|
|
83
83
|
Style/SingleLineBlockParams:
|
84
84
|
Enabled: false
|
85
85
|
|
86
|
-
|
87
|
-
|
88
|
-
|
86
|
+
Style/TrailingCommaInArguments:
|
87
|
+
Enabled: false
|
88
|
+
|
89
|
+
Style/TrailingCommaInLiteral:
|
89
90
|
Enabled: false
|
90
91
|
|
91
92
|
Style/WhenThen:
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# MockRedis Changelog
|
2
2
|
|
3
|
+
### 0.16.0
|
4
|
+
|
5
|
+
* Add stub implementations for `script`/`eval`/`evalsha` commands
|
6
|
+
* Add implementations for `SCAN` family (`sscan`/`hscan`/`zscan`)
|
7
|
+
family of commands
|
8
|
+
|
3
9
|
### 0.15.4
|
4
10
|
|
5
11
|
* Fix `zrange`/`zrevrange` to return elements with equal values in
|
data/Gemfile
CHANGED
@@ -4,10 +4,10 @@ source 'http://rubygems.org'
|
|
4
4
|
gemspec
|
5
5
|
|
6
6
|
# Run all pre-commit hooks via Overcommit during CI runs
|
7
|
-
gem 'overcommit', '0.
|
7
|
+
gem 'overcommit', '0.30.0'
|
8
8
|
|
9
9
|
# Pin tool versions (which are executed by Overcommit) for Travis builds
|
10
|
-
gem 'rubocop', '0.
|
10
|
+
gem 'rubocop', '0.36.0'
|
11
11
|
gem 'travis', '~> 1.7'
|
12
12
|
|
13
13
|
gem 'coveralls', require: false
|
data/README.md
CHANGED
data/lib/mock_redis.rb
CHANGED
@@ -23,7 +23,7 @@ class MockRedis
|
|
23
23
|
:password => nil,
|
24
24
|
:db => 0,
|
25
25
|
:time_class => Time,
|
26
|
-
}
|
26
|
+
}.freeze
|
27
27
|
|
28
28
|
def self.connect(*args)
|
29
29
|
new(*args)
|
@@ -42,7 +42,7 @@ class MockRedis
|
|
42
42
|
def id
|
43
43
|
"redis://#{host}:#{port}/#{db}"
|
44
44
|
end
|
45
|
-
|
45
|
+
alias location id
|
46
46
|
|
47
47
|
def call(command, &_block)
|
48
48
|
send(*command)
|
@@ -63,7 +63,7 @@ class MockRedis
|
|
63
63
|
def now
|
64
64
|
options[:time_class].now
|
65
65
|
end
|
66
|
-
|
66
|
+
alias time now
|
67
67
|
|
68
68
|
def time_at(timestamp)
|
69
69
|
options[:time_class].at(timestamp)
|
data/lib/mock_redis/database.rb
CHANGED
@@ -8,6 +8,7 @@ require 'mock_redis/zset_methods'
|
|
8
8
|
require 'mock_redis/sort_method'
|
9
9
|
require 'mock_redis/indifferent_hash'
|
10
10
|
require 'mock_redis/info_method'
|
11
|
+
require 'mock_redis/utility_methods'
|
11
12
|
|
12
13
|
class MockRedis
|
13
14
|
class Database
|
@@ -18,6 +19,7 @@ class MockRedis
|
|
18
19
|
include ZsetMethods
|
19
20
|
include SortMethod
|
20
21
|
include InfoMethod
|
22
|
+
include UtilityMethods
|
21
23
|
|
22
24
|
attr_reader :data, :expire_times
|
23
25
|
|
@@ -119,14 +121,17 @@ class MockRedis
|
|
119
121
|
end
|
120
122
|
|
121
123
|
def scan(cursor, opts = {})
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
keys = data.keys
|
126
|
-
limit = cursor + count
|
127
|
-
next_cursor = limit >= keys.length ? '0' : limit.to_s
|
124
|
+
common_scan(data.keys, cursor, opts)
|
125
|
+
end
|
128
126
|
|
129
|
-
|
127
|
+
def scan_each(opts = {}, &block)
|
128
|
+
return to_enum(:scan_each, opts) unless block_given?
|
129
|
+
cursor = 0
|
130
|
+
loop do
|
131
|
+
cursor, keys = scan(cursor, opts)
|
132
|
+
keys.each(&block)
|
133
|
+
break if cursor == '0'
|
134
|
+
end
|
130
135
|
end
|
131
136
|
|
132
137
|
def lastsave
|
@@ -224,6 +229,15 @@ class MockRedis
|
|
224
229
|
end
|
225
230
|
end
|
226
231
|
|
232
|
+
def script(subcommand, *args)
|
233
|
+
end
|
234
|
+
|
235
|
+
def evalsha(*args)
|
236
|
+
end
|
237
|
+
|
238
|
+
def eval(*args)
|
239
|
+
end
|
240
|
+
|
227
241
|
private
|
228
242
|
|
229
243
|
def assert_valid_timeout(timeout)
|
@@ -109,6 +109,21 @@ class MockRedis
|
|
109
109
|
hmset(key, *kvpairs)
|
110
110
|
end
|
111
111
|
|
112
|
+
def hscan(key, cursor, opts = {})
|
113
|
+
opts = opts.merge(key: lambda { |x| x[0] })
|
114
|
+
common_scan(hgetall(key).to_a, cursor, opts)
|
115
|
+
end
|
116
|
+
|
117
|
+
def hscan_each(key, opts = {}, &block)
|
118
|
+
return to_enum(:hscan_each, key, opts) unless block_given?
|
119
|
+
cursor = 0
|
120
|
+
loop do
|
121
|
+
cursor, values = hscan(key, cursor, opts)
|
122
|
+
values.each(&block)
|
123
|
+
break if cursor == '0'
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
112
127
|
def hset(key, field, value)
|
113
128
|
with_hash_at(key) { |h| h[field.to_s] = value.to_s }
|
114
129
|
true
|
@@ -15,14 +15,14 @@ class MockRedis
|
|
15
15
|
'tcp_port' => '6379',
|
16
16
|
'uptime_in_days' => '0',
|
17
17
|
'uptime_in_seconds' => '84215',
|
18
|
-
}
|
18
|
+
}.freeze
|
19
19
|
|
20
20
|
CLIENTS_INFO = {
|
21
21
|
'blocked_clients' => '0',
|
22
22
|
'client_biggest_input_buf' => '0',
|
23
23
|
'client_longest_output_list' => '0',
|
24
24
|
'connected_clients' => '1',
|
25
|
-
}
|
25
|
+
}.freeze
|
26
26
|
|
27
27
|
MEMORY_INFO = {
|
28
28
|
'mem_allocator' => 'libc',
|
@@ -33,7 +33,7 @@ class MockRedis
|
|
33
33
|
'used_memory_peak' => '1005424',
|
34
34
|
'used_memory_peak_human' => '981.86K',
|
35
35
|
'used_memory_rss' => '1904640',
|
36
|
-
}
|
36
|
+
}.freeze
|
37
37
|
|
38
38
|
PERSISTENCE_INFO = {
|
39
39
|
'aof_current_rewrite_time_sec' => '-1',
|
@@ -49,7 +49,7 @@ class MockRedis
|
|
49
49
|
'rdb_last_bgsave_status' => 'ok',
|
50
50
|
'rdb_last_bgsave_time_sec' => '-1',
|
51
51
|
'rdb_last_save_time' => '1361423635',
|
52
|
-
}
|
52
|
+
}.freeze
|
53
53
|
|
54
54
|
STATS_INFO = {
|
55
55
|
'evicted_keys' => '0',
|
@@ -63,23 +63,23 @@ class MockRedis
|
|
63
63
|
'rejected_connections' => '0',
|
64
64
|
'total_commands_processed' => '196800',
|
65
65
|
'total_connections_received' => '4359',
|
66
|
-
}
|
66
|
+
}.freeze
|
67
67
|
|
68
68
|
REPLICATION_INFO = {
|
69
69
|
'role' => 'master',
|
70
70
|
'connected_slaves' => '0',
|
71
|
-
}
|
71
|
+
}.freeze
|
72
72
|
|
73
73
|
CPU_INFO = {
|
74
74
|
'used_cpu_sys' => '5.54',
|
75
75
|
'used_cpu_sys_childrens' => '0.00',
|
76
76
|
'used_cpu_user' => '7.65',
|
77
77
|
'used_cpu_user_childrens' => '0.02',
|
78
|
-
}
|
78
|
+
}.freeze
|
79
79
|
|
80
80
|
KEYSPACE_INFO = {
|
81
81
|
'db0' => 'keys=8,expires=0',
|
82
|
-
}
|
82
|
+
}.freeze
|
83
83
|
|
84
84
|
# The Ruby Redis client returns commandstats differently when it's called as
|
85
85
|
# "INFO commandstats".
|
@@ -102,7 +102,7 @@ class MockRedis
|
|
102
102
|
'slowlog' => { 'calls' => '136', 'usec' => '16815', 'usec_per_call' => '123.64' },
|
103
103
|
'smembers' => { 'calls' => '58', 'usec' => '231', 'usec_per_call' => '3.98' },
|
104
104
|
'sunionstore' => { 'calls' => '4185027', 'usec' => '11762454022', 'usec_per_call' => '2810.60' },
|
105
|
-
}
|
105
|
+
}.freeze
|
106
106
|
|
107
107
|
COMMAND_STATS_COMBINED_INFO = {
|
108
108
|
'cmdstat_auth' => 'calls=572506,usec=2353182,usec_per_call=4.11',
|
@@ -122,7 +122,7 @@ class MockRedis
|
|
122
122
|
'cmdstat_slowlog' => 'calls=136,usec=16815,usec_per_call=123.64',
|
123
123
|
'cmdstat_smembers' => 'calls=58,usec=231,usec_per_call=3.98',
|
124
124
|
'cmdstat_sunionstore' => 'calls=4185027,usec=11762454022,usec_per_call=2810.60',
|
125
|
-
}
|
125
|
+
}.freeze
|
126
126
|
# rubocop:enable Metrics/LineLength
|
127
127
|
|
128
128
|
DEFAULT_INFO = [
|
@@ -44,7 +44,7 @@ class MockRedis
|
|
44
44
|
else
|
45
45
|
case current_db.type(key)
|
46
46
|
when 'hash'
|
47
|
-
dest.hmset(key, *
|
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)
|
@@ -95,7 +95,7 @@ class MockRedis
|
|
95
95
|
if count > 0
|
96
96
|
members.sample(count)
|
97
97
|
else
|
98
|
-
count.abs
|
98
|
+
Array.new(count.abs) { members[rand(members.length)] }
|
99
99
|
end
|
100
100
|
else
|
101
101
|
members[rand(members.length)]
|
@@ -114,6 +114,20 @@ class MockRedis
|
|
114
114
|
end
|
115
115
|
end
|
116
116
|
|
117
|
+
def sscan(key, cursor, opts = {})
|
118
|
+
common_scan(smembers(key), cursor, opts)
|
119
|
+
end
|
120
|
+
|
121
|
+
def sscan_each(key, opts = {}, &block)
|
122
|
+
return to_enum(:sscan_each, key, opts) unless block_given?
|
123
|
+
cursor = 0
|
124
|
+
loop do
|
125
|
+
cursor, keys = sscan(key, cursor, opts)
|
126
|
+
keys.each(&block)
|
127
|
+
break if cursor == '0'
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
117
131
|
def sunion(*keys)
|
118
132
|
assert_has_args(keys, 'sunion')
|
119
133
|
with_sets_at(*keys) { |*sets| sets.reduce(&:+).to_a }
|
@@ -140,7 +154,7 @@ class MockRedis
|
|
140
154
|
else
|
141
155
|
with_set_at(keys.first) do |set|
|
142
156
|
with_sets_at(*(keys[1..-1])) do |*sets|
|
143
|
-
|
157
|
+
yield(*([set] + sets))
|
144
158
|
end
|
145
159
|
end
|
146
160
|
end
|
@@ -22,5 +22,21 @@ class MockRedis
|
|
22
22
|
del(key)
|
23
23
|
end
|
24
24
|
end
|
25
|
+
|
26
|
+
def common_scan(values, cursor, opts = {})
|
27
|
+
count = (opts[:count] || 10).to_i
|
28
|
+
cursor = cursor.to_i
|
29
|
+
match = opts[:match] || '*'
|
30
|
+
key = opts[:key] || lambda { |x| x }
|
31
|
+
|
32
|
+
limit = cursor + count
|
33
|
+
next_cursor = limit >= values.length ? '0' : limit.to_s
|
34
|
+
|
35
|
+
filtered_values = values[cursor...limit].select do |val|
|
36
|
+
redis_pattern_to_ruby_regex(match).match(key.call(val))
|
37
|
+
end
|
38
|
+
|
39
|
+
[next_cursor, filtered_values]
|
40
|
+
end
|
25
41
|
end
|
26
42
|
end
|
data/lib/mock_redis/version.rb
CHANGED
data/lib/mock_redis/zset.rb
CHANGED
@@ -23,11 +23,12 @@ class MockRedis
|
|
23
23
|
|
24
24
|
def add(score, member)
|
25
25
|
members.add(member)
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
26
|
+
scores[member] =
|
27
|
+
if score.to_f.to_i == score.to_f
|
28
|
+
score.to_f.to_i
|
29
|
+
else
|
30
|
+
score.to_f
|
31
|
+
end
|
31
32
|
self
|
32
33
|
end
|
33
34
|
|
@@ -128,6 +128,21 @@ class MockRedis
|
|
128
128
|
with_zset_at(key) { |z| z.sorted_members.reverse.index(member.to_s) }
|
129
129
|
end
|
130
130
|
|
131
|
+
def zscan(key, cursor, opts = {})
|
132
|
+
opts = opts.merge(key: lambda { |x| x[0] })
|
133
|
+
common_scan(zrange(key, 0, -1, withscores: true), cursor, opts)
|
134
|
+
end
|
135
|
+
|
136
|
+
def zscan_each(key, opts = {}, &block)
|
137
|
+
return to_enum(:zscan_each, key, opts) unless block_given?
|
138
|
+
cursor = 0
|
139
|
+
loop do
|
140
|
+
cursor, values = zscan(key, cursor, opts)
|
141
|
+
values.each(&block)
|
142
|
+
break if cursor == '0'
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
131
146
|
def zscore(key, member)
|
132
147
|
with_zset_at(key) do |z|
|
133
148
|
score = z.score(member.to_s)
|
@@ -205,7 +220,7 @@ class MockRedis
|
|
205
220
|
else
|
206
221
|
with_zset_at(keys.first) do |set|
|
207
222
|
with_zsets_at(*(keys[1..-1])) do |*sets|
|
208
|
-
|
223
|
+
yield(*([set] + sets))
|
209
224
|
end
|
210
225
|
end
|
211
226
|
end
|
@@ -230,7 +245,7 @@ class MockRedis
|
|
230
245
|
def assert_scorey(value, message = 'ERR value is not a valid float')
|
231
246
|
return if value =~ /\(?(\-|\+)inf/
|
232
247
|
|
233
|
-
value = $1 if value.to_s
|
248
|
+
value = $1 if value.to_s =~ /\((.*)/
|
234
249
|
unless looks_like_float?(value)
|
235
250
|
raise Redis::CommandError, message
|
236
251
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe '#hscan_each' do
|
4
|
+
subject { MockRedis::Database.new(self) }
|
5
|
+
|
6
|
+
let(:key) { 'mock-redis-test:hscan_each' }
|
7
|
+
|
8
|
+
before do
|
9
|
+
allow(subject).to receive(:hgetall).and_return(collection)
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'when no keys are found' do
|
13
|
+
let(:collection) { [] }
|
14
|
+
|
15
|
+
it 'does not iterate over any elements' do
|
16
|
+
results = subject.hscan_each(key).map do |k, v|
|
17
|
+
[k, v]
|
18
|
+
end
|
19
|
+
expect(results).to match_array(collection)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'when keys are found' do
|
24
|
+
context 'when no match filter is supplied' do
|
25
|
+
let(:collection) { Array.new(20) { |i| ["k#{i}", "v#{i}"] } }
|
26
|
+
|
27
|
+
it 'iterates over each item in the collection' do
|
28
|
+
results = subject.hscan_each(key).map do |k, v|
|
29
|
+
[k, v]
|
30
|
+
end
|
31
|
+
expect(results).to match_array(collection)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'when giving a custom match filter' do
|
36
|
+
let(:match) { 'k1*' }
|
37
|
+
let(:collection) { Array.new(12) { |i| ["k#{i}", "v#{i}"] } }
|
38
|
+
let(:expected) { [%w[k1 v1], %w[k10 v10], %w[k11 v11]] }
|
39
|
+
|
40
|
+
it 'iterates over each item in the filtered collection' do
|
41
|
+
results = subject.hscan_each(key, match: match).map do |k, v|
|
42
|
+
[k, v]
|
43
|
+
end
|
44
|
+
expect(results).to match_array(expected)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe '#hscan' do
|
4
|
+
let(:count) { 10 }
|
5
|
+
let(:match) { '*' }
|
6
|
+
let(:key) { 'mock-redis-test:hscan' }
|
7
|
+
|
8
|
+
context 'when the hash does not exist' do
|
9
|
+
it 'returns a 0 cursor and an empty collection' do
|
10
|
+
expect(@redises.hscan(key, 0, count: count, match: match)).to eq(['0', []])
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'when the hash exists' do
|
15
|
+
before do
|
16
|
+
@redises.hset(key, 'k1', 'v1')
|
17
|
+
@redises.hset(key, 'k2', 'v2')
|
18
|
+
@redises.hset(key, 'k3', 'v3')
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:expected) { ['0', [%w[k1 v1], %w[k2 v2], %w[k3 v3]]] }
|
22
|
+
|
23
|
+
it 'returns a 0 cursor and the collection' do
|
24
|
+
expect(@redises.hscan(key, 0, count: 10)).to eq(expected)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/spec/commands/keys_spec.rb
CHANGED
@@ -48,7 +48,7 @@ describe '#keys()' do
|
|
48
48
|
]
|
49
49
|
end
|
50
50
|
|
51
|
-
it
|
51
|
+
it 'treats \\? as a literal ?' do
|
52
52
|
@redises.keys('mock-redis-test:special-key\?').sort.should == [
|
53
53
|
'mock-redis-test:special-key?',
|
54
54
|
]
|
@@ -68,7 +68,7 @@ describe '#keys()' do
|
|
68
68
|
]
|
69
69
|
end
|
70
70
|
|
71
|
-
it
|
71
|
+
it 'treats \\* as a literal *' do
|
72
72
|
@redises.keys('mock-redis-test:special-key\*').sort.should == [
|
73
73
|
'mock-redis-test:special-key*',
|
74
74
|
]
|
@@ -101,7 +101,7 @@ describe '#keys()' do
|
|
101
101
|
end
|
102
102
|
|
103
103
|
describe 'character classes ([a-c])' do
|
104
|
-
it
|
104
|
+
it 'specifies a range which matches any lowercase letter from "a" to "c"' do
|
105
105
|
@redises.keys('mock-redis-test:regexp-key4[a-c]').sort.should == [
|
106
106
|
'mock-redis-test:regexp-key4a',
|
107
107
|
'mock-redis-test:regexp-key4b',
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe '#scan_each' do
|
4
|
+
subject { MockRedis::Database.new(self) }
|
5
|
+
|
6
|
+
let(:match) { '*' }
|
7
|
+
|
8
|
+
before do
|
9
|
+
allow(subject).to receive_message_chain(:data, :keys).and_return(collection)
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'when no keys are found' do
|
13
|
+
let(:collection) { [] }
|
14
|
+
|
15
|
+
it 'does not iterate over any elements' do
|
16
|
+
expect(subject.scan_each.to_a).to be_empty
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'when keys are found' do
|
21
|
+
context 'when no match filter is supplied' do
|
22
|
+
let(:collection) { Array.new(20) { |i| "mock:key#{i}" } }
|
23
|
+
|
24
|
+
it 'iterates over each item in the collection' do
|
25
|
+
expect(subject.scan_each.to_a).to match_array(collection)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'when giving a custom match filter' do
|
30
|
+
let(:match) { 'mock:key*' }
|
31
|
+
let(:collection) { %w[mock:key mock:key2 mock:otherkey] }
|
32
|
+
let(:expected) { %w[mock:key mock:key2] }
|
33
|
+
|
34
|
+
it 'iterates over each item in the filtered collection' do
|
35
|
+
expect(subject.scan_each(match: match).to_a).to match_array(expected)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/spec/commands/scan_spec.rb
CHANGED
@@ -7,7 +7,7 @@ describe '#scan' do
|
|
7
7
|
let(:match) { '*' }
|
8
8
|
|
9
9
|
before do
|
10
|
-
|
10
|
+
allow(subject).to receive_message_chain(:data, :keys).and_return(collection)
|
11
11
|
end
|
12
12
|
|
13
13
|
context 'when no keys are found' do
|
@@ -20,16 +20,21 @@ describe '#scan' do
|
|
20
20
|
|
21
21
|
context 'when keys are found' do
|
22
22
|
context 'when count is lower than collection size' do
|
23
|
-
let(:collection) { (count
|
24
|
-
let(:
|
23
|
+
let(:collection) { Array.new(count * 2) { |i| "mock:key#{i}" } }
|
24
|
+
let(:expected_first) { [count.to_s, collection[0...count]] }
|
25
|
+
let(:expected_second) { ['0', collection[count..-1]] }
|
25
26
|
|
26
27
|
it 'returns a the next cursor and the collection' do
|
27
|
-
expect(subject.scan(0, count: count, match: match)).to eq(
|
28
|
+
expect(subject.scan(0, count: count, match: match)).to eq(expected_first)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'returns the correct results of the next cursor' do
|
32
|
+
expect(subject.scan(count, count: count, match: match)).to eq(expected_second)
|
28
33
|
end
|
29
34
|
end
|
30
35
|
|
31
36
|
context 'when count is greater or equal than collection size' do
|
32
|
-
let(:collection) { count
|
37
|
+
let(:collection) { Array.new(count) { |i| "mock:key#{i}" } }
|
33
38
|
let(:expected) { ['0', collection] }
|
34
39
|
|
35
40
|
it 'returns a 0 cursor and the collection' do
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe '#sscan_each' do
|
4
|
+
subject { MockRedis::Database.new(self) }
|
5
|
+
|
6
|
+
let(:key) { 'mock-redis-test:sscan_each' }
|
7
|
+
|
8
|
+
before do
|
9
|
+
allow(subject).to receive(:smembers).and_return(collection)
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'when no keys are found' do
|
13
|
+
let(:collection) { [] }
|
14
|
+
|
15
|
+
it 'does not iterate over any elements' do
|
16
|
+
results = subject.sscan_each(key).map do |k|
|
17
|
+
k
|
18
|
+
end
|
19
|
+
expect(results).to match_array(collection)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'when keys are found' do
|
24
|
+
context 'when no match filter is supplied' do
|
25
|
+
let(:collection) { Array.new(20) { |i| "k#{i}" } }
|
26
|
+
|
27
|
+
it 'iterates over each item in the collection' do
|
28
|
+
results = subject.sscan_each(key).map do |k|
|
29
|
+
k
|
30
|
+
end
|
31
|
+
expect(results).to match_array(collection)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'when giving a custom match filter' do
|
36
|
+
let(:match) { 'k1*' }
|
37
|
+
let(:collection) { Array.new(12) { |i| "k#{i}" } }
|
38
|
+
let(:expected) { %w[k1 k10 k11] }
|
39
|
+
|
40
|
+
it 'iterates over each item in the filtered collection' do
|
41
|
+
results = subject.sscan_each(key, match: match).map do |k|
|
42
|
+
k
|
43
|
+
end
|
44
|
+
expect(results).to match_array(expected)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe '#sscan' do
|
4
|
+
let(:count) { 10 }
|
5
|
+
let(:match) { '*' }
|
6
|
+
let(:key) { 'mock-redis-test:sscan' }
|
7
|
+
|
8
|
+
before do
|
9
|
+
# The return order of the members is non-deterministic, so we sort them to compare
|
10
|
+
expect_any_instance_of(Redis).to receive(:sscan).and_wrap_original do |m, *args|
|
11
|
+
result = m.call(*args)
|
12
|
+
[result[0], result[1].sort]
|
13
|
+
end
|
14
|
+
expect_any_instance_of(MockRedis).to receive(:sscan).and_wrap_original do |m, *args|
|
15
|
+
result = m.call(*args)
|
16
|
+
[result[0], result[1].sort]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'when the set does not exist' do
|
21
|
+
it 'returns a 0 cursor and an empty collection' do
|
22
|
+
expect(@redises.sscan(key, 0, count: count, match: match)).to eq(['0', []])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'when the set exists' do
|
27
|
+
before do
|
28
|
+
@redises.sadd(key, 'Hello')
|
29
|
+
@redises.sadd(key, 'World')
|
30
|
+
@redises.sadd(key, 'Test')
|
31
|
+
end
|
32
|
+
|
33
|
+
let(:expected) { ['0', %w[Hello Test World]] }
|
34
|
+
|
35
|
+
it 'returns a 0 cursor and the collection' do
|
36
|
+
expect(@redises.sscan(key, 0, count: count)).to eq(expected)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe '#zscan_each' do
|
4
|
+
subject { MockRedis::Database.new(self) }
|
5
|
+
|
6
|
+
let(:key) { 'mock-redis-test:zscan_each' }
|
7
|
+
|
8
|
+
before do
|
9
|
+
allow(subject).to receive(:zrange).and_return(collection)
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'when no keys are found' do
|
13
|
+
let(:collection) { [] }
|
14
|
+
|
15
|
+
it 'does not iterate over any elements' do
|
16
|
+
results = subject.zscan_each(key).map do |m, s|
|
17
|
+
[m, s]
|
18
|
+
end
|
19
|
+
expect(results).to match_array(collection)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'when keys are found' do
|
24
|
+
context 'when no match filter is supplied' do
|
25
|
+
let(:collection) { Array.new(20) { |i| ["m#{i}", i] } }
|
26
|
+
|
27
|
+
it 'iterates over each item in the collection' do
|
28
|
+
results = subject.zscan_each(key).map do |m, s|
|
29
|
+
[m, s]
|
30
|
+
end
|
31
|
+
expect(results).to match_array(collection)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'when giving a custom match filter' do
|
36
|
+
let(:match) { 'm1*' }
|
37
|
+
let(:collection) { Array.new(12) { |i| ["m#{i}", i] } }
|
38
|
+
let(:expected) { [['m1', 1], ['m10', 10], ['m11', 11]] }
|
39
|
+
|
40
|
+
it 'iterates over each item in the filtered collection' do
|
41
|
+
results = subject.zscan_each(key, match: match).map do |m, s|
|
42
|
+
[m, s]
|
43
|
+
end
|
44
|
+
expect(results).to match_array(expected)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe '#zscan' do
|
4
|
+
let(:count) { 10 }
|
5
|
+
let(:match) { '*' }
|
6
|
+
let(:key) { 'mock-redis-test:zscan' }
|
7
|
+
|
8
|
+
context 'when the zset does not exist' do
|
9
|
+
it 'returns a 0 cursor and an empty collection' do
|
10
|
+
expect(@redises.zscan(key, 0, count: count, match: match)).to eq(['0', []])
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'when the zset exists' do
|
15
|
+
before do
|
16
|
+
@redises.zadd(key, 1.0, 'member1')
|
17
|
+
@redises.zadd(key, 2.0, 'member2')
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'returns a 0 cursor and the collection' do
|
21
|
+
result = @redises.zscan(key, 0)
|
22
|
+
expect(result[0]).to eq('0')
|
23
|
+
expect(result[1]).to match_array([['member1', 1.0], ['member2', 2.0]])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
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.16.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brigade Engineering
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2016-01-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -126,6 +126,8 @@ files:
|
|
126
126
|
- spec/commands/del_spec.rb
|
127
127
|
- spec/commands/disconnect_spec.rb
|
128
128
|
- spec/commands/echo_spec.rb
|
129
|
+
- spec/commands/eval_spec.rb
|
130
|
+
- spec/commands/evalsha_spec.rb
|
129
131
|
- spec/commands/exists_spec.rb
|
130
132
|
- spec/commands/expire_spec.rb
|
131
133
|
- spec/commands/expireat_spec.rb
|
@@ -147,6 +149,8 @@ files:
|
|
147
149
|
- spec/commands/hlen_spec.rb
|
148
150
|
- spec/commands/hmget_spec.rb
|
149
151
|
- spec/commands/hmset_spec.rb
|
152
|
+
- spec/commands/hscan_each_spec.rb
|
153
|
+
- spec/commands/hscan_spec.rb
|
150
154
|
- spec/commands/hset_spec.rb
|
151
155
|
- spec/commands/hsetnx_spec.rb
|
152
156
|
- spec/commands/hvals_spec.rb
|
@@ -191,8 +195,10 @@ files:
|
|
191
195
|
- spec/commands/rpushx_spec.rb
|
192
196
|
- spec/commands/sadd_spec.rb
|
193
197
|
- spec/commands/save_spec.rb
|
198
|
+
- spec/commands/scan_each_spec.rb
|
194
199
|
- spec/commands/scan_spec.rb
|
195
200
|
- spec/commands/scard_spec.rb
|
201
|
+
- spec/commands/script_spec.rb
|
196
202
|
- spec/commands/sdiff_spec.rb
|
197
203
|
- spec/commands/sdiffstore_spec.rb
|
198
204
|
- spec/commands/select_spec.rb
|
@@ -212,6 +218,8 @@ files:
|
|
212
218
|
- spec/commands/spop_spec.rb
|
213
219
|
- spec/commands/srandmember_spec.rb
|
214
220
|
- spec/commands/srem_spec.rb
|
221
|
+
- spec/commands/sscan_each_spec.rb
|
222
|
+
- spec/commands/sscan_spec.rb
|
215
223
|
- spec/commands/strlen_spec.rb
|
216
224
|
- spec/commands/sunion_spec.rb
|
217
225
|
- spec/commands/sunionstore_spec.rb
|
@@ -233,6 +241,8 @@ files:
|
|
233
241
|
- spec/commands/zrevrange_spec.rb
|
234
242
|
- spec/commands/zrevrangebyscore_spec.rb
|
235
243
|
- spec/commands/zrevrank_spec.rb
|
244
|
+
- spec/commands/zscan_each_spec.rb
|
245
|
+
- spec/commands/zscan_spec.rb
|
236
246
|
- spec/commands/zscore_spec.rb
|
237
247
|
- spec/commands/zunionstore_spec.rb
|
238
248
|
- spec/mock_redis_spec.rb
|
@@ -287,6 +297,8 @@ test_files:
|
|
287
297
|
- spec/commands/del_spec.rb
|
288
298
|
- spec/commands/disconnect_spec.rb
|
289
299
|
- spec/commands/echo_spec.rb
|
300
|
+
- spec/commands/eval_spec.rb
|
301
|
+
- spec/commands/evalsha_spec.rb
|
290
302
|
- spec/commands/exists_spec.rb
|
291
303
|
- spec/commands/expire_spec.rb
|
292
304
|
- spec/commands/expireat_spec.rb
|
@@ -308,6 +320,8 @@ test_files:
|
|
308
320
|
- spec/commands/hlen_spec.rb
|
309
321
|
- spec/commands/hmget_spec.rb
|
310
322
|
- spec/commands/hmset_spec.rb
|
323
|
+
- spec/commands/hscan_each_spec.rb
|
324
|
+
- spec/commands/hscan_spec.rb
|
311
325
|
- spec/commands/hset_spec.rb
|
312
326
|
- spec/commands/hsetnx_spec.rb
|
313
327
|
- spec/commands/hvals_spec.rb
|
@@ -352,8 +366,10 @@ test_files:
|
|
352
366
|
- spec/commands/rpushx_spec.rb
|
353
367
|
- spec/commands/sadd_spec.rb
|
354
368
|
- spec/commands/save_spec.rb
|
369
|
+
- spec/commands/scan_each_spec.rb
|
355
370
|
- spec/commands/scan_spec.rb
|
356
371
|
- spec/commands/scard_spec.rb
|
372
|
+
- spec/commands/script_spec.rb
|
357
373
|
- spec/commands/sdiff_spec.rb
|
358
374
|
- spec/commands/sdiffstore_spec.rb
|
359
375
|
- spec/commands/select_spec.rb
|
@@ -373,6 +389,8 @@ test_files:
|
|
373
389
|
- spec/commands/spop_spec.rb
|
374
390
|
- spec/commands/srandmember_spec.rb
|
375
391
|
- spec/commands/srem_spec.rb
|
392
|
+
- spec/commands/sscan_each_spec.rb
|
393
|
+
- spec/commands/sscan_spec.rb
|
376
394
|
- spec/commands/strlen_spec.rb
|
377
395
|
- spec/commands/sunion_spec.rb
|
378
396
|
- spec/commands/sunionstore_spec.rb
|
@@ -394,6 +412,8 @@ test_files:
|
|
394
412
|
- spec/commands/zrevrange_spec.rb
|
395
413
|
- spec/commands/zrevrangebyscore_spec.rb
|
396
414
|
- spec/commands/zrevrank_spec.rb
|
415
|
+
- spec/commands/zscan_each_spec.rb
|
416
|
+
- spec/commands/zscan_spec.rb
|
397
417
|
- spec/commands/zscore_spec.rb
|
398
418
|
- spec/commands/zunionstore_spec.rb
|
399
419
|
- spec/mock_redis_spec.rb
|