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.
Files changed (201) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/lint.yml +31 -0
  3. data/.github/workflows/tests.yml +63 -0
  4. data/.gitignore +1 -1
  5. data/.overcommit.yml +21 -0
  6. data/.rspec +1 -1
  7. data/.rubocop.yml +148 -0
  8. data/.rubocop_todo.yml +35 -0
  9. data/.simplecov +4 -0
  10. data/CHANGELOG.md +278 -0
  11. data/Gemfile +9 -5
  12. data/LICENSE.md +21 -0
  13. data/README.md +52 -16
  14. data/Rakefile +0 -8
  15. data/lib/mock_redis/assertions.rb +0 -1
  16. data/lib/mock_redis/connection_method.rb +13 -0
  17. data/lib/mock_redis/database.rb +193 -257
  18. data/lib/mock_redis/expire_wrapper.rb +2 -2
  19. data/lib/mock_redis/future.rb +23 -0
  20. data/lib/mock_redis/geospatial_methods.rb +240 -0
  21. data/lib/mock_redis/hash_methods.rb +83 -24
  22. data/lib/mock_redis/indifferent_hash.rb +11 -0
  23. data/lib/mock_redis/info_method.rb +160 -0
  24. data/lib/mock_redis/list_methods.rb +34 -19
  25. data/lib/mock_redis/multi_db_wrapper.rb +8 -7
  26. data/lib/mock_redis/pipelined_wrapper.rb +42 -16
  27. data/lib/mock_redis/set_methods.rb +62 -19
  28. data/lib/mock_redis/sort_method.rb +81 -0
  29. data/lib/mock_redis/stream/id.rb +58 -0
  30. data/lib/mock_redis/stream.rb +88 -0
  31. data/lib/mock_redis/stream_methods.rb +102 -0
  32. data/lib/mock_redis/string_methods.rb +235 -42
  33. data/lib/mock_redis/transaction_wrapper.rb +62 -28
  34. data/lib/mock_redis/utility_methods.rb +62 -11
  35. data/lib/mock_redis/version.rb +4 -1
  36. data/lib/mock_redis/zset.rb +24 -29
  37. data/lib/mock_redis/zset_methods.rb +187 -59
  38. data/lib/mock_redis.rb +77 -27
  39. data/mock_redis.gemspec +23 -15
  40. data/spec/client_spec.rb +29 -0
  41. data/spec/cloning_spec.rb +17 -18
  42. data/spec/commands/append_spec.rb +4 -4
  43. data/spec/commands/auth_spec.rb +1 -1
  44. data/spec/commands/bgrewriteaof_spec.rb +2 -2
  45. data/spec/commands/bgsave_spec.rb +2 -2
  46. data/spec/commands/bitcount_spec.rb +25 -0
  47. data/spec/commands/bitfield_spec.rb +169 -0
  48. data/spec/commands/blpop_spec.rb +19 -21
  49. data/spec/commands/brpop_spec.rb +25 -20
  50. data/spec/commands/brpoplpush_spec.rb +16 -17
  51. data/spec/commands/connected_spec.rb +7 -0
  52. data/spec/commands/connection_spec.rb +15 -0
  53. data/spec/commands/dbsize_spec.rb +3 -3
  54. data/spec/commands/decr_spec.rb +8 -8
  55. data/spec/commands/decrby_spec.rb +8 -8
  56. data/spec/commands/del_spec.rb +35 -3
  57. data/spec/commands/disconnect_spec.rb +7 -0
  58. data/spec/commands/dump_spec.rb +19 -0
  59. data/spec/commands/echo_spec.rb +4 -4
  60. data/spec/commands/eval_spec.rb +7 -0
  61. data/spec/commands/evalsha_spec.rb +10 -0
  62. data/spec/commands/exists_spec.rb +36 -7
  63. data/spec/commands/expire_spec.rb +48 -20
  64. data/spec/commands/expireat_spec.rb +12 -13
  65. data/spec/commands/flushall_spec.rb +5 -5
  66. data/spec/commands/flushdb_spec.rb +5 -5
  67. data/spec/commands/future_spec.rb +30 -0
  68. data/spec/commands/geoadd_spec.rb +58 -0
  69. data/spec/commands/geodist_spec.rb +118 -0
  70. data/spec/commands/geohash_spec.rb +52 -0
  71. data/spec/commands/geopos_spec.rb +55 -0
  72. data/spec/commands/get_spec.rb +14 -6
  73. data/spec/commands/getbit_spec.rb +7 -7
  74. data/spec/commands/getrange_spec.rb +9 -9
  75. data/spec/commands/getset_spec.rb +7 -7
  76. data/spec/commands/hdel_spec.rb +41 -11
  77. data/spec/commands/hexists_spec.rb +11 -11
  78. data/spec/commands/hget_spec.rb +7 -7
  79. data/spec/commands/hgetall_spec.rb +15 -5
  80. data/spec/commands/hincrby_spec.rb +16 -16
  81. data/spec/commands/hincrbyfloat_spec.rb +58 -0
  82. data/spec/commands/hkeys_spec.rb +5 -5
  83. data/spec/commands/hlen_spec.rb +5 -5
  84. data/spec/commands/hmget_spec.rb +19 -9
  85. data/spec/commands/hmset_spec.rb +38 -12
  86. data/spec/commands/hscan_each_spec.rb +48 -0
  87. data/spec/commands/hscan_spec.rb +27 -0
  88. data/spec/commands/hset_spec.rb +26 -12
  89. data/spec/commands/hsetnx_spec.rb +16 -16
  90. data/spec/commands/hvals_spec.rb +5 -5
  91. data/spec/commands/incr_spec.rb +8 -8
  92. data/spec/commands/incrby_spec.rb +13 -13
  93. data/spec/commands/incrbyfloat_spec.rb +13 -13
  94. data/spec/commands/info_spec.rb +54 -5
  95. data/spec/commands/keys_spec.rb +83 -31
  96. data/spec/commands/lastsave_spec.rb +2 -2
  97. data/spec/commands/lindex_spec.rb +20 -10
  98. data/spec/commands/linsert_spec.rb +14 -14
  99. data/spec/commands/llen_spec.rb +4 -4
  100. data/spec/commands/lpop_spec.rb +6 -6
  101. data/spec/commands/lpush_spec.rb +21 -15
  102. data/spec/commands/lpushx_spec.rb +24 -11
  103. data/spec/commands/lrange_spec.rb +24 -8
  104. data/spec/commands/lrem_spec.rb +16 -16
  105. data/spec/commands/lset_spec.rb +17 -12
  106. data/spec/commands/ltrim_spec.rb +17 -7
  107. data/spec/commands/mapped_hmget_spec.rb +13 -9
  108. data/spec/commands/mapped_hmset_spec.rb +12 -12
  109. data/spec/commands/mapped_mget_spec.rb +22 -0
  110. data/spec/commands/mapped_mset_spec.rb +19 -0
  111. data/spec/commands/mapped_msetnx_spec.rb +26 -0
  112. data/spec/commands/mget_spec.rb +48 -17
  113. data/spec/commands/move_spec.rb +37 -37
  114. data/spec/commands/mset_spec.rb +20 -6
  115. data/spec/commands/msetnx_spec.rb +14 -14
  116. data/spec/commands/persist_spec.rb +15 -16
  117. data/spec/commands/pexpire_spec.rb +86 -0
  118. data/spec/commands/pexpireat_spec.rb +48 -0
  119. data/spec/commands/ping_spec.rb +6 -2
  120. data/spec/commands/pipelined_spec.rb +98 -7
  121. data/spec/commands/pttl_spec.rb +41 -0
  122. data/spec/commands/randomkey_spec.rb +3 -3
  123. data/spec/commands/rename_spec.rb +16 -12
  124. data/spec/commands/renamenx_spec.rb +13 -15
  125. data/spec/commands/restore_spec.rb +47 -0
  126. data/spec/commands/rpop_spec.rb +6 -6
  127. data/spec/commands/rpoplpush_spec.rb +13 -8
  128. data/spec/commands/rpush_spec.rb +21 -15
  129. data/spec/commands/rpushx_spec.rb +24 -11
  130. data/spec/commands/sadd_spec.rb +14 -10
  131. data/spec/commands/scan_each_spec.rb +39 -0
  132. data/spec/commands/scan_spec.rb +64 -0
  133. data/spec/commands/scard_spec.rb +3 -3
  134. data/spec/commands/script_spec.rb +9 -0
  135. data/spec/commands/sdiff_spec.rb +13 -13
  136. data/spec/commands/sdiffstore_spec.rb +13 -13
  137. data/spec/commands/select_spec.rb +13 -5
  138. data/spec/commands/set_spec.rb +112 -0
  139. data/spec/commands/setbit_spec.rb +25 -16
  140. data/spec/commands/setex_spec.rb +20 -4
  141. data/spec/commands/setnx_spec.rb +6 -6
  142. data/spec/commands/setrange_spec.rb +12 -12
  143. data/spec/commands/sinter_spec.rb +11 -13
  144. data/spec/commands/sinterstore_spec.rb +12 -12
  145. data/spec/commands/sismember_spec.rb +10 -10
  146. data/spec/commands/smembers_spec.rb +15 -5
  147. data/spec/commands/smove_spec.rb +13 -13
  148. data/spec/commands/sort_list_spec.rb +21 -0
  149. data/spec/commands/sort_set_spec.rb +21 -0
  150. data/spec/commands/sort_zset_spec.rb +21 -0
  151. data/spec/commands/spop_spec.rb +19 -4
  152. data/spec/commands/srandmember_spec.rb +28 -4
  153. data/spec/commands/srem_spec.rb +17 -12
  154. data/spec/commands/sscan_each_spec.rb +48 -0
  155. data/spec/commands/sscan_spec.rb +39 -0
  156. data/spec/commands/strlen_spec.rb +4 -5
  157. data/spec/commands/sunion_spec.rb +13 -11
  158. data/spec/commands/sunionstore_spec.rb +12 -12
  159. data/spec/commands/ttl_spec.rb +11 -6
  160. data/spec/commands/type_spec.rb +1 -1
  161. data/spec/commands/watch_spec.rb +9 -4
  162. data/spec/commands/xadd_spec.rb +122 -0
  163. data/spec/commands/xlen_spec.rb +22 -0
  164. data/spec/commands/xrange_spec.rb +164 -0
  165. data/spec/commands/xread_spec.rb +66 -0
  166. data/spec/commands/xrevrange_spec.rb +130 -0
  167. data/spec/commands/xtrim_spec.rb +36 -0
  168. data/spec/commands/zadd_spec.rb +100 -11
  169. data/spec/commands/zcard_spec.rb +4 -4
  170. data/spec/commands/zcount_spec.rb +18 -10
  171. data/spec/commands/zincrby_spec.rb +6 -6
  172. data/spec/commands/zinterstore_spec.rb +54 -20
  173. data/spec/commands/zpopmax_spec.rb +60 -0
  174. data/spec/commands/zpopmin_spec.rb +60 -0
  175. data/spec/commands/zrange_spec.rb +54 -13
  176. data/spec/commands/zrangebyscore_spec.rb +42 -27
  177. data/spec/commands/zrank_spec.rb +4 -4
  178. data/spec/commands/zrem_spec.rb +18 -12
  179. data/spec/commands/zremrangebyrank_spec.rb +5 -5
  180. data/spec/commands/zremrangebyscore_spec.rb +12 -5
  181. data/spec/commands/zrevrange_spec.rb +35 -10
  182. data/spec/commands/zrevrangebyscore_spec.rb +26 -15
  183. data/spec/commands/zrevrank_spec.rb +4 -4
  184. data/spec/commands/zscan_each_spec.rb +48 -0
  185. data/spec/commands/zscan_spec.rb +26 -0
  186. data/spec/commands/zscore_spec.rb +7 -7
  187. data/spec/commands/zunionstore_spec.rb +54 -21
  188. data/spec/mock_redis_spec.rb +61 -0
  189. data/spec/spec_helper.rb +35 -8
  190. data/spec/support/redis_multiplexer.rb +62 -37
  191. data/spec/support/shared_examples/does_not_cleanup_empty_strings.rb +14 -0
  192. data/spec/support/shared_examples/only_operates_on_hashes.rb +5 -3
  193. data/spec/support/shared_examples/only_operates_on_lists.rb +5 -3
  194. data/spec/support/shared_examples/only_operates_on_sets.rb +5 -3
  195. data/spec/support/shared_examples/only_operates_on_strings.rb +4 -4
  196. data/spec/support/shared_examples/only_operates_on_zsets.rb +18 -16
  197. data/spec/support/shared_examples/sorts_enumerables.rb +56 -0
  198. data/spec/transactions_spec.rb +79 -29
  199. metadata +162 -42
  200. data/LICENSE +0 -19
  201. data/spec/commands/hash_operator_spec.rb +0 -21
