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,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "#zrevrange(key, start, stop [, :with_scores => true])" do
3
+ describe '#zrevrange(key, start, stop [, :with_scores => true])' do
4
4
  before do
5
5
  @key = 'mock-redis-test:zrevrange'
6
6
  @redises.zadd(@key, 1, 'Washington')
@@ -9,23 +9,48 @@ describe "#zrevrange(key, start, stop [, :with_scores => true])" do
9
9
  @redises.zadd(@key, 4, 'Madison')
10
10
  end
11
11
 
12
- it "returns the elements in order by score" do
13
- @redises.zrevrange(@key, 0, 1).should == ['Madison', 'Jefferson']
12
+ context 'when the zset is empty' do
13
+ before do
14
+ @redises.del(@key)
15
+ end
16
+
17
+ it 'should return an empty array' do
18
+ @redises.exists?(@key).should == false
19
+ @redises.zrevrange(@key, 0, 4).should == []
20
+ end
21
+ end
22
+
23
+ it 'returns the elements in order by score' do
24
+ @redises.zrevrange(@key, 0, 1).should == %w[Madison Jefferson]
25
+ end
26
+
27
+ context 'when a subset of elements have the same score' do
28
+ before do
29
+ @redises.zadd(@key, 1, 'Martha')
30
+ end
31
+
32
+ it 'returns the elements in descending lexicographical order' do
33
+ @redises.zrevrange(@key, 3, 4).should == %w[Washington Martha]
34
+ end
35
+ end
36
+
37
+ it 'returns the elements in order by score (negative indices)' do
38
+ @redises.zrevrange(@key, -2, -1).should == %w[Adams Washington]
14
39
  end
15
40
 
16
- it "returns the elements in order by score (negative indices)" do
17
- @redises.zrevrange(@key, -2, -1).should == ['Adams', 'Washington']
41
+ it 'returns empty list when start is too large' do
42
+ @redises.zrevrange(@key, 5, -1).should == []
18
43
  end
19
44
 
20
- it "returns the scores when :with_scores is specified" do
45
+ it 'returns the scores when :with_scores is specified' do
21
46
  @redises.zrevrange(@key, 2, 3, :with_scores => true).
22
- should == [["Adams", 2.0], ["Washington", 1.0]]
47
+ should == [['Adams', 2.0], ['Washington', 1.0]]
23
48
  end
24
49
 
25
- it "returns the scores when :withscores is specified" do
50
+ it 'returns the scores when :withscores is specified' do
26
51
  @redises.zrevrange(@key, 2, 3, :withscores => true).
27
- should == [["Adams", 2.0], ["Washington", 1.0]]
52
+ should == [['Adams', 2.0], ['Washington', 1.0]]
28
53
  end
29
54
 
30
- it_should_behave_like "a zset-only command"
55
+ it_should_behave_like 'a zset-only command'
31
56
  end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "#zrevrangebyscore(key, start, stop [:with_scores => true] [:limit => [offset count]])" do
3
+ describe '#zrevrangebyscore(key, start, stop [:with_scores => true] [:limit => [offset count]])' do
4
4
  before do
5
5
  @key = 'mock-redis-test:zrevrangebyscore'
6
6
  @redises.zadd(@key, 1, 'Washington')
@@ -9,39 +9,50 @@ describe "#zrevrangebyscore(key, start, stop [:with_scores => true] [:limit => [
9
9
  @redises.zadd(@key, 4, 'Madison')
10
10
  end
11
11
 
12
- it "returns the elements in order by score" do
13
- @redises.zrevrangebyscore(@key, 4, 3).should == ['Madison', 'Jefferson']
12
+ context 'when the zset is empty' do
13
+ before do
14
+ @redises.del(@key)
15
+ end
16
+
17
+ it 'should return an empty array' do
18
+ @redises.exists?(@key).should == false
19
+ @redises.zrevrangebyscore(@key, 0, 4).should == []
20
+ end
21
+ end
22
+
23
+ it 'returns the elements in order by score' do
24
+ @redises.zrevrangebyscore(@key, 4, 3).should == %w[Madison Jefferson]
14
25
  end
15
26
 
16
- it "returns the scores when :with_scores is specified" do
27
+ it 'returns the scores when :with_scores is specified' do
17
28
  @redises.zrevrangebyscore(@key, 4, 3, :with_scores => true).
