kuende-fakeredis 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.travis.yml +19 -0
  4. data/Gemfile +13 -0
  5. data/Guardfile +8 -0
  6. data/LICENSE +21 -0
  7. data/README.md +102 -0
  8. data/Rakefile +27 -0
  9. data/fakeredis.gemspec +24 -0
  10. data/gemfiles/redisrb-master.gemfile +14 -0
  11. data/lib/fake_redis.rb +1 -0
  12. data/lib/fakeredis.rb +6 -0
  13. data/lib/fakeredis/bitop_command.rb +56 -0
  14. data/lib/fakeredis/command_executor.rb +25 -0
  15. data/lib/fakeredis/expiring_hash.rb +70 -0
  16. data/lib/fakeredis/minitest.rb +24 -0
  17. data/lib/fakeredis/rspec.rb +24 -0
  18. data/lib/fakeredis/sort_method.rb +117 -0
  19. data/lib/fakeredis/sorted_set_argument_handler.rb +74 -0
  20. data/lib/fakeredis/sorted_set_store.rb +80 -0
  21. data/lib/fakeredis/transaction_commands.rb +83 -0
  22. data/lib/fakeredis/version.rb +3 -0
  23. data/lib/fakeredis/zset.rb +39 -0
  24. data/lib/redis/connection/memory.rb +1375 -0
  25. data/spec/bitop_command_spec.rb +209 -0
  26. data/spec/compatibility_spec.rb +9 -0
  27. data/spec/connection_spec.rb +85 -0
  28. data/spec/hashes_spec.rb +261 -0
  29. data/spec/keys_spec.rb +488 -0
  30. data/spec/lists_spec.rb +229 -0
  31. data/spec/memory_spec.rb +28 -0
  32. data/spec/server_spec.rb +100 -0
  33. data/spec/sets_spec.rb +280 -0
  34. data/spec/sort_method_spec.rb +74 -0
  35. data/spec/sorted_sets_spec.rb +578 -0
  36. data/spec/spec_helper.rb +29 -0
  37. data/spec/spec_helper_live_redis.rb +14 -0
  38. data/spec/strings_spec.rb +289 -0
  39. data/spec/subscription_spec.rb +107 -0
  40. data/spec/support/shared_examples/bitwise_operation.rb +59 -0
  41. data/spec/support/shared_examples/sortable.rb +69 -0
  42. data/spec/transactions_spec.rb +92 -0
  43. data/spec/upcase_method_name_spec.rb +18 -0
  44. metadata +148 -0
