fakeredis 0.5.0 → 0.8.0

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