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,5 +1,7 @@
1
1
  class BlankSlate
2
- instance_methods.each {|m| undef_method(m) unless m =~ /^__/ || ['inspect', 'object_id'].include?(m.to_s)}
2
+ instance_methods.each do |m|
3
+ undef_method(m) unless m =~ /^__/ || %w[inspect object_id].include?(m.to_s)
4
+ end
3
5
  end
4
6
 
5
7
  class RedisMultiplexer < BlankSlate
@@ -7,54 +9,69 @@ class RedisMultiplexer < BlankSlate
7
9
 
8
10
  def initialize(*a)
9
11
  @mock_redis = MockRedis.new(*a)
12
+ Redis.exists_returns_integer = true
10
13
  @real_redis = Redis.new(*a)
14
+ _gsub_clear
11
15
  end
12
16
 
13
- def method_missing(method, *args, &blk)
14
- # if we're in a Redis command that accepts a block, and we execute more redis commands, ONLY execute them
15
- # on the Redis implementation that the block came from.
16
- # e.g. if a pipelined command is started on a MockRedis object, DON'T send commands inside the pipelined block
17
- # to the real Redis object, as that one WON'T be inside a pipelined command, and we'll see weird behaviour
18
- if blk
19
- @in_mock_block = true
20
- @in_redis_block = false
21
- end
22
- mock_retval, mock_error = catch_errors { @in_redis_block ? :no_op : @mock_redis.send(method, *args, &blk) }
17
+ def _gsub(from, to)
18
+ @gsub_from = from
19
+ @gsub_to = to
20
+ end
21
+
22
+ def _gsub_clear
23
+ @gsub_from = @gsub_to = ''
24
+ end
23
25
 
26
+ ruby2_keywords def method_missing(method, *args, &blk)
27
+ # If we're in a Redis command that accepts a block, and we execute more
28
+ # redis commands, ONLY execute them on the Redis implementation that the
29
+ # block came from.
30
+ # e.g. if a pipelined command is started on a MockRedis object, DON'T send
31
+ # commands inside the pipelined block to the real Redis object, as that one
32
+ # WON'T be inside a pipelined command, and we'll see weird behaviour
24
33
  if blk
25
34
  @in_mock_block = false
26
35
  @in_redis_block = true
27
36
  end
28
- real_retval, real_error = catch_errors { @in_mock_block ? :no_op : @real_redis.send(method, *args, &blk) }
37
+ real_retval, real_error =
38
+ catch_errors { @in_mock_block ? :no_op : @real_redis.send(method, *args, &blk) }
39
+
40
+ if blk
41
+ @in_mock_block = true
42
+ @in_redis_block = false
43
+ end
44
+ mock_retval, mock_error =
45
+ catch_errors { @in_redis_block ? :no_op : @mock_redis.send(method, *args, &blk) }
29
46
 
30
47
  if blk
31
48
  @in_mock_block = false
32
49
  @in_redis_block = false
33
50
  end
34
51
 
35
- if (mock_retval == :no_op || real_retval == :no_op)
36
- # ignore, we were inside a block (like pipelined)
37
- elsif (!equalish?(mock_retval, real_retval) && !mock_error && !real_error)
52
+ if mock_retval == :no_op || real_retval == :no_op
53
+ # ignore, we were inside a block (like pipelined)
54
+ elsif !equalish?(mock_retval, real_retval) && !mock_error && !real_error
38
55
  # no exceptions, just different behavior
39
56
  raise MismatchedResponse,
40
- "Mock failure: responses not equal.\n" +
41
- "Redis.#{method}(#{args.inspect}) returned #{real_retval.inspect}\n" +
57
+ "Mock failure: responses not equal.\n" \
58
+ "Redis.#{method}(#{args.inspect}) returned #{real_retval.inspect}\n" \
42
59
  "MockRedis.#{method}(#{args.inspect}) returned #{mock_retval.inspect}\n"
