fakeredis 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +0 -1
- data/README.md +15 -0
- data/Rakefile +1 -0
- data/lib/fakeredis/rspec.rb +24 -0
- data/lib/fakeredis/version.rb +1 -1
- data/lib/redis/connection/memory.rb +194 -41
- data/spec/hashes_spec.rb +38 -5
- data/spec/keys_spec.rb +11 -2
- data/spec/lists_spec.rb +9 -0
- data/spec/sets_spec.rb +15 -3
- data/spec/sorted_sets_spec.rb +139 -65
- data/spec/strings_spec.rb +17 -3
- metadata +8 -7
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -30,9 +30,24 @@ You can use FakeRedis without any changes:
|
|
30
30
|
Read [redis-rb](https://github.com/ezmobius/redis-rb) documentation and
|
31
31
|
[Redis](http://redis.io) homepage for more info about commands
|
32
32
|
|
33
|
+
## Usage with RSpec
|
34
|
+
|
35
|
+
Require this either in your Gemfile or in RSpec's support scripts. So either:
|
36
|
+
|
37
|
+
# Gemfile
|
38
|
+
group :test do
|
39
|
+
gem "rspec"
|
40
|
+
gem "fakeredis", :require => "fakeredis/rspec"
|
41
|
+
end
|
42
|
+
|
43
|
+
Or:
|
44
|
+
|
45
|
+
# spec/support/fakeredis.rb
|
46
|
+
require 'fakeredis/rspec'
|
33
47
|
|
34
48
|
## Acknowledgements
|
35
49
|
|
50
|
+
* [dim](https://github.com/dim)
|
36
51
|
* [czarneckid](https://github.com/czarneckid)
|
37
52
|
* [obrie](https://github.com/obrie)
|
38
53
|
* [Travis-CI](http://travis-ci.org/) (Travis-CI also uses Fakeredis in its tests!!!)
|
data/Rakefile
CHANGED
@@ -0,0 +1,24 @@
|
|
1
|
+
# Require this either in your Gemfile or in RSpec's
|
2
|
+
# support scripts. Examples:
|
3
|
+
#
|
4
|
+
# # Gemfile
|
5
|
+
# group :test do
|
6
|
+
# gem "rspec"
|
7
|
+
# gem "fakeredis", :require => "fakeredis/rspec"
|
8
|
+
# end
|
9
|
+
#
|
10
|
+
# # spec/support/fakeredis.rb
|
11
|
+
# require 'fakeredis/rspec'
|
12
|
+
#
|
13
|
+
|
14
|
+
require 'rspec/core'
|
15
|
+
require 'fakeredis'
|
16
|
+
|
17
|
+
RSpec.configure do |c|
|
18
|
+
|
19
|
+
c.before do
|
20
|
+
redis = Redis.current
|
21
|
+
redis.flushdb if redis.client.connection.is_a?(Redis::Connection::Memory)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
data/lib/fakeredis/version.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'set'
|
1
2
|
require 'redis/connection/registry'
|
2
3
|
require 'redis/connection/command_helper'
|
3
4
|
|
@@ -59,6 +60,9 @@ class Redis
|
|
59
60
|
end
|
60
61
|
end
|
61
62
|
|
63
|
+
class ZSet < Hash
|
64
|
+
end
|
65
|
+
|
62
66
|
include Redis::Connection::CommandHelper
|
63
67
|
|
64
68
|
def initialize
|
@@ -123,20 +127,8 @@ class Redis
|
|
123
127
|
# * substr
|
124
128
|
# * unwatch
|
125
129
|
# * watch
|
126
|
-
# * zadd
|
127
|
-
# * zcard
|
128
|
-
# * zcount
|
129
|
-
# * zincrby
|
130
|
-
# * zinterstore
|
131
|
-
# * zrange
|
132
|
-
# * zrangescore
|
133
|
-
# * zrank
|
134
|
-
# * zrem
|
135
130
|
# * zremrangebyrank
|
136
131
|
# * zremrangebyscore
|
137
|
-
# * zrevrange
|
138
|
-
# * zrevrangebyscore
|
139
|
-
# * zscore
|
140
132
|
# * zunionstore
|
141
133
|
def flushdb
|
142
134
|
@data = ExpiringHash.new
|
@@ -220,13 +212,14 @@ class Redis
|
|
220
212
|
def hget(key, field)
|
221
213
|
return unless @data[key]
|
222
214
|
fail "Not a hash" unless @data[key].is_a?(Hash)
|
223
|
-
@data[key][field]
|
215
|
+
@data[key][field.to_s]
|
224
216
|
end
|
225
217
|
|
226
218
|
def hdel(key, field)
|
227
219
|
return unless @data[key]
|
228
220
|
fail "Not a hash" unless @data[key].is_a?(Hash)
|
229
221
|
@data[key].delete(field)
|
222
|
+
remove_key_for_empty_collection(key)
|
230
223
|
end
|
231
224
|
|
232
225
|
def hkeys(key)
|
@@ -312,15 +305,18 @@ class Redis
|
|
312
305
|
fail "Not a list" unless @data[key].is_a?(Array)
|
313
306
|
return unless @data[key]
|
314
307
|
old_size = @data[key].size
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
308
|
+
diff =
|
309
|
+
if count == 0
|
310
|
+
@data[key].delete(value)
|
311
|
+
old_size - @data[key].size
|
312
|
+
else
|
313
|
+
array = count > 0 ? @data[key].dup : @data[key].reverse
|
314
|
+
count.abs.times{ array.delete_at(array.index(value) || array.length) }
|
315
|
+
@data[key] = count > 0 ? array.dup : array.reverse
|
316
|
+
old_size - @data[key].size
|
317
|
+
end
|
318
|
+
remove_key_for_empty_collection(key)
|
319
|
+
diff
|
324
320
|
end
|
325
321
|
|
326
322
|
def rpush(key, value)
|
@@ -384,24 +380,28 @@ class Redis
|
|
384
380
|
def sadd(key, value)
|
385
381
|
fail_unless_set(key)
|
386
382
|
case set = @data[key]
|
387
|
-
when nil then @data[key] = Set.new([value.to_s])
|
388
|
-
when Set then set.add(value.to_s)
|
383
|
+
when nil then @data[key] = Set.new([value.to_s]); true
|
384
|
+
when Set then !!set.add?(value.to_s)
|
389
385
|
end
|
390
386
|
end
|
391
387
|
|
392
388
|
def srem(key, value)
|
393
389
|
fail_unless_set(key)
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
390
|
+
deleted =
|
391
|
+
case set = @data[key]
|
392
|
+
when nil then false
|
393
|
+
when Set then !!set.delete?(value.to_s)
|
394
|
+
end
|
395
|
+
|
396
|
+
remove_key_for_empty_collection(key)
|
397
|
+
deleted
|
398
398
|
end
|
399
399
|
|
400
400
|
def smove(source, destination, value)
|
401
401
|
fail_unless_set(destination)
|
402
|
-
|
403
|
-
|
404
|
-
|
402
|
+
result = self.srem(source, value)
|
403
|
+
self.sadd(destination, value) if result
|
404
|
+
result
|
405
405
|
end
|
406
406
|
|
407
407
|
def spop(key)
|
@@ -479,7 +479,12 @@ class Redis
|
|
479
479
|
end
|
480
480
|
|
481
481
|
def setnx(key, value)
|
482
|
-
|
482
|
+
if exists(key)
|
483
|
+
false
|
484
|
+
else
|
485
|
+
set(key, value)
|
486
|
+
true
|
487
|
+
end
|
483
488
|
end
|
484
489
|
|
485
490
|
def rename(key, new_key)
|
@@ -490,7 +495,12 @@ class Redis
|
|
490
495
|
end
|
491
496
|
|
492
497
|
def renamenx(key, new_key)
|
493
|
-
|
498
|
+
if exists(new_key)
|
499
|
+
false
|
500
|
+
else
|
501
|
+
rename(key, new_key)
|
502
|
+
true
|
503
|
+
end
|
494
504
|
end
|
495
505
|
|
496
506
|
def expire(key, ttl)
|
@@ -513,25 +523,27 @@ class Redis
|
|
513
523
|
end
|
514
524
|
|
515
525
|
def persist(key)
|
516
|
-
|
526
|
+
!!@data.expires.delete(key)
|
517
527
|
end
|
518
528
|
|
519
529
|
def hset(key, field, value)
|
530
|
+
field = field.to_s
|
520
531
|
case hash = @data[key]
|
521
|
-
when nil then @data[key] = { field => value.to_s }
|
522
|
-
when Hash then hash[field] = value.to_s
|
532
|
+
when nil then @data[key] = { field => value.to_s }; true
|
533
|
+
when Hash then result = !hash.include?(field); hash[field] = value.to_s; result
|
523
534
|
else fail "Not a hash"
|
524
535
|
end
|
525
536
|
end
|
526
537
|
|
527
538
|
def hsetnx(key, field, value)
|
528
|
-
|
539
|
+
field = field.to_s
|
540
|
+
return false if (@data[key][field] rescue false)
|
529
541
|
hset(key, field, value)
|
530
542
|
end
|
531
543
|
|
532
544
|
def hmset(key, *fields)
|
533
545
|
@data[key] ||= {}
|
534
|
-
fail "Not a hash" unless @data[key].is_a?(Hash)
|
546
|
+
fail "Not a hash" unless @data[key].is_a?(Hash)
|
535
547
|
fields.each_slice(2) do |field|
|
536
548
|
@data[key][field[0].to_s] = field[1].to_s
|
537
549
|
end
|
@@ -540,7 +552,8 @@ class Redis
|
|
540
552
|
def hmget(key, *fields)
|
541
553
|
values = []
|
542
554
|
fields.each do |field|
|
543
|
-
|
555
|
+
field = field.to_s
|
556
|
+
case hash = @data[key]
|
544
557
|
when nil then values << nil
|
545
558
|
when Hash then values << hash[field]
|
546
559
|
else fail "Not a hash"
|
@@ -567,10 +580,11 @@ class Redis
|
|
567
580
|
|
568
581
|
def hincrby(key, field, increment)
|
569
582
|
case hash = @data[key]
|
570
|
-
when nil then @data[key] = { field =>
|
583
|
+
when nil then @data[key] = { field => increment.to_s }
|
571
584
|
when Hash then hash[field] = (hash[field].to_i + increment.to_i).to_s
|
572
585
|
else fail "Not a hash"
|
573
586
|
end
|
587
|
+
@data[key][field].to_i
|
574
588
|
end
|
575
589
|
|
576
590
|
def hexists(key, field)
|
@@ -604,7 +618,7 @@ class Redis
|
|
604
618
|
end
|
605
619
|
|
606
620
|
def setex(key, seconds, value)
|
607
|
-
@data[key] = value
|
621
|
+
@data[key] = value.to_s
|
608
622
|
expire(key, seconds)
|
609
623
|
end
|
610
624
|
|
@@ -641,21 +655,25 @@ class Redis
|
|
641
655
|
def incr(key)
|
642
656
|
@data[key] = (@data[key] || "0")
|
643
657
|
@data[key] = (@data[key].to_i + 1).to_s
|
658
|
+
@data[key].to_i
|
644
659
|
end
|
645
660
|
|
646
661
|
def incrby(key, by)
|
647
662
|
@data[key] = (@data[key] || "0")
|
648
663
|
@data[key] = (@data[key].to_i + by.to_i).to_s
|
664
|
+
@data[key].to_i
|
649
665
|
end
|
650
666
|
|
651
667
|
def decr(key)
|
652
668
|
@data[key] = (@data[key] || "0")
|
653
669
|
@data[key] = (@data[key].to_i - 1).to_s
|
670
|
+
@data[key].to_i
|
654
671
|
end
|
655
672
|
|
656
673
|
def decrby(key, by)
|
657
674
|
@data[key] = (@data[key] || "0")
|
658
675
|
@data[key] = (@data[key].to_i - by.to_i).to_s
|
676
|
+
@data[key].to_i
|
659
677
|
end
|
660
678
|
|
661
679
|
def type(key)
|
@@ -686,7 +704,126 @@ class Redis
|
|
686
704
|
"OK"
|
687
705
|
end
|
688
706
|
|
707
|
+
def zadd(key, score, value)
|
708
|
+
fail_unless_zset(key)
|
709
|
+
@data[key] ||= ZSet.new
|
710
|
+
exists = @data[key].key?(value.to_s)
|
711
|
+
@data[key][value.to_s] = score.to_i
|
712
|
+
!exists
|
713
|
+
end
|
714
|
+
|
715
|
+
def zrem(key, value)
|
716
|
+
fail_unless_zset(key)
|
717
|
+
exists = false
|
718
|
+
exists = @data[key].delete(value.to_s) if @data[key]
|
719
|
+
remove_key_for_empty_collection(key)
|
720
|
+
!!exists
|
721
|
+
end
|
722
|
+
|
723
|
+
def zcard(key)
|
724
|
+
fail_unless_zset(key)
|
725
|
+
@data[key] ? @data[key].size : 0
|
726
|
+
end
|
727
|
+
|
728
|
+
def zscore(key, value)
|
729
|
+
fail_unless_zset(key)
|
730
|
+
@data[key] && @data[key][value.to_s].to_s
|
731
|
+
end
|
732
|
+
|
733
|
+
def zcount(key, min, max)
|
734
|
+
fail_unless_zset(key)
|
735
|
+
return 0 unless @data[key]
|
736
|
+
zrange_select_by_score(key, min, max).size
|
737
|
+
end
|
738
|
+
|
739
|
+
def zincrby(key, num, value)
|
740
|
+
fail_unless_zset(key)
|
741
|
+
@data[key][value.to_s] ||= 0
|
742
|
+
@data[key][value.to_s] += num
|
743
|
+
@data[key][value.to_s].to_s
|
744
|
+
end
|
745
|
+
|
746
|
+
def zrank(key, value)
|
747
|
+
fail_unless_zset(key)
|
748
|
+
@data[key].keys.sort_by {|k| @data[key][k] }.index(value.to_s)
|
749
|
+
end
|
750
|
+
|
751
|
+
def zrevrank(key, value)
|
752
|
+
fail_unless_zset(key)
|
753
|
+
@data[key].keys.sort_by {|k| -@data[key][k] }.index(value.to_s)
|
754
|
+
end
|
755
|
+
|
756
|
+
def zrange(key, start, stop, with_scores = nil)
|
757
|
+
fail_unless_zset(key)
|
758
|
+
return [] unless @data[key]
|
759
|
+
|
760
|
+
if with_scores
|
761
|
+
@data[key].sort_by {|_,v| v }
|
762
|
+
else
|
763
|
+
@data[key].keys.sort_by {|k| @data[key][k] }
|
764
|
+
end[start..stop].flatten.map(&:to_s)
|
765
|
+
end
|
766
|
+
|
767
|
+
def zrevrange(key, start, stop, with_scores = nil)
|
768
|
+
fail_unless_zset(key)
|
769
|
+
return [] unless @data[key]
|
770
|
+
|
771
|
+
if with_scores
|
772
|
+
@data[key].sort_by {|_,v| -v }
|
773
|
+
else
|
774
|
+
@data[key].keys.sort_by {|k| -@data[key][k] }
|
775
|
+
end[start..stop].flatten.map(&:to_s)
|
776
|
+
end
|
777
|
+
|
778
|
+
def zrangebyscore(key, min, max, with_scores = nil)
|
779
|
+
fail_unless_zset(key)
|
780
|
+
return [] unless @data[key]
|
781
|
+
|
782
|
+
range = zrange_select_by_score(key, min, max)
|
783
|
+
if with_scores
|
784
|
+
range.sort_by {|_,v| v }
|
785
|
+
else
|
786
|
+
range.keys.sort_by {|k| range[k] }
|
787
|
+
end.flatten.map(&:to_s)
|
788
|
+
end
|
789
|
+
|
790
|
+
def zrevrangebyscore(key, max, min, with_scores = nil)
|
791
|
+
fail_unless_zset(key)
|
792
|
+
return [] unless @data[key]
|
793
|
+
|
794
|
+
range = zrange_select_by_score(key, min, max)
|
795
|
+
if with_scores
|
796
|
+
range.sort_by {|_,v| -v }
|
797
|
+
else
|
798
|
+
range.keys.sort_by {|k| -range[k] }
|
799
|
+
end.flatten.map(&:to_s)
|
800
|
+
end
|
801
|
+
|
802
|
+
def zinterstore(out, _, *keys)
|
803
|
+
fail_unless_zset(out)
|
804
|
+
|
805
|
+
hashes = keys.map do |src|
|
806
|
+
case @data[src]
|
807
|
+
when Set
|
808
|
+
Hash[@data[src].zip([0] * @data[src].size)]
|
809
|
+
when Hash
|
810
|
+
@data[src]
|
811
|
+
else
|
812
|
+
{}
|
813
|
+
end
|
814
|
+
end
|
815
|
+
|
816
|
+
@data[out] = ZSet.new
|
817
|
+
values = hashes.inject([]) {|r, h| r.empty? ? h.keys : r & h.keys }
|
818
|
+
values.each do |value|
|
819
|
+
@data[out][value] = hashes.inject(0) {|n, h| n + h[value].to_i }
|
820
|
+
end
|
821
|
+
|
822
|
+
@data[out].size
|
823
|
+
end
|
824
|
+
|
689
825
|
private
|
826
|
+
|
690
827
|
def is_a_set?(key)
|
691
828
|
@data[key].is_a?(Set) || @data[key].nil?
|
692
829
|
end
|
@@ -694,6 +831,22 @@ class Redis
|
|
694
831
|
def fail_unless_set(key)
|
695
832
|
fail "Not a set" unless is_a_set?(key)
|
696
833
|
end
|
834
|
+
|
835
|
+
def is_a_zset?(key)
|
836
|
+
@data[key].is_a?(ZSet) || @data[key].nil?
|
837
|
+
end
|
838
|
+
|
839
|
+
def fail_unless_zset(key)
|
840
|
+
fail "Not a sorted set" unless is_a_zset?(key)
|
841
|
+
end
|
842
|
+
|
843
|
+
def zrange_select_by_score(key, min, max)
|
844
|
+
@data[key].reject {|_,v| v < min || v > max }
|
845
|
+
end
|
846
|
+
|
847
|
+
def remove_key_for_empty_collection(key)
|
848
|
+
del(key) if @data[key] && @data[key].empty?
|
849
|
+
end
|
697
850
|
end
|
698
851
|
end
|
699
852
|
end
|
data/spec/hashes_spec.rb
CHANGED
@@ -15,6 +15,31 @@ module FakeRedis
|
|
15
15
|
@client.hget("key1", "k2").should == "val2"
|
16
16
|
end
|
17
17
|
|
18
|
+
it "should remove a hash with no keys left" do
|
19
|
+
@client.hset("key1", "k1", "val1")
|
20
|
+
@client.hset("key1", "k2", "val2")
|
21
|
+
@client.hdel("key1", "k1")
|
22
|
+
@client.hdel("key1", "k2")
|
23
|
+
|
24
|
+
@client.exists("key1").should == false
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should convert key to a string via to_s for hset" do
|
28
|
+
m = double("key")
|
29
|
+
m.stub(:to_s).and_return("foo")
|
30
|
+
|
31
|
+
@client.hset("key1", m, "bar")
|
32
|
+
@client.hget("key1", "foo").should == "bar"
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should convert key to a string via to_s for hget" do
|
36
|
+
m = double("key")
|
37
|
+
m.stub(:to_s).and_return("foo")
|
38
|
+
|
39
|
+
@client.hset("key1", "foo", "bar")
|
40
|
+
@client.hget("key1", m).should == "bar"
|
41
|
+
end
|
42
|
+
|
18
43
|
it "should determine if a hash field exists" do
|
19
44
|
@client.hset("key1", "index", "value")
|
20
45
|
|
@@ -37,11 +62,15 @@ module FakeRedis
|
|
37
62
|
|
38
63
|
it "should increment the integer value of a hash field by the given number" do
|
39
64
|
@client.hset("key1", "cont1", "5")
|
40
|
-
@client.hincrby("key1", "cont1", "5")
|
41
|
-
|
65
|
+
@client.hincrby("key1", "cont1", "5").should == 10
|
42
66
|
@client.hget("key1", "cont1").should == "10"
|
43
67
|
end
|
44
68
|
|
69
|
+
it "should increment non existing hash keys" do
|
70
|
+
@client.hget("key1", "cont2").should be_nil
|
71
|
+
@client.hincrby("key1", "cont2", "5").should == 5
|
72
|
+
end
|
73
|
+
|
45
74
|
it "should get all the fields in a hash" do
|
46
75
|
@client.hset("key1", "i1", "val1")
|
47
76
|
@client.hset("key1", "i2", "val2")
|
@@ -73,18 +102,22 @@ module FakeRedis
|
|
73
102
|
end
|
74
103
|
|
75
104
|
it "should set the string value of a hash field" do
|
76
|
-
@client.hset("key1", "k1", "val1")
|
105
|
+
@client.hset("key1", "k1", "val1").should == true
|
106
|
+
@client.hset("key1", "k1", "val1").should == false
|
77
107
|
|
78
108
|
@client.hget("key1", "k1").should == "val1"
|
79
109
|
end
|
80
110
|
|
81
111
|
it "should set the value of a hash field, only if the field does not exist" do
|
82
112
|
@client.hset("key1", "k1", "val1")
|
83
|
-
@client.hsetnx("key1", "k1", "value")
|
84
|
-
@client.hsetnx("key1", "k2", "val2")
|
113
|
+
@client.hsetnx("key1", "k1", "value").should == false
|
114
|
+
@client.hsetnx("key1", "k2", "val2").should == true
|
115
|
+
@client.hsetnx("key1", :k1, "value").should == false
|
116
|
+
@client.hsetnx("key1", :k3, "val3").should == true
|
85
117
|
|
86
118
|
@client.hget("key1", "k1").should == "val1"
|
87
119
|
@client.hget("key1", "k2").should == "val2"
|
120
|
+
@client.hget("key1", "k3").should == "val3"
|
88
121
|
end
|
89
122
|
|
90
123
|
it "should get all the values in a hash" do
|
data/spec/keys_spec.rb
CHANGED
@@ -18,7 +18,6 @@ module FakeRedis
|
|
18
18
|
it "should determine if a key exists" do
|
19
19
|
@client.set("key1", "1")
|
20
20
|
|
21
|
-
puts "checking existence"
|
22
21
|
@client.exists("key1").should == true
|
23
22
|
@client.exists("key2").should == false
|
24
23
|
end
|
@@ -94,7 +93,9 @@ puts "checking existence"
|
|
94
93
|
|
95
94
|
it "should remove the expiration from a key" do
|
96
95
|
@client.set("key1", "1")
|
97
|
-
@client.
|
96
|
+
@client.expireat("key1", Time.now.to_i)
|
97
|
+
@client.persist("key1").should == true
|
98
|
+
@client.persist("key1").should == false
|
98
99
|
|
99
100
|
@client.ttl("key1").should == -1
|
100
101
|
end
|
@@ -137,5 +138,13 @@ puts "checking existence"
|
|
137
138
|
@client.type("key1").should == "string"
|
138
139
|
@client.type("key0").should == "none"
|
139
140
|
end
|
141
|
+
|
142
|
+
it "should convert the value into a string before storing" do
|
143
|
+
@client.set("key1", 1)
|
144
|
+
@client.get("key1").should == "1"
|
145
|
+
|
146
|
+
@client.setex("key2", 30, 1)
|
147
|
+
@client.get("key2").should == "1"
|
148
|
+
end
|
140
149
|
end
|
141
150
|
end
|
data/spec/lists_spec.rb
CHANGED
@@ -77,6 +77,15 @@ module FakeRedis
|
|
77
77
|
@client.llen("key1").should == 2
|
78
78
|
end
|
79
79
|
|
80
|
+
it "should remove list's key when list is empty" do
|
81
|
+
@client.rpush("key1", "v1")
|
82
|
+
@client.rpush("key1", "v2")
|
83
|
+
@client.lrem("key1", 1, "v1")
|
84
|
+
@client.lrem("key1", 1, "v2")
|
85
|
+
|
86
|
+
@client.exists("key1").should == false
|
87
|
+
end
|
88
|
+
|
80
89
|
it "should set the value of an element in a list by its index" do
|
81
90
|
@client.rpush("key1", "one")
|
82
91
|
@client.rpush("key1", "two")
|
data/spec/sets_spec.rb
CHANGED
@@ -7,7 +7,8 @@ module FakeRedis
|
|
7
7
|
end
|
8
8
|
|
9
9
|
it "should add a member to a set" do
|
10
|
-
@client.sadd("key", "value")
|
10
|
+
@client.sadd("key", "value").should == true
|
11
|
+
@client.sadd("key", "value").should == false
|
11
12
|
|
12
13
|
@client.smembers("key").should == ["value"]
|
13
14
|
end
|
@@ -93,7 +94,8 @@ module FakeRedis
|
|
93
94
|
@client.sadd("key1", "a")
|
94
95
|
@client.sadd("key1", "b")
|
95
96
|
@client.sadd("key2", "c")
|
96
|
-
@client.smove("key1", "key2", "a")
|
97
|
+
@client.smove("key1", "key2", "a").should == true
|
98
|
+
@client.smove("key1", "key2", "a").should == false
|
97
99
|
|
98
100
|
@client.smembers("key1").should == ["b"]
|
99
101
|
@client.smembers("key2").should =~ ["c", "a"]
|
@@ -118,11 +120,21 @@ module FakeRedis
|
|
118
120
|
it "should remove a member from a set" do
|
119
121
|
@client.sadd("key1", "a")
|
120
122
|
@client.sadd("key1", "b")
|
121
|
-
@client.srem("key1", "a")
|
123
|
+
@client.srem("key1", "a").should == true
|
124
|
+
@client.srem("key1", "a").should == false
|
122
125
|
|
123
126
|
@client.smembers("key1").should == ["b"]
|
124
127
|
end
|
125
128
|
|
129
|
+
it "should remove the set's key once it's empty" do
|
130
|
+
@client.sadd("key1", "a")
|
131
|
+
@client.sadd("key1", "b")
|
132
|
+
@client.srem("key1", "b")
|
133
|
+
@client.srem("key1", "a")
|
134
|
+
|
135
|
+
@client.exists("key1").should == false
|
136
|
+
end
|
137
|
+
|
126
138
|
it "should add multiple sets" do
|
127
139
|
@client.sadd("key1", "a")
|
128
140
|
@client.sadd("key1", "b")
|
data/spec/sorted_sets_spec.rb
CHANGED
@@ -1,68 +1,142 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module FakeRedis
|
4
|
+
describe "SortedSetsMethods" do
|
5
|
+
before(:each) do
|
6
|
+
@client = Redis.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should add a member to a sorted set, or update its score if it already exists" do
|
10
|
+
@client.zadd("key", 1, "val").should be(true)
|
11
|
+
@client.zscore("key", "val").should == "1"
|
12
|
+
|
13
|
+
@client.zadd("key", 2, "val").should be(false)
|
14
|
+
@client.zscore("key", "val").should == "2"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should remove members from sorted sets" do
|
18
|
+
@client.zrem("key", "val").should be(false)
|
19
|
+
@client.zadd("key", 1, "val").should be(true)
|
20
|
+
@client.zrem("key", "val").should be(true)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should remove sorted set's key when it is empty" do
|
24
|
+
@client.zadd("key", 1, "val")
|
25
|
+
@client.zrem("key", "val")
|
26
|
+
@client.exists("key").should == false
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should get the number of members in a sorted set" do
|
30
|
+
@client.zadd("key", 1, "val2")
|
31
|
+
@client.zadd("key", 2, "val1")
|
32
|
+
@client.zadd("key", 5, "val3")
|
33
|
+
|
34
|
+
@client.zcard("key").should == 3
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should count the members in a sorted set with scores within the given values" do
|
38
|
+
@client.zadd("key", 1, "val1")
|
39
|
+
@client.zadd("key", 2, "val2")
|
40
|
+
@client.zadd("key", 3, "val3")
|
41
|
+
|
42
|
+
@client.zcount("key", 2, 3).should == 2
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should increment the score of a member in a sorted set" do
|
46
|
+
@client.zadd("key", 1, "val1")
|
47
|
+
@client.zincrby("key", 2, "val1").should == "3"
|
48
|
+
@client.zscore("key", "val1").should == "3"
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should convert the key to a string for zscore" do
|
52
|
+
@client.zadd("key", 1, 1)
|
53
|
+
@client.zscore("key", 1).should == "1"
|
54
|
+
end
|
38
55
|
#it "should intersect multiple sorted sets and store the resulting sorted set in a new key"
|
39
56
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
57
|
+
it "should return a range of members in a sorted set, by index" do
|
58
|
+
@client.zadd("key", 1, "one")
|
59
|
+
@client.zadd("key", 2, "two")
|
60
|
+
@client.zadd("key", 3, "three")
|
61
|
+
|
62
|
+
@client.zrange("key", 0, -1).should == ["one", "two", "three"]
|
63
|
+
@client.zrange("key", 1, 2).should == ["two", "three"]
|
64
|
+
@client.zrange("key", 0, -1, :withscores => true).should == ["one", "1", "two", "2", "three", "3"]
|
65
|
+
@client.zrange("key", 1, 2, :with_scores => true).should == ["two", "2", "three", "3"]
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should return a reversed range of members in a sorted set, by index" do
|
69
|
+
@client.zadd("key", 1, "one")
|
70
|
+
@client.zadd("key", 2, "two")
|
71
|
+
@client.zadd("key", 3, "three")
|
72
|
+
|
73
|
+
@client.zrevrange("key", 0, -1).should == ["three", "two", "one"]
|
74
|
+
@client.zrevrange("key", 1, 2).should == ["two", "one"]
|
75
|
+
@client.zrevrange("key", 0, -1, :withscores => true).should == ["three", "3", "two", "2", "one", "1"]
|
76
|
+
@client.zrevrange("key", 0, -1, :with_scores => true).should == ["three", "3", "two", "2", "one", "1"]
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should return a range of members in a sorted set, by score" do
|
80
|
+
@client.zadd("key", 1, "one")
|
81
|
+
@client.zadd("key", 2, "two")
|
82
|
+
@client.zadd("key", 3, "three")
|
83
|
+
|
84
|
+
@client.zrangebyscore("key", 0, 100).should == ["one", "two", "three"]
|
85
|
+
@client.zrangebyscore("key", 1, 2).should == ["one", "two"]
|
86
|
+
@client.zrangebyscore("key", 0, 100, :withscores => true).should == ["one", "1", "two", "2", "three", "3"]
|
87
|
+
@client.zrangebyscore("key", 1, 2, :with_scores => true).should == ["one", "1", "two", "2"]
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should return a reversed range of members in a sorted set, by score" do
|
91
|
+
@client.zadd("key", 1, "one")
|
92
|
+
@client.zadd("key", 2, "two")
|
93
|
+
@client.zadd("key", 3, "three")
|
94
|
+
|
95
|
+
@client.zrevrangebyscore("key", 100, 0).should == ["three", "two", "one"]
|
96
|
+
@client.zrevrangebyscore("key", 2, 1).should == ["two", "one"]
|
97
|
+
@client.zrevrangebyscore("key", 1, 2).should == []
|
98
|
+
@client.zrevrangebyscore("key", 2, 1, :with_scores => true).should == ["two", "2", "one", "1"]
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should determine the index of a member in a sorted set" do
|
102
|
+
@client.zadd("key", 1, "one")
|
103
|
+
@client.zadd("key", 2, "two")
|
104
|
+
@client.zadd("key", 3, "three")
|
105
|
+
|
106
|
+
@client.zrank("key", "three").should == 2
|
107
|
+
@client.zrank("key", "four").should be_nil
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should determine the reversed index of a member in a sorted set" do
|
111
|
+
@client.zadd("key", 1, "one")
|
112
|
+
@client.zadd("key", 2, "two")
|
113
|
+
@client.zadd("key", 3, "three")
|
114
|
+
|
115
|
+
@client.zrevrank("key", "three").should == 0
|
116
|
+
@client.zrevrank("key", "four").should be_nil
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should create untersections between multiple (sorted) sets and store the resulting sorted set in a new key" do
|
120
|
+
@client.zadd("key1", 1, "one")
|
121
|
+
@client.zadd("key1", 2, "two")
|
122
|
+
@client.zadd("key1", 3, "three")
|
123
|
+
@client.zadd("key2", 5, "two")
|
124
|
+
@client.zadd("key2", 7, "three")
|
125
|
+
@client.sadd("key3", 'one')
|
126
|
+
@client.sadd("key3", 'two')
|
127
|
+
|
128
|
+
@client.zinterstore("out", ["key1", "key2"]).should == 2
|
129
|
+
@client.zrange("out", 0, 100, :with_scores => true).should == ['two', '7', 'three', '10']
|
130
|
+
|
131
|
+
@client.zinterstore("out", ["key1", "key3"]).should == 2
|
132
|
+
@client.zrange("out", 0, 100, :with_scores => true).should == ['one', '1', 'two', '2']
|
133
|
+
|
134
|
+
@client.zinterstore("out", ["key1", "key2", "key3"]).should == 1
|
135
|
+
@client.zrange("out", 0, 100, :with_scores => true).should == ['two', '7']
|
136
|
+
|
137
|
+
@client.zinterstore("out", ["key1", "no_key"]).should == 0
|
138
|
+
@client.zrange("out", 0, 100, :with_scores => true).should == []
|
139
|
+
end
|
66
140
|
|
67
141
|
#it "should remove all members in a sorted set within the given indexes"
|
68
142
|
|
@@ -77,5 +151,5 @@
|
|
77
151
|
#it "should get the score associated with the given member in a sorted set"
|
78
152
|
|
79
153
|
#it "should add multiple sorted sets and store the resulting sorted set in a new key"
|
80
|
-
|
81
|
-
|
154
|
+
end
|
155
|
+
end
|
data/spec/strings_spec.rb
CHANGED
@@ -64,16 +64,30 @@ module FakeRedis
|
|
64
64
|
|
65
65
|
it "should increment the integer value of a key by one" do
|
66
66
|
@client.set("counter", "1")
|
67
|
-
@client.incr("counter")
|
67
|
+
@client.incr("counter").should == 2
|
68
68
|
|
69
69
|
@client.get("counter").should == "2"
|
70
70
|
end
|
71
|
+
|
72
|
+
it "should decrement the integer value of a key by one" do
|
73
|
+
@client.set("counter", "1")
|
74
|
+
@client.decr("counter").should == 0
|
75
|
+
|
76
|
+
@client.get("counter").should == "0"
|
77
|
+
end
|
71
78
|
|
72
79
|
it "should increment the integer value of a key by the given number" do
|
73
80
|
@client.set("counter", "10")
|
74
|
-
@client.incrby("counter", "5")
|
81
|
+
@client.incrby("counter", "5").should == 15
|
82
|
+
@client.incrby("counter", 2).should == 17
|
83
|
+
@client.get("counter").should == "17"
|
84
|
+
end
|
75
85
|
|
76
|
-
|
86
|
+
it "should decrement the integer value of a key by the given number" do
|
87
|
+
@client.set("counter", "10")
|
88
|
+
@client.decrby("counter", "5").should == 5
|
89
|
+
@client.decrby("counter", 2).should == 3
|
90
|
+
@client.get("counter").should == "3"
|
77
91
|
end
|
78
92
|
|
79
93
|
it "should get the values of all the given keys" 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.
|
4
|
+
version: 0.3.0
|
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:
|
12
|
+
date: 2012-03-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: redis
|
16
|
-
requirement: &
|
16
|
+
requirement: &70149263528920 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 2.2.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70149263528920
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rspec
|
27
|
-
requirement: &
|
27
|
+
requirement: &70149263528400 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
version: 2.0.0
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70149263528400
|
36
36
|
description: Fake (In-memory) driver for redis-rb. Useful for testing environment
|
37
37
|
and machines without Redis.
|
38
38
|
email:
|
@@ -50,6 +50,7 @@ files:
|
|
50
50
|
- Rakefile
|
51
51
|
- fakeredis.gemspec
|
52
52
|
- lib/fakeredis.rb
|
53
|
+
- lib/fakeredis/rspec.rb
|
53
54
|
- lib/fakeredis/version.rb
|
54
55
|
- lib/redis/connection/memory.rb
|
55
56
|
- spec/compatibility_spec.rb
|
@@ -83,7 +84,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
83
84
|
version: '0'
|
84
85
|
requirements: []
|
85
86
|
rubyforge_project: fakeredis
|
86
|
-
rubygems_version: 1.8.
|
87
|
+
rubygems_version: 1.8.17
|
87
88
|
signing_key:
|
88
89
|
specification_version: 3
|
89
90
|
summary: Fake (In-memory) driver for redis-rb.
|