fakeredis 0.5.0 → 0.8.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 +5 -5
  2. data/.gitignore +3 -0
  3. data/.travis.yml +14 -5
  4. data/LICENSE +1 -1
  5. data/README.md +42 -24
  6. data/fakeredis.gemspec +1 -1
  7. data/lib/fakeredis.rb +28 -0
  8. data/lib/fakeredis/bitop_command.rb +56 -0
  9. data/lib/fakeredis/command_executor.rb +6 -9
  10. data/lib/fakeredis/expiring_hash.rb +3 -5
  11. data/lib/fakeredis/geo_commands.rb +142 -0
  12. data/lib/fakeredis/geo_set.rb +84 -0
  13. data/lib/fakeredis/minitest.rb +24 -0
  14. data/lib/fakeredis/rspec.rb +1 -0
  15. data/lib/fakeredis/sort_method.rb +3 -3
  16. data/lib/fakeredis/sorted_set_store.rb +1 -1
  17. data/lib/fakeredis/transaction_commands.rb +2 -2
  18. data/lib/fakeredis/version.rb +1 -1
  19. data/lib/fakeredis/zset.rb +8 -2
  20. data/lib/redis/connection/memory.rb +650 -82
  21. data/spec/bitop_command_spec.rb +209 -0
  22. data/spec/command_executor_spec.rb +15 -0
  23. data/spec/compatibility_spec.rb +1 -1
  24. data/spec/connection_spec.rb +21 -21
  25. data/spec/fakeredis_spec.rb +73 -0
  26. data/spec/geo_set_spec.rb +164 -0
  27. data/spec/hashes_spec.rb +138 -57
  28. data/spec/hyper_log_logs_spec.rb +50 -0
  29. data/spec/keys_spec.rb +232 -90
  30. data/spec/lists_spec.rb +91 -35
  31. data/spec/memory_spec.rb +80 -7
  32. data/spec/server_spec.rb +38 -24
  33. data/spec/sets_spec.rb +112 -46
  34. data/spec/sort_method_spec.rb +6 -0
  35. data/spec/sorted_sets_spec.rb +482 -150
  36. data/spec/spec_helper.rb +9 -18
  37. data/spec/spec_helper_live_redis.rb +4 -4
  38. data/spec/strings_spec.rb +113 -79
  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 +20 -16
  42. data/spec/transactions_spec.rb +34 -13
  43. data/spec/upcase_method_name_spec.rb +2 -2
  44. metadata +23 -6
data/spec/hashes_spec.rb CHANGED
@@ -9,168 +9,194 @@ module FakeRedis
9
9
  it "should delete a hash field" do
10
10
  @client.hset("key1", "k1", "val1")
11
11
  @client.hset("key1", "k2", "val2")
12
- @client.hdel("key1", "k1").should be(1)
12
+ expect(@client.hdel("key1", "k1")).to be(1)
13
13
 
14
- @client.hget("key1", "k1").should be_nil
15
- @client.hget("key1", "k2").should be == "val2"
14
+ expect(@client.hget("key1", "k1")).to be_nil
15
+ expect(@client.hget("key1", "k2")).to eq("val2")
16
+ end
17
+
18
+ it "should delete array of fields" do
19
+ @client.hset("key1", "k1", "val1")
20
+ @client.hset("key1", "k2", "val2")
21
+ @client.hset("key1", "k3", "val3")
22
+ expect(@client.hdel("key1", ["k1", "k2"])).to be(2)
23
+
24
+ expect(@client.hget("key1", "k1")).to be_nil
25
+ expect(@client.hget("key1", "k2")).to be_nil
26
+ expect(@client.hget("key1", "k3")).to eq("val3")
16
27
  end
17
28
 
18
29
  it "should remove a hash with no keys left" do
19
30
  @client.hset("key1", "k1", "val1")
20
31
  @client.hset("key1", "k2", "val2")
21
- @client.hdel("key1", "k1").should be(1)
22
- @client.hdel("key1", "k2").should be(1)
32
+ expect(@client.hdel("key1", "k1")).to be(1)
33
+ expect(@client.hdel("key1", "k2")).to be(1)
23
34
 
24
- @client.exists("key1").should be == false
35
+ expect(@client.exists("key1")).to eq(false)
25
36
  end
26
37
 
27
38
  it "should convert key to a string for hset" do
28
39
  m = double("key")
29
- m.stub(:to_s).and_return("foo")
40
+ allow(m).to receive(:to_s).and_return("foo")
30
41
 
31
42
  @client.hset("key1", m, "bar")
32
- @client.hget("key1", "foo").should be == "bar"
43
+ expect(@client.hget("key1", "foo")).to eq("bar")
33
44
  end
34
45
 
35
46
  it "should convert key to a string for hget" do
36
47
  m = double("key")
37
- m.stub(:to_s).and_return("foo")
48
+ allow(m).to receive(:to_s).and_return("foo")
38
49
 
39
50
  @client.hset("key1", "foo", "bar")
40
- @client.hget("key1", m).should be == "bar"
51
+ expect(@client.hget("key1", m)).to eq("bar")
41
52
  end
42
53
 
43
54
  it "should determine if a hash field exists" do
44
55
  @client.hset("key1", "index", "value")
45
56
 
46
- @client.hexists("key1", "index").should be true
47
- @client.hexists("key2", "i2").should be false
57
+ expect(@client.hexists("key1", "index")).to be true
58
+ expect(@client.hexists("key2", "i2")).to be false
48
59
  end
49
60
 
50
61
  it "should get the value of a hash field" do
51
62
  @client.hset("key1", "index", "value")
52
63
 
