redis 3.0.0.rc1 → 3.0.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. data/.travis.yml +50 -0
  2. data/.travis/Gemfile +11 -0
  3. data/CHANGELOG.md +47 -19
  4. data/README.md +160 -149
  5. data/Rakefile +15 -50
  6. data/examples/pubsub.rb +1 -1
  7. data/examples/unicorn/config.ru +1 -1
  8. data/examples/unicorn/unicorn.rb +1 -1
  9. data/lib/redis.rb +790 -390
  10. data/lib/redis/client.rb +137 -49
  11. data/lib/redis/connection/hiredis.rb +26 -15
  12. data/lib/redis/connection/ruby.rb +170 -53
  13. data/lib/redis/connection/synchrony.rb +23 -35
  14. data/lib/redis/distributed.rb +92 -32
  15. data/lib/redis/errors.rb +4 -2
  16. data/lib/redis/pipeline.rb +17 -6
  17. data/lib/redis/version.rb +1 -1
  18. data/redis.gemspec +4 -6
  19. data/test/blocking_commands_test.rb +42 -0
  20. data/test/command_map_test.rb +18 -17
  21. data/test/commands_on_hashes_test.rb +13 -12
  22. data/test/commands_on_lists_test.rb +35 -45
  23. data/test/commands_on_sets_test.rb +55 -54
  24. data/test/commands_on_sorted_sets_test.rb +106 -105
  25. data/test/commands_on_strings_test.rb +64 -55
  26. data/test/commands_on_value_types_test.rb +66 -54
  27. data/test/connection_handling_test.rb +136 -151
  28. data/test/distributed_blocking_commands_test.rb +33 -40
  29. data/test/distributed_commands_on_hashes_test.rb +6 -7
  30. data/test/distributed_commands_on_lists_test.rb +13 -14
  31. data/test/distributed_commands_on_sets_test.rb +57 -58
  32. data/test/distributed_commands_on_sorted_sets_test.rb +11 -12
  33. data/test/distributed_commands_on_strings_test.rb +31 -32
  34. data/test/distributed_commands_on_value_types_test.rb +61 -46
  35. data/test/distributed_commands_requiring_clustering_test.rb +108 -108
  36. data/test/distributed_connection_handling_test.rb +14 -15
  37. data/test/distributed_internals_test.rb +7 -19
  38. data/test/distributed_key_tags_test.rb +36 -36
  39. data/test/distributed_persistence_control_commands_test.rb +17 -14
  40. data/test/distributed_publish_subscribe_test.rb +61 -69
  41. data/test/distributed_remote_server_control_commands_test.rb +39 -28
  42. data/test/distributed_sorting_test.rb +12 -13
  43. data/test/distributed_test.rb +40 -41
  44. data/test/distributed_transactions_test.rb +20 -21
  45. data/test/encoding_test.rb +12 -9
  46. data/test/error_replies_test.rb +42 -36
  47. data/test/helper.rb +118 -85
  48. data/test/helper_test.rb +20 -6
  49. data/test/internals_test.rb +167 -103
  50. data/test/lint/blocking_commands.rb +124 -0
  51. data/test/lint/hashes.rb +115 -93
  52. data/test/lint/lists.rb +86 -80
  53. data/test/lint/sets.rb +68 -62
  54. data/test/lint/sorted_sets.rb +200 -195
  55. data/test/lint/strings.rb +112 -94
  56. data/test/lint/value_types.rb +76 -55
  57. data/test/persistence_control_commands_test.rb +17 -12
  58. data/test/pipelining_commands_test.rb +135 -126
  59. data/test/publish_subscribe_test.rb +105 -110
  60. data/test/remote_server_control_commands_test.rb +74 -58
  61. data/test/sorting_test.rb +31 -29
  62. data/test/support/connection/hiredis.rb +1 -0
  63. data/test/support/connection/ruby.rb +1 -0
  64. data/test/support/connection/synchrony.rb +17 -0
  65. data/test/{redis_mock.rb → support/redis_mock.rb} +24 -21
  66. data/test/support/wire/synchrony.rb +24 -0
  67. data/test/support/wire/thread.rb +5 -0
  68. data/test/synchrony_driver.rb +9 -9
  69. data/test/test.conf +1 -1
  70. data/test/thread_safety_test.rb +21 -19
  71. data/test/transactions_test.rb +189 -118
  72. data/test/unknown_commands_test.rb +9 -8
  73. data/test/url_param_test.rb +46 -41
  74. metadata +28 -43
  75. data/TODO.md +0 -4
  76. data/benchmarking/thread_safety.rb +0 -38
  77. data/test/lint/internals.rb +0 -36
