leaderboard 1.0.5 → 2.0.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/.rvmrc CHANGED
@@ -1 +1,2 @@
1
- rvm 1.8.7
1
+ rvm --create 1.8.7@leaderboard_gem
2
+ rvm --create 1.9.2@leaderboard_gem
@@ -1,3 +1,17 @@
1
+ # leaderboard 2.0.0 (2011-08-05)
2
+
3
+ * Change `add_member` to `rank_member` - https://github.com/agoragames/leaderboard/issues/3
4
+ * Added `delete_leaderboard` and `delete_leaderboard_named` - https://github.com/agoragames/leaderboard/issues/2
5
+ * Ability to pass in an existing Redis connection in initializer - https://github.com/agoragames/leaderboard/issues/1
6
+ * Added transaction support for `score_and_rank_for`, `leaders`, `around_me` and `ranked_in_list`
7
+ * Updated initializer to take a leaderboard name, `options` hash and `redis_options` hash
8
+ * Simplified `leaders`, `around_me` and `ranked_in_list` to use an `options` hash with defaults for the previously individual parameters
9
+
10
+ # leaderboard 1.0.6 (unreleased)
11
+
12
+ * Added `disconnect` method
13
+ * Check for invalid page size when changing
14
+
1
15
  # leaderboard 1.0.5 (2011-05-04)
2
16
 
3
17
  * Updated Rakefile to run tests under ruby 1.8.7 and ruby 1.9.2
data/Gemfile CHANGED
@@ -8,5 +8,5 @@ group :development do
8
8
  gem "rcov", ">= 0"
9
9
  end
10
10
 
11
- gem 'redis', "~> 2.1.1"
11
+ gem 'redis', "~> 2.2.0"
12
12
 
@@ -8,7 +8,7 @@ Builds off ideas proposed in http://blog.agoragames.com/2011/01/01/creating-high
8
8
 
9
9
  Install the gem:
10
10
 
11
- gem install leaderboard
11
+ gem "leaderboard", "~> 2.0.0"
12
12
 
13
13
  Make sure your redis server is running! Redis configuration is outside the scope of this README, but
14
14
  check out the Redis documentation, http://redis.io/documentation.
@@ -21,138 +21,163 @@ The gem has been built and tested under Ruby 1.8.7 and Ruby 1.9.2
21
21
 
22
22
  Create a new leaderboard or attach to an existing leaderboard named 'highscores':
23
23
 
24
- ruby-1.8.7-p302 > highscore_lb = Leaderboard.new('highscores')
25
- => #<Leaderboard:0x1018e4250 @page_size=25, @port=6379, @host="localhost", @redis_connection=#<Redis client v2.1.1 connected to redis://localhost:6379/0 (Redis v2.1.10)>, @leaderboard_name="highscores">
26
-
27
- If you need to pass in options for Redis, you can do this with the redis_options parameter:
24
+ ruby-1.9.2-p180 :002 > highscore_lb = Leaderboard.new('highscores')
25
+ => #<Leaderboard:0x0000010307b530 @leaderboard_name="highscores", @page_size=25, @redis_connection=#<Redis client v2.2.2 connected to redis://localhost:6379/0 (Redis v2.2.5)>>
26
+
27
+ If you need to pass in options for Redis, you can do this in the initializer:
28
+
29
+ ruby-1.9.2-p180 :007 > redis_options = {:host => 'localhost', :port => 6379, :db => 1}
30
+ => {:host=>"localhost", :port=>6379, :db=>1}
31
+ ruby-1.9.2-p180 :008 > highscore_lb = Leaderboard.new('highscores', Leaderboard::DEFAULT_OPTIONS, redis_options)
32
+ => #<Leaderboard:0x00000103095200 @leaderboard_name="highscores", @page_size=25, @redis_connection=#<Redis client v2.2.2 connected to redis://localhost:6379/1 (Redis v2.2.5)>>
28
33
 
29
- redis_options = {:host => 'localhost', :port => 6379, :password => 'password', :db => 'some_redis_db'}
30
- highscore_lb = Leaderboard.new('highscores', redis_options[:host], redis_options[:port], Leaderboard::DEFAULT_PAGE_SIZE, redis_options))
34
+ You can pass in an existing connection to Redis using :redis_connection in the Redis options hash:
31
35
 
