redis 3.3.5 → 4.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/.travis/Gemfile +3 -1
  3. data/.travis.yml +36 -52
  4. data/CHANGELOG.md +18 -4
  5. data/Gemfile +0 -1
  6. data/README.md +31 -75
  7. data/benchmarking/logging.rb +1 -1
  8. data/bors.toml +14 -0
  9. data/lib/redis/client.rb +12 -8
  10. data/lib/redis/connection/command_helper.rb +2 -8
  11. data/lib/redis/connection/hiredis.rb +2 -2
  12. data/lib/redis/connection/ruby.rb +8 -28
  13. data/lib/redis/connection/synchrony.rb +12 -4
  14. data/lib/redis/connection.rb +2 -2
  15. data/lib/redis/distributed.rb +19 -6
  16. data/lib/redis/hash_ring.rb +20 -64
  17. data/lib/redis/pipeline.rb +0 -6
  18. data/lib/redis/version.rb +1 -1
  19. data/lib/redis.rb +89 -40
  20. data/makefile +42 -0
  21. data/redis.gemspec +7 -9
  22. data/test/bitpos_test.rb +13 -19
  23. data/test/blocking_commands_test.rb +3 -5
  24. data/test/client_test.rb +1 -1
  25. data/test/command_map_test.rb +3 -5
  26. data/test/commands_on_hashes_test.rb +2 -4
  27. data/test/commands_on_hyper_log_log_test.rb +3 -5
  28. data/test/commands_on_lists_test.rb +2 -4
  29. data/test/commands_on_sets_test.rb +2 -4
  30. data/test/commands_on_sorted_sets_test.rb +17 -4
  31. data/test/commands_on_strings_test.rb +3 -5
  32. data/test/commands_on_value_types_test.rb +44 -6
  33. data/test/connection_handling_test.rb +5 -7
  34. data/test/distributed_blocking_commands_test.rb +2 -4
  35. data/test/distributed_commands_on_hashes_test.rb +2 -4
  36. data/test/distributed_commands_on_hyper_log_log_test.rb +2 -4
  37. data/test/distributed_commands_on_lists_test.rb +2 -4
  38. data/test/distributed_commands_on_sets_test.rb +27 -4
  39. data/test/distributed_commands_on_sorted_sets_test.rb +2 -4
  40. data/test/distributed_commands_on_strings_test.rb +20 -10
  41. data/test/distributed_commands_on_value_types_test.rb +2 -4
  42. data/test/distributed_commands_requiring_clustering_test.rb +1 -3
  43. data/test/distributed_connection_handling_test.rb +1 -3
  44. data/test/distributed_internals_test.rb +8 -19
  45. data/test/distributed_key_tags_test.rb +4 -6
  46. data/test/distributed_persistence_control_commands_test.rb +1 -3
  47. data/test/distributed_publish_subscribe_test.rb +1 -3
  48. data/test/distributed_remote_server_control_commands_test.rb +1 -3
  49. data/test/distributed_scripting_test.rb +1 -3
  50. data/test/distributed_sorting_test.rb +1 -3
  51. data/test/distributed_test.rb +12 -14
  52. data/test/distributed_transactions_test.rb +1 -3
  53. data/test/encoding_test.rb +4 -8
  54. data/test/error_replies_test.rb +2 -4
  55. data/test/fork_safety_test.rb +1 -6
  56. data/test/helper.rb +10 -41
  57. data/test/helper_test.rb +1 -3
  58. data/test/internals_test.rb +27 -55
  59. data/test/lint/strings.rb +6 -20
  60. data/test/lint/value_types.rb +8 -0
  61. data/test/persistence_control_commands_test.rb +1 -3
  62. data/test/pipelining_commands_test.rb +4 -8
  63. data/test/publish_subscribe_test.rb +1 -3
  64. data/test/remote_server_control_commands_test.rb +60 -3
  65. data/test/scanning_test.rb +1 -7
  66. data/test/scripting_test.rb +1 -3
  67. data/test/sentinel_command_test.rb +1 -3
  68. data/test/sentinel_test.rb +1 -3
  69. data/test/sorting_test.rb +1 -3
  70. data/test/ssl_test.rb +45 -49
  71. data/test/support/connection/hiredis.rb +1 -1
  72. data/test/support/connection/ruby.rb +1 -1
  73. data/test/support/connection/synchrony.rb +1 -1
  74. data/test/synchrony_driver.rb +6 -9
  75. data/test/thread_safety_test.rb +1 -3
  76. data/test/transactions_test.rb +1 -3
  77. data/test/unknown_commands_test.rb +1 -3
  78. data/test/url_param_test.rb +44 -46
  79. metadata +29 -15
  80. data/Rakefile +0 -87