53
- @client.hget("key1", "index").should be == "value"
64
+ expect(@client.hget("key1", "index")).to eq("value")
54
65
  end
55
66
 
56
67
  it "should get all the fields and values in a hash" do
57
68
  @client.hset("key1", "i1", "val1")
58
69
  @client.hset("key1", "i2", "val2")
59
70
 
60
- @client.hgetall("key1").should be == {"i1" => "val1", "i2" => "val2"}
71
+ expect(@client.hgetall("key1")).to eq({"i1" => "val1", "i2" => "val2"})
61
72
  end
62
73
 
63
74
  it "should increment the integer value of a hash field by the given number" do
64
75
  @client.hset("key1", "cont1", "5")
65
- @client.hincrby("key1", "cont1", "5").should be == 10
66
- @client.hget("key1", "cont1").should be == "10"
76
+ expect(@client.hincrby("key1", "cont1", "5")).to eq(10)
77
+ expect(@client.hget("key1", "cont1")).to eq("10")
67
78
  end
68
79
 
69
80
  it "should increment non existing hash keys" do
70
- @client.hget("key1", "cont2").should be_nil
71
- @client.hincrby("key1", "cont2", "5").should be == 5
81
+ expect(@client.hget("key1", "cont2")).to be_nil
82
+ expect(@client.hincrby("key1", "cont2", "5")).to eq(5)
72
83
  end
73
84
 
74
85
  it "should increment the float value of a hash field by the given float" do
75
86
  @client.hset("key1", "cont1", 5.0)
76
- @client.hincrbyfloat("key1", "cont1", 4.1).should be == 9.1
77
- @client.hget("key1", "cont1").should be == "9.1"
87
+ expect(@client.hincrbyfloat("key1", "cont1", 4.1)).to eq(9.1)
88
+ expect(@client.hget("key1", "cont1")).to eq("9.1")
78
89
  end
79
90
 
80
91
  it "should increment non existing hash keys" do
81
- @client.hget("key1", "cont2").should be_nil
82
- @client.hincrbyfloat("key1", "cont2", 5.5).should be == 5.5
92
+ expect(@client.hget("key1", "cont2")).to be_nil
93
+ expect(@client.hincrbyfloat("key1", "cont2", 5.5)).to eq(5.5)
83
94
  end
84
95
 
85
96
  it "should get all the fields in a hash" do
86
97
  @client.hset("key1", "i1", "val1")
87
98
  @client.hset("key1", "i2", "val2")
88
99
 
89
- @client.hkeys("key1").should =~ ["i1", "i2"]
90
- @client.hkeys("key2").should be == []
100
+ expect(@client.hkeys("key1")).to match_array(["i1", "i2"])
101
+ expect(@client.hkeys("key2")).to eq([])
91
102
  end
92
103
 
93
104
  it "should get the number of fields in a hash" do
94
105
  @client.hset("key1", "i1", "val1")
95
106
  @client.hset("key1", "i2", "val2")
96
107
 
97
- @client.hlen("key1").should be == 2
108
+ expect(@client.hlen("key1")).to eq(2)
109
+ end
110
+
111
+ it "should get the string length of the value associated with field in a hash" do
112
+ @client.hset("key1", "i1", "val1")
113
+ expect(@client.hstrlen("key1", "i1")).to eq(4)
114
+ expect(@client.hstrlen("key1", "nonexistent")).to eq(0)
115
+ expect(@client.hstrlen("nonexistent", "field")).to eq(0)
98
116
  end
99
117
 
100
118
  it "should get the values of all the given hash fields" do
101
119
  @client.hset("key1", "i1", "val1")
102
120
  @client.hset("key1", "i2", "val2")
103
121
 
104
- @client.hmget("key1", "i1", "i2", "i3").should =~ ["val1", "val2", nil]
105
- @client.hmget("key1", ["i1", "i2", "i3"]).should =~ ["val1", "val2", nil]
122
+ expect(@client.hmget("key1", "i1", "i2", "i3")).to match_array(["val1", "val2", nil])
123
+ expect(@client.hmget("key1", ["i1", "i2", "i3"])).to match_array(["val1", "val2", nil])
106
124
 
107
- @client.hmget("key2", "i1", "i2").should be == [nil, nil]
125
+ expect(@client.hmget("key2", "i1", "i2")).to eq([nil, nil])
108
126
  end
109
127
 
110
128
  it "should throw an argument error when you don't ask for any keys" do
111
- lambda { @client.hmget("key1") }.should raise_error(Redis::CommandError)
129
+ expect { @client.hmget("key1") }.to raise_error(Redis::CommandError)
130
+ end
131
+
132
+ it "should throw an argument error when the list of keys you ask for is empty" do
133
+ expect { @client.hmget("key1", []) }.to raise_error(Redis::CommandError)
112
134
  end
113
135
 
114
136
  it "should reject an empty list of values" do
115
- lambda { @client.hmset("key") }.should raise_error(Redis::CommandError)
116
- @client.exists("key").should be false
137
+ expect { @client.hmset("key") }.to raise_error(Redis::CommandError)
138
+ expect(@client.exists("key")).to be false
117
139
  end
118
140
 
119
141
  it "rejects an insert with a key but no value" do
120
- lambda { @client.hmset("key", 'foo') }.should raise_error(Redis::CommandError)
121
- lambda { @client.hmset("key", 'foo', 3, 'bar') }.should raise_error(Redis::CommandError)
122
- @client.exists("key").should be false
142
+ expect { @client.hmset("key", 'foo') }.to raise_error(Redis::CommandError)
143
+ expect { @client.hmset("key", 'foo', 3, 'bar') }.to raise_error(Redis::CommandError)
144
+ expect(@client.exists("key")).to be false
123
145
  end
