mock_redis 0.25.0 → 0.27.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e4a2d7e6a155059cb97120f7f95c1e992a87a3933be5fe337a443dc0a9ac30df
4
- data.tar.gz: 135172a723e9d5bfb058eec85863387093d56e3a6d7729f28da425f2b239e4bb
3
+ metadata.gz: f61e830490badf3dffbb7dff2ba426f7a359bbc9023243de838e4698318e8aaa
4
+ data.tar.gz: 21bc925aad3d1b8b67e799da8ea8015810a79f40f0d8962a08d32ca9cee9c9bc
5
5
  SHA512:
6
- metadata.gz: 1e1b5cba39d01b11b2c85442c5d9485285bf661316e5196448484bc78dd9d866c3829648cd547ac0996d454f113d054c3bc43728f917740870f5fe191c97b15c
7
- data.tar.gz: bf5d20de1111be19c03cacb2639f303d0ced578656bfc5b4dae4e8cd6e28991be003e7a20702ab6825526fbee6f91ebcd676fbb27c9010792abd37a2e7eab218
6
+ metadata.gz: 01c57f3b8db4fb7835a6cf83cbe67010f3a501945751b7f2c7138b5488f62b72734903592e9bf189b2e41d6c9c6caad4d33799c0158bf5707990cec853860961
7
+ data.tar.gz: 352e3efacf4b47935dcb20f4a427833858fe2229a33568251dc6f670b40ba5a0db22e484f92d5467ff26bd95b42696971211d86b97513efb9d6e65cd21d71740
@@ -20,6 +20,7 @@ rvm:
20
20
  - 2.4
21
21
  - 2.5
22
22
  - 2.6
23
+ - 2.7
23
24
 
24
25
  before_script:
25
26
  - git config --local user.email "travis@travis.ci"
@@ -1,5 +1,28 @@
1
1
  # MockRedis Changelog
2
2
 
3
+ ### 0.27.3
4
+
5
+ * Ensure `ruby2_keywords` dependency is `require`d at runtime
6
+
7
+ ### 0.27.2
8
+
9
+ * Switch `ruby2_keywords` gem from development dependency to runtime dependency
10
+
11
+ ### 0.27.1
12
+
13
+ * Fix missing `ruby2_keywords` gem
14
+ * Allow passing string `offset` to `getbit` ([#203](https://github.com/sds/mock_redis/pull/203))
15
+
16
+ ### 0.27.0
17
+
18
+ * Fix handling of keyword arguments on Ruby 3 ([#199](https://github.com/sds/mock_redis/pull/199))
19
+ * Allow passing string `offset` to `setbit` ([#200](https://github.com/sds/mock_redis/pull/200))
20
+ * Add `connection` method ([#201](https://github.com/sds/mock_redis/pull/201))
21
+
22
+ ### 0.26.0
23
+
24
+ * Add block and count support to `xread` ([#194](https://github.com/sds/mock_redis/pull/194))
25
+
3
26
  ### 0.25.0
4
27
 
5
28
  * Add support for `xread` command ([#190](https://github.com/sds/mock_redis/pull/190))
@@ -1,4 +1,5 @@
1
1
  require 'set'
2
+ require 'ruby2_keywords'
2
3
 
3
4
  require 'mock_redis/assertions'
4
5
  require 'mock_redis/database'
@@ -84,7 +85,7 @@ class MockRedis
84
85
  super || @db.respond_to?(method, include_private)
85
86
  end
86
87
 
87
- def method_missing(method, *args, &block)
88
+ ruby2_keywords def method_missing(method, *args, &block)
88
89
  @db.send(method, *args, &block)
89
90
  end
90
91
 
@@ -0,0 +1,13 @@
1
+ class MockRedis
2
+ module ConnectionMethod
3
+ def connection
4
+ {
5
+ :host => @base.host,
6
+ :port => @base.port,
7
+ :db => @base.db,
8
+ :id => @base.id,
9
+ :location => "#{@base.host}:#{@base.port}"
10
+ }
11
+ end
12
+ end
13
+ end
@@ -11,6 +11,7 @@ require 'mock_redis/info_method'
11
11
  require 'mock_redis/utility_methods'
12
12
  require 'mock_redis/geospatial_methods'
13
13
  require 'mock_redis/stream_methods'
14
+ require 'mock_redis/connection_method'
14
15
 
15
16
  class MockRedis
16
17
  class Database
@@ -24,6 +25,7 @@ class MockRedis
24
25
  include UtilityMethods
25
26
  include GeospatialMethods
26
27
  include StreamMethods
28
+ include ConnectionMethod
27
29
 
28
30
  attr_reader :data, :expire_times
29
31
 
@@ -12,7 +12,7 @@ class MockRedis
12
12
  @db = db
13
13
  end
14
14
 
15
- def method_missing(method, *args, &block)
15
+ ruby2_keywords def method_missing(method, *args, &block)
16
16
  @db.expire_keys
17
17
  @db.send(method, *args, &block)
18
18
  end
@@ -12,7 +12,7 @@ class MockRedis
12
12
  D_R = Math::PI / 180.0
13
13
  EARTH_RADIUS_IN_METERS = 6_372_797.560856
14
14
 
15
- def geoadd(key, *args)
15
+ ruby2_keywords def geoadd(key, *args)
16
16
  points = parse_points(args)
17
17
 
18
18
  scored_points = points.map do |point|
@@ -17,7 +17,7 @@ class MockRedis
17
17
  super || current_db.respond_to?(method, include_private)
18
18
  end
19
19
 
20
- def method_missing(method, *args, &block)
20
+ ruby2_keywords def method_missing(method, *args, &block)
21
21
  current_db.send(method, *args, &block)
22
22
  end
23
23
 
@@ -18,7 +18,7 @@ class MockRedis
18
18
  @pipelined_futures = @pipelined_futures.clone
19
19
  end
20
20
 
21
- def method_missing(method, *args, &block)
21
+ ruby2_keywords def method_missing(method, *args, &block)
22
22
  if in_pipeline?
23
23
  future = MockRedis::Future.new([method, *args], block)
24
24
  @pipelined_futures << future
@@ -25,10 +25,7 @@ class MockRedis
25
25
  @last_id = MockRedis::Stream::Id.new(id, min: @last_id)
26
26
  if @last_id.to_s == '0-0'
27
27
  raise Redis::CommandError,
28
- 'ERR The ID specified in XADD is equal or smaller than ' \
29
- 'the target stream top item'
30
- # TOOD: Redis version 6.0.4, w redis 4.2.1 generates the following error message:
31
- # 'ERR The ID specified in XADD must be greater than 0-0'
28
+ 'ERR The ID specified in XADD must be greater than 0-0'
32
29
  end
33
30
  members.add [@last_id, Hash[values.map { |k, v| [k.to_s, v.to_s] }]]
34
31
  @last_id.to_s
@@ -60,9 +57,12 @@ class MockRedis
60
57
  items
61
58
  end
62
59
 
63
- def read(id)
60
+ def read(id, *opts_in)
61
+ opts = options opts_in, %w[count block]
64
62
  stream_id = MockRedis::Stream::Id.new(id)
65
- members.select { |m| (stream_id < m[0]) }.map { |m| [m[0].to_s, m[1]] }
63
+ items = members.select { |m| (stream_id < m[0]) }.map { |m| [m[0].to_s, m[1]] }
64
+ return items.first(opts['count'].to_i) if opts.key?('count')
65
+ items
66
66
  end
67
67
 
68
68
  def each
@@ -66,14 +66,16 @@ class MockRedis
66
66
  end
67
67
  end
68
68
 
69
- # TODO: Implement count and block parameters
70
- def xread(keys, ids)
69
+ def xread(keys, ids, count: nil, block: nil)
70
+ args = []
71
+ args += ['COUNT', count] if count
72
+ args += ['BLOCK', block.to_i] if block
71
73
  result = {}
72
74
  keys = keys.is_a?(Array) ? keys : [keys]
73
75
  ids = ids.is_a?(Array) ? ids : [ids]
74
76
  keys.each_with_index do |key, index|
75
77
  with_stream_at(key) do |stream|
76
- data = stream.read(ids[index])
78
+ data = stream.read(ids[index], *args)
77
79
  result[key] = data unless data.empty?
78
80
  end
79
81
  end
@@ -93,6 +93,7 @@ class MockRedis
93
93
  def getbit(key, offset)
94
94
  assert_stringy(key)
95
95
 
96
+ offset = offset.to_i
96
97
  offset_of_byte = offset / 8
97
98
  offset_within_byte = offset % 8
98
99
 
@@ -201,18 +202,19 @@ class MockRedis
201
202
  msetnx(*hash.to_a.flatten)
202
203
  end
203
204
 
204
- def set(key, value, options = {})
205
+ # Parameer list required to ensure the ArgumentError is returned correctly
206
+ # rubocop:disable Metrics/ParameterLists
207
+ def set(key, value, ex: nil, px: nil, nx: nil, xx: nil, keepttl: nil)
205
208
  key = key.to_s
206
209
  return_true = false
207
- options = options.dup
208
- if options.delete(:nx)
210
+ if nx
209
211
  if exists?(key)
210
212
  return false
211
213
  else
212
214
  return_true = true
213
215
  end
214
216
  end
215
- if options.delete(:xx)
217
+ if xx
216
218
  if exists?(key)
217
219
  return_true = true
218
220
  else
@@ -221,27 +223,24 @@ class MockRedis
221
223
  end
222
224
  data[key] = value.to_s
223
225
 
224
- duration = options.delete(:ex)
225
- if duration
226
- if duration == 0
226
+ remove_expiration(key) unless keepttl
227
+ if ex
228
+ if ex == 0
227
229
  raise Redis::CommandError, 'ERR invalid expire time in set'
228
230
  end
229
- expire(key, duration)
231
+ expire(key, ex)
230
232
  end
231
233
 
232
- duration = options.delete(:px)
233
- if duration
234
- if duration == 0
234
+ if px
235
+ if px == 0
235
236
  raise Redis::CommandError, 'ERR invalid expire time in set'
236
237
  end
237
- pexpire(key, duration)
238
- end
239
- unless options.empty?
240
- raise ArgumentError, "unknown keyword: #{options.keys[0]}"
238
+ pexpire(key, px)
241
239
  end
242
240
 
243
241
  return_true ? true : 'OK'
244
242
  end
243
+ # rubocop:enable Metrics/ParameterLists
245
244
 
246
245
  def setbit(key, offset, value)
247
246
  assert_stringy(key, 'ERR bit is not an integer or out of range')
@@ -249,6 +248,7 @@ class MockRedis
249
248
 
250
249
  str = data[key] || ''
251
250
 
251
+ offset = offset.to_i
252
252
  offset_of_byte = offset / 8
253
253
  offset_within_byte = offset % 8
254
254
 
@@ -15,7 +15,7 @@ class MockRedis
15
15
  @multi_block_given = false
16
16
  end
17
17
 
18
- def method_missing(method, *args, &block)
18
+ ruby2_keywords def method_missing(method, *args, &block)
19
19
  if in_multi?
20
20
  future = MockRedis::Future.new([method, *args], block)
21
21
  @transaction_futures << future
@@ -2,5 +2,5 @@
2
2
 
3
3
  # Defines the gem version.
4
4
  class MockRedis
5
- VERSION = '0.25.0'
5
+ VERSION = '0.27.3'
6
6
  end
@@ -23,6 +23,8 @@ Gem::Specification.new do |s|
23
23
 
24
24
  s.required_ruby_version = '>= 2.4'
25
25
 
26
+ s.add_runtime_dependency 'ruby2_keywords'
27
+
26
28
  s.add_development_dependency 'redis', '~> 4.2.0'
27
29
  s.add_development_dependency 'rspec', '~> 3.0'
28
30
  s.add_development_dependency 'rspec-its', '~> 1.0'
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe '#connection' do
4
+ let(:redis) { @redises.mock }
5
+
6
+ it 'returns the correct values' do
7
+ redis.connection.should == {
8
+ :host => '127.0.0.1',
9
+ :port => 6379,
10
+ :db => 0,
11
+ :id => 'redis://127.0.0.1:6379/0',
12
+ :location => '127.0.0.1:6379'
13
+ }
14
+ end
15
+ end
@@ -6,7 +6,9 @@ describe '#del(key [, key, ...])' do
6
6
  end
7
7
 
8
8
  before :each do
9
- @redises._gsub(/\d{3}-\d/, '...-.')
9
+ # TODO: Redis appears to be returning a timestamp a few seconds in the future
10
+ # so we're ignoring the last 5 digits (time in milliseconds)
11
+ @redises._gsub(/\d{5}-\d/, '...-.')
10
12
  end
11
13
 
12
14
  it 'returns the number of keys deleted' do
@@ -1,6 +1,8 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe '#set(key, value)' do
4
+ let(:key) { 'mock-redis-test' }
5
+
4
6
  it "responds with 'OK'" do
5
7
  @redises.set('mock-redis-test', 1).should == 'OK'
6
8
  end
@@ -19,26 +21,72 @@ describe '#set(key, value)' do
19
21
  end
20
22
 
21
23
  it 'accepts NX' do
22
- key = 'mock-redis-test'
23
24
  @redises.del(key)
24
25
  @redises.set(key, 1, nx: true).should == true
25
26
  @redises.set(key, 1, nx: true).should == false
26
27
  end
27
28
 
28
29
  it 'accepts XX' do
29
- key = 'mock-redis-test'
30
30
  @redises.del(key)
31
31
  @redises.set(key, 1, xx: true).should == false
32
32
  @redises.set(key, 1).should == 'OK'
33
33
  @redises.set(key, 1, xx: true).should == true
34
34
  end
35
35
 
36
+ it 'sets the ttl to -1' do
37
+ @redises.set(key, 1)
38
+ expect(@redises.ttl(key)).to eq(-1)
39
+ end
40
+
41
+ context 'with an expiry time' do
42
+ before :each do
43
+ Timecop.freeze
44
+ @redises.set(key, 1, ex: 90)
45
+ end
46
+
47
+ after :each do
48
+ @redises.del(key)
49
+ Timecop.return
50
+ end
51
+
52
+ it 'has the TTL set' do
53
+ expect(@redises.ttl(key)).to eq 90
54
+ end
55
+
56
+ it 'resets the TTL without keepttl' do
57
+ expect do
58
+ @redises.set(key, 2)
59
+ end.to change { @redises.ttl(key) }.from(90).to(-1)
60
+ end
61
+
62
+ it 'does not change the TTL with keepttl: true' do
63
+ expect do
64
+ @redises.set(key, 2, keepttl: true)
65
+ end.not_to change { @redises.ttl(key) }.from(90)
66
+ end
67
+ end
68
+
69
+ it 'accepts KEEPTTL' do
70
+ expect(@redises.set(key, 1, keepttl: true)).to eq 'OK'
71
+ end
72
+
73
+ it 'does not set TTL without ex' do
74
+ @redises.set(key, 1)
75
+ expect(@redises.ttl(key)).to eq(-1)
76
+ end
77
+
78
+ it 'sets the TTL' do
79
+ Timecop.freeze do
80
+ @redises.set(key, 1, ex: 90)
81
+ expect(@redises.ttl(key)).to eq 90
82
+ end
83
+ end
84
+
36
85
  it 'raises on unknown options' do
37
- key = 'mock-redis-test'
38
86
  @redises.del(key)
39
87
  expect do
40
88
  @redises.set(key, 1, logger: :something)
41
- end.to raise_error(ArgumentError, 'unknown keyword: logger')
89
+ end.to raise_error(ArgumentError, /unknown keyword/)
42
90
  end
43
91
 
44
92
  context '[mock only]' do
@@ -52,7 +100,6 @@ describe '#set(key, value)' do
52
100
  end
53
101
 
54
102
  it 'accepts EX seconds' do
55
- key = 'mock-redis-test'
56
103
  @mock.set(key, 1, ex: 1).should == 'OK'
57
104
  @mock.get(key).should_not be_nil
58
105
  Time.stub(:now).and_return(@now + 2)
@@ -60,7 +107,6 @@ describe '#set(key, value)' do
60
107
  end
61
108
 
62
109
  it 'accepts PX milliseconds' do
63
- key = 'mock-redis-test'
64
110
  @mock.set(key, 1, px: 500).should == 'OK'
65
111
  @mock.get(key).should_not be_nil
66
112
  Time.stub(:now).and_return(@now + 300 / 1000.to_f)
@@ -7,11 +7,14 @@ describe '#xadd("mystream", { f1: "v1", f2: "v2" }, id: "0-0", maxlen: 1000, app
7
7
  end
8
8
 
9
9
  before :each do
10
- @redises._gsub(/\d{3}-\d/, '...-.')
10
+ # TODO: Redis appears to be returning a timestamp a few seconds in the future
11
+ # so we're ignoring the last 5 digits (time in milliseconds)
12
+ @redises._gsub(/\d{5}-\d/, '....-.')
11
13
  end
12
14
 
13
15
  it 'returns an id based on the timestamp' do
14
16
  t = Time.now.to_i
17
+ id = @redises.xadd(@key, key: 'value')
15
18
  expect(@redises.xadd(@key, key: 'value')).to match(/#{t}\d{3}-0/)
16
19
  end
17
20
 
@@ -52,10 +55,7 @@ describe '#xadd("mystream", { f1: "v1", f2: "v2" }, id: "0-0", maxlen: 1000, app
52
55
  expect { @redises.xadd('mock-redis-test:unknown-stream', { key: 'value' }, id: '0') }
53
56
  .to raise_error(
54
57
  Redis::CommandError,
55
- 'ERR The ID specified in XADD is equal or smaller than the target ' \
56
- 'stream top item'
57
- # TOOD: Redis version 6.0.4, w redis 4.2.1 generates the following error message:
58
- # 'ERR The ID specified in XADD must be greater than 0-0'
58
+ 'ERR The ID specified in XADD must be greater than 0-0'
59
59
  )
60
60
  end
61
61
 
@@ -7,7 +7,9 @@ describe '#xlen(key)' do
7
7
  end
8
8
 
9
9
  before :each do
10
- @redises._gsub(/\d{3}-\d/, '...-.')
10
+ # TODO: Redis appears to be returning a timestamp a few seconds in the future
11
+ # so we're ignoring the last 5 digits (time in milliseconds)
12
+ @redises._gsub(/\d{5}-\d/, '...-.')
11
13
  end
12
14
 
13
15
  it 'returns the number of items in the stream' do
@@ -47,4 +47,20 @@ describe '#xread(keys, ids)' do
47
47
  expect(@redises.xread([@key, @key1], %w[1234567891234-2 1234567891234-1]))
48
48
  .to eq({ @key1 => [['1234567891234-2', { 'key1' => 'value2' }]] })
49
49
  end
50
+
51
+ it 'supports the block parameter' do
52
+ @redises.xadd(@key, { key: 'value' }, id: '1234567891234-0')
53
+ expect(@redises.xread(@key, '0-0', block: 1000))
54
+ .to eq({ @key => [['1234567891234-0', { 'key' => 'value' }]] })
55
+ end
56
+
57
+ it 'limits results with count' do
58
+ @redises.xadd(@key, { key: 'value' }, id: '1234567891234-0')
59
+ @redises.xadd(@key, { key: 'value' }, id: '1234567891234-1')
60
+ @redises.xadd(@key, { key: 'value' }, id: '1234567891234-2')
61
+ expect(@redises.xread(@key, '0-0', count: 1))
62
+ .to eq({ @key => [['1234567891234-0', { 'key' => 'value' }]] })
63
+ expect(@redises.xread(@key, '1234567891234-0', count: 1))
64
+ .to eq({ @key => [['1234567891234-1', { 'key' => 'value' }]] })
65
+ end
50
66
  end
@@ -40,8 +40,6 @@ end
40
40
  RSpec.configure do |config|
41
41
  config.expect_with :rspec do |c|
42
42
  c.syntax = [:expect, :should]
43
- # Allow for a large output so we can debug error messages
44
- c.max_formatted_output_length = 1_000_000
45
43
  end
46
44
 
47
45
  config.mock_with :rspec do |c|
@@ -23,7 +23,7 @@ class RedisMultiplexer < BlankSlate
23
23
  @gsub_from = @gsub_to = ''
24
24
  end
25
25
 
26
- def method_missing(method, *args, &blk)
26
+ ruby2_keywords def method_missing(method, *args, &blk)
27
27
  # If we're in a Redis command that accepts a block, and we execute more
28
28
  # redis commands, ONLY execute them on the Redis implementation that the
29
29
  # block came from.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mock_redis
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.25.0
4
+ version: 0.27.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shane da Silva
@@ -9,8 +9,22 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-06-25 00:00:00.000000000 Z
12
+ date: 2021-01-10 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: ruby2_keywords
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
14
28
  - !ruby/object:Gem::Dependency
15
29
  name: redis
16
30
  requirement: !ruby/object:Gem::Requirement
@@ -90,6 +104,7 @@ files:
90
104
  - Rakefile
91
105
  - lib/mock_redis.rb
92
106
  - lib/mock_redis/assertions.rb
107
+ - lib/mock_redis/connection_method.rb
93
108
  - lib/mock_redis/database.rb
94
109
  - lib/mock_redis/exceptions.rb
95
110
  - lib/mock_redis/expire_wrapper.rb
@@ -126,6 +141,7 @@ files:
126
141
  - spec/commands/brpop_spec.rb
127
142
  - spec/commands/brpoplpush_spec.rb
128
143
  - spec/commands/connected_spec.rb
144
+ - spec/commands/connection_spec.rb
129
145
  - spec/commands/dbsize_spec.rb
130
146
  - spec/commands/decr_spec.rb
131
147
  - spec/commands/decrby_spec.rb
@@ -294,7 +310,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
294
310
  - !ruby/object:Gem::Version
295
311
  version: '0'
296
312
  requirements: []
297
- rubygems_version: 3.1.1
313
+ rubygems_version: 3.1.4
298
314
  signing_key:
299
315
  specification_version: 4
300
316
  summary: Redis mock that just lives in memory; useful for testing.
@@ -311,6 +327,7 @@ test_files:
311
327
  - spec/commands/brpop_spec.rb
312
328
  - spec/commands/brpoplpush_spec.rb
313
329
  - spec/commands/connected_spec.rb
330
+ - spec/commands/connection_spec.rb
314
331
  - spec/commands/dbsize_spec.rb
315
332
  - spec/commands/decr_spec.rb
316
333
  - spec/commands/decrby_spec.rb