@@ -1,31 +1,31 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "#expireat(key, timestamp)" do
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 "returns true for a key that exists" do
10
- @redises.expireat(@key, Time.now.to_i + 1).should be_true
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 "returns false for a key that does not exist" do
14
- @redises.expireat('mock-redis-test:nonesuch', Time.now.to_i + 1).should be_false
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 "removes a key immediately when timestamp is now" do
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) # oops, forgot .to_i
25
- end.should raise_error(RuntimeError)
24
+ @redises.expireat(@key, Time.now) # oops, forgot .to_i
25
+ end.should raise_error(Redis::CommandError)
26
26
  end
27
27
 
28
- context "[mock only]" do
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!(:now).and_return(@now)
38
+ Time.stub(:now).and_return(@now)
39
39
  end
40
40
 
41
- it "removes keys after enough time has passed" do
41
+ it 'removes keys after enough time has passed' do
42
42
  @mock.expireat(@key, @now.to_i + 5)
43
- Time.stub!(:now).and_return(@now + 5)
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 "#flushall [mock only]" do
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 "removes all keys in the current DB" do
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 "removes all keys in other DBs, too" do
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 "removes expiration times" do
31
+ it 'removes expiration times' do
32
32
  @mock.set('k1', 'v1')
33
- @mock.expire('k1', 360000)
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 "#flushdb [mock only]" do
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 "removes all keys in the current DB" do
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 "leaves other databases alone" do
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 "removes expiration times" do
31
+ it 'removes expiration times' do
32
32
  @mock.set('k1', 'v1')
33
- @mock.expire('k1', 360000)
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
@@ -1,23 +1,31 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "#get(key)" do
3
+ describe '#get(key)' do
4
4
  before do
5
5
  @key = 'mock-redis-test:73288'
6
6
  end
7
7
 
8
- it "returns nil for a nonexistent value" do
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 "returns a stored string value" do
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 "treats integers as strings" do
17
+ it 'treats integers as strings' do
18
18
  @redises.set(@key, 100)
19
- @redises.get(@key).should == "100"
19
+ @redises.get(@key).should == '100'
20
20
  end
21
21
 
22
- it_should_behave_like "a string-only command"
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 "#getbit(key, offset)" do
3
+ describe '#getbit(key, offset)' do
4
4
  before do
5
5
  @key = 'mock-redis-test:getbit'
6
- @redises.set(@key, 'h') # ASCII 0x68
6
+ @redises.set(@key, 'h') # ASCII 0x68
7
7
  end
8
8
 
9
- it "gets the bits from the key" do
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 "returns 0 for out-of-range bits" do
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 "does not modify the stored value for out-of-range bits" do
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 "treats nonexistent keys as empty strings" do
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 "a string-only command"
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 "#getrange(key, start, stop)" do
3
+ describe '#getrange(key, start, stop)' do
4
4
  before do
