redis 3.0.0.rc1 → 3.0.0.rc2

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 (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