Skip to content

Commit

Permalink
first pass of changes for resolving issue
Browse files Browse the repository at this point in the history
  • Loading branch information
CoderMiguel committed Jan 4, 2024
1 parent 3974db9 commit 012d96f
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 46 deletions.
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ gem 'rubocop', '1.44.1'

gem 'simplecov', '~> 0.22.0'
gem 'simplecov-lcov', '~> 0.8.0'
gem 'redis', '>= 5.0.0'
32 changes: 14 additions & 18 deletions lib/mock_redis/set_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,16 @@ module SetMethods
include UtilityMethods

def sadd(key, members)
members_class = members.class
members = Array(members).map(&:to_s)
assert_has_args(members, 'sadd')

with_set_at(key) do |s|
size_before = s.size
if members.size > 1
members.reverse_each { |m| s << m }
s.size - size_before
size_after(s) { members.reverse_each { |m| s << m } }
elsif redis_gem_v5?
size_after(s) { s.add?(members.first) }
else
added = !!s.add?(members.first)
if members_class == Array
s.size - size_before
else
added
end
!!s.add?(members.first)
end
end
end
Expand Down Expand Up @@ -125,14 +119,13 @@ def srandmember(key, count = nil)
end

def srem(key, members)
members = Array(members).map(&:to_s)

with_set_at(key) do |s|
if members.is_a?(Array)
orig_size = s.size
members = members.map(&:to_s)
s.delete_if { |m| members.include?(m) }
orig_size - s.size
if members.size > 1 || redis_gem_v5?
size_after(s) { s.delete_if { |m| members.include?(m) } }
else
!!s.delete?(members.to_s)
!!s.delete?(members.first)
end
end
end
Expand Down Expand Up @@ -190,9 +183,12 @@ def sety?(key)
def assert_sety(key)
unless sety?(key)
# Not the most helpful error, but it's what redis-rb barfs up
raise Redis::CommandError,
'WRONGTYPE Operation against a key holding the wrong kind of value'
raise wrong_type_error, 'WRONGTYPE Operation against a key holding the wrong kind of value'
end
end

def wrong_type_error
redis_gem_v5? ? Redis::WrongTypeError : Redis::CommandError
end
end
end
10 changes: 10 additions & 0 deletions lib/mock_redis/utility_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,15 @@ def left_pad(str, size)

str
end

def redis_gem_v5?
Redis::VERSION.to_i == 5
end

def size_after(obj, &blk)
size_before = obj.size
yield
(obj.size - size_before).abs
end
end
end
27 changes: 17 additions & 10 deletions spec/commands/srem_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,31 @@
@redises.sadd(@key, 'ernie')
end

it 'returns true if member is in the set' do
expect(@redises.srem(@key, 'bert')).to eq(true)
end
context "adapts to redis-rd version 4 and 5 outputs" do
include MockRedis::UtilityMethods

let(:positive_response) { redis_gem_v5? ? 1 : true }
let(:negative_response) { redis_gem_v5? ? 0 : false }

it 'returns positive response if member is in the set' do
expect(@redises.srem(@key, 'bert')).to eq(positive_response)
end

it 'returns false if member is not in the set' do
expect(@redises.srem(@key, 'cookiemonster')).to eq(false)
it 'returns negative response if member is not in the set' do
expect(@redises.srem(@key, 'cookiemonster')).to eq(negative_response)
end

it 'stringifies member' do
@redises.sadd(@key, '1')
expect(@redises.srem(@key, 1)).to eq(positive_response)
end
end

it 'removes member from the set' do
@redises.srem(@key, 'ernie')
expect(@redises.smembers(@key)).to eq(['bert'])
end

it 'stringifies member' do
@redises.sadd(@key, '1')
expect(@redises.srem(@key, 1)).to eq(true)
end

