mock_redis 0.5.4 → 0.31.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 +7 -0
- data/.github/workflows/lint.yml +31 -0
- data/.github/workflows/tests.yml +63 -0
- data/.gitignore +1 -1
- data/.overcommit.yml +21 -0
- data/.rspec +1 -1
- data/.rubocop.yml +148 -0
- data/.rubocop_todo.yml +35 -0
- data/.simplecov +4 -0
- data/CHANGELOG.md +278 -0
- data/Gemfile +9 -5
- data/LICENSE.md +21 -0
- data/README.md +52 -16
- data/Rakefile +0 -8
- data/lib/mock_redis/assertions.rb +0 -1
- data/lib/mock_redis/connection_method.rb +13 -0
- data/lib/mock_redis/database.rb +193 -257
- data/lib/mock_redis/expire_wrapper.rb +2 -2
- data/lib/mock_redis/future.rb +23 -0
- data/lib/mock_redis/geospatial_methods.rb +240 -0
- data/lib/mock_redis/hash_methods.rb +83 -24
- data/lib/mock_redis/indifferent_hash.rb +11 -0
- data/lib/mock_redis/info_method.rb +160 -0
- data/lib/mock_redis/list_methods.rb +34 -19
- data/lib/mock_redis/multi_db_wrapper.rb +8 -7
- data/lib/mock_redis/pipelined_wrapper.rb +42 -16
- data/lib/mock_redis/set_methods.rb +62 -19
- data/lib/mock_redis/sort_method.rb +81 -0
- data/lib/mock_redis/stream/id.rb +58 -0
- data/lib/mock_redis/stream.rb +88 -0
- data/lib/mock_redis/stream_methods.rb +102 -0
- data/lib/mock_redis/string_methods.rb +235 -42
- data/lib/mock_redis/transaction_wrapper.rb +62 -28
- data/lib/mock_redis/utility_methods.rb +62 -11
- data/lib/mock_redis/version.rb +4 -1
- data/lib/mock_redis/zset.rb +24 -29
- data/lib/mock_redis/zset_methods.rb +187 -59
- data/lib/mock_redis.rb +77 -27
- data/mock_redis.gemspec +23 -15
- data/spec/client_spec.rb +29 -0
- 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 +25 -0
- data/spec/commands/bitfield_spec.rb +169 -0
- data/spec/commands/blpop_spec.rb +19 -21
- data/spec/commands/brpop_spec.rb +25 -20
- data/spec/commands/brpoplpush_spec.rb +16 -17
- data/spec/commands/connected_spec.rb +7 -0
- data/spec/commands/connection_spec.rb +15 -0
- data/spec/commands/dbsize_spec.rb +3 -3
- data/spec/commands/decr_spec.rb +8 -8
- data/spec/commands/decrby_spec.rb +8 -8
- data/spec/commands/del_spec.rb +35 -3
- data/spec/commands/disconnect_spec.rb +7 -0
- data/spec/commands/dump_spec.rb +19 -0
- data/spec/commands/echo_spec.rb +4 -4
- data/spec/commands/eval_spec.rb +7 -0
- data/spec/commands/evalsha_spec.rb +10 -0
- data/spec/commands/exists_spec.rb +36 -7
- data/spec/commands/expire_spec.rb +48 -20
- data/spec/commands/expireat_spec.rb +12 -13
- data/spec/commands/flushall_spec.rb +5 -5
- data/spec/commands/flushdb_spec.rb +5 -5
- data/spec/commands/future_spec.rb +30 -0
- data/spec/commands/geoadd_spec.rb +58 -0
- data/spec/commands/geodist_spec.rb +118 -0
- data/spec/commands/geohash_spec.rb +52 -0
- data/spec/commands/geopos_spec.rb +55 -0
- data/spec/commands/get_spec.rb +14 -6
- data/spec/commands/getbit_spec.rb +7 -7
- data/spec/commands/getrange_spec.rb +9 -9
- data/spec/commands/getset_spec.rb +7 -7
- data/spec/commands/hdel_spec.rb +41 -11
- data/spec/commands/hexists_spec.rb +11 -11
- data/spec/commands/hget_spec.rb +7 -7
- data/spec/commands/hgetall_spec.rb +15 -5
- data/spec/commands/hincrby_spec.rb +16 -16
- data/spec/commands/hincrbyfloat_spec.rb +58 -0
- data/spec/commands/hkeys_spec.rb +5 -5
- data/spec/commands/hlen_spec.rb +5 -5
- data/spec/commands/hmget_spec.rb +19 -9
- data/spec/commands/hmset_spec.rb +38 -12
- data/spec/commands/hscan_each_spec.rb +48 -0
- data/spec/commands/hscan_spec.rb +27 -0
- data/spec/commands/hset_spec.rb +26 -12
- data/spec/commands/hsetnx_spec.rb +16 -16
- data/spec/commands/hvals_spec.rb +5 -5
- data/spec/commands/incr_spec.rb +8 -8
- data/spec/commands/incrby_spec.rb +13 -13
- data/spec/commands/incrbyfloat_spec.rb +13 -13
- data/spec/commands/info_spec.rb +54 -5
- data/spec/commands/keys_spec.rb +83 -31
- data/spec/commands/lastsave_spec.rb +2 -2
- data/spec/commands/lindex_spec.rb +20 -10
- data/spec/commands/linsert_spec.rb +14 -14
- data/spec/commands/llen_spec.rb +4 -4
- data/spec/commands/lpop_spec.rb +6 -6
- data/spec/commands/lpush_spec.rb +21 -15
- data/spec/commands/lpushx_spec.rb +24 -11
- data/spec/commands/lrange_spec.rb +24 -8
- data/spec/commands/lrem_spec.rb +16 -16
- data/spec/commands/lset_spec.rb +17 -12
- data/spec/commands/ltrim_spec.rb +17 -7
- data/spec/commands/mapped_hmget_spec.rb +13 -9
- data/spec/commands/mapped_hmset_spec.rb +12 -12
- data/spec/commands/mapped_mget_spec.rb +22 -0
- data/spec/commands/mapped_mset_spec.rb +19 -0
- data/spec/commands/mapped_msetnx_spec.rb +26 -0
- data/spec/commands/mget_spec.rb +48 -17
- data/spec/commands/move_spec.rb +37 -37
- data/spec/commands/mset_spec.rb +20 -6
- data/spec/commands/msetnx_spec.rb +14 -14
- data/spec/commands/persist_spec.rb +15 -16
- data/spec/commands/pexpire_spec.rb +86 -0
- data/spec/commands/pexpireat_spec.rb +48 -0
- data/spec/commands/ping_spec.rb +6 -2
- data/spec/commands/pipelined_spec.rb +98 -7
- data/spec/commands/pttl_spec.rb +41 -0
- data/spec/commands/randomkey_spec.rb +3 -3
- data/spec/commands/rename_spec.rb +16 -12
- data/spec/commands/renamenx_spec.rb +13 -15
- data/spec/commands/restore_spec.rb +47 -0
- data/spec/commands/rpop_spec.rb +6 -6
- data/spec/commands/rpoplpush_spec.rb +13 -8
- data/spec/commands/rpush_spec.rb +21 -15
- data/spec/commands/rpushx_spec.rb +24 -11
- data/spec/commands/sadd_spec.rb +14 -10
- data/spec/commands/scan_each_spec.rb +39 -0
- data/spec/commands/scan_spec.rb +64 -0
- data/spec/commands/scard_spec.rb +3 -3
- data/spec/commands/script_spec.rb +9 -0
- data/spec/commands/sdiff_spec.rb +13 -13
- data/spec/commands/sdiffstore_spec.rb +13 -13
- data/spec/commands/select_spec.rb +13 -5
- data/spec/commands/set_spec.rb +112 -0
- data/spec/commands/setbit_spec.rb +25 -16
- data/spec/commands/setex_spec.rb +20 -4
- data/spec/commands/setnx_spec.rb +6 -6
- data/spec/commands/setrange_spec.rb +12 -12
- data/spec/commands/sinter_spec.rb +11 -13
- data/spec/commands/sinterstore_spec.rb +12 -12
- data/spec/commands/sismember_spec.rb +10 -10
- data/spec/commands/smembers_spec.rb +15 -5
- data/spec/commands/smove_spec.rb +13 -13
- data/spec/commands/sort_list_spec.rb +21 -0
- data/spec/commands/sort_set_spec.rb +21 -0
- data/spec/commands/sort_zset_spec.rb +21 -0
- data/spec/commands/spop_spec.rb +19 -4
- data/spec/commands/srandmember_spec.rb +28 -4
- data/spec/commands/srem_spec.rb +17 -12
- data/spec/commands/sscan_each_spec.rb +48 -0
- data/spec/commands/sscan_spec.rb +39 -0
- data/spec/commands/strlen_spec.rb +4 -5
- data/spec/commands/sunion_spec.rb +13 -11
- data/spec/commands/sunionstore_spec.rb +12 -12
- data/spec/commands/ttl_spec.rb +11 -6
- data/spec/commands/type_spec.rb +1 -1
- data/spec/commands/watch_spec.rb +9 -4
- data/spec/commands/xadd_spec.rb +122 -0
- data/spec/commands/xlen_spec.rb +22 -0
- data/spec/commands/xrange_spec.rb +164 -0
- data/spec/commands/xread_spec.rb +66 -0
- data/spec/commands/xrevrange_spec.rb +130 -0
- data/spec/commands/xtrim_spec.rb +36 -0
- data/spec/commands/zadd_spec.rb +100 -11
- data/spec/commands/zcard_spec.rb +4 -4
- data/spec/commands/zcount_spec.rb +18 -10
- data/spec/commands/zincrby_spec.rb +6 -6
- data/spec/commands/zinterstore_spec.rb +54 -20
- data/spec/commands/zpopmax_spec.rb +60 -0
- data/spec/commands/zpopmin_spec.rb +60 -0
- data/spec/commands/zrange_spec.rb +54 -13
- data/spec/commands/zrangebyscore_spec.rb +42 -27
- data/spec/commands/zrank_spec.rb +4 -4
- data/spec/commands/zrem_spec.rb +18 -12
- data/spec/commands/zremrangebyrank_spec.rb +5 -5
- data/spec/commands/zremrangebyscore_spec.rb +12 -5
- data/spec/commands/zrevrange_spec.rb +35 -10
- data/spec/commands/zrevrangebyscore_spec.rb +26 -15
- data/spec/commands/zrevrank_spec.rb +4 -4
- data/spec/commands/zscan_each_spec.rb +48 -0
- data/spec/commands/zscan_spec.rb +26 -0
- data/spec/commands/zscore_spec.rb +7 -7
- data/spec/commands/zunionstore_spec.rb +54 -21
- data/spec/mock_redis_spec.rb +61 -0
- data/spec/spec_helper.rb +35 -8
- data/spec/support/redis_multiplexer.rb +62 -37
- data/spec/support/shared_examples/does_not_cleanup_empty_strings.rb +14 -0
- data/spec/support/shared_examples/only_operates_on_hashes.rb +5 -3
- data/spec/support/shared_examples/only_operates_on_lists.rb +5 -3
- data/spec/support/shared_examples/only_operates_on_sets.rb +5 -3
- data/spec/support/shared_examples/only_operates_on_strings.rb +4 -4
- data/spec/support/shared_examples/only_operates_on_zsets.rb +18 -16
- data/spec/support/shared_examples/sorts_enumerables.rb +56 -0
- data/spec/transactions_spec.rb +79 -29
- metadata +162 -42
- data/LICENSE +0 -19
- data/spec/commands/hash_operator_spec.rb +0 -21
@@ -1,31 +1,31 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe '#expireat(key, timestamp)' do
|
4
4
|
before do
|
5
5
|
@key = 'mock-redis-test:expireat'
|
6
6
|
@redises.set(@key, 'spork')
|
7
7
|
end
|
8
8
|
|
9
|
-
it
|
10
|
-
@redises.expireat(@key, Time.now.to_i + 1).should
|
9
|
+
it 'returns true for a key that exists' do
|
10
|
+
@redises.expireat(@key, Time.now.to_i + 1).should == true
|
11
11
|
end
|
12
12
|
|
13
|
-
it
|
14
|
-
@redises.expireat('mock-redis-test:nonesuch', Time.now.to_i + 1).should
|
13
|
+
it 'returns false for a key that does not exist' do
|
14
|
+
@redises.expireat('mock-redis-test:nonesuch', Time.now.to_i + 1).should == false
|
15
15
|
end
|
16
16
|
|
17
|
-
it
|
17
|
+
it 'removes a key immediately when timestamp is now' do
|
18
18
|
@redises.expireat(@key, Time.now.to_i)
|
19
19
|
@redises.get(@key).should be_nil
|
20
20
|
end
|
21
21
|
|
22
22
|
it "raises an error if you don't give it a Unix timestamp" do
|
23
23
|
lambda do
|
24
|
-
@redises.expireat(@key, Time.now)
|
25
|
-
end.should raise_error(
|
24
|
+
@redises.expireat(@key, Time.now) # oops, forgot .to_i
|
25
|
+
end.should raise_error(Redis::CommandError)
|
26
26
|
end
|
27
27
|
|
28
|
-
context
|
28
|
+
context '[mock only]' do
|
29
29
|
# These are mock-only since we can't actually manipulate time in
|
30
30
|
# the real Redis.
|
31
31
|
|
@@ -35,14 +35,13 @@ describe "#expireat(key, timestamp)" do
|
|
35
35
|
|
36
36
|
before do
|
37
37
|
@now = Time.now
|
38
|
-
Time.stub
|
38
|
+
Time.stub(:now).and_return(@now)
|
39
39
|
end
|
40
40
|
|
41
|
-
it
|
41
|
+
it 'removes keys after enough time has passed' do
|
42
42
|
@mock.expireat(@key, @now.to_i + 5)
|
43
|
-
Time.stub
|
43
|
+
Time.stub(:now).and_return(@now + 5)
|
44
44
|
@mock.get(@key).should be_nil
|
45
45
|
end
|
46
|
-
|
47
46
|
end
|
48
47
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe '#flushall [mock only]' do
|
4
4
|
# don't want to hurt things in the real redis that are outside our
|
5
5
|
# namespace.
|
6
6
|
before { @mock = @redises.mock }
|
@@ -10,7 +10,7 @@ describe "#flushall [mock only]" do
|
|
10
10
|
@mock.flushall.should == 'OK'
|
11
11
|
end
|
12
12
|
|
13
|
-
it
|
13
|
+
it 'removes all keys in the current DB' do
|
14
14
|
@mock.set('k1', 'v1')
|
15
15
|
@mock.lpush('k2', 'v2')
|
16
16
|
|
@@ -18,7 +18,7 @@ describe "#flushall [mock only]" do
|
|
18
18
|
@mock.keys('*').should == []
|
19
19
|
end
|
20
20
|
|
21
|
-
it
|
21
|
+
it 'removes all keys in other DBs, too' do
|
22
22
|
@mock.set('k1', 'v1')
|
23
23
|
|
24
24
|
@mock.select(1)
|
@@ -28,9 +28,9 @@ describe "#flushall [mock only]" do
|
|
28
28
|
@mock.get('k1').should be_nil
|
29
29
|
end
|
30
30
|
|
31
|
-
it
|
31
|
+
it 'removes expiration times' do
|
32
32
|
@mock.set('k1', 'v1')
|
33
|
-
@mock.expire('k1',
|
33
|
+
@mock.expire('k1', 360_000)
|
34
34
|
@mock.flushall
|
35
35
|
@mock.set('k1', 'v1')
|
36
36
|
@mock.ttl('k1').should == -1
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe '#flushdb [mock only]' do
|
4
4
|
# don't want to hurt things in the real redis that are outside our
|
5
5
|
# namespace.
|
6
6
|
before { @mock = @redises.mock }
|
@@ -10,7 +10,7 @@ describe "#flushdb [mock only]" do
|
|
10
10
|
@mock.flushdb.should == 'OK'
|
11
11
|
end
|
12
12
|
|
13
|
-
it
|
13
|
+
it 'removes all keys in the current DB' do
|
14
14
|
@mock.set('k1', 'v1')
|
15
15
|
@mock.lpush('k2', 'v2')
|
16
16
|
|
@@ -18,7 +18,7 @@ describe "#flushdb [mock only]" do
|
|
18
18
|
@mock.keys('*').should == []
|
19
19
|
end
|
20
20
|
|
21
|
-
it
|
21
|
+
it 'leaves other databases alone' do
|
22
22
|
@mock.set('k1', 'v1')
|
23
23
|
|
24
24
|
@mock.select(1)
|
@@ -28,9 +28,9 @@ describe "#flushdb [mock only]" do
|
|
28
28
|
@mock.get('k1').should == 'v1'
|
29
29
|
end
|
30
30
|
|
31
|
-
it
|
31
|
+
it 'removes expiration times' do
|
32
32
|
@mock.set('k1', 'v1')
|
33
|
-
@mock.expire('k1',
|
33
|
+
@mock.expire('k1', 360_000)
|
34
34
|
@mock.flushdb
|
35
35
|
@mock.set('k1', 'v1')
|
36
36
|
@mock.ttl('k1').should == -1
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MockRedis::Future do
|
4
|
+
let(:command) { [:get, 'foo'] }
|
5
|
+
let(:result) { 'bar' }
|
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
|
12
|
+
|
13
|
+
it 'remembers the command' do
|
14
|
+
@future.command.should eq(command)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'raises an error if the value is requested before the result is set' do
|
18
|
+
expect { @future.value }.to raise_error(MockRedis::FutureNotReady)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'returns the value after the result has been set' do
|
22
|
+
@future.store_result(result)
|
23
|
+
@future.value.should eq(result)
|
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
|
30
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe '#geoadd' do
|
4
|
+
let(:key) { 'cities' }
|
5
|
+
|
6
|
+
context 'with valid points' do
|
7
|
+
let(:san_francisco) { [-122.5076404, 37.757815, 'SF'] }
|
8
|
+
let(:los_angeles) { [-118.6919259, 34.0207305, 'LA'] }
|
9
|
+
let(:expected_result) do
|
10
|
+
[['LA', 1.364461589564902e+15], ['SF', 1.367859319053696e+15]]
|
11
|
+
end
|
12
|
+
|
13
|
+
before { @redises.geoadd(key, *san_francisco, *los_angeles) }
|
14
|
+
|
15
|
+
after { @redises.zrem(key, %w[SF LA]) }
|
16
|
+
|
17
|
+
it 'adds members to ZSET' do
|
18
|
+
cities = @redises.zrange(key, 0, -1, with_scores: true)
|
19
|
+
expect(cities).to be == expected_result
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'with invalud points' do
|
24
|
+
context 'when number of arguments wrong' do
|
25
|
+
let(:message) { "ERR wrong number of arguments for 'geoadd' command" }
|
26
|
+
|
27
|
+
it 'raises Redis::CommandError' do
|
28
|
+
expect { @redises.geoadd(key, 1, 1) }
|
29
|
+
.to raise_error(Redis::CommandError, message)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'when coordinates are not in allowed range' do
|
34
|
+
let(:coords) { [181, 86] }
|
35
|
+
let(:message) do
|
36
|
+
formatted_coords = coords.map { |c| format('%<coords>.6f', coords: c) }
|
37
|
+
"ERR invalid longitude,latitude pair #{formatted_coords.join(',')}"
|
38
|
+
end
|
39
|
+
|
40
|
+
after { @redises.zrem(key, 'SF') }
|
41
|
+
|
42
|
+
it 'raises Redis::CommandError' do
|
43
|
+
expect { @redises.geoadd(key, *coords, 'SF') }
|
44
|
+
.to raise_error(Redis::CommandError, message)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'when coordinates are not valid floats' do
|
49
|
+
let(:coords) { ['x', 35] }
|
50
|
+
let(:message) { 'ERR value is not a valid float' }
|
51
|
+
|
52
|
+
it 'raises Redis::CommandError' do
|
53
|
+
expect { @redises.geoadd key, *coords, 'SF' }
|
54
|
+
.to raise_error(Redis::CommandError, message)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
shared_examples 'a distance calculator' do
|
4
|
+
it 'returns distance between two points in specified unit' do
|
5
|
+
dist = @redises.geodist(key, 'SF', 'LA', unit)
|
6
|
+
expect(dist).to be == expected_result
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#geodist' do
|
11
|
+
let(:key) { 'cities' }
|
12
|
+
|
13
|
+
context 'with existing key' do
|
14
|
+
let(:san_francisco) { [-122.5076404, 37.757815, 'SF'] }
|
15
|
+
let(:los_angeles) { [-118.6919259, 34.0207305, 'LA'] }
|
16
|
+
|
17
|
+
before { @redises.geoadd(key, *san_francisco, *los_angeles) }
|
18
|
+
|
19
|
+
after { @redises.zrem(key, %w[SF LA]) }
|
20
|
+
|
21
|
+
context 'with existing points only' do
|
22
|
+
context 'using m as unit' do
|
23
|
+
let(:unit) { 'm' }
|
24
|
+
let(:expected_result) { '539327.9659' }
|
25
|
+
|
26
|
+
it 'returns distance between two points in meters' do
|
27
|
+
dist = @redises.geodist(key, 'SF', 'LA')
|
28
|
+
expect(dist).to be == expected_result
|
29
|
+
end
|
30
|
+
|
31
|
+
it_behaves_like 'a distance calculator'
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'using km as unit' do
|
35
|
+
let(:unit) { 'km' }
|
36
|
+
let(:expected_result) { '539.3280' }
|
37
|
+
|
38
|
+
it_behaves_like 'a distance calculator'
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'using ft as unit' do
|
42
|
+
let(:unit) { 'ft' }
|
43
|
+
let(:expected_result) { '1769448.7069' }
|
44
|
+
|
45
|
+
it_behaves_like 'a distance calculator'
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'using mi as unit' do
|
49
|
+
let(:unit) { 'mi' }
|
50
|
+
let(:expected_result) { '335.1237' }
|
51
|
+
|
52
|
+
it_behaves_like 'a distance calculator'
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'with non-existing points only' do
|
56
|
+
it 'returns nil' do
|
57
|
+
dist = @redises.geodist(key, 'FF', 'FA')
|
58
|
+
expect(dist).to be_nil
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'with both existing and non-existing points' do
|
63
|
+
it 'returns nil' do
|
64
|
+
dist = @redises.geodist(key, 'SF', 'FA')
|
65
|
+
expect(dist).to be_nil
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'with non-existing key' do
|
72
|
+
it 'returns empty string' do
|
73
|
+
dist = @redises.geodist(key, 'SF', 'LA')
|
74
|
+
expect(dist).to be_nil
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'with wrong number of arguments' do
|
79
|
+
let(:list) { [key, 'SF', 'LA', 'm', 'smth'] }
|
80
|
+
|
81
|
+
context 'with less than 3 arguments' do
|
82
|
+
[1, 2].each do |count|
|
83
|
+
context "with #{count} arguments" do
|
84
|
+
it 'raises an error' do
|
85
|
+
args = list.slice(0, count)
|
86
|
+
expect { @redises.geodist(*args) }
|
87
|
+
.to raise_error(
|
88
|
+
ArgumentError,
|
89
|
+
/wrong number of arguments \((given\s)?#{count}(,\sexpected\s|\sfor\s)3?\.\.4\)$/
|
90
|
+
)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'with more than 3 arguments' do
|
97
|
+
let(:message) { 'ERR syntax error' }
|
98
|
+
|
99
|
+
it 'raises an error' do
|
100
|
+
args = list.slice(0, 5)
|
101
|
+
expect { @redises.geodist(*args) }
|
102
|
+
.to raise_error(
|
103
|
+
ArgumentError,
|
104
|
+
/wrong number of arguments \((given\s)?5(,\sexpected\s|\sfor\s)3?\.\.4\)$/
|
105
|
+
)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'with wrong unit' do
|
111
|
+
let(:message) { 'ERR unsupported unit provided. please use m, km, ft, mi' }
|
112
|
+
|
113
|
+
it 'raises an error' do
|
114
|
+
expect { @redises.geodist(key, 'SF', 'LA', 'a') }
|
115
|
+
.to raise_error(Redis::CommandError, message)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe '#geohash' do
|
4
|
+
let(:key) { 'cities' }
|
5
|
+
|
6
|
+
context 'with existing key' do
|
7
|
+
let(:san_francisco) { [-122.5076404, 37.757815, 'SF'] }
|
8
|
+
let(:los_angeles) { [-118.6919259, 34.0207305, 'LA'] }
|
9
|
+
|
10
|
+
before { @redises.geoadd(key, *san_francisco, *los_angeles) }
|
11
|
+
|
12
|
+
after { @redises.zrem(key, %w[SF LA]) }
|
13
|
+
|
14
|
+
context 'with existing points only' do
|
15
|
+
let(:expected_result) do
|
16
|
+
%w[9q8yu38ejp0 9q59e171je0]
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'returns decoded coordinates pairs for each point' do
|
20
|
+
results = @redises.geohash(key, %w[SF LA])
|
21
|
+
expect(results).to be == expected_result
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'with non-existing points only' do
|
25
|
+
it 'returns array filled with nils' do
|
26
|
+
results = @redises.geohash(key, %w[FF FA])
|
27
|
+
expect(results).to be == [nil, nil]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'with both existing and non-existing points' do
|
32
|
+
let(:expected_result) do
|
33
|
+
['9q8yu38ejp0', nil]
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'returns mixture of nil and coordinates pair' do
|
37
|
+
results = @redises.geohash(key, %w[SF FA])
|
38
|
+
expect(results).to be == expected_result
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'with non-existing key' do
|
45
|
+
before { @redises.del(key) }
|
46
|
+
|
47
|
+
it 'returns empty array' do
|
48
|
+
results = @redises.geohash(key, %w[SF LA])
|
49
|
+
expect(results).to be == [nil, nil]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe '#geopos' do
|
4
|
+
let(:key) { 'cities' }
|
5
|
+
|
6
|
+
context 'with existing key' do
|
7
|
+
let(:san_francisco) { [-122.5076404, 37.757815, 'SF'] }
|
8
|
+
let(:los_angeles) { [-118.6919259, 34.0207305, 'LA'] }
|
9
|
+
|
10
|
+
before { @redises.geoadd(key, *san_francisco, *los_angeles) }
|
11
|
+
|
12
|
+
after { @redises.zrem(key, %w[SF LA]) }
|
13
|
+
|
14
|
+
context 'with existing points only' do
|
15
|
+
let(:expected_result) do
|
16
|
+
[
|
17
|
+
%w[-122.5076410174369812 37.75781598995183685],
|
18
|
+
%w[-118.69192510843276978 34.020729570911179]
|
19
|
+
]
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'returns decoded coordinates pairs for each point' do
|
23
|
+
coords = @redises.geopos(key, %w[SF LA])
|
24
|
+
expect(coords).to be == expected_result
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'with non-existing points only' do
|
28
|
+
it 'returns array filled with nils' do
|
29
|
+
coords = @redises.geopos(key, %w[FF FA])
|
30
|
+
expect(coords).to be == [nil, nil]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'with both existing and non-existing points' do
|
35
|
+
let(:expected_result) do
|
36
|
+
[%w[-122.5076410174369812 37.75781598995183685], nil]
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'returns mixture of nil and coordinates pair' do
|
40
|
+
coords = @redises.geopos(key, %w[SF FA])
|
41
|
+
expect(coords).to be == expected_result
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'with non-existing key' do
|
48
|
+
before { @redises.del(key) }
|
49
|
+
|
50
|
+
it 'returns empty array' do
|
51
|
+
coords = @redises.geopos(key, %w[SF LA])
|
52
|
+
expect(coords).to be == [nil, nil]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/spec/commands/get_spec.rb
CHANGED
@@ -1,23 +1,31 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe '#get(key)' do
|
4
4
|
before do
|
5
5
|
@key = 'mock-redis-test:73288'
|
6
6
|
end
|
7
7
|
|
8
|
-
it
|
8
|
+
it 'returns nil for a nonexistent value' do
|
9
9
|
@redises.get('mock-redis-test:does-not-exist').should be_nil
|
10
10
|
end
|
11
11
|
|
12
|
-
it
|
12
|
+
it 'returns a stored string value' do
|
13
13
|
@redises.set(@key, 'forsooth')
|
14
14
|
@redises.get(@key).should == 'forsooth'
|
15
15
|
end
|
16
16
|
|
17
|
-
it
|
17
|
+
it 'treats integers as strings' do
|
18
18
|
@redises.set(@key, 100)
|
19
|
-
@redises.get(@key).should ==
|
19
|
+
@redises.get(@key).should == '100'
|
20
20
|
end
|
21
21
|
|
22
|
-
|
22
|
+
it 'stringifies key' do
|
23
|
+
key = :a_symbol
|
24
|
+
|
25
|
+
@redises.set(key, 'hello')
|
26
|
+
@redises.get(key.to_s).should == 'hello'
|
27
|
+
@redises.get(key).should == 'hello'
|
28
|
+
end
|
29
|
+
|
30
|
+
it_should_behave_like 'a string-only command'
|
23
31
|
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe '#getbit(key, offset)' do
|
4
4
|
before do
|
5
5
|
@key = 'mock-redis-test:getbit'
|
6
|
-
@redises.set(@key, 'h')
|
6
|
+
@redises.set(@key, 'h') # ASCII 0x68
|
7
7
|
end
|
8
8
|
|
9
|
-
it
|
9
|
+
it 'gets the bits from the key' do
|
10
10
|
@redises.getbit(@key, 0).should == 0
|
11
11
|
@redises.getbit(@key, 1).should == 1
|
12
12
|
@redises.getbit(@key, 2).should == 1
|
@@ -17,18 +17,18 @@ describe "#getbit(key, offset)" do
|
|
17
17
|
@redises.getbit(@key, 7).should == 0
|
18
18
|
end
|
19
19
|
|
20
|
-
it
|
20
|
+
it 'returns 0 for out-of-range bits' do
|
21
21
|
@redises.getbit(@key, 100).should == 0
|
22
22
|
end
|
23
23
|
|
24
|
-
it
|
24
|
+
it 'does not modify the stored value for out-of-range bits' do
|
25
25
|
@redises.getbit(@key, 100)
|
26
26
|
@redises.get(@key).should == 'h'
|
27
27
|
end
|
28
28
|
|
29
|
-
it
|
29
|
+
it 'treats nonexistent keys as empty strings' do
|
30
30
|
@redises.getbit('mock-redis-test:not-found', 0).should == 0
|
31
31
|
end
|
32
32
|
|
33
|
-
it_should_behave_like
|
33
|
+
it_should_behave_like 'a string-only command'
|
34
34
|
end
|
@@ -1,22 +1,22 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe '#getrange(key, start, stop)' do
|
4
4
|
before do
|
5
5
|
@key = 'mock-redis-test:getrange'
|
6
|
-
@redises.set(@key,
|
6
|
+
@redises.set(@key, 'This is a string')
|
7
7
|
end
|
8
8
|
|
9
|
-
it
|
10
|
-
@redises.getrange(@key, 0, 3).should ==
|
9
|
+
it 'returns a substring' do
|
10
|
+
@redises.getrange(@key, 0, 3).should == 'This'
|
11
11
|
end
|
12
12
|
|
13
|
-
it
|
14
|
-
@redises.getrange(@key, -3, -1).should ==
|
13
|
+
it 'works with negative indices' do
|
14
|
+
@redises.getrange(@key, -3, -1).should == 'ing'
|
15
15
|
end
|
16
16
|
|
17
|
-
it
|
18
|
-
@redises.getrange(@key, 10, 100).should ==
|
17
|
+
it 'limits the result to the actual length of the string' do
|
18
|
+
@redises.getrange(@key, 10, 100).should == 'string'
|
19
19
|
end
|
20
20
|
|
21
|
-
it_should_behave_like
|
21
|
+
it_should_behave_like 'a string-only command'
|
22
22
|
end
|
@@ -1,23 +1,23 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe '#getrange(key, value)' do
|
4
4
|
before do
|
5
5
|
@key = 'mock-redis-test:getset'
|
6
|
-
@redises.set(@key,
|
6
|
+
@redises.set(@key, 'oldvalue')
|
7
7
|
end
|
8
8
|
|
9
|
-
it
|
10
|
-
@redises.getset(@key, 'newvalue').should ==
|
9
|
+
it 'returns the old value' do
|
10
|
+
@redises.getset(@key, 'newvalue').should == 'oldvalue'
|
11
11
|
end
|
12
12
|
|
13
|
-
it
|
13
|
+
it 'sets the value to the new value' do
|
14
14
|
@redises.getset(@key, 'newvalue')
|
15
15
|
@redises.get(@key).should == 'newvalue'
|
16
16
|
end
|
17
17
|
|
18
|
-
it
|
18
|
+
it 'returns nil for nonexistent keys' do
|
19
19
|
@redises.getset('mock-redis-test:not-found', 1).should be_nil
|
20
20
|
end
|
21
21
|
|
22
|
-
it_should_behave_like
|
22
|
+
it_should_behave_like 'a string-only command'
|
23
23
|
end
|
data/spec/commands/hdel_spec.rb
CHANGED
@@ -1,47 +1,77 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe '#hdel(key, field)' do
|
4
4
|
before do
|
5
|
-
@key =
|
5
|
+
@key = 'mock-redis-test:hdel'
|
6
6
|
@redises.hset(@key, 'k1', 'v1')
|
7
7
|
@redises.hset(@key, 'k2', 'v2')
|
8
8
|
end
|
9
9
|
|
10
|
-
it
|
10
|
+
it 'returns 1 when it removes a field' do
|
11
11
|
@redises.hdel(@key, 'k1').should == 1
|
12
12
|
end
|
13
13
|
|
14
|
-
it
|
14
|
+
it 'returns 0 when it does not remove a field' do
|
15
15
|
@redises.hdel(@key, 'nonesuch').should == 0
|
16
16
|
end
|
17
17
|
|
18
|
-
it
|
18
|
+
it 'actually removes the field' do
|
19
19
|
@redises.hdel(@key, 'k1')
|
20
20
|
@redises.hget(@key, 'k1').should be_nil
|
21
21
|
end
|
22
22
|
|
23
|
-
it
|
23
|
+
it 'treats the field as a string' do
|
24
24
|
field = 2
|
25
25
|
@redises.hset(@key, field, 'two')
|
26
26
|
@redises.hdel(@key, field)
|
27
27
|
@redises.hget(@key, field).should be_nil
|
28
28
|
end
|
29
29
|
|
30
|
-
it
|
30
|
+
it 'removes only the field specified' do
|
31
31
|
@redises.hdel(@key, 'k1')
|
32
32
|
@redises.hget(@key, 'k2').should == 'v2'
|
33
33
|
end
|
34
34
|
|
35
|
-
it
|
35
|
+
it 'cleans up empty hashes' do
|
36
36
|
@redises.hdel(@key, 'k1')
|
37
37
|
@redises.hdel(@key, 'k2')
|
38
38
|
@redises.get(@key).should be_nil
|
39
39
|
end
|
40
40
|
|
41
|
-
it
|
42
|
-
@redises.hdel(@key,
|
41
|
+
it 'supports a variable number of arguments' do
|
42
|
+
@redises.hdel(@key, 'k1', 'k2')
|
43
43
|
@redises.get(@key).should be_nil
|
44
44
|
end
|
45
45
|
|
46
|
-
|
46
|
+
it 'treats variable arguments as strings' do
|
47
|
+
field = 2
|
48
|
+
@redises.hset(@key, field, 'two')
|
49
|
+
@redises.hdel(@key, field)
|
50
|
+
@redises.hget(@key, field).should be_nil
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'supports a variable number of fields as array' do
|
54
|
+
@redises.hdel(@key, %w[k1 k2]).should == 2
|
55
|
+
|
56
|
+
@redises.hget(@key, 'k1').should be_nil
|
57
|
+
@redises.hget(@key, 'k2').should be_nil
|
58
|
+
@redises.get(@key).should be_nil
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'supports a list of fields in various way' do
|
62
|
+
@redises.hdel(@key, ['k1'], 'k2').should == 2
|
63
|
+
|
64
|
+
@redises.hget(@key, 'k1').should be_nil
|
65
|
+
@redises.hget(@key, 'k2').should be_nil
|
66
|
+
@redises.get(@key).should be_nil
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'raises error if an empty array is passed' do
|
70
|
+
expect { @redises.hdel(@key, []) }.to raise_error(
|
71
|
+
Redis::CommandError,
|
72
|
+
"ERR wrong number of arguments for 'hdel' command"
|
73
|
+
)
|
74
|
+
end
|
75
|
+
|
76
|
+
it_should_behave_like 'a hash-only command'
|
47
77
|
end
|