redis-objects 0.8.0 → 0.9.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.
@@ -46,6 +46,24 @@ describe Redis::Value do
46
46
  @value.options[:marshal] = false
47
47
  end
48
48
 
49
+ it "should not erroneously unmarshall a string" do
50
+ json_string = {json: 'value'}
51
+ @value = Redis::Value.new('spec/value', :marshal => true)
52
+ @value.value = json_string
53
+ @value.value.should == json_string
54
+ @value.clear
55
+
56
+ default_json_string = {json: 'default'}
57
+ @value = Redis::Value.new('spec/default', :default => default_json_string, :marshal => true)
58
+ @value.value.should == default_json_string
59
+ @value.clear
60
+
61
+ marshalled_string = Marshal.dump({json: 'marshal'})
62
+ @value = Redis::Value.new('spec/marshal', :default => marshalled_string, :marshal => true)
63
+ @value.value.should == marshalled_string
64
+ @value.clear
65
+ end
66
+
49
67
  it "should support renaming values" do
50
68
  @value.value = 'Peter Pan'
51
69
  @value.key.should == 'spec/value'
@@ -86,6 +104,19 @@ describe Redis::Value do
86
104
  @value.nil?.should == true
87
105
  end
88
106
 
107
+ it 'should set time to live in seconds when expiration option assigned' do
108
+ @value = Redis::Value.new('spec/value', :expiration => 10)
109
+ @value.value = 'monkey'
110
+ @value.ttl.should > 0
111
+ @value.ttl.should <= 10
112
+ end
113
+
114
+ it 'should set expiration when expireat option assigned' do
115
+ @value = Redis::Value.new('spec/value', :expireat => Time.now + 10.seconds)
116
+ @value.value = 'monkey'
117
+ @value.ttl.should > 0
118
+ end
119
+
89
120
  after do
90
121
  @value.delete
91
122
  end
@@ -298,6 +329,20 @@ describe Redis::List do
298
329
  @list.redis.del('spec/list2')
299
330
  end
300
331
 
332
+ it 'should set time to live in seconds when expiration option assigned' do
333
+ @list = Redis::List.new('spec/list', :expiration => 10)
334
+ @list << 'val'
335
+ @list.ttl.should > 0
336
+ @list.ttl.should <= 10
337
+ end
338
+
339
+ it 'should set expiration when expireat option assigned' do
340
+ @list = Redis::List.new('spec/list', :expireat => Time.now + 10.seconds)
341
+ @list << 'val'
342
+ @list.ttl.should > 0
343
+ @list.ttl.should <= 10
344
+ end
345
+
301
346
  after do
302
347
  @list.clear
303
348
  end
@@ -341,6 +386,33 @@ describe Redis::Counter do
341
386
  @counter.should == 111
342
387
  end
343
388
 
389
+ it "should support increment/decrement by float" do
390
+ @counter = Redis::Counter.new('spec/floater')
391
+ @counter.set 10.5
392
+ @counter.incrbyfloat 1
393
+ @counter.incrbyfloat 0.01
394
+ @counter.to_f.should == 11.51
395
+ @counter.set '5.0e3'
396
+ @counter.decrbyfloat -14.31
397
+ @counter.incrbyfloat 2.0e2
398
+ @counter.to_f.should == 5214.31
399
+ @counter.clear
400
+ end
401
+
402
+ it 'should set time to live in seconds when expiration option assigned' do
403
+ @counter = Redis::Counter.new('spec/counter', :expiration => 10)
404
+ @counter.increment
405
+ @counter.ttl.should > 0
406
+ @counter.ttl.should <= 10
407
+ end
408
+
409
+ it 'should set expiration when expireat option assigned' do
410
+ @counter = Redis::Counter.new('spec/counter', :expireat => Time.now + 10.seconds)
411
+ @counter.increment
412
+ @counter.ttl.should > 0
413
+ @counter.ttl.should <= 10
414
+ end
415
+
344
416
  after do
345
417
  @counter.delete
346
418
  end
@@ -473,8 +545,8 @@ describe Redis::HashKey do
473
545
  it "should handle complex marshaled values" do
474
546
  @hash.options[:marshal] = true
475
547
  @hash['abc'].should == nil