5
5
  @key = 'mock-redis-test:getrange'
6
- @redises.set(@key, "This is a string")
6
+ @redises.set(@key, 'This is a string')
7
7
  end
8
8
 
9
- it "returns a substring" do
10
- @redises.getrange(@key, 0, 3).should == "This"
9
+ it 'returns a substring' do
10
+ @redises.getrange(@key, 0, 3).should == 'This'
11
11
  end
12
12
 
13
- it "works with negative indices" do
14
- @redises.getrange(@key, -3, -1).should == "ing"
13
+ it 'works with negative indices' do
14
+ @redises.getrange(@key, -3, -1).should == 'ing'
15
15
  end
16
16
 
17
- it "limits the result to the actual length of the string" do
18
- @redises.getrange(@key, 10, 100).should == "string"
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 "a string-only command"
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 "#getrange(key, value)" do
3
+ describe '#getrange(key, value)' do
4
4
  before do
5
5
  @key = 'mock-redis-test:getset'
6
- @redises.set(@key, "oldvalue")
6
+ @redises.set(@key, 'oldvalue')
7
7
  end
8
8
 
9
- it "returns the old value" do
10
- @redises.getset(@key, 'newvalue').should == "oldvalue"
9
+ it 'returns the old value' do
10
+ @redises.getset(@key, 'newvalue').should == 'oldvalue'
11
11
  end
12
12
 
13
- it "sets the value to the new value" do
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 "returns nil for nonexistent keys" do
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 "a string-only command"
22
+ it_should_behave_like 'a string-only command'
23
23
  end
@@ -1,47 +1,77 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "#hdel(key, field)" do
3
+ describe '#hdel(key, field)' do
4
4
  before do
5
- @key = "mock-redis-test:hdel"
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 "returns 1 when it removes a field" do
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 "returns 0 when it does not remove a field" do
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 "actually removes the field" do
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 "treats the field as a string" do
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 "removes only the field specified" do
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 "cleans up empty hashes" do
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 "supports a variable number of arguments" do
42
- @redises.hdel(@key, ['k1', 'k2'])
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
- it_should_behave_like "a hash-only command"
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