it 'cleans up empty sets' do
@redises.smembers(@key).each { |m| @redises.srem(@key, m) }
expect(@redises.get(@key)).to be_nil
Expand Down
39 changes: 25 additions & 14 deletions spec/support/redis_multiplexer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class RedisMultiplexer < BlankSlate
def initialize(*a)
super()
@mock_redis = MockRedis.new(*a)
Redis.exists_returns_integer = true
configure_redis
@real_redis = Redis.new(*a)
_gsub_clear
end
Expand Down Expand Up @@ -55,25 +55,25 @@ def _gsub_clear
elsif !equalish?(mock_retval, real_retval) && !mock_error && !real_error
# no exceptions, just different behavior
raise MismatchedResponse,
"Mock failure: responses not equal.\n" \
"Redis.#{method}(#{args.inspect}) returned #{real_retval.inspect}\n" \
"MockRedis.#{method}(#{args.inspect}) returned #{mock_retval.inspect}\n"
"Mock failure: responses not equal.\n" \
"Redis.#{method}(#{args.inspect}) returned #{real_retval.inspect}\n" \
"MockRedis.#{method}(#{args.inspect}) returned #{mock_retval.inspect}\n"
elsif !mock_error && real_error
raise MismatchedResponse,
"Mock failure: didn't raise an error when it should have.\n" \
"Redis.#{method}(#{args.inspect}) raised #{real_error.inspect}\n" \
"MockRedis.#{method}(#{args.inspect}) raised nothing " \
"and returned #{mock_retval.inspect}"
"Mock failure: didn't raise an error when it should have.\n" \
"Redis.#{method}(#{args.inspect}) raised #{real_error.inspect}\n" \
"MockRedis.#{method}(#{args.inspect}) raised nothing " \
"and returned #{mock_retval.inspect}"
elsif !real_error && mock_error
raise MismatchedResponse,
"Mock failure: raised an error when it shouldn't have.\n" \
"Redis.#{method}(#{args.inspect}) returned #{real_retval.inspect}\n" \
"MockRedis.#{method}(#{args.inspect}) raised #{mock_error.inspect}"
"Mock failure: raised an error when it shouldn't have.\n" \
"Redis.#{method}(#{args.inspect}) returned #{real_retval.inspect}\n" \
"MockRedis.#{method}(#{args.inspect}) raised #{mock_error.inspect}"
elsif mock_error && real_error && !equalish?(mock_error, real_error)
raise MismatchedResponse,
"Mock failure: raised the wrong error.\n" \
"Redis.#{method}(#{args.inspect}) raised #{real_error.inspect}\n" \
"MockRedis.#{method}(#{args.inspect}) raised #{mock_error.inspect}"
"Mock failure: raised the wrong error.\n" \
"Redis.#{method}(#{args.inspect}) raised #{real_error.inspect}\n" \
"MockRedis.#{method}(#{args.inspect}) raised #{mock_error.inspect}"
end

raise mock_error if mock_error
Expand Down Expand Up @@ -121,4 +121,15 @@ def catch_errors
rescue StandardError => e
[nil, e]
end

private

def configure_redis
case Redis::VERSION.to_i
when 5
# do nothing
else
Redis.exists_returns_integer = true
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
key = 'mock-redis-test:not-a-string'

method = method_from_description(example)
args = args_for_method(method).unshift(key)
args = [key, args_for_method(method)]

@redises.set(key, '')
expect do
@redises.send(method, *args)
end.to raise_error(defined?(default_error) ? default_error : RuntimeError)
end.to raise_error(defined?(default_error) ? default_error : Redis::BaseError)
expect(@redises.get(key)).to eq('')
end
end
4 changes: 2 additions & 2 deletions spec/support/shared_examples/only_operates_on_sets.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
key = 'mock-redis-test:set-only'

method = method_from_description(example)
args = args_for_method(method).unshift(key)
args = [key, args_for_method(method)]

@redises.set(key, 1)
expect do
@redises.send(method, *args)
end.to raise_error(RuntimeError)
end.to raise_error(Redis::BaseError)
end

it_should_behave_like 'does not remove empty strings on error'
Expand Down

0 comments on commit 012d96f

Please sign in to comment.