@@ -25,7 +25,6 @@ class Redis
25
25
  @nodes << node
26
26
  @replicas.times do |i|
27
27
  key = Zlib.crc32("#{node.id}:#{i}")
28
- raise "Node ID collision" if @ring.has_key?(key)
29
28
  @ring[key] = node
30
29
  @sorted_keys << key
31
30
  end
@@ -61,72 +60,29 @@ class Redis
61
60
  end
62
61
  end
63
62
 
64
- class << self
65
-
66
- # gem install RubyInline to use this code
67
- # Native extension to perform the binary search within the hashring.
68
- # There's a pure ruby version below so this is purely optional
69
- # for performance. In testing 20k gets and sets, the native
70
- # binary search shaved about 12% off the runtime (9sec -> 8sec).
71
- begin
72
- require 'inline'
73
- inline do |builder|
74
- builder.c <<-EOM
75
- int binary_search(VALUE ary, unsigned int r) {
76
- int upper = RARRAY_LEN(ary) - 1;
77
- int lower = 0;
78
- int idx = 0;
79
-
80
- while (lower <= upper) {
81
- idx = (lower + upper) / 2;
82
-
83
- VALUE continuumValue = RARRAY_PTR(ary)[idx];
84
- unsigned int l = NUM2UINT(continuumValue);
85
- if (l == r) {
86
- return idx;
87
- }
88
- else if (l > r) {
89
- upper = idx - 1;
90
- }
91
- else {
92
- lower = idx + 1;
93
- }
94
- }
95
- if (upper < 0) {
96
- upper = RARRAY_LEN(ary) - 1;
97
- }
98
- return upper;
99
- }
100
- EOM
101
- end
102
- rescue Exception
103
- # Find the closest index in HashRing with value <= the given value
104
- def binary_search(ary, value, &block)
105
- upper = ary.size - 1
106
- lower = 0
107
- idx = 0
108
-
109
- while(lower <= upper) do
110
- idx = (lower + upper) / 2
111
- comp = ary[idx] <=> value
112
-
113
- if comp == 0
114
- return idx
115
- elsif comp > 0
116
- upper = idx - 1
117
- else
118
- lower = idx + 1
119
- end
120
- end
121
-
122
- if upper < 0
123
- upper = ary.size - 1
124
- end
125
- return upper
63
+ # Find the closest index in HashRing with value <= the given value
64
+ def self.binary_search(ary, value, &block)
65
+ upper = ary.size - 1
66
+ lower = 0
67
+ idx = 0
68
+
69
+ while(lower <= upper) do
70
+ idx = (lower + upper) / 2
71
+ comp = ary[idx] <=> value
72
+
73
+ if comp == 0
74
+ return idx
75
+ elsif comp > 0
76
+ upper = idx - 1
77
+ else
78
+ lower = idx + 1
126
79
  end
80
+ end
127
81
 
82
+ if upper < 0
83
+ upper = ary.size - 1
128
84
  end
85
+ return upper
129
86
  end
130
-
131
87
  end
132
88
  end
@@ -1,10 +1,4 @@
1
1
  class Redis
2
- unless defined?(::BasicObject)
3
- class BasicObject
4
- instance_methods.each { |meth| undef_method(meth) unless meth =~ /\A(__|instance_eval)/ }
5
- end
6
- end
7
-
8
2
  class Pipeline
9
3
  attr_accessor :db
10
4
 
data/lib/redis/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class Redis
2
- VERSION = "3.3.5"
2
+ VERSION = "4.0.1"
3
3
  end
data/lib/redis.rb CHANGED
@@ -1,21 +1,8 @@
1
1
  require "monitor"
2
- require "redis/errors"
2
+ require_relative "redis/errors"
3
3
 
4
4
  class Redis
5
5
 
6
- def self.deprecate(message, trace = caller[0])
7
- $stderr.puts "\n#{message} (in #{trace})"
8
- end
9
-
10
- attr :client
11
-
12
- # @deprecated The preferred way to create a new client object is using `#new`.
13
- # This method does not actually establish a connection to Redis,
14
- # in contrary to what you might expect.
15
- def self.connect(options = {})
16
- new(options)
17
- end
18
-
19
6
  def self.current
20
7
  @current ||= Redis.new
21
8
  end
@@ -119,6 +106,10 @@ class Redis
119
106
  end
120
107
  end
121
108
 
109
+ def _client
110
+ @client
111
+ end
112
+
122
113
  # Authenticate to the server.
123
114
  #
124
115
  # @param [String] password must match the password specified in the
@@ -143,10 +134,11 @@ class Redis
143
134
 
144
135
  # Ping the server.
145
136
  #
137
+ # @param [optional, String] message
146
138
  # @return [String] `PONG`
147
- def ping
139
+ def ping(message = nil)
148
140
  synchronize do |client|
149
- client.call([:ping])
141
+ client.call([:ping, message].compact)
150
142
  end
151
143
  end
152
144
 
@@ -209,6 +201,25 @@ class Redis
209
201
  end
210
202
  end
211
203
 
204
+ # Manage client connections.
205
+ #
206
+ # @param [String, Symbol] subcommand e.g. `kill`, `list`, `getname`, `setname`
207
+ # @return [String, Hash] depends on subcommand
208
+ def client(subcommand = nil, *args)
209
+ synchronize do |client|
210
+ client.call([:client, subcommand] + args) do |reply|
211
+ if subcommand.to_s == "list"
212
+ reply.lines.map do |line|
213
+ entries = line.chomp.split(/[ =]/)
214
+ Hash[entries.each_slice(2).to_a]
215
+ end
216
+ else
217
+ reply
218
+ end
219
+ end
220
+ end
221
+ end
222
+
212
223
  # Return the number of keys in the selected database.
213
224
  #
214
225
  # @return [Fixnum]
@@ -226,19 +237,31 @@ class Redis
226
237
 
227
238
  # Remove all keys from all databases.
228
239
  #
240
+ # @param [Hash] options
241
+ # - `:async => Boolean`: async flush (default: false)
229
242
  # @return [String] `OK`
230
- def flushall
243
+ def flushall(options = nil)
231
244
  synchronize do |client|
232
- client.call([:flushall])
245
+ if options && options[:async]
246
+ client.call([:flushall, :async])
247
+ else
248
+ client.call([:flushall])
249
+ end
233
250
  end
234
251
  end
235
252
 
236
253
  # Remove all keys from the current database.
237
254
  #
255
+ # @param [Hash] options
256
+ # - `:async => Boolean`: async flush (default: false)
238
257
  # @return [String] `OK`
239
- def flushdb
258
+ def flushdb(options = nil)
240
259
  synchronize do |client|
241
- client.call([:flushdb])
260
+ if options && options[:async]
261
+ client.call([:flushdb, :async])
262
+ else
263
+ client.call([:flushdb])
264
+ end
242
265
  end
243
266
  end
244
267
 
@@ -458,10 +481,16 @@ class Redis
458
481
  # @param [String] key
459
482
  # @param [String] ttl
460
483
  # @param [String] serialized_value
484
+ # @param [Hash] options
485
+ # - `:replace => Boolean`: if false, raises an error if key already exists
486
+ # @raise [Redis::CommandError]
461
487
  # @return [String] `"OK"`
462
- def restore(key, ttl, serialized_value)
488
+ def restore(key, ttl, serialized_value, options = {})
489
+ args = [:restore, key, ttl, serialized_value]
490
+ args << 'REPLACE' if options[:replace]
491
+
463
492
  synchronize do |client|
464
- client.call([:restore, key, ttl, serialized_value])
493
+ client.call(args)
465
494
  end
466
495
  end
467
496
 
@@ -477,8 +506,8 @@ class Redis
477
506
  def migrate(key, options)
478
507
  host = options[:host] || raise(RuntimeError, ":host not specified")
479
508
  port = options[:port] || raise(RuntimeError, ":port not specified")
480
- db = (options[:db] || client.db).to_i
481
- timeout = (options[:timeout] || client.timeout).to_i
509
+ db = (options[:db] || @client.db).to_i
510
+ timeout = (options[:timeout] || @client.timeout).to_i
482
511
 
483
512
  synchronize do |client|
484
513
  client.call([:migrate, host, port, key, db, timeout])
@@ -756,8 +785,6 @@ class Redis
756
785
  end
757
786
  end
758
787
 
759
- alias :[]= :set
760
-
761
788
  # Set the time to live in seconds of a key.
762
789
  #
763
790
  # @param [String] key
@@ -863,8 +890,6 @@ class Redis
863
890
  end
864
891
  end
865
892
 
866
- alias :[] :get
867
-
868
893
  # Get the values of all the given keys.
869
894
  #
870
895
  # @example
@@ -1041,7 +1066,7 @@ class Redis
1041
1066
  # Prepend one or more values to a list, creating the list if it doesn't exist
1042
1067
  #
1043
1068
  # @param [String] key
1044
- # @param [String, Array] value string value, or array of string values to push
1069
+ # @param [String, Array<String>] value string value, or array of string values to push
1045
1070
  # @return [Fixnum] the length of the list after the push operation
1046
1071
  def lpush(key, value)
1047
1072
  synchronize do |client|
@@ -1063,7 +1088,7 @@ class Redis
1063
1088
  # Append one or more values to a list, creating the list if it doesn't exist
1064
1089
  #
1065
1090
  # @param [String] key
1066
- # @param [String] value
1091
+ # @param [String, Array<String>] value string value, or array of string values to push
1067
1092
  # @return [Fixnum] the length of the list after the push operation
1068
1093
  def rpush(key, value)
1069
1094
  synchronize do |client|
@@ -1701,6 +1726,30 @@ class Redis
1701
1726
  end
1702
1727
  end
1703
1728
 
1729
+ # Count the members, with the same score in a sorted set, within the given lexicographical range.
1730
+ #
1731
+ # @example Count members matching a
1732
+ # redis.zlexcount("zset", "[a", "[a\xff")
1733
+ # # => 1
1734
+ # @example Count members matching a-z
1735
+ # redis.zlexcount("zset", "[a", "[z\xff")
1736
+ # # => 26
1737
+ #
1738
+ # @param [String] key
1739
+ # @param [String] min
1740
+ # - inclusive minimum is specified by prefixing `(`
1741
+ # - exclusive minimum is specified by prefixing `[`
1742
+ # @param [String] max
1743
+ # - inclusive maximum is specified by prefixing `(`
1744
+ # - exclusive maximum is specified by prefixing `[`
1745
+ #
1746
+ # @return [Fixnum] number of members within the specified lexicographical range
1747
+ def zlexcount(key, min, max)
1748
+ synchronize do |client|
1749
+ client.call([:zlexcount, key, min, max])
1750
+ end
1751
+ end
1752
+
1704
1753
  # Return a range of members with the same score in a sorted set, by lexicographical ordering
