redis 2.0.0 → 2.2.1

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 (81) hide show
  1. data/.gitignore +8 -0
  2. data/CHANGELOG.md +49 -0
  3. data/README.md +208 -0
  4. data/Rakefile +183 -73
  5. data/TODO.md +4 -0
  6. data/benchmarking/logging.rb +62 -0
  7. data/benchmarking/pipeline.rb +51 -0
  8. data/benchmarking/speed.rb +21 -0
  9. data/benchmarking/suite.rb +24 -0
  10. data/benchmarking/thread_safety.rb +38 -0
  11. data/benchmarking/worker.rb +71 -0
  12. data/examples/basic.rb +15 -0
  13. data/examples/dist_redis.rb +43 -0
  14. data/examples/incr-decr.rb +17 -0
  15. data/examples/list.rb +26 -0
  16. data/examples/pubsub.rb +31 -0
  17. data/examples/sets.rb +36 -0
  18. data/examples/unicorn/config.ru +3 -0
  19. data/examples/unicorn/unicorn.rb +20 -0
  20. data/lib/redis/client.rb +149 -165
  21. data/lib/redis/connection/command_helper.rb +45 -0
  22. data/lib/redis/connection/hiredis.rb +49 -0
  23. data/lib/redis/connection/registry.rb +12 -0
  24. data/lib/redis/connection/ruby.rb +135 -0
  25. data/lib/redis/connection/synchrony.rb +129 -0
  26. data/lib/redis/connection.rb +9 -0
  27. data/lib/redis/distributed.rb +182 -7
  28. data/lib/redis/pipeline.rb +22 -1
  29. data/lib/redis/subscribe.rb +19 -4
  30. data/lib/redis/version.rb +3 -0
  31. data/lib/redis.rb +715 -155
  32. data/redis.gemspec +24 -0
  33. data/test/commands_on_hashes_test.rb +32 -0
  34. data/test/commands_on_lists_test.rb +60 -0
  35. data/test/commands_on_sets_test.rb +78 -0
  36. data/test/commands_on_sorted_sets_test.rb +109 -0
  37. data/test/commands_on_strings_test.rb +80 -0
  38. data/test/commands_on_value_types_test.rb +88 -0
  39. data/test/connection_handling_test.rb +88 -0
  40. data/test/db/.gitignore +1 -0
  41. data/test/distributed_blocking_commands_test.rb +53 -0
  42. data/test/distributed_commands_on_hashes_test.rb +12 -0
  43. data/test/distributed_commands_on_lists_test.rb +24 -0
  44. data/test/distributed_commands_on_sets_test.rb +85 -0
  45. data/test/distributed_commands_on_strings_test.rb +50 -0
  46. data/test/distributed_commands_on_value_types_test.rb +73 -0
  47. data/test/distributed_commands_requiring_clustering_test.rb +148 -0
  48. data/test/distributed_connection_handling_test.rb +25 -0
  49. data/test/distributed_internals_test.rb +27 -0
  50. data/test/distributed_key_tags_test.rb +53 -0
  51. data/test/distributed_persistence_control_commands_test.rb +24 -0
  52. data/test/distributed_publish_subscribe_test.rb +101 -0
  53. data/test/distributed_remote_server_control_commands_test.rb +43 -0
  54. data/test/distributed_sorting_test.rb +21 -0
  55. data/test/distributed_test.rb +59 -0
  56. data/test/distributed_transactions_test.rb +34 -0
  57. data/test/encoding_test.rb +16 -0
  58. data/test/error_replies_test.rb +53 -0
  59. data/test/helper.rb +145 -0
  60. data/test/internals_test.rb +160 -0
  61. data/test/lint/hashes.rb +114 -0
  62. data/test/lint/internals.rb +37 -0
  63. data/test/lint/lists.rb +93 -0
  64. data/test/lint/sets.rb +66 -0
  65. data/test/lint/sorted_sets.rb +167 -0
  66. data/test/lint/strings.rb +137 -0
  67. data/test/lint/value_types.rb +84 -0
  68. data/test/persistence_control_commands_test.rb +22 -0
  69. data/test/pipelining_commands_test.rb +123 -0
  70. data/test/publish_subscribe_test.rb +158 -0
  71. data/test/redis_mock.rb +80 -0
  72. data/test/remote_server_control_commands_test.rb +82 -0
  73. data/test/sorting_test.rb +44 -0
  74. data/test/synchrony_driver.rb +57 -0
  75. data/test/test.conf +8 -0
  76. data/test/thread_safety_test.rb +30 -0
  77. data/test/transactions_test.rb +100 -0
  78. data/test/unknown_commands_test.rb +14 -0
  79. data/test/url_param_test.rb +60 -0
  80. metadata +130 -22
  81. data/README.markdown +0 -120
