fakeredis 0.2.2 → 0.3.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.
- 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.
|