124
146
 
125
147
  it "should reject the wrong number of arguments" do
126
- lambda { @client.hmset("hash", "foo1", "bar1", "foo2", "bar2", "foo3") }.should raise_error(Redis::CommandError, "ERR wrong number of arguments for HMSET")
148
+ expect { @client.hmset("hash", "foo1", "bar1", "foo2", "bar2", "foo3") }.to raise_error(Redis::CommandError, "ERR wrong number of arguments for HMSET")
149
+ end
150
+
151
+ it "should return OK on success" do
152
+ expect(@client.hmset("key", "k1", "value1")).to eq("OK")
127
153
  end
128
154
 
129
155
  it "should set multiple hash fields to multiple values" do
130
156
  @client.hmset("key", "k1", "value1", "k2", "value2")
131
157
 
132
- @client.hget("key", "k1").should be == "value1"
133
- @client.hget("key", "k2").should be == "value2"
158
+ expect(@client.hget("key", "k1")).to eq("value1")
159
+ expect(@client.hget("key", "k2")).to eq("value2")
134
160
  end
135
161
 
136
162
  it "should set multiple hash fields from a ruby hash to multiple values" do
137
163
  @client.mapped_hmset("foo", :k1 => "value1", :k2 => "value2")
138
164
 
139
- @client.hget("foo", "k1").should be == "value1"
140
- @client.hget("foo", "k2").should be == "value2"
165
+ expect(@client.hget("foo", "k1")).to eq("value1")
166
+ expect(@client.hget("foo", "k2")).to eq("value2")
141
167
  end
142
168
 
143
169
  it "should set the string value of a hash field" do
144
- @client.hset("key1", "k1", "val1").should be == true
145
- @client.hset("key1", "k1", "val1").should be == false
170
+ expect(@client.hset("key1", "k1", "val1")).to eq(true)
171
+ expect(@client.hset("key1", "k1", "val1")).to eq(false)
146
172
 
147
- @client.hget("key1", "k1").should be == "val1"
173
+ expect(@client.hget("key1", "k1")).to eq("val1")
148
174
  end
149
175
 
150
176
  it "should set the value of a hash field, only if the field does not exist" do
151
177
  @client.hset("key1", "k1", "val1")
152
- @client.hsetnx("key1", "k1", "value").should be == false
153
- @client.hsetnx("key1", "k2", "val2").should be == true
154
- @client.hsetnx("key1", :k1, "value").should be == false
155
- @client.hsetnx("key1", :k3, "val3").should be == true
156
-
157
- @client.hget("key1", "k1").should be == "val1"
158
- @client.hget("key1", "k2").should be == "val2"
159
- @client.hget("key1", "k3").should be == "val3"
178
+ expect(@client.hsetnx("key1", "k1", "value")).to eq(false)
179
+ expect(@client.hsetnx("key1", "k2", "val2")).to eq(true)
180
+ expect(@client.hsetnx("key1", :k1, "value")).to eq(false)
181
+ expect(@client.hsetnx("key1", :k3, "val3")).to eq(true)
182
+
183
+ expect(@client.hget("key1", "k1")).to eq("val1")
184
+ expect(@client.hget("key1", "k2")).to eq("val2")
185
+ expect(@client.hget("key1", "k3")).to eq("val3")
160
186
  end
161
187
 
162
188
  it "should get all the values in a hash" do
163
189
  @client.hset("key1", "k1", "val1")
164
190
  @client.hset("key1", "k2", "val2")
165
191
 
166
- @client.hvals("key1").should =~ ["val1", "val2"]
192
+ expect(@client.hvals("key1")).to match_array(["val1", "val2"])
167
193
  end
168
194
 
169
195
  it "should accept a list of array pairs as arguments and not throw an invalid argument number error" do
170
196
  @client.hmset("key1", [:k1, "val1"], [:k2, "val2"], [:k3, "val3"])
171
- @client.hget("key1", :k1).should be == "val1"
172
- @client.hget("key1", :k2).should be == "val2"
173
- @client.hget("key1", :k3).should be == "val3"
197
+ expect(@client.hget("key1", :k1)).to eq("val1")
198
+ expect(@client.hget("key1", :k2)).to eq("val2")
199
+ expect(@client.hget("key1", :k3)).to eq("val3")
174
200
  end
175
201
 
176
202
  it "should reject a list of arrays that contain an invalid number of arguments" do
@@ -179,17 +205,72 @@ module FakeRedis
179
205
 
180
206
  it "should convert a integer field name to string for hdel" do
181
207
  @client.hset("key1", "1", 1)
182
- @client.hdel("key1", 1).should be(1)
208
+ expect(@client.hdel("key1", 1)).to be(1)
183
209
  end
184
210
 
185
211
  it "should convert a integer field name to string for hexists" do
186
212
  @client.hset("key1", "1", 1)
187
- @client.hexists("key1", 1).should be true
213
+ expect(@client.hexists("key1", 1)).to be true
188
214
  end
189
215
 
190
216
  it "should convert a integer field name to string for hincrby" do
191
217
  @client.hset("key1", 1, 0)
