redis 4.0.1 → 4.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.travis.yml +17 -29
  4. data/.travis/Gemfile +5 -0
  5. data/CHANGELOG.md +29 -0
  6. data/Gemfile +5 -0
  7. data/README.md +1 -1
  8. data/bin/build +71 -0
  9. data/lib/redis.rb +198 -12
  10. data/lib/redis/client.rb +26 -12
  11. data/lib/redis/cluster.rb +285 -0
  12. data/lib/redis/cluster/command.rb +81 -0
  13. data/lib/redis/cluster/command_loader.rb +32 -0
  14. data/lib/redis/cluster/key_slot_converter.rb +72 -0
  15. data/lib/redis/cluster/node.rb +104 -0
  16. data/lib/redis/cluster/node_key.rb +35 -0
  17. data/lib/redis/cluster/node_loader.rb +35 -0
  18. data/lib/redis/cluster/option.rb +76 -0
  19. data/lib/redis/cluster/slot.rb +69 -0
  20. data/lib/redis/cluster/slot_loader.rb +47 -0
  21. data/lib/redis/connection/ruby.rb +5 -2
  22. data/lib/redis/distributed.rb +10 -2
  23. data/lib/redis/errors.rb +46 -0
  24. data/lib/redis/pipeline.rb +9 -1
  25. data/lib/redis/version.rb +1 -1
  26. data/makefile +54 -22
  27. data/redis.gemspec +2 -1
  28. data/test/client_test.rb +17 -0
  29. data/test/cluster_abnormal_state_test.rb +38 -0
  30. data/test/cluster_blocking_commands_test.rb +15 -0
  31. data/test/cluster_client_internals_test.rb +77 -0
  32. data/test/cluster_client_key_hash_tags_test.rb +88 -0
  33. data/test/cluster_client_options_test.rb +147 -0
  34. data/test/cluster_client_pipelining_test.rb +59 -0
  35. data/test/cluster_client_replicas_test.rb +36 -0
  36. data/test/cluster_client_slots_test.rb +94 -0
  37. data/test/cluster_client_transactions_test.rb +71 -0
  38. data/test/cluster_commands_on_cluster_test.rb +165 -0
  39. data/test/cluster_commands_on_connection_test.rb +40 -0
  40. data/test/cluster_commands_on_geo_test.rb +74 -0
  41. data/test/cluster_commands_on_hashes_test.rb +11 -0
  42. data/test/cluster_commands_on_hyper_log_log_test.rb +17 -0
  43. data/test/cluster_commands_on_keys_test.rb +134 -0
  44. data/test/cluster_commands_on_lists_test.rb +15 -0
  45. data/test/cluster_commands_on_pub_sub_test.rb +101 -0
  46. data/test/cluster_commands_on_scripting_test.rb +56 -0
  47. data/test/cluster_commands_on_server_test.rb +221 -0
  48. data/test/cluster_commands_on_sets_test.rb +39 -0
  49. data/test/cluster_commands_on_sorted_sets_test.rb +35 -0
  50. data/test/cluster_commands_on_streams_test.rb +196 -0
  51. data/test/cluster_commands_on_strings_test.rb +15 -0
  52. data/test/cluster_commands_on_transactions_test.rb +41 -0
  53. data/test/cluster_commands_on_value_types_test.rb +14 -0
  54. data/test/commands_on_geo_test.rb +116 -0
  55. data/test/commands_on_hashes_test.rb +2 -14
  56. data/test/commands_on_hyper_log_log_test.rb +2 -14
  57. data/test/commands_on_lists_test.rb +2 -13
  58. data/test/commands_on_sets_test.rb +2 -70
  59. data/test/commands_on_sorted_sets_test.rb +2 -145
  60. data/test/commands_on_strings_test.rb +2 -94
  61. data/test/commands_on_value_types_test.rb +36 -0
  62. data/test/distributed_blocking_commands_test.rb +8 -0
  63. data/test/distributed_commands_on_hashes_test.rb +16 -3
  64. data/test/distributed_commands_on_hyper_log_log_test.rb +8 -13
  65. data/test/distributed_commands_on_lists_test.rb +4 -5
  66. data/test/distributed_commands_on_sets_test.rb +45 -46
  67. data/test/distributed_commands_on_sorted_sets_test.rb +51 -8
  68. data/test/distributed_commands_on_strings_test.rb +10 -0
  69. data/test/distributed_commands_on_value_types_test.rb +36 -0
  70. data/test/helper.rb +176 -32
  71. data/test/internals_test.rb +20 -1
  72. data/test/lint/blocking_commands.rb +40 -16
  73. data/test/lint/hashes.rb +41 -0
  74. data/test/lint/hyper_log_log.rb +15 -1
  75. data/test/lint/lists.rb +16 -0
  76. data/test/lint/sets.rb +142 -0
  77. data/test/lint/sorted_sets.rb +183 -2
  78. data/test/lint/strings.rb +102 -0
  79. data/test/pipelining_commands_test.rb +8 -0
  80. data/test/support/cluster/orchestrator.rb +199 -0
  81. data/test/support/redis_mock.rb +1 -1
  82. data/test/transactions_test.rb +10 -0
  83. metadata +81 -2
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'helper'
4
+ require_relative 'lint/strings'
5
+
6
+ # ruby -w -Itest test/cluster_commands_on_strings_test.rb
7
+ # @see https://redis.io/commands#string
8
+ class TestClusterCommandsOnStrings < Test::Unit::TestCase
9
+ include Helper::Cluster
10
+ include Lint::Strings
11
+
12
+ def mock(*args, &block)
13
+ redis_cluster_mock(*args, &block)
14
+ end
15
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'helper'
4
+
5
+ # ruby -w -Itest test/cluster_commands_on_transactions_test.rb
6
+ # @see https://redis.io/commands#transactions
7
+ class TestClusterCommandsOnTransactions < Test::Unit::TestCase
8
+ include Helper::Cluster
9
+
10
+ def test_discard
11
+ assert_raise(Redis::Cluster::AmbiguousNodeError) do
12
+ redis.discard
13
+ end
14
+ end
15
+
16
+ def test_exec
17
+ assert_raise(Redis::Cluster::AmbiguousNodeError) do
18
+ redis.exec
19
+ end
20
+ end
21
+
22
+ def test_multi
23
+ assert_raise(Redis::Cluster::AmbiguousNodeError) do
24
+ redis.multi
25
+ end
26
+ end
27
+
28
+ def test_unwatch
29
+ assert_raise(Redis::Cluster::AmbiguousNodeError) do
30
+ redis.unwatch
31
+ end
32
+ end
33
+
34
+ def test_watch
35
+ assert_raise(Redis::CommandError, "CROSSSLOT Keys in request don't hash to the same slot") do
36
+ redis.watch('key1', 'key2')
37
+ end
38
+
39
+ assert_equal 'OK', redis.watch('{key}1', '{key}2')
40
+ end
41
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'helper'
4
+ require_relative 'lint/value_types'
5
+
6
+ # ruby -w -Itest test/cluster_commands_on_value_types_test.rb
7
+ class TestClusterCommandsOnValueTypes < Test::Unit::TestCase
8
+ include Helper::Cluster
9
+ include Lint::ValueTypes
10
+
11
+ def test_move
12
+ assert_raise(Redis::CommandError) { super }
13
+ end
14
+ end
@@ -0,0 +1,116 @@
1
+ require_relative "helper"
2
+
3
+ class TestCommandsGeo < Test::Unit::TestCase
4
+ include Helper::Client
5
+
6
+ def setup
7
+ super
8
+
9
+ target_version "3.2.0" do
10
+ added_items_count = r.geoadd("Sicily", 13.361389, 38.115556, "Palermo", 15.087269, 37.502669, "Catania")
11
+ assert_equal 2, added_items_count
12
+ end
13
+ end
14
+
15
+ def test_georadius_with_sort
16
+ target_version "3.2.0" do
17
+ nearest_cities = r.georadius("Sicily", 15, 37, 200, 'km', sort: 'asc')
18
+ assert_equal %w(Catania Palermo), nearest_cities
19
+
20
+ farthest_cities = r.georadius("Sicily", 15, 37, 200, 'km', sort: 'desc')
21
+ assert_equal %w(Palermo Catania), farthest_cities
22
+ end
23
+ end
24
+
25
+ def test_georadius_with_count
26
+ target_version "3.2.0" do
27
+ city = r.georadius("Sicily", 15, 37, 200, 'km', count: 1)
28
+ assert_equal %w(Catania), city
29
+ end
30
+ end
31
+
32
+ def test_georadius_with_options_count_sort
33
+ target_version "3.2.0" do
34
+ city = r.georadius("Sicily", 15, 37, 200, 'km', sort: :desc, options: :WITHDIST, count: 1)
35
+ assert_equal [["Palermo", "190.4424"]], city
36
+ end
37
+ end
38
+
39
+ def test_georadiusbymember_with_sort
40
+ target_version "3.2.0" do
41
+ nearest_cities = r.georadiusbymember("Sicily", "Catania", 200, 'km', sort: 'asc')
42
+ assert_equal %w(Catania Palermo), nearest_cities
43
+
44
+ farthest_cities = r.georadiusbymember("Sicily", "Catania", 200, 'km', sort: 'desc')
45
+ assert_equal %w(Palermo Catania), farthest_cities
46
+ end
47
+ end
48
+
49
+ def test_georadiusbymember_with_count
50
+ target_version "3.2.0" do
51
+ city = r.georadiusbymember("Sicily", "Catania", 200, 'km', count: 1)
52
+ assert_equal %w(Catania), city
53
+ end
54
+ end
55
+
56
+ def test_georadiusbymember_with_options_count_sort
57
+ target_version "3.2.0" do
58
+ city = r.georadiusbymember("Sicily", "Catania", 200, 'km', sort: :desc, options: :WITHDIST, count: 1)
59
+ assert_equal [["Palermo", "166.2742"]], city
60
+ end
61
+ end
62
+
63
+ def test_geopos
64
+ target_version "3.2.0" do
65
+ location = r.geopos("Sicily", "Catania")
66
+ assert_equal [["15.08726745843887329", "37.50266842333162032"]], location
67
+
68
+ locations = r.geopos("Sicily", ["Palermo", "Catania"])
69
+ assert_equal [["13.36138933897018433", "38.11555639549629859"], ["15.08726745843887329", "37.50266842333162032"]], locations
70
+ end
71
+ end
72
+
73
+ def test_geopos_nonexistant_location
74
+ target_version "3.2.0" do
75
+ location = r.geopos("Sicily", "Rome")
76
+ assert_equal [nil], location
77
+
78
+ locations = r.geopos("Sicily", ["Rome", "Catania"])
79
+ assert_equal [nil, ["15.08726745843887329", "37.50266842333162032"]], locations
80
+ end
81
+ end
82
+
83
+ def test_geodist
84
+ target_version "3.2.0" do
85
+ distination_in_meters = r.geodist("Sicily", "Palermo", "Catania")
86
+ assert_equal "166274.1516", distination_in_meters
87
+
88
+ distination_in_feet = r.geodist("Sicily", "Palermo", "Catania", 'ft')
89
+ assert_equal "545518.8700", distination_in_feet
90
+ end
91
+ end
92
+
93
+ def test_geodist_with_nonexistant_location
94
+ target_version "3.2.0" do
95
+ distination = r.geodist("Sicily", "Palermo", "Rome")
96
+ assert_equal nil, distination
97
+ end
98
+ end
99
+
100
+ def test_geohash
101
+ target_version "3.2.0" do
102
+ geohash = r.geohash("Sicily", "Palermo")
103
+ assert_equal ["sqc8b49rny0"], geohash
104
+
105
+ geohashes = r.geohash("Sicily", ["Palermo", "Catania"])
106
+ assert_equal %w(sqc8b49rny0 sqdtr74hyu0), geohashes
107
+ end
108
+ end
109
+
110
+ def test_geohash_with_nonexistant_location
111
+ target_version "3.2.0" do
112
+ geohashes = r.geohash("Sicily", ["Palermo", "Rome"])
113
+ assert_equal ["sqc8b49rny0", nil], geohashes
114
+ end
115
+ end
116
+ end
@@ -1,19 +1,7 @@
1
- require_relative "helper"
2
- require_relative "lint/hashes"
1
+ require_relative 'helper'
2
+ require_relative 'lint/hashes'
3
3
 
4
4
  class TestCommandsOnHashes < Test::Unit::TestCase
5
-
6
5
  include Helper::Client
7
6
  include Lint::Hashes
8
-
9
- def test_mapped_hmget_in_a_pipeline_returns_hash
10
- r.hset("foo", "f1", "s1")
11
- r.hset("foo", "f2", "s2")
12
-
13
- result = r.pipelined do
14
- r.mapped_hmget("foo", "f1", "f2")
15
- end
16
-
17
- assert_equal result[0], { "f1" => "s1", "f2" => "s2" }
18
- end
19
7
  end
@@ -1,19 +1,7 @@
1
- require_relative "helper"
2
- require_relative "lint/hyper_log_log"
1
+ require_relative 'helper'
2
+ require_relative 'lint/hyper_log_log'
3
3
 
4
4
  class TestCommandsOnHyperLogLog < Test::Unit::TestCase
5
-
6
5
  include Helper::Client
7
6
  include Lint::HyperLogLog
8
-
9
- def test_pfmerge
10
- target_version "2.8.9" do
11
- r.pfadd "foo", "s1"
12
- r.pfadd "bar", "s2"
13
-
14
- assert_equal true, r.pfmerge("res", "foo", "bar")
15
- assert_equal 2, r.pfcount("res")
16
- end
17
- end
18
-
19
7
  end
@@ -1,18 +1,7 @@
1
- require_relative "helper"
2
- require_relative "lint/lists"
1
+ require_relative 'helper'
2
+ require_relative 'lint/lists'
3
3
 
4
4
  class TestCommandsOnLists < Test::Unit::TestCase
5
-
6
5
  include Helper::Client
7
6
  include Lint::Lists
8
-
9
- def test_rpoplpush
10
- r.rpush "foo", "s1"
11
- r.rpush "foo", "s2"
12
-
13
- assert_equal "s2", r.rpoplpush("foo", "bar")
14
- assert_equal ["s2"], r.lrange("bar", 0, -1)
15
- assert_equal "s1", r.rpoplpush("foo", "bar")
16
- assert_equal ["s1", "s2"], r.lrange("bar", 0, -1)
17
- end
18
7
  end
@@ -1,75 +1,7 @@
1
- require_relative "helper"
2
- require_relative "lint/sets"
1
+ require_relative 'helper'
2
+ require_relative 'lint/sets'
3
3
 
4
4
  class TestCommandsOnSets < Test::Unit::TestCase
5
-
6
5
  include Helper::Client
7
6
  include Lint::Sets
8
-
9
- def test_smove
10
- r.sadd "foo", "s1"
11
- r.sadd "bar", "s2"
12
-
13
- assert r.smove("foo", "bar", "s1")
14
- assert r.sismember("bar", "s1")
15
- end
16
-
17
- def test_sinter
18
- r.sadd "foo", "s1"
19
- r.sadd "foo", "s2"
20
- r.sadd "bar", "s2"
21
-
22
- assert_equal ["s2"], r.sinter("foo", "bar")
23
- end
24
-
25
- def test_sinterstore
26
- r.sadd "foo", "s1"
27
- r.sadd "foo", "s2"
28
- r.sadd "bar", "s2"
29
-
30
- r.sinterstore("baz", "foo", "bar")
31
-
32
- assert_equal ["s2"], r.smembers("baz")
33
- end
34
-
35
- def test_sunion
36
- r.sadd "foo", "s1"
37
- r.sadd "foo", "s2"
38
- r.sadd "bar", "s2"
39
- r.sadd "bar", "s3"
40
-
41
- assert_equal ["s1", "s2", "s3"], r.sunion("foo", "bar").sort
42
- end
43
-
44
- def test_sunionstore
45
- r.sadd "foo", "s1"
46
- r.sadd "foo", "s2"
47
- r.sadd "bar", "s2"
48
- r.sadd "bar", "s3"
49
-
50
- r.sunionstore("baz", "foo", "bar")
51
-
52
- assert_equal ["s1", "s2", "s3"], r.smembers("baz").sort
53
- end
54
-
55
- def test_sdiff
56
- r.sadd "foo", "s1"
57
- r.sadd "foo", "s2"
58
- r.sadd "bar", "s2"
59
- r.sadd "bar", "s3"
60
-
61
- assert_equal ["s1"], r.sdiff("foo", "bar")
62
- assert_equal ["s3"], r.sdiff("bar", "foo")
63
- end
64
-
65
- def test_sdiffstore
66
- r.sadd "foo", "s1"
67
- r.sadd "foo", "s2"
68
- r.sadd "bar", "s2"
69
- r.sadd "bar", "s3"
70
-
71
- r.sdiffstore("baz", "foo", "bar")
72
-
73
- assert_equal ["s1"], r.smembers("baz")
74
- end
75
7
  end
@@ -1,150 +1,7 @@
1
- require_relative "helper"
2
- require_relative "lint/sorted_sets"
1
+ require_relative 'helper'
2
+ require_relative 'lint/sorted_sets'
3
3
 
4
4
  class TestCommandsOnSortedSets < Test::Unit::TestCase
5
-
6
5
  include Helper::Client
7
6
  include Lint::SortedSets
8
-
9
- def test_zlexcount
10
- target_version "2.8.9" do
11
- r.zadd "foo", 0, "aaren"
12
- r.zadd "foo", 0, "abagael"
13
- r.zadd "foo", 0, "abby"
14
- r.zadd "foo", 0, "abbygail"
15
-
16
- assert_equal 4, r.zlexcount("foo", "[a", "[a\xff")
17
- assert_equal 4, r.zlexcount("foo", "[aa", "[ab\xff")
18
- assert_equal 3, r.zlexcount("foo", "(aaren", "[ab\xff")
19
- assert_equal 2, r.zlexcount("foo", "[aba", "(abbygail")
20
- assert_equal 1, r.zlexcount("foo", "(aaren", "(abby")
21
- end
22
- end
23
-
24
- def test_zrangebylex
25
- target_version "2.8.9" do
26
- r.zadd "foo", 0, "aaren"
27
- r.zadd "foo", 0, "abagael"
28
- r.zadd "foo", 0, "abby"
29
- r.zadd "foo", 0, "abbygail"
30
-
31
- assert_equal ["aaren", "abagael", "abby", "abbygail"], r.zrangebylex("foo", "[a", "[a\xff")
32
- assert_equal ["aaren", "abagael"], r.zrangebylex("foo", "[a", "[a\xff", :limit => [0, 2])
33
- assert_equal ["abby", "abbygail"], r.zrangebylex("foo", "(abb", "(abb\xff")
34
- assert_equal ["abbygail"], r.zrangebylex("foo", "(abby", "(abby\xff")
35
- end
36
- end
37
-
38
- def test_zrevrangebylex
39
- target_version "2.9.9" do
40
- r.zadd "foo", 0, "aaren"
41
- r.zadd "foo", 0, "abagael"
42
- r.zadd "foo", 0, "abby"
43
- r.zadd "foo", 0, "abbygail"
44
-
45
- assert_equal ["abbygail", "abby", "abagael", "aaren"], r.zrevrangebylex("foo", "[a\xff", "[a")
46
- assert_equal ["abbygail", "abby"], r.zrevrangebylex("foo", "[a\xff", "[a", :limit => [0, 2])
47
- assert_equal ["abbygail", "abby"], r.zrevrangebylex("foo", "(abb\xff", "(abb")
48
- assert_equal ["abbygail"], r.zrevrangebylex("foo", "(abby\xff", "(abby")
49
- end
50
- end
51
-
52
- def test_zcount
53
- r.zadd "foo", 1, "s1"
54
- r.zadd "foo", 2, "s2"
55
- r.zadd "foo", 3, "s3"
56
-
57
- assert_equal 2, r.zcount("foo", 2, 3)
58
- end
59
-
60
- def test_zunionstore
61
- r.zadd "foo", 1, "s1"
62
- r.zadd "bar", 2, "s2"
63
- r.zadd "foo", 3, "s3"
64
- r.zadd "bar", 4, "s4"
65
-
66
- assert_equal 4, r.zunionstore("foobar", ["foo", "bar"])
67
- assert_equal ["s1", "s2", "s3", "s4"], r.zrange("foobar", 0, -1)
68
- end
69
-
70
- def test_zunionstore_with_weights
71
- r.zadd "foo", 1, "s1"
72
- r.zadd "foo", 3, "s3"
73
- r.zadd "bar", 20, "s2"
74
- r.zadd "bar", 40, "s4"
75
-
76
- assert_equal 4, r.zunionstore("foobar", ["foo", "bar"])
77
- assert_equal ["s1", "s3", "s2", "s4"], r.zrange("foobar", 0, -1)
78
-
79
- assert_equal 4, r.zunionstore("foobar", ["foo", "bar"], :weights => [10, 1])
80
- assert_equal ["s1", "s2", "s3", "s4"], r.zrange("foobar", 0, -1)
81
- end
82
-
83
- def test_zunionstore_with_aggregate
84
- r.zadd "foo", 1, "s1"
85
- r.zadd "foo", 2, "s2"
86
- r.zadd "bar", 4, "s2"
87
- r.zadd "bar", 3, "s3"
88
-
89
- assert_equal 3, r.zunionstore("foobar", ["foo", "bar"])
90
- assert_equal ["s1", "s3", "s2"], r.zrange("foobar", 0, -1)
91
-
92
- assert_equal 3, r.zunionstore("foobar", ["foo", "bar"], :aggregate => :min)
93
- assert_equal ["s1", "s2", "s3"], r.zrange("foobar", 0, -1)
94
-
95
- assert_equal 3, r.zunionstore("foobar", ["foo", "bar"], :aggregate => :max)
96
- assert_equal ["s1", "s3", "s2"], r.zrange("foobar", 0, -1)
97
- end
98
-
99
- def test_zinterstore
100
- r.zadd "foo", 1, "s1"
101
- r.zadd "bar", 2, "s1"
102
- r.zadd "foo", 3, "s3"
103
- r.zadd "bar", 4, "s4"
104
-
105
- assert_equal 1, r.zinterstore("foobar", ["foo", "bar"])
106
- assert_equal ["s1"], r.zrange("foobar", 0, -1)
107
- end
108
-
109
- def test_zinterstore_with_weights
110
- r.zadd "foo", 1, "s1"
111
- r.zadd "foo", 2, "s2"
112
- r.zadd "foo", 3, "s3"
113
- r.zadd "bar", 20, "s2"
114
- r.zadd "bar", 30, "s3"
115
- r.zadd "bar", 40, "s4"
116
-
117
- assert_equal 2, r.zinterstore("foobar", ["foo", "bar"])
118
- assert_equal ["s2", "s3"], r.zrange("foobar", 0, -1)
119
-
120
- assert_equal 2, r.zinterstore("foobar", ["foo", "bar"], :weights => [10, 1])
121
- assert_equal ["s2", "s3"], r.zrange("foobar", 0, -1)
122
-
123
- assert_equal 40.0, r.zscore("foobar", "s2")
124
- assert_equal 60.0, r.zscore("foobar", "s3")
125
- end
126
-
127
- def test_zinterstore_with_aggregate
128
- r.zadd "foo", 1, "s1"
129
- r.zadd "foo", 2, "s2"
130
- r.zadd "foo", 3, "s3"
131
- r.zadd "bar", 20, "s2"
132
- r.zadd "bar", 30, "s3"
133
- r.zadd "bar", 40, "s4"
134
-
135
- assert_equal 2, r.zinterstore("foobar", ["foo", "bar"])
136
- assert_equal ["s2", "s3"], r.zrange("foobar", 0, -1)
137
- assert_equal 22.0, r.zscore("foobar", "s2")
138
- assert_equal 33.0, r.zscore("foobar", "s3")
139
-
140
- assert_equal 2, r.zinterstore("foobar", ["foo", "bar"], :aggregate => :min)
141
- assert_equal ["s2", "s3"], r.zrange("foobar", 0, -1)
142
- assert_equal 2.0, r.zscore("foobar", "s2")
143
- assert_equal 3.0, r.zscore("foobar", "s3")
144
-
145
- assert_equal 2, r.zinterstore("foobar", ["foo", "bar"], :aggregate => :max)
146
- assert_equal ["s2", "s3"], r.zrange("foobar", 0, -1)
147
- assert_equal 20.0, r.zscore("foobar", "s2")
148
- assert_equal 30.0, r.zscore("foobar", "s3")
149
- end
150
7
  end