redis-objects 1.5.1 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5c7bc592d203647a8b7e9fd574a78eec1ec466e85fef95d30fac6d831f5d086a
4
- data.tar.gz: e89a8a50ddac32cc8b0fd5692697c21620ef97bac6f28c1841c0e50e9a833429
3
+ metadata.gz: 831f2916f47c47d9e3fcce9f8c585327c3e0e6e56204880ddfc860c279ec0e85
4
+ data.tar.gz: 188263c23463afc2f68b026efb79bac230ed140fba5d164540c99bac9d4553c2
5
5
  SHA512:
6
- metadata.gz: 7a91ab932b94a4a36ab4da40d173804b71c46b21c28e917acefb5f1720da1dd60fe3e4c0d06e124c172118789c31fa11f0f4b96b7b27da97cbd8f7a90f01dd6c
7
- data.tar.gz: d92e900d1fcec537a439e99ad7d311a83ad23c1e5c28ecc84e8922a0c7da56b4fdcfc9cadcb48aca382c4a6c8045dd24ecbeb81d681aa4fcad2c9d13b3cf9a8f
6
+ metadata.gz: 2189c5151d3f59ca67445e4f560e23f68e34c62c6a257b58bbf9eb08775420044b82680c7dc4b808769347542c27fa1f295776bd418e4bf34a1d1e1b78799843
7
+ data.tar.gz: a26ad235bba5d586b8076c5640d4f725806187e41345af154d929b8ba4339932d97c86fb9d4a512777052df67aeca0a3f0fcda7d22e4f55248ff78fd14e3b552
data/.gitignore CHANGED
@@ -9,3 +9,5 @@ spec/redis.pid
9
9
  dump.rdb
10
10
  Gemfile.lock
11
11
  redis-objects-*.gem
12
+ coverage/
13
+ .DS_Store
data/.travis.yml CHANGED
@@ -5,7 +5,12 @@ before_install:
5
5
  - gem install bundler
6
6
 
7
7
  rvm:
8
- - 2.3.3
9
- - 2.4.0
10
- - 2.5.1
11
- - 2.6.4
8
+ - 2.3.8
9
+ - 2.4.10
10
+ - 2.5.9
11
+ - 2.6.7
12
+ - 2.7.3
13
+ - 3.0.1
14
+
15
+ # For code coverage reports
16
+ script: bundle exec rake
data/README.md CHANGED
@@ -1,7 +1,8 @@
1
1
  Redis::Objects - Map Redis types directly to Ruby objects
2
2
  =========================================================
3
3
 
4
- [![Build Status](https://travis-ci.org/nateware/redis-objects.png)](https://travis-ci.org/nateware/redis-objects)
4
+ [![Build Status](https://app.travis-ci.com/nateware/redis-objects.svg?branch=master)](https://travis-ci.com/github/nateware/redis-objects)
5
+ [![Code Coverage](https://codecov.io/gh/nateware/redis-objects/branch/master/graph/badge.svg)](https://codecov.io/gh/nateware/redis-objects)
5
6
  [![Donate](https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=MJF7JU5M7F8VL)
6
7
 
7
8
  This is **not** an ORM. People that are wrapping ORM’s around Redis are missing the point.
@@ -123,24 +123,20 @@ class Redis
123
123
  hsh
124
124
  end
125
125
 
126
- # Get values in bulk, takes an array of keys as arguments.
126
+ # Get values in bulk, takes an array of fields as arguments.
127
127
  # Values are returned in a collection in the same order than their keys in *keys Redis: HMGET
128
- def bulk_values(*keys)
129
- get_keys = *keys.flatten
130
- return [] if get_keys.empty?
131
- res = redis.hmget(key, get_keys)
132
- get_keys.inject([]){|collection, k| collection << unmarshal(res.shift, options[:marshal_keys][k])}
128
+ def bulk_values(*fields)
129
+ get_fields = *fields.flatten
130
+ return [] if get_fields.empty?
131
+ res = redis.hmget(key, get_fields)
132
+ get_fields.collect{|k| unmarshal(res.shift, options[:marshal_keys][k])}
133
133
  end
134
134
 
135
135
  # Increment value by integer at field. Redis: HINCRBY
136
136
  def incrby(field, by=1)
137
137
  allow_expiration do
138
138
  ret = redis.hincrby(key, field, by)
139
- unless ret.is_a? Array
140
- ret.to_i
141
- else
142
- nil
143
- end
139
+ ret.to_i
144
140
  end
145
141
  end
146
142
  alias_method :incr, :incrby
@@ -155,11 +151,7 @@ class Redis
155
151
  def incrbyfloat(field, by=1.0)
156
152
  allow_expiration do
157
153
  ret = redis.hincrbyfloat(key, field, by)
158
- unless ret.is_a? Array
159
- ret.to_f
160
- else
161
- nil
162
- end
154
+ ret.to_f
163
155
  end
164
156
  end
165
157
 
@@ -2,6 +2,10 @@ class Redis
2
2
  module Helpers
3
3
  # These are core commands that all types share (rename, etc)
4
4
  module CoreCommands
5
+ def exists
6
+ redis.exists key
7
+ end
8
+
5
9
  def exists?
6
10
  redis.exists? key
7
11
  end
@@ -1,5 +1,5 @@
1
1
  class Redis
2
2
  module Objects
3
- VERSION = "1.5.1"
3
+ VERSION = "1.6.0"
4
4
  end
5
5
  end
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  # Only fix this one version or else tests break
22
- spec.add_dependency "redis", "~> 4.2"
22
+ spec.add_dependency "redis", "< 4.6"
23
23
 
24
24
  # Ignore gemspec warnings on these. Trying to fix them to versions breaks TravisCI
25
25
  spec.add_development_dependency "bundler"
@@ -29,6 +29,10 @@ Gem::Specification.new do |spec|
29
29
 
30
30
  # Compatibility testing
31
31
  spec.add_development_dependency "redis-namespace"
32
+ spec.add_development_dependency "activesupport"
32
33
  spec.add_development_dependency "activerecord"
33
34
  spec.add_development_dependency "sqlite3"
35
+
36
+ # Code coverage
37
+ spec.add_development_dependency "simplecov-cobertura"
34
38
  end
@@ -4,7 +4,7 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
4
4
  # tests whether autoload functionality works correctly; had issues previously
5
5
 
6
6
  require 'redis/objects'
7
- # $redis used automatically
7
+ Redis::Objects.redis = REDIS_HANDLE
8
8
 
9
9
  describe 'Redis::Objects' do
10
10
  it "should autoload everything" do
@@ -5,6 +5,7 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
5
5
 
6
6
  require 'redis/objects'
7
7
  require 'connection_pool'
8
+ Redis::Objects.redis = REDIS_HANDLE
8
9
 
9
10
  BAD_REDIS = "totally bad bogus redis handle"
10
11
 
@@ -95,13 +96,13 @@ describe 'Connection tests' do
95
96
  end
96
97
 
97
98
  it "should support local handles with a vanilla redis connection" do
98
- Redis.current = nil # reset from other tests
99
+ # Redis.current = nil # reset from other tests
99
100
  Redis::Objects.redis = nil
100
101
  @redis_handle = Redis.new(:host => REDIS_HOST, :port => REDIS_PORT)
101
102
 
102
103
  # Redis.current is lazily auto-populated to touch 6379
103
104
  # This why we choose the weird 9212 port to avoid
104
- Redis.current.inspect.should == Redis.new.inspect
105
+ # Redis.current.inspect.should == Redis.new.inspect
105
106
  Redis::Objects.redis.inspect.should == Redis.new.inspect
106
107
 
107
108
  v = Redis::Value.new('conn/value', @redis_handle)
@@ -140,13 +141,13 @@ describe 'Connection tests' do
140
141
  end
141
142
 
142
143
  it "should support local handles with a connection_pool" do
143
- Redis.current = nil # reset from other tests
144
+ # Redis.current = nil # reset from other tests
144
145
  Redis::Objects.redis = nil
145
146
  @redis_handle = ConnectionPool.new { Redis.new(:host => REDIS_HOST, :port => REDIS_PORT) }
146
147
 
147
148
  # Redis.current is lazily auto-populated to touch 6379
148
149
  # This why we choose the weird 9212 port to avoid
149
- Redis.current.inspect.should == Redis.new.inspect
150
+ # Redis.current.inspect.should == Redis.new.inspect
150
151
  Redis::Objects.redis.inspect.should == Redis.new.inspect
151
152
 
152
153
  v = Redis::Value.new('conn/value', @redis_handle)
@@ -184,24 +185,19 @@ describe 'Connection tests' do
184
185
  c.decr(1)
185
186
  end
186
187
 
187
- it "should support Redis.current" do
188
- Redis.current = Redis.new(:host => REDIS_HOST, :port => REDIS_PORT)
189
-
190
- Redis::Value.new('conn/value').should == 'yay'
191
- Redis::HashKey.new('conn/hash').keys.should == ['k']
192
- Redis::List.new('conn/list').sort.should == ['3', '4', '5']
193
- Redis::Set.new('conn/set').sort.should == ['5', '6', '7']
194
- Redis::SortedSet.new('conn/zset').should == ['d', 'b', 'a', 'c']
195
- Redis::Counter.new('conn/counter').should == 2
188
+ it "should properly support fallback handle variables" do
189
+ # Redis.current is lazily auto-populated to touch 6379
190
+ # This why we choose the weird 9212 port to avoid
191
+ old_redis = $redis
192
+ $redis = BAD_REDIS
193
+ Redis::Objects.redis.should == BAD_REDIS
194
+ $redis = old_redis
196
195
  end
197
196
 
198
197
  it "should support Redis::Objects.redis= with a connection_pool" do
198
+ # reset redis
199
199
  @redis_handle = ConnectionPool.new { Redis.new(:host => REDIS_HOST, :port => REDIS_PORT) }
200
-
201
- # Redis.current is lazily auto-populated to touch 6379
202
- # This why we choose the weird 9212 port to avoid
203
- Redis.current = BAD_REDIS
204
- Redis::Objects.redis.should == BAD_REDIS
200
+ Redis::Objects.redis = @redis_handle
205
201
 
206
202
  # This set of tests sucks, it fucks up the per-data-type handles
207
203
  # because Redis.current is then set to a BS value, and the lazy
@@ -229,13 +225,8 @@ describe 'Connection tests' do
229
225
 
230
226
  it "should support Redis::Objects.redis= with a vanilla redis connection" do
231
227
  # reset redis
232
- Redis::Objects.redis = nil
233
228
  @redis_handle = Redis.new(:host => REDIS_HOST, :port => REDIS_PORT)
234
-
235
- # Redis.current is lazily auto-populated to touch 6379
236
- # This why we choose the weird 9212 port to avoid
237
- Redis.current = BAD_REDIS
238
- Redis::Objects.redis.should == BAD_REDIS
229
+ Redis::Objects.redis = @redis_handle
239
230
 
240
231
  # This set of tests sucks, it fucks up the per-data-type handles
241
232
  # because Redis.current is then set to a BS value, and the lazy
@@ -260,7 +251,7 @@ describe 'Connection tests' do
260
251
  Redis::Counter.new('conn/counter').should == 2
261
252
 
262
253
  # Fix for future tests
263
- Redis.current = @redis_handle
254
+ # Redis.current = @redis_handle
264
255
  end
265
256
 
266
257
  it "should support pipelined changes" do
@@ -2,6 +2,7 @@
2
2
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
3
3
 
4
4
  require 'redis/objects'
5
+ Redis::Objects.redis = REDIS_HANDLE
5
6
 
6
7
  class CustomSerializer
7
8
  class << self
@@ -2,6 +2,7 @@
2
2
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
3
3
 
4
4
  require 'redis/objects'
5
+ Redis::Objects.redis = REDIS_HANDLE
5
6
 
6
7
  describe Redis::Value do
7
8
  before do
@@ -19,6 +20,21 @@ describe Redis::Value do
19
20
  @value.value.should == false
20
21
  end
21
22
 
23
+ it "should handle simple values" do
24
+ @value.should == nil
25
+ @value.value = 'Trevor Hoffman'
26
+ @value.should == 'Trevor Hoffman'
27
+ @value.get.should == 'Trevor Hoffman'
28
+ @value.exists?.should == true
29
+ @value.exists.should == 1
30
+ @value.del.should == 1
31
+ @value.should.be.nil
32
+ @value.exists?.should == false
33
+ @value.exists.should == 0
34
+ @value.value = 42
35
+ @value.value.should == '42'
36
+ end
37
+
22
38
  it "should compress non marshaled values" do
23
39
  @value = Redis::Value.new('spec/value', compress: true)
24
40
  @value.value = 'Trevor Hoffman'
@@ -39,17 +55,8 @@ describe Redis::Value do
39
55
  @value.value.should == nil
40
56
  @value.value = ''
41
57
  @value.value.should == ''
42
- end
43
-
44
- it "should handle simple values" do
45
- @value.should == nil
46
- @value.value = 'Trevor Hoffman'
47
- @value.should == 'Trevor Hoffman'
48
- @value.get.should == 'Trevor Hoffman'
49
- @value.del.should == 1
50
- @value.should.be.nil
51
- @value.value = 42
52
- @value.value.should == '42'
58
+ @value.delete
59
+ @value.value.should.be.nil
53
60
  end
54
61
 
55
62
  it "should handle complex marshaled values" do
@@ -88,7 +95,7 @@ describe Redis::Value do
88
95
  marshalled_string = Marshal.dump({json: 'marshal'})
89
96
  @value = Redis::Value.new('spec/marshal', :default => marshalled_string, :marshal => true)
90
97
  @value.value.should == marshalled_string
91
- @value.clear
98
+ @value.delete
92
99
  end
93
100
 
94
101
  it "should support renaming values" do
@@ -499,6 +506,7 @@ describe Redis::Counter do
499
506
  @counter.incrbyfloat 2.0e2
500
507
  @counter.to_f.should == 5214.31
501
508
  @counter.clear
509
+ @counter.should.be.nil
502
510
  end
503
511
 
504
512
  it "should support an atomic block" do
@@ -545,6 +553,9 @@ describe Redis::Counter do
545
553
  @updated = @counter.decrement(1) { |updated| updated == 2 ? 'yep' : nil }
546
554
  @updated.should == 'yep'
547
555
  @counter.should == 2
556
+
557
+ @counter.value = nil
558
+ @counter.should == 0
548
559
  end
549
560
 
550
561
  it "should support #to_json" do
@@ -644,7 +655,7 @@ describe Redis::Lock do
644
655
  REDIS_HANDLE.get("test_lock").should.be.nil
645
656
  end
646
657
 
647
- it "should not let non-expired locks be gettable" do
658
+ it "should not let blocks execute if they timeout" do
648
659
  expiry = 15
649
660
  lock = Redis::Lock.new(:test_lock, :expiration => expiry, :timeout => 0.1)
650
661
 
@@ -669,19 +680,68 @@ describe Redis::Lock do
669
680
  REDIS_HANDLE.get("test_lock").should.not.be.nil
670
681
  end
671
682
 
683
+ it "should handle a timeout of 0" do
684
+ expiry = 15
685
+ lock = Redis::Lock.new(:test_lock, :timeout => 0)
686
+
687
+ # create a fake lock
688
+ REDIS_HANDLE.set("test_lock", (Time.now + expiry).to_f)
689
+
690
+ gotit = false
691
+ error = nil
692
+ begin
693
+ lock.lock do
694
+ gotit = true
695
+ end
696
+ rescue => error
697
+ end
698
+
699
+ error.should.be.kind_of(Redis::Lock::LockTimeout)
700
+
701
+ # should not have the lock
702
+ gotit.should.not.be.true
703
+
704
+ # lock value should still be set
705
+ REDIS_HANDLE.get("test_lock").should.not.be.nil
706
+ end
707
+
708
+ it "should properly keep the lock across threads" do
709
+ lock = Redis::Lock.new(:test_lock0)
710
+
711
+ t1 = Thread.new do
712
+ lock.lock do
713
+ lock.exists?.should.be.true if RUNNING_LOCALLY
714
+ REDIS_HANDLE.exists?("test_lock0").should.be.true if RUNNING_LOCALLY
715
+ sleep 1.0 # hang onto the lock across other thread
716
+ end
717
+ end
718
+
719
+ t2 = Thread.new do
720
+ # check for the lock from another thread
721
+ lock.exists?.should.be.true if RUNNING_LOCALLY
722
+ REDIS_HANDLE.exists?("test_lock0").should.be.true if RUNNING_LOCALLY
723
+ end
724
+
725
+ t1.join
726
+ t2.join
727
+
728
+ # lock value should not be set since the lock was held for more than the expiry
729
+ lock.exists?.should.be.false
730
+ REDIS_HANDLE.exists?("test_lock0").should.be.false
731
+ end
732
+
672
733
  it "Redis should remove the key if lock is held past expiration" do
673
- lock = Redis::Lock.new(:test_lock, :expiration => 0.1)
734
+ lock = Redis::Lock.new(:test_lock1, :expiration => 0.1)
674
735
 
675
736
  lock.lock do
676
- REDIS_HANDLE.exists("test_lock").should.be.true
677
- sleep 0.3
678
- # technically undefined behavior because we don't have a BG thread
679
- # running and deleting lock keys - that is only triggered on block exit
680
- #REDIS_HANDLE.exists("test_lock").should.be.false
737
+ lock.exists?.should.be.true
738
+ REDIS_HANDLE.exists?("test_lock1").should.be.true
739
+ sleep 1.0 # hang onto the lock > expiry
681
740
  end
682
741
 
683
742
  # lock value should not be set since the lock was held for more than the expiry
684
- REDIS_HANDLE.exists("test_lock").should.be.false
743
+ lock.exists?.should.be.false
744
+ REDIS_HANDLE.exists?("test_lock1").should.be.false
685
745
  end
686
746
 
687
747
 
@@ -689,9 +749,9 @@ describe Redis::Lock do
689
749
  lock = Redis::Lock.new(:test_lock2, :expiration => 0.1)
690
750
 
691
751
  lock.lock do
692
- REDIS_HANDLE.exists("test_lock2").should.be.true
693
- sleep 0.3 # expired, key is deleted
694
- REDIS_HANDLE.exists("test_lock2").should.be.false
752
+ REDIS_HANDLE.exists?("test_lock2").should.be.true
753
+ sleep 1.0 # expired, key is deleted
754
+ REDIS_HANDLE.exists?("test_lock2").should.be.false
695
755
  REDIS_HANDLE.set("test_lock2", "foo") # this is no longer a lock key, name is a coincidence
696
756
  end
697
757
 
@@ -699,17 +759,17 @@ describe Redis::Lock do
699
759
  end
700
760
 
701
761
  it "should manually delete the key if finished before expiration" do
702
- lock = Redis::Lock.new(:test_lock3, :expiration => 0.5)
762
+ lock = Redis::Lock.new(:test_lock3, :expiration => 10.0)
703
763
 
704
764
  lock.lock do
705
- REDIS_HANDLE.exists("test_lock3").should.be.true
765
+ REDIS_HANDLE.exists?("test_lock3").should.be.true
706
766
  sleep 0.1
707
- REDIS_HANDLE.exists("test_lock3").should.be.true
767
+ REDIS_HANDLE.exists?("test_lock3").should.be.true
708
768
  end
709
769
 
710
- # should delete the key because the lock block is done, regardless of time
770
+ # should delete the key because the lock block is done, regardless of expiry
711
771
  # for some strange reason, I have seen this test fail randomly, which is worrisome.
712
- #REDIS_HANDLE.exists("test_lock3").should.be.false
772
+ REDIS_HANDLE.exists?("test_lock3").should.be.false
713
773
  end
714
774
 
715
775
 
@@ -929,6 +989,13 @@ describe Redis::HashKey do
929
989
  hsh['foo'].should == 'bar'
930
990
  end
931
991
 
992
+ it "should return multiple items via bulk_values" do
993
+ @hash['taco'] = 42
994
+ @hash['burrito'] = 99
995
+ res = @hash.bulk_values('taco', 'burrito')
996
+ res.should == ['42', '99'] # hashes don't convert
997
+ end
998
+
932
999
  it "should increment field" do
933
1000
  @hash.incr('counter')
934
1001
  @hash.incr('counter')
@@ -1036,7 +1103,9 @@ describe Redis::Set do
1036
1103
 
1037
1104
  it "should handle sets of simple values" do
1038
1105
  @set.should.be.empty
1039
- @set << 'a' << 'a' << 'a'
1106
+ @set << 'a'
1107
+ @set.randmember.should == 'a'
1108
+ @set << 'a' << 'a'
1040
1109
  @set.should == ['a']
1041
1110
  @set.to_s.should == 'a'
1042
1111
  @set.get.should == ['a']
@@ -1077,11 +1146,13 @@ describe Redis::Set do
1077
1146
  coll = @set.select{|st| st == 'c'}
1078
1147
  coll.should == ['c']
1079
1148
  @set.sort.should == ['a','b','c']
1149
+ @set.randmember.should.not == 'd'
1080
1150
  @set.delete_if{|m| m == 'c'}
1081
1151
  @set.sort.should == ['a','b']
1082
1152
 
1083
1153
  @set << nil
1084
1154
  @set.include?("").should.be.true
1155
+ @set.sort.should == ['','a','b']
1085
1156
  end
1086
1157
 
1087
1158
  it "should handle empty array adds" do
@@ -1197,6 +1268,12 @@ describe Redis::Set do
1197
1268
  @set_1.value.should == ['a']
1198
1269
  end
1199
1270
 
1271
+ it "should support moving between sets" do
1272
+ @set_1 << 'X' << 'Y' << 'Z'
1273
+ @set_1.move('X', @set_2)
1274
+ @set_2.should == ['X']
1275
+ end
1276
+
1200
1277
  it "should respond to #to_json" do
1201
1278
  @set_1 << 'a'
1202
1279
  JSON.parse(@set_1.to_json)['value'].should == ['a']
@@ -1296,6 +1373,9 @@ describe Redis::SortedSet do
1296
1373
  @set.to_s.should == 'a, b'
1297
1374
  @set.should == ['a','b']
1298
1375
  @set.members.should == ['a','b']
1376
+ @set.member?('a').should == true
1377
+ @set.member?('b').should == true
1378
+ @set.member?('c').should == false
1299
1379
  @set['d'] = 0
1300
1380
 
1301
1381
  @set.rangebyscore(0, 4).should == ['d','a']
@@ -1345,6 +1425,10 @@ describe Redis::SortedSet do
1345
1425
 
1346
1426
  @set.delete_if{|m| m == 'b'}
1347
1427
  @set.size.should == 3
1428
+
1429
+ # this is destructive so must come last
1430
+ res = @set.remrangebyrank(0, 2)
1431
+ res.should == 3
1348
1432
  end
1349
1433
 
1350
1434
  it "should handle inserting multiple values at once" do
@@ -2,6 +2,7 @@
2
2
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
3
3
 
4
4
  require 'redis/objects'
5
+ Redis::Objects.redis = REDIS_HANDLE
5
6
 
6
7
  class Roster
7
8
  include Redis::Objects
@@ -14,11 +15,15 @@ class Roster
14
15
  list :player_stats, :marshal => true
15
16
  set :outfielders, :marshal => true
16
17
  sorted_set :rank
18
+ lock :per_field
17
19
 
18
20
  # global class counters
19
21
  counter :total_players_online, :global => true
20
22
  set :all_players_online, :global => true
21
23
  value :last_player, :global => true
24
+ lock :nasty_global_mutex, :global => true # remember it appends "_lock"
25
+ sorted_set :global_player_leaderboard, :global => true
26
+ hash_key :global_player_online_status, :global => true
22
27
 
23
28
  # custom keys
24
29
  counter :player_totals, :key => 'players/#{username}/total'
@@ -210,6 +215,21 @@ describe Redis::Objects do
210
215
  end
211
216
  end
212
217
 
218
+ it "should handle obtaining / clearing locks" do
219
+ # class-level calls for Admin reasons
220
+ # this is a really weird API and I wonder if anyone actually uses it
221
+ id = 88
222
+ roster = Roster.new(id)
223
+ roster.per_field_lock.exists?.should == false
224
+ Roster.obtain_lock(:per_field, id) do
225
+ roster.per_field_lock.exists?.should == true
226
+ end
227
+ roster.per_field_lock.exists?.should == false
228
+
229
+ Roster.clear_lock(:per_field, id)
230
+ roster.per_field_lock.exists?.should == false
231
+ end
232
+
213
233
  it "should support increment/decrement of counters" do
214
234
  @roster.available_slots.key.should == 'roster:1:available_slots'
215
235
  @roster.available_slots.should == 10
@@ -273,6 +293,26 @@ describe Redis::Objects do
273
293
  Roster.get_counter(:total_players_online).should == 111
274
294
  end
275
295
 
296
+ it "should support class-level manipulation of global objects" do
297
+ Roster.nasty_global_mutex_lock.exists?.should == false
298
+ Roster.nasty_global_mutex_lock do
299
+ Roster.nasty_global_mutex_lock.exists?.should == true
300
+ end
301
+ Roster.nasty_global_mutex_lock.exists?.should == false
302
+
303
+ Roster.global_player_leaderboard.exists?.should == false
304
+ Roster.global_player_leaderboard.add('nate', 22)
305
+ Roster.global_player_leaderboard.add('jim', 11)
306
+ Roster.global_player_leaderboard.rank('nate').should == 1 # 0-based
307
+
308
+ Roster.global_player_online_status.exists?.should == false
309
+ Roster.global_player_online_status['nate'] = 'online'
310
+ Roster.global_player_online_status['jeff'] = 'offline'
311
+ Roster.global_player_online_status['nate'].should == 'online'
312
+ Roster.global_player_online_status['jeff'].should == 'offline'
313
+ Roster.global_player_online_status['bobby'].should.be.nil
314
+ end
315
+
276
316
  it "should take an atomic block for increment/decrement" do
277
317
  a = false
278
318
  @roster.available_slots.should == 10
@@ -431,6 +471,13 @@ describe Redis::Objects do
431
471
  end
432
472
  error.should.be.kind_of(NoMethodError)
433
473
 
474
+ error = nil
475
+ begin
476
+ Roster.increment_counter(:available_slots, nil)
477
+ rescue => error
478
+ end
479
+ error.should.be.kind_of(Redis::Objects::MissingID)
480
+
434
481
  error = nil
435
482
  begin
436
483
  Roster.obtain_lock(:badness, 2){}
@@ -1042,4 +1089,10 @@ describe Redis::Objects do
1042
1089
  @roster.redis_instance_keys.include?('roster:1:player_stats').should == true
1043
1090
  @roster.redis_instance_keys.include?('players:all_stats').should == false
1044
1091
  end
1092
+
1093
+ it "should handle per-class connection handles" do
1094
+ redis = Roster.redis
1095
+ Roster.redis = redis
1096
+ Roster.redis.should == redis
1097
+ end
1045
1098
  end
data/spec/spec_helper.rb CHANGED
@@ -9,6 +9,21 @@ if $0 =~ /\brspec$/
9
9
  raise "\n===\nThese tests are in bacon, not rspec. Try: bacon #{ARGV * ' '}\n===\n"
10
10
  end
11
11
 
12
+ # For the incompatible change from redis.rb
13
+ Redis.exists_returns_integer = true
14
+
15
+ # Avoid phantom remote test failures
16
+ RUNNING_LOCALLY = !ENV['TRAVIS']
17
+
18
+ # Code coverage reports
19
+ require 'simplecov'
20
+ SimpleCov.start
21
+
22
+ require 'simplecov-cobertura'
23
+ SimpleCov.formatter = SimpleCov::Formatter::CoberturaFormatter
24
+
25
+ #require "active_support/xml_mini"
26
+ require "active_support"
12
27
  require "active_support/testing/time_helpers"
13
28
  include ActiveSupport::Testing::TimeHelpers
14
29
 
@@ -69,8 +84,6 @@ end
69
84
 
70
85
  # Grab a global handle
71
86
  REDIS_HANDLE = Redis.new(:host => REDIS_HOST, :port => REDIS_PORT)
72
- #$redis = REDIS_HANDLE
73
- Redis.current = REDIS_HANDLE
74
87
 
75
88
  SORT_ORDER = {:order => 'desc alpha'}
76
89
  SORT_LIMIT = {:limit => [2, 2]}
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis-objects
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.1
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nate Wiger
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-10 00:00:00.000000000 Z
11
+ date: 2022-04-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - "<"
18
18
  - !ruby/object:Gem::Version
19
- version: '4.2'
19
+ version: '4.6'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - "<"
25
25
  - !ruby/object:Gem::Version
26
- version: '4.2'
26
+ version: '4.6'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: activesupport
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: activerecord
99
113
  requirement: !ruby/object:Gem::Requirement
@@ -122,6 +136,20 @@ dependencies:
122
136
  - - ">="
123
137
  - !ruby/object:Gem::Version
124
138
  version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: simplecov-cobertura
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
125
153
  description: Map Redis types directly to Ruby objects. Works with any class or ORM.
126
154
  email:
127
155
  - nwiger@gmail.com
@@ -171,7 +199,7 @@ homepage: http://github.com/nateware/redis-objects
171
199
  licenses:
172
200
  - Artistic-2.0
173
201
  metadata: {}
174
- post_install_message:
202
+ post_install_message:
175
203
  rdoc_options: []
176
204
  require_paths:
177
205
  - lib
@@ -186,8 +214,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
186
214
  - !ruby/object:Gem::Version
187
215
  version: '0'
188
216
  requirements: []
189
- rubygems_version: 3.2.15
190
- signing_key:
217
+ rubygems_version: 3.0.3.1
218
+ signing_key:
191
219
  specification_version: 4
192
220
  summary: Map Redis types directly to Ruby objects
193
221
  test_files: