Skip to content

Commit 9477e66

Browse files
committed
Support Redis-rb v5
1 parent ab8638b commit 9477e66

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+415
-269
lines changed

lib/mock_redis.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
require 'set'
22

33
require 'mock_redis/assertions'
4+
require 'mock_redis/error'
45
require 'mock_redis/database'
56
require 'mock_redis/expire_wrapper'
67
require 'mock_redis/future'

lib/mock_redis/assertions.rb

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,27 @@
1+
require 'mock_redis/error'
2+
13
class MockRedis
4+
DUMP_TYPES = RedisClient::RESP3::DUMP_TYPES
5+
26
module Assertions
37
private
48

59
def assert_has_args(args, command)
6-
unless args.any?
7-
raise Redis::CommandError,
8-
"ERR wrong number of arguments for '#{command}' command"
10+
if args.empty?
11+
raise Error.command_error(
12+
"ERR wrong number of arguments for '#{command}' command",
13+
self
14+
)
15+
end
16+
end
17+
18+
def assert_type(*args)
19+
args.each do |arg|
20+
DUMP_TYPES.fetch(arg.class) do |unexpected_class|
21+
unless DUMP_TYPES.keys.find { |t| t > unexpected_class }
22+
raise TypeError, "Unsupported command argument type: #{unexpected_class}"
23+
end
24+
end
925
end
1026
end
1127
end

lib/mock_redis/database.rb

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -95,32 +95,33 @@ def echo(msg)
9595
end
9696

9797
def expire(key, seconds, nx: nil, xx: nil, lt: nil, gt: nil) # rubocop:disable Metrics/ParameterLists
98-
assert_valid_integer(seconds)
98+
seconds = Integer(seconds)
9999

100100
pexpire(key, seconds.to_i * 1000, nx: nx, xx: xx, lt: lt, gt: gt)
101101
end
102102

103103
def pexpire(key, ms, nx: nil, xx: nil, lt: nil, gt: nil) # rubocop:disable Metrics/ParameterLists
104-
assert_valid_integer(ms)
104+
ms = Integer(ms)
105105

106106
now, miliseconds = @base.now
107107
now_ms = (now * 1000) + miliseconds
108108
pexpireat(key, now_ms + ms.to_i, nx: nx, xx: xx, lt: lt, gt: gt)
109109
end
110110

111111
def expireat(key, timestamp, nx: nil, xx: nil, lt: nil, gt: nil) # rubocop:disable Metrics/ParameterLists
112-
assert_valid_integer(timestamp)
112+
timestamp = Integer(timestamp)
113113

114114
pexpireat(key, timestamp.to_i * 1000, nx: nx, xx: xx, lt: lt, gt: gt)
115115
end
116116

117117
def pexpireat(key, timestamp_ms, nx: nil, xx: nil, lt: nil, gt: nil) # rubocop:disable Metrics/ParameterLists
118-
assert_valid_integer(timestamp_ms)
118+
timestamp_ms = Integer(timestamp_ms)
119119

120120
if nx && gt || gt && lt || lt && nx || nx && xx
121-
raise Redis::CommandError, <<~TXT.chomp
122-
ERR NX and XX, GT or LT options at the same time are not compatible
123-
TXT
121+
raise Error.command_error(
122+
'ERR NX and XX, GT or LT options at the same time are not compatible',
123+
self
124+
)
124125
end
125126

126127
return false unless exists?(key)
@@ -157,7 +158,7 @@ def dump(key)
157158

158159
def restore(key, ttl, value, replace: false)
159160
if !replace && exists?(key)
160-
raise Redis::CommandError, 'BUSYKEY Target key name already exists.'
161+
raise Error.command_error('BUSYKEY Target key name already exists.', self)
161162
end
162163
data[key] = Marshal.load(value) # rubocop:disable Security/MarshalLoad
163164
if ttl > 0
@@ -211,7 +212,7 @@ def randomkey
211212

212213
def rename(key, newkey)
213214
unless data.include?(key)
214-
raise Redis::CommandError, 'ERR no such key'
215+
raise Error.command_error('ERR no such key', self)
215216
end
216217