36
+ ruby-1.9.2-p180 :009 > redis = Redis.new
37
+ => #<Redis client v2.2.2 connected to redis://127.0.0.1:6379/0 (Redis v2.2.5)>
38
+ ruby-1.9.2-p180 :010 > redis_options = {:redis_connection => redis}
39
+ => {:redis_connection=>#<Redis client v2.2.2 connected to redis://127.0.0.1:6379/0 (Redis v2.2.5)>}
40
+ ruby-1.9.2-p180 :011 > highscore_lb = Leaderboard.new('highscores', Leaderboard::DEFAULT_OPTIONS, redis_options)
41
+ => #<Leaderboard:0x000001028791e8 @leaderboard_name="highscores", @page_size=25, @redis_connection=#<Redis client v2.2.2 connected to redis://127.0.0.1:6379/0 (Redis v2.2.5)>>
42
+
32
43
  You can set the page size to something other than the default page size (25):
33
44
 
34
- ruby-1.8.7-p302 > highscore_lb.page_size = 5
45
+ ruby-1.9.2-p180 :012 > highscore_lb.page_size = 5
35
46
  => 5
36
- ruby-1.8.7-p302 > highscore_lb
37
- => #<Leaderboard:0x1018e2130 @leaderboard_name="highscores", @page_size=5, @port=6379, @redis_connection=#<Redis client v2.1.1 connected to redis://localhost:6379/0 (Redis v2.1.10)>, @host="localhost", @redis_options={:host=>"localhost", :port=>6379}>
47
+ ruby-1.9.2-p180 :013 > highscore_lb
48
+ => #<Leaderboard:0x000001028791e8 @leaderboard_name="highscores", @page_size=5, @redis_connection=#<Redis client v2.2.2 connected to redis://127.0.0.1:6379/0 (Redis v2.2.5)>>
38
49
 
39
- Add members to your leaderboard:
50
+ Add members to your leaderboard using rank_member:
40
51
 
41
- ruby-1.8.7-p302 > 1.upto(10) do |index|
42
- ruby-1.8.7-p302 > highscore_lb.add_member("member_#{index}", index)
43
- ruby-1.8.7-p302 ?> end
52
+ ruby-1.9.2-p180 :014 > 1.upto(10) do |index|
53
+ ruby-1.9.2-p180 :015 > highscore_lb.rank_member("member_#{index}", index)
54
+ ruby-1.9.2-p180 :016?> end
44
55
  => 1
45
-
56
+
57
+ You can call rank_member with the same member and the leaderboard will be updated automatically.
58
+
46
59
  Get some information about your leaderboard:
47
60
 
48
- ruby-1.8.7-p302 > highscore_lb.total_members
61
+ ruby-1.9.2-p180 :020 > highscore_lb.total_members
49
62
  => 10
50
- ruby-1.8.7-p302 > highscore_lb.total_pages
63
+ ruby-1.9.2-p180 :021 > highscore_lb.total_pages
51
64
  => 1
52
65
 
53
66
  Get some information about a specific member(s) in the leaderboard:
54
67
 
55
- ruby-1.8.7-p302 > highscore_lb.score_for('member_4')
68
+ ruby-1.9.2-p180 :022 > highscore_lb.score_for('member_4')
56
69
  => 4.0
57
- ruby-1.8.7-p302 > highscore_lb.rank_for('member_4')
70
+ ruby-1.9.2-p180 :023 > highscore_lb.rank_for('member_4')
58
71
  => 7
59
- ruby-1.8.7-p302 > highscore_lb.rank_for('member_10')
72
+ ruby-1.9.2-p180 :024 > highscore_lb.rank_for('member_10')
60
73
  => 1
61
74
 
62
75
  Get page 1 in the leaderboard:
63
76
 
64
- ruby-1.8.7-p302 > highscore_lb.leaders(1)
65
- => [{:member=>"member_10", :rank=>1, :score=>"10"}, {:member=>"member_9", :rank=>2, :score=>"9"}, {:member=>"member_8", :rank=>3, :score=>"8"}, {:member=>"member_7", :rank=>4, :score=>"7"}, {:member=>"member_6", :rank=>5, :score=>"6"}, {:member=>"member_5", :rank=>6, :score=>"5"}, {:member=>"member_4", :rank=>7, :score=>"4"}, {:member=>"member_3", :rank=>8, :score=>"3"}, {:member=>"member_2", :rank=>9, :score=>"2"}, {:member=>"member_1", :rank=>10, :score=>"1"}]
77
+ ruby-1.9.2-p180 :025 > highscore_lb.leaders(1)
78
+ => [{:member=>"member_10", :rank=>1, :score=>10.0}, {:member=>"member_9", :rank=>2, :score=>9.0}, {:member=>"member_8", :rank=>3, :score=>8.0}, {:member=>"member_7", :rank=>4, :score=>7.0}, {:member=>"member_6", :rank=>5, :score=>6.0}, {:member=>"member_5", :rank=>6, :score=>5.0}, {:member=>"member_4", :rank=>7, :score=>4.0}, {:member=>"member_3", :rank=>8, :score=>3.0}, {:member=>"member_2", :rank=>9, :score=>2.0}, {:member=>"member_1", :rank=>10, :score=>1.0}]
66
79
 
80
+ You can pass various options to the calls `leaders`, `around_me` and `ranked_in_list`. Valid options are :with_scores, :with_rank, :use_zero_index_for_rank and :page_size.
81
+ Below is an example of retrieving the first page in the leaderboard without ranks:
82
+
83
+ ruby-1.9.2-p180 :026 > highscore_lb.leaders(1, :with_scores => true, :with_rank => false, :use_zero_index_for_rank => false)
84
+ => [{:member=>"member_10", :score=>9.0}, {:member=>"member_9", :score=>7.0}, {:member=>"member_8", :score=>5.0}, {:member=>"member_7", :score=>3.0}, {:member=>"member_6", :score=>1.0}, {:member=>"member_5", :score=>0.0}, {:member=>"member_4", :score=>0.0}, {:member=>"member_3", :score=>0.0}, {:member=>"member_2", :score=>0.0}, {:member=>"member_1", :score=>0.0}]
85
+
86
+ Below is an example of retrieving the first page in the leaderboard without scores or ranks:
87
+
88
+ ruby-1.9.2-p180 :028 > highscore_lb.leaders(1, :with_scores => false, :with_rank => false)
89
+ => [{:member=>"member_10"}, {:member=>"member_9"}, {:member=>"member_8"}, {:member=>"member_7"}, {:member=>"member_6"}, {:member=>"member_5"}, {:member=>"member_4"}, {:member=>"member_3"}, {:member=>"member_2"}, {:member=>"member_1"}]
90
+
67
91
  Add more members to your leaderboard:
68
92
 
69
- ruby-1.8.7-p302 > 50.upto(95) do |index|
70
- ruby-1.8.7-p302 > highscore_lb.add_member("member_#{index}", index)
71
- ruby-1.8.7-p302 ?> end
93
+ ruby-1.9.2-p180 :029 > 50.upto(95) do |index|
94
+ ruby-1.9.2-p180 :030 > highscore_lb.rank_member("member_#{index}", index)
95
+ ruby-1.9.2-p180 :031?> end
72
96
  => 50
73
- ruby-1.8.7-p302 > highscore_lb.total_pages
97
+ ruby-1.9.2-p180 :032 > highscore_lb.total_pages
74
98
  => 3
75
99
 
76
100
  Get an "Around Me" leaderboard for a member:
77
101
 
78
- ruby-1.8.7-p302 > highscore_lb.around_me('member_53')
79
- => [{:member=>"member_65", :rank=>31, :score=>"65"}, {:member=>"member_64", :rank=>32, :score=>"64"}, {:member=>"member_63", :rank=>33, :score=>"63"}, {:member=>"member_62", :rank=>34, :score=>"62"}, {:member=>"member_61", :rank=>35, :score=>"61"}, {:member=>"member_60", :rank=>36, :score=>"60"}, {:member=>"member_59", :rank=>37, :score=>"59"}, {:member=>"member_58", :rank=>38, :score=>"58"}, {:member=>"member_57", :rank=>39, :score=>"57"}, {:member=>"member_56", :rank=>40, :score=>"56"}, {:member=>"member_55", :rank=>41, :score=>"55"}, {:member=>"member_54", :rank=>42, :score=>"54"}, {:member=>"member_53", :rank=>43, :score=>"53"}, {:member=>"member_52", :rank=>44, :score=>"52"}, {:member=>"member_51", :rank=>45, :score=>"51"}, {:member=>"member_50", :rank=>46, :score=>"50"}, {:member=>"member_10", :rank=>47, :score=>"10"}, {:member=>"member_9", :rank=>48, :score=>"9"}, {:member=>"member_8", :rank=>49, :score=>"8"}, {:member=>"member_7", :rank=>50, :score=>"7"}, {:member=>"member_6", :rank=>51, :score=>"6"}, {:member=>"member_5", :rank=>52, :score=>"5"}, {:member=>"member_4", :rank=>53, :score=>"4"}, {:member=>"member_3", :rank=>54, :score=>"3"}, {:member=>"member_2", :rank=>55, :score=>"2"}]
102
+ ruby-1.9.2-p180 :033 > highscore_lb.around_me('member_53')
103
+ => [{:member=>"member_65", :rank=>31, :score=>65.0}, {:member=>"member_64", :rank=>32, :score=>64.0}, {:member=>"member_63", :rank=>33, :score=>63.0}, {:member=>"member_62", :rank=>34, :score=>62.0}, {:member=>"member_61", :rank=>35, :score=>61.0}, {:member=>"member_60", :rank=>36, :score=>60.0}, {:member=>"member_59", :rank=>37, :score=>59.0}, {:member=>"member_58", :rank=>38, :score=>58.0}, {:member=>"member_57", :rank=>39, :score=>57.0}, {:member=>"member_56", :rank=>40, :score=>56.0}, {:member=>"member_55", :rank=>41, :score=>55.0}, {:member=>"member_54", :rank=>42, :score=>54.0}, {:member=>"member_53", :rank=>43, :score=>53.0}, {:member=>"member_52", :rank=>44, :score=>52.0}, {:member=>"member_51", :rank=>45, :score=>51.0}, {:member=>"member_50", :rank=>46, :score=>50.0}, {:member=>"member_10", :rank=>47, :score=>10.0}, {:member=>"member_9", :rank=>48, :score=>9.0}, {:member=>"member_8", :rank=>49, :score=>8.0}, {:member=>"member_7", :rank=>50, :score=>7.0}, {:member=>"member_6", :rank=>51, :score=>6.0}, {:member=>"member_5", :rank=>52, :score=>5.0}, {:member=>"member_4", :rank=>53, :score=>4.0}, {:member=>"member_3", :rank=>54, :score=>3.0}, {:member=>"member_2", :rank=>55, :score=>2.0}]
80
104
 
81
105
  Get rank and score for an arbitrary list of members (e.g. friends):
82
106
 
83
- ruby-1.8.7-p302 > highscore_lb.ranked_in_list(['member_1', 'member_62', 'member_67'], true)
84
- => [{:rank=>55, :member=>"member_1", :score=>1.0}, {:rank=>33, :member=>"member_62", :score=>62.0}, {:rank=>28, :member=>"member_67", :score=>67.0}]
85
-
107
+ ruby-1.9.2-p180 :034 > highscore_lb.ranked_in_list(['member_1', 'member_62', 'member_67'])
108
+ => [{:member=>"member_1", :rank=>56, :score=>1.0}, {:member=>"member_62", :rank=>34, :score=>62.0}, {:member=>"member_67", :rank=>29, :score=>67.0}]
109
+
86
110
  === Other useful methods
87
111
 
88
- remove_member(member): Remove a member from the leaderboard
89
- total_members_in_score_range(min_score, max_score): Count the number of members within a score range in the leaderboard
90
- change_score_for(member, delta): Change the score for a member by some amount delta (delta could be positive or negative)
91
- check_member?(member): Check to see whether member is in the leaderboard
92
- score_and_rank_for(member, use_zero_index_for_rank = false): Retrieve the score and rank for a member in a single call
93
- remove_members_in_score_range(min_score, max_score): Remove members from the leaderboard within a score range
94
- merge_leaderboards(destination, keys, options = {:aggregate => :min}): Merge leaderboards given by keys with this leaderboard into destination
95
- intersect_leaderboards(destination, keys, options = {:aggregate => :min}): Intersect leaderboards given by keys with this leaderboard into destination
112
+ delete_leaderboard: Delete the current leaderboard
113
+ remove_member(member): Remove a member from the leaderboard
114
+ total_members: Total # of members in the leaderboard
115
+ total_pages: Total # of pages in the leaderboard given the leaderboard's page_size
116
+ total_members_in_score_range(min_score, max_score): Count the number of members within a score range in the leaderboard
117
+ change_score_for(member, delta): Change the score for a member by some amount delta (delta could be positive or negative)
118
+ rank_for(member): Retrieve the rank for a given member in the leaderboard
119
+ score_for(member): Retrieve the score for a given member in the leaderboard
120
+ check_member?(member): Check to see whether member is in the leaderboard
121
+ score_and_rank_for(member): Retrieve the score and rank for a member in a single call
122
+ remove_members_in_score_range(min_score, max_score): Remove members from the leaderboard within a score range
123
+ merge_leaderboards(destination, keys, options = {:aggregate => :min}): Merge leaderboards given by keys with this leaderboard into destination
124
+ intersect_leaderboards(destination, keys, options = {:aggregate => :min}): Intersect leaderboards given by keys with this leaderboard into destination
125
+
126
+ Check the online documentation for more detail, http://rubydoc.info/gems/leaderboard/
96
127
 
97
128
  == Performance Metrics
98
129
 
99
130
  10 million sequential scores insert:
100
131
 
101
- ruby-1.8.7-p302 > insert_time = Benchmark.measure do
102
- ruby-1.8.7-p302 > 1.upto(10000000) do |index|
103
- ruby-1.8.7-p302 > highscore_lb.add_member("member_#{index}", index)
104
- ruby-1.8.7-p302 ?> end
105
- ruby-1.8.7-p302 ?> end
106
- => #<Benchmark::Tms:0x101605660 @label="", @stime=173.61, @total=577.52, @real=911.718175172806, @utime=403.91, @cstime=0.0, @cutime=0.0>
132
+ ruby-1.9.2-p180 :003 > highscore_lb = Leaderboard.new('highscores')
133
+ => #<Leaderboard:0x0000010205fc50 @leaderboard_name="highscores", @page_size=25, @redis_connection=#<Redis client v2.2.2 connected to redis://localhost:6379/0 (Redis v2.2.5)>>
134
+ ruby-1.9.2-p180 :004 > insert_time = Benchmark.measure do
135
+ ruby-1.9.2-p180 :005 > 1.upto(10000000) do |index|
136
+ ruby-1.9.2-p180 :006 > highscore_lb.rank_member("member_#{index}", index)
137
+ ruby-1.9.2-p180 :007?> end
138
+ ruby-1.9.2-p180 :008?> end
139
+ => 323.070000 148.560000 471.630000 (942.068307)
107
140
 
108
141
  Average time to request an arbitrary page from the leaderboard:
109
142
 
110
- ruby-1.8.7-p302 > requests_to_make = 50000
143
+ ruby-1.9.2-p180 :009 > requests_to_make = 50000
111
144
  => 50000
112
- ruby-1.8.7-p302 > lb_request_time = 0
145
+ ruby-1.9.2-p180 :010 > lb_request_time = 0
113
146
  => 0
114
- ruby-1.8.7-p302 > 1.upto(requests_to_make) do
115
- ruby-1.8.7-p302 > lb_request_time += Benchmark.measure do
116
- ruby-1.8.7-p302 > highscore_lb.leaders(rand(highscore_lb.total_pages))
117
- ruby-1.8.7-p302 ?> end.total
118
- ruby-1.8.7-p302 ?> end
147
+ ruby-1.9.2-p180 :011 > 1.upto(requests_to_make) do
148
+ ruby-1.9.2-p180 :012 > lb_request_time += Benchmark.measure do
149
+ ruby-1.9.2-p180 :013 > highscore_lb.leaders(rand(highscore_lb.total_pages))
150
+ ruby-1.9.2-p180 :014?> end.total
151
+ ruby-1.9.2-p180 :015?> end
119
152
  => 1
120
- ruby-1.8.7-p302 >
121
- ruby-1.8.7-p302 > p lb_request_time / requests_to_make
122
- 0.001808
123
- => nil
124
-
153
+ ruby-1.9.2-p180 :016 > p lb_request_time / requests_to_make
154
+ 0.001513999999999998
155
+ => 0.001513999999999998
156
+
125
157
  10 million random scores insert:
126
158
 
127
- ruby-1.8.7-p302 > insert_time = Benchmark.measure do
128
- ruby-1.8.7-p302 > 1.upto(10000000) do |index|
129
- ruby-1.8.7-p302 > highscore_lb.add_member("member_#{index}", rand(50000000))
130
- ruby-1.8.7-p302 ?> end
131
- ruby-1.8.7-p302 ?> end
132
- => #<Benchmark::Tms:0x10164ebf8 @label="", @stime=172.94, @total=577.91, @real=1356.57155895233, @utime=404.97, @cstime=0.0, @cutime=0.0>
159
+ ruby-1.9.2-p180 :018 > insert_time = Benchmark.measure do
160
+ ruby-1.9.2-p180 :019 > 1.upto(10000000) do |index|
161
+ ruby-1.9.2-p180 :020 > highscore_lb.rank_member("member_#{index}", rand(50000000))
162
+ ruby-1.9.2-p180 :021?> end
163
+ ruby-1.9.2-p180 :022?> end
164
+ => 338.480000 155.200000 493.680000 (2188.702475)
133
165
 
134
166
  Average time to request an arbitrary page from the leaderboard:
135
167
 
136
- ruby-1.8.7-p302 > requests_to_make = 50000
137
- => 50000
138
- ruby-1.8.7-p302 > lb_request_time = 0
139
- => 0
140
- ruby-1.8.7-p302 > 1.upto(requests_to_make) do
141
- ruby-1.8.7-p302 > lb_request_time += Benchmark.measure do
142
- ruby-1.8.7-p302 > highscore_lb.leaders(rand(highscore_lb.total_pages))
143
- ruby-1.8.7-p302 ?> end.total
144
- ruby-1.8.7-p302 ?> end
168
+ ruby-1.9.2-p180 :007 > 1.upto(requests_to_make) do
169
+ ruby-1.9.2-p180 :008 > lb_request_time += Benchmark.measure do
170
+ ruby-1.9.2-p180 :009 > highscore_lb.leaders(rand(highscore_lb.total_pages))
171
+ ruby-1.9.2-p180 :010?> end.total
172
+ ruby-1.9.2-p180 :011?> end
145
173
  => 1
146
- ruby-1.8.7-p302 >
147
- ruby-1.8.7-p302 > p lb_request_time / requests_to_make
148
- 0.00179680000000001
149
- => nil
174
+ ruby-1.9.2-p180 :012 > p lb_request_time / requests_to_make
175
+ 0.0014615999999999531
176
+ => 0.0014615999999999531
150
177
 
151
178
  == Future Ideas
152
179
 
153
180
  * Bulk insert
154
- * Atomicity for various operations?
155
- * Is nil? OK to return if Redis returns no data or should it be []?
156
181
 
157
182
  == Contributing to leaderboard
158
183
 
data/Rakefile CHANGED
@@ -89,5 +89,5 @@ task :stop do
89
89
  end
90
90
 
91
91
  task :test_rubies do
92
- system "rvm 1.8.7,1.9.2 rake test"
93
- end
92
+ system "rvm 1.8.7@leaderboard_gem,1.9.2@leaderboard_gem rake test"
93
+ end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.5
1
+ 2.0.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{leaderboard}
8
- s.version = "1.0.5"
8
+ s.version = "2.0.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["David Czarnecki"]
12
- s.date = %q{2011-05-04}
11
+ s.authors = [%q{David Czarnecki}]
12
+ s.date = %q{2011-08-17}
13
13
  s.description = %q{Leaderboards backed by Redis in Ruby}
14
14
  s.email = %q{dczarnecki@agoragames.com}
15
15
  s.extra_rdoc_files = [
@@ -33,9 +33,9 @@ Gem::Specification.new do |s|
33
33
  "test/test_leaderboard.rb"
34
34
  ]
35
35
  s.homepage = %q{http://github.com/agoragames/leaderboard}
36
- s.licenses = ["MIT"]
37
- s.require_paths = ["lib"]
38
- s.rubygems_version = %q{1.3.7}
36
+ s.licenses = [%q{MIT}]
37
+ s.require_paths = [%q{lib}]
38
+ s.rubygems_version = %q{1.8.6}
39
39
  s.summary = %q{Leaderboards backed by Redis in Ruby}
40
40
  s.test_files = [
41
41
  "test/helper.rb",
@@ -43,22 +43,21 @@ Gem::Specification.new do |s|
43
43
  ]
44
44
 
45
45
  if s.respond_to? :specification_version then
46
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
47
46
  s.specification_version = 3
48
47
 
49
48
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
50
- s.add_runtime_dependency(%q<redis>, ["~> 2.1.1"])
49
+ s.add_runtime_dependency(%q<redis>, ["~> 2.2.0"])
51
50
  s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
52
51
  s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
53
52
  s.add_development_dependency(%q<rcov>, [">= 0"])
54
53
  else
55
- s.add_dependency(%q<redis>, ["~> 2.1.1"])
54
+ s.add_dependency(%q<redis>, ["~> 2.2.0"])
56
55
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
57
56
  s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
58
57
  s.add_dependency(%q<rcov>, [">= 0"])
59
58
  end
60
59
  else
61
- s.add_dependency(%q<redis>, ["~> 2.1.1"])
60
+ s.add_dependency(%q<redis>, ["~> 2.2.0"])
62
61
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
63
62
  s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
64
63
  s.add_dependency(%q<rcov>, [">= 0"])
@@ -1,42 +1,69 @@
1
1
  require 'redis'
2
2
 
3
3
  class Leaderboard
4
- VERSION = '1.0.5'.freeze
4
+ VERSION = '2.0.0'.freeze
5
5
 
6
6
  DEFAULT_PAGE_SIZE = 25
7
+ DEFAULT_OPTIONS = {
8
+ :page_size => DEFAULT_PAGE_SIZE
9
+ }
10
+
7
11
  DEFAULT_REDIS_HOST = 'localhost'
8
- DEFAULT_REDIS_PORT = 6379
12
+ DEFAULT_REDIS_PORT = 6379
13
+ DEFAULT_REDIS_OPTIONS = {
14
+ :host => DEFAULT_REDIS_HOST,
15
+ :port => DEFAULT_REDIS_PORT
16
+ }
17
+
18
+ DEFAULT_LEADERBOARD_REQUEST_OPTIONS = {
19
+ :with_scores => true,
20
+ :with_rank => true,
21
+ :use_zero_index_for_rank => false,
22
+ :page_size => nil
23
+ }
9
24
 
10
- attr_reader :host
11
- attr_reader :port
12
25
  attr_reader :leaderboard_name
13
26
  attr_accessor :page_size
14
27
 
15
- def initialize(leaderboard_name, host = DEFAULT_REDIS_HOST, port = DEFAULT_REDIS_PORT, page_size = DEFAULT_PAGE_SIZE, redis_options = {})
28
+ def initialize(leaderboard_name, options = DEFAULT_OPTIONS, redis_options = DEFAULT_REDIS_OPTIONS)
16
29
  @leaderboard_name = leaderboard_name
17
- @host = host
18
- @port = port
19
30
 
20
- if page_size < 1
21
- page_size = DEFAULT_PAGE_SIZE
31
+ @page_size = options[:page_size]
32
+ if @page_size < 1
33
+ @page_size = DEFAULT_PAGE_SIZE
22
34
  end
23
35
 
36
+ @redis_connection = redis_options[:redis_connection]
37
+ unless @redis_connection.nil?
38
+ redis_options.delete(:redis_connection)
39
+ end
40
+
41
+ @redis_connection = Redis.new(redis_options) if @redis_connection.nil?
42
+ end
43
+
44
+ def page_size=(page_size)
45
+ page_size = DEFAULT_PAGE_SIZE if page_size < 1
46
+
24
47
  @page_size = page_size
25
-
26
- redis_options = redis_options.dup
27
- redis_options[:host] ||= @host
28
- redis_options[:port] ||= @port
29
-
30
- @redis_options = redis_options
31
-
32
- @redis_connection = Redis.new(@redis_options)
48
+ end
49
+
50
+ def disconnect
51
+ @redis_connection.client.disconnect
52
+ end
53
+
54
+ def delete_leaderboard
55
+ delete_leaderboard_named(@leaderboard_name)
56
+ end
57
+
58
+ def delete_leaderboard_named(leaderboard_name)
59
+ @redis_connection.del(leaderboard_name)
33
60
  end
34
61
 
35
- def add_member(member, score)
36
- add_member_to(@leaderboard_name, member, score)
62
+ def rank_member(member, score)
63
+ rank_member_in(@leaderboard_name, member, score)
37
64
  end
38
65
 
39
- def add_member_to(leaderboard_name, member, score)
66
+ def rank_member_in(leaderboard_name, member, score)
40
67
  @redis_connection.zadd(leaderboard_name, score, member)
41
68
  end
42
69
 
@@ -114,7 +141,17 @@ class Leaderboard
114
141
  end
115
142
 
116
143
  def score_and_rank_for_in(leaderboard_name, member, use_zero_index_for_rank = false)
117
- {:member => member, :score => score_for_in(leaderboard_name, member), :rank => rank_for_in(leaderboard_name, member, use_zero_index_for_rank)}
144
+ responses = @redis_connection.multi do |transaction|
145
+ transaction.zscore(leaderboard_name, member)
146
+ transaction.zrevrank(leaderboard_name, member)
147
+ end
148
+
149
+ responses[0] = responses[0].to_f
150
+ if !use_zero_index_for_rank
151
+ responses[1] = responses[1] + 1 rescue nil
152
+ end
153
+
154
+ {:member => member, :score => responses[0], :rank => responses[1]}
118
155
  end
119
156
 
120
157
  def remove_members_in_score_range(min_score, max_score)
@@ -125,17 +162,17 @@ class Leaderboard
125
162
  @redis_connection.zremrangebyscore(leaderboard_name, min_score, max_score)
126
163
  end
127
164
 
128
- def leaders(current_page, with_scores = true, with_rank = true, use_zero_index_for_rank = false, page_size = nil)
129
- leaders_in(@leaderboard_name, current_page, with_scores, with_rank, use_zero_index_for_rank, page_size)
165
+ def leaders(current_page, options = DEFAULT_LEADERBOARD_REQUEST_OPTIONS)
166
+ leaders_in(@leaderboard_name, current_page, options)
130
167
  end
131
168
 
132
- def leaders_in(leaderboard_name, current_page, with_scores = true, with_rank = true, use_zero_index_for_rank = false, page_size = nil)
169
+ def leaders_in(leaderboard_name, current_page, options = DEFAULT_LEADERBOARD_REQUEST_OPTIONS)
133
170
  if current_page < 1
134
171
  current_page = 1
135
172
  end
173
+
174
+ page_size = validate_page_size(options[:page_size]) || @page_size
136
175
 
137
- page_size ||= @page_size
138
-
139
176
  if current_page > total_pages_in(leaderboard_name, page_size)
140
177
  current_page = total_pages_in(leaderboard_name, page_size)
141
178
  end
@@ -148,23 +185,23 @@ class Leaderboard
148
185
  end
149
186
 
150
187
  ending_offset = (starting_offset + page_size) - 1
151
-
152
- raw_leader_data = @redis_connection.zrevrange(leaderboard_name, starting_offset, ending_offset, :with_scores => with_scores)
188
+
189
+ raw_leader_data = @redis_connection.zrevrange(leaderboard_name, starting_offset, ending_offset, :with_scores => false)
153
190
  if raw_leader_data
154
- massage_leader_data(leaderboard_name, raw_leader_data, with_scores, with_rank, use_zero_index_for_rank)
191
+ return ranked_in_list_in(leaderboard_name, raw_leader_data, options)
155
192
  else
156
- return nil
193
+ return []
157
194
  end
158
195
  end
159
196
 
160
- def around_me(member, with_scores = true, with_rank = true, use_zero_index_for_rank = false, page_size = nil)
161
- around_me_in(@leaderboard_name, member, with_scores, with_rank, use_zero_index_for_rank, page_size)
197
+ def around_me(member, options = DEFAULT_LEADERBOARD_REQUEST_OPTIONS)
198
+ around_me_in(@leaderboard_name, member, options)
162
199
  end
163
200
 
164
- def around_me_in(leaderboard_name, member, with_scores = true, with_rank = true, use_zero_index_for_rank = false, page_size = nil)
201
+ def around_me_in(leaderboard_name, member, options = DEFAULT_LEADERBOARD_REQUEST_OPTIONS)
165
202
  reverse_rank_for_member = @redis_connection.zrevrank(leaderboard_name, member)
166
203
 
167
- page_size ||= @page_size
204
+ page_size = validate_page_size(options[:page_size]) || @page_size
168
205
 
169
206
  starting_offset = reverse_rank_for_member - (page_size / 2)
170
207
  if starting_offset < 0
@@ -173,26 +210,50 @@ class Leaderboard
173
210
 
174
211
  ending_offset = (starting_offset + page_size) - 1
175
212
 
176
- raw_leader_data = @redis_connection.zrevrange(leaderboard_name, starting_offset, ending_offset, :with_scores => with_scores)
213
+ raw_leader_data = @redis_connection.zrevrange(leaderboard_name, starting_offset, ending_offset, :with_scores => false)
177
214
  if raw_leader_data
178
- massage_leader_data(leaderboard_name, raw_leader_data, with_scores, with_rank, use_zero_index_for_rank)
215
+ return ranked_in_list_in(leaderboard_name, raw_leader_data, options)
179
216
  else
180
- return nil
217
+ return []
181
218
  end
182
219
  end
183
220
 
184
- def ranked_in_list(members, with_scores = true, use_zero_index_for_rank = false)
185
- ranked_in_list_in(@leaderboard_name, members, with_scores, use_zero_index_for_rank)
221
+ def ranked_in_list(members, options = DEFAULT_LEADERBOARD_REQUEST_OPTIONS)
222
+ ranked_in_list_in(@leaderboard_name, members, options)
186
223
  end
187
224
 
188
- def ranked_in_list_in(leaderboard_name, members, with_scores = true, use_zero_index_for_rank = false)
225
+ def ranked_in_list_in(leaderboard_name, members, options = DEFAULT_LEADERBOARD_REQUEST_OPTIONS)
189
226
  ranks_for_members = []
190
227
 
191
- members.each do |member|
228
+ responses = @redis_connection.multi do |transaction|
229
+ members.each do |member|
230
+ transaction.zrevrank(leaderboard_name, member) if options[:with_rank]
231
+ transaction.zscore(leaderboard_name, member) if options[:with_scores]
232
+ end
233
+ end
234
+
235
+ members.each_with_index do |member, index|
192
236
  data = {}
193
237
  data[:member] = member
194
- data[:rank] = rank_for_in(leaderboard_name, member, use_zero_index_for_rank)
195
- data[:score] = score_for_in(leaderboard_name, member) if with_scores
238
+ if options[:with_scores]
239
+ if options[:with_rank]
240
+ if options[:use_zero_index_for_rank]
241
+ data[:rank] = responses[index * 2]
242
+ else
243
+ data[:rank] = responses[index * 2] + 1
244
+ end
245
+ end
246
+
247
+ data[:score] = responses[index * 2 + 1].to_f
248
+ else
249
+ if options[:with_rank]
250
+ if options[:use_zero_index_for_rank]
251
+ data[:rank] = responses[index]
252
+ else
253
+ data[:rank] = responses[index] + 1
254
+ end
255
+ end
256
+ end
196
257
 
197
258
  ranks_for_members << data
198
259
  end
@@ -212,29 +273,11 @@ class Leaderboard
212
273
 
213
274
  private
214
275
 
215
- def massage_leader_data(leaderboard_name, leaders, with_scores, with_rank, use_zero_index_for_rank)
216
- member_attribute = true
217
- leader_data = []
218
-
219
- data = {}
220
- leaders.each do |leader_data_item|
221
- if member_attribute
222
- data[:member] = leader_data_item
223
- else
224
- data[:score] = leader_data_item.to_f
225
- data[:rank] = rank_for_in(leaderboard_name, data[:member], use_zero_index_for_rank) if with_rank
226
- leader_data << data
227
- data = {}
228
- end
229
-
230
- if with_scores
231
- member_attribute = !member_attribute
232
- else
233
- leader_data << data
234
- data = {}
235
- end
276
+ def validate_page_size(page_size)
277
+ if page_size && page_size < 1
278
+ page_size = DEFAULT_PAGE_SIZE
236
279
  end
237
280
 
238
- leader_data
281
+ page_size
239
282
  end
240
283
  end
@@ -8,64 +8,92 @@ class TestLeaderboard < Test::Unit::TestCase
8
8
 
9
9
  def teardown
10
10
  @redis_connection.flushdb
11
+ @leaderboard.disconnect
12
+ @redis_connection.client.disconnect
11
13
  end
12
14
 
13
15
  def test_version
14
- assert_equal '1.0.5', Leaderboard::VERSION
16
+ assert_equal '2.0.0', Leaderboard::VERSION
15
17
  end
16
18
 
17
19
  def test_initialize_with_defaults
18
20
  assert_equal 'name', @leaderboard.leaderboard_name
19
- assert_equal 'localhost', @leaderboard.host
20
- assert_equal 6379, @leaderboard.port
21
21
  assert_equal Leaderboard::DEFAULT_PAGE_SIZE, @leaderboard.page_size
22
22
  end
23
23
 
24
+ def test_disconnect
25
+ assert_equal nil, @leaderboard.disconnect
26
+ end
27
+
28
+ def test_will_automatically_reconnect_after_a_disconnect
29
+ assert_equal 0, @leaderboard.total_members
30
+ rank_members_in_leaderboard(5)
31
+ assert_equal 5, @leaderboard.total_members
32
+ assert_equal nil, @leaderboard.disconnect
33
+ assert_equal 5, @leaderboard.total_members
34
+ end
35
+
24
36
  def test_page_size_is_default_page_size_if_set_to_invalid_value
25
- @leaderboard = Leaderboard.new('name', 'localhost', 6379, 0)
37
+ some_leaderboard = Leaderboard.new('name', {:page_size => 0})
26
38
 
27
- assert_equal Leaderboard::DEFAULT_PAGE_SIZE, @leaderboard.page_size
39
+ assert_equal Leaderboard::DEFAULT_PAGE_SIZE, some_leaderboard.page_size
40
+ some_leaderboard.disconnect
28
41
  end
29
42
 
30
- def test_add_member_and_total_members
31
- @leaderboard.add_member('member', 1)
43
+ def test_delete_leaderboard
44
+ rank_members_in_leaderboard
45
+
46
+ assert_equal true, @redis_connection.exists('name')
47
+ @leaderboard.delete_leaderboard
48
+ assert_equal false, @redis_connection.exists('name')
49
+ end
50
+
51
+ def test_can_pass_existing_redis_connection_to_initializer
52
+ @leaderboard = Leaderboard.new('name', Leaderboard::DEFAULT_OPTIONS, {:redis_connection => @redis_connection})
53
+ rank_members_in_leaderboard
54
+
55
+ assert_equal 1, @redis_connection.info["connected_clients"].to_i
56
+ end
57
+
58
+ def test_rank_member_and_total_members
59
+ @leaderboard.rank_member('member', 1)
32
60
 
33
61
  assert_equal 1, @leaderboard.total_members
34
62
  end
35
63
 
36
64
  def test_total_members_in_score_range
37
- add_members_to_leaderboard(5)
65
+ rank_members_in_leaderboard(5)
38
66
 
39
67
  assert_equal 3, @leaderboard.total_members_in_score_range(2, 4)
40
68
  end
41
69
 
42
70
  def test_rank_for
43
- add_members_to_leaderboard(5)
71
+ rank_members_in_leaderboard(5)
44
72
 
45
73
  assert_equal 2, @leaderboard.rank_for('member_4')
46
74
  assert_equal 1, @leaderboard.rank_for('member_4', true)
47
75
  end
48
76
 
49
77
  def test_score_for
50
- add_members_to_leaderboard(5)
78
+ rank_members_in_leaderboard(5)
51
79
 
52
80
  assert_equal 4, @leaderboard.score_for('member_4')
53
81
  end
54
82
 
55
83
  def test_total_pages
56
- add_members_to_leaderboard(10)
84
+ rank_members_in_leaderboard(10)
57
85
 
58
86
  assert_equal 1, @leaderboard.total_pages
59
87
 
60
88
  @redis_connection.flushdb
61
89
 
62
- add_members_to_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE + 1)
90
+ rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE + 1)
63
91
 