192
- @client.hincrby("key1", 1, 1).should be(1)
218
+ expect(@client.hincrby("key1", 1, 1)).to be(1)
219
+ end
220
+
221
+ describe "#hscan" do
222
+ it 'with no arguments and few items, returns all items' do
223
+ @client.hmset('hash', 'name', 'Jack', 'age', '33')
224
+ result = @client.hscan('hash', 0)
225
+
226
+ expect(result[0]).to eq('0')
227
+ expect(result[1]).to eq([['name', 'Jack'], ['age', '33']])
228
+ end
229
+
230
+ it 'with a count should return that number of members or more' do
231
+ @client.hmset('hash',
232
+ 'a', '1', 'b', '2', 'c', '3', 'd', '4', 'e', '5', 'f', '6', 'g', '7'
233
+ )
234
+ result = @client.hscan('hash', 0, count: 3)
235
+ expect(result[0]).to eq('3')
236
+ expect(result[1]).to eq([
237
+ ['a', '1'],
238
+ ['b', '2'],
239
+ ['c', '3'],
240
+ ])
241
+ end
242
+
243
+ it 'returns items starting at the provided cursor' do
244
+ @client.hmset('hash',
245
+ 'a', '1', 'b', '2', 'c', '3', 'd', '4', 'e', '5', 'f', '6', 'g', '7'
246
+ )
247
+ result = @client.hscan('hash', 2, count: 3)
248
+ expect(result[0]).to eq('5')
249
+ expect(result[1]).to eq([
250
+ ['c', '3'],
251
+ ['d', '4'],
252
+ ['e', '5']
253
+ ])
254
+ end
255
+
256
+ it 'with match, returns items matching the given pattern' do
257
+ @client.hmset('hash',
258
+ 'aa', '1', 'b', '2', 'cc', '3', 'd', '4', 'ee', '5', 'f', '6', 'gg', '7'
259
+ )
260
+ result = @client.hscan('hash', 2, count: 3, match: '??')
261
+ expect(result[0]).to eq('5')
262
+ expect(result[1]).to eq([
263
+ ['cc', '3'],
264
+ ['ee', '5']
265
+ ])
266
+ end
267
+
268
+ it 'returns an empty result if the key is not found' do
269
+ result = @client.hscan('hash', 0)
270
+
271
+ expect(result[0]).to eq('0')
272
+ expect(result[1]).to eq([])
273
+ end
193
274
  end
194
275
  end
195
276
  end
@@ -0,0 +1,50 @@
1
+ require "spec_helper"
2
+
3
+ module FakeRedis
4
+ describe "HyperLogLogsMethods" do
5
+ let(:redis) { Redis.new }
6
+
7
+ it "should add item to hyperloglog" do
8
+ expect(redis.pfadd("hll", "val")).to eq(true)
9
+ expect(redis.pfcount("hll")).to eq(1)
10
+ end
11
+
12
+ it "should not add duplicated item to hyperloglog" do
13
+ redis.pfadd("hll", "val")
14
+ expect(redis.pfadd("hll", "val")).to eq(false)
15
+ expect(redis.pfcount("hll")).to eq(1)
16
+ end
17
+
18
+ it "should not add multiple items to hyperloglog" do
19
+ expect(redis.pfadd("hll", ["val1", "val2"])).to eq(true)
20
+ expect(redis.pfcount("hll")).to eq(2)
21
+ end
22
+
23
+ it "should return zero as cardinality for nonexistent key" do
24
+ expect(redis.pfcount("nonexistent")).to eq(0)
25
+ end
26
+
27
+ it "should return cardinality of union of hyperloglogs" do
28
+ redis.pfadd("hll1", ["val1", "val2"])
29
+ redis.pfadd("hll2", ["val2", "val3"])
30
+ expect(redis.pfcount("hll1", "hll2")).to eq(3)
31
+ end
32
+
33
+ it "should error if an empty list of keys is given" do
34
+ expect { redis.pfcount([]) }.to raise_error(Redis::CommandError, "ERR wrong number of arguments for 'pfcount' command")
35
+ end
36
+
37
+ it "should merge hyperloglogs" do
38
+ redis.pfadd("hll1", ["val1", "val2"])
39
+ redis.pfadd("hll2", ["val2", "val3"])
40
+ expect(redis.pfmerge("hll3", "hll1", "hll2")).to eq(true)
41
+ expect(redis.pfcount("hll3")).to eq(3)
42
+ end
43
+
44
+ it "should merge nonexistent hyperloglogs with others" do
45
+ redis.pfadd("hll1", "val")
46
+ expect(redis.pfmerge("hll3", "hll1", "nonexistent")).to eq(true)
47
+ expect(redis.pfcount("hll3")).to eq(1)
48
+ end
49
+ end
50
+ end
data/spec/keys_spec.rb CHANGED
@@ -7,56 +7,89 @@ module FakeRedis
7
7
  @client = Redis.new
8
8
  end
9
9
 
10
- it "should delete a key" do
11
- @client.set("key1", "1")
12
- @client.set("key2", "2")
13
- @client.del("key1", "key2")
10
+ [:del, :unlink].each do |command|
11
+ it "should #{command} a key" do
12
+ @client.set("key1", "1")
13
+ @client.set("key2", "2")
14
+ @client.public_send(command, "key1", "key2")
14
15
 
15
- @client.get("key1").should be == nil
16
- end
16
+ expect(@client.get("key1")).to eq(nil)
17
+ end
17
18
 
18
- it "should delete multiple keys" do
19
- @client.set("key1", "1")
20
- @client.set("key2", "2")
21
- @client.del(["key1", "key2"])
19
+ it "should #{command} multiple keys" do
20
+ @client.set("key1", "1")
21
+ @client.set("key2", "2")
22
+ @client.public_send(command, ["key1", "key2"])
22
23
 