1705
1754
  #
1706
1755
  # @example Retrieve members matching a
@@ -2702,11 +2751,11 @@ class Redis
2702
2751
 
2703
2752
  def connection
2704
2753
  {
2705
- :host => @original_client.host,
2706
- :port => @original_client.port,
2707
- :db => @original_client.db,
2708
- :id => @original_client.id,
2709
- :location => @original_client.location
2754
+ host: @original_client.host,
2755
+ port: @original_client.port,
2756
+ db: @original_client.db,
2757
+ id: @original_client.id,
2758
+ location: @original_client.location
2710
2759
  }
2711
2760
  end
2712
2761
 
@@ -2781,8 +2830,8 @@ private
2781
2830
 
2782
2831
  end
2783
2832
 
2784
- require "redis/version"
2785
- require "redis/connection"
2786
- require "redis/client"
2787
- require "redis/pipeline"
2788
- require "redis/subscribe"
2833
+ require_relative "redis/version"
2834
+ require_relative "redis/connection"
2835
+ require_relative "redis/client"
2836
+ require_relative "redis/pipeline"
2837
+ require_relative "redis/subscribe"
data/makefile ADDED
@@ -0,0 +1,42 @@
1
+ TEST_FILES := $(shell find test -name *_test.rb -type f)
2
+ REDIS_BRANCH := unstable
3
+ TMP := tmp
4
+ BUILD_DIR := ${TMP}/redis-${REDIS_BRANCH}
5
+ TARBALL := ${TMP}/redis-${REDIS_BRANCH}.tar.gz
6
+ BINARY := ${BUILD_DIR}/src/redis-server
7
+ PID_PATH := ${BUILD_DIR}/redis.pid
8
+ SOCKET_PATH := ${BUILD_DIR}/redis.sock
9
+ PORT := 6381
10
+
11
+ test: ${TEST_FILES}
12
+ make start
13
+ env SOCKET_PATH=${SOCKET_PATH} \
14
+ ruby -v $$(echo $? | tr ' ' '\n' | awk '{ print "-r./" $$0 }') -e ''
15
+ make stop
16
+
17
+ ${TMP}:
18
+ mkdir $@
19
+
20
+ ${TARBALL}: ${TMP}
21
+ wget https://github.com/antirez/redis/archive/${REDIS_BRANCH}.tar.gz -O $@
22
+
23
+ ${BINARY}: ${TARBALL} ${TMP}
24
+ rm -rf ${BUILD_DIR}
25
+ mkdir -p ${BUILD_DIR}
26
+ tar xf ${TARBALL} -C ${TMP}
27
+ cd ${BUILD_DIR} && make
28
+
29
+ stop:
30
+ (test -f ${PID_PATH} && (kill $$(cat ${PID_PATH}) || true) && rm -f ${PID_PATH}) || true
31
+
32
+ start: ${BINARY}
33
+ ${BINARY} \
34
+ --daemonize yes \
35
+ --pidfile ${PID_PATH} \
36
+ --port ${PORT} \
37
+ --unixsocket ${SOCKET_PATH}
38
+
39
+ clean:
40
+ (test -d ${BUILD_DIR} && cd ${BUILD_DIR}/src && make clean distclean) || true
41
+
42
+ .PHONY: test start stop
data/redis.gemspec CHANGED
@@ -1,8 +1,4 @@
1
- # -*- encoding: utf-8 -*-
2
-
3
- $:.unshift File.expand_path("../lib", __FILE__)
4
-
5
- require "redis/version"
1
+ require "./lib/redis/version"
6
2
 
7
3
  Gem::Specification.new do |s|
8
4
  s.name = "redis"