476
- @hash['abc'] = {:json => 'data'}
477
- @hash['abc'].should == {:json => 'data'}
548
+ @hash['abc'] = {:json => 'hash marshal'}
549
+ @hash['abc'].should == {:json => 'hash marshal'}
478
550
 
479
551
  # no marshaling
480
552
  @hash.options[:marshal] = false
@@ -544,6 +616,29 @@ describe Redis::HashKey do
544
616
  end
545
617
  end
546
618
 
619
+ it "should handle increment/decrement" do
620
+ @hash['integer'] = 1
621
+ @hash.incrby('integer')
622
+ @hash.incrby('integer', 2)
623
+ @hash.get('integer').to_i.should == 4
624
+
625
+ @hash['integer'] = 9
626
+ @hash.decrby('integer')
627
+ @hash.decrby('integer', 6)
628
+ @hash.get('integer').to_i.should == 2
629
+
630
+ @hash['float'] = 12.34
631
+ @hash.decrbyfloat('float')
632
+ @hash.decrbyfloat('float', 6.3)
633
+ @hash.get('float').to_f.should == 5.04
634
+
635
+ @hash['float'] = '5.0e3'
636
+ @hash.incrbyfloat('float')
637
+ @hash.incrbyfloat('float', '1.23e3')
638
+ @hash.incrbyfloat('float', 45.3)
639
+ @hash.get('float').to_f.should == 6276.3
640
+ end
641
+
547
642
  it "should respond to each_value" do
548
643
  @hash['foo'] = 'bar'
549
644
  @hash.each_value do |val|
@@ -603,6 +698,31 @@ describe Redis::HashKey do
603
698
  end
604
699
  end
605
700
 
701
+ it "should fetch default values" do
702
+ @hash['abc'] = "123"
703
+
704
+ value = @hash.fetch('missing_key','default_value')
705
+ block = @hash.fetch("missing_key") {|key| "oops: #{key}" }
706
+ no_error = @hash.fetch("abc") rescue "error"
707
+
708
+ no_error.should == "123"
709
+ value.should == "default_value"
710
+ block.should == "oops: missing_key"
711
+ end
712
+
713
+ it 'should set time to live in seconds when expiration option assigned' do
714
+ @hash = Redis::HashKey.new('spec/hash_key', :expiration => 10)
715
+ @hash['foo'] = 'bar'
716
+ @hash.ttl.should > 0
717
+ @hash.ttl.should <= 10
718
+ end
719
+
720
+ it 'should set expiration when expireat option assigned' do
721
+ @hash = Redis::HashKey.new('spec/hash_key', :expireat => Time.now + 10.seconds)
722
+ @hash['foo'] = 'bar'
723
+ @hash.ttl.should > 0
724
+ end
725
+
606
726
  after do
607
727
  @hash.clear
608
728
  end
@@ -665,6 +785,17 @@ describe Redis::Set do
665
785
  @set.sort.should == ['a','b','c']
666
786
  @set.delete_if{|m| m == 'c'}
667
787
  @set.sort.should == ['a','b']
788
+
789
+ @set << nil
790
+ @set.include?("").should.be.true
791
+ end
792
+
793
+ it "should handle empty array adds" do
794
+ should.not.raise(Redis::CommandError) { @set.add([]) }
795
+ @set.should.be.empty
796
+
797
+ should.not.raise(Redis::CommandError) { @set << [] }
798
+ @set.should.be.empty
668
799
  end
669
800
 
670
801
  it "should handle set intersections, unions, and diffs" do
@@ -764,7 +895,20 @@ describe Redis::Set do
764
895
  @set_1.redis.del val1.key
765
896
  @set_1.redis.del val2.key
766
897
  @set_1.redis.del SORT_STORE[:store]
898
+ end
899
+
900
+ it 'should set time to live in seconds when expiration option assigned' do
901
+ @set = Redis::Set.new('spec/set', :expiration => 10)
902
+ @set << 'val'
903
+ @set.ttl.should > 0
904
+ @set.ttl.should <= 10
905
+ end
767
906
 
907
+ it 'should set expiration when expireat option assigned' do
908
+ @set = Redis::Set.new('spec/set', :expireat => Time.now + 10.seconds)
909
+ @set << 'val'
910
+ @set.ttl.should > 0
911
+ @set.ttl.should <= 10
768
912
  end
769
913
 
770
914
  after do
@@ -882,6 +1026,17 @@ describe Redis::SortedSet do
882
1026
  @set.size.should == 3