@@ -9,13 +9,14 @@ Gem::Specification.new do |s|
9
9
 
10
10
  s.version = Redis::VERSION
11
11
 
12
- s.homepage = "https://github.com/ezmobius/redis-rb"
12
+ s.homepage = "https://github.com/redis/redis-rb"
13
13
 
14
14
  s.summary = "A Ruby client library for the Redis key-value store."
15
15
 
16
16
  s.description = <<-EOS
17
- A simple Ruby client trying to match Redis' API one-to-one while still providing a Rubystic interface.
18
- It features thread safety, client-side sharding, and an obsession for performance.
17
+ A Ruby client that tries to match Redis' API one-to-one, while still
18
+ providing an idiomatic interface. It features thread-safety,
19
+ client-side sharding, pipelining, and an obsession for performance.
19
20
  EOS
20
21
 
21
22
  s.authors = [
@@ -37,7 +38,4 @@ Gem::Specification.new do |s|
37
38
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
38
39
 
39
40
  s.add_development_dependency("rake")
40
- s.add_development_dependency("cutest")
41
- s.add_development_dependency("hiredis")
42
- s.add_development_dependency("em-synchrony")
43
41
  end
@@ -0,0 +1,42 @@
1
+ # encoding: UTF-8
2
+
3
+ require "helper"
4
+ require "lint/blocking_commands"
5
+
6
+ class TestBlockingCommands < Test::Unit::TestCase
7
+
8
+ include Helper::Client
9
+ include Lint::BlockingCommands
10
+
11
+ def assert_takes_longer_than_client_timeout
12
+ timeout = OPTIONS[:timeout]
13
+ delay = timeout * 2
14
+
15
+ mock(:delay => delay) do |r|
16
+ t1 = Time.now
17
+ yield(r)
18
+ t2 = Time.now
19
+
20
+ assert timeout == r.client.timeout
21
+ assert delay <= (t2 - t1)
22
+ end
23
+ end
24
+
25
+ def test_blpop_disable_client_timeout
26
+ assert_takes_longer_than_client_timeout do |r|
27
+ assert_equal ["foo", "0"], r.blpop("foo")
28
+ end
29
+ end
30
+
31
+ def test_brpop_disable_client_timeout
32
+ assert_takes_longer_than_client_timeout do |r|
33
+ assert_equal ["foo", "0"], r.brpop("foo")
34
+ end
35
+ end
36
+
37
+ def test_brpoplpush_disable_client_timeout
38
+ assert_takes_longer_than_client_timeout do |r|
39
+ assert_equal "0", r.brpoplpush("foo", "bar")
40
+ end
41
+ end
42
+ end
@@ -1,29 +1,30 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require File.expand_path("./helper", File.dirname(__FILE__))
3
+ require "helper"
4
4
 
5
- setup do
6
- init Redis.new(OPTIONS)
7
- end
8
-
9
- test "Override existing commands" do |r|
10
- r.set("counter", 1)
5
+ class TestCommandMap < Test::Unit::TestCase
11
6
 
12
- assert 2 == r.incr("counter")
7
+ include Helper::Client
13
8
 
14
- r.client.command_map[:incr] = :decr
9
+ def test_override_existing_commands
10
+ r.set("counter", 1)
15
11
 
16
- assert 1 == r.incr("counter")
17
- end
12
+ assert_equal 2, r.incr("counter")
18
13
 
19
- test "Override non-existing commands" do |r|
20
- r.set("key", "value")
14
+ r.client.command_map[:incr] = :decr
21
15
 
22
- assert_raise Redis::CommandError do
23
- r.idontexist("key")
16
+ assert_equal 1, r.incr("counter")
24
17
  end
25
18
 
26
- r.client.command_map[:idontexist] = :get
19
+ def test_override_non_existing_commands
20
+ r.set("key", "value")
27
21
 
28
- assert "value" == r.idontexist("key")
22
+ assert_raise Redis::CommandError do
23
+ r.idontexist("key")
24
+ end
25
+
26
+ r.client.command_map[:idontexist] = :get
27
+
28
+ assert_equal "value", r.idontexist("key")
29
+ end
29
30
  end
@@ -1,20 +1,21 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require File.expand_path("./helper", File.dirname(__FILE__))
3
+ require "helper"
4
+ require "lint/hashes"
4
5
 
5
- setup do
6
- init Redis.new(OPTIONS)
7
- end
6
+ class TestCommandsOnHashes < Test::Unit::TestCase
8
7
 
9
- load './test/lint/hashes.rb'
8
+ include Helper::Client
9
+ include Lint::Hashes
10
10
 
11
- test "Mapped HMGET in a pipeline returns hash" do |r|
12
- r.hset("foo", "f1", "s1")
13
- r.hset("foo", "f2", "s2")
11
+ def test_mapped_hmget_in_a_pipeline_returns_hash
12
+ r.hset("foo", "f1", "s1")
13
+ r.hset("foo", "f2", "s2")
14
14
 
15
- result = r.pipelined do
16
- r.mapped_hmget("foo", "f1", "f2")
17
- end
15
+ result = r.pipelined do
16
+ r.mapped_hmget("foo", "f1", "f2")
17
+ end
18
18
 
19
- assert result[0] == { "f1" => "s1", "f2" => "s2" }
19
+ assert_equal result[0], { "f1" => "s1", "f2" => "s2" }
20
+ end
20
21
  end
@@ -1,60 +1,50 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require File.expand_path("./helper", File.dirname(__FILE__))
3
+ require "helper"
4
+ require "lint/lists"
4
5
 
5
- setup do
6
- init Redis.new(OPTIONS)
7
- end
8
-
9
- load './test/lint/lists.rb'
10
-
11
- test "RPUSHX" do |r|
12
- r.rpushx "foo", "s1"
13
- r.rpush "foo", "s2"
14
- r.rpushx "foo", "s3"
6
+ class TestCommandsOnLists < Test::Unit::TestCase
15
7
 
16
- assert 2 == r.llen("foo")
17
- assert ["s2", "s3"] == r.lrange("foo", 0, -1)
18
- end
19
-
20
- test "LPUSHX" do |r|
21
- r.lpushx "foo", "s1"
22
- r.lpush "foo", "s2"
23
- r.lpushx "foo", "s3"
8
+ include Helper::Client
9
+ include Lint::Lists
24
10
 
25
- assert 2 == r.llen("foo")
26
- assert ["s3", "s2"] == r.lrange("foo", 0, -1)
27
- end
11
+ def test_rpushx
12
+ r.rpushx "foo", "s1"
13
+ r.rpush "foo", "s2"
14
+ r.rpushx "foo", "s3"
28
15
 
29
- test "LINSERT" do |r|
30
- r.rpush "foo", "s1"
31
- r.rpush "foo", "s3"
32
- r.linsert "foo", :before, "s3", "s2"
16
+ assert_equal 2, r.llen("foo")
17
+ assert_equal ["s2", "s3"], r.lrange("foo", 0, -1)
18
+ end
33
19
 
34
- assert ["s1", "s2", "s3"] == r.lrange("foo", 0, -1)
20
+ def test_lpushx
21
+ r.lpushx "foo", "s1"
22
+ r.lpush "foo", "s2"
23
+ r.lpushx "foo", "s3"
35
24
 
36
- assert_raise(Redis::CommandError) do
37
- r.linsert "foo", :anywhere, "s3", "s2"
25
+ assert_equal 2, r.llen("foo")
26
+ assert_equal ["s3", "s2"], r.lrange("foo", 0, -1)
38
27
  end
39
- end
40
-
41
- test "RPOPLPUSH" do |r|
42
- r.rpush "foo", "s1"
43
- r.rpush "foo", "s2"
44
28
 
45
- assert "s2" == r.rpoplpush("foo", "bar")
46
- assert ["s2"] == r.lrange("bar", 0, -1)
47
- assert "s1" == r.rpoplpush("foo", "bar")
48
- assert ["s1", "s2"] == r.lrange("bar", 0, -1)
49
- end
29
+ def test_linsert
30
+ r.rpush "foo", "s1"
31
+ r.rpush "foo", "s3"
32
+ r.linsert "foo", :before, "s3", "s2"
50
33
 
51
- test "BRPOPLPUSH" do |r|
52
- r.rpush "foo", "s1"
53
- r.rpush "foo", "s2"
34
+ assert_equal ["s1", "s2", "s3"], r.lrange("foo", 0, -1)
54
35
 
55
- assert_equal "s2", r.brpoplpush("foo", "bar", 1)
36
+ assert_raise(Redis::CommandError) do
37
+ r.linsert "foo", :anywhere, "s3", "s2"
38
+ end
39
+ end
56
40
 
57
- assert_equal nil, r.brpoplpush("baz", "qux", 1)
41
+ def test_rpoplpush
42
+ r.rpush "foo", "s1"
43
+ r.rpush "foo", "s2"
58
44
 
59
- assert_equal ["s2"], r.lrange("bar", 0, -1)
45
+ assert_equal "s2", r.rpoplpush("foo", "bar")
46
+ assert_equal ["s2"], r.lrange("bar", 0, -1)
47
+ assert_equal "s1", r.rpoplpush("foo", "bar")
48
+ assert_equal ["s1", "s2"], r.lrange("bar", 0, -1)
49
+ end
60
50
  end
@@ -1,76 +1,77 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require File.expand_path("./helper", File.dirname(__FILE__))
3
+ require "helper"
4
+ require "lint/sets"
4
5
 
5
- setup do
6
- init Redis.new(OPTIONS)
7
- end
6
+ class TestCommandsOnSets < Test::Unit::TestCase
8
7
 
9
- load './test/lint/sets.rb'
8
+ include Helper::Client
9
+ include Lint::Sets
10
10
 
11
- test "SMOVE" do |r|
12
- r.sadd "foo", "s1"
13
- r.sadd "bar", "s2"
11
+ def test_smove
12
+ r.sadd "foo", "s1"
13
+ r.sadd "bar", "s2"
14
14
 
15
- assert r.smove("foo", "bar", "s1")
16
- assert r.sismember("bar", "s1")
17
- end
15
+ assert r.smove("foo", "bar", "s1")
16
+ assert r.sismember("bar", "s1")
17
+ end
18
18
 
19
- test "SINTER" do |r|
20
- r.sadd "foo", "s1"
21
- r.sadd "foo", "s2"
22
- r.sadd "bar", "s2"
19
+ def test_sinter
20
+ r.sadd "foo", "s1"
21
+ r.sadd "foo", "s2"
22
+ r.sadd "bar", "s2"
23
23
 
24
- assert ["s2"] == r.sinter("foo", "bar")
25
- end
24
+ assert_equal ["s2"], r.sinter("foo", "bar")
25
+ end
26
26
 
27
- test "SINTERSTORE" do |r|
28
- r.sadd "foo", "s1"
29
- r.sadd "foo", "s2"
30
- r.sadd "bar", "s2"
27
+ def test_sinterstore
28
+ r.sadd "foo", "s1"
29
+ r.sadd "foo", "s2"
30
+ r.sadd "bar", "s2"
31
31
 
32
- r.sinterstore("baz", "foo", "bar")
32
+ r.sinterstore("baz", "foo", "bar")
33
33
 
34
- assert ["s2"] == r.smembers("baz")
35
- end
34
+ assert_equal ["s2"], r.smembers("baz")
35
+ end
36
36
 
37
- test "SUNION" do |r|
38
- r.sadd "foo", "s1"
39
- r.sadd "foo", "s2"
40
- r.sadd "bar", "s2"
41
- r.sadd "bar", "s3"
37
+ def test_sunion
38
+ r.sadd "foo", "s1"
39
+ r.sadd "foo", "s2"
40
+ r.sadd "bar", "s2"
41
+ r.sadd "bar", "s3"
42
42
 
43
- assert ["s1", "s2", "s3"] == r.sunion("foo", "bar").sort
44
- end
43
+ assert_equal ["s1", "s2", "s3"], r.sunion("foo", "bar").sort
44
+ end
45
45
 
46
- test "SUNIONSTORE" do |r|
47
- r.sadd "foo", "s1"
48
- r.sadd "foo", "s2"
49
- r.sadd "bar", "s2"
50
- r.sadd "bar", "s3"
46
+ def test_sunionstore
47
+ r.sadd "foo", "s1"
48
+ r.sadd "foo", "s2"
49
+ r.sadd "bar", "s2"
50
+ r.sadd "bar", "s3"
51
51
 
52
- r.sunionstore("baz", "foo", "bar")
52
+ r.sunionstore("baz", "foo", "bar")
53
53
 
54
- assert ["s1", "s2", "s3"] == r.smembers("baz").sort
55
- end
54
+ assert_equal ["s1", "s2", "s3"], r.smembers("baz").sort
55
+ end
56
56
 
57
- test "SDIFF" do |r|
58
- r.sadd "foo", "s1"
59
- r.sadd "foo", "s2"
60
- r.sadd "bar", "s2"
61
- r.sadd "bar", "s3"
57
+ def test_sdiff
58
+ r.sadd "foo", "s1"
59
+ r.sadd "foo", "s2"
60
+ r.sadd "bar", "s2"
61
+ r.sadd "bar", "s3"
62
62
 
63
- assert ["s1"] == r.sdiff("foo", "bar")
64
- assert ["s3"] == r.sdiff("bar", "foo")
65
- end
63
+ assert_equal ["s1"], r.sdiff("foo", "bar")
64
+ assert_equal ["s3"], r.sdiff("bar", "foo")
65
+ end
66
66
 
67
- test "SDIFFSTORE" do |r|
68
- r.sadd "foo", "s1"
69
- r.sadd "foo", "s2"
70
- r.sadd "bar", "s2"
71
- r.sadd "bar", "s3"
67
+ def test_sdiffstore
68
+ r.sadd "foo", "s1"
69
+ r.sadd "foo", "s2"
70
+ r.sadd "bar", "s2"
71
+ r.sadd "bar", "s3"
72
72
 
73
- r.sdiffstore("baz", "foo", "bar")
73
+ r.sdiffstore("baz", "foo", "bar")
74
74
 
75
- assert ["s1"] == r.smembers("baz")
75
+ assert_equal ["s1"], r.smembers("baz")
76
+ end
76
77
  end
@@ -1,108 +1,109 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require File.expand_path("./helper", File.dirname(__FILE__))
4
-
5
- setup do
6
- init Redis.new(OPTIONS)
7
- end
8
-
9
- load './test/lint/sorted_sets.rb'
10
-
11
- test "ZCOUNT" do |r|
12
- r.zadd "foo", 1, "s1"
13
- r.zadd "foo", 2, "s2"
14
- r.zadd "foo", 3, "s3"
15
-
16
- assert 2 == r.zcount("foo", 2, 3)
17
- end
18
-
19
- test "ZUNIONSTORE" do |r|
20
- r.zadd "foo", 1, "s1"
21
- r.zadd "bar", 2, "s2"
22
- r.zadd "foo", 3, "s3"
23
- r.zadd "bar", 4, "s4"
24
-
25
- assert 4 == r.zunionstore("foobar", ["foo", "bar"])
26
- assert ["s1", "s2", "s3", "s4"] == r.zrange("foobar", 0, -1)
27
- end
28
-
29
- test "ZUNIONSTORE with WEIGHTS" do |r|
30
- r.zadd "foo", 1, "s1"
31
- r.zadd "foo", 3, "s3"
32
- r.zadd "bar", 20, "s2"
33
- r.zadd "bar", 40, "s4"
34
-
35
- assert 4 == r.zunionstore("foobar", ["foo", "bar"])
36
- assert ["s1", "s3", "s2", "s4"] == r.zrange("foobar", 0, -1)
37
-
38
- assert 4 == r.zunionstore("foobar", ["foo", "bar"], :weights => [10, 1])
39
- assert ["s1", "s2", "s3", "s4"] == r.zrange("foobar", 0, -1)
40
- end
41
-
42
- test "ZUNIONSTORE with AGGREGATE" do |r|
43
- r.zadd "foo", 1, "s1"
44
- r.zadd "foo", 2, "s2"
45
- r.zadd "bar", 4, "s2"
46
- r.zadd "bar", 3, "s3"
47
-
48
- assert 3 == r.zunionstore("foobar", ["foo", "bar"])
49
- assert ["s1", "s3", "s2"] == r.zrange("foobar", 0, -1)
50
-
51
- assert 3 == r.zunionstore("foobar", ["foo", "bar"], :aggregate => :min)
52
- assert ["s1", "s2", "s3"] == r.zrange("foobar", 0, -1)
53
-
54
- assert 3 == r.zunionstore("foobar", ["foo", "bar"], :aggregate => :max)
55
- assert ["s1", "s3", "s2"] == r.zrange("foobar", 0, -1)
56
- end
57
-
58
- test "ZINTERSTORE" do |r|
59
- r.zadd "foo", 1, "s1"
60
- r.zadd "bar", 2, "s1"
61
- r.zadd "foo", 3, "s3"
62
- r.zadd "bar", 4, "s4"
63
-
64
- assert 1 == r.zinterstore("foobar", ["foo", "bar"])
65
- assert ["s1"] == r.zrange("foobar", 0, -1)
66
- end
67
-
68
- test "ZINTERSTORE with WEIGHTS" do |r|
69
- r.zadd "foo", 1, "s1"
70
- r.zadd "foo", 2, "s2"
71
- r.zadd "foo", 3, "s3"
72
- r.zadd "bar", 20, "s2"
73
- r.zadd "bar", 30, "s3"
74
- r.zadd "bar", 40, "s4"
75
-
76
- assert 2 == r.zinterstore("foobar", ["foo", "bar"])
77
- assert ["s2", "s3"] == r.zrange("foobar", 0, -1)
78
-
79
- assert 2 == r.zinterstore("foobar", ["foo", "bar"], :weights => [10, 1])
80
- assert ["s2", "s3"] == r.zrange("foobar", 0, -1)
81
-
82
- assert 40.0 == r.zscore("foobar", "s2")
83
- assert 60.0 == r.zscore("foobar", "s3")
84
- end
85
-
86
- test "ZINTERSTORE with AGGREGATE" do |r|
87
- r.zadd "foo", 1, "s1"
88
- r.zadd "foo", 2, "s2"
89
- r.zadd "foo", 3, "s3"
90
- r.zadd "bar", 20, "s2"
91
- r.zadd "bar", 30, "s3"
92
- r.zadd "bar", 40, "s4"
93
-
94
- assert 2 == r.zinterstore("foobar", ["foo", "bar"])
95
- assert ["s2", "s3"] == r.zrange("foobar", 0, -1)
96
- assert 22.0 == r.zscore("foobar", "s2")
97
- assert 33.0 == r.zscore("foobar", "s3")
98
-
99
- assert 2 == r.zinterstore("foobar", ["foo", "bar"], :aggregate => :min)
100
- assert ["s2", "s3"] == r.zrange("foobar", 0, -1)
101
- assert 2.0 == r.zscore("foobar", "s2")
102
- assert 3.0 == r.zscore("foobar", "s3")
103
-
104
- assert 2 == r.zinterstore("foobar", ["foo", "bar"], :aggregate => :max)
105
- assert ["s2", "s3"] == r.zrange("foobar", 0, -1)
106
- assert 20.0 == r.zscore("foobar", "s2")
107
- assert 30.0 == r.zscore("foobar", "s3")
3
+ require "helper"
4
+ require "lint/sorted_sets"
5
+
6
+ class TestCommandsOnSortedSets < Test::Unit::TestCase
7
+
8
+ include Helper::Client
9
+ include Lint::SortedSets
10
+
11
+ def test_zcount
12
+ r.zadd "foo", 1, "s1"
13
+ r.zadd "foo", 2, "s2"
14
+ r.zadd "foo", 3, "s3"
15
+
16
+ assert_equal 2, r.zcount("foo", 2, 3)
17
+ end
18
+
19
+ def test_zunionstore
20
+ r.zadd "foo", 1, "s1"
21
+ r.zadd "bar", 2, "s2"
22
+ r.zadd "foo", 3, "s3"
23
+ r.zadd "bar", 4, "s4"
24
+
25
+ assert_equal 4, r.zunionstore("foobar", ["foo", "bar"])
26
+ assert_equal ["s1", "s2", "s3", "s4"], r.zrange("foobar", 0, -1)
27
+ end
28
+
29
+ def test_zunionstore_with_weights
30
+ r.zadd "foo", 1, "s1"
31
+ r.zadd "foo", 3, "s3"
32
+ r.zadd "bar", 20, "s2"
33
+ r.zadd "bar", 40, "s4"
34
+
35
+ assert_equal 4, r.zunionstore("foobar", ["foo", "bar"])
36
+ assert_equal ["s1", "s3", "s2", "s4"], r.zrange("foobar", 0, -1)
37
+
38
+ assert_equal 4, r.zunionstore("foobar", ["foo", "bar"], :weights => [10, 1])
39
+ assert_equal ["s1", "s2", "s3", "s4"], r.zrange("foobar", 0, -1)
40
+ end
41
+
42
+ def test_zunionstore_with_aggregate
43
+ r.zadd "foo", 1, "s1"
44
+ r.zadd "foo", 2, "s2"
45
+ r.zadd "bar", 4, "s2"
46
+ r.zadd "bar", 3, "s3"
47
+
48
+ assert_equal 3, r.zunionstore("foobar", ["foo", "bar"])
49
+ assert_equal ["s1", "s3", "s2"], r.zrange("foobar", 0, -1)
50
+
51
+ assert_equal 3, r.zunionstore("foobar", ["foo", "bar"], :aggregate => :min)
52
+ assert_equal ["s1", "s2", "s3"], r.zrange("foobar", 0, -1)
53
+
54
+ assert_equal 3, r.zunionstore("foobar", ["foo", "bar"], :aggregate => :max)
55
+ assert_equal ["s1", "s3", "s2"], r.zrange("foobar", 0, -1)
56
+ end
57
+
58
+ def test_zinterstore
59
+ r.zadd "foo", 1, "s1"
60
+ r.zadd "bar", 2, "s1"
61
+ r.zadd "foo", 3, "s3"
62
+ r.zadd "bar", 4, "s4"
63
+
64
+ assert_equal 1, r.zinterstore("foobar", ["foo", "bar"])
65
+ assert_equal ["s1"], r.zrange("foobar", 0, -1)
66
+ end
67
+
68
+ def test_zinterstore_with_weights
69
+ r.zadd "foo", 1, "s1"
70
+ r.zadd "foo", 2, "s2"
71
+ r.zadd "foo", 3, "s3"
72
+ r.zadd "bar", 20, "s2"
73
+ r.zadd "bar", 30, "s3"
74
+ r.zadd "bar", 40, "s4"
75
+
76
+ assert_equal 2, r.zinterstore("foobar", ["foo", "bar"])
77
+ assert_equal ["s2", "s3"], r.zrange("foobar", 0, -1)
78
+
79
+ assert_equal 2, r.zinterstore("foobar", ["foo", "bar"], :weights => [10, 1])
80
+ assert_equal ["s2", "s3"], r.zrange("foobar", 0, -1)
81
+
82
+ assert_equal 40.0, r.zscore("foobar", "s2")
83
+ assert_equal 60.0, r.zscore("foobar", "s3")
84
+ end
85
+
86
+ def test_zinterstore_with_aggregate
87
+ r.zadd "foo", 1, "s1"
88
+ r.zadd "foo", 2, "s2"
89
+ r.zadd "foo", 3, "s3"
90
+ r.zadd "bar", 20, "s2"
91
+ r.zadd "bar", 30, "s3"
92
+ r.zadd "bar", 40, "s4"
93
+
94
+ assert_equal 2, r.zinterstore("foobar", ["foo", "bar"])
95
+ assert_equal ["s2", "s3"], r.zrange("foobar", 0, -1)
96
+ assert_equal 22.0, r.zscore("foobar", "s2")
97
+ assert_equal 33.0, r.zscore("foobar", "s3")
98
+
99
+ assert_equal 2, r.zinterstore("foobar", ["foo", "bar"], :aggregate => :min)
100
+ assert_equal ["s2", "s3"], r.zrange("foobar", 0, -1)
101
+ assert_equal 2.0, r.zscore("foobar", "s2")
102
+ assert_equal 3.0, r.zscore("foobar", "s3")
103
+
104
+ assert_equal 2, r.zinterstore("foobar", ["foo", "bar"], :aggregate => :max)
105
+ assert_equal ["s2", "s3"], r.zrange("foobar", 0, -1)
106
+ assert_equal 20.0, r.zscore("foobar", "s2")
107
+ assert_equal 30.0, r.zscore("foobar", "s3")
108
+ end
108
109
  end