@@ -0,0 +1,29 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+ require 'fakeredis'
5
+ require "fakeredis/rspec"
6
+
7
+ require "support/shared_examples/sortable"
8
+ require "support/shared_examples/bitwise_operation"
9
+
10
+ RSpec.configure do |config|
11
+ # replaces -b -fdoc --color in .rspec
12
+ config.color = true
13
+ config.default_formatter = "doc"
14
+ config.backtrace_exclusion_patterns = []
15
+
16
+ config.mock_with :rspec do |c|
17
+ # TODO: upgrade should syntax to expect syntax
18
+ c.syntax = [:should, :expect]
19
+ end
20
+
21
+ config.expect_with :rspec do |c|
22
+ # TODO: upgrade should syntax to expect syntax
23
+ c.syntax = [:should, :expect]
24
+ end
25
+ end
26
+
27
+ def fakeredis?
28
+ true
29
+ end
@@ -0,0 +1,14 @@
1
+ require "spec_helper"
2
+
3
+ # Remove memory so we test against actual redis
4
+ Redis::Connection.drivers.pop
5
+
6
+ RSpec.configure do |config|
7
+ config.before(:each) do
8
+ Redis.new.flushall
9
+ end
10
+ end
11
+
12
+ def fakeredis?
13
+ false
14
+ end
@@ -0,0 +1,289 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'spec_helper'
4
+
5
+ module FakeRedis
6
+ describe "StringsMethods" do
7
+
8
+ before(:each) do
9
+ @client = Redis.new
10
+ end
11
+
12
+ it "should append a value to key" do
13
+ @client.set("key1", "Hello")
14
+ @client.append("key1", " World")
15
+
16
+ expect(@client.get("key1")).to eq("Hello World")
17
+ end
18
+
19
+ it "should decrement the integer value of a key by one" do
20
+ @client.set("counter", "1")
21
+ @client.decr("counter")
22
+
23
+ expect(@client.get("counter")).to eq("0")
24
+ end
25
+
26
+ it "should decrement the integer value of a key by the given number" do
27
+ @client.set("counter", "10")
28
+ @client.decrby("counter", "5")
29
+
30
+ expect(@client.get("counter")).to eq("5")
31
+ end
32
+
33
+ it "should get the value of a key" do
34
+ expect(@client.get("key2")).to eq(nil)
35
+ end
36
+
37
+ it "should returns the bit value at offset in the string value stored at key" do
38
+ @client.set("key1", "a")
39
+
40
+ expect(@client.getbit("key1", 1)).to eq(1)
41
+ expect(@client.getbit("key1", 2)).to eq(1)
42
+ expect(@client.getbit("key1", 3)).to eq(0)
43
+ expect(@client.getbit("key1", 4)).to eq(0)
44
+ expect(@client.getbit("key1", 5)).to eq(0)
45
+ expect(@client.getbit("key1", 6)).to eq(0)
46
+ expect(@client.getbit("key1", 7)).to eq(1)
47
+ end
48
+
49
+ it "should allow direct bit manipulation even if the string isn't set" do
50
+ @client.setbit("key1", 10, 1)
51
+ expect(@client.getbit("key1", 10)).to eq(1)
52
+ end
53
+
54
+ context 'when a bit is previously set to 0' do
55
+ before { @client.setbit("key1", 10, 0) }
56
+
57
+ it 'setting it to 1 returns 0' do
58
+ expect(@client.setbit("key1", 10, 1)).to eql 0
59
+ end
60
+
61
+ it 'setting it to 0 returns 0' do
62
+ expect(@client.setbit("key1", 10, 0)).to eql 0
63
+ end
64
+ end
65
+
66
+ context 'when a bit is previously set to 1' do
67
+ before { @client.setbit("key1", 10, 1) }
68
+
69
+ it 'setting it to 0 returns 1' do
70
+ expect(@client.setbit("key1", 10, 0)).to eql 1
71
+ end
72
+
73
+ it 'setting it to 1 returns 1' do
74
+ expect(@client.setbit("key1", 10, 1)).to eql 1
75
+ end
76
+ end
77
+
78
+ it "should get a substring of the string stored at a key" do
79
+ @client.set("key1", "This a message")
80
+
81
+ expect(@client.getrange("key1", 0, 3)).to eq("This")
82
+ expect(@client.substr("key1", 0, 3)).to eq("This")
83
+ end
84
+
85
+ it "should set the string value of a key and return its old value" do
86
+ @client.set("key1","value1")
87
+
88
+ expect(@client.getset("key1", "value2")).to eq("value1")
89
+ expect(@client.get("key1")).to eq("value2")
90
+ end
91
+
92
+ it "should return nil for #getset if the key does not exist when setting" do
93
+ expect(@client.getset("key1", "value1")).to eq(nil)
94
+ expect(@client.get("key1")).to eq("value1")
95
+ end
96
+
97
+ it "should increment the integer value of a key by one" do
98
+ @client.set("counter", "1")
99
+ expect(@client.incr("counter")).to eq(2)
100
+
101
+ expect(@client.get("counter")).to eq("2")
102
+ end
103
+
104
+ it "should not change the expire value of the key during incr" do
105
+ @client.set("counter", "1")
106
+ expect(@client.expire("counter", 600)).to be true
107
+ expect(@client.ttl("counter")).to eq(600)
108
+ expect(@client.incr("counter")).to eq(2)
109
+ expect(@client.ttl("counter")).to eq(600)
110
+ end
111
+
112
+ it "should decrement the integer value of a key by one" do
113
+ @client.set("counter", "1")
114
+ expect(@client.decr("counter")).to eq(0)
115
+
116
+ expect(@client.get("counter")).to eq("0")
117
+ end
118
+
119
+ it "should not change the expire value of the key during decr" do
120
+ @client.set("counter", "2")
121
+ expect(@client.expire("counter", 600)).to be true
122
+ expect(@client.ttl("counter")).to eq(600)
123
+ expect(@client.decr("counter")).to eq(1)
124
+ expect(@client.ttl("counter")).to eq(600)
125
+ end
126
+
127
+ it "should increment the integer value of a key by the given number" do
128
+ @client.set("counter", "10")
129
+ expect(@client.incrby("counter", "5")).to eq(15)
130
+ expect(@client.incrby("counter", 2)).to eq(17)
131
+ expect(@client.get("counter")).to eq("17")
132
+ end
133
+
134
+ it "should increment the float value of a key by the given number" do
135
+ @client.set("counter", 10.0)
136
+ expect(@client.incrbyfloat("counter", 2.1)).to eq(12.1)
137
+ expect(@client.get("counter")).to eq("12.1")
138
+ end
139
+
140
+ it "should not change the expire value of the key during incrby" do
141
+ @client.set("counter", "1")
142
+ expect(@client.expire("counter", 600)).to be true
143
+ expect(@client.ttl("counter")).to eq(600)
144
+ expect(@client.incrby("counter", "5")).to eq(6)
145
+ expect(@client.ttl("counter")).to eq(600)
146
+ end
147
+
148
+ it "should decrement the integer value of a key by the given number" do
149
+ @client.set("counter", "10")
150
+ expect(@client.decrby("counter", "5")).to eq(5)
151
+ expect(@client.decrby("counter", 2)).to eq(3)
152
+ expect(@client.get("counter")).to eq("3")
153
+ end
154
+
155
+ it "should not change the expire value of the key during decrby" do
156
+ @client.set("counter", "8")
157
+ expect(@client.expire("counter", 600)).to be true
158
+ expect(@client.ttl("counter")).to eq(600)
159
+ expect(@client.decrby("counter", "3")).to eq(5)
160
+ expect(@client.ttl("counter")).to eq(600)
161
+ end
162
+
163
+ it "should get the values of all the given keys" do
164
+ @client.set("key1", "value1")
165
+ @client.set("key2", "value2")
166
+ @client.set("key3", "value3")
167
+
168
+ expect(@client.mget("key1", "key2", "key3")).to eq(["value1", "value2", "value3"])
169
+ expect(@client.mget(["key1", "key2", "key3"])).to eq(["value1", "value2", "value3"])
170
+ end
171
+
172
+ it "returns nil for non existent keys" do
173
+ @client.set("key1", "value1")
174
+ @client.set("key3", "value3")
175
+
176
+ expect(@client.mget("key1", "key2", "key3", "key4")).to eq(["value1", nil, "value3", nil])
177
+ expect(@client.mget(["key1", "key2", "key3", "key4"])).to eq(["value1", nil, "value3", nil])
178
+ end
179
+
180
+ it 'raises an argument error when not passed any fields' do
181
+ @client.set("key3", "value3")
182
+
183
+ expect { @client.mget }.to raise_error(Redis::CommandError)
184
+ end
185
+
186
+ it "should set multiple keys to multiple values" do
187
+ @client.mset(:key1, "value1", :key2, "value2")
188
+
189
+ expect(@client.get("key1")).to eq("value1")
190
+ expect(@client.get("key2")).to eq("value2")
191
+ end
192
+
193
+ it "should raise error if command arguments count is wrong" do
194
+ expect { @client.mset }.to raise_error(Redis::CommandError, "ERR wrong number of arguments for 'mset' command")
195
+ expect { @client.mset(:key1) }.to raise_error(Redis::CommandError, "ERR wrong number of arguments for 'mset' command")
196
+ expect { @client.mset(:key1, "value", :key2) }.to raise_error(Redis::CommandError, "ERR wrong number of arguments for MSET")
197
+
198
+ expect(@client.get("key1")).to be_nil
199
+ expect(@client.get("key2")).to be_nil
200
+ end
201
+
202
+ it "should set multiple keys to multiple values, only if none of the keys exist" do
203
+ expect(@client.msetnx(:key1, "value1", :key2, "value2")).to eq(true)
204
+ expect(@client.msetnx(:key1, "value3", :key2, "value4")).to eq(false)
205
+
206
+ expect(@client.get("key1")).to eq("value1")
207
+ expect(@client.get("key2")).to eq("value2")
208
+ end
209
+
210
+ it "should set multiple keys to multiple values with a hash" do
211
+ @client.mapped_mset(:key1 => "value1", :key2 => "value2")
212
+
213
+ expect(@client.get("key1")).to eq("value1")
214
+ expect(@client.get("key2")).to eq("value2")
215
+ end
216
+
217
+ it "should set multiple keys to multiple values with a hash, only if none of the keys exist" do
218
+ expect(@client.mapped_msetnx(:key1 => "value1", :key2 => "value2")).to eq(true)
219
+ expect(@client.mapped_msetnx(:key1 => "value3", :key2 => "value4")).to eq(false)
220
+
221
+ expect(@client.get("key1")).to eq("value1")
222
+ expect(@client.get("key2")).to eq("value2")
223
+ end
224
+
225
+ it "should set the string value of a key" do
226
+ @client.set("key1", "1")
227
+
228
+ expect(@client.get("key1")).to eq("1")
229
+ end
230
+
231
+ it "should sets or clears the bit at offset in the string value stored at key" do
232
+ @client.set("key1", "abc")
233
+ @client.setbit("key1", 11, 1)
234
+
235
+ expect(@client.get("key1")).to eq("arc")
236
+ end
237
+
238
+ it "should set the value and expiration of a key" do
239
+ @client.setex("key1", 30, "value1")
240
+
241
+ expect(@client.get("key1")).to eq("value1")
242
+ expect(@client.ttl("key1")).to eq(30)
243
+ end
244
+
245
+ it "should set the value of a key, only if the key does not exist" do
246
+ @client.set("key1", "test value")
247
+ @client.setnx("key1", "new value")
248
+ @client.setnx("key2", "another value")
249
+
250
+ expect(@client.get("key1")).to eq("test value")
251
+ expect(@client.get("key2")).to eq("another value")
252
+ end
253
+
254
+ it "should overwrite part of a string at key starting at the specified offset" do
255
+ @client.set("key1", "Hello World")
256
+ @client.setrange("key1", 6, "Redis")
257
+
258
+ expect(@client.get("key1")).to eq("Hello Redis")
259
+ end
260
+
261
+ it "should get the length of the value stored in a key" do
262
+ @client.set("key1", "abc")
263
+
264
+ expect(@client.strlen("key1")).to eq(3)
265
+ end
266
+
267
+ it "should return 0 bits when there's no key" do
268
+ expect(@client.bitcount("key1")).to eq(0)
269
+ end
270
+
271
+ it "should count the number of bits of a string" do
272
+ @client.set("key1", "foobar")
273
+ expect(@client.bitcount("key1")).to eq(26)
274
+ end
275
+
276
+ it "should count correctly with UTF-8 strings" do
277
+ @client.set("key1", '判')
278
+ expect(@client.bitcount("key1")).to eq(10)
279
+ end
280
+
281
+ it "should count the number of bits of a string given a range" do
282
+ @client.set("key1", "foobar")
283
+
284
+ expect(@client.bitcount("key1", 0, 0)).to eq(4)
285
+ expect(@client.bitcount("key1", 1, 1)).to eq(6)
286
+ expect(@client.bitcount("key1", 0, 1)).to eq(10)
287
+ end
288
+ end
289
+ end
@@ -0,0 +1,107 @@
1
+ require 'spec_helper'
2
+ require 'timeout' #Need to use this avoid blocking
3
+
4
+ module FakeRedis
5
+ describe "SubscriptionMethods" do
6
+ before(:each) do
7
+ @client = Redis.new
8
+ end
9
+
10
+ context "publish" do
11
+ it "should add to channels" do
12
+ @client.publish("channel1", "val1").should be == 0
13
+ @client.publish("channel1", "val2").should be == 0
14
+ end
15
+ end
16
+
17
+ context "subscribe" do
18
+ it "should get all messages from a channel" do
19
+ @client.publish("channel1", "val1")
20
+ @client.publish("channel1", "val2")
21
+ @client.publish("channel2", "val3")
22
+
23
+ msgs = []
24
+ subscribe_sent = unsubscribe_sent = false
25
+ Timeout.timeout(1) do
26
+ @client.subscribe("channel1") do |on|
27
+ on.subscribe do |channel|
28
+ subscribe_sent = true
29
+ channel.should be == "channel1"
30
+ end
31
+
32
+ on.message do |channel,msg|
33
+ channel.should be == "channel1"
34
+ msgs << msg
35
+ end
36
+
37
+ on.unsubscribe do
38
+ unsubscribe_sent = true
39
+ end
40
+ end
41
+ end
42
+
43
+ msgs.should be == ["val1", "val2"]
44
+ subscribe_sent.should
45
+ unsubscribe_sent.should
46
+ end
47
+
48
+ it "should get all messages from multiple channels" do
49
+ @client.publish("channel1", "val1")
50
+ @client.publish("channel2", "val2")
51
+ @client.publish("channel2", "val3")
52
+
53
+ msgs = []
54
+ Timeout.timeout(1) do
55
+ @client.subscribe("channel1", "channel2") do |on|
56
+ on.message do |channel,msg|
57
+ msgs << [channel, msg]
58
+ end
59
+ end
60
+ end
61
+
62
+ msgs[0].should be == ["channel1", "val1"]
63
+ msgs[1].should be == ["channel2", "val2"]
64
+ msgs[2].should be == ["channel2", "val3"]
65
+ end
66
+ end
67
+
68
+ context "unsubscribe" do
69
+ end
70
+
71
+ context "with patterns" do
72
+ context "psubscribe" do
73
+ it "should get all messages using pattern" do
74
+ @client.publish("channel1", "val1")
75
+ @client.publish("channel1", "val2")
76
+ @client.publish("channel2", "val3")
77
+
78
+ msgs = []
79
+ subscribe_sent = unsubscribe_sent = false
80
+ Timeout.timeout(1) do
81
+ @client.psubscribe("channel*") do |on|
82
+ on.psubscribe do |channel|
83
+ subscribe_sent = true
84
+ end
85
+
86
+ on.pmessage do |pattern,channel,msg|
87
+ pattern.should be == "channel*"
88
+ msgs << msg
89
+ end
90
+
91
+ on.punsubscribe do
92
+ unsubscribe_sent = true
93
+ end
94
+ end
95
+ end
96
+
97
+ msgs.should be == ["val1", "val2", "val3"]
98
+ subscribe_sent.should
99
+ unsubscribe_sent.should
100
+ end
101
+ end
102
+
103
+ context "punsubscribe" do
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,59 @@
1
+ shared_examples_for "a bitwise operation" do |operator|
2
+ it 'raises an argument error when not passed any source keys' do
3
+ lambda { @client.bitop(operator, "destkey") }.should raise_error(Redis::CommandError)
4
+ end
5
+
6
+ it "should not create destination key if nothing found" do
7
+ @client.bitop(operator, "dest1", "nothing_here1").should be == 0
8
+ @client.exists("dest1").should be false
9
+ end
10
+
11
+ it "should accept operator as a case-insensitive symbol" do
12
+ @client.set("key1", "foobar")
13
+ @client.bitop(operator.to_s.downcase.to_sym, "dest1", "key1")
14
+ @client.bitop(operator.to_s.upcase.to_sym, "dest2", "key1")
15
+
16
+ @client.get("dest1").should be == "foobar"
17
+ @client.get("dest2").should be == "foobar"
18
+ end
19
+
20
+ it "should accept operator as a case-insensitive string" do
21
+ @client.set("key1", "foobar")
22
+ @client.bitop(operator.to_s.downcase, "dest1", "key1")
23
+ @client.bitop(operator.to_s.upcase, "dest2", "key1")
24
+
25
+ @client.get("dest1").should be == "foobar"
26
+ @client.get("dest2").should be == "foobar"
27
+ end
28
+
29
+ it "should copy original string for single key" do
30
+ @client.set("key1", "foobar")
31
+ @client.bitop(operator, "dest1", "key1")
32
+
33
+ @client.get("dest1").should be == "foobar"
34
+ end
35
+
36
+ it "should copy original string for single key" do
37
+ @client.set("key1", "foobar")
38
+ @client.bitop(operator, "dest1", "key1")
39
+
40
+ @client.get("dest1").should be == "foobar"
41
+ end
42
+
43
+ it "should return length of the string stored in the destination key" do
44
+ @client.set("key1", "foobar")
45
+ @client.set("key2", "baz")
46
+
47
+ @client.bitop(operator, "dest1", "key1").should be == 6
48
+ @client.bitop(operator, "dest2", "key2").should be == 3
49
+ end
50
+
51
+ it "should overwrite previous value with new one" do
52
+ @client.set("key1", "foobar")
53
+ @client.set("key2", "baz")
54
+ @client.bitop(operator, "dest1", "key1")
55
+ @client.bitop(operator, "dest1", "key2")
56
+
57
+ @client.get("dest1").should be == "baz"
58
+ end
59
+ end