883
1027
  end
884
1028
 
1029
+ it "should handle inserting multiple values at once" do
1030
+ @set.merge({ 'a' => 1, 'b' => 2 })
1031
+ @set.merge([['a', 4], ['c', 5]])
1032
+ @set.merge({d: 0, e: 9 })
1033
+
1034
+ @set.members.should == ["d", "b", "a", "c", "e"]
1035
+
1036
+ @set[:f] = 3
1037
+ @set.members.should == ["d", "b", "f", "a", "c", "e"]
1038
+ end
1039
+
885
1040
  it "should support marshaling key names" do
886
1041
  @set_4[Object] = 1.20
887
1042
  @set_4[Module] = 2.30
@@ -909,6 +1064,20 @@ describe Redis::SortedSet do
909
1064
  @set.redis.del('spec/zset2')
910
1065
  end
911
1066
 
1067
+ it 'should set time to live in seconds when expiration option assigned' do
1068
+ @set = Redis::SortedSet.new('spec/zset', :expiration => 10)
1069
+ @set['val'] = 1
1070
+ @set.ttl.should > 0
1071
+ @set.ttl.should <= 10
1072
+ end
1073
+
1074
+ it 'should set expiration when expireat option assigned' do
1075
+ @set = Redis::SortedSet.new('spec/zset', :expireat => Time.now + 10.seconds)
1076
+ @set['val'] = 1
1077
+ @set.ttl.should > 0
1078
+ @set.ttl.should <= 10
1079
+ end
1080
+
912
1081
  after do
913
1082
  @set.clear
914
1083
  @set_1.clear
@@ -33,6 +33,20 @@ class Roster
33
33
  #callable as key
34
34
  counter :daily, :global => true, :key => Proc.new { |roster| "#{roster.name}:#{Time.now.strftime('%Y-%m-%dT%H')}:daily" }
35
35
 
36
+ # set default expiration
37
+ value :value_with_expiration, :expiration => 10
38
+ value :value_with_expireat, :expireat => Time.now + 10.seconds
39
+ set :set_with_expiration, :expiration => 10
40
+ set :set_with_expireat, :expireat => Time.now + 10.seconds
41
+ list :list_with_expiration, :expiration => 10
42
+ list :list_with_expireat, :expireat => Time.now + 10.seconds
43
+ hash_key :hash_with_expiration, :expiration => 10
44
+ hash_key :hash_with_expireat, :expireat => Time.now + 10.seconds
45
+ counter :counter_with_expiration, :expiration => 10
46
+ counter :counter_with_expireat, :expireat => Time.now + 10.seconds
47
+ sorted_set :sorted_set_with_expiration,:expiration => 10
48
+ sorted_set :sorted_set_with_expireat, :expireat => Time.now + 10.seconds
49
+
36
50
  def initialize(id=1) @id = id end
37
51
  def id; @id; end
38
52
  def username; "user#{id}"; end
@@ -594,19 +608,23 @@ describe Redis::Objects do
594
608
  @roster_1.outfielders.intersection(@roster_2.outfielders, @roster_3.outfielders).sort.should == ['d']
595
609
  @roster_1.outfielders.intersect(@roster_2.outfielders).sort.should == ['c','d','e']
596
610
  @roster_1.outfielders.inter(@roster_2.outfielders, @roster_3.outfielders).sort.should == ['d']
611
+
597
612
  @roster_1.outfielders.interstore(INTERSTORE_KEY, @roster_2.outfielders).should == 3
598
- @roster_1.redis.smembers(INTERSTORE_KEY).sort.should == ['c','d','e']
613
+ @roster_1.redis.smembers(INTERSTORE_KEY).sort.map{|v| Marshal.restore(v)}.should == ['c','d','e']
614
+
599
615
  @roster_1.outfielders.interstore(INTERSTORE_KEY, @roster_2.outfielders, @roster_3.outfielders).should == 1
600
- @roster_1.redis.smembers(INTERSTORE_KEY).sort.should == ['d']
616
+ @roster_1.redis.smembers(INTERSTORE_KEY).sort.map{|v| Marshal.restore(v)}.should == ['d']
601
617
 
602
618
  (@roster_1.outfielders | @roster_2.outfielders).sort.should == ['a','b','c','d','e','f','g']
603
619
  (@roster_1.outfielders + @roster_2.outfielders).sort.should == ['a','b','c','d','e','f','g']
604
620
  @roster_1.outfielders.union(@roster_2.outfielders).sort.should == ['a','b','c','d','e','f','g']
605
621
  @roster_1.outfielders.union(@roster_2.outfielders, @roster_3.outfielders).sort.should == ['a','b','c','d','e','f','g','l','m']
622
+
606
623
  @roster_1.outfielders.unionstore(UNIONSTORE_KEY, @roster_2.outfielders).should == 7
607
- @roster_1.redis.smembers(UNIONSTORE_KEY).sort.should == ['a','b','c','d','e','f','g']
624
+ @roster_1.redis.smembers(UNIONSTORE_KEY).map{|v| Marshal.restore(v)}.sort.should == ['a','b','c','d','e','f','g']
625
+
608
626
  @roster_1.outfielders.unionstore(UNIONSTORE_KEY, @roster_2.outfielders, @roster_3.outfielders).should == 9
609
- @roster_1.redis.smembers(UNIONSTORE_KEY).sort.should == ['a','b','c','d','e','f','g','l','m']
627
+ @roster_1.redis.smembers(UNIONSTORE_KEY).map{|v| Marshal.restore(v)}.sort.should == ['a','b','c','d','e','f','g','l','m']
610
628
  end
611
629
 
612
630
  it "should handle class-level global lists of simple values" do
@@ -920,4 +938,52 @@ describe Redis::Objects do
920
938
  extended_roster.extended_sorted_set.should.be.kind_of(Redis::SortedSet)
921
939
  @roster.respond_to?(:extended_sorted_set).should == false
922
940
  end
941
+
942
+ it "should set time to live in seconds when expiration option assigned" do
943
+ @roster.value_with_expiration.value = 'val'
944
+ @roster.value_with_expiration.ttl.should > 0
945
+ @roster.value_with_expiration.ttl.should <= 10
946
+
947
+ @roster.set_with_expiration << 'val'
948
+ @roster.set_with_expiration.ttl.should > 0
949
+ @roster.set_with_expiration.ttl.should <= 10
950
+
951
+ @roster.list_with_expiration << 'val'
952
+ @roster.list_with_expiration.ttl.should > 0
953
+ @roster.list_with_expiration.ttl.should <= 10
954
+
955
+ @roster.hash_with_expiration[:foo] = :bar
956
+ @roster.hash_with_expiration.ttl.should > 0
957
+ @roster.hash_with_expiration.ttl.should <= 10
958
+
959
+ @roster.counter_with_expiration.increment
960
+ @roster.counter_with_expiration.ttl.should > 0
961
+ @roster.counter_with_expiration.ttl.should <= 10
962
+
963
+ @roster.sorted_set_with_expiration[:foo] = 1
964
+ @roster.sorted_set_with_expiration.ttl.should > 0
965
+ @roster.sorted_set_with_expiration.ttl.should <= 10
966
+ end
967
+
968
+ it "should set expiration when expireat option assigned" do
969
+ @roster.value_with_expireat.value = 'val'
970
+ @roster.value_with_expireat.ttl.should > 0
971
+ @roster.value_with_expireat.ttl.should <= 10
972
+
973
+ @roster.set_with_expireat << 'val'
974
+ @roster.set_with_expireat.ttl.should > 0
975
+ @roster.set_with_expireat.ttl.should <= 10
976
+
977
+ @roster.list_with_expireat << 'val'
978
+ @roster.list_with_expireat.ttl.should > 0
979
+ @roster.list_with_expireat.ttl.should <= 10
980
+
981
+ @roster.hash_with_expireat[:foo] = :bar
982
+ @roster.hash_with_expireat.ttl.should > 0
983
+ @roster.hash_with_expireat.ttl.should <= 10
984
+
985
+ @roster.sorted_set_with_expireat[:foo] = 1
986
+ @roster.sorted_set_with_expireat.ttl.should > 0
987
+ @roster.sorted_set_with_expireat.ttl.should <= 10
988
+ end
923
989
  end
data/spec/spec_helper.rb CHANGED
@@ -19,26 +19,31 @@ DIFFSTORE_KEY = 'test:diffstore'
19
19
  REDIS_BIN = 'redis-server'
20
20
  REDIS_PORT = ENV['REDIS_PORT'] || 9212
21
21
  REDIS_HOST = ENV['REDIS_HOST'] || 'localhost'
22
- REDIS_PID = File.expand_path 'redis.pid', File.dirname(__FILE__)
23
- REDIS_DUMP = File.expand_path 'redis.rdb', File.dirname(__FILE__)
22
+ REDIS_PID = 'redis.pid' # can't be absolute
23
+ REDIS_DUMP = 'redis.rdb' # can't be absolute
24
+ REDIS_RUNDIR = File.dirname(__FILE__)
24
25
 
25
- describe 'redis-server' do
26
- it "starting redis-server on #{REDIS_HOST}:#{REDIS_PORT}" do
27
- fork_pid = fork do
28
- system "(echo port #{REDIS_PORT}; echo logfile /dev/null; echo daemonize yes; echo pidfile #{REDIS_PID}; echo dbfilename #{REDIS_DUMP}) | #{REDIS_BIN} -"
26
+ if !(defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby")
27
+ describe 'redis-server' do
28
+ it "starting redis-server on #{REDIS_HOST}:#{REDIS_PORT}" do
29
+ fork_pid = fork do
30
+ system "cd #{REDIS_RUNDIR} && (echo port #{REDIS_PORT}; echo logfile /dev/null; echo daemonize yes; echo pidfile #{REDIS_PID}; echo dbfilename #{REDIS_DUMP}; echo databases 32) | #{REDIS_BIN} -"
31
+ end
32
+ fork_pid.should > 0
33
+ sleep 2
29
34
  end
30
- fork_pid.should > 0
31
- sleep 2
32
35
  end
33
- end
34
36
 
35
- at_exit do
36
- pid = File.read(REDIS_PID).to_i
37
- puts "=> Killing #{REDIS_BIN} with pid #{pid}"
38
- Process.kill "TERM", pid
39
- Process.kill "KILL", pid
40
- File.unlink REDIS_PID
41
- File.unlink REDIS_DUMP if File.exists? REDIS_DUMP
37
+ at_exit do
38
+ pidfile = File.expand_path REDIS_PID, REDIS_RUNDIR
39
+ rdbfile = File.expand_path REDIS_DUMP, REDIS_RUNDIR
40
+ pid = File.read(pidfile).to_i
41
+ puts "=> Killing #{REDIS_BIN} with pid #{pid}"
42
+ Process.kill "TERM", pid
43
+ Process.kill "KILL", pid
44
+ File.unlink pidfile
45
+ File.unlink rdbfile if File.exists? rdbfile
46
+ end
42
47
  end
43
48
 
44
49
  def raises_exception(&block)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis-objects
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nate Wiger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-09 00:00:00.000000000 Z
11
+ date: 2014-02-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
@@ -115,7 +115,6 @@ files:
115
115
  - lib/redis/counter.rb
116
116
  - lib/redis/hash_key.rb
117
117
  - lib/redis/helpers/core_commands.rb
118
- - lib/redis/helpers/serialize.rb
119
118
  - lib/redis/list.rb
120
119
  - lib/redis/lock.rb
121
120
  - lib/redis/objects.rb
@@ -1,41 +0,0 @@
1
- class Redis
2
- module Helpers
3
- module Serialize
4
- include Marshal
5
-
6
- def to_redis(value, marshal=false)
7
- return value unless options[:marshal] || marshal
8
- case value
9
- when String, Fixnum, Bignum, Float
10
- value
11
- else
12
- dump(value)
13
- end
14
- end
15
-
16
- def from_redis(value, marshal=false)
17
- # This was removed because we can't reliably determine
18
- # if a person said @value = "123.4" maybe for space/etc.
19
- #begin
20
- # case value
21
- # when /^\d+$/
22
- # return Integer(value)
23
- # when /^(?:\d+\d.\d*|\d*\.\d+)$/
24
- # return Float(value)
25
- # end
26
- #rescue
27
- # # continue below
28
- #end
29
- return value unless options[:marshal] || marshal
30
- case value
31
- when Array
32
- value.collect{|v| from_redis(v)}
33
- when Hash
34
- value.inject({}) { |h, (k, v)| h[k] = from_redis(v); h }
35
- else
36
- restore(value) rescue value
37
- end
38
- end
39
- end
40
- end
41
- end