43
- elsif (!mock_error && real_error)
60
+ elsif !mock_error && real_error
44
61
  raise MismatchedResponse,
45
- "Mock failure: didn't raise an error when it should have.\n" +
46
- "Redis.#{method}(#{args.inspect}) raised #{real_error.inspect}\n" +
47
- "MockRedis.#{method}(#{args.inspect}) raised nothing " +
62
+ "Mock failure: didn't raise an error when it should have.\n" \
63
+ "Redis.#{method}(#{args.inspect}) raised #{real_error.inspect}\n" \
64
+ "MockRedis.#{method}(#{args.inspect}) raised nothing " \
48
65
  "and returned #{mock_retval.inspect}"
49
- elsif (!real_error && mock_error)
66
+ elsif !real_error && mock_error
50
67
  raise MismatchedResponse,
51
- "Mock failure: raised an error when it shouldn't have.\n" +
52
- "Redis.#{method}(#{args.inspect}) returned #{real_retval.inspect}\n" +
68
+ "Mock failure: raised an error when it shouldn't have.\n" \
69
+ "Redis.#{method}(#{args.inspect}) returned #{real_retval.inspect}\n" \
53
70
  "MockRedis.#{method}(#{args.inspect}) raised #{mock_error.inspect}"
54
- elsif (mock_error && real_error && !equalish?(mock_error, real_error))
71
+ elsif mock_error && real_error && !equalish?(mock_error, real_error)
55
72
  raise MismatchedResponse,
56
- "Mock failure: raised the wrong error.\n" +
57
- "Redis.#{method}(#{args.inspect}) raised #{real_error.inspect}\n" +
73
+ "Mock failure: raised the wrong error.\n" \
74
+ "Redis.#{method}(#{args.inspect}) raised #{real_error.inspect}\n" \
58
75
  "MockRedis.#{method}(#{args.inspect}) raised #{mock_error.inspect}"
59
76
  end
60
77
 
@@ -65,8 +82,10 @@ class RedisMultiplexer < BlankSlate
65
82
  def equalish?(a, b)
66
83
  if a == b
67
84
  true
85
+ elsif a.is_a?(String) && b.is_a?(String)
86
+ masked(a) == masked(b)
68
87
  elsif a.is_a?(Array) && b.is_a?(Array)
69
- a.collect(&:to_s).sort == b.collect(&:to_s).sort
88
+ a.collect { |c| masked(c.to_s) }.sort == b.collect { |c| masked(c.to_s) }.sort
70
89
  elsif a.is_a?(Exception) && b.is_a?(Exception)
71
90
  a.class == b.class && a.message == b.message
72
91
  elsif a.is_a?(Float) && b.is_a?(Float)
@@ -77,8 +96,17 @@ class RedisMultiplexer < BlankSlate
77
96
  end
78
97
  end
79
98
 
80
- def mock() @mock_redis end
81
- def real() @real_redis end
99
+ def masked(str)
100
+ str.gsub(@gsub_from, @gsub_to)
101
+ end
102
+
103
+ def mock
104
+ @mock_redis
105
+ end
106
+
107
+ def real
108
+ @real_redis
109
+ end
82
110
 
83
111
  # Used in cleanup before() blocks.
84
112
  def send_without_checking(method, *args)
@@ -87,12 +115,9 @@ class RedisMultiplexer < BlankSlate
87
115
  end
88
116
 
89
117
  def catch_errors
90
- begin
91
- retval = yield
92
- [retval, nil]
93
- rescue StandardError => e
94
- [nil, e]
95
- end
118
+ retval = yield
119
+ [retval, nil]
120
+ rescue StandardError => e
121
+ [nil, e]
96
122
  end
97
123
  end