18
- should == [["Madison", 4.0], ["Jefferson", 3.0]]
29
+ should == [['Madison', 4.0], ['Jefferson', 3.0]]
19
30
  end
20
31
 
21
- it "returns the scores when :withscores is specified" do
32
+ it 'returns the scores when :withscores is specified' do
22
33
  @redises.zrevrangebyscore(@key, 4, 3, :withscores => true).
23
- should == [["Madison", 4.0], ["Jefferson", 3.0]]
34
+ should == [['Madison', 4.0], ['Jefferson', 3.0]]
24
35
  end
25
36
 
26
- it "treats +inf as positive infinity" do
27
- @redises.zrevrangebyscore(@key, "+inf", 3).
37
+ it 'treats +inf as positive infinity' do
38
+ @redises.zrevrangebyscore(@key, '+inf', 3).
28
39
  should == %w[Madison Jefferson]
29
40
  end
30
41
 
31
- it "honors the :limit => [offset count] argument" do
42
+ it 'honors the :limit => [offset count] argument' do
32
43
  @redises.zrevrangebyscore(@key, 100, -100, :limit => [1, 2]).
33
- should == ["Jefferson", "Adams"]
44
+ should == %w[Jefferson Adams]
34
45
  end
35
46
 
36
47
  it "raises an error if :limit isn't a 2-tuple" do
37
48
  lambda do
38
49
  @redises.zrevrangebyscore(@key, 100, -100, :limit => [1, 2, 3])
39
- end.should raise_error(RuntimeError)
50
+ end.should raise_error(Redis::CommandError)
40
51
 
41
52
  lambda do
42
- @redises.zrevrangebyscore(@key, 100, -100, :limit => "1, 2")
43
- end.should raise_error
53
+ @redises.zrevrangebyscore(@key, 100, -100, :limit => '1, 2')
54
+ end.should raise_error(RedisMultiplexer::MismatchedResponse)
44
55
  end
45
56
 
46
- it_should_behave_like "a zset-only command"
57
+ it_should_behave_like 'a zset-only command'
47
58
  end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "#zrevrank(key, member)" do
3
+ describe '#zrevrank(key, member)' do
4
4
  before do
5
5
  @key = 'mock-redis-test:zrevrank'
6
6
 
@@ -13,17 +13,17 @@ describe "#zrevrank(key, member)" do
13
13
  @redises.zrevrank(@key, 'foo').should be_nil
14
14
  end
15
15
 
16
- it "returns the index of the member in the set (ordered by -score)" do
16
+ it 'returns the index of the member in the set (ordered by -score)' do
17
17
  @redises.zrevrank(@key, 'one').should == 2
18
18
  @redises.zrevrank(@key, 'two').should == 1
19
19
  @redises.zrevrank(@key, 'three').should == 0
20
20
  end
21
21
 
22
- it "handles integer members correctly" do
22
+ it 'handles integer members correctly' do
23
23
  member = 11
24
24
  @redises.zadd(@key, 4, member)
25
25
  @redises.zrevrank(@key, member).should == 0
26
26
  end
27
27
 
28
- it_should_behave_like "a zset-only command"
28
+ it_should_behave_like 'a zset-only command'
29
29
  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
@@ -1,22 +1,22 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "#zscore(key, member)" do
3
+ describe '#zscore(key, member)' do
4
4
  before { @key = 'mock-redis-test:zscore' }
5
5
 
6
- it "returns the score as a string" do
7
- @redises.zadd(@key, 0.25, 'foo').should be_true
6
+ it 'returns the score as a string' do
7
+ @redises.zadd(@key, 0.25, 'foo').should == true
8
8
  @redises.zscore(@key, 'foo').should == 0.25
9
9
  end
10
10
 
11
- it "handles integer members correctly" do
11
+ it 'handles integer members correctly' do
12
12
  member = 11
13
- @redises.zadd(@key, 0.25, member).should be_true
13
+ @redises.zadd(@key, 0.25, member).should == true
14
14
  @redises.zscore(@key, member).should == 0.25
15
15
  end
16
16
 
17
- it "returns nil if member is not present in the set" do
17
+ it 'returns nil if member is not present in the set' do
18
18
  @redises.zscore(@key, 'foo').should be_nil