23
- @client.get("key1").should be == nil
24
- @client.get("key2").should be == nil
24
+ expect(@client.get("key1")).to eq(nil)
25
+ expect(@client.get("key2")).to eq(nil)
26
+ end
27
+
28
+ it "should return the number of '#{command}'ed keys" do
29
+ @client.set("key1", "1")
30
+ expect(@client.public_send(command, ["key1", "key2"])).to eq(1)
31
+ end
32
+
33
+ it "should error '#{command}'ing no keys" do
34
+ expect { @client.public_send(command) }.to raise_error(Redis::CommandError, "ERR wrong number of arguments for '#{command}' command")
35
+ expect { @client.public_send(command, []) }.to raise_error(Redis::CommandError, "ERR wrong number of arguments for '#{command}' command")
36
+ end
37
+ end
38
+
39
+ it "should return true when setnx keys that don't exist" do
40
+ expect(@client.setnx("key1", "1")).to eq(true)
25
41
  end
26
42
 
27
- it "should error deleting no keys" do
28
- lambda { @client.del }.should raise_error(Redis::CommandError, "ERR wrong number of arguments for 'del' command")
29
- lambda { @client.del [] }.should raise_error(Redis::CommandError, "ERR wrong number of arguments for 'del' command")
43
+ it "should return false when setnx keys exist" do
44
+ @client.set("key1", "1")
45
+ expect(@client.setnx("key1", "1")).to eq(false)
30
46
  end
31
47
 
32
48
  it "should return true when setting expires on keys that exist" do
33
49
  @client.set("key1", "1")
34
- @client.expire("key1", 1).should == true
50
+ expect(@client.expire("key1", 1)).to eq(true)
51
+ end
52
+
53
+ it "should return true when setting pexpires on keys that exist" do
54
+ @client.set("key1", "1")
55
+ expect(@client.pexpire("key1", 1)).to eq(true)
35
56
  end
36
57
 
37
58
  it "should return false when attempting to set expires on a key that does not exist" do
38
- @client.expire("key1", 1).should == false
59
+ expect(@client.expire("key1", 1)).to eq(false)
60
+ end
61
+
62
+ it "should return false when attempting to set pexpires on a key that does not exist" do
63
+ expect(@client.pexpire("key1", 1)).to eq(false)
39
64
  end
40
65
 
41
66
  it "should determine if a key exists" do
42
67
  @client.set("key1", "1")
43
68
 
44
- @client.exists("key1").should be == true
45
- @client.exists("key2").should be == false
69
+ expect(@client.exists("key1")).to eq(true)
70
+ expect(@client.exists("key2")).to eq(false)
46
71
  end
47
72
 
48
73
  it "should set a key's time to live in seconds" do
49
74
  @client.set("key1", "1")
50
75
  @client.expire("key1", 1)
51
76
 
52
- @client.ttl("key1").should be == 1
77
+ expect(@client.ttl("key1")).to eq(1)
78
+ end
79
+
80
+ it "should set a key's time to live in miliseconds" do
81
+ allow(Time).to receive(:now).and_return(1000)
82
+ @client.set("key1", "1")
83
+ @client.pexpire("key1", 2200)
84
+ expect(@client.pttl("key1")).to be_within(0.1).of(2200)
85
+ allow(Time).to receive(:now).and_call_original
53
86
  end
54
87
 
55
88
  it "should set the expiration for a key as a UNIX timestamp" do
56
89
  @client.set("key1", "1")
57
90
  @client.expireat("key1", Time.now.to_i + 2)
58
91
 
59
- @client.ttl("key1").should be == 2
92
+ expect(@client.ttl("key1")).to eq(2)
60
93
  end
61
94
 
62
95
  it "should not have an expiration after re-set" do
@@ -64,21 +97,21 @@ module FakeRedis
64
97
  @client.expireat("key1", Time.now.to_i + 2)
65
98
  @client.set("key1", "1")
66
99
 
67
- @client.ttl("key1").should be == -1
100
+ expect(@client.ttl("key1")).to eq(-1)
68
101
  end
69
102
 
70
103
  it "should not have a ttl if expired (and thus key does not exist)" do
71
104
  @client.set("key1", "1")
72
105
  @client.expireat("key1", Time.now.to_i)
73
106
 
74
- @client.ttl("key1").should be == -2
107
+ expect(@client.ttl("key1")).to eq(-2)
75
108
  end
76
109
 
77
110
  it "should not find a key if expired" do
78
111
  @client.set("key1", "1")
79
112
  @client.expireat("key1", Time.now.to_i)
80
113
 
81
- @client.get("key1").should be_nil
114
+ expect(@client.get("key1")).to be_nil
82
115
  end
83
116
 
84
117
  it "should not find multiple keys if expired" do
@@ -86,7 +119,7 @@ module FakeRedis
86
119
  @client.set("key2", "2")
87
120
  @client.expireat("key1", Time.now.to_i)
88
121
 
89
- @client.mget("key1", "key2").should be == [nil, "2"]
122
+ expect(@client.mget("key1", "key2")).to eq([nil, "2"])
90
123
  end
91
124
 
92
125
  it "should only find keys that aren't expired" do
@@ -94,14 +127,21 @@ module FakeRedis
94
127
  @client.set("key2", "2")
95
128
  @client.expireat("key1", Time.now.to_i)
96
129
 
97
- @client.keys.should be == ["key2"]
130
+ expect(@client.keys).to eq(["key2"])
98
131
  end
99
132
 
100
133
  it "should not exist if expired" do
101
134
  @client.set("key1", "1")
102
135
  @client.expireat("key1", Time.now.to_i)
103
136
 
104
- @client.exists("key1").should be false
137
+ expect(@client.exists("key1")).to be false
138
+ end
139
+
140
+ it "should get integer and string keys" do
141
+ @client.set("key1", "1")
142
+ @client.set(2, "2")
143
+
144
+ expect(@client.mget("key1", 2)).to eq(["1", "2"])
105
145
  end
106
146
 
107
147
  it "should find all keys matching the given pattern" do
@@ -113,32 +153,32 @@ module FakeRedis
113
153
 
