fakeredis 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +1 -1
- data/README.md +3 -1
- data/lib/fakeredis/version.rb +1 -1
- data/lib/redis/connection/memory.rb +93 -51
- data/spec/hashes_spec.rb +15 -0
- data/spec/sorted_sets_spec.rb +44 -2
- data/spec/strings_spec.rb +18 -17
- metadata +18 -7
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -50,6 +50,8 @@ Or:
|
|
50
50
|
* [dim](https://github.com/dim)
|
51
51
|
* [czarneckid](https://github.com/czarneckid)
|
52
52
|
* [obrie](https://github.com/obrie)
|
53
|
+
* [jredville](https://github.com/jredville)
|
54
|
+
* [redsquirrel](https://github.com/redsquirrel)
|
53
55
|
* [Travis-CI](http://travis-ci.org/) (Travis-CI also uses Fakeredis in its tests!!!)
|
54
56
|
|
55
57
|
|
@@ -66,5 +68,5 @@ Or:
|
|
66
68
|
|
67
69
|
## Copyright
|
68
70
|
|
69
|
-
Copyright (c) 2011 Guillermo Iguaran. See LICENSE for
|
71
|
+
Copyright (c) 2011-2012 Guillermo Iguaran. See LICENSE for
|
70
72
|
further details.
|
data/lib/fakeredis/version.rb
CHANGED
@@ -116,19 +116,11 @@ class Redis
|
|
116
116
|
# * brpop
|
117
117
|
# * brpoplpush
|
118
118
|
# * discard
|
119
|
-
# * mapped_hmset
|
120
|
-
# * mapped_hmget
|
121
|
-
# * mapped_mset
|
122
|
-
# * mapped_msetnx
|
123
119
|
# * move
|
124
120
|
# * subscribe
|
125
121
|
# * psubscribe
|
126
122
|
# * publish
|
127
|
-
# * substr
|
128
|
-
# * unwatch
|
129
|
-
# * watch
|
130
123
|
# * zremrangebyrank
|
131
|
-
# * zremrangebyscore
|
132
124
|
# * zunionstore
|
133
125
|
def flushdb
|
134
126
|
@data = ExpiringHash.new
|
@@ -173,13 +165,14 @@ class Redis
|
|
173
165
|
|
174
166
|
def getbit(key, offset)
|
175
167
|
return unless @data[key]
|
176
|
-
@data[key].unpack('
|
168
|
+
@data[key].unpack('B*')[0].split("")[offset].to_i
|
177
169
|
end
|
178
170
|
|
179
171
|
def getrange(key, start, ending)
|
180
172
|
return unless @data[key]
|
181
173
|
@data[key][start..ending]
|
182
174
|
end
|
175
|
+
alias :substr :getrange
|
183
176
|
|
184
177
|
def getset(key, value)
|
185
178
|
old_value = @data[key]
|
@@ -188,6 +181,7 @@ class Redis
|
|
188
181
|
end
|
189
182
|
|
190
183
|
def mget(*keys)
|
184
|
+
raise ArgumentError, "wrong number of arguments for 'mget' command" if keys.empty?
|
191
185
|
@data.values_at(*keys)
|
192
186
|
end
|
193
187
|
|
@@ -281,7 +275,7 @@ class Redis
|
|
281
275
|
case where
|
282
276
|
when :before then @data[key].insert(index, value)
|
283
277
|
when :after then @data[key].insert(index + 1, value)
|
284
|
-
else raise ArgumentError
|
278
|
+
else raise ArgumentError
|
285
279
|
end
|
286
280
|
end
|
287
281
|
|
@@ -355,99 +349,99 @@ class Redis
|
|
355
349
|
end
|
356
350
|
|
357
351
|
def smembers(key)
|
358
|
-
data_type_check(key, Set)
|
352
|
+
data_type_check(key, ::Set)
|
359
353
|
return [] unless @data[key]
|
360
354
|
@data[key].to_a.reverse
|
361
355
|
end
|
362
356
|
|
363
357
|
def sismember(key, value)
|
364
|
-
data_type_check(key, Set)
|
358
|
+
data_type_check(key, ::Set)
|
365
359
|
return false unless @data[key]
|
366
360
|
@data[key].include?(value.to_s)
|
367
361
|
end
|
368
362
|
|
369
363
|
def sadd(key, value)
|
370
|
-
data_type_check(key, Set)
|
364
|
+
data_type_check(key, ::Set)
|
371
365
|
if @data[key]
|
372
366
|
!!@data[key].add?(value.to_s)
|
373
367
|
else
|
374
|
-
@data[key] = Set.new([value.to_s])
|
368
|
+
@data[key] = ::Set.new([value.to_s])
|
375
369
|
true
|
376
370
|
end
|
377
371
|
end
|
378
372
|
|
379
373
|
def srem(key, value)
|
380
|
-
data_type_check(key, Set)
|
374
|
+
data_type_check(key, ::Set)
|
381
375
|
deleted = !!(@data[key] && @data[key].delete?(value.to_s))
|
382
376
|
remove_key_for_empty_collection(key)
|
383
377
|
deleted
|
384
378
|
end
|
385
379
|
|
386
380
|
def smove(source, destination, value)
|
387
|
-
data_type_check(destination, Set)
|
381
|
+
data_type_check(destination, ::Set)
|
388
382
|
result = self.srem(source, value)
|
389
383
|
self.sadd(destination, value) if result
|
390
384
|
result
|
391
385
|
end
|
392
386
|
|
393
387
|
def spop(key)
|
394
|
-
data_type_check(key, Set)
|
388
|
+
data_type_check(key, ::Set)
|
395
389
|
elem = srandmember(key)
|
396
390
|
srem(key, elem)
|
397
391
|
elem
|
398
392
|
end
|
399
393
|
|
400
394
|
def scard(key)
|
401
|
-
data_type_check(key, Set)
|
395
|
+
data_type_check(key, ::Set)
|
402
396
|
return 0 unless @data[key]
|
403
397
|
@data[key].size
|
404
398
|
end
|
405
399
|
|
406
400
|
def sinter(*keys)
|
407
|
-
keys.each { |k| data_type_check(k, Set) }
|
408
|
-
return Set.new if keys.any? { |k| @data[k].nil? }
|
409
|
-
keys = keys.map { |k| @data[k] || Set.new }
|
401
|
+
keys.each { |k| data_type_check(k, ::Set) }
|
402
|
+
return ::Set.new if keys.any? { |k| @data[k].nil? }
|
403
|
+
keys = keys.map { |k| @data[k] || ::Set.new }
|
410
404
|
keys.inject do |set, key|
|
411
405
|
set & key
|
412
406
|
end.to_a
|
413
407
|
end
|
414
408
|
|
415
409
|
def sinterstore(destination, *keys)
|
416
|
-
data_type_check(destination, Set)
|
410
|
+
data_type_check(destination, ::Set)
|
417
411
|
result = sinter(*keys)
|
418
|
-
@data[destination] = Set.new(result)
|
412
|
+
@data[destination] = ::Set.new(result)
|
419
413
|
end
|
420
414
|
|
421
415
|
def sunion(*keys)
|
422
|
-
keys.each { |k| data_type_check(k, Set) }
|
423
|
-
keys = keys.map { |k| @data[k] || Set.new }
|
424
|
-
keys.inject(Set.new) do |set, key|
|
416
|
+
keys.each { |k| data_type_check(k, ::Set) }
|
417
|
+
keys = keys.map { |k| @data[k] || ::Set.new }
|
418
|
+
keys.inject(::Set.new) do |set, key|
|
425
419
|
set | key
|
426
420
|
end.to_a
|
427
421
|
end
|
428
422
|
|
429
423
|
def sunionstore(destination, *keys)
|
430
|
-
data_type_check(destination, Set)
|
424
|
+
data_type_check(destination, ::Set)
|
431
425
|
result = sunion(*keys)
|
432
|
-
@data[destination] = Set.new(result)
|
426
|
+
@data[destination] = ::Set.new(result)
|
433
427
|
end
|
434
428
|
|
435
429
|
def sdiff(key1, *keys)
|
436
|
-
[key1, *keys].each { |k| data_type_check(k, Set) }
|
437
|
-
keys = keys.map { |k| @data[k] || Set.new }
|
430
|
+
[key1, *keys].each { |k| data_type_check(k, ::Set) }
|
431
|
+
keys = keys.map { |k| @data[k] || ::Set.new }
|
438
432
|
keys.inject(@data[key1]) do |memo, set|
|
439
433
|
memo - set
|
440
434
|
end.to_a
|
441
435
|
end
|
442
436
|
|
443
437
|
def sdiffstore(destination, key1, *keys)
|
444
|
-
data_type_check(destination, Set)
|
438
|
+
data_type_check(destination, ::Set)
|
445
439
|
result = sdiff(key1, *keys)
|
446
|
-
@data[destination] = Set.new(result)
|
440
|
+
@data[destination] = ::Set.new(result)
|
447
441
|
end
|
448
442
|
|
449
443
|
def srandmember(key)
|
450
|
-
data_type_check(key, Set)
|
444
|
+
data_type_check(key, ::Set)
|
451
445
|
return nil unless @data[key]
|
452
446
|
@data[key].to_a[rand(@data[key].size)]
|
453
447
|
end
|
@@ -529,6 +523,7 @@ class Redis
|
|
529
523
|
end
|
530
524
|
|
531
525
|
def hmset(key, *fields)
|
526
|
+
raise ArgumentError, "wrong number of arguments for 'hmset' command" if fields.empty? || fields.size.odd?
|
532
527
|
data_type_check(key, Hash)
|
533
528
|
@data[key] ||= {}
|
534
529
|
fields.each_slice(2) do |field|
|
@@ -537,6 +532,7 @@ class Redis
|
|
537
532
|
end
|
538
533
|
|
539
534
|
def hmget(key, *fields)
|
535
|
+
raise ArgumentError, "wrong number of arguments for 'hmget' command" if fields.empty?
|
540
536
|
data_type_check(key, Hash)
|
541
537
|
values = []
|
542
538
|
fields.map do |field|
|
@@ -593,12 +589,15 @@ class Redis
|
|
593
589
|
end
|
594
590
|
|
595
591
|
def setbit(key, offset, bit)
|
596
|
-
|
597
|
-
|
592
|
+
old_val = @data[key] ? @data[key].unpack('B*')[0].split("") : []
|
593
|
+
size_increment = [((offset/8)+1)*8-old_val.length, 0].max
|
594
|
+
old_val += Array.new(size_increment).map{"0"}
|
595
|
+
original_val = old_val[offset]
|
598
596
|
old_val[offset] = bit.to_s
|
599
597
|
new_val = ""
|
600
598
|
old_val.each_slice(8){|b| new_val = new_val + b.join("").to_i(2).chr }
|
601
599
|
@data[key] = new_val
|
600
|
+
original_val
|
602
601
|
end
|
603
602
|
|
604
603
|
def setex(key, seconds, value)
|
@@ -627,13 +626,8 @@ class Redis
|
|
627
626
|
true
|
628
627
|
end
|
629
628
|
|
630
|
-
def mapped_mget(*keys)
|
631
|
-
reply = mget(*keys)
|
632
|
-
Hash[*keys.zip(reply).flatten]
|
633
|
-
end
|
634
|
-
|
635
629
|
def sort(key)
|
636
|
-
# TODO:
|
630
|
+
# TODO: Implement
|
637
631
|
end
|
638
632
|
|
639
633
|
def incr(key)
|
@@ -666,7 +660,7 @@ class Redis
|
|
666
660
|
when String then "string"
|
667
661
|
when Hash then "hash"
|
668
662
|
when Array then "list"
|
669
|
-
when Set then "set"
|
663
|
+
when ::Set then "set"
|
670
664
|
end
|
671
665
|
end
|
672
666
|
|
@@ -688,11 +682,19 @@ class Redis
|
|
688
682
|
"OK"
|
689
683
|
end
|
690
684
|
|
685
|
+
def watch(_)
|
686
|
+
"OK"
|
687
|
+
end
|
688
|
+
|
689
|
+
def unwatch
|
690
|
+
"OK"
|
691
|
+
end
|
692
|
+
|
691
693
|
def zadd(key, score, value)
|
692
694
|
data_type_check(key, ZSet)
|
693
695
|
@data[key] ||= ZSet.new
|
694
696
|
exists = @data[key].key?(value.to_s)
|
695
|
-
@data[key][value.to_s] = score
|
697
|
+
@data[key][value.to_s] = score
|
696
698
|
!exists
|
697
699
|
end
|
698
700
|
|
@@ -722,6 +724,7 @@ class Redis
|
|
722
724
|
|
723
725
|
def zincrby(key, num, value)
|
724
726
|
data_type_check(key, ZSet)
|
727
|
+
@data[key] ||= ZSet.new
|
725
728
|
@data[key][value.to_s] ||= 0
|
726
729
|
@data[key][value.to_s] += num
|
727
730
|
@data[key][value.to_s].to_s
|
@@ -759,28 +762,47 @@ class Redis
|
|
759
762
|
end[start..stop].flatten.map(&:to_s)
|
760
763
|
end
|
761
764
|
|
762
|
-
def zrangebyscore(key, min, max,
|
765
|
+
def zrangebyscore(key, min, max, *opts)
|
763
766
|
data_type_check(key, ZSet)
|
764
767
|
return [] unless @data[key]
|
765
768
|
|
766
769
|
range = zrange_select_by_score(key, min, max)
|
767
|
-
if
|
770
|
+
vals = if opts.include?('WITHSCORES')
|
768
771
|
range.sort_by {|_,v| v }
|
769
772
|
else
|
770
773
|
range.keys.sort_by {|k| range[k] }
|
771
|
-
end
|
774
|
+
end
|
775
|
+
|
776
|
+
limit = get_limit(opts, vals)
|
777
|
+
vals = vals[*limit] if limit
|
778
|
+
|
779
|
+
vals.flatten.map(&:to_s)
|
772
780
|
end
|
773
781
|
|
774
|
-
def zrevrangebyscore(key, max, min,
|
782
|
+
def zrevrangebyscore(key, max, min, *opts)
|
775
783
|
data_type_check(key, ZSet)
|
776
784
|
return [] unless @data[key]
|
777
785
|
|
778
786
|
range = zrange_select_by_score(key, min, max)
|
779
|
-
if
|
787
|
+
vals = if opts.include?('WITHSCORES')
|
780
788
|
range.sort_by {|_,v| -v }
|
781
789
|
else
|
782
790
|
range.keys.sort_by {|k| -range[k] }
|
783
|
-
end
|
791
|
+
end
|
792
|
+
|
793
|
+
limit = get_limit(opts, vals)
|
794
|
+
vals = vals[*limit] if limit
|
795
|
+
|
796
|
+
vals.flatten.map(&:to_s)
|
797
|
+
end
|
798
|
+
|
799
|
+
def zremrangebyscore(key, min, max)
|
800
|
+
data_type_check(key, ZSet)
|
801
|
+
return 0 unless @data[key]
|
802
|
+
|
803
|
+
range = zrange_select_by_score(key, min, max)
|
804
|
+
range.each {|k,_| @data[key].delete(k) }
|
805
|
+
range.size
|
784
806
|
end
|
785
807
|
|
786
808
|
def zinterstore(out, _, *keys)
|
@@ -788,7 +810,7 @@ class Redis
|
|
788
810
|
|
789
811
|
hashes = keys.map do |src|
|
790
812
|
case @data[src]
|
791
|
-
when Set
|
813
|
+
when ::Set
|
792
814
|
Hash[@data[src].zip([0] * @data[src].size)]
|
793
815
|
when Hash
|
794
816
|
@data[src]
|
@@ -806,6 +828,13 @@ class Redis
|
|
806
828
|
@data[out].size
|
807
829
|
end
|
808
830
|
|
831
|
+
def zremrangebyrank(key, start, stop)
|
832
|
+
sorted_elements = @data[key].sort { |(v_a, r_a), (v_b, r_b)| r_a <=> r_b }
|
833
|
+
elements_to_delete = sorted_elements[start..stop]
|
834
|
+
elements_to_delete.each { |elem, rank| @data[key].delete(elem) }
|
835
|
+
elements_to_delete.size
|
836
|
+
end
|
837
|
+
|
809
838
|
private
|
810
839
|
|
811
840
|
def zrange_select_by_score(key, min, max)
|
@@ -815,12 +844,25 @@ class Redis
|
|
815
844
|
def remove_key_for_empty_collection(key)
|
816
845
|
del(key) if @data[key] && @data[key].empty?
|
817
846
|
end
|
818
|
-
|
847
|
+
|
819
848
|
def data_type_check(key, klass)
|
820
849
|
if @data[key] && !@data[key].is_a?(klass)
|
821
850
|
fail "Operation against a key holding the wrong kind of value: Expected #{klass} at #{key}."
|
822
851
|
end
|
823
852
|
end
|
853
|
+
|
854
|
+
def get_limit(opts, vals)
|
855
|
+
index = opts.index('LIMIT')
|
856
|
+
|
857
|
+
if index
|
858
|
+
offset = opts[index + 1]
|
859
|
+
|
860
|
+
count = opts[index + 2]
|
861
|
+
count = vals.size if count < 0
|
862
|
+
|
863
|
+
[offset, count]
|
864
|
+
end
|
865
|
+
end
|
824
866
|
end
|
825
867
|
end
|
826
868
|
end
|
data/spec/hashes_spec.rb
CHANGED
@@ -94,6 +94,21 @@ module FakeRedis
|
|
94
94
|
@client.hmget("key2", "i1", "i2").should == [nil, nil]
|
95
95
|
end
|
96
96
|
|
97
|
+
it "throws an argument error when you don't ask for any keys" do
|
98
|
+
lambda { @client.hmget("key1") }.should raise_error(ArgumentError)
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should reject an empty list of values" do
|
102
|
+
lambda { @client.hmset("key") }.should raise_error(ArgumentError)
|
103
|
+
@client.exists("key").should be_false
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'rejects an insert with a key but no value' do
|
107
|
+
lambda { @client.hmset("key", 'foo') }.should raise_error(ArgumentError)
|
108
|
+
lambda { @client.hmset("key", 'foo', 3, 'bar') }.should raise_error(ArgumentError)
|
109
|
+
@client.exists("key").should be_false
|
110
|
+
end
|
111
|
+
|
97
112
|
it "should set multiple hash fields to multiple values" do
|
98
113
|
@client.hmset("key", "k1", "value1", "k2", "value2")
|
99
114
|
|
data/spec/sorted_sets_spec.rb
CHANGED
@@ -14,6 +14,14 @@ module FakeRedis
|
|
14
14
|
@client.zscore("key", "val").should == "2"
|
15
15
|
end
|
16
16
|
|
17
|
+
it "should allow floats as scores when adding or updating" do
|
18
|
+
@client.zadd("key", 4.321, "val").should be(true)
|
19
|
+
@client.zscore("key", "val").should == "4.321"
|
20
|
+
|
21
|
+
@client.zadd("key", 54.3210, "val").should be(false)
|
22
|
+
@client.zscore("key", "val").should == "54.321"
|
23
|
+
end
|
24
|
+
|
17
25
|
it "should remove members from sorted sets" do
|
18
26
|
@client.zrem("key", "val").should be(false)
|
19
27
|
@client.zadd("key", 1, "val").should be(true)
|
@@ -48,6 +56,10 @@ module FakeRedis
|
|
48
56
|
@client.zscore("key", "val1").should == "3"
|
49
57
|
end
|
50
58
|
|
59
|
+
it "initializes the sorted set if the key wasnt already set" do
|
60
|
+
@client.zincrby("key", 1, "val1").should == "1"
|
61
|
+
end
|
62
|
+
|
51
63
|
it "should convert the key to a string for zscore" do
|
52
64
|
@client.zadd("key", 1, 1)
|
53
65
|
@client.zscore("key", 1).should == "1"
|
@@ -85,6 +97,9 @@ module FakeRedis
|
|
85
97
|
@client.zrangebyscore("key", 1, 2).should == ["one", "two"]
|
86
98
|
@client.zrangebyscore("key", 0, 100, :withscores => true).should == ["one", "1", "two", "2", "three", "3"]
|
87
99
|
@client.zrangebyscore("key", 1, 2, :with_scores => true).should == ["one", "1", "two", "2"]
|
100
|
+
@client.zrangebyscore("key", 0, 100, :limit => [0, 1]).should == ["one"]
|
101
|
+
@client.zrangebyscore("key", 0, 100, :limit => [0, -1]).should == ["one", "two", "three"]
|
102
|
+
@client.zrangebyscore("key", 0, 100, :limit => [1, -1], :with_scores => true).should == ["two", "2", "three", "3"]
|
88
103
|
end
|
89
104
|
|
90
105
|
it "should return a reversed range of members in a sorted set, by score" do
|
@@ -96,6 +111,9 @@ module FakeRedis
|
|
96
111
|
@client.zrevrangebyscore("key", 2, 1).should == ["two", "one"]
|
97
112
|
@client.zrevrangebyscore("key", 1, 2).should == []
|
98
113
|
@client.zrevrangebyscore("key", 2, 1, :with_scores => true).should == ["two", "2", "one", "1"]
|
114
|
+
@client.zrevrangebyscore("key", 100, 0, :limit => [0, 1]).should == ["three"]
|
115
|
+
@client.zrevrangebyscore("key", 100, 0, :limit => [0, -1]).should == ["three", "two", "one"]
|
116
|
+
@client.zrevrangebyscore("key", 100, 0, :limit => [1, -1], :with_scores => true).should == ["two", "2", "one", "1"]
|
99
117
|
end
|
100
118
|
|
101
119
|
it "should determine the index of a member in a sorted set" do
|
@@ -138,9 +156,33 @@ module FakeRedis
|
|
138
156
|
@client.zrange("out", 0, 100, :with_scores => true).should == []
|
139
157
|
end
|
140
158
|
|
141
|
-
|
159
|
+
context "zremrangebyscore" do
|
160
|
+
it "should remove items by score" do
|
161
|
+
@client.zadd("key", 1, "one")
|
162
|
+
@client.zadd("key", 2, "two")
|
163
|
+
@client.zadd("key", 3, "three")
|
164
|
+
|
165
|
+
@client.zremrangebyscore("key", 0, 2).should == 2
|
166
|
+
@client.zcard("key").should == 1
|
167
|
+
end
|
142
168
|
|
143
|
-
|
169
|
+
it "should return 0 if the key didn't exist" do
|
170
|
+
@client.zremrangebyscore("key", 0, 2).should == 0
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
context '#zremrangebyrank' do
|
175
|
+
it 'removes all elements with in the given range' do
|
176
|
+
@client.zadd("key", 1, "one")
|
177
|
+
@client.zadd("key", 2, "two")
|
178
|
+
@client.zadd("key", 3, "three")
|
179
|
+
|
180
|
+
@client.zremrangebyrank("key", 0, 1).should == 2
|
181
|
+
@client.zcard('key').should == 1
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
#it "should remove all members in a sorted set within the given indexes"
|
144
186
|
|
145
187
|
#it "should return a range of members in a sorted set, by index, with scores ordered from high to low"
|
146
188
|
|
data/spec/strings_spec.rb
CHANGED
@@ -35,19 +35,25 @@ module FakeRedis
|
|
35
35
|
it "should returns the bit value at offset in the string value stored at key" do
|
36
36
|
@client.set("key1", "a")
|
37
37
|
|
38
|
-
@client.getbit("key1", 1).should ==
|
39
|
-
@client.getbit("key1", 2).should ==
|
40
|
-
@client.getbit("key1", 3).should ==
|
41
|
-
@client.getbit("key1", 4).should ==
|
42
|
-
@client.getbit("key1", 5).should ==
|
43
|
-
@client.getbit("key1", 6).should ==
|
44
|
-
@client.getbit("key1", 7).should ==
|
38
|
+
@client.getbit("key1", 1).should == 1
|
39
|
+
@client.getbit("key1", 2).should == 1
|
40
|
+
@client.getbit("key1", 3).should == 0
|
41
|
+
@client.getbit("key1", 4).should == 0
|
42
|
+
@client.getbit("key1", 5).should == 0
|
43
|
+
@client.getbit("key1", 6).should == 0
|
44
|
+
@client.getbit("key1", 7).should == 1
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should allow direct bit manipulation even if the string isn't set" do
|
48
|
+
@client.setbit("key1", 10, 1)
|
49
|
+
@client.getbit("key1", 10).should == 1
|
45
50
|
end
|
46
51
|
|
47
52
|
it "should get a substring of the string stored at a key" do
|
48
53
|
@client.set("key1", "This a message")
|
49
54
|
|
50
55
|
@client.getrange("key1", 0, 3).should == "This"
|
56
|
+
@client.substr("key1", 0, 3).should == "This"
|
51
57
|
end
|
52
58
|
|
53
59
|
it "should set the string value of a key and return its old value" do
|
@@ -56,7 +62,7 @@ module FakeRedis
|
|
56
62
|
@client.getset("key1", "value2").should == "value1"
|
57
63
|
@client.get("key1").should == "value2"
|
58
64
|
end
|
59
|
-
|
65
|
+
|
60
66
|
it "should return nil for #getset if the key does not exist when setting" do
|
61
67
|
@client.getset("key1", "value1").should == nil
|
62
68
|
@client.get("key1").should == "value1"
|
@@ -68,11 +74,11 @@ module FakeRedis
|
|
68
74
|
|
69
75
|
@client.get("counter").should == "2"
|
70
76
|
end
|
71
|
-
|
77
|
+
|
72
78
|
it "should decrement the integer value of a key by one" do
|
73
79
|
@client.set("counter", "1")
|
74
80
|
@client.decr("counter").should == 0
|
75
|
-
|
81
|
+
|
76
82
|
@client.get("counter").should == "0"
|
77
83
|
end
|
78
84
|
|
@@ -98,15 +104,10 @@ module FakeRedis
|
|
98
104
|
@client.mget("key1", "key2", "key3").should == ["value1", "value2", "value3"]
|
99
105
|
end
|
100
106
|
|
101
|
-
it
|
102
|
-
@client.set("key1", "value1")
|
103
|
-
@client.set("key2", "value2")
|
107
|
+
it 'raises an argument error when not passed any fields' do
|
104
108
|
@client.set("key3", "value3")
|
105
|
-
response = @client.mapped_mget("key1", "key2", "key3")
|
106
109
|
|
107
|
-
|
108
|
-
response["key2"].should == "value2"
|
109
|
-
response["key3"].should == "value3"
|
110
|
+
lambda { @client.mget }.should raise_error(ArgumentError)
|
110
111
|
end
|
111
112
|
|
112
113
|
it "should set multiple keys to multiple values" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fakeredis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-06-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: redis
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,15 @@ dependencies:
|
|
21
21
|
version: 2.2.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 2.2.0
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: rspec
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
35
|
- - ! '>='
|
@@ -32,7 +37,12 @@ dependencies:
|
|
32
37
|
version: 2.0.0
|
33
38
|
type: :development
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 2.0.0
|
36
46
|
description: Fake (In-memory) driver for redis-rb. Useful for testing environment
|
37
47
|
and machines without Redis.
|
38
48
|
email:
|
@@ -84,7 +94,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
84
94
|
version: '0'
|
85
95
|
requirements: []
|
86
96
|
rubyforge_project: fakeredis
|
87
|
-
rubygems_version: 1.8.
|
97
|
+
rubygems_version: 1.8.24
|
88
98
|
signing_key:
|
89
99
|
specification_version: 3
|
90
100
|
summary: Fake (In-memory) driver for redis-rb.
|
@@ -100,3 +110,4 @@ test_files:
|
|
100
110
|
- spec/spec_helper.rb
|
101
111
|
- spec/strings_spec.rb
|
102
112
|
- spec/transactions_spec.rb
|
113
|
+
has_rdoc:
|