19
19
  end
20
20
 
21
- it_should_behave_like "a zset-only command"
21
+ it_should_behave_like 'a zset-only command'
22
22
  end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "#zunionstore(destination, keys, [:weights => [w,w,], [:aggregate => :sum|:min|:max])" do
3
+ describe '#zunionstore(destination, keys, [:weights => [w,w,], [:aggregate => :sum|:min|:max])' do
4
4
  before do
5
5
  @set1 = 'mock-redis-test:zunionstore1'
6
6
  @set2 = 'mock-redis-test:zunionstore2'
@@ -17,45 +17,78 @@ describe "#zunionstore(destination, keys, [:weights => [w,w,], [:aggregate => :s
17
17
  @redises.zadd(@set3, 3, 'three')
18
18
  end
19
19
 
20
- it "returns the number of elements in the new set" do
20
+ it 'returns the number of elements in the new set' do
21
21
  @redises.zunionstore(@dest, [@set1, @set2, @set3]).should == 3
22
22
  end
23
23
 
24
24
  it "sums the members' scores by default" do
25
25
  @redises.zunionstore(@dest, [@set1, @set2, @set3])
26
26
  @redises.zrange(@dest, 0, -1, :with_scores => true).should ==
27
- [["one", 3.0], ["three", 3.0], ["two", 4.0]]
27
+ [['one', 3.0], ['three', 3.0], ['two', 4.0]]
28
28
  end
29
29
 
30
- it "removes existing elements in destination" do
30
+ it 'removes existing elements in destination' do
31
31
  @redises.zadd(@dest, 10, 'ten')
32
32
 
33
33
  @redises.zunionstore(@dest, [@set1])
34
34
  @redises.zrange(@dest, 0, -1, :with_scores => true).should ==
35
- [["one", 1.0]]
35
+ [['one', 1.0]]
36
36
  end
37
37
 
38
- it "raises an error if keys is empty" do
38
+ it 'raises an error if keys is empty' do
39
39
  lambda do
40
40
  @redises.zunionstore(@dest, [])
41
- end.should raise_error(RuntimeError)
41
+ end.should raise_error(Redis::CommandError)
42
42
  end
43
43
 
44
- context "the :weights argument" do
45
- it "multiplies the scores by the weights while aggregating" do
44
+ context 'when used with a set' do
45
+ before do
46
+ @set4 = 'mock-redis-test:zunionstore4'
47
+
48
+ @redises.sadd(@set4, 'two')
49
+ @redises.sadd(@set4, 'three')
50
+ @redises.sadd(@set4, 'four')
51
+ end
52
+
53
+ it 'returns the number of elements in the new set' do
54
+ @redises.zunionstore(@dest, [@set3, @set4]).should == 4
55
+ end
56
+
57
+ it 'sums the scores, substituting 1.0 for set values' do
58
+ @redises.zunionstore(@dest, [@set3, @set4])
59
+ @redises.zrange(@dest, 0, -1, :with_scores => true).should ==
60
+ [['four', 1.0], ['one', 1.0], ['two', 3.0], ['three', 4.0]]
61
+ end
62
+ end
63
+
64
+ context 'when used with a non-coercible structure' do
65
+ before do
66
+ @non_set = 'mock-redis-test:zunionstore4'
67
+
68
+ @redises.set(@non_set, 'one')
69
+ end
70
+ it 'raises an error for wrong value type' do
71
+ lambda do
72
+ @redises.zunionstore(@dest, [@set1, @non_set])
73
+ end.should raise_error(Redis::CommandError)
74
+ end
75
+ end
76
+
77
+ context 'the :weights argument' do
78
+ it 'multiplies the scores by the weights while aggregating' do
46
79
  @redises.zunionstore(@dest, [@set1, @set2, @set3], :weights => [2, 3, 5])
47
80
  @redises.zrange(@dest, 0, -1, :with_scores => true).should ==
48
- [["one", 10.0], ["three", 15.0], ["two", 16.0]]
81
+ [['one', 10.0], ['three', 15.0], ['two', 16.0]]
49
82
  end
50
83
 
51
- it "raises an error if the number of weights != the number of keys" do
84
+ it 'raises an error if the number of weights != the number of keys' do
52
85
  lambda do
