Coder Social home page Coder Social logo

fakeredis's Introduction

FakeRedis

Build Status

This a fake implementation of redis-rb for machines without Redis or test environments

Installation

Install the gem:

gem install fakeredis

Add it to your Gemfile:

gem "fakeredis"

Versions

FakeRedis currently supports redis-rb v3 or later, if you are using redis-rb v2.2 install the version 0.3.x:

gem install fakeredis -v "~> 0.3.0"

or use the branch 0-3-x on your Gemfile:

gem "fakeredis", :git => "git://github.com/guilleiguaran/fakeredis.git", :branch => "0-3-x"

Usage

You can use FakeRedis without any changes:

    require "fakeredis"

    redis = Redis.new

    >> redis.set "foo", "bar"
    => "OK"

    >> redis.get "foo"
    => "bar"

Read redis-rb documentation and Redis homepage for more info about commands

Usage with RSpec

Require this either in your Gemfile or in RSpec's support scripts. So either:

# Gemfile
group :test do
  gem "rspec"
  gem "fakeredis", :require => "fakeredis/rspec"
end

Or:

# spec/support/fakeredis.rb
require 'fakeredis/rspec'

Usage with Minitest

Require this either in your Gemfile or in Minitest's support scripts. So either:

# Gemfile
group :test do
  gem "minitest"
  gem "fakeredis", :require => "fakeredis/minitest"
end

Or:

# test/test_helper.rb (or test/minitest_config.rb)
require 'fakeredis/minitest'

Acknowledgements

Thanks to all contributors.

Contributing to FakeRedis

  • Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
  • Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
  • Fork the project
  • Start a feature/bugfix branch
  • Commit and push until you are happy with your contribution
  • Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
  • Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.

Copyright

Copyright (c) 2011-2023 Guillermo Iguaran. See LICENSE for further details.

fakeredis's People

Contributors

agau4779 avatar andrehjr avatar artygus avatar caius avatar caulfield avatar dim avatar dpick avatar fatkodima avatar gfx avatar guilleiguaran avatar jnoconor avatar joaofagundes avatar jredville avatar kellyfelkins avatar larrylv avatar magicguitarist avatar maxim-filimonov avatar mkdynamic avatar morgoth avatar obrie avatar redsquirrel avatar ryanswood avatar sjweil9 avatar stevenwilkin avatar strech avatar tfausak avatar tiagotex avatar timherby avatar tubaxenor avatar zlx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fakeredis's Issues

Another discrepancy noticed

Using redis gem:

redis = Redis.new
redis.mset(["511c47838712ff1907000006", "", "511c47838712ff1907000007", "", "511c47838712ff1907000008", "", "511c47838712ff1907000009", ""])
=> "OK"
redis.mget(["511c47838712ff1907000006", "511c47838712ff1907000007", "511c47838712ff1907000008", "511c47838712ff1907000009"])
=> ["", "", "", ""]

Using fake redis:

fake_redis = Redis.new
fake_redis.mset(["511c47838712ff1907000006", "", "511c47838712ff1907000007", "", "511c47838712ff1907000008", "", "511c47838712ff1907000009", ""])
=>  "OK"
fake_redis.mget(["511c47838712ff1907000006", "511c47838712ff1907000007", "511c47838712ff1907000008", "511c47838712ff1907000009"])
=> [nil]

If I use the ruby splat operator then fake redis works.

Issue with sorted sets

When using Redis:

redis.flushall
=> "OK"
redis.zadd "key1", 10.0, "member1"
=> true
redis.zremrangebyscore "key1", "-inf", "+inf"
=> 1
redis.zscore "key1", "member1"
=> nil

When using Fakeredis:

fake_redis.flushall
=> {}
fake_redis.zadd "key1", 10.0, "member1"
=> true
fake_redis.zremrangebyscore "key1", "-inf", "+inf"
=> 0
fake_redis.zscore "key1", "member1"
ArgumentError: invalid value for Float(): ""
    from /Users/kapilisrani/.rbenv/versions/1.9.3-p286/lib/ruby/gems/1.9.1/gems/redis-3.0.2/lib/redis.rb:2212:in `Float'
    from /Users/kapilisrani/.rbenv/versions/1.9.3-p286/lib/ruby/gems/1.9.1/gems/redis-3.0.2/lib/redis.rb:2212:in `_floatify'
    from /Users/kapilisrani/.rbenv/versions/1.9.3-p286/lib/ruby/gems/1.9.1/gems/redis-3.0.2/lib/redis.rb:1366:in `block (2 levels) in zscore'
    from /Users/kapilisrani/.rbenv/versions/1.9.3-p286/lib/ruby/gems/1.9.1/gems/redis-3.0.2/lib/redis/client.rb:88:in `call'
    from /Users/kapilisrani/.rbenv/versions/1.9.3-p286/lib/ruby/gems/1.9.1/gems/redis-3.0.2/lib/redis/client.rb:88:in `call'
    from /Users/kapilisrani/.rbenv/versions/1.9.3-p286/lib/ruby/gems/1.9.1/gems/newrelic-redis-1.3.2/lib/newrelic_redis/instrumentation.rb:37:in `block in call_with_newrelic_trace'
    from /Users/kapilisrani/.rbenv/versions/1.9.3-p286/lib/ruby/gems/1.9.1/gems/newrelic_rpm-3.5.5.38/lib/new_relic/agent/method_tracer.rb:240:in `trace_execution_scoped'
    from /Users/kapilisrani/.rbenv/versions/1.9.3-p286/lib/ruby/gems/1.9.1/gems/newrelic-redis-1.3.2/lib/newrelic_redis/instrumentation.rb:33:in `call_with_newrelic_trace'
    from /Users/kapilisrani/.rbenv/versions/1.9.3-p286/lib/ruby/gems/1.9.1/gems/redis-3.0.2/lib/redis.rb:1365:in `block in zscore'
    from /Users/kapilisrani/.rbenv/versions/1.9.3-p286/lib/ruby/gems/1.9.1/gems/redis-3.0.2/lib/redis.rb:36:in `block in synchronize'
    from /Users/kapilisrani/.rbenv/versions/1.9.3-p286/lib/ruby/1.9.1/monitor.rb:211:in `mon_synchronize'
    from /Users/kapilisrani/.rbenv/versions/1.9.3-p286/lib/ruby/gems/1.9.1/gems/redis-3.0.2/lib/redis.rb:36:in `synchronize'
    from /Users/kapilisrani/.rbenv/versions/1.9.3-p286/lib/ruby/gems/1.9.1/gems/redis-3.0.2/lib/redis.rb:1364:in `zscore'
    from (irb):213
    from /Users/kapilisrani/.rbenv/versions/1.9.3-p286/lib/ruby/gems/1.9.1/gems/railties-3.2.11/lib/rails/commands/console.rb:47:in `start'
    from /Users/kapilisrani/.rbenv/versions/1.9.3-p286/lib/ruby/gems/1.9.1/gems/railties-3.2.11/lib/rails/commands/console.rb:8:in `start'
    from /Users/kapilisrani/.rbenv/versions/1.9.3-p286/lib/ruby/gems/1.9.1/gems/railties-3.2.11/lib/rails/commands.rb:41:in `<top (required)>'
    from script/rails:11:in `require'

Request: Add ZRANGEBYLEX and ZREVRANGEBYLEX

Hi,

I'm using zrangebylex in one of my methods that I'm trying to test and after looking through the redis source code I noticed that this command isn't included in fakeredis.

Thanks!

Redis & fakeredis discrepancy issue

This is using the fakeredis master branch.

Using redis gem 'redis', '3.0.2'

irb(main):008:0> redis.zadd "key1", 10.0, "member1"
=> true
irb(main):009:0> redis.zrem "key1", ["member1"]
=> 1
irb(main):010:0> redis.zscore "key1", "member1"
=> nil

Using fakeredis gem 'fakeredis', git: 'git://github.com/guilleiguaran/fakeredis.git', require: 'fakeredis/rspec'

irb(main):006:0> redis.zadd "key1", 10.0, "member1"
=> true
irb(main):007:0> redis.zrem "key1", ["member1"]
=> 0
irb(main):008:0> redis.zscore "key1", "member1"
=> 10.0

Discrepancy between redis & fakeredis

Noticed this difference when using mongo bson object id. You can use the "bson" gem to try this.

When using redis:

redis = Redis.new
redis.set(BSON::ObjectId.new, "some_value")
=> "OK"
redis.keys
=> ["511c40358712ff0711000001"]

When using fake redis:

fake_redis = Redis.new
fake_redis.set(BSON::ObjectId.new, "some_value")
=> "OK"
fake_redis.keys
=> []

inconsistent spec results

Given these specs:

describe 'MultiAccountStore' do
  let(:store) { MultiAccountStore.new(@redis) }
  let(:user_1) { FactoryGirl.create(:user)}
  let(:users) { [user_1, user_2] }
  let(:ip) { '1.1.1.1' }

  before(:each) do
    @redis = REDIS
  end

  context '.store' do
    it 'persists the data' do
      store.ips.size.should eql(0)
      store.store(ip, users)
      store.ips.size.should eql(1)
    end

    it 'does not persist data when there is a single User' do
      store.store(ip, [user_1])
      store.ips.size.should eql(0)
    end
  end
end

when I run the specs, they randomly pass or fail. The failing lines are the store.ips.size.should eql(0) Which, instead of being empty (which they should since the redis instance is restarted at every test), still contains some left over data.

NOTE: I did add:

    gem "fakeredis", :require => "fakeredis/rspec"

I must have ran the file 100 times now and I can't find any pattern in the success/failure rates.

Redis 3.1.0 support

Do you have any plans on supporting Redis 3.1.0? May be fakeredis even won't break with 3.1.0, but there's ~> 3.0.0 dependency.

fakeredis can't work with resque scheduler

QUEUE=* bundle exec rake resque:scheduler

rake aborted!
undefined method `zrangebyscore' for #<Redis::Connection::Memory:0xb92ac38>
/home/saberma/.rvm/gems/ruby-1.9.3-p0/gems/fakeredis-0.2.2/lib/redis/connection/memory.rb:93:in `write'
/home/saberma/.rvm/gems/ruby-1.9.3-p0/gems/redis-2.2.2/lib/redis/client.rb:139:in `block (3 levels) in process'
/home/saberma/.rvm/gems/ruby-1.9.3-p0/gems/redis-2.2.2/lib/redis/client.rb:138:in `each'
/home/saberma/.rvm/gems/ruby-1.9.3-p0/gems/redis-2.2.2/lib/redis/client.rb:138:in `block (2 levels) in process'
/home/saberma/.rvm/gems/ruby-1.9.3-p0/gems/redis-2.2.2/lib/redis/client.rb:250:in `ensure_connected'
/home/saberma/.rvm/gems/ruby-1.9.3-p0/gems/redis-2.2.2/lib/redis/client.rb:137:in `block in process'
/home/saberma/.rvm/gems/ruby-1.9.3-p0/gems/redis-2.2.2/lib/redis/client.rb:206:in `logging'
/home/saberma/.rvm/gems/ruby-1.9.3-p0/gems/redis-2.2.2/lib/redis/client.rb:136:in `process'
/home/saberma/.rvm/gems/ruby-1.9.3-p0/gems/redis-2.2.2/lib/redis/client.rb:46:in `call'
/home/saberma/.rvm/gems/ruby-1.9.3-p0/gems/redis-2.2.2/lib/redis.rb:573:in `block in zrangebyscore'
/home/saberma/.rvm/rubies/ruby-1.9.3-p0/lib/ruby/1.9.1/monitor.rb:211:in `mon_synchronize'
/home/saberma/.rvm/gems/ruby-1.9.3-p0/gems/redis-2.2.2/lib/redis.rb:572:in `zrangebyscore'
/home/saberma/.rvm/gems/ruby-1.9.3-p0/gems/redis-namespace-1.0.3/lib/redis/namespace.rb:213:in `method_missing'
/home/saberma/.rvm/gems/ruby-1.9.3-p0/bundler/gems/resque-scheduler-54075b0f5492/lib/resque_scheduler.rb:170:in `next_delayed_timestamp'
/home/saberma/.rvm/gems/ruby-1.9.3-p0/bundler/gems/resque-scheduler-54075b0f5492/lib/resque/scheduler.rb:147:in `handle_delayed_items'
/home/saberma/.rvm/gems/ruby-1.9.3-p0/bundler/gems/resque-scheduler-54075b0f5492/lib/resque/scheduler.rb:51:in `block in run'
/home/saberma/.rvm/gems/ruby-1.9.3-p0/bundler/gems/resque-scheduler-54075b0f5492/lib/resque/scheduler.rb:49:in `loop'
/home/saberma/.rvm/gems/ruby-1.9.3-p0/bundler/gems/resque-scheduler-54075b0f5492/lib/resque/scheduler.rb:49:in `run'
/home/saberma/.rvm/gems/ruby-1.9.3-p0/bundler/gems/resque-scheduler-54075b0f5492/lib/resque_scheduler/tasks.rb:23:in `block (2 levels) in <top (required)>'

https://github.com/Viximo/fakeredis/commit/7f81b71fd6a9d7f7f4a6c6f7013ca5d9084913e6

This guy implement the method, consider to merge it?

hmget with array fields

redis.hmset 'event', 'a', '123', 'b', '456', 'c', '789'

redis.hmget 'event', 'a', 'b', 'c'
=> ["123", "456", "789"]
redis.hmget 'event', ['a', 'b', 'c']
=> [nil]

fakeredis does not support the extended set command

Redis.set("foo", "bar", { nx: true, ex: 100}) when using fakeredis 0.4.3 results in:

     ArgumentError:
       wrong number of arguments (5 for 2)

Looks like fakeredis does not support the arguments hash in Redis.set

(String, Boolean) set(key, value, options = {})
Also known as: []=
Set the string value of a key.

Parameters:
key (String)
value (String)
options (Hash) (defaults to: {}) —
:ex => Fixnum: Set the specified expire time, in seconds.
:px => Fixnum: Set the specified expire time, in milliseconds.
:nx => true: Only set the key if it does not already exist.
:xx => true: Only set the key if it already exist.
Returns:
(String, Boolean) — "OK" or true, false if :nx => true or :xx => true

linsert method is case sensitive (require lower case where)

require "fakeredis"
redis = Redis.new

This does no work (raises error):

redis.linsert('mylist', :BEFORE, "Hello", "bye")
Redis::CommandError: ERR syntax error
from /home/yves/.rvm/gems/ruby-2.2.3@h3ts/gems/fakeredis-0.5.0/lib/redis/connection/memory.rb:981:in `raise_syntax_error'