98
-
@@ -0,0 +1,14 @@
1
+ shared_examples_for 'does not remove empty strings on error' do
2
+ it 'does not remove empty strings on error' do |example|
3
+ key = 'mock-redis-test:not-a-string'
4
+
5
+ method = method_from_description(example)
6
+ args = args_for_method(method).unshift(key)
7
+
8
+ @redises.set(key, '')
9
+ lambda do
10
+ @redises.send(method, *args)
11
+ end.should raise_error(RuntimeError)
12
+ @redises.get(key).should == ''
13
+ end
14
+ end
@@ -1,8 +1,8 @@
1
- shared_examples_for "a hash-only command" do
2
- it "raises an error for non-hash values" do
1
+ shared_examples_for 'a hash-only command' do
2
+ it 'raises an error for non-hash values' do |example|
3
3
  key = 'mock-redis-test:hash-only'
4
4
 
5
- method = method_from_description
5
+ method = method_from_description(example)
6
6
  args = args_for_method(method).unshift(key)
7
7
 
8
8
  @redises.set(key, 1)
@@ -10,4 +10,6 @@ shared_examples_for "a hash-only command" do
10
10
  @redises.send(method, *args)
11
11
  end.should raise_error(RuntimeError)
12
12
  end
13
+
14
+ it_should_behave_like 'does not remove empty strings on error'
13
15
  end
@@ -1,8 +1,8 @@
1
- shared_examples_for "a list-only command" do
2
- it "raises an error for non-list values" do
1
+ shared_examples_for 'a list-only command' do
2
+ it 'raises an error for non-list values' do |example|
3
3
  key = 'mock-redis-test:list-only'
4
4
 
5
- method = method_from_description
5
+ method = method_from_description(example)
6
6
  args = args_for_method(method).unshift(key)
7
7
 
8
8
  @redises.set(key, 1)
@@ -10,4 +10,6 @@ shared_examples_for "a list-only command" do
10
10
  @redises.send(method, *args)
11
11
  end.should raise_error(RuntimeError)
12
12
  end
13
+
14
+ it_should_behave_like 'does not remove empty strings on error'
13
15
  end
@@ -1,8 +1,8 @@
1
- shared_examples_for "a set-only command" do
2
- it "raises an error for non-set values" do
1
+ shared_examples_for 'a set-only command' do
2
+ it 'raises an error for non-set values' do |example|
3
3
  key = 'mock-redis-test:set-only'
4
4
 
5
- method = method_from_description
5
+ method = method_from_description(example)
6
6
  args = args_for_method(method).unshift(key)
7
7
 
8
8
  @redises.set(key, 1)
@@ -10,4 +10,6 @@ shared_examples_for "a set-only command" do
10
10
  @redises.send(method, *args)
11
11
  end.should raise_error(RuntimeError)
12
12
  end
13
+
14
+ it_should_behave_like 'does not remove empty strings on error'
13
15
  end
@@ -1,8 +1,8 @@
1
- shared_examples_for "a string-only command" do
2
- it "raises an error for non-string values" do
3
- key = "mock-redis-test:string-only-command"
1
+ shared_examples_for 'a string-only command' do
2
+ it 'raises an error for non-string values' do |example|
3
+ key = 'mock-redis-test:string-only-command'
4
4
 
5
- method = method_from_description
5
+ method = method_from_description(example)
6
6
  args = args_for_method(method).unshift(key)
7
7
 
8
8
  @redises.lpush(key, 1)
@@ -1,8 +1,8 @@
1
- shared_examples_for "a zset-only command" do
2
- it "raises an error for non-zset values" do
1
+ shared_examples_for 'a zset-only command' do
2
+ it 'raises an error for non-zset values' do |example|
3
3
  key = 'mock-redis-test:zset-only'
4
4
 
5
- method = method_from_description
5
+ method = method_from_description(example)
6
6
  args = args_for_method(method).unshift(key)
7
7
 
8
8
  @redises.set(key, 1)
@@ -10,47 +10,49 @@ shared_examples_for "a zset-only command" do
10
10
  @redises.send(method, *args)
11
11
  end.should raise_error(RuntimeError)
12
12
  end
13
+
14
+ it_should_behave_like 'does not remove empty strings on error'
13
15
  end
14
16
 
15
- shared_examples_for "arg 1 is a score" do
17
+ shared_examples_for 'arg 1 is a score' do
16
18
  before { @_arg_index = 1 }
17
- it_should_behave_like "arg N is a score"
19
+ it_should_behave_like 'arg N is a score'
18
20
  end
19
21
 
20
- shared_examples_for "arg 2 is a score" do
22
+ shared_examples_for 'arg 2 is a score' do
21
23
  before { @_arg_index = 2 }
22
- it_should_behave_like "arg N is a score"
24
+ it_should_behave_like 'arg N is a score'
23
25
  end
24
26
 
25
- shared_examples_for "arg N is a score" do
26
- before do
27
+ shared_examples_for 'arg N is a score' do
28
+ before do |example|
27
29
  key = 'mock-redis-test:zset-only'
28
30
 
29
- @method = method_from_description
31
+ @method = method_from_description(example)
30
32
  @args = args_for_method(@method).unshift(key)
31
33
  end
32
34
 
33
- it "is okay with positive ints" do
35
+ it 'is okay with positive ints' do
34
36
  @args[@_arg_index] = 1
35
37
  lambda { @redises.send(@method, *@args) }.should_not raise_error
36
38
  end
37
39
 
38
- it "is okay with negative ints" do
40
+ it 'is okay with negative ints' do
39
41
  @args[@_arg_index] = -1
40
42
  lambda { @redises.send(@method, *@args) }.should_not raise_error
41
43
  end
42
44
 
43
- it "is okay with positive floats" do
45
+ it 'is okay with positive floats' do
44
46
  @args[@_arg_index] = 1.5
45
47
  lambda { @redises.send(@method, *@args) }.should_not raise_error
46
48
  end
47
49
 
48
- it "is okay with negative floats" do
49
- @args[@_arg_index] = 1.5
50
+ it 'is okay with negative floats' do
51
+ @args[@_arg_index] = -1.5
50
52
  lambda { @redises.send(@method, *@args) }.should_not raise_error
51
53
  end
52
54
 
53
- it "rejects non-numbers" do
55
+ it 'rejects non-numbers' do
54
56
  @args[@_arg_index] = 'foo'
55
57
  lambda { @redises.send(@method, *@args) }.should raise_error(RuntimeError)
56
58
  end
@@ -0,0 +1,56 @@
1
+ shared_examples_for 'a sortable' do
2
+ it 'returns empty array on nil' do
3
+ @redises.sort(nil).should == []
4
+ end
5
+
6
+ context 'ordering' do
7
+ it 'orders ascending by default' do
8
+ @redises.sort(@key).should == %w[1 2]
9
+ end
10
+
11
+ it 'orders by descending when specified' do
12
+ @redises.sort(@key, :order => 'DESC').should == %w[2 1]
13
+ end
14
+ end
15
+
16
+ context 'projections' do
17
+ it 'projects element when :get is "#"' do
18
+ @redises.sort(@key, :get => '#').should == %w[1 2]
19
+ end
20
+
21
+ it 'projects through a key pattern' do
22
+ @redises.sort(@key, :get => 'mock-redis-test:values_*').should == %w[a b]
23
+ end
24
+
25
+ it 'projects through a key pattern and reflects element' do
26
+ @redises.sort(@key, :get => ['#', 'mock-redis-test:values_*']).should == [%w[1 a], %w[2 b]]
27
+ end
28
+
29
+ it 'projects through a hash key pattern' do
30
+ @redises.sort(@key, :get => 'mock-redis-test:hash_*->key').should == %w[x y]
31
+ end
32
+ end
33
+
34
+ context 'weights' do
35
+ it 'weights by projecting through a key pattern' do
36
+ @redises.sort(@key, :by => 'mock-redis-test:weight_*').should == %w[2 1]
37
+ end
38
+
39
+ it 'weights by projecting through a key pattern and a specific order' do
40
+ @redises.sort(@key, :order => 'DESC', :by => 'mock-redis-test:weight_*').should == %w[1 2]
41
+ end
42
+ end
43
+
44
+ context 'limit' do
45
+ it 'only returns requested window in the enumerable' do
46
+ @redises.sort(@key, :limit => [0, 1]).should == ['1']
47
+ end
48
+ end
49
+
50
+ context 'store' do
51
+ it 'stores into another key' do
52
+ @redises.sort(@key, :store => 'mock-redis-test:some_bucket').should == 2
53
+ @redises.lrange('mock-redis-test:some_bucket', 0, -1).should == %w[1 2]
54
+ end
55
+ end
56
+ end
@@ -5,21 +5,21 @@ describe 'transactions (multi/exec/discard)' do
5
5
  @redises.discard rescue nil
