ryansch-mock_redis 0.2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. data/.gitignore +4 -0
  2. data/.rspec +1 -0
  3. data/CHANGELOG.md +20 -0
  4. data/Gemfile +9 -0
  5. data/LICENSE +19 -0
  6. data/README.md +94 -0
  7. data/Rakefile +10 -0
  8. data/lib/mock_redis.rb +32 -0
  9. data/lib/mock_redis/assertions.rb +13 -0
  10. data/lib/mock_redis/database.rb +432 -0
  11. data/lib/mock_redis/exceptions.rb +3 -0
  12. data/lib/mock_redis/expire_wrapper.rb +25 -0
  13. data/lib/mock_redis/hash_methods.rb +102 -0
  14. data/lib/mock_redis/list_methods.rb +187 -0
  15. data/lib/mock_redis/multi_db_wrapper.rb +86 -0
  16. data/lib/mock_redis/set_methods.rb +125 -0
  17. data/lib/mock_redis/string_methods.rb +195 -0
  18. data/lib/mock_redis/transaction_wrapper.rb +80 -0
  19. data/lib/mock_redis/undef_redis_methods.rb +11 -0
  20. data/lib/mock_redis/utility_methods.rb +22 -0
  21. data/lib/mock_redis/version.rb +3 -0
  22. data/lib/mock_redis/zset.rb +110 -0
  23. data/lib/mock_redis/zset_methods.rb +209 -0
  24. data/mock_redis.gemspec +24 -0
  25. data/spec/cloning_spec.rb +96 -0
  26. data/spec/commands/append_spec.rb +24 -0
  27. data/spec/commands/auth_spec.rb +7 -0
  28. data/spec/commands/bgrewriteaof_spec.rb +7 -0
  29. data/spec/commands/bgsave_spec.rb +7 -0
  30. data/spec/commands/blpop_spec.rb +55 -0
  31. data/spec/commands/brpop_spec.rb +54 -0
  32. data/spec/commands/brpoplpush_spec.rb +53 -0
  33. data/spec/commands/dbsize_spec.rb +18 -0
  34. data/spec/commands/decr_spec.rb +34 -0
  35. data/spec/commands/decrby_spec.rb +34 -0
  36. data/spec/commands/del_spec.rb +20 -0
  37. data/spec/commands/echo_spec.rb +11 -0
  38. data/spec/commands/exists_spec.rb +14 -0
  39. data/spec/commands/expire_spec.rb +83 -0
  40. data/spec/commands/expireat_spec.rb +48 -0
  41. data/spec/commands/flushall_spec.rb +38 -0
  42. data/spec/commands/flushdb_spec.rb +38 -0
  43. data/spec/commands/get_spec.rb +23 -0
  44. data/spec/commands/getbit_spec.rb +34 -0
  45. data/spec/commands/getrange_spec.rb +22 -0
  46. data/spec/commands/getset_spec.rb +23 -0
  47. data/spec/commands/hdel_spec.rb +35 -0
  48. data/spec/commands/hexists_spec.rb +22 -0
  49. data/spec/commands/hget_spec.rb +23 -0
  50. data/spec/commands/hgetall_spec.rb +22 -0
  51. data/spec/commands/hincrby_spec.rb +52 -0
  52. data/spec/commands/hkeys_spec.rb +19 -0
  53. data/spec/commands/hlen_spec.rb +19 -0
  54. data/spec/commands/hmget_spec.rb +30 -0
  55. data/spec/commands/hmset_spec.rb +43 -0
  56. data/spec/commands/hset_spec.rb +23 -0
  57. data/spec/commands/hsetnx_spec.rb +39 -0
  58. data/spec/commands/hvals_spec.rb +19 -0
  59. data/spec/commands/incr_spec.rb +34 -0
  60. data/spec/commands/incrby_spec.rb +44 -0
  61. data/spec/commands/info_spec.rb +13 -0
  62. data/spec/commands/keys_spec.rb +87 -0
  63. data/spec/commands/lastsave_spec.rb +8 -0
  64. data/spec/commands/lindex_spec.rb +39 -0
  65. data/spec/commands/linsert_spec.rb +68 -0
  66. data/spec/commands/llen_spec.rb +16 -0
  67. data/spec/commands/lpop_spec.rb +34 -0
  68. data/spec/commands/lpush_spec.rb +30 -0
  69. data/spec/commands/lpushx_spec.rb +33 -0
  70. data/spec/commands/lrange_spec.rb +35 -0
  71. data/spec/commands/lrem_spec.rb +79 -0
  72. data/spec/commands/lset_spec.rb +38 -0
  73. data/spec/commands/ltrim_spec.rb +35 -0
  74. data/spec/commands/mget_spec.rb +34 -0
  75. data/spec/commands/move_spec.rb +147 -0
  76. data/spec/commands/mset_spec.rb +29 -0
  77. data/spec/commands/msetnx_spec.rb +40 -0
  78. data/spec/commands/persist_spec.rb +49 -0
  79. data/spec/commands/ping_spec.rb +7 -0
  80. data/spec/commands/quit_spec.rb +7 -0
  81. data/spec/commands/randomkey_spec.rb +20 -0
  82. data/spec/commands/rename_spec.rb +31 -0
  83. data/spec/commands/renamenx_spec.rb +36 -0
  84. data/spec/commands/rpop_spec.rb +34 -0
  85. data/spec/commands/rpoplpush_spec.rb +45 -0
  86. data/spec/commands/rpush_spec.rb +30 -0
  87. data/spec/commands/rpushx_spec.rb +33 -0
  88. data/spec/commands/sadd_spec.rb +22 -0
  89. data/spec/commands/save_spec.rb +7 -0
  90. data/spec/commands/scard_spec.rb +18 -0
  91. data/spec/commands/sdiff_spec.rb +47 -0
  92. data/spec/commands/sdiffstore_spec.rb +58 -0
  93. data/spec/commands/select_spec.rb +53 -0
  94. data/spec/commands/set_spec.rb +7 -0
  95. data/spec/commands/setbit_spec.rb +46 -0
  96. data/spec/commands/setex_spec.rb +22 -0
  97. data/spec/commands/setnx_spec.rb +25 -0
  98. data/spec/commands/setrange_spec.rb +30 -0
  99. data/spec/commands/sinter_spec.rb +41 -0
  100. data/spec/commands/sinterstore_spec.rb +53 -0
  101. data/spec/commands/sismember_spec.rb +29 -0
  102. data/spec/commands/smembers_spec.rb +18 -0
  103. data/spec/commands/smove_spec.rb +41 -0
  104. data/spec/commands/spop_spec.rb +25 -0
  105. data/spec/commands/srandmember_spec.rb +25 -0
  106. data/spec/commands/srem_spec.rb +35 -0
  107. data/spec/commands/strlen_spec.rb +19 -0
  108. data/spec/commands/sunion_spec.rb +40 -0
  109. data/spec/commands/sunionstore_spec.rb +53 -0
  110. data/spec/commands/ttl_spec.rb +36 -0
  111. data/spec/commands/type_spec.rb +36 -0
  112. data/spec/commands/unwatch_spec.rb +7 -0
  113. data/spec/commands/watch_spec.rb +7 -0
  114. data/spec/commands/zadd_spec.rb +29 -0
  115. data/spec/commands/zcard_spec.rb +19 -0
  116. data/spec/commands/zcount_spec.rb +23 -0
  117. data/spec/commands/zincrby_spec.rb +24 -0
  118. data/spec/commands/zinterstore_spec.rb +96 -0
  119. data/spec/commands/zrange_spec.rb +31 -0
  120. data/spec/commands/zrangebyscore_spec.rb +68 -0
  121. data/spec/commands/zrank_spec.rb +23 -0
  122. data/spec/commands/zrem_spec.rb +25 -0
  123. data/spec/commands/zremrangebyrank_spec.rb +22 -0
  124. data/spec/commands/zremrangebyscore_spec.rb +28 -0
  125. data/spec/commands/zrevrange_spec.rb +31 -0
  126. data/spec/commands/zrevrangebyscore_spec.rb +47 -0
  127. data/spec/commands/zrevrank_spec.rb +23 -0
  128. data/spec/commands/zscore_spec.rb +16 -0
  129. data/spec/commands/zunionstore_spec.rb +104 -0
  130. data/spec/spec_helper.rb +44 -0
  131. data/spec/support/redis_multiplexer.rb +91 -0
  132. data/spec/support/shared_examples/only_operates_on_hashes.rb +13 -0
  133. data/spec/support/shared_examples/only_operates_on_lists.rb +13 -0
  134. data/spec/support/shared_examples/only_operates_on_sets.rb +13 -0
  135. data/spec/support/shared_examples/only_operates_on_strings.rb +13 -0
  136. data/spec/support/shared_examples/only_operates_on_zsets.rb +57 -0
  137. data/spec/transactions_spec.rb +96 -0
  138. metadata +361 -0
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "mock_redis/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "ryansch-mock_redis"
7
+ s.version = MockRedis::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Samuel Merritt", "Ryan Schlesinger"]
10
+ s.email = ["ryan@instanceinc.com"]
11
+ s.homepage = "https://github.com/ryansch/mock_redis"
12
+ s.summary = %q{Redis mock that just lives in memory; useful for testing.}
13
+
14
+ s.description = %q{Instantiate one with `redis = MockRedis.new` and treat it like you would a normal Redis object. It supports all the usual Redis operations.}
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_development_dependency "redis", "~> 2.2.1"
22
+ s.add_development_dependency "rspec", "~> 2.6.0"
23
+ s.add_development_dependency "ZenTest"
24
+ end
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+
3
+ describe "MockRedis#clone" do
4
+ before do
5
+ @mock = MockRedis.new
6
+ end
7
+
8
+ context "the stored data" do
9
+ before do
10
+ @mock.set('foo', 'bar')
11
+ @mock.hset('foohash', 'bar', 'baz')
12
+ @mock.lpush('foolist', 'bar')
13
+ @mock.sadd('fooset', 'bar')
14
+ @mock.zadd('foozset', 1, 'bar')
15
+
16
+ @clone = @mock.clone
17
+ end
18
+
19
+ it "copies the stored data to the clone" do
20
+ @clone.get('foo').should == 'bar'
21
+ end
22
+
23
+ it "performs a deep copy (string values)" do
24
+ @mock.del('foo')
25
+ @clone.get('foo').should == 'bar'
26
+ end
27
+
28
+ it "performs a deep copy (list values)" do
29
+ @mock.lpop('foolist')
30
+ @clone.lrange('foolist', 0, 1).should == ['bar']
31
+ end
32
+
33
+ it "performs a deep copy (hash values)" do
34
+ @mock.hset('foohash', 'bar', 'quux')
35
+ @clone.hgetall('foohash').should == {'bar' => 'baz'}
36
+ end
37
+
38
+ it "performs a deep copy (set values)" do
39
+ @mock.srem('fooset', 'bar')
40
+ @clone.smembers('fooset').should == ['bar']
41
+ end
42
+
43
+ it "performs a deep copy (zset values)" do
44
+ @mock.zadd('foozset', 2, 'bar')
45
+ @clone.zscore('foozset', 'bar').should == "1"
46
+ end
47
+ end
48
+
49
+ context "expiration times" do
50
+ before do
51
+ @mock.set('foo', 1)
52
+ @mock.expire('foo', 60026)
53
+
54
+ @clone = @mock.clone
55
+ end
56
+
57
+ it "copies the expiration times" do
58
+ @clone.ttl('foo').should > 0
59
+ end
60
+
61
+ it "deep-copies the expiration times" do
62
+ @mock.persist('foo')
63
+ @clone.ttl('foo').should > 0
64
+ end
65
+
66
+ it "deep-copies the expiration times" do
67
+ @clone.persist('foo')
68
+ @mock.ttl('foo').should > 0
69
+ end
70
+ end
71
+
72
+ context "transactional info" do
73
+ before do
74
+ @mock.multi
75
+ @mock.incr('foo')
76
+ @mock.incrby('foo', 2)
77
+ @mock.incrby('foo', 4)
78
+
79
+ @clone = @mock.clone
80
+ end
81
+
82
+ it "makes sure the clone is in a transaction" do
83
+ lambda do
84
+ @clone.exec
85
+ end.should_not raise_error
86
+ end
87
+
88
+ it "deep-copies the queued commands" do
89
+ @clone.incrby('foo', 8)
90
+ @clone.exec.should == [1, 3, 7, 15]
91
+
92
+ @mock.exec.should == [1, 3, 7]
93
+ end
94
+ end
95
+
96
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe '#append(key, value)' do
4
+ before { @key = 'mock-redis-test:append' }
5
+
6
+ it "returns the new length of the string" do
7
+ @redises.set(@key, 'porkchop')
8
+ @redises.append(@key, 'sandwiches').should == 18
9
+ end
10
+
11
+ it "appends value to the previously-stored value" do
12
+ @redises.set(@key, 'porkchop')
13
+ @redises.append(@key, 'sandwiches')
14
+
15
+ @redises.get(@key).should == 'porkchopsandwiches'
16
+ end
17
+
18
+ it "treats a missing key as an empty string" do
19
+ @redises.append(@key, 'foo')
20
+ @redises.get(@key).should == 'foo'
21
+ end
22
+
23
+ it_should_behave_like "a string-only command"
24
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe "#auth(password) [mock only]" do
4
+ it "just returns 'OK'" do
5
+ @redises.mock.auth('foo').should == 'OK'
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe "#bgrewriteaof [mock only]" do
4
+ it "just returns a canned string" do
5
+ @redises.mock.bgrewriteaof.should =~ /append/
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe "#bgsave [mock only]" do
4
+ it "just returns a canned string" do
5
+ @redises.mock.bgsave.should =~ /saving/
6
+ end
7
+ end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ describe '#blpop(key [, key, ...,], timeout)' do
4
+ before do
5
+ @list1 = 'mock-redis-test:blpop1'
6
+ @list2 = 'mock-redis-test:blpop2'
7
+
8
+ @redises.rpush(@list1, 'one')
9
+ @redises.rpush(@list1, 'two')
10
+ @redises.rpush(@list2, 'ten')
11
+ @redises.rpush(@list2, 'eleven')
12
+ end
13
+
14
+ it "returns [first-nonempty-list, popped-value]" do
15
+ @redises.blpop(@list1, @list2, 1).should == [@list1, 'one']
16
+ end
17
+
18
+ it "pops that value off the list" do
19
+ @redises.blpop(@list1, @list2, 1)
20
+ @redises.blpop(@list1, @list2, 1)
21
+
22
+ @redises.blpop(@list1, @list2, 1).should == [@list2, 'ten']
23
+ end
24
+
25
+ it "ignores empty keys" do
26
+ @redises.blpop('mock-redis-test:not-here', @list1, 1).should ==
27
+ [@list1, 'one']
28
+ end
29
+
30
+ it "raises an error on non-integer timeout" do
31
+ lambda do
32
+ @redises.blpop(@list1, @list2, 0.5)
33
+ end.should raise_error(RuntimeError)
34
+ end
35
+
36
+ it "raises an error on negative timeout" do
37
+ lambda do
38
+ @redises.blpop(@list1, @list2, -1)
39
+ end.should raise_error(RuntimeError)
40
+ end
41
+
42
+ it_should_behave_like "a list-only command"
43
+
44
+ context "[mock only]" do
45
+ it "ignores positive timeouts and returns nil" do
46
+ @redises.mock.blpop('mock-redis-test:not-here', 1).should be_nil
47
+ end
48
+
49
+ it "raises WouldBlock on zero timeout (no blocking in the mock)" do
50
+ lambda do
51
+ @redises.mock.blpop('mock-redis-test:not-here', 0)
52
+ end.should raise_error(MockRedis::WouldBlock)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+
3
+ describe '#brpop(key [, key, ...,], timeout)' do
4
+ before do
5
+ @list1 = 'mock-redis-test:brpop1'
6
+ @list2 = 'mock-redis-test:brpop2'
7
+
8
+ @redises.rpush(@list1, 'one')
9
+ @redises.rpush(@list1, 'two')
10
+
11
+ @redises.rpush(@list2, 'ten')
12
+ end
13
+
14
+ it "returns [first-nonempty-list, popped-value]" do
15
+ @redises.brpop(@list1, @list2, 1).should == [@list1, 'two']
16
+ end
17
+
18
+ it "pops that value off the list" do
19
+ @redises.brpop(@list1, @list2, 1)
20
+ @redises.brpop(@list1, @list2, 1)
21
+ @redises.brpop(@list1, @list2, 1).should == [@list2, 'ten']
22
+ end
23
+
24
+ it "ignores empty keys" do
25
+ @redises.brpop('mock-redis-test:not-here', @list1, 1).should ==
26
+ [@list1, 'two']
27
+ end
28
+
29
+ it "raises an error on non-integer timeout" do
30
+ lambda do
31
+ @redises.brpop(@list1, @list2, 0.5)
32
+ end.should raise_error(RuntimeError)
33
+ end
34
+
35
+ it "raises an error on negative timeout" do
36
+ lambda do
37
+ @redises.brpop(@list1, @list2, -1)
38
+ end.should raise_error(RuntimeError)
39
+ end
40
+
41
+ it_should_behave_like "a list-only command"
42
+
43
+ context "[mock only]" do
44
+ it "ignores positive timeouts and returns nil" do
45
+ @redises.mock.brpop('mock-redis-test:not-here', 1).should be_nil
46
+ end
47
+
48
+ it "raises WouldBlock on zero timeout (no blocking in the mock)" do
49
+ lambda do
50
+ @redises.mock.brpop('mock-redis-test:not-here', 0)
51
+ end.should raise_error(MockRedis::WouldBlock)
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ require 'spec_helper'
4
+
5
+ describe '#brpoplpush(source, destination, timeout)' do
6
+ before do
7
+ @list1 = 'mock-redis-test:brpoplpush1'
8
+ @list2 = 'mock-redis-test:brpoplpush2'
9
+
10
+ @redises.rpush(@list1, 'A')
11
+ @redises.rpush(@list1, 'B')
12
+
13
+ @redises.rpush(@list2, 'alpha')
14
+ @redises.rpush(@list2, 'beta')
15
+ end
16
+
17
+ it "takes the last element of source and prepends it to destination" do
18
+ @redises.brpoplpush(@list1, @list2, 0)
19
+ @redises.lrange(@list1, 0, -1).should == %w[A]
20
+ @redises.lrange(@list2, 0, -1).should == %w[B alpha beta]
21
+ end
22
+
23
+ it "returns the moved element" do
24
+ @redises.brpoplpush(@list1, @list2, 0).should == "B"
25
+ end
26
+
27
+ it "raises an error on non-integer timeout" do
28
+ lambda do
29
+ @redises.brpoplpush(@list1, @list2, 0.5)
30
+ end.should raise_error(RuntimeError)
31
+ end
32
+
33
+ it "raises an error on negative timeout" do
34
+ lambda do
35
+ @redises.brpoplpush(@list1, @list2, -1)
36
+ end.should raise_error(RuntimeError)
37
+ end
38
+
39
+ it_should_behave_like "a list-only command"
40
+
41
+ context "[mock only]" do
42
+ it "ignores positive timeouts and returns nil" do
43
+ @redises.mock.brpoplpush('mock-redis-test:not-here', @list1, 1).
44
+ should be_nil
45
+ end
46
+
47
+ it "raises WouldBlock on zero timeout (no blocking in the mock)" do
48
+ lambda do
49
+ @redises.mock.brpoplpush('mock-redis-test:not-here', @list1, 0)
50
+ end.should raise_error(MockRedis::WouldBlock)
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe "#dbsize [mock only]" do
4
+ # mock only since we can't guarantee that the real Redis is empty
5
+ before { @mock = @redises.mock }
6
+
7
+ it "returns 0 for an empty DB" do
8
+ @mock.dbsize.should == 0
9
+ end
10
+
11
+ it "returns the number of keys in the DB" do
12
+ @mock.set('foo', 1)
13
+ @mock.lpush('bar', 2)
14
+ @mock.hset('baz', 3, 4)
15
+
16
+ @mock.dbsize.should == 3
17
+ end
18
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe '#decr(key)' do
4
+ before { @key = 'mock-redis-test:46895' }
5
+
6
+ it "returns the value after the decrement" do
7
+ @redises.set(@key, 2)
8
+ @redises.decr(@key).should == 1
9
+ end
10
+
11
+ it "treats a missing key like 0" do
12
+ @redises.decr(@key).should == -1
13
+ end
14
+
15
+ it "decrements negative numbers" do
16
+ @redises.set(@key, -10)
17
+ @redises.decr(@key).should == -11
18
+ end
19
+
20
+ it "works multiple times" do
21
+ @redises.decr(@key).should == -1
22
+ @redises.decr(@key).should == -2
23
+ @redises.decr(@key).should == -3
24
+ end
25
+
26
+ it "raises an error if the value does not look like an integer" do
27
+ @redises.set(@key, "minus one")
28
+ lambda do
29
+ @redises.decr(@key)
30
+ end.should raise_error(RuntimeError)
31
+ end
32
+
33
+ it_should_behave_like "a string-only command"
34
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe '#decrby(key, decrement)' do
4
+ before { @key = 'mock-redis-test:43650' }
5
+
6
+ it "returns the value after the decrement" do
7
+ @redises.set(@key, 4)
8
+ @redises.decrby(@key, 2).should == 2
9
+ end
10
+
11
+ it "treats a missing key like 0" do
12
+ @redises.decrby(@key, 2).should == -2
13
+ end
14
+
15
+ it "decrements negative numbers" do
16
+ @redises.set(@key, -10)
17
+ @redises.decrby(@key, 2).should == -12
18
+ end
19
+
20
+ it "works multiple times" do
21
+ @redises.decrby(@key, 2).should == -2
22
+ @redises.decrby(@key, 2).should == -4
23
+ @redises.decrby(@key, 2).should == -6
24
+ end
25
+
26
+ it "raises an error if the value does not look like an integer" do
27
+ @redises.set(@key, "one")
28
+ lambda do
29
+ @redises.decrby(@key, 1)
30
+ end.should raise_error(RuntimeError)
31
+ end
32
+
33
+ it_should_behave_like "a string-only command"
34
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe '#del(key [, key, ...])' do
4
+ it "returns the number of keys deleted" do
5
+ @redises.set('mock-redis-test:1', 1)
6
+ @redises.set('mock-redis-test:2', 1)
7
+
8
+ @redises.del(
9
+ 'mock-redis-test:1',
10
+ 'mock-redis-test:2',
11
+ 'mock-redis-test:other').should == 2
12
+ end
13
+
14
+ it "actually removes the key" do
15
+ @redises.set('mock-redis-test:1', 1)
16
+ @redises.del('mock-redis-test:1')
17
+
18
+ @redises.get('mock-redis-test:1').should be_nil
19
+ end
20
+ end