114
154
  @client.mset("database", 1, "above", 2, "suitability", 3, "able", 4)
115
155
 
116
- @client.keys("key:*").should =~ ["key:a", "key:b", "key:c"]
117
- @client.keys("ab*").should =~ ["above", "able"]
156
+ expect(@client.keys("key:*")).to match_array(["key:a", "key:b", "key:c"])
157
+ expect(@client.keys("ab*")).to match_array(["above", "able"])
118
158
  end
119
159
 
120
160
  it "should remove the expiration from a key" do
121
161
  @client.set("key1", "1")
122
162
  @client.expireat("key1", Time.now.to_i + 1)
123
- @client.persist("key1").should be == true
124
- @client.persist("key1").should be == false
163
+ expect(@client.persist("key1")).to eq(true)
164
+ expect(@client.persist("key1")).to eq(false)
125
165
 
126
- @client.ttl("key1").should be == -1
166
+ expect(@client.ttl("key1")).to eq(-1)
127
167
  end
128
168
 
129
169
  it "should return a random key from the keyspace" do
130
170
  @client.set("key1", "1")
131
171
  @client.set("key2", "2")
132
172
 
133
- ["key1", "key2"].include?(@client.randomkey).should be == true
173
+ expect(["key1", "key2"].include?(@client.randomkey)).to eq(true)
134
174
  end
135
175
 
136
176
  it "should rename a key" do
137
177
  @client.set("key1", "2")
138
178
  @client.rename("key1", "key2")
139
179
 
140
- @client.get("key1").should be == nil
141
- @client.get("key2").should be == "2"
180
+ expect(@client.get("key1")).to eq(nil)
181
+ expect(@client.get("key2")).to eq("2")
142
182
  end
143
183
 
144
184
  it "should rename a key, only if new key does not exist" do
@@ -148,100 +188,100 @@ module FakeRedis
148
188
  @client.renamenx("key1", "key2")
149
189
  @client.renamenx("key3", "key4")
150
190
 
151
- @client.get("key1").should be == "1"
152
- @client.get("key2").should be == "2"
153
- @client.get("key3").should be == nil
154
- @client.get("key4").should be == "3"
191
+ expect(@client.get("key1")).to eq("1")
192
+ expect(@client.get("key2")).to eq("2")
193
+ expect(@client.get("key3")).to eq(nil)
194
+ expect(@client.get("key4")).to eq("3")
155
195
  end
156
196
 
157
197
  it "should determine the type stored at key" do
158
198
  # Non-existing key
159
- @client.type("key0").should be == "none"
199
+ expect(@client.type("key0")).to eq("none")
160
200
 
161
201
  # String
162
202
  @client.set("key1", "1")
163
- @client.type("key1").should be == "string"
203
+ expect(@client.type("key1")).to eq("string")
164
204
 
165
205
  # List
166
206
  @client.lpush("key2", "1")
167
- @client.type("key2").should be == "list"
207
+ expect(@client.type("key2")).to eq("list")
168
208
 
169
209
  # Set
170
210
  @client.sadd("key3", "1")
171
- @client.type("key3").should be == "set"
211
+ expect(@client.type("key3")).to eq("set")
172
212
 
173
213
  # Sorted Set
174
214
  @client.zadd("key4", 1.0, "1")
175
- @client.type("key4").should be == "zset"
215
+ expect(@client.type("key4")).to eq("zset")
176
216
 
177
217
  # Hash
178
218
  @client.hset("key5", "a", "1")
179
- @client.type("key5").should be == "hash"
219
+ expect(@client.type("key5")).to eq("hash")
180
220
  end
181
221
 
182
222
  it "should convert the value into a string before storing" do
183
223
  @client.set("key1", 1)
184
- @client.get("key1").should be == "1"
224
+ expect(@client.get("key1")).to eq("1")
185
225
 
186
226
  @client.setex("key2", 30, 1)
187
- @client.get("key2").should be == "1"
227
+ expect(@client.get("key2")).to eq("1")
188
228
 
189
229
  @client.getset("key3", 1)
190
- @client.get("key3").should be == "1"
230
+ expect(@client.get("key3")).to eq("1")
191
231
  end
192
232
 
193
233
  it "should return 'OK' for the setex command" do
194
- @client.setex("key4", 30, 1).should be == "OK"
234
+ expect(@client.setex("key4", 30, 1)).to eq("OK")
195
235
  end
196
236
 
197
237
  it "should convert the key into a string before storing" do
198
238
  @client.set(123, "foo")
199
- @client.keys.should include("123")
200
- @client.get("123").should be == "foo"
239
+ expect(@client.keys).to include("123")
240
+ expect(@client.get("123")).to eq("foo")
201
241
 
202
242
  @client.setex(456, 30, "foo")
203
- @client.keys.should include("456")
204
- @client.get("456").should be == "foo"
243
+ expect(@client.keys).to include("456")
244
+ expect(@client.get("456")).to eq("foo")
205
245
 
206
246
  @client.getset(789, "foo")
207
- @client.keys.should include("789")
208
- @client.get("789").should be == "foo"
247
+ expect(@client.keys).to include("789")
248
+ expect(@client.get("789")).to eq("foo")
209
249
  end
210
250
 
211
251
  it "should only operate against keys containing string values" do
212
252
  @client.sadd("key1", "one")
213
- lambda { @client.get("key1") }.should raise_error(Redis::CommandError, "WRONGTYPE Operation against a key holding the wrong kind of value")
214
- lambda { @client.getset("key1", 1) }.should raise_error(Redis::CommandError, "WRONGTYPE Operation against a key holding the wrong kind of value")
253
+ expect { @client.get("key1") }.to raise_error(Redis::CommandError, "WRONGTYPE Operation against a key holding the wrong kind of value")
254
+ expect { @client.getset("key1", 1) }.to raise_error(Redis::CommandError, "WRONGTYPE Operation against a key holding the wrong kind of value")
215
255
 