6
6
  end
7
7
 
8
- context "#multi" do
8
+ context '#multi' do
9
9
  it "responds with 'OK'" do
10
10
  @redises.multi.should == 'OK'
11
11
  end
12
12
 
13
- it "forbids nesting" do
13
+ it 'does not permit nesting' do
14
14
  @redises.multi
15
15
  lambda do
16
16
  @redises.multi
17
- end.should raise_error(RuntimeError)
17
+ end.should raise_error(Redis::CommandError, 'ERR MULTI calls can not be nested')
18
18
  end
19
19
 
20
- it "cleanup the state of tansaction wrapper if an exception occurs while a transaction is being processed" do
20
+ it 'cleans state of transaction wrapper if exception occurs during transaction' do
21
21
  lambda do
22
- @redises.mock.multi do |r|
22
+ @redises.mock.multi do |_r|
23
23
  raise "i'm a command that fails"
24
24
  end
25
25
  end.should raise_error(RuntimeError)
@@ -28,58 +28,85 @@ describe 'transactions (multi/exec/discard)' do
28
28
  lambda do
29
29
  @redises.mock.multi do |r|
30
30
  # do stuff that succeed
31
- s.set(nil, 'string')
31
+ r.set(nil, 'string')
32
32
  end
33
- end.should_not raise_error(RuntimeError)
34
-
33
+ end.should_not raise_error
35
34
  end
36
35
  end
37
36
 
38
- context "#blocks" do
39
- it "implicitly runs exec when finished" do
40
- @redises.set("counter", 5)
37
+ context '#blocks' do
38
+ it 'implicitly runs exec when finished' do
39
+ @redises.set('counter', 5)
41
40
  @redises.multi do |r|
42
- r.set("test", 1)
43
- r.incr("counter")
41
+ r.set('test', 1)
42
+ r.incr('counter')
44
43
  end
45
- @redises.get("counter").should == "6"
46
- @redises.get("test").should == "1"
44
+ @redises.get('counter').should eq '6'
45
+ @redises.get('test').should eq '1'
47
46
  end
48
47
 
49
- it "forbids nesting via blocks" do
48
+ it 'permits nesting via blocks' do
50
49
  # Have to use only the mock here. redis-rb has a bug in it where
51
50
  # nested #multi calls raise NoMethodError because it gets a nil
52
51
  # where it's not expecting one.
53
52
  @redises.mock.multi do |r|
54
53
  lambda do
55
54
  r.multi {}
56
- end.should raise_error(RuntimeError)
55
+ end.should_not raise_error
56
+ end
57
+ end
58
+
59
+ it 'allows pipelined calls within multi blocks' do
60
+ @redises.set('counter', 5)
61
+ @redises.multi do |r|
62
+ r.pipelined do |pr|
63
+ pr.set('test', 1)
64
+ pr.incr('counter')
65
+ end
57
66
  end
67
+ @redises.get('counter').should eq '6'
68
+ @redises.get('test').should eq '1'
69
+ end
70
+
71
+ it 'allows blocks within multi blocks' do
72
+ @redises.set('foo', 'bar')
73
+ @redises.set('fuu', 'baz')
74
+
75
+ result = nil
76
+
77
+ @redises.multi do |r|
78
+ result = r.mget('foo', 'fuu') { |reply| reply.map(&:upcase) }
79
+ r.del('foo', 'fuu')
80
+ end
81
+
82
+ result.value.should eq %w[BAR BAZ]
83
+ @redises.get('foo').should eq nil
84
+ @redises.get('fuu').should eq nil
58
85
  end
59
86
  end
60
87
 
61
- context "#discard" do
88
+ context '#discard' do
62
89
  it "responds with 'OK' after #multi" do
63
90
  @redises.multi
64
- @redises.discard.should == 'OK'
91
+ @redises.discard.should eq 'OK'
65
92
  end
66
93
 
67
94
  it "can't be run outside of #multi/#exec" do
68
95
  lambda do
69
96
  @redises.discard
70
- end.should raise_error(RuntimeError)
97
+ end.should raise_error(Redis::CommandError)
71
98
  end
72
99
  end
73
100
 
74
- context "#exec" do
75
- it "raises an error outside of #multi" do
101
+ context '#exec' do
102
+ it 'raises an error outside of #multi' do
76
103
  lambda do
77
104
  @redises.exec.should raise_error
78
105
  end
79
106
  end
80
107
  end
81
108
 
82
- context "saving up commands for later" do
109
+ context 'saving up commands for later' do
83
110
  before(:each) do
84
111
  @redises.multi
85
112
  @string = 'mock-redis-test:string'
@@ -87,8 +114,8 @@ describe 'transactions (multi/exec/discard)' do
87
114
  end
88
115
 
89
116
  it "makes commands respond with 'QUEUED'" do
90
- @redises.set(@string, 'string').should == 'QUEUED'
91
- @redises.lpush(@list, 'list').should == 'QUEUED'
117
+ @redises.set(@string, 'string').should eq 'QUEUED'
118
+ @redises.lpush(@list, 'list').should eq 'QUEUED'
92
119
  end
93
120
 
94
121
  it "gives you the commands' responses when you call #exec" do
@@ -96,7 +123,7 @@ describe 'transactions (multi/exec/discard)' do
96
123
  @redises.lpush(@list, 'list')
97
124
  @redises.lpush(@list, 'list')
98
125
 
99
- @redises.exec.should == ['OK', 1, 2]
126
+ @redises.exec.should eq ['OK', 1, 2]
100
127
  end
101
128
 
102
129
  it "does not raise exceptions, but rather puts them in #exec's response" do
@@ -105,9 +132,32 @@ describe 'transactions (multi/exec/discard)' do
105
132
  @redises.lpush(@list, 'list')
106
133
 
107
134
  responses = @redises.exec
108
- responses[0].should == 'OK'
109
- responses[1].should be_a(RuntimeError)
110
- responses[2].should == 1
135
+ responses[0].should eq 'OK'
136
+ responses[1].should be_a(Redis::CommandError)
137
+ responses[2].should eq 1
138
+ end
139
+ end
140
+
141
+ context 'saving commands with multi block' do
142
+ before(:each) do
143
+ @string = 'mock-redis-test:string'
144
+ @list = 'mock-redis-test:list'
145
+ end
146
+
147
+ it 'commands return response after exec is called' do
148
+ set_response = nil
149
+ lpush_response = nil
150
+ second_lpush_response = nil
151
+
152
+ @redises.multi do |mult|
153
+ set_response = mult.set(@string, 'string')
154
+ lpush_response = mult.lpush(@list, 'list')
155
+ second_lpush_response = mult.lpush(@list, 'list')
156
+ end
157
+
158
+ set_response.value.should eq 'OK'
159
+ lpush_response.value.should eq 1
160
+ second_lpush_response.value.should eq 2
111
161
  end
112
162
  end
113
163
  end