53
- @redises.zunionstore(@dest, [@set1, @set2, @set3], :weights => [1,2])
54
- end.should raise_error(RuntimeError)
86
+ @redises.zunionstore(@dest, [@set1, @set2, @set3], :weights => [1, 2])
87
+ end.should raise_error(Redis::CommandError)
55
88
  end
56
89
  end
57
90
 
58
- context "the :aggregate argument" do
91
+ context 'the :aggregate argument' do
59
92
  before do
60
93
  @smalls = 'mock-redis-test:zunionstore:smalls'
61
94
  @bigs = 'mock-redis-test:zunionstore:bigs'
@@ -66,19 +99,19 @@ describe "#zunionstore(destination, keys, [:weights => [w,w,], [:aggregate => :s
66
99
  @redises.zadd(@bigs, 200, 'ernie')
67
100
  end
68
101
 
69
- it "aggregates scores with min when :aggregate => :min is specified" do
102
+ it 'aggregates scores with min when :aggregate => :min is specified' do
70
103
  @redises.zunionstore(@dest, [@bigs, @smalls], :aggregate => :min)
71
104
  @redises.zrange(@dest, 0, -1, :with_scores => true).should ==
72
- [["bert", 1.0], ["ernie", 2.0]]
105
+ [['bert', 1.0], ['ernie', 2.0]]
73
106
  end
74
107
 
75
- it "aggregates scores with max when :aggregate => :max is specified" do
108
+ it 'aggregates scores with max when :aggregate => :max is specified' do
76
109
  @redises.zunionstore(@dest, [@bigs, @smalls], :aggregate => :max)
77
110
  @redises.zrange(@dest, 0, -1, :with_scores => true).should ==
78
- [["bert", 100.0], ["ernie", 200.0]]
111
+ [['bert', 100.0], ['ernie', 200.0]]
79
112
  end
80
113
 
81
- it "ignores scores for missing members" do
114
+ it 'ignores scores for missing members' do
82
115
  @redises.zadd(@smalls, 3, 'grover')
83
116
  @redises.zunionstore(@dest, [@bigs, @smalls], :aggregate => :min)
84
117
  @redises.zscore(@dest, 'grover').should == 3.0
@@ -95,10 +128,10 @@ describe "#zunionstore(destination, keys, [:weights => [w,w,], [:aggregate => :s
95
128
  @redises.zscore(@dest, 'bert').should == 1.0
96
129
  end
97
130
 
98
- it "raises an error for unknown aggregation function" do
131
+ it 'raises an error for unknown aggregation function' do
99
132
  lambda do
100
133
  @redises.zunionstore(@dest, [@bigs, @smalls], :aggregate => :mix)
101
- end.should raise_error(RuntimeError)
134
+ end.should raise_error(Redis::CommandError)
102
135
  end
103
136
  end
104
137
  end
@@ -29,4 +29,65 @@ describe MockRedis do
29
29
 
30
30
  its(:id) { should == url }
31
31
  end
32
+
33
+ describe 'Injecting a time class' do
34
+ describe '.options' do
35
+ let(:time_stub) { double 'Time' }
36
+ let(:options) { { :time_class => time_stub } }
37
+
38
+ it 'defaults to Time' do
39
+ mock_redis = MockRedis.new
40
+
41
+ mock_redis.options[:time_class].should == Time
42
+ end
43
+
44
+ it 'has a configurable Time class' do
45
+ mock_redis = MockRedis.new(options)
46
+
47
+ mock_redis.options[:time_class].should == time_stub
48
+ end
49
+ end
50
+
51
+ describe '.now' do
52
+ let(:time_stub) { double 'Time', :now => Time.new(2019, 1, 2, 3, 4, 6, '+00:00') }
53
+ let(:options) { { :time_class => time_stub } }
54
+
55
+ subject { MockRedis.new(options) }
56
+
57
+ its(:now) { should == [1_546_398_246, 0] }
58
+ end
59
+
60
+ describe '.time' do
61
+ let(:time_stub) { double 'Time', :now => Time.new(2019, 1, 2, 3, 4, 6, '+00:00') }
62
+ let(:options) { { :time_class => time_stub } }
63
+
64
+ subject { MockRedis.new(options) }
65
+
66
+ its(:time) { should == [1_546_398_246, 0] }
67
+ end
68
+
69
+ describe '.expireat' do
70
+ let(:time_at) { 'expireat' }
71
+ let(:time_stub) { double 'Time' }
72
+ let(:options) { { :time_class => time_stub } }
73
+ let(:timestamp) { 123_456 }
74
+
75
+ subject { MockRedis.new(options) }
76
+
77
+ it 'Forwards time_at to the time_class' do
78
+ time_stub.should_receive(:at).with(timestamp).and_return(time_at)
79
+
80
+ subject.time_at(timestamp).should == time_at
81
+ end
82
+ end
83
+ end
84
+
85
+ describe 'supplying a logger' do
86
+ it 'logs redis commands' do
87
+ logger = double('Logger', debug?: true, debug: nil)
88
+ mock_redis = MockRedis.new(logger: logger)
89
+ expect(logger).to receive(:debug).with(/command=HMGET args="hash" "key1" "key2"/)
90
+ mock_redis.hmget('hash', 'key1', 'key2')
91
+ end
92
+ end
32
93
  end