This does work:

redis.linsert('mylist', :before, "Hello", "bye")
[
    [0] "bye",
    [1] "Hello"
]

REDIS is case insensitive:

127.0.0.1:6379>  RPUSH mylist "Hello"
(integer) 1
127.0.0.1:6379>  LINSERT mylist after "Hello" "There"
(integer) 2
127.0.0.1:6379>  LINSERT mylist AFTER "There" "World"
(integer) 3
127.0.0.1:6379> lrange  mylist  0 -1
1) "Hello"
2) "There"
3) "World"

Request: ZSCAN

In my application, I've used zscan redis command. While run the test code, I'm getting error like

ERR unknown command 'zscan'

I think that command isn't included in fakeredis.

How to use fakeredis with sidekiq?

Hi, guys

In my project, I use sidekiq for delay jobs. And In my Test, I want to use fakeredis as redis faker.

But it does not work after I add require 'fakeredis' in my test_helper.rb

I debug and try to find why, and I find sidekiq will require redis/namespace when I config sidekiq:

Sidekiq.configure_server do |config|
  config.redis = { url: 'redis://127.0.0.1:6379/1, namespace: "cms_queues"}
end
Sidekiq.configure_client do |config|
  config.redis = { url: 'redis://127.0.0.1:6379/1, namespace: "cms_queues"}
end

And fakeredis does not have the file: redis/namespace right now

How does fakeredis process namespace case ?
And how to use fakeredis with sidekiq?

setex result does not match actual redis behavior

Compare fakeredis:

irb(main):004:0> require 'fakeredis'
=> true
irb(main):007:0> r = Redis.new
=> #<Redis client v3.0.4 for redis://127.0.0.1:6379/0>
irb(main):011:0> r.set("foo","haha")
=> "OK"
irb(main):012:0> r.setex("foo", 2592000, "umm")
=> 1

To the redis gem:

irb(main):001:0> require 'redis'
=> true
irb(main):002:0> r = Redis.new
=> #<Redis client v3.0.4 for redis://127.0.0.1:6379/0>
irb(main):003:0> r.set("foo", "haha")
=> "OK"
irb(main):004:0> r.setex("foo", 2592000, "umm")
=> "OK"

And redis-cli:

redis 127.0.0.1:6379> SET foo haha
OK
redis 127.0.0.1:6379> SETEX foo 123 yep
OK

By returning an integer 1 instead of the string "OK" it causes an error with redis-store here:

https://github.com/redis-store/redis-rack/blob/a13a9d/lib/rack/session/redis.rb#L31

can't convert Fixnum to String (TypeError)
./gems/redis-store-a21b17d2bbb0/redis-rack/lib/rack/session/redis.rb:35:in `block in get_session'
./gems/redis-store-a21b17d2bbb0/redis-rack/lib/rack/session/redis.rb:59:in `with_lock'
./gems/1.9.1/bundler/gems/redis-store-a21b17d2bbb0/redis-rack/lib/rack/session/redis.rb:28:in `get_session'

You need to return "OK" when the setex command succeeds, same as set.

Additional redis arguments errors

Redis::CommandError: ERR wrong number of arguments for 'mset' command

and

Redis::CommandError: ERR wrong number of arguments for 'sadd' command

Could you please add this two?

fake_redis or Fakeredis

I know it's annoying to change stuff once people got used to it,
but having to remember that fakeredis is the name/what you have to require is also kind of annoying.
so maybe an activesupport style duality with deprecation would be a nice way to go (having an old file that requires the new + warns)

ZSet does not support "greater than" only "greater or equal to

Redis supports calling zrevrangebyscore with a max and min value prefixed by a parenthesis. This syntax causes the range to be exclusive rather than inclusive.

See this example from the docs http://redis.io/commands/ZREVRANGEBYSCORE

edis> ZREVRANGEBYSCORE myzset 2 1
1) "two"
2) "one"
redis> ZREVRANGEBYSCORE myzset 2 (1
1) "two"
redis> ZREVRANGEBYSCORE myzset (2 (1
(empty list or set)

When you try this using FakeRedis, you get the following error since the min/max values are parsed as floats:

ArgumentError: invalid value for Float(): "(1391277300"

RSpec 3 breaks the test suite

We need to update a few things and add some configuration in I think. I've pinned master to rspec "~> 2.0" for now to keep it working.

Deprecation Warnings:

--------------------------------------------------------------------------------
The semantics of `RSpec::Core::Pending#pending` are changing in
RSpec 3.  In RSpec 2.x, it caused the example to be skipped. In
RSpec 3, the rest of the example will still be run but is expected
to fail, and will be marked as a failure (rather than as pending)
if the example passes.

Any passed block will no longer be executed. This feature is being
removed since it was semantically inconsistent, and the behaviour it
offered is being made available with the other ways of marking an
example pending.

To keep the same skip semantics, change `pending` to `skip`.
Otherwise, if you want the new RSpec 3 behavior, you can safely
ignore this warning and continue to upgrade to RSpec 3 without
addressing it.

Called from /Users/caius/Projects/fakeredis/spec/keys_spec.rb:149:in `block (2 levels) in <module:FakeRedis>'.

--------------------------------------------------------------------------------

Using `n` as a shortcut for the DocumentationFormatter is deprecated. Use `d`, `doc`, or `documentation` instead.

`be_false` is deprecated. Use `be_falsey` (for Ruby's conditional semantics) or `be false` (for exact `== false` equality) instead. Called from /Users/caius/Projects/fakeredis/spec/hashes_spec.rb:47:in `block (2 levels) in <module:FakeRedis>'.
`be_false` is deprecated. Use `be_falsey` (for Ruby's conditional semantics) or `be false` (for exact `== false` equality) instead. Called from /Users/caius/Projects/fakeredis/spec/hashes_spec.rb:116:in `block (2 levels) in <module:FakeRedis>'.
`be_false` is deprecated. Use `be_falsey` (for Ruby's conditional semantics) or `be false` (for exact `== false` equality) instead. Called from /Users/caius/Projects/fakeredis/spec/hashes_spec.rb:122:in `block (2 levels) in <module:FakeRedis>'.
Too many uses of deprecated '`be_false`'. Pass `--deprecation-out` or set `config.deprecation_stream` to a file for full output.

`be_true` is deprecated. Use `be_truthy` (for Ruby's conditional semantics) or `be true` (for exact `== true` equality) instead. Called from /Users/caius/Projects/fakeredis/spec/hashes_spec.rb:46:in `block (2 levels) in <module:FakeRedis>'.
`be_true` is deprecated. Use `be_truthy` (for Ruby's conditional semantics) or `be true` (for exact `== true` equality) instead. Called from /Users/caius/Projects/fakeredis/spec/hashes_spec.rb:187:in `block (2 levels) in <module:FakeRedis>'.
`be_true` is deprecated. Use `be_truthy` (for Ruby's conditional semantics) or `be true` (for exact `== true` equality) instead. Called from /Users/caius/Projects/fakeredis/spec/server_spec.rb:48:in `block (3 levels) in <module:FakeRedis>'.
Too many uses of deprecated '`be_true`'. Pass `--deprecation-out` or set `config.deprecation_stream` to a file for full output.


If you need more of the backtrace for any of these deprecations to
identify where to make the necessary changes, you can configure
`config.raise_errors_for_deprecations!`, and it will turn the
deprecation warnings into errors, giving you the full backtrace.

23 deprecation warnings total

Fails against sorted set tests from redis-rb

I've rigged up redis-rb so I can run it's test(unit) suite against fakeredis to find out where we differ in behaviour to live redis. The sorted_set test file has a few failures in it:


julius:redis-rb(test-against-memory) caius$ conn=memory ruby -I test test/commands_on_sorted_sets_test.rb
/Users/caius/.rvm/gems/ruby-1.9.3-p125/gems/fakeredis-0.4.1/lib/redis/connection/memory.rb:442: warning: assigned but unused variable - deleted_count
/Users/caius/.rvm/gems/ruby-1.9.3-p125/gems/fakeredis-0.4.1/lib/redis/connection/memory.rb:527: warning: assigned but unused variable - values
/Users/caius/.rvm/gems/ruby-1.9.3-p125/gems/fakeredis-0.4.1/lib/redis/connection/memory.rb:648: warning: assigned but unused variable - value
/Users/caius/.rvm/gems/ruby-1.9.3-p125/gems/fakeredis-0.4.1/lib/redis/connection/memory.rb:705: warning: shadowing outer local variable - score
/Users/caius/.rvm/gems/ruby-1.9.3-p125/gems/fakeredis-0.4.1/lib/redis/connection/memory.rb:705: warning: shadowing outer local variable - value
/Users/caius/.rvm/gems/ruby-1.9.3-p125/gems/fakeredis-0.4.1/lib/redis/connection/memory.rb:843: warning: assigned but unused variable - v_a
/Users/caius/.rvm/gems/ruby-1.9.3-p125/gems/fakeredis-0.4.1/lib/redis/connection/memory.rb:843: warning: assigned but unused variable - v_b
Run options: 

# Running tests:

.......FF.............EEEE

Finished tests in 0.051707s, 502.8333 tests/s, 1276.4229 assertions/s.

  1) Failure:
test_zinterstore_with_aggregate(TestCommandsOnSortedSets) [test/commands_on_sorted_sets_test.rb:99]:
<2> expected but was
<0>.

  2) Failure:
test_zinterstore_with_weights(TestCommandsOnSortedSets) [test/commands_on_sorted_sets_test.rb:79]:
<2> expected but was
<0>.

  3) Error:
test_zscore(TestCommandsOnSortedSets):
ArgumentError: invalid value for Float(): ""
    /Users/caius/sources/redis-rb/lib/redis.rb:2212:in `Float'
    /Users/caius/sources/redis-rb/lib/redis.rb:2212:in `_floatify'
    /Users/caius/sources/redis-rb/lib/redis.rb:1366:in `block (2 levels) in zscore'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:87:in `call'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:87:in `call'
    /Users/caius/sources/redis-rb/lib/redis.rb:1365:in `block in zscore'
    /Users/caius/sources/redis-rb/lib/redis.rb:36:in `block in synchronize'

  4) Error:
test_zunionstore(TestCommandsOnSortedSets):
Redis::CommandError: ERR unknown command 'zunionstore'
    /Users/caius/.rvm/gems/ruby-1.9.3-p125/gems/fakeredis-0.4.1/lib/redis/connection/memory.rb:60:in `write'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:216:in `block in write'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:201:in `io'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:215:in `write'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:179:in `block (3 levels) in process'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:173:in `each'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:173:in `block (2 levels) in process'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:286:in `ensure_connected'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:172:in `block in process'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:255:in `logging'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:171:in `process'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:83:in `call'
    /Users/caius/sources/redis-rb/lib/redis.rb:1670:in `block in zunionstore'
    /Users/caius/sources/redis-rb/lib/redis.rb:36:in `block in synchronize'

  5) Error:
test_zunionstore_with_aggregate(TestCommandsOnSortedSets):
Redis::CommandError: ERR unknown command 'zunionstore'
    /Users/caius/.rvm/gems/ruby-1.9.3-p125/gems/fakeredis-0.4.1/lib/redis/connection/memory.rb:60:in `write'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:216:in `block in write'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:201:in `io'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:215:in `write'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:179:in `block (3 levels) in process'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:173:in `each'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:173:in `block (2 levels) in process'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:286:in `ensure_connected'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:172:in `block in process'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:255:in `logging'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:171:in `process'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:83:in `call'
    /Users/caius/sources/redis-rb/lib/redis.rb:1670:in `block in zunionstore'
    /Users/caius/sources/redis-rb/lib/redis.rb:36:in `block in synchronize'

  6) Error:
test_zunionstore_with_weights(TestCommandsOnSortedSets):
Redis::CommandError: ERR unknown command 'zunionstore'
    /Users/caius/.rvm/gems/ruby-1.9.3-p125/gems/fakeredis-0.4.1/lib/redis/connection/memory.rb:60:in `write'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:216:in `block in write'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:201:in `io'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:215:in `write'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:179:in `block (3 levels) in process'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:173:in `each'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:173:in `block (2 levels) in process'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:286:in `ensure_connected'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:172:in `block in process'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:255:in `logging'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:171:in `process'
    /Users/caius/sources/redis-rb/lib/redis/client.rb:83:in `call'
    /Users/caius/sources/redis-rb/lib/redis.rb:1670:in `block in zunionstore'
    /Users/caius/sources/redis-rb/lib/redis.rb:36:in `block in synchronize'

26 tests, 66 assertions, 2 failures, 4 errors, 0 skips

RBX consistently failing to run on Travis

Having just merged a few pull requests in, I've seen consistent failures for RBX (rubinius) on travis for this repo, annoyingly.

Wonder if we've got the travis config setup correctly for it, seems to be failing at installing the runtime, not on running the tests, see https://travis-ci.org/caius/fakeredis/jobs/25645123:

$ rvm use rbx --install --binary --fuzzy
rbx is not installed - installing.
Searching for binary rubies, this might take some time.
Requested binary installation but no rubies are available to download, consider skipping --binary flag.
Gemset '' does not exist, 'rvm rbx do rvm gemset create ' first, or append '--create'.
The command "rvm use rbx --install --binary --fuzzy" failed and exited with 2 during setup.
Your build has been stopped.

zrem make me confusion

For an example:

redis = Redis.new

redis.zadd "key", 1, 2

p redis.zscore "key", 2    #=> 1.0

redis.zrem "key", 2  #=> false

p redis.zscore "key", 2  #=> 1.0

I must

redis.zrem "key", "2"

p redis.zscore "key", 2 #=> nil

Updating the 3.x version of the gem

Can we pull some of @caius fixes to the argument checking of methods to the 3.x version of the gem. We're still using redis-rb 2.2 so we can't upgrade to the newest version of the gem and I just got bit passing the wrong number of args to hmset.

FakeRedis is failing with Ohm

FakeRedis is failing with Ohm (https://github.com/soveran/ohm)

test_helper.rb:

ENV["RAILS_ENV"] = "test"
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'

class ActiveSupport::TestCase
  Ohm.redis = FakeRedis::Redis.new
  Ohm.flush
end

The models are saved but their attributes not

FakeRedis and FakeStrictRedis do not resolve as StrictRedis type

This example is from the code of the RQ library:

if not isinstance(connection, StrictRedis):
        raise ValueError('A StrictRedis or Redis connection is required.')

if connection in this case is a FakeRedis object the return value is false. I will have a PR momentarily that fixes this problem.

getbit/setbit not working

It seems the get/setbit calls aren't working.

This is what it looks like to me when I use fakeredis:

Loading development environment (Rails 3.2.2)
1.9.3p0 :001 > require "fakeredis"
 => true 
1.9.3p0 :002 > redis = Redis.new
 => #<Redis client v3.0.0.rc1 connected to redis://127.0.0.1:6379/0 (Redis v0.07)> 
1.9.3p0 :003 > redis.setbit("test", 7, 1)
 => nil 
1.9.3p0 :004 > redis.getbit("test", 7)
 => nil 

And this is what it looks like without.

Loading development environment (Rails 3.2.2)
1.9.3p0 :001 > redis = Redis.new
 => #<Redis client v3.0.0.rc1 connected to redis://127.0.0.1:6379/0 (Redis v2.4.4)> 
1.9.3p0 :002 > redis.setbit("test", 7, 1)
 => 0 
1.9.3p0 :003 > redis.getbit("test", 7)
 => 1 

Tests failing with Redis 3.0.6

  1) SortedSetsMethods should return a reversed range of members in a sorted set, by score
     Failure/Error: @client.zrevrangebyscore("key", 2, 1, :with_scores => true).should be == [["two", 2], ["one", 1]]
     ArgumentError:
       invalid value for Float(): "one"
     # /Users/guille/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/redis-3.0.6/lib/redis.rb:2469:in `Float'
     # /Users/guille/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/redis-3.0.6/lib/redis.rb:2469:in `block in _floatify'
     # /Users/guille/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/redis-3.0.6/lib/redis.rb:2479:in `call'
     # /Users/guille/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/redis-3.0.6/lib/redis.rb:2479:in `block (2 levels) in _floatify_pairs'
     # /Users/guille/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/redis-3.0.6/lib/redis.rb:2478:in `each'
     # /Users/guille/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/redis-3.0.6/lib/redis.rb:2478:in `each_slice'
     # /Users/guille/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/redis-3.0.6/lib/redis.rb:2478:in `each'
     # /Users/guille/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/redis-3.0.6/lib/redis.rb:2478:in `map'
     # /Users/guille/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/redis-3.0.6/lib/redis.rb:2478:in `block in _floatify_pairs'
     # /Users/guille/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/redis-3.0.6/lib/redis/client.rb:88:in `call'
     # /Users/guille/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/redis-3.0.6/lib/redis/client.rb:88:in `call'
     # /Users/guille/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/redis-3.0.6/lib/redis.rb:1642:in `block in zrevrangebyscore'
     # /Users/guille/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/redis-3.0.6/lib/redis.rb:36:in `block in synchronize'
     # /Users/guille/.rbenv/versions/2.0.0-p247/lib/ruby/2.0.0/monitor.rb:211:in `mon_synchronize'
     # /Users/guille/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/redis-3.0.6/lib/redis.rb:36:in `synchronize'
     # /Users/guille/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/redis-3.0.6/lib/redis.rb:1641:in `zrevrangebyscore'
     # ./spec/sorted_sets_spec.rb:185:in `block (2 levels) in <module:FakeRedis>'

Everything is green with Redis 3.0.5

Blocking list operations appear to be broken

Even though Redis::Connection::Memory implements #brpoplpush and friends, calling any of them throws a CommandError with message "unknown command":

$ gem install redis fakeredis
[...]
2 gems installed
$ irb -rfakeredis
2.1.2 :001 > r = Redis.new
 => #<Redis client v3.2.1 for redis://127.0.0.1:6379/0> 
2.1.2 :002 > command = :brpoplpush
 => :brpoplpush 
2.1.2 :003 > r.respond_to? command
 => true 
2.1.2 :004 > r.send command, 'a', 'b'
Redis::CommandError: ERR unknown command 'brpoplpush'
    from (rvm)/gems/ruby-2.1.2@fakeredis/gems/fakeredis-0.5.0/lib/fakeredis/command_executor.rb:12:in `write'
    from (rvm)/gems/ruby-2.1.2@fakeredis/gems/redis-3.2.1/lib/redis/client.rb:257:in `block in write'
    from (rvm)/gems/ruby-2.1.2@fakeredis/gems/redis-3.2.1/lib/redis/client.rb:236:in `io'
    from (rvm)/gems/ruby-2.1.2@fakeredis/gems/redis-3.2.1/lib/redis/client.rb:255:in `write'
    from (rvm)/gems/ruby-2.1.2@fakeredis/gems/redis-3.2.1/lib/redis/client.rb:214:in `block (3 levels) in process'
    from (rvm)/gems/ruby-2.1.2@fakeredis/gems/redis-3.2.1/lib/redis/client.rb:208:in `each'
    from (rvm)/gems/ruby-2.1.2@fakeredis/gems/redis-3.2.1/lib/redis/client.rb:208:in `block (2 levels) in process'
    from (rvm)/gems/ruby-2.1.2@fakeredis/gems/redis-3.2.1/lib/redis/client.rb:353:in `ensure_connected'
    from (rvm)/gems/ruby-2.1.2@fakeredis/gems/redis-3.2.1/lib/redis/client.rb:207:in `block in process'
    from (rvm)/gems/ruby-2.1.2@fakeredis/gems/redis-3.2.1/lib/redis/client.rb:292:in `logging'
    from (rvm)/gems/ruby-2.1.2@fakeredis/gems/redis-3.2.1/lib/redis/client.rb:206:in `process'
    from (rvm)/gems/ruby-2.1.2@fakeredis/gems/redis-3.2.1/lib/redis/client.rb:112:in `call'
    from (rvm)/gems/ruby-2.1.2@fakeredis/gems/redis-3.2.1/lib/redis/client.rb:195:in `block in call_with_timeout'
    from (rvm)/gems/ruby-2.1.2@fakeredis/gems/redis-3.2.1/lib/redis/client.rb:266:in `with_socket_timeout'
    from (rvm)/gems/ruby-2.1.2@fakeredis/gems/redis-3.2.1/lib/redis/client.rb:194:in `call_with_timeout'
    from (rvm)/gems/ruby-2.1.2@fakeredis/gems/redis-3.2.1/lib/redis.rb:1132:in `block in brpoplpush'
    from (rvm)/gems/ruby-2.1.2@fakeredis/gems/redis-3.2.1/lib/redis.rb:37:in `block in synchronize'
    from (rvm)/rubies/ruby-2.1.2/lib/ruby/2.1.0/monitor.rb:211:in `mon_synchronize'
    from (rvm)/gems/ruby-2.1.2@fakeredis/gems/redis-3.2.1/lib/redis.rb:37:in `synchronize'
    from (rvm)/gems/ruby-2.1.2@fakeredis/gems/redis-3.2.1/lib/redis.rb:1129:in `brpoplpush'
    from (irb):4
    from (rvm)/rubies/ruby-2.1.2/bin/irb:11:in `<main>'

All of the non-blocking list commands work fine.

setnx method fails due to expire value not present

I'm testing a Sinatra app + Resque with RSpec. I've the resque-lock plugin added to Resque which makes a simple call to Redis to provide a lock...

Resque.redis.setnx(lock(*args), true)

My specs are failing due to #setnx not behaving as stated here.

After a bit of debugging this is down to the expires object within the ExpiringHash class. The #setex method sets an expire time against a key when it is set, as documented here.

The problem is that the #setnx does not set an expire time (and nor should it) but the method chain is as follows #setnx => #exists(key) => ExpiringHash#key? => ExpiringHash#expired? where #expired? throws an exception at the following line...

expires.include?(key) && expires[key] < Time.now

...because expires[key] => nil

Currently the #setnx method is unusable due to this problem

fakeredis incorrectly returns real data types without pickling with hset/hget() instead of str()

In the contrived example below, there is a type difference for the returned value in
some circumstances. hset/hget with fake returns a long whereas real returns a string.

mimicking the return type of real redis is probably desired here.

Basically, whatever is shipped off into real redis returns as a string. However, only some content that goes into fake redis returns as a string. Some return as the native object type without pickling.

--code--
import redis
import fakeredis

real = redis.StrictRedis()
fake = fakeredis.FakeStrictRedis()

fake.set("blah", 0L)
real.set("blah", 0L)
print "fake:", type(fake.get("blah"))
print "real:", type(real.get("blah"))

fake.hset("blah1", "key", 0L)
real.hset("blah1", "key", 0L)
print "fake:", type(fake.hget("blah1", "key"))
print "real:", type(real.hget("blah1", "key"))

--output--
fake: <type 'str'>
real: <type 'str'>
fake: <type 'long'>
real: <type 'str'>

gem release

It would be awesome if you could release the latest code. I'd like to use an official gem rather than pointing straight at the repo, but I need the return value fixes that aren't in the latest gem.

Redis.current.client.connection is nil

I'm testing a Sinatra app + Resque with RSpec using the following setup

# Gemfile
gem "fakeredis"

# spec_helper.rb
require "fakeredis/rspec"

According to the docs this should be enough to get fakeredis up and working. This wasn't working for me and after some debugging I found that the RSpec before hook defined in lib\fakeredis\rspec.rbcontains this line redis.flushdb if redis.client.connection.is_a?(Redis::Connection::Memory)

The problem was that redis.client.connection => nil and thus the flushdb method never got invoked.

After experimenting in the irb I confirmed that redis.client.connection was nil BUT after I made a call to Redis.current.infoit would suddenly appear as an instance of Redis::Connection::Memory

I now have the following (which works)...

# spec_helper.rb
require "fakeredis/rspec"
Redis.current.info

...but this is just a hack to force fakeredis to work as it should.

Is there a cleaner way to get fakeredis working as it should and why does it behave like this in the first place?

Is there a way to disable fakeredis once it's loaded?

I'm working with some code that uses fakeredis for specs, but whenever I run those specs from a REPL, fakeredis stays around and commands like Redis.new will just give me fakeredis. I need to be able to disable it to be able to access the real redis store again.

Is there a way to disable/enable it in the REPL?

Using `GET` with a hash returns a stringified representation of that hash

If you set a key to a value in a hash (thereby provisioning it in Fakeredis' internal storage), but then access it as if it were a simple key, fakeredis responds by stringifying an internal object and passing it back, where it should raise a TypeError.

Steps to reproduce:

  1. fakeredis.hset('hash', 'key', 'value')
  2. fakeredis.get('hash') produces '<fakeredis._StrKeyDict object at 0x10ad47d90>'

How Redis handles this:

  1. HSET blab bleebs 5
  2. HGET blab bleebs produces 5
  3. GET blab produces (error) WRONGTYPE Operation against a key holding the wrong kind of value

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.