redis2-namespaced 3.0.7

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 (99) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.order +170 -0
  4. data/.travis/Gemfile +11 -0
  5. data/.travis.yml +55 -0
  6. data/.yardopts +3 -0
  7. data/CHANGELOG.md +285 -0
  8. data/LICENSE +20 -0
  9. data/README.md +251 -0
  10. data/Rakefile +403 -0
  11. data/benchmarking/logging.rb +71 -0
  12. data/benchmarking/pipeline.rb +51 -0
  13. data/benchmarking/speed.rb +21 -0
  14. data/benchmarking/suite.rb +24 -0
  15. data/benchmarking/worker.rb +71 -0
  16. data/examples/basic.rb +15 -0
  17. data/examples/dist_redis.rb +43 -0
  18. data/examples/incr-decr.rb +17 -0
  19. data/examples/list.rb +26 -0
  20. data/examples/pubsub.rb +37 -0
  21. data/examples/sets.rb +36 -0
  22. data/examples/unicorn/config.ru +3 -0
  23. data/examples/unicorn/unicorn.rb +20 -0
  24. data/lib/redis2/client.rb +419 -0
  25. data/lib/redis2/connection/command_helper.rb +44 -0
  26. data/lib/redis2/connection/hiredis.rb +63 -0
  27. data/lib/redis2/connection/registry.rb +12 -0
  28. data/lib/redis2/connection/ruby.rb +322 -0
  29. data/lib/redis2/connection/synchrony.rb +124 -0
  30. data/lib/redis2/connection.rb +9 -0
  31. data/lib/redis2/distributed.rb +853 -0
  32. data/lib/redis2/errors.rb +40 -0
  33. data/lib/redis2/hash_ring.rb +131 -0
  34. data/lib/redis2/pipeline.rb +141 -0
  35. data/lib/redis2/subscribe.rb +83 -0
  36. data/lib/redis2/version.rb +3 -0
  37. data/lib/redis2.rb +2533 -0
  38. data/redis.gemspec +43 -0
  39. data/test/bitpos_test.rb +69 -0
  40. data/test/blocking_commands_test.rb +42 -0
  41. data/test/command_map_test.rb +30 -0
  42. data/test/commands_on_hashes_test.rb +21 -0
  43. data/test/commands_on_lists_test.rb +20 -0
  44. data/test/commands_on_sets_test.rb +77 -0
  45. data/test/commands_on_sorted_sets_test.rb +109 -0
  46. data/test/commands_on_strings_test.rb +101 -0
  47. data/test/commands_on_value_types_test.rb +131 -0
  48. data/test/connection_handling_test.rb +189 -0
  49. data/test/db/.gitkeep +0 -0
  50. data/test/distributed_blocking_commands_test.rb +46 -0
  51. data/test/distributed_commands_on_hashes_test.rb +10 -0
  52. data/test/distributed_commands_on_lists_test.rb +22 -0
  53. data/test/distributed_commands_on_sets_test.rb +83 -0
  54. data/test/distributed_commands_on_sorted_sets_test.rb +18 -0
  55. data/test/distributed_commands_on_strings_test.rb +59 -0
  56. data/test/distributed_commands_on_value_types_test.rb +95 -0
  57. data/test/distributed_commands_requiring_clustering_test.rb +164 -0
  58. data/test/distributed_connection_handling_test.rb +23 -0
  59. data/test/distributed_internals_test.rb +70 -0
  60. data/test/distributed_key_tags_test.rb +52 -0
  61. data/test/distributed_persistence_control_commands_test.rb +26 -0
  62. data/test/distributed_publish_subscribe_test.rb +92 -0
  63. data/test/distributed_remote_server_control_commands_test.rb +66 -0
  64. data/test/distributed_scripting_test.rb +102 -0
  65. data/test/distributed_sorting_test.rb +20 -0
  66. data/test/distributed_test.rb +58 -0
  67. data/test/distributed_transactions_test.rb +32 -0
  68. data/test/encoding_test.rb +18 -0
  69. data/test/error_replies_test.rb +59 -0
  70. data/test/helper.rb +218 -0
  71. data/test/helper_test.rb +24 -0
  72. data/test/internals_test.rb +410 -0
  73. data/test/lint/blocking_commands.rb +150 -0
  74. data/test/lint/hashes.rb +162 -0
  75. data/test/lint/lists.rb +143 -0
  76. data/test/lint/sets.rb +125 -0
  77. data/test/lint/sorted_sets.rb +238 -0
  78. data/test/lint/strings.rb +260 -0
  79. data/test/lint/value_types.rb +122 -0
  80. data/test/persistence_control_commands_test.rb +26 -0
  81. data/test/pipelining_commands_test.rb +242 -0
  82. data/test/publish_subscribe_test.rb +210 -0
  83. data/test/remote_server_control_commands_test.rb +117 -0
  84. data/test/scanning_test.rb +413 -0
  85. data/test/scripting_test.rb +78 -0
  86. data/test/sorting_test.rb +59 -0
  87. data/test/support/connection/hiredis.rb +1 -0
  88. data/test/support/connection/ruby.rb +1 -0
  89. data/test/support/connection/synchrony.rb +17 -0
  90. data/test/support/redis_mock.rb +115 -0
  91. data/test/support/wire/synchrony.rb +24 -0
  92. data/test/support/wire/thread.rb +5 -0
  93. data/test/synchrony_driver.rb +88 -0
  94. data/test/test.conf +9 -0
  95. data/test/thread_safety_test.rb +32 -0
  96. data/test/transactions_test.rb +264 -0
  97. data/test/unknown_commands_test.rb +14 -0
  98. data/test/url_param_test.rb +132 -0
  99. metadata +226 -0