217218
if key != newkey
@@ -227,7 +228,7 @@ def rename(key, newkey)
227228

228229
def renamenx(key, newkey)
229230
unless data.include?(key)
230-
raise Redis::CommandError, 'ERR no such key'
231+
raise Error.command_error('ERR no such key', self)
231232
end
232233

233234
if exists?(newkey)
@@ -301,19 +302,13 @@ def eval(*args); end
301302

302303
private
303304

304-
def assert_valid_integer(integer)
305-
unless looks_like_integer?(integer.to_s)
306-
raise Redis::CommandError, 'ERR value is not an integer or out of range'
307-
end
308-
integer
309-
end
310-
311305
def assert_valid_timeout(timeout)
312-
if !looks_like_integer?(timeout.to_s)
313-
raise Redis::CommandError, 'ERR timeout is not an integer or out of range'
314-
elsif timeout < 0
315-
raise Redis::CommandError, 'ERR timeout is negative'
306+
timeout = Integer(timeout)
307+
308+
if timeout < 0
309+
raise ArgumentError, 'time interval must not be negative'
316310
end
311+
317312
timeout
318313
end
319314

@@ -347,7 +342,7 @@ def has_expiration?(key)
347342
end
348343

349344
def looks_like_integer?(str)
350-
str =~ /^-?\d+$/
345+
!!Integer(str) rescue false
351346
end
352347

353348
def looks_like_float?(str)

lib/mock_redis/error.rb

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
class MockRedis
2+
module Error
3+
module_function
4+
5+
def build(error_class, message, database)
6+
connection = database.connection
7+
url = "redis://#{connection[:host]}:#{connection[:port]}"
8+
error_class.new("#{message} (#{url})")
9+
end
10+
11+
def wrong_type_error(database)
12+
build(
13+
Redis::WrongTypeError,
14+
'WRONGTYPE Operation against a key holding the wrong kind of value',
15+
database
16+
)
17+
end
18+
19+
def syntax_error(database)
20+
command_error('ERR syntax error', database)
21+
end
22+
23+
def command_error(message, database)
24+
build(Redis::CommandError, message, database)
25+
end
26+
end
27+
end

lib/mock_redis/geospatial_methods.rb

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
require 'mock_redis/error'
2+
13
class MockRedis
24
module GeospatialMethods
35
LNG_RANGE = (-180..180)
@@ -81,8 +83,7 @@ def parse_points(args)
8183
points = args.each_slice(3).to_a
8284

8385
if points.last.size != 3
84-
raise Redis::CommandError,
85-
"ERR wrong number of arguments for 'geoadd' command"
86+
raise Error.command_error("ERR wrong number of arguments for 'geoadd' command", self)
8687
end
8788

8889
points.map do |point|
@@ -97,13 +98,15 @@ def parse_point(point)
9798
unless LNG_RANGE.include?(lng) && LAT_RANGE.include?(lat)
9899
lng = format('%<long>.6f', long: lng)
99100
lat = format('%<lat>.6f', lat: lat)
100-
raise Redis::CommandError,
101-
"ERR invalid longitude,latitude pair #{lng},#{lat}"
101+
raise Error.command_error(
102+
"ERR invalid longitude,latitude pair #{lng},#{lat}",
103+
self
104+
)
102105
end
103106

104107
{ key: point[2], lng: lng, lat: lat }
105108
rescue ArgumentError
106-
raise Redis::CommandError, 'ERR value is not a valid float'
109+
raise Error.command_error('ERR value is not a valid float', self)
107110
end
108111

109112
# Returns ZSET score for passed coordinates
@@ -212,8 +215,7 @@ def parse_unit(unit)
212215
unit = unit.to_sym
213216
return UNITS[unit] if UNITS[unit]
214217

215-
raise Redis::CommandError,
216-
'ERR unsupported unit provided. please use m, km, ft, mi'
218+
raise Error.command_error('ERR unsupported unit provided. please use m, km, ft, mi', self)
217219
end
218220

219221
def geohash_distance(lng1d, lat1d, lng2d, lat2d)

0 commit comments

Comments
 (0)