ryansch-mock_redis 0.2.0.1

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.
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