216
256
  @client.hset("key2", "one", "two")
217
- lambda { @client.get("key2") }.should raise_error(Redis::CommandError, "WRONGTYPE Operation against a key holding the wrong kind of value")
218
- lambda { @client.getset("key2", 1) }.should raise_error(Redis::CommandError, "WRONGTYPE Operation against a key holding the wrong kind of value")
257
+ expect { @client.get("key2") }.to raise_error(Redis::CommandError, "WRONGTYPE Operation against a key holding the wrong kind of value")
258
+ expect { @client.getset("key2", 1) }.to raise_error(Redis::CommandError, "WRONGTYPE Operation against a key holding the wrong kind of value")
219
259
  end
220
260
 
221
261
  it "should move a key from one database to another successfully" do
222
262
  @client.select(0)
223
263
  @client.set("key1", "1")
224
264
 
225
- @client.move("key1", 1).should be == true
265
+ expect(@client.move("key1", 1)).to eq(true)
226
266
 
227
267
  @client.select(0)
228
- @client.get("key1").should be_nil
268
+ expect(@client.get("key1")).to be_nil
229
269
 
230
270
  @client.select(1)
231
- @client.get("key1").should be == "1"
271
+ expect(@client.get("key1")).to eq("1")
232
272
  end
233
273
 
234
274
  it "should fail to move a key that does not exist in the source database" do
235
275
  @client.select(0)
236
- @client.get("key1").should be_nil
276
+ expect(@client.get("key1")).to be_nil
237
277
 
238
- @client.move("key1", 1).should be == false
278
+ expect(@client.move("key1", 1)).to eq(false)
239
279
 
240
280
  @client.select(0)
241
- @client.get("key1").should be_nil
281
+ expect(@client.get("key1")).to be_nil
242
282
 
243
283
  @client.select(1)
244
- @client.get("key1").should be_nil
284
+ expect(@client.get("key1")).to be_nil
245
285
  end
246
286
 
247
287
  it "should fail to move a key that exists in the destination database" do
@@ -252,23 +292,23 @@ module FakeRedis
252
292
  @client.set("key1", "2")
253
293
 
254
294
  @client.select(0)
255
- @client.move("key1", 1).should be == false
295
+ expect(@client.move("key1", 1)).to eq(false)
256
296
 
257
297
  @client.select(0)
258
- @client.get("key1").should be == "1"
298
+ expect(@client.get("key1")).to eq("1")
259
299
 
260
300
  @client.select(1)
261
- @client.get("key1").should be == "2"
301
+ expect(@client.get("key1")).to eq("2")
262
302
  end
263
303
 
264
304
  it "should fail to move a key to the same database" do
265
305
  @client.select(0)
266
306
  @client.set("key1", "1")
267
307
 
268
- lambda { @client.move("key1", 0) }.should raise_error(Redis::CommandError, "ERR source and destination objects are the same")
308
+ expect { @client.move("key1", 0) }.to raise_error(Redis::CommandError, "ERR source and destination objects are the same")
269
309
 
270
310
  @client.select(0)
271
- @client.get("key1").should be == "1"
311
+ expect(@client.get("key1")).to eq("1")
272
312
  end
273
313
 
274
314
  it "should scan all keys in the database" do
@@ -284,8 +324,8 @@ module FakeRedis
284
324
  break if cursor == "0"
285
325
  }
286
326
 
287
- all_keys.uniq.size.should == 100
288
- all_keys[0].should =~ /key\d+/
327
+ expect(all_keys.uniq.size).to eq(100)
328
+ expect(all_keys[0]).to match(/key\d+/)
289
329
  end
290
330
 
291
331
  it "should match keys to a pattern when scanning" do
@@ -304,7 +344,7 @@ module FakeRedis
304
344
  break if cursor == "0"
305
345
  }
306
346
 
307
- all_keys.uniq.size.should == 50
347
+ expect(all_keys.uniq.size).to eq(50)
308
348
  end
309
349
 
310
350
  it "should specify doing more work when scanning" do
@@ -314,23 +354,23 @@ module FakeRedis
314
354
 
315
355
  cursor, all_keys = @client.scan(cursor, :count => 100)
316
356
 
317
- cursor.should == "0"
318
- all_keys.uniq.size.should == 100
357
+ expect(cursor).to eq("0")
358
+ expect(all_keys.uniq.size).to eq(100)
319
359
  end
320
360
 
321
361
  context "with extended options" do
322
362
  it "uses ex option to set the expire time, in seconds" do
323
363
  ttl = 7
324
364
 
325
- @client.set("key1", "1", { :ex => ttl }).should == "OK"
326
- @client.ttl("key1").should == ttl
365
+ expect(@client.set("key1", "1", { :ex => ttl })).to eq("OK")
366
+ expect(@client.ttl("key1")).to eq(ttl)
327
367
  end
328
368
 
329
369
  it "uses px option to set the expire time, in miliseconds" do
330
370
  ttl = 7000
331
371
 
332
- @client.set("key1", "1", { :px => ttl }).should == "OK"
333
- @client.ttl("key1").should == (ttl / 1000)
372
+ expect(@client.set("key1", "1", { :px => ttl })).to eq("OK")
373
+ expect(@client.ttl("key1")).to eq(ttl / 1000)
334
374
  end
335
375
 
336
376
  # Note that the redis-rb implementation will always give PX last.