64
92
  assert_equal 2, @leaderboard.total_pages
65
93
  end
66
94
 
67
95
  def test_leaders
68
- add_members_to_leaderboard(25)
96
+ rank_members_in_leaderboard(25)
69
97
 
70
98
  assert_equal 25, @leaderboard.total_members
71
99
 
@@ -79,7 +107,7 @@ class TestLeaderboard < Test::Unit::TestCase
79
107
  end
80
108
 
81
109
  def test_leaders_with_multiple_pages
82
- add_members_to_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE * 3 + 1)
110
+ rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE * 3 + 1)
83
111
 
84
112
  assert_equal Leaderboard::DEFAULT_PAGE_SIZE * 3 + 1, @leaderboard.total_members
85
113
 
@@ -102,8 +130,21 @@ class TestLeaderboard < Test::Unit::TestCase
102
130
  assert_equal 1, leaders.size
103
131
  end
104
132
 
133
+ def test_leaders_without_retrieving_scores_and_ranks
134
+ rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE)
135
+
136
+ assert_equal Leaderboard::DEFAULT_PAGE_SIZE, @leaderboard.total_members
137
+ leaders = @leaderboard.leaders(1, {:with_scores => false, :with_ranks => false})
138
+
139
+ member_25 = {:member => 'member_25'}
140
+ assert_equal member_25, leaders[0]
141
+
142
+ member_1 = {:member => 'member_1'}
143
+ assert_equal member_1, leaders[24]
144
+ end
145
+
105
146
  def test_around_me