data/test/lint/sets.rb ADDED
@@ -0,0 +1,66 @@
1
+ test "SADD" do |r|
2
+ r.sadd "foo", "s1"
3
+ r.sadd "foo", "s2"
4
+
5
+ assert ["s1", "s2"] == r.smembers("foo").sort
6
+ end
7
+
8
+ test "SREM" do |r|
9
+ r.sadd "foo", "s1"
10
+ r.sadd "foo", "s2"
11
+
12
+ r.srem("foo", "s1")
13
+
14
+ assert ["s2"] == r.smembers("foo")
15
+ end
16
+
17
+ test "SPOP" do |r|
18
+ r.sadd "foo", "s1"
19
+ r.sadd "foo", "s2"
20
+
21
+ assert ["s1", "s2"].include?(r.spop("foo"))
22
+ assert ["s1", "s2"].include?(r.spop("foo"))
23
+ assert nil == r.spop("foo")
24
+ end
25
+
26
+ test "SCARD" do |r|
27
+ assert 0 == r.scard("foo")
28
+
29
+ r.sadd "foo", "s1"
30
+
31
+ assert 1 == r.scard("foo")
32
+
33
+ r.sadd "foo", "s2"
34
+
35
+ assert 2 == r.scard("foo")
36
+ end
37
+
38
+ test "SISMEMBER" do |r|
39
+ assert false == r.sismember("foo", "s1")
40
+
41
+ r.sadd "foo", "s1"
42
+
43
+ assert true == r.sismember("foo", "s1")
44
+ assert false == r.sismember("foo", "s2")
45
+ end
46
+
47
+ test "SMEMBERS" do |r|
48
+ assert [] == r.smembers("foo")
49
+
50
+ r.sadd "foo", "s1"
51
+ r.sadd "foo", "s2"
52
+
53
+ assert ["s1", "s2"] == r.smembers("foo").sort
54
+ end
55
+
56
+ test "SRANDMEMBER" do |r|
57
+ r.sadd "foo", "s1"
58
+ r.sadd "foo", "s2"
59
+
60
+ 4.times do
61
+ assert ["s1", "s2"].include?(r.srandmember("foo"))
62
+ end
63
+
64
+ assert 2 == r.scard("foo")
65
+ end
66
+
@@ -0,0 +1,167 @@
1
+ test "ZADD" do |r|
2
+ assert 0 == r.zcard("foo")
3
+
4
+ r.zadd "foo", 1, "s1"
5
+
6
+ assert 1 == r.zcard("foo")
7
+ end
8
+
9
+ test "ZREM" do |r|
10
+ r.zadd "foo", 1, "s1"
11
+
12
+ assert 1 == r.zcard("foo")
13
+
14
+ r.zadd "foo", 2, "s2"
15
+
16
+ assert 2 == r.zcard("foo")
17
+
18
+ r.zrem "foo", "s1"
19
+
20
+ assert 1 == r.zcard("foo")
21
+ end
22
+
23
+ test "ZINCRBY" do |r|
24
+ r.zincrby "foo", 1, "s1"
25
+
26
+ assert "1" == r.zscore("foo", "s1")
27
+
28
+ r.zincrby "foo", 10, "s1"
29
+
30
+ assert "11" == r.zscore("foo", "s1")
31
+ end
32
+
33
+ test "ZRANK" do |r|
34
+ r.zadd "foo", 1, "s1"
35
+ r.zadd "foo", 2, "s2"
36
+ r.zadd "foo", 3, "s3"
37
+
38
+ assert 2 == r.zrank("foo", "s3")
39
+ end
40
+
41
+ test "ZREVRANK" do |r|
42
+ r.zadd "foo", 1, "s1"
43
+ r.zadd "foo", 2, "s2"
44
+ r.zadd "foo", 3, "s3"
45
+
46
+ assert 0 == r.zrevrank("foo", "s3")
47
+ end
48
+
49
+ test "ZRANGE" do |r|
50
+ r.zadd "foo", 1, "s1"
51
+ r.zadd "foo", 2, "s2"
52
+ r.zadd "foo", 3, "s3"
53
+
54
+ assert ["s1", "s2"] == r.zrange("foo", 0, 1)
55
+ assert ["s1", "1", "s2", "2"] == r.zrange("foo", 0, 1, :with_scores => true)
56
+ assert ["s1", "1", "s2", "2"] == r.zrange("foo", 0, 1, :withscores => true)
57
+ end
58
+
59
+ test "ZREVRANGE" do |r|
60
+ r.zadd "foo", 1, "s1"
61
+ r.zadd "foo", 2, "s2"
62
+ r.zadd "foo", 3, "s3"
63
+
64
+ assert ["s3", "s2"] == r.zrevrange("foo", 0, 1)
65
+ assert ["s3", "3", "s2", "2"] == r.zrevrange("foo", 0, 1, :with_scores => true)
66
+ assert ["s3", "3", "s2", "2"] == r.zrevrange("foo", 0, 1, :withscores => true)
67
+ end
68
+
69
+ test "ZRANGEBYSCORE" do |r|
70
+ r.zadd "foo", 1, "s1"
71
+ r.zadd "foo", 2, "s2"
72
+ r.zadd "foo", 3, "s3"
73
+
74
+ assert ["s2", "s3"] == r.zrangebyscore("foo", 2, 3)
75
+ end
76
+
77
+ test "ZREVRANGEBYSCORE" do |r|
78
+ r.zadd "foo", 1, "s1"
79
+ r.zadd "foo", 2, "s2"
80
+ r.zadd "foo", 3, "s3"
81
+
82
+ assert ["s3", "s2"] == r.zrevrangebyscore("foo", 3, 2)
83
+ end
84
+
85
+ test "ZRANGEBYSCORE with LIMIT" do |r|
86
+ r.zadd "foo", 1, "s1"
87
+ r.zadd "foo", 2, "s2"
88
+ r.zadd "foo", 3, "s3"
89
+ r.zadd "foo", 4, "s4"
90
+
91
+ assert ["s2"] == r.zrangebyscore("foo", 2, 4, :limit => [0, 1])
92
+ assert ["s3"] == r.zrangebyscore("foo", 2, 4, :limit => [1, 1])
93
+ assert ["s3", "s4"] == r.zrangebyscore("foo", 2, 4, :limit => [1, 2])
94
+ end
95
+
96
+ test "ZREVRANGEBYSCORE with LIMIT" do |r|
97
+ r.zadd "foo", 1, "s1"
98
+ r.zadd "foo", 2, "s2"
99
+ r.zadd "foo", 3, "s3"
100
+ r.zadd "foo", 4, "s4"
101
+
102
+ assert ["s4"] == r.zrevrangebyscore("foo", 4, 2, :limit => [0, 1])
103
+ assert ["s3"] == r.zrevrangebyscore("foo", 4, 2, :limit => [1, 1])
104
+ assert ["s3", "s2"] == r.zrevrangebyscore("foo", 4, 2, :limit => [1, 2])
105
+ end
106
+
107
+ test "ZRANGEBYSCORE with WITHSCORES" do |r|
108
+ r.zadd "foo", 1, "s1"
109
+ r.zadd "foo", 2, "s2"
110
+ r.zadd "foo", 3, "s3"
111
+ r.zadd "foo", 4, "s4"
112
+
113
+ assert ["s2", "2"] == r.zrangebyscore("foo", 2, 4, :limit => [0, 1], :with_scores => true)
114
+ assert ["s3", "3"] == r.zrangebyscore("foo", 2, 4, :limit => [1, 1], :with_scores => true)
115
+ assert ["s2", "2"] == r.zrangebyscore("foo", 2, 4, :limit => [0, 1], :withscores => true)
116
+ assert ["s3", "3"] == r.zrangebyscore("foo", 2, 4, :limit => [1, 1], :withscores => true)
117
+ end
118
+
119
+ test "ZREVRANGEBYSCORE with WITHSCORES" do |r|
120
+ r.zadd "foo", 1, "s1"
121
+ r.zadd "foo", 2, "s2"
122
+ r.zadd "foo", 3, "s3"
123
+ r.zadd "foo", 4, "s4"
124
+
125
+ assert ["s4", "4"] == r.zrevrangebyscore("foo", 4, 2, :limit => [0, 1], :with_scores => true)
126
+ assert ["s3", "3"] == r.zrevrangebyscore("foo", 4, 2, :limit => [1, 1], :with_scores => true)
127
+ assert ["s4", "4"] == r.zrevrangebyscore("foo", 4, 2, :limit => [0, 1], :withscores => true)
128
+ assert ["s3", "3"] == r.zrevrangebyscore("foo", 4, 2, :limit => [1, 1], :withscores => true)
129
+ end
130
+
131
+ test "ZCARD" do |r|
132
+ assert 0 == r.zcard("foo")
133
+
134
+ r.zadd "foo", 1, "s1"
135
+
136
+ assert 1 == r.zcard("foo")
137
+ end
138
+
139
+ test "ZSCORE" do |r|
140
+ r.zadd "foo", 1, "s1"
141
+
142
+ assert "1" == r.zscore("foo", "s1")
143
+
144
+ assert nil == r.zscore("foo", "s2")
145
+ assert nil == r.zscore("bar", "s1")
146
+ end
147
+
148
+ test "ZREMRANGEBYRANK" do |r|
149
+ r.zadd "foo", 10, "s1"
150
+ r.zadd "foo", 20, "s2"
151
+ r.zadd "foo", 30, "s3"
152
+ r.zadd "foo", 40, "s4"
153
+
154
+ assert 3 == r.zremrangebyrank("foo", 1, 3)
155
+ assert ["s1"] == r.zrange("foo", 0, -1)
156
+ end
157
+
158
+ test "ZREMRANGEBYSCORE" do |r|
159
+ r.zadd "foo", 1, "s1"
160
+ r.zadd "foo", 2, "s2"
161
+ r.zadd "foo", 3, "s3"
162
+ r.zadd "foo", 4, "s4"
163
+
164
+ assert 3 == r.zremrangebyscore("foo", 2, 4)
165
+ assert ["s1"] == r.zrange("foo", 0, -1)
166
+ end
167
+
@@ -0,0 +1,137 @@
1
+ test "SET and GET" do |r|
2
+ r.set("foo", "s1")
3
+
4
+ assert "s1" == r.get("foo")
5
+ end
6
+
7
+ test "SET and GET with brackets" do |r|
8
+ r["foo"] = "s1"
9
+
10
+ assert "s1" == r["foo"]
11
+ end
12
+
13
+ test "SET and GET with brackets and symbol" do |r|
14
+ r[:foo] = "s1"
15
+
16
+ assert "s1" == r[:foo]
17
+ end
18
+
19
+ test "SET and GET with newline characters" do |r|
20
+ r.set("foo", "1\n")
21
+
22
+ assert "1\n" == r.get("foo")
23
+ end
24
+
25
+ test "SET and GET with ASCII characters" do |r|
26
+ with_external_encoding("ASCII-8BIT") do
27
+ (0..255).each do |i|
28
+ str = "#{i.chr}---#{i.chr}"
29
+ r.set("foo", str)
30
+
31
+ assert str == r.get("foo")
32
+ end
33
+ end
34
+ end if defined?(Encoding)
35
+
36
+ test "SETEX" do |r|
37
+ r.setex("foo", 1, "s1")
38
+
39
+ assert "s1" == r.get("foo")
40
+
41
+ sleep 2
42
+
43
+ assert nil == r.get("foo")
44
+ end
45
+
46
+ test "GETSET" do |r|
47
+ r.set("foo", "bar")
48
+
49
+ assert "bar" == r.getset("foo", "baz")
50
+ assert "baz" == r.get("foo")
51
+ end
52
+
53
+ test "SETNX" do |r|
54
+ r.set("foo", "s1")
55
+
56
+ assert "s1" == r.get("foo")
57
+
58
+ r.setnx("foo", "s2")
59
+
60
+ assert "s1" == r.get("foo")
61
+ end
62
+
63
+ test "INCR" do |r|
64
+ assert 1 == r.incr("foo")
65
+ assert 2 == r.incr("foo")
66
+ assert 3 == r.incr("foo")
67
+ end
68
+
69
+ test "INCRBY" do |r|
70
+ assert 1 == r.incrby("foo", 1)
71
+ assert 3 == r.incrby("foo", 2)
72
+ assert 6 == r.incrby("foo", 3)
73
+ end
74
+
75
+ test "DECR" do |r|
76
+ r.set("foo", 3)
77
+
78
+ assert 2 == r.decr("foo")
79
+ assert 1 == r.decr("foo")
80
+ assert 0 == r.decr("foo")
81
+ end
82
+
83
+ test "DECRBY" do |r|
84
+ r.set("foo", 6)
85
+
86
+ assert 3 == r.decrby("foo", 3)
87
+ assert 1 == r.decrby("foo", 2)
88
+ assert 0 == r.decrby("foo", 1)
89
+ end
90
+
91
+ test "APPEND" do |r|
92
+ r.set "foo", "s"
93
+ r.append "foo", "1"
94
+
95
+ assert "s1" == r.get("foo")
96
+ end
97
+
98
+ test "SUBSTR" do |r|
99
+ r.set "foo", "lorem"
100
+
101
+ assert "ore" == r.substr("foo", 1, 3)
102
+ end
103
+
104
+ test "GETBIT" do |r|
105
+ r.set("foo", "a")
106
+
107
+ assert_equal 1, r.getbit("foo", 1)
108
+ assert_equal 1, r.getbit("foo", 2)
109
+ assert_equal 0, r.getbit("foo", 3)
110
+ assert_equal 0, r.getbit("foo", 4)
111
+ assert_equal 0, r.getbit("foo", 5)
112
+ assert_equal 0, r.getbit("foo", 6)
113
+ assert_equal 1, r.getbit("foo", 7)
114
+ end
115
+
116
+ test "SETBIT" do |r|
117
+ r.set("foo", "a")
118
+
119
+ r.setbit("foo", 6, 1)
120
+
121
+ assert_equal "c", r.get("foo")
122
+ end
123
+
124
+ test "GETRANGE" do |r|
125
+ r.set("foo", "abcde")
126
+
127
+ assert_equal "bcd", r.getrange("foo", 1, 3)
128
+ assert_equal "abcde", r.getrange("foo", 0, -1)
129
+ end
130
+
131
+ test "SETRANGE" do |r|
132
+ r.set("foo", "abcde")
133
+
134
+ r.setrange("foo", 1, "bar")
135
+
136
+ assert_equal "abare", r.get("foo")
137
+ end
@@ -0,0 +1,84 @@
1
+ test "EXISTS" do |r|
2
+ assert false == r.exists("foo")
3
+
4
+ r.set("foo", "s1")
5
+
6
+ assert true == r.exists("foo")
7
+ end
8
+
9
+ test "TYPE" do |r|
10
+ assert "none" == r.type("foo")
11
+
12
+ r.set("foo", "s1")
13
+
14
+ assert "string" == r.type("foo")
15
+ end
16
+
17
+ test "KEYS" do |r|
18
+ r.set("f", "s1")
19
+ r.set("fo", "s2")
20
+ r.set("foo", "s3")
21
+
22
+ assert ["f","fo", "foo"] == r.keys("f*").sort
23
+ end
24
+
25
+ test "EXPIRE" do |r|
26
+ r.set("foo", "s1")
27
+ r.expire("foo", 1)
28
+
29
+ assert "s1" == r.get("foo")
30
+
31
+ sleep 2
32
+
33
+ assert nil == r.get("foo")
34
+ end
35
+
36
+ test "EXPIREAT" do |r|
37
+ r.set("foo", "s1")
38
+ r.expireat("foo", Time.now.to_i + 1)
39
+
40
+ assert "s1" == r.get("foo")
41
+
42
+ sleep 2
43
+
44
+ assert nil == r.get("foo")
45
+ end
46
+
47
+ test "PERSIST" do |r|
48
+ r.set("foo", "s1")
49
+ r.expire("foo", 1)
50
+ r.persist("foo")
51
+
52
+ assert(-1 == r.ttl("foo"))
53
+ end
54
+
55
+ test "TTL" do |r|
56
+ r.set("foo", "s1")
57
+ r.expire("foo", 1)
58
+
59
+ assert 1 == r.ttl("foo")
60
+ end
61
+
62
+ test "MOVE" do |r|
63
+ r.select 14
64
+ r.flushdb
65
+
66
+ r.set "bar", "s3"
67
+
68
+ r.select 15
69
+
70
+ r.set "foo", "s1"
71
+ r.set "bar", "s2"
72
+
73
+ assert r.move("foo", 14)
74
+ assert nil == r.get("foo")
75
+
76
+ assert !r.move("bar", 14)
77
+ assert "s2" == r.get("bar")
78
+
79
+ r.select 14
80
+
81
+ assert "s1" == r.get("foo")
82
+ assert "s3" == r.get("bar")
83
+ end
84
+
@@ -0,0 +1,22 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("./helper", File.dirname(__FILE__))
4
+
5
+ setup do
6
+ init Redis.new(OPTIONS)
7
+ end
8
+
9
+ test "SAVE and BGSAVE" do |r|
10
+ assert_nothing_raised do
11
+ r.save
12
+ end
13
+
14
+ assert_nothing_raised do
15
+ r.bgsave
16
+ end
17
+ end
18
+
19
+ test "LASTSAVE" do |r|
20
+ assert Time.at(r.lastsave) <= Time.now
21
+ end
22
+
@@ -0,0 +1,123 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("./helper", File.dirname(__FILE__))
4
+
5
+ setup do
6
+ init Redis.new(OPTIONS)
7
+ end
8
+
9
+ test "BULK commands" do |r|
10
+ r.pipelined do
11
+ r.lpush "foo", "s1"
12
+ r.lpush "foo", "s2"
13
+ end
14
+
15
+ assert 2 == r.llen("foo")
16
+ assert "s2" == r.lpop("foo")
17
+ assert "s1" == r.lpop("foo")
18
+ end
19
+
20
+ test "MULTI_BULK commands" do |r|
21
+ r.pipelined do
22
+ r.mset("foo", "s1", "bar", "s2")
23
+ r.mset("baz", "s3", "qux", "s4")
24
+ end
25
+
26
+ assert "s1" == r.get("foo")
27
+ assert "s2" == r.get("bar")
28
+ assert "s3" == r.get("baz")
29
+ assert "s4" == r.get("qux")
30
+ end
31
+
32
+ test "BULK and MULTI_BULK commands mixed" do |r|
33
+ r.pipelined do
34
+ r.lpush "foo", "s1"
35
+ r.lpush "foo", "s2"
36
+ r.mset("baz", "s3", "qux", "s4")
37
+ end
38
+
39
+ assert 2 == r.llen("foo")
40
+ assert "s2" == r.lpop("foo")
41
+ assert "s1" == r.lpop("foo")
42
+ assert "s3" == r.get("baz")
43
+ assert "s4" == r.get("qux")
44
+ end
45
+
46
+ test "MULTI_BULK and BULK commands mixed" do |r|
47
+ r.pipelined do
48
+ r.mset("baz", "s3", "qux", "s4")
49
+ r.lpush "foo", "s1"
50
+ r.lpush "foo", "s2"
51
+ end
52
+
53
+ assert 2 == r.llen("foo")
54
+ assert "s2" == r.lpop("foo")
55
+ assert "s1" == r.lpop("foo")
56
+ assert "s3" == r.get("baz")
57
+ assert "s4" == r.get("qux")
58
+ end
59
+
60
+ test "Pipelined with an empty block" do |r|
61
+ assert_nothing_raised do
62
+ r.pipelined do
63
+ end
64
+ end
65
+
66
+ assert 0 == r.dbsize
67
+ end
68
+
69
+ test "Returning the result of a pipeline" do |r|
70
+ result = r.pipelined do
71
+ r.set "foo", "bar"
72
+ r.get "foo"
73
+ r.get "bar"
74
+ end
75
+
76
+ assert ["OK", "bar", nil] == result
77
+ end
78
+
79
+ test "Nesting pipeline blocks" do |r|
80
+ r.pipelined do
81
+ r.set("foo", "s1")
82
+ r.pipelined do
83
+ r.set("bar", "s2")
84
+ end
85
+ end
86
+
87
+ assert "s1" == r.get("foo")
88
+ assert "s2" == r.get("bar")
89
+ end
90
+
91
+ test "INFO in a pipeline" do |r|
92
+ result = r.pipelined do
93
+ r.info
94
+ end
95
+
96
+ assert result.first.kind_of?(String)
97
+ end
98
+
99
+ test "CONFIG GET in a pipeline" do |r|
100
+ result = r.pipelined do
101
+ r.config(:get, "*")
102
+ end
103
+
104
+ assert result.first.kind_of?(Array)
105
+ end
106
+
107
+ test "HGETALL in a pipeline should not return hash" do |r|
108
+ r.hmset("hash", "field", "value")
109
+ result = r.pipelined do
110
+ r.hgetall("hash")
111
+ end
112
+
113
+ assert ["field", "value"] == result.first
114
+ end
115
+
116
+ test "KEYS in a pipeline" do |r|
117
+ r.set("key", "value")
118
+ result = r.pipelined do
119
+ r.keys("*")
120
+ end
121
+
122
+ assert ["key"] == result.first
123
+ end