@@ -15,8 +11,7 @@ Gem::Specification.new do |s|
15
11
 
16
12
  s.description = <<-EOS
17
13
  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.
14
+ providing an idiomatic interface.
20
15
  EOS
21
16
 
22
17
  s.license = "MIT"
@@ -39,6 +34,9 @@ Gem::Specification.new do |s|
39
34
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
40
35
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
41
36
 
42
- s.add_development_dependency("rake", "<11.0.0")
43
- s.add_development_dependency("test-unit", "3.1.5")
37
+ s.required_ruby_version = '>= 2.2.2'
38
+
39
+ s.add_development_dependency("test-unit", ">= 3.1.5")
40
+ s.add_development_dependency("hiredis")
41
+ s.add_development_dependency("em-synchrony")
44
42
  end
data/test/bitpos_test.rb CHANGED
@@ -1,10 +1,4 @@
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
1
+ require_relative "helper"
8
2
 
9
3
  class TestBitpos < Test::Unit::TestCase
10
4
 
@@ -13,48 +7,48 @@ class TestBitpos < Test::Unit::TestCase
13
7
  def test_bitpos_empty_zero
14
8
  target_version "2.9.11" do
15
9
  r.del "foo"
16
- assert_equal 0, r.bitpos("foo", 0)
10
+ assert_equal(0, r.bitpos("foo", 0))
17
11
  end
18
12
  end
19
13
 
20
14
  def test_bitpos_empty_one
21
15
  target_version "2.9.11" do
22
16
  r.del "foo"
23
- assert_equal -1, r.bitpos("foo", 1)
17
+ assert_equal(-1, r.bitpos("foo", 1))
24
18
  end
25
19
  end
26
20
 
27
21
  def test_bitpos_zero
28
22
  target_version "2.9.11" do
29
23
  r.set "foo", "\xff\xf0\x00"
30
- assert_equal 12, r.bitpos("foo", 0)
24
+ assert_equal(12, r.bitpos("foo", 0))
31
25
  end
32
26
  end
33
27
 
34
28
  def test_bitpos_one
35
29
  target_version "2.9.11" do
36
30
  r.set "foo", "\x00\x0f\x00"
37
- assert_equal 12, r.bitpos("foo", 1)
31
+ assert_equal(12, r.bitpos("foo", 1))
38
32
  end
39
33
  end
40
34
 
41
35
  def test_bitpos_zero_end_is_given
42
36
  target_version "2.9.11" do
43
37
  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)
38
+ assert_equal(24, r.bitpos("foo", 0))
39
+ assert_equal(24, r.bitpos("foo", 0, 0))
40
+ assert_equal(-1, r.bitpos("foo", 0, 0, -1))
47
41
  end
48
42
  end
49
43
 
50
44
  def test_bitpos_one_intervals
51
45
  target_version "2.9.11" do
52
46
  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)
47
+ assert_equal(8, r.bitpos("foo", 1, 0, -1))
48
+ assert_equal(8, r.bitpos("foo", 1, 1, -1))
49
+ assert_equal(-1, r.bitpos("foo", 1, 2, -1))
50
+ assert_equal(-1, r.bitpos("foo", 1, 2, 200))
51
+ assert_equal(8, r.bitpos("foo", 1, 1, 1))
58
52
  end
59
53
  end
60
54
 
@@ -1,7 +1,5 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("helper", File.dirname(__FILE__))
4
- require "lint/blocking_commands"
1
+ require_relative "helper"
2
+ require_relative "lint/blocking_commands"
5
3
 
6
4
  class TestBlockingCommands < Test::Unit::TestCase
7
5
 
@@ -17,7 +15,7 @@ class TestBlockingCommands < Test::Unit::TestCase
17
15
  yield(r)
18
16
  t2 = Time.now
19
17
 
20
- assert timeout == r.client.timeout
18
+ assert timeout == r._client.timeout
21
19
  assert delay <= (t2 - t1)
22
20
  end
23
21
  end
data/test/client_test.rb CHANGED
@@ -1,4 +1,4 @@
1
- require File.expand_path("helper", File.dirname(__FILE__))
1
+ require_relative "helper"
2
2
 
3
3
  class TestClient < Test::Unit::TestCase
4
4
 
@@ -1,6 +1,4 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("helper", File.dirname(__FILE__))
1
+ require_relative "helper"
4
2
 
5
3
  class TestCommandMap < Test::Unit::TestCase
6
4
 
@@ -11,7 +9,7 @@ class TestCommandMap < Test::Unit::TestCase
11
9
 
12
10
  assert_equal 2, r.incr("counter")
13
11
 
14
- r.client.command_map[:incr] = :decr
12
+ r._client.command_map[:incr] = :decr
15
13
 
16
14
  assert_equal 1, r.incr("counter")
17
15
  end
@@ -23,7 +21,7 @@ class TestCommandMap < Test::Unit::TestCase
23
21
  r.idontexist("key")
24
22
  end
25
23
 
26
- r.client.command_map[:idontexist] = :get
24
+ r._client.command_map[:idontexist] = :get
27
25
 
28
26
  assert_equal "value", r.idontexist("key")
29
27
  end
@@ -1,7 +1,5 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("helper", File.dirname(__FILE__))
4
- require "lint/hashes"
1
+ require_relative "helper"
2
+ require_relative "lint/hashes"
5
3
 
6
4
  class TestCommandsOnHashes < Test::Unit::TestCase
7
5
 
@@ -1,7 +1,5 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("helper", File.dirname(__FILE__))
4
- require "lint/hyper_log_log"
1
+ require_relative "helper"
2
+ require_relative "lint/hyper_log_log"
5
3
 
6
4
  class TestCommandsOnHyperLogLog < Test::Unit::TestCase
7
5
 
@@ -18,4 +16,4 @@ class TestCommandsOnHyperLogLog < Test::Unit::TestCase
18
16
  end
19
17
  end
20
18
 
21
- end
19
+ end
@@ -1,7 +1,5 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("helper", File.dirname(__FILE__))
4
- require "lint/lists"
1
+ require_relative "helper"
2
+ require_relative "lint/lists"
5
3
 
6
4
  class TestCommandsOnLists < Test::Unit::TestCase
7
5
 
@@ -1,7 +1,5 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("helper", File.dirname(__FILE__))
4
- require "lint/sets"
1
+ require_relative "helper"
2
+ require_relative "lint/sets"
5
3
 
6
4
  class TestCommandsOnSets < Test::Unit::TestCase
7
5
 
@@ -1,13 +1,26 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("helper", File.dirname(__FILE__))
4
- require "lint/sorted_sets"
1
+ require_relative "helper"
2
+ require_relative "lint/sorted_sets"
5
3
 
6
4
  class TestCommandsOnSortedSets < Test::Unit::TestCase
7
5
 
8
6
  include Helper::Client
9
7
  include Lint::SortedSets
10
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
+
11
24
  def test_zrangebylex
12
25
  target_version "2.8.9" do
13
26
  r.zadd "foo", 0, "aaren"
@@ -1,7 +1,5 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("helper", File.dirname(__FILE__))
4
- require "lint/strings"
1
+ require_relative "helper"
2
+ require_relative "lint/strings"
5
3
 
6
4
  class TestCommandsOnStrings < Test::Unit::TestCase
7
5
 
@@ -82,7 +80,7 @@ class TestCommandsOnStrings < Test::Unit::TestCase
82
80
  end
83
81
 
84
82
  def test_bitop
85
- try_encoding("UTF-8") do
83
+ with_external_encoding("UTF-8") do
86
84
  target_version "2.5.10" do
87
85
  r.set("foo", "a")
88
86
  r.set("bar", "b")