106
- add_members_to_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE * 3 + 1)
147
+ rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE * 3 + 1)
107
148
 
108
149
  assert_equal Leaderboard::DEFAULT_PAGE_SIZE * 3 + 1, @leaderboard.total_members
109
150
 
@@ -118,12 +159,12 @@ class TestLeaderboard < Test::Unit::TestCase
118
159
  end
119
160
 
120
161
  def test_ranked_in_list
121
- add_members_to_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE)
162
+ rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE)
122
163
 
123
164
  assert_equal Leaderboard::DEFAULT_PAGE_SIZE, @leaderboard.total_members
124
165
 
125
166
  members = ['member_1', 'member_5', 'member_10']
126
- ranked_members = @leaderboard.ranked_in_list(members, true)
167
+ ranked_members = @leaderboard.ranked_in_list(members, Leaderboard::DEFAULT_LEADERBOARD_REQUEST_OPTIONS)
127
168
 
128
169
  assert_equal 3, ranked_members.size
129
170
 
@@ -137,8 +178,25 @@ class TestLeaderboard < Test::Unit::TestCase
137
178
  assert_equal 10, ranked_members[2][:score]
138
179
  end
139
180
 
181
+ def test_ranked_in_list_without_scores
182
+ rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE)
183
+
184
+ assert_equal Leaderboard::DEFAULT_PAGE_SIZE, @leaderboard.total_members
185
+
186
+ members = ['member_1', 'member_5', 'member_10']
187
+ ranked_members = @leaderboard.ranked_in_list(members, {:with_scores => false, :with_rank => true, :use_zero_index_for_rank => false})
188
+
189
+ assert_equal 3, ranked_members.size
190
+
191
+ assert_equal 25, ranked_members[0][:rank]
192
+
193
+ assert_equal 21, ranked_members[1][:rank]
194
+
195
+ assert_equal 16, ranked_members[2][:rank]
196
+ end
197
+
140
198
  def test_remove_member
141
- add_members_to_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE)
199
+ rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE)
142
200
 
143
201
  assert_equal Leaderboard::DEFAULT_PAGE_SIZE, @leaderboard.total_members
144
202
 
@@ -149,7 +207,7 @@ class TestLeaderboard < Test::Unit::TestCase
149
207
  end
150
208
 
151
209
  def test_change_score_for
152
- @leaderboard.add_member('member_1', 5)
210
+ @leaderboard.rank_member('member_1', 5)
153
211
  assert_equal 5, @leaderboard.score_for('member_1')
154
212
 
155
213
  @leaderboard.change_score_for('member_1', 5)
@@ -160,22 +218,31 @@ class TestLeaderboard < Test::Unit::TestCase
160
218
  end
161
219
 
162
220
  def test_check_member
163
- @leaderboard.add_member('member_1', 10)
221
+ @leaderboard.rank_member('member_1', 10)
164
222
 
165
223
  assert_equal true, @leaderboard.check_member?('member_1')
166
224
  assert_equal false, @leaderboard.check_member?('member_2')
167
225
  end
168
226
 
169
227
  def test_can_change_page_size_and_have_it_reflected_in_size_of_result_set
170
- add_members_to_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE)
228
+ rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE)
171
229
 
172
230
  @leaderboard.page_size = 5
231
+
173
232
  assert_equal 5, @leaderboard.total_pages
174
233
  assert_equal 5, @leaderboard.leaders(1).size
175
234
  end
176
235
 
236
+ def test_cannot_set_page_size_to_invalid_page_size
237
+ rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE)
238
+
239
+ @leaderboard.page_size = 0
240
+ assert_equal 1, @leaderboard.total_pages
241
+ assert_equal Leaderboard::DEFAULT_PAGE_SIZE, @leaderboard.leaders(1).size
242
+ end
243
+
177
244
  def test_score_and_rank_for
178
- add_members_to_leaderboard
245
+ rank_members_in_leaderboard
179
246
 
180
247
  data = @leaderboard.score_and_rank_for('member_1')
181
248
  assert_equal 'member_1', data[:member]
@@ -184,13 +251,13 @@ class TestLeaderboard < Test::Unit::TestCase
184
251
  end
185
252
 
186
253
  def test_remove_members_in_score_range
187
- add_members_to_leaderboard
254
+ rank_members_in_leaderboard
188
255
 
189
256
  assert_equal 5, @leaderboard.total_members
190
257
 
191
- @leaderboard.add_member('cheater_1', 100)
192
- @leaderboard.add_member('cheater_2', 101)
193
- @leaderboard.add_member('cheater_3', 102)
258
+ @leaderboard.rank_member('cheater_1', 100)
259
+ @leaderboard.rank_member('cheater_2', 101)
260
+ @leaderboard.rank_member('cheater_3', 102)
194
261
 
195
262
  assert_equal 8, @leaderboard.total_members
196
263
 
@@ -205,14 +272,14 @@ class TestLeaderboard < Test::Unit::TestCase
205
272
  end
206
273
 
207
274
  def test_merge_leaderboards
208
- foo = Leaderboard.new('foo')
275
+ foo = Leaderboard.new('foo')
209
276
  bar = Leaderboard.new('bar')
210
277
 
211
- foo.add_member('foo_1', 1)
212
- foo.add_member('foo_2', 2)
213
- bar.add_member('bar_1', 3)
214
- bar.add_member('bar_2', 4)
215
- bar.add_member('bar_3', 5)
278
+ foo.rank_member('foo_1', 1)
279
+ foo.rank_member('foo_2', 2)
280
+ bar.rank_member('bar_1', 3)
281
+ bar.rank_member('bar_2', 4)
282
+ bar.rank_member('bar_3', 5)
216
283
 
217
284
  foobar_keys = foo.merge_leaderboards('foobar', ['bar'])
218
285
  assert_equal 5, foobar_keys
@@ -224,18 +291,22 @@ class TestLeaderboard < Test::Unit::TestCase
224
291
  assert_equal 1, first_leader_in_foobar[:rank]
225
292
  assert_equal 'bar_3', first_leader_in_foobar[:member]
226
293
  assert_equal 5, first_leader_in_foobar[:score]
294
+
295
+ foo.disconnect
296
+ bar.disconnect
297
+ foobar.disconnect
227
298
  end
228
299
 
229
300
  def test_intersect_leaderboards
230
301
  foo = Leaderboard.new('foo')
231
302
  bar = Leaderboard.new('bar')
232
303
 
233
- foo.add_member('foo_1', 1)
234
- foo.add_member('foo_2', 2)
235
- foo.add_member('bar_3', 6)
236
- bar.add_member('bar_1', 3)
237
- bar.add_member('foo_1', 4)
238
- bar.add_member('bar_3', 5)
304
+ foo.rank_member('foo_1', 1)
305
+ foo.rank_member('foo_2', 2)
306
+ foo.rank_member('bar_3', 6)
307
+ bar.rank_member('bar_1', 3)
308
+ bar.rank_member('foo_1', 4)
309
+ bar.rank_member('bar_3', 5)
239
310
 
240
311
  foobar_keys = foo.intersect_leaderboards('foobar', ['bar'], {:aggregate => :max})
241
312
  assert_equal 2, foobar_keys
@@ -247,53 +318,57 @@ class TestLeaderboard < Test::Unit::TestCase
247
318
  assert_equal 1, first_leader_in_foobar[:rank]
248
319
  assert_equal 'bar_3', first_leader_in_foobar[:member]
249
320
  assert_equal 6, first_leader_in_foobar[:score]
321
+
322
+ foo.disconnect
323
+ bar.disconnect
324
+ foobar.disconnect
250
325
  end
251
326
 
252
327
  def test_massage_leader_data_respects_with_scores
253
- add_members_to_leaderboard(25)
328
+ rank_members_in_leaderboard(25)
254
329
 
255
330
  assert_equal 25, @leaderboard.total_members
256
331
 
257
- leaders = @leaderboard.leaders(1, false, false, false)
332
+ leaders = @leaderboard.leaders(1, {:with_scores => false, :with_rank => false})
258
333
  assert_not_nil leaders[0][:member]
259
334
  assert_nil leaders[0][:score]
260
335
  assert_nil leaders[0][:rank]
261
336
 
262
337
  @leaderboard.page_size = 25
263
- leaders = @leaderboard.leaders(1, false, false, false)
338
+ leaders = @leaderboard.leaders(1, {:with_scores => false, :with_rank => false})
264
339
  assert_equal 25, leaders.size
265
340
 
266
341
  @leaderboard.page_size = Leaderboard::DEFAULT_PAGE_SIZE
267
- leaders = @leaderboard.leaders(1, true, true, false)
342
+ leaders = @leaderboard.leaders(1, Leaderboard::DEFAULT_LEADERBOARD_REQUEST_OPTIONS)
268
343
  assert_not_nil leaders[0][:member]
269
344
  assert_not_nil leaders[0][:score]
270
345
  assert_not_nil leaders[0][:rank]
271
346
 
272
347
  @leaderboard.page_size = 25
273
- leaders = @leaderboard.leaders(1, true, true, false)
348
+ leaders = @leaderboard.leaders(1, Leaderboard::DEFAULT_LEADERBOARD_REQUEST_OPTIONS)
274
349
  assert_equal 25, leaders.size
275
350
  end
276
351
 
277
352
  def test_total_pages_in_with_new_page_size
278
- add_members_to_leaderboard(25)
353
+ rank_members_in_leaderboard(25)
279
354
 
280
355
  assert_equal 1, @leaderboard.total_pages_in(@leaderboard.leaderboard_name)