@@ -340,30 +380,132 @@ module FakeRedis
340
380
  ttl_ex = 10
341
381
 
342
382
  @client.set("key1", "1", { :px => ttl_px, :ex => ttl_ex })
343
- @client.ttl("key1").should == (ttl_px / 1000)
383
+ expect(@client.ttl("key1")).to eq(ttl_px / 1000)
344
384
 
345
385
  @client.set("key1", "1", { :ex => ttl_ex, :px => ttl_px })
346
- @client.ttl("key1").should == (ttl_px / 1000)
386
+ expect(@client.ttl("key1")).to eq(ttl_px / 1000)
347
387
  end
348
388
 
349
389
  it "uses nx option to only set the key if it does not already exist" do
350
- @client.set("key1", "1", { :nx => true }).should == true
351
- @client.set("key1", "2", { :nx => true }).should == false
390
+ expect(@client.set("key1", "1", { :nx => true })).to eq(true)
391
+ expect(@client.set("key1", "2", { :nx => true })).to eq(false)
352
392
 
353
- @client.get("key1").should == "1"
393
+ expect(@client.get("key1")).to eq("1")
354
394
  end
355
395
 
356
396
  it "uses xx option to only set the key if it already exists" do
357
- @client.set("key2", "1", { :xx => true }).should == false
397
+ expect(@client.set("key2", "1", { :xx => true })).to eq(false)
358
398
  @client.set("key2", "2")
359
- @client.set("key2", "1", { :xx => true }).should == true
399
+ expect(@client.set("key2", "1", { :xx => true })).to eq(true)
360
400
 
361
- @client.get("key2").should == "1"
401
+ expect(@client.get("key2")).to eq("1")
362
402
  end
363
403
 
364
404
  it "does not set the key if both xx and nx option are specified" do
365
- @client.set("key2", "1", { :nx => true, :xx => true }).should == false
366
- @client.get("key2").should be_nil
405
+ expect(@client.set("key2", "1", { :nx => true, :xx => true })).to eq(false)
406
+ expect(@client.get("key2")).to be_nil
407
+ end
408
+ end
409
+
410
+ describe "#dump" do
411
+ it "returns nil for unknown key" do
412
+ expect(@client.exists("key1")).to be false
413
+ expect(@client.dump("key1")).to be nil
414
+ end
415
+
416
+ it "dumps a single known key successfully" do
417
+ @client.set("key1", "zomgwtf")
418
+
419
+ value = @client.dump("key1")
420
+ expect(value).not_to eq nil
421
+ expect(value).to be_a_kind_of(String)
422
+ end
423
+
424
+ it "errors with more than one argument" do
425
+ expect { @client.dump("key1", "key2") }.to raise_error(ArgumentError)
426
+ end
427
+ end
428
+
429
+ describe "#restore" do
430
+ it "errors with a missing payload" do
431
+ expect do
432
+ @client.restore("key1", 0, nil)
433
+ end.to raise_error(Redis::CommandError, "ERR DUMP payload version or checksum are wrong")
434
+ end
435
+
436
+ it "errors with an invalid payload" do
437
+ expect do
438
+ @client.restore("key1", 0, "zomgwtf not valid")
439
+ end.to raise_error(Redis::CommandError, "ERR DUMP payload version or checksum are wrong")
440
+ end
441
+
442
+ describe "with a dumped value" do
443
+ before do
444
+ @client.set("key1", "original value")
445
+ @dumped_value = @client.dump("key1")
446
+
447
+ @client.del("key1")
448
+ expect(@client.exists("key1")).to be false
449
+ end
450
+
451
+ it "restores to a new key successfully" do
452
+ response = @client.restore("key1", 0, @dumped_value)
453
+ expect(response).to eq "OK"
454
+ end
455
+
456
+ it "errors trying to restore to an existing key" do
457
+ @client.set("key1", "something else")
458
+
459
+ expect do
460
+ @client.restore("key1", 0, @dumped_value)
461
+ end.to raise_error(Redis::CommandError, "ERR Target key name is busy.")
462
+ end
463
+
464
+ it "restores successfully with a given expire time" do
465
+ @client.restore("key2", 2000, @dumped_value)
466
+
467
+ expect(@client.ttl("key2")).to eq 2
468
+ end
469
+
470
+ it "restores a list successfully" do
471
+ @client.lpush("key1", "val1")
472
+ @client.lpush("key1", "val2")
473
+
474
+ expect(@client.type("key1")).to eq "list"
475
+
476
+ dumped_value = @client.dump("key1")
477
+
478
+ response = @client.restore("key2", 0, dumped_value)
479
+ expect(response).to eq "OK"
480
+
481
+ expect(@client.type("key2")).to eq "list"
482
+ end
483
+
484
+ it "restores a set successfully" do
485
+ @client.sadd("key1", "val1")
486
+ @client.sadd("key1", "val2")
487
+
488
+ expect(@client.type("key1")).to eq "set"
489
+
490
+ dumped_value = @client.dump("key1")
491
+
492
+ response = @client.restore("key2", 0, dumped_value)
493
+ expect(response).to eq "OK"
494
+
495
+ expect(@client.type("key2")).to eq "set"
496
+ end
497
+ end
498
+ end
499
+
500
+ describe "#psetex" do
501
+ it "should set a key's time to live in milliseconds" do
502
+ allow(Time).to receive(:now).and_return(1000)
503
+ @client.psetex("key", 2200, "value")
504
+ expect(@client.pttl("key")).to be_within(0.1).of(2200)
505
+ end
506
+
507
+ it "should return 'OK'" do
508
+ expect(@client.psetex("key", 1000, "value")).to eq("OK")
367
509
  end
368
510
  end
369
511
  end