data/spec/spec_helper.rb CHANGED
@@ -1,24 +1,42 @@
1
- require 'rspec'
1
+ require 'simplecov'
2
+ SimpleCov.start do
3
+ add_filter 'spec/'
4
+
5
+ if ENV['CI']
6
+ require 'simplecov-lcov'
7
+
8
+ SimpleCov::Formatter::LcovFormatter.config do |c|
9
+ c.report_with_single_file = true
10
+ c.single_report_path = 'coverage/lcov.info'
11
+ end
12
+
13
+ formatter SimpleCov::Formatter::LcovFormatter
14
+ end
15
+ end
16
+
17
+ require 'rspec/its'
2
18
  require 'redis'
3
- $LOAD_PATH.unshift(File.expand_path(File.join(__FILE__, "..", "..", "lib")))
19
+ $LOAD_PATH.unshift(File.expand_path(File.join(__FILE__, '..', '..', 'lib')))
4
20
  require 'mock_redis'
21
+ require 'timecop'
5
22
 
6
23
  $LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..')))
7
- Dir["spec/support/**/*.rb"].each {|x| require x}
24
+ Dir['spec/support/**/*.rb'].sort.each { |x| require x }
8
25
 
9
26
  module TypeCheckingHelper
10
- def method_from_description
27
+ def method_from_description(example)
11
28
  # extracting this from the RSpec description string may or may not
12
29
  # be a good idea. On the one hand, it enforces the convention of
13
30
  # putting the method name in the right place; on the other hand,
14
31
  # it's pretty magic-looking.
15
- self.example.full_description.match(/#(\w+)/).captures.first
32
+ example.full_description.match(/#(\w+)/).captures.first
16
33
  end
17
34
 
18
35
  def args_for_method(method)
36
+ return [] if %w[spop zpopmin zpopmax].include?(method.to_s)
19
37
  method_arity = @redises.real.method(method).arity
20
- if method_arity < 0 # -1 comes from def foo(*args)
21
- [1, 2] # probably good enough
38
+ if method_arity < 0 # -1 comes from def foo(*args)
39
+ [1, 2] # probably good enough
22
40
  else
23
41
  1.upto(method_arity - 1).to_a
24
42
  end
@@ -26,6 +44,14 @@ module TypeCheckingHelper
26
44
  end
27
45
 
28
46
  RSpec.configure do |config|
47
+ config.expect_with :rspec do |c|
48
+ c.syntax = [:expect, :should]
49
+ end
50
+
51
+ config.mock_with :rspec do |c|
52
+ c.syntax = [:expect, :should]
53
+ end
54
+
29
55
  config.include(TypeCheckingHelper)
30
56
 
31
57
  config.before(:all) do
@@ -36,9 +62,10 @@ RSpec.configure do |config|
36
62
  # databases mentioned in our tests
37
63
  [1, 0].each do |db|
38
64
  @redises.send_without_checking(:select, db)
39
- @redises.send_without_checking(:keys, "mock-redis-test:*").each do |key|
65
+ @redises.send_without_checking(:keys, 'mock-redis-test:*').each do |key|
40
66
  @redises.send_without_checking(:del, key)
41
67
  end
42
68
  end
69
+ @redises._gsub_clear
43
70
  end
44
71
  end