data/redis.gemspec ADDED
@@ -0,0 +1,43 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ $:.unshift File.expand_path("../lib", __FILE__)
4
+
5
+ require "redis2/version"
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = "redis2-namespaced"
9
+
10
+ s.version = Redis2::VERSION
11
+
12
+ s.homepage = "https://github.com/redis/redis-rb"
13
+
14
+ s.summary = "A Ruby client library for Redis2"
15
+
16
+ s.description = <<-EOS
17
+ A Ruby client that tries to match Redis2' 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.
20
+ EOS
21
+
22
+ s.license = "MIT"
23
+
24
+ s.authors = [
25
+ "Ezra Zygmuntowicz",
26
+ "Taylor Weibley",
27
+ "Matthew Clark",
28
+ "Brian McKinney",
29
+ "Salvatore Sanfilippo",
30
+ "Luca Guidi",
31
+ "Michel Martens",
32
+ "Damian Janowski",
33
+ "Pieter Noordhuis"
34
+ ]
35
+
36
+ s.email = ["redis-db@googlegroups.com"]
37
+
38
+ s.files = `git ls-files`.split("\n")
39
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
40
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
41
+
42
+ s.add_development_dependency("rake")
43
+ end
@@ -0,0 +1,69 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("helper", File.dirname(__FILE__))
4
+
5
+ unless defined?(Enumerator)
6
+ Enumerator = Enumerable::Enumerator
7
+ end
8
+
9
+ class TestBitpos < Test::Unit::TestCase
10
+
11
+ include Helper::Client
12
+
13
+ def test_bitpos_empty_zero
14
+ target_version "2.9.11" do
15
+ r.del "foo"
16
+ assert_equal 0, r.bitpos("foo", 0)
17
+ end
18
+ end
19
+
20
+ def test_bitpos_empty_one
21
+ target_version "2.9.11" do
22
+ r.del "foo"
23
+ assert_equal -1, r.bitpos("foo", 1)
24
+ end
25
+ end
26
+
27
+ def test_bitpos_zero
28
+ target_version "2.9.11" do
29
+ r.set "foo", "\xff\xf0\x00"
30
+ assert_equal 12, r.bitpos("foo", 0)
31
+ end
32
+ end
33
+
34
+ def test_bitpos_one
35
+ target_version "2.9.11" do
36
+ r.set "foo", "\x00\x0f\x00"
37
+ assert_equal 12, r.bitpos("foo", 1)
38
+ end
39
+ end
40
+
41
+ def test_bitpos_zero_end_is_given
42
+ target_version "2.9.11" do
43
+ r.set "foo", "\xff\xff\xff"
44
+ assert_equal 24, r.bitpos("foo", 0)
45
+ assert_equal 24, r.bitpos("foo", 0, 0)
46
+ assert_equal -1, r.bitpos("foo", 0, 0, -1)
47
+ end
48
+ end
49
+
50
+ def test_bitpos_one_intervals
51
+ target_version "2.9.11" do
52
+ r.set "foo", "\x00\xff\x00"
53
+ assert_equal 8, r.bitpos("foo", 1, 0, -1)
54
+ assert_equal 8, r.bitpos("foo", 1, 1, -1)
55
+ assert_equal -1, r.bitpos("foo", 1, 2, -1)
56
+ assert_equal -1, r.bitpos("foo", 1, 2, 200)
57
+ assert_equal 8, r.bitpos("foo", 1, 1, 1)
58
+ end
59
+ end
60
+
61
+ def test_bitpos_raise_exception_if_stop_not_start
62
+ target_version "2.9.11" do
63
+ assert_raises(ArgumentError) do
64
+ r.bitpos("foo", 0, nil, 2)
65
+ end
66
+ end
67
+ end
68
+
69
+ end
@@ -0,0 +1,42 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("helper", File.dirname(__FILE__))
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
@@ -0,0 +1,30 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("helper", File.dirname(__FILE__))
4
+
5
+ class TestCommandMap < Test::Unit::TestCase
6
+
7
+ include Helper::Client
8
+
9
+ def test_override_existing_commands
10
+ r.set("counter", 1)
11
+
12
+ assert_equal 2, r.incr("counter")
13
+
14
+ r.client.command_map[:incr] = :decr
15
+
16
+ assert_equal 1, r.incr("counter")
17
+ end
18
+
19
+ def test_override_non_existing_commands
20
+ r.set("key", "value")
21
+
22
+ assert_raise Redis2::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
30
+ end
@@ -0,0 +1,21 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("helper", File.dirname(__FILE__))
4
+ require "lint/hashes"
5
+
6
+ class TestCommandsOnHashes < Test::Unit::TestCase
7
+
8
+ include Helper::Client
9
+ include Lint::Hashes
10
+
11
+ def test_mapped_hmget_in_a_pipeline_returns_hash
12
+ r.hset("foo", "f1", "s1")
13
+ r.hset("foo", "f2", "s2")
14
+
15
+ result = r.pipelined do
16
+ r.mapped_hmget("foo", "f1", "f2")
17
+ end
18
+
19
+ assert_equal result[0], { "f1" => "s1", "f2" => "s2" }
20
+ end
21
+ end
@@ -0,0 +1,20 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("helper", File.dirname(__FILE__))
4
+ require "lint/lists"
5
+
6
+ class TestCommandsOnLists < Test::Unit::TestCase
7
+
8
+ include Helper::Client
9
+ include Lint::Lists
10
+
11
+ def test_rpoplpush
12
+ r.rpush "foo", "s1"
13
+ r.rpush "foo", "s2"
14
+
15
+ assert_equal "s2", r.rpoplpush("foo", "bar")
16
+ assert_equal ["s2"], r.lrange("bar", 0, -1)
17
+ assert_equal "s1", r.rpoplpush("foo", "bar")
18
+ assert_equal ["s1", "s2"], r.lrange("bar", 0, -1)
19
+ end
20
+ end
@@ -0,0 +1,77 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("helper", File.dirname(__FILE__))
4
+ require "lint/sets"
5
+
6
+ class TestCommandsOnSets < Test::Unit::TestCase
7
+
8
+ include Helper::Client
9
+ include Lint::Sets
10
+
11
+ def test_smove
12
+ r.sadd "foo", "s1"
13
+ r.sadd "bar", "s2"
14
+
15
+ assert r.smove("foo", "bar", "s1")
16
+ assert r.sismember("bar", "s1")
17
+ end
18
+
19
+ def test_sinter
20
+ r.sadd "foo", "s1"
21
+ r.sadd "foo", "s2"
22
+ r.sadd "bar", "s2"
23
+
24
+ assert_equal ["s2"], r.sinter("foo", "bar")
25
+ end
26
+
27
+ def test_sinterstore
28
+ r.sadd "foo", "s1"
29
+ r.sadd "foo", "s2"
30
+ r.sadd "bar", "s2"
31
+
32
+ r.sinterstore("baz", "foo", "bar")
33
+
34
+ assert_equal ["s2"], r.smembers("baz")
35
+ end
36
+
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
+
43
+ assert_equal ["s1", "s2", "s3"], r.sunion("foo", "bar").sort
44
+ end
45
+
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
+
52
+ r.sunionstore("baz", "foo", "bar")
53
+
54
+ assert_equal ["s1", "s2", "s3"], r.smembers("baz").sort
55
+ end
56
+
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
+
63
+ assert_equal ["s1"], r.sdiff("foo", "bar")
64
+ assert_equal ["s3"], r.sdiff("bar", "foo")
65
+ end
66
+
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
+
73
+ r.sdiffstore("baz", "foo", "bar")
74
+
75
+ assert_equal ["s1"], r.smembers("baz")
76
+ end
77
+ end
@@ -0,0 +1,109 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("helper", File.dirname(__FILE__))
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
109
+ end
@@ -0,0 +1,101 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("helper", File.dirname(__FILE__))
4
+ require "lint/strings"
5
+
6
+ class TestCommandsOnStrings < Test::Unit::TestCase
7
+
8
+ include Helper::Client
9
+ include Lint::Strings
10
+
11
+ def test_mget
12
+ r.set("foo", "s1")
13
+ r.set("bar", "s2")
14
+
15
+ assert_equal ["s1", "s2"] , r.mget("foo", "bar")
16
+ assert_equal ["s1", "s2", nil], r.mget("foo", "bar", "baz")
17
+ end
18
+
19
+ def test_mget_mapped
20
+ r.set("foo", "s1")
21
+ r.set("bar", "s2")
22
+
23
+ response = r.mapped_mget("foo", "bar")
24
+
25
+ assert_equal "s1", response["foo"]
26
+ assert_equal "s2", response["bar"]
27
+
28
+ response = r.mapped_mget("foo", "bar", "baz")
29
+
30
+ assert_equal "s1", response["foo"]
31
+ assert_equal "s2", response["bar"]
32
+ assert_equal nil , response["baz"]
33
+ end
34
+
35
+ def test_mapped_mget_in_a_pipeline_returns_hash
36
+ r.set("foo", "s1")
37
+ r.set("bar", "s2")
38
+
39
+ result = r.pipelined do
40
+ r.mapped_mget("foo", "bar")
41
+ end
42
+
43
+ assert_equal result[0], { "foo" => "s1", "bar" => "s2" }
44
+ end
45
+
46
+ def test_mset
47
+ r.mset(:foo, "s1", :bar, "s2")
48
+
49
+ assert_equal "s1", r.get("foo")
50
+ assert_equal "s2", r.get("bar")
51
+ end
52
+
53
+ def test_mset_mapped
54
+ r.mapped_mset(:foo => "s1", :bar => "s2")
55
+
56
+ assert_equal "s1", r.get("foo")
57
+ assert_equal "s2", r.get("bar")
58
+ end
59
+
60
+ def test_msetnx
61
+ r.set("foo", "s1")
62
+ assert_equal false, r.msetnx(:foo, "s2", :bar, "s3")
63
+ assert_equal "s1", r.get("foo")
64
+ assert_equal nil, r.get("bar")
65
+
66
+ r.del("foo")
67
+ assert_equal true, r.msetnx(:foo, "s2", :bar, "s3")
68
+ assert_equal "s2", r.get("foo")
69
+ assert_equal "s3", r.get("bar")
70
+ end
71
+
72
+ def test_msetnx_mapped
73
+ r.set("foo", "s1")
74
+ assert_equal false, r.mapped_msetnx(:foo => "s2", :bar => "s3")
75
+ assert_equal "s1", r.get("foo")
76
+ assert_equal nil, r.get("bar")
77
+
78
+ r.del("foo")
79
+ assert_equal true, r.mapped_msetnx(:foo => "s2", :bar => "s3")
80
+ assert_equal "s2", r.get("foo")
81
+ assert_equal "s3", r.get("bar")
82
+ end
83
+
84
+ def test_bitop
85
+ try_encoding("UTF-8") do
86
+ target_version "2.5.10" do
87
+ r.set("foo", "a")
88
+ r.set("bar", "b")
89
+
90
+ r.bitop(:and, "foo&bar", "foo", "bar")
91
+ assert_equal "\x60", r.get("foo&bar")
92
+ r.bitop(:or, "foo|bar", "foo", "bar")
93
+ assert_equal "\x63", r.get("foo|bar")
94
+ r.bitop(:xor, "foo^bar", "foo", "bar")
95
+ assert_equal "\x03", r.get("foo^bar")
96
+ r.bitop(:not, "~foo", "foo")
97
+ assert_equal "\x9E", r.get("~foo")
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,131 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("helper", File.dirname(__FILE__))
4
+ require "lint/value_types"
5
+
6
+ class TestCommandsOnValueTypes < Test::Unit::TestCase
7
+
8
+ include Helper::Client
9
+ include Lint::ValueTypes
10
+
11
+ def test_del
12
+ r.set "foo", "s1"
13
+ r.set "bar", "s2"
14
+ r.set "baz", "s3"
15
+
16
+ assert_equal ["bar", "baz", "foo"], r.keys("*").sort
17
+
18
+ assert_equal 1, r.del("foo")
19
+
20
+ assert_equal ["bar", "baz"], r.keys("*").sort
21
+
22
+ assert_equal 2, r.del("bar", "baz")
23
+
24
+ assert_equal [], r.keys("*").sort
25
+ end
26
+
27
+ def test_del_with_array_argument
28
+ r.set "foo", "s1"
29
+ r.set "bar", "s2"
30
+ r.set "baz", "s3"
31
+
32
+ assert_equal ["bar", "baz", "foo"], r.keys("*").sort
33
+
34
+ assert_equal 1, r.del(["foo"])
35
+
36
+ assert_equal ["bar", "baz"], r.keys("*").sort
37
+
38
+ assert_equal 2, r.del(["bar", "baz"])
39
+
40
+ assert_equal [], r.keys("*").sort
41
+ end
42
+
43
+ def test_randomkey
44
+ assert r.randomkey.to_s.empty?
45
+
46
+ r.set("foo", "s1")
47
+
48
+ assert_equal "foo", r.randomkey
49
+
50
+ r.set("bar", "s2")
51
+
52
+ 4.times do
53
+ assert ["foo", "bar"].include?(r.randomkey)
54
+ end
55
+ end
56
+
57
+ def test_rename
58
+ r.set("foo", "s1")
59
+ r.rename "foo", "bar"
60
+
61
+ assert_equal "s1", r.get("bar")
62
+ assert_equal nil, r.get("foo")
63
+ end
64
+
65
+ def test_renamenx
66
+ r.set("foo", "s1")
67
+ r.set("bar", "s2")
68
+
69
+ assert_equal false, r.renamenx("foo", "bar")
70
+
71
+ assert_equal "s1", r.get("foo")
72
+ assert_equal "s2", r.get("bar")
73
+ end
74
+
75
+ def test_dbsize
76
+ assert_equal 0, r.dbsize
77
+
78
+ r.set("foo", "s1")
79
+
80
+ assert_equal 1, r.dbsize
81
+ end
82
+
83
+ def test_flushdb
84
+ r.set("foo", "s1")
85
+ r.set("bar", "s2")
86
+
87
+ assert_equal 2, r.dbsize
88
+
89
+ r.flushdb
90
+
91
+ assert_equal 0, r.dbsize
92
+ end
93
+
94
+ def test_flushall
95
+ redis_mock(:flushall => lambda { "+FLUSHALL" }) do |redis|
96
+ assert_equal "FLUSHALL", redis.flushall
97
+ end
98
+ end
99
+
100
+ def test_migrate
101
+ redis_mock(:migrate => lambda { |*args| args }) do |redis|
102
+ options = { :host => "127.0.0.1", :port => 1234 }
103
+
104
+ assert_raise(RuntimeError, /host not specified/) do
105
+ redis.migrate("foo", options.reject { |key, _| key == :host })
106
+ end
107
+
108
+ assert_raise(RuntimeError, /port not specified/) do
109
+ redis.migrate("foo", options.reject { |key, _| key == :port })
110
+ end
111
+
112
+ default_db = redis.client.db.to_i
113
+ default_timeout = redis.client.timeout.to_i
114
+
115
+ # Test defaults
116
+ actual = redis.migrate("foo", options)
117
+ expected = ["127.0.0.1", "1234", "foo", default_db.to_s, default_timeout.to_s]
118
+ assert_equal expected, actual
119
+
120
+ # Test db override
121
+ actual = redis.migrate("foo", options.merge(:db => default_db + 1))
122
+ expected = ["127.0.0.1", "1234", "foo", (default_db + 1).to_s, default_timeout.to_s]
123
+ assert_equal expected, actual
124
+
125
+ # Test timeout override
126
+ actual = redis.migrate("foo", options.merge(:timeout => default_timeout + 1))
127
+ expected = ["127.0.0.1", "1234", "foo", default_db.to_s, (default_timeout + 1).to_s]
128
+ assert_equal expected, actual
129
+ end
130
+ end
131
+ end