281
356
  assert_equal 5, @leaderboard.total_pages_in(@leaderboard.leaderboard_name, 5)
282
357
  end
283
358
 
284
359
  def test_leaders_call_with_new_page_size
285
- add_members_to_leaderboard(25)
360
+ rank_members_in_leaderboard(25)
286
361
 
287
- assert_equal 5, @leaderboard.leaders(1, true, true, false, 5).size
288
- assert_equal 10, @leaderboard.leaders(1, true, true, false, 10).size
289
- assert_equal 10, @leaderboard.leaders(2, true, true, false, 10).size
290
- assert_equal 5, @leaderboard.leaders(3, true, true, false, 10).size
362
+ assert_equal 5, @leaderboard.leaders(1, Leaderboard::DEFAULT_LEADERBOARD_REQUEST_OPTIONS.merge({:page_size => 5})).size
363
+ assert_equal 10, @leaderboard.leaders(1, Leaderboard::DEFAULT_LEADERBOARD_REQUEST_OPTIONS.merge({:page_size => 10})).size
364
+ assert_equal 10, @leaderboard.leaders(2, Leaderboard::DEFAULT_LEADERBOARD_REQUEST_OPTIONS.merge({:page_size => 10})).size
365
+ assert_equal 5, @leaderboard.leaders(3, Leaderboard::DEFAULT_LEADERBOARD_REQUEST_OPTIONS.merge({:page_size => 10})).size
291
366
  end
292
367
 
293
368
  def test_around_me_call_with_new_page_size
294
- add_members_to_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE * 3 + 1)
369
+ rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE * 3 + 1)
295
370
 
296
- leaders_around_me = @leaderboard.around_me('member_30', true, true, false, 3)
371
+ leaders_around_me = @leaderboard.around_me('member_30', Leaderboard::DEFAULT_LEADERBOARD_REQUEST_OPTIONS.merge({:page_size => 3}))
297
372
  assert_equal 3, leaders_around_me.size
298
373
  assert_equal 'member_31', leaders_around_me[0][:member]
299
374
  assert_equal 'member_29', leaders_around_me[2][:member]
@@ -301,9 +376,9 @@ class TestLeaderboard < Test::Unit::TestCase
301
376
 
302
377
  private
303
378
 
304
- def add_members_to_leaderboard(members_to_add = 5)
379
+ def rank_members_in_leaderboard(members_to_add = 5)
305
380
  1.upto(members_to_add) do |index|
306
- @leaderboard.add_member("member_#{index}", index)
381
+ @leaderboard.rank_member("member_#{index}", index)
307
382
  end
308
383
  end
309
384
  end
metadata CHANGED
@@ -1,95 +1,68 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: leaderboard
3
- version: !ruby/object:Gem::Version
4
- hash: 29
5
- prerelease: false
6
- segments:
7
- - 1
8
- - 0
9
- - 5
10
- version: 1.0.5
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.0
5
+ prerelease:
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - David Czarnecki
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-05-04 00:00:00 -04:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
22
- type: :runtime
23
- prerelease: false
12
+ date: 2011-08-17 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
24
15
  name: redis
25
- version_requirements: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &70114074547140 !ruby/object:Gem::Requirement
26
17
  none: false
27
- requirements:
18
+ requirements:
28
19
  - - ~>
29
- - !ruby/object:Gem::Version
30
- hash: 9
31
- segments:
32
- - 2
33
- - 1
34
- - 1
35
- version: 2.1.1
36
- requirement: *id001
37
- - !ruby/object:Gem::Dependency
38
- type: :development
20
+ - !ruby/object:Gem::Version
21
+ version: 2.2.0
22
+ type: :runtime
39
23
  prerelease: false
24
+ version_requirements: *70114074547140
25
+ - !ruby/object:Gem::Dependency
40
26
  name: bundler
41
- version_requirements: &id002 !ruby/object:Gem::Requirement
27
+ requirement: &70114074545640 !ruby/object:Gem::Requirement
42
28
  none: false
43
- requirements:
29
+ requirements:
44
30
  - - ~>
45
- - !ruby/object:Gem::Version
46
- hash: 23
47
- segments:
48
- - 1
49
- - 0
50
- - 0
31
+ - !ruby/object:Gem::Version
51
32
  version: 1.0.0
52
- requirement: *id002
53
- - !ruby/object:Gem::Dependency
54
33
  type: :development
55
34
  prerelease: false
35
+ version_requirements: *70114074545640
36
+ - !ruby/object:Gem::Dependency
56
37
  name: jeweler
57
- version_requirements: &id003 !ruby/object:Gem::Requirement
38
+ requirement: &70114074543920 !ruby/object:Gem::Requirement
58
39
  none: false
59
- requirements:
40
+ requirements:
60
41
  - - ~>
61
- - !ruby/object:Gem::Version
62
- hash: 7
63
- segments:
64
- - 1
65
- - 5
66
- - 2
42
+ - !ruby/object:Gem::Version
67
43
  version: 1.5.2
68
- requirement: *id003
69
- - !ruby/object:Gem::Dependency
70
44
  type: :development
71
45
  prerelease: false
46
+ version_requirements: *70114074543920
47
+ - !ruby/object:Gem::Dependency
72
48
  name: rcov
73
- version_requirements: &id004 !ruby/object:Gem::Requirement
49
+ requirement: &70114074539440 !ruby/object:Gem::Requirement
74
50
  none: false
75
- requirements:
76
- - - ">="
77
- - !ruby/object:Gem::Version
78
- hash: 3
79
- segments:
80
- - 0
81
- version: "0"
82
- requirement: *id004
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70114074539440
83
58
  description: Leaderboards backed by Redis in Ruby
84
59
  email: dczarnecki@agoragames.com
85
60
  executables: []
86
-
87
61
  extensions: []
88
-
89
- extra_rdoc_files:
62
+ extra_rdoc_files:
90
63
  - LICENSE.txt
91
64
  - README.rdoc
92
- files:
65
+ files:
93
66
  - .document
94
67
  - .rvmrc
95
68
  - CHANGELOG.markdown
@@ -104,40 +77,34 @@ files:
104
77
  - test/helper.rb
105
78
  - test/test.conf
106
79
  - test/test_leaderboard.rb
107
- has_rdoc: true
108
80
  homepage: http://github.com/agoragames/leaderboard
109
- licenses:
81
+ licenses:
110
82
  - MIT
111
83
  post_install_message:
112
84
  rdoc_options: []
113
-
114
- require_paths:
85
+ require_paths:
115
86
  - lib
116
- required_ruby_version: !ruby/object:Gem::Requirement
87
+ required_ruby_version: !ruby/object:Gem::Requirement
117
88
  none: false
118
- requirements:
119
- - - ">="
120
- - !ruby/object:Gem::Version
121
- hash: 3
122
- segments:
89
+ requirements:
90
+ - - ! '>='
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ segments:
123
94
  - 0
124
- version: "0"
125
- required_rubygems_version: !ruby/object:Gem::Requirement
95
+ hash: -2495258638232902776
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
126
97
  none: false
127
- requirements:
128
- - - ">="
129
- - !ruby/object:Gem::Version
130
- hash: 3
131
- segments:
132
- - 0
133
- version: "0"
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
134
102
  requirements: []
135
-
136
103
  rubyforge_project:
137
- rubygems_version: 1.3.7
104
+ rubygems_version: 1.8.6
138
105
  signing_key:
139
106
  specification_version: 3
140
107
  summary: Leaderboards backed by Redis in Ruby
141
- test_files:
108
+ test_files:
142
109
  - test/helper.rb
143
110
  - test/test_leaderboard.rb