leaderboard 2.0.5 → 2.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +2 -0
- data/CHANGELOG.markdown +4 -0
- data/README.markdown +73 -69
- data/Rakefile +12 -12
- data/leaderboard.gemspec +1 -0
- data/lib/leaderboard.rb +19 -1
- data/lib/leaderboard/version.rb +2 -1
- data/spec/db/.gitkeep +0 -0
- data/spec/leaderboard_spec.rb +503 -0
- data/spec/reverse_leaderboard_spec.rb +292 -0
- data/spec/spec_helper.rb +15 -0
- data/{test → spec}/test.conf +1 -1
- data/spec/version_spec.rb +7 -0
- metadata +32 -18
- data/test/test_helper.rb +0 -19
- data/test/test_leaderboard.rb +0 -484
- data/test/test_rev_leaderboard.rb +0 -484
data/.rspec
ADDED
data/CHANGELOG.markdown
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## leaderboard 2.0.6 (2012-04-26)
|
4
|
+
|
5
|
+
* Added accessor for +reverse+ option so that you can set reverse after creating a leaderboard to see results in either highest-to-lowest or lowest-to-highest order.
|
6
|
+
|
3
7
|
## leaderboard 2.0.5 (2012-03-14)
|
4
8
|
|
5
9
|
* Added `rank_members(members_and_scores)` and `rank_members_in(leaderboard_name, members_and_scores)` allowing you to pass in some variable number of `member_name, score` and so on or an actual array of those data items. Use this method to do bulk insert of data, but be mindful of the amount of data you are inserting since a single transaction can get quite large.
|
data/README.markdown
CHANGED
@@ -26,16 +26,16 @@ The gem has been built and tested under Ruby 1.8.7, Ruby 1.9.2 and Ruby 1.9.3
|
|
26
26
|
Create a new leaderboard or attach to an existing leaderboard named 'highscores':
|
27
27
|
|
28
28
|
```ruby
|
29
|
-
|
29
|
+
highscore_lb = Leaderboard.new('highscores')
|
30
30
|
=> #<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)>>
|
31
31
|
```
|
32
32
|
|
33
33
|
If you need to pass in options for Redis, you can do this in the initializer:
|
34
34
|
|
35
35
|
```ruby
|
36
|
-
|
36
|
+
redis_options = {:host => 'localhost', :port => 6379, :db => 1}
|
37
37
|
=> {:host=>"localhost", :port=>6379, :db=>1}
|
38
|
-
|
38
|
+
highscore_lb = Leaderboard.new('highscores', Leaderboard::DEFAULT_OPTIONS, redis_options)
|
39
39
|
=> #<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)>>
|
40
40
|
```
|
41
41
|
|
@@ -48,63 +48,66 @@ DEFAULT_OPTIONS = {
|
|
48
48
|
}
|
49
49
|
```
|
50
50
|
|
51
|
-
|
51
|
+
The `DEFAULT_PAGE_SIZE` is 25.
|
52
52
|
|
53
|
-
You
|
53
|
+
You would use the option, `:reverse => true`, if you wanted a leaderboard sorted from lowest-to-highest score. You
|
54
|
+
may also set the `reverse` option on a leaderboard after you have created a new instance of a leaderboard.
|
55
|
+
|
56
|
+
You can pass in an existing connection to Redis using `:redis_connection` in the Redis options hash:
|
54
57
|
|
55
58
|
```ruby
|
56
|
-
|
59
|
+
redis = Redis.new
|
57
60
|
=> #<Redis client v2.2.2 connected to redis://127.0.0.1:6379/0 (Redis v2.2.5)>
|
58
|
-
|
61
|
+
redis_options = {:redis_connection => redis}
|
59
62
|
=> {:redis_connection=>#<Redis client v2.2.2 connected to redis://127.0.0.1:6379/0 (Redis v2.2.5)>}
|
60
|
-
|
63
|
+
highscore_lb = Leaderboard.new('highscores', Leaderboard::DEFAULT_OPTIONS, redis_options)
|
61
64
|
=> #<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)>>
|
62
65
|
```
|
63
66
|
|
64
67
|
You can set the page size to something other than the default page size (25):
|
65
68
|
|
66
69
|
```ruby
|
67
|
-
|
70
|
+
highscore_lb.page_size = 5
|
68
71
|
=> 5
|
69
|
-
|
72
|
+
highscore_lb
|
70
73
|
=> #<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)>>
|
71
74
|
```
|
72
75
|
|
73
|
-
Add members to your leaderboard using rank_member
|
76
|
+
Add members to your leaderboard using `rank_member`:
|
74
77
|
|
75
78
|
```ruby
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
+
1.upto(10) do |index|
|
80
|
+
highscore_lb.rank_member("member_#{index}", index)
|
81
|
+
end
|
79
82
|
=> 1
|
80
83
|
```
|
81
84
|
|
82
|
-
You can call rank_member with the same member and the leaderboard will be updated automatically.
|
85
|
+
You can call `rank_member` with the same member and the leaderboard will be updated automatically.
|
83
86
|
|
84
87
|
Get some information about your leaderboard:
|
85
88
|
|
86
89
|
```ruby
|
87
|
-
|
90
|
+
highscore_lb.total_members
|
88
91
|
=> 10
|
89
|
-
|
92
|
+
highscore_lb.total_pages
|
90
93
|
=> 1
|
91
94
|
```
|
92
95
|
|
93
96
|
Get some information about a specific member(s) in the leaderboard:
|
94
97
|
|
95
98
|
```ruby
|
96
|
-
|
99
|
+
highscore_lb.score_for('member_4')
|
97
100
|
=> 4.0
|
98
|
-
|
101
|
+
highscore_lb.rank_for('member_4')
|
99
102
|
=> 7
|
100
|
-
|
103
|
+
highscore_lb.rank_for('member_10')
|
101
104
|
=> 1
|
102
105
|
```
|
103
106
|
|
104
107
|
Get page 1 in the leaderboard:
|
105
108
|
|
106
109
|
```ruby
|
107
|
-
|
110
|
+
highscore_lb.leaders(1)
|
108
111
|
=> [{: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}]
|
109
112
|
```
|
110
113
|
|
@@ -112,39 +115,39 @@ You can pass various options to the calls `leaders`, `around_me` and `ranked_in_
|
|
112
115
|
Below is an example of retrieving the first page in the leaderboard without ranks:
|
113
116
|
|
114
117
|
```ruby
|
115
|
-
|
118
|
+
highscore_lb.leaders(1, :with_rank => false)
|
116
119
|
=> [{: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}]
|
117
120
|
```
|
118
121
|
|
119
122
|
Below is an example of retrieving the first page in the leaderboard without scores or ranks:
|
120
123
|
|
121
124
|
```ruby
|
122
|
-
|
125
|
+
highscore_lb.leaders(1, :with_scores => false, :with_rank => false)
|
123
126
|
=> [{: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"}]
|
124
127
|
```
|
125
128
|
|
126
129
|
Add more members to your leaderboard:
|
127
130
|
|
128
131
|
```ruby
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
+
50.upto(95) do |index|
|
133
|
+
highscore_lb.rank_member("member_#{index}", index)
|
134
|
+
end
|
132
135
|
=> 50
|
133
|
-
|
136
|
+
highscore_lb.total_pages
|
134
137
|
=> 3
|
135
138
|
```
|
136
139
|
|
137
|
-
Get an "Around Me" leaderboard for a member:
|
140
|
+
Get an "Around Me" leaderboard page for a given member, which pulls members above and below the given member:
|
138
141
|
|
139
142
|
```ruby
|
140
|
-
|
143
|
+
highscore_lb.around_me('member_53')
|
141
144
|
=> [{: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}]
|
142
145
|
```
|
143
146
|
|
144
|
-
Get rank and score for an arbitrary list of members (e.g. friends):
|
147
|
+
Get rank and score for an arbitrary list of members (e.g. friends) from the leaderboard:
|
145
148
|
|
146
149
|
```ruby
|
147
|
-
|
150
|
+
highscore_lb.ranked_in_list(['member_1', 'member_62', 'member_67'])
|
148
151
|
=> [{:member=>"member_1", :rank=>56, :score=>1.0}, {:member=>"member_62", :rank=>34, :score=>62.0}, {:member=>"member_67", :rank=>29, :score=>67.0}]
|
149
152
|
```
|
150
153
|
|
@@ -192,30 +195,31 @@ Check the [online documentation](http://rubydoc.info/github/agoragames/leaderboa
|
|
192
195
|
10 million sequential scores insert:
|
193
196
|
|
194
197
|
```ruby
|
195
|
-
|
198
|
+
highscore_lb = Leaderboard.new('highscores')
|
196
199
|
=> #<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)>>
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
200
|
+
|
201
|
+
insert_time = Benchmark.measure do
|
202
|
+
1.upto(10000000) do |index|
|
203
|
+
highscore_lb.rank_member("member_#{index}", index)
|
204
|
+
end
|
205
|
+
end
|
202
206
|
=> 323.070000 148.560000 471.630000 (942.068307)
|
203
207
|
```
|
204
208
|
|
205
209
|
Average time to request an arbitrary page from the leaderboard:
|
206
210
|
|
207
211
|
```ruby
|
208
|
-
|
212
|
+
requests_to_make = 50000
|
209
213
|
=> 50000
|
210
|
-
|
214
|
+
lb_request_time = 0
|
211
215
|
=> 0
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
216
|
+
1.upto(requests_to_make) do
|
217
|
+
lb_request_time += Benchmark.measure do
|
218
|
+
highscore_lb.leaders(rand(highscore_lb.total_pages))
|
219
|
+
end.total
|
220
|
+
end
|
217
221
|
=> 1
|
218
|
-
|
222
|
+
p lb_request_time / requests_to_make
|
219
223
|
0.001513999999999998
|
220
224
|
=> 0.001513999999999998
|
221
225
|
```
|
@@ -223,24 +227,24 @@ Average time to request an arbitrary page from the leaderboard:
|
|
223
227
|
10 million random scores insert:
|
224
228
|
|
225
229
|
```ruby
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
230
|
+
insert_time = Benchmark.measure do
|
231
|
+
1.upto(10000000) do |index|
|
232
|
+
highscore_lb.rank_member("member_#{index}", rand(50000000))
|
233
|
+
end
|
234
|
+
end
|
231
235
|
=> 338.480000 155.200000 493.680000 (2188.702475)
|
232
236
|
```
|
233
237
|
|
234
238
|
Average time to request an arbitrary page from the leaderboard:
|
235
239
|
|
236
240
|
```ruby
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
241
|
+
1.upto(requests_to_make) do
|
242
|
+
lb_request_time += Benchmark.measure do
|
243
|
+
highscore_lb.leaders(rand(highscore_lb.total_pages))
|
244
|
+
end.total
|
245
|
+
end
|
242
246
|
=> 1
|
243
|
-
|
247
|
+
p lb_request_time / requests_to_make
|
244
248
|
0.0014615999999999531
|
245
249
|
=> 0.0014615999999999531
|
246
250
|
```
|
@@ -250,27 +254,27 @@ Bulk insert performance:
|
|
250
254
|
Ranking individual members:
|
251
255
|
|
252
256
|
```ruby
|
253
|
-
|
254
|
-
1.
|
255
|
-
|
256
|
-
|
257
|
-
|
257
|
+
insert_time = Benchmark.measure do
|
258
|
+
1.upto(1000000) do |index|
|
259
|
+
highscore_lb.rank_member("member_#{index}", index)
|
260
|
+
end
|
261
|
+
end
|
258
262
|
=> 29.340000 15.050000 44.390000 ( 81.673507)
|
259
263
|
```
|
260
264
|
|
261
265
|
Ranking multiple members at once:
|
262
266
|
|
263
267
|
```ruby
|
264
|
-
|
268
|
+
member_data = []
|
265
269
|
=> []
|
266
|
-
1.
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
+
1.upto(1000000) do |index|
|
271
|
+
member_data << "member_#{index}"
|
272
|
+
member_data << index
|
273
|
+
end
|
270
274
|
=> 1
|
271
|
-
|
272
|
-
|
273
|
-
|
275
|
+
insert_time = Benchmark.measure do
|
276
|
+
highscore_lb.rank_members(member_data)
|
277
|
+
end
|
274
278
|
=> 22.390000 6.380000 28.770000 ( 31.144027)
|
275
279
|
```
|
276
280
|
|
data/Rakefile
CHANGED
@@ -1,15 +1,15 @@
|
|
1
|
-
require 'bundler
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
#
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
|
6
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
7
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
8
|
+
spec.rspec_opts = ['--backtrace']
|
9
|
+
# spec.ruby_opts = ['-w']
|
10
10
|
end
|
11
11
|
|
12
|
-
REDIS_DIR = File.expand_path(File.join("..", "
|
12
|
+
REDIS_DIR = File.expand_path(File.join("..", "spec"), __FILE__)
|
13
13
|
REDIS_CNF = File.join(REDIS_DIR, "test.conf")
|
14
14
|
REDIS_PID = File.join(REDIS_DIR, "db", "redis.pid")
|
15
15
|
REDIS_LOCATION = ENV['REDIS_LOCATION']
|
@@ -17,7 +17,7 @@ REDIS_LOCATION = ENV['REDIS_LOCATION']
|
|
17
17
|
task :default => :run
|
18
18
|
|
19
19
|
desc "Run tests and manage server start/stop"
|
20
|
-
task :run => [:start, :
|
20
|
+
task :run => [:start, :spec, :stop]
|
21
21
|
|
22
22
|
desc "Start the Redis server"
|
23
23
|
task :start do
|
@@ -46,6 +46,6 @@ end
|
|
46
46
|
|
47
47
|
task :test_rubies do
|
48
48
|
Rake::Task['start'].execute
|
49
|
-
system "rvm 1.8.7@leaderboard_gem,1.9.2@leaderboard_gem,1.9.3@leaderboard_gem do rake
|
49
|
+
system "rvm 1.8.7@leaderboard_gem,1.9.2@leaderboard_gem,1.9.3@leaderboard_gem do rake spec"
|
50
50
|
Rake::Task['stop'].execute
|
51
51
|
end
|
data/leaderboard.gemspec
CHANGED
data/lib/leaderboard.rb
CHANGED
@@ -1,23 +1,36 @@
|
|
1
1
|
require 'redis'
|
2
2
|
require 'leaderboard/version'
|
3
3
|
|
4
|
-
class Leaderboard
|
4
|
+
class Leaderboard
|
5
|
+
# Default page size: 25
|
5
6
|
DEFAULT_PAGE_SIZE = 25
|
6
7
|
|
8
|
+
# Default options when creating a leaderboard. Page size is 25 and reverse
|
9
|
+
# is set to false, meaning various methods will return results in
|
10
|
+
# highest-to-lowest order.
|
7
11
|
DEFAULT_OPTIONS = {
|
8
12
|
:page_size => DEFAULT_PAGE_SIZE,
|
9
13
|
:reverse => false
|
10
14
|
}
|
11
15
|
|
16
|
+
# Default Redis host: localhost
|
12
17
|
DEFAULT_REDIS_HOST = 'localhost'
|
13
18
|
|
19
|
+
# Default Redis post: 6379
|
14
20
|
DEFAULT_REDIS_PORT = 6379
|
15
21
|
|
22
|
+
# Default Redis options when creating a connection to Redis. The
|
23
|
+
# +DEFAULT_REDIS_HOST+ and +DEFAULT_REDIS_PORT+ will be passed.
|
16
24
|
DEFAULT_REDIS_OPTIONS = {
|
17
25
|
:host => DEFAULT_REDIS_HOST,
|
18
26
|
:port => DEFAULT_REDIS_PORT
|
19
27
|
}
|
20
28
|
|
29
|
+
# Default options when requesting data from a leaderboard.
|
30
|
+
# +:with_scores+ true: Return scores along with the member names.
|
31
|
+
# +:with_rank+ true: Return ranks along with the member names.
|
32
|
+
# +:use_zero_index_for_rank+ false: If you want to 0-index ranks.
|
33
|
+
# +:page_size+ nil: The default page size will be used.
|
21
34
|
DEFAULT_LEADERBOARD_REQUEST_OPTIONS = {
|
22
35
|
:with_scores => true,
|
23
36
|
:with_rank => true,
|
@@ -30,6 +43,11 @@ class Leaderboard
|
|
30
43
|
|
31
44
|
# Page size to be used when paging through the leaderboard.
|
32
45
|
attr_reader :page_size
|
46
|
+
|
47
|
+
# Determines whether or not various leaderboard methods return their
|
48
|
+
# data in highest-to-lowest (+:reverse+ false) or
|
49
|
+
# lowest-to-highest (+:reverse+ true)
|
50
|
+
attr_accessor :reverse
|
33
51
|
|
34
52
|
# Create a new instance of a leaderboard.
|
35
53
|
#
|
data/lib/leaderboard/version.rb
CHANGED
data/spec/db/.gitkeep
ADDED
File without changes
|
@@ -0,0 +1,503 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Leaderboard' do
|
4
|
+
before(:each) do
|
5
|
+
@redis_connection = Redis.new(:host => "127.0.0.1", :db => 15)
|
6
|
+
@leaderboard = Leaderboard.new('name', Leaderboard::DEFAULT_LEADERBOARD_REQUEST_OPTIONS, :host => "127.0.0.1", :db => 15)
|
7
|
+
end
|
8
|
+
|
9
|
+
after(:each) do
|
10
|
+
@redis_connection.flushdb
|
11
|
+
@leaderboard.disconnect
|
12
|
+
@redis_connection.client.disconnect
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should be initialized with defaults' do
|
16
|
+
@leaderboard.leaderboard_name.should == 'name'
|
17
|
+
@leaderboard.page_size.should == Leaderboard::DEFAULT_PAGE_SIZE
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should be able to disconnect its connection to Redis' do
|
21
|
+
@leaderboard.disconnect.should be_nil
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should automatically reconnect to Redis after a disconnect' do
|
25
|
+
@leaderboard.total_members.should be(0)
|
26
|
+
rank_members_in_leaderboard(5)
|
27
|
+
@leaderboard.total_members.should be(5)
|
28
|
+
@leaderboard.disconnect.should be_nil
|
29
|
+
@leaderboard.total_members.should be(5)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should set the page size to the default page size if passed an invalid value' do
|
33
|
+
some_leaderboard = Leaderboard.new('name', {:page_size => 0})
|
34
|
+
|
35
|
+
some_leaderboard.page_size.should be(Leaderboard::DEFAULT_PAGE_SIZE)
|
36
|
+
some_leaderboard.disconnect
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should allow you to delete a leaderboard' do
|
40
|
+
rank_members_in_leaderboard
|
41
|
+
|
42
|
+
@redis_connection.exists('name').should be_true
|
43
|
+
@leaderboard.delete_leaderboard
|
44
|
+
@redis_connection.exists('name').should be_false
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should allow you to pass in an existing redis connection in the initializer' do
|
48
|
+
@leaderboard = Leaderboard.new('name', Leaderboard::DEFAULT_OPTIONS, {:redis_connection => @redis_connection})
|
49
|
+
rank_members_in_leaderboard
|
50
|
+
|
51
|
+
@redis_connection.info["connected_clients"].to_i.should be(1)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should allow you to rank a member and see that reflected in total members' do
|
55
|
+
@leaderboard.rank_member('member', 1)
|
56
|
+
|
57
|
+
@leaderboard.total_members.should be(1)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should return the correct number of members in a given score range' do
|
61
|
+
rank_members_in_leaderboard(5)
|
62
|
+
|
63
|
+
@leaderboard.total_members_in_score_range(2, 4).should be(3)
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should return the correct rank when calling rank_for' do
|
67
|
+
rank_members_in_leaderboard(5)
|
68
|
+
|
69
|
+
@leaderboard.rank_for('member_4').should be(2)
|
70
|
+
@leaderboard.rank_for('member_4', true).should be(1)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should return the correct score when calling score_for' do
|
74
|
+
rank_members_in_leaderboard(5)
|
75
|
+
|
76
|
+
@leaderboard.score_for('member_4').should == 4
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'should return the correct total pages' do
|
80
|
+
rank_members_in_leaderboard(10)
|
81
|
+
|
82
|
+
@leaderboard.total_pages.should be(1)
|
83
|
+
|
84
|
+
@redis_connection.flushdb
|
85
|
+
|
86
|
+
rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE + 1)
|
87
|
+
|
88
|
+
@leaderboard.total_pages.should be(2)
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'should return the correct list when calling leaders' do
|
92
|
+
rank_members_in_leaderboard(25)
|
93
|
+
|
94
|
+
@leaderboard.total_members.should be(25)
|
95
|
+
|
96
|
+
leaders = @leaderboard.leaders(1)
|
97
|
+
|
98
|
+
leaders.size.should be(25)
|
99
|
+
leaders[0][:member].should == 'member_25'
|
100
|
+
leaders[-2][:member].should == 'member_2'
|
101
|
+
leaders[-1][:member].should == 'member_1'
|
102
|
+
leaders[-1][:score].to_i.should be(1)
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'should return the correct number of members when calling leaders with multiple pages' do
|
106
|
+
rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE * 3 + 1)
|
107
|
+
|
108
|
+
@leaderboard.total_members.should be(Leaderboard::DEFAULT_PAGE_SIZE * 3 + 1)
|
109
|
+
|
110
|
+
leaders = @leaderboard.leaders(1)
|
111
|
+
leaders.size.should be(@leaderboard.page_size)
|
112
|
+
|
113
|
+
leaders = @leaderboard.leaders(2)
|
114
|
+
leaders.size.should be(@leaderboard.page_size)
|
115
|
+
|
116
|
+
leaders = @leaderboard.leaders(3)
|
117
|
+
leaders.size.should be(@leaderboard.page_size)
|
118
|
+
|
119
|
+
leaders = @leaderboard.leaders(4)
|
120
|
+
leaders.size.should be(1)
|
121
|
+
|
122
|
+
leaders = @leaderboard.leaders(-5)
|
123
|
+
leaders.size.should be(@leaderboard.page_size)
|
124
|
+
|
125
|
+
leaders = @leaderboard.leaders(10)
|
126
|
+
leaders.size.should be(1)
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'should allow you to retrieve leaders without scores and ranks' do
|
130
|
+
rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE)
|
131
|
+
|
132
|
+
@leaderboard.total_members.should be(Leaderboard::DEFAULT_PAGE_SIZE)
|
133
|
+
leaders = @leaderboard.leaders(1, {:with_scores => false, :with_rank => false})
|
134
|
+
|
135
|
+
member_25 = {:member => 'member_25'}
|
136
|
+
leaders[0].should == member_25
|
137
|
+
|
138
|
+
member_1 = {:member => 'member_1'}
|
139
|
+
leaders[24].should == member_1
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'should allow you to call leaders with various options that respect the defaults for the options not passed in' do
|
143
|
+
rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE + 1)
|
144
|
+
|
145
|
+
leaders = @leaderboard.leaders(1, :page_size => 1)
|
146
|
+
leaders.size.should be(1)
|
147
|
+
|
148
|
+
leaders = @leaderboard.leaders(1, :with_rank => false)
|
149
|
+
leaders.size.should be(Leaderboard::DEFAULT_PAGE_SIZE)
|
150
|
+
member_26 = {:member => 'member_26', :score => 26}
|
151
|
+
member_25 = {:member => 'member_25', :score => 25}
|
152
|
+
member_24 = {:member => 'member_24', :score => 24}
|
153
|
+
leaders[0].should == member_26
|
154
|
+
leaders[1].should == member_25
|
155
|
+
leaders[2].should == member_24
|
156
|
+
|
157
|
+
leaders = @leaderboard.leaders(1, :with_scores => false)
|
158
|
+
leaders.size.should be(Leaderboard::DEFAULT_PAGE_SIZE)
|
159
|
+
member_26 = {:member => 'member_26', :rank => 1}
|
160
|
+
member_25 = {:member => 'member_25', :rank => 2}
|
161
|
+
leaders[0].should == member_26
|
162
|
+
leaders[1].should == member_25
|
163
|
+
|
164
|
+
leaders = @leaderboard.leaders(1, :with_scores => false, :with_rank => false)
|
165
|
+
leaders.size.should be(Leaderboard::DEFAULT_PAGE_SIZE)
|
166
|
+
member_26 = {:member => 'member_26'}
|
167
|
+
member_25 = {:member => 'member_25'}
|
168
|
+
leaders[0].should == member_26
|
169
|
+
leaders[1].should == member_25
|
170
|
+
|
171
|
+
leaders = @leaderboard.leaders(1, :with_rank => false, :page_size => 1)
|
172
|
+
leaders.size.should be(1)
|
173
|
+
member_26 = {:member => 'member_26', :score => 26}
|
174
|
+
leaders[0].should == member_26
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'should return the correct information when calling around_me' do
|
178
|
+
rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE * 3 + 1)
|
179
|
+
|
180
|
+
@leaderboard.total_members.should be(Leaderboard::DEFAULT_PAGE_SIZE * 3 + 1)
|
181
|
+
|
182
|
+
leaders_around_me = @leaderboard.around_me('member_30')
|
183
|
+
(leaders_around_me.size / 2).should be(@leaderboard.page_size / 2)
|
184
|
+
|
185
|
+
leaders_around_me = @leaderboard.around_me('member_1')
|
186
|
+
leaders_around_me.size.should be(@leaderboard.page_size / 2 + 1)
|
187
|
+
|
188
|
+
leaders_around_me = @leaderboard.around_me('member_76')
|
189
|
+
(leaders_around_me.size / 2).should be(@leaderboard.page_size / 2)
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'should return the correct information when calling ranked_in_list' do
|
193
|
+
rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE)
|
194
|
+
|
195
|
+
@leaderboard.total_members.should be(Leaderboard::DEFAULT_PAGE_SIZE)
|
196
|
+
|
197
|
+
members = ['member_1', 'member_5', 'member_10']
|
198
|
+
ranked_members = @leaderboard.ranked_in_list(members, Leaderboard::DEFAULT_LEADERBOARD_REQUEST_OPTIONS)
|
199
|
+
|
200
|
+
ranked_members.size.should be(3)
|
201
|
+
|
202
|
+
ranked_members[0][:rank].should be(25)
|
203
|
+
ranked_members[0][:score].should == 1
|
204
|
+
|
205
|
+
ranked_members[1][:rank].should be(21)
|
206
|
+
ranked_members[1][:score].should == 5
|
207
|
+
|
208
|
+
ranked_members[2][:rank].should be(16)
|
209
|
+
ranked_members[2][:score].should == 10
|
210
|
+
end
|
211
|
+
|
212
|
+
it 'should return the correct information when calling ranked_in_list without scores' do
|
213
|
+
rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE)
|
214
|
+
|
215
|
+
@leaderboard.total_members.should be(Leaderboard::DEFAULT_PAGE_SIZE)
|
216
|
+
|
217
|
+
members = ['member_1', 'member_5', 'member_10']
|
218
|
+
ranked_members = @leaderboard.ranked_in_list(members, {:with_scores => false, :with_rank => true, :use_zero_index_for_rank => false})
|
219
|
+
|
220
|
+
ranked_members.size.should be(3)
|
221
|
+
ranked_members[0][:rank].should be(25)
|
222
|
+
ranked_members[1][:rank].should be(21)
|
223
|
+
ranked_members[2][:rank].should be(16)
|
224
|
+
end
|
225
|
+
|
226
|
+
it 'should allow you to remove members' do
|
227
|
+
rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE)
|
228
|
+
|
229
|
+
@leaderboard.total_members.should be(Leaderboard::DEFAULT_PAGE_SIZE)
|
230
|
+
|
231
|
+
@leaderboard.remove_member('member_1')
|
232
|
+
|
233
|
+
@leaderboard.total_members.should be(Leaderboard::DEFAULT_PAGE_SIZE - 1)
|
234
|
+
@leaderboard.rank_for('member_1').should be_nil
|
235
|
+
end
|
236
|
+
|
237
|
+
it 'should allow you to change the score for a member' do
|
238
|
+
@leaderboard.rank_member('member_1', 5)
|
239
|
+
@leaderboard.score_for('member_1').should == 5
|
240
|
+
|
241
|
+
@leaderboard.change_score_for('member_1', 5)
|
242
|
+
@leaderboard.score_for('member_1').should == 10
|
243
|
+
|
244
|
+
@leaderboard.change_score_for('member_1', -5)
|
245
|
+
@leaderboard.score_for('member_1').should == 5
|
246
|
+
end
|
247
|
+
|
248
|
+
it 'should allow you to check if a member exists' do
|
249
|
+
@leaderboard.rank_member('member_1', 10)
|
250
|
+
|
251
|
+
@leaderboard.check_member?('member_1').should be_true
|
252
|
+
@leaderboard.check_member?('member_2').should be_false
|
253
|
+
end
|
254
|
+
|
255
|
+
it 'should allow you to change the page size and have that reflected in the size of the result set' do
|
256
|
+
rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE)
|
257
|
+
|
258
|
+
@leaderboard.page_size = 5
|
259
|
+
|
260
|
+
@leaderboard.total_pages.should be(5)
|
261
|
+
@leaderboard.leaders(1).size.should be(5)
|
262
|
+
end
|
263
|
+
|
264
|
+
it 'should not allow you to set the page size to an invalid page size' do
|
265
|
+
rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE)
|
266
|
+
|
267
|
+
@leaderboard.page_size = 0
|
268
|
+
@leaderboard.total_pages.should be(1)
|
269
|
+
@leaderboard.leaders(1).size.should be(Leaderboard::DEFAULT_PAGE_SIZE)
|
270
|
+
end
|
271
|
+
|
272
|
+
it 'should return the correct information when calling score_and_rank_for' do
|
273
|
+
rank_members_in_leaderboard
|
274
|
+
|
275
|
+
data = @leaderboard.score_and_rank_for('member_1')
|
276
|
+
data[:member].should == 'member_1'
|
277
|
+
data[:score].should == 1
|
278
|
+
data[:rank].should == 5
|
279
|
+
end
|
280
|
+
|
281
|
+
it 'should allow you to remove members in a given score range' do
|
282
|
+
rank_members_in_leaderboard
|
283
|
+
|
284
|
+
@leaderboard.total_members.should be(5)
|
285
|
+
|
286
|
+
@leaderboard.rank_member('cheater_1', 100)
|
287
|
+
@leaderboard.rank_member('cheater_2', 101)
|
288
|
+
@leaderboard.rank_member('cheater_3', 102)
|
289
|
+
|
290
|
+
@leaderboard.total_members.should be(8)
|
291
|
+
|
292
|
+
@leaderboard.remove_members_in_score_range(100, 102)
|
293
|
+
|
294
|
+
@leaderboard.total_members.should be(5)
|
295
|
+
|
296
|
+
leaders = @leaderboard.leaders(1)
|
297
|
+
leaders.each do |leader|
|
298
|
+
leader[:score].should be < 100
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
it 'should allow you to merge leaderboards' do
|
303
|
+
foo = Leaderboard.new('foo', Leaderboard::DEFAULT_LEADERBOARD_REQUEST_OPTIONS, :host => "127.0.0.1", :db => 15)
|
304
|
+
bar = Leaderboard.new('bar', Leaderboard::DEFAULT_LEADERBOARD_REQUEST_OPTIONS, :host => "127.0.0.1", :db => 15)
|
305
|
+
|
306
|
+
foo.rank_member('foo_1', 1)
|
307
|
+
foo.rank_member('foo_2', 2)
|
308
|
+
bar.rank_member('bar_1', 3)
|
309
|
+
bar.rank_member('bar_2', 4)
|
310
|
+
bar.rank_member('bar_3', 5)
|
311
|
+
|
312
|
+
foobar_keys = foo.merge_leaderboards('foobar', ['bar'])
|
313
|
+
foobar_keys.should be(5)
|
314
|
+
|
315
|
+
foobar = Leaderboard.new('foobar', Leaderboard::DEFAULT_LEADERBOARD_REQUEST_OPTIONS, :host => "127.0.0.1", :db => 15)
|
316
|
+
foobar.total_members.should be(5)
|
317
|
+
|
318
|
+
first_leader_in_foobar = foobar.leaders(1).first
|
319
|
+
first_leader_in_foobar[:rank].should == 1
|
320
|
+
first_leader_in_foobar[:member].should == 'bar_3'
|
321
|
+
first_leader_in_foobar[:score].should == 5
|
322
|
+
|
323
|
+
foo.disconnect
|
324
|
+
bar.disconnect
|
325
|
+
foobar.disconnect
|
326
|
+
end
|
327
|
+
|
328
|
+
it 'should allow you to intersect leaderboards' do
|
329
|
+
foo = Leaderboard.new('foo', Leaderboard::DEFAULT_LEADERBOARD_REQUEST_OPTIONS, :host => "127.0.0.1", :db => 15)
|
330
|
+
bar = Leaderboard.new('bar', Leaderboard::DEFAULT_LEADERBOARD_REQUEST_OPTIONS, :host => "127.0.0.1", :db => 15)
|
331
|
+
|
332
|
+
foo.rank_member('foo_1', 1)
|
333
|
+
foo.rank_member('foo_2', 2)
|
334
|
+
foo.rank_member('bar_3', 6)
|
335
|
+
bar.rank_member('bar_1', 3)
|
336
|
+
bar.rank_member('foo_1', 4)
|
337
|
+
bar.rank_member('bar_3', 5)
|
338
|
+
|
339
|
+
foobar_keys = foo.intersect_leaderboards('foobar', ['bar'], {:aggregate => :max})
|
340
|
+
foobar_keys.should be(2)
|
341
|
+
|
342
|
+
foobar = Leaderboard.new('foobar', Leaderboard::DEFAULT_LEADERBOARD_REQUEST_OPTIONS, :host => "127.0.0.1", :db => 15)
|
343
|
+
foobar.total_members.should be(2)
|
344
|
+
|
345
|
+
first_leader_in_foobar = foobar.leaders(1).first
|
346
|
+
first_leader_in_foobar[:rank].should == 1
|
347
|
+
first_leader_in_foobar[:member].should == 'bar_3'
|
348
|
+
first_leader_in_foobar[:score].should == 6
|
349
|
+
|
350
|
+
foo.disconnect
|
351
|
+
bar.disconnect
|
352
|
+
foobar.disconnect
|
353
|
+
end
|
354
|
+
|
355
|
+
it 'should respect the with_scores option in the massage_leader_data method' do
|
356
|
+
rank_members_in_leaderboard(25)
|
357
|
+
|
358
|
+
@leaderboard.total_members.should be(25)
|
359
|
+
|
360
|
+
leaders = @leaderboard.leaders(1, {:with_scores => false, :with_rank => false})
|
361
|
+
leaders[0][:member].should_not be_nil
|
362
|
+
leaders[0][:score].should be_nil
|
363
|
+
leaders[0][:rank].should be_nil
|
364
|
+
|
365
|
+
@leaderboard.page_size = 25
|
366
|
+
leaders = @leaderboard.leaders(1, {:with_scores => false, :with_rank => false})
|
367
|
+
leaders.size.should be(25)
|
368
|
+
|
369
|
+
@leaderboard.page_size = Leaderboard::DEFAULT_PAGE_SIZE
|
370
|
+
leaders = @leaderboard.leaders(1, Leaderboard::DEFAULT_LEADERBOARD_REQUEST_OPTIONS)
|
371
|
+
leaders[0][:member].should_not be_nil
|
372
|
+
leaders[0][:score].should_not be_nil
|
373
|
+
leaders[0][:rank].should_not be_nil
|
374
|
+
|
375
|
+
@leaderboard.page_size = 25
|
376
|
+
leaders = @leaderboard.leaders(1, Leaderboard::DEFAULT_LEADERBOARD_REQUEST_OPTIONS)
|
377
|
+
leaders.size.should be(25)
|
378
|
+
end
|
379
|
+
|
380
|
+
it 'should return the correct number of pages when calling total_pages_in page size option' do
|
381
|
+
rank_members_in_leaderboard(25)
|
382
|
+
|
383
|
+
@leaderboard.total_pages_in(@leaderboard.leaderboard_name).should be(1)
|
384
|
+
@leaderboard.total_pages_in(@leaderboard.leaderboard_name, 5).should be(5)
|
385
|
+
end
|
386
|
+
|
387
|
+
it 'should return the correct number of members when calling leaders with a page_size option' do
|
388
|
+
rank_members_in_leaderboard(25)
|
389
|
+
|
390
|
+
@leaderboard.leaders(1, Leaderboard::DEFAULT_LEADERBOARD_REQUEST_OPTIONS.merge({:page_size => 5})).size.should be(5)
|
391
|
+
@leaderboard.leaders(1, Leaderboard::DEFAULT_LEADERBOARD_REQUEST_OPTIONS.merge({:page_size => 10})).size.should be(10)
|
392
|
+
@leaderboard.leaders(2, Leaderboard::DEFAULT_LEADERBOARD_REQUEST_OPTIONS.merge({:page_size => 10})).size.should be(10)
|
393
|
+
@leaderboard.leaders(3, Leaderboard::DEFAULT_LEADERBOARD_REQUEST_OPTIONS.merge({:page_size => 10})).size.should be(5)
|
394
|
+
end
|
395
|
+
|
396
|
+
it 'should return the correct number of members when calling around_me with a page_size options' do
|
397
|
+
rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE * 3 + 1)
|
398
|
+
|
399
|
+
leaders_around_me = @leaderboard.around_me('member_30', Leaderboard::DEFAULT_LEADERBOARD_REQUEST_OPTIONS.merge({:page_size => 3}))
|
400
|
+
leaders_around_me.size.should be(3)
|
401
|
+
leaders_around_me[0][:member].should == 'member_31'
|
402
|
+
leaders_around_me[2][:member].should == 'member_29'
|
403
|
+
end
|
404
|
+
|
405
|
+
it 'should return the correct information when calling percentile_for' do
|
406
|
+
rank_members_in_leaderboard(12)
|
407
|
+
|
408
|
+
@leaderboard.percentile_for('member_1').should == 0
|
409
|
+
@leaderboard.percentile_for('member_2').should == 9
|
410
|
+
@leaderboard.percentile_for('member_3').should == 17
|
411
|
+
@leaderboard.percentile_for('member_4').should == 25
|
412
|
+
@leaderboard.percentile_for('member_12').should == 92
|
413
|
+
end
|
414
|
+
|
415
|
+
it 'should not throw an exception when calling around_me with a member not in the leaderboard' do
|
416
|
+
rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE * 3 + 1)
|
417
|
+
|
418
|
+
leaders_around_me = @leaderboard.around_me('jones', Leaderboard::DEFAULT_LEADERBOARD_REQUEST_OPTIONS.merge({:page_size => 3}))
|
419
|
+
leaders_around_me.size.should be(0)
|
420
|
+
end
|
421
|
+
|
422
|
+
it 'should not throw an exception when calling score_and_rank_for with a member not in the leaderboard' do
|
423
|
+
score_and_rank_for_member = @leaderboard.score_and_rank_for('jones')
|
424
|
+
|
425
|
+
score_and_rank_for_member[:member].should == 'jones'
|
426
|
+
score_and_rank_for_member[:score].should == 0.0
|
427
|
+
score_and_rank_for_member[:rank].should be_nil
|
428
|
+
end
|
429
|
+
|
430
|
+
it 'should not throw an exception when calling ranked_in_list with a member not in the leaderboard' do
|
431
|
+
rank_members_in_leaderboard
|
432
|
+
|
433
|
+
members = ['member_1', 'member_5', 'jones']
|
434
|
+
ranked_members = @leaderboard.ranked_in_list(members)
|
435
|
+
|
436
|
+
ranked_members.size.should be(3)
|
437
|
+
ranked_members[2][:rank].should be_nil
|
438
|
+
end
|
439
|
+
|
440
|
+
it 'should not throw an exception when calling percentile_for with a member not in the leaderboard' do
|
441
|
+
percentile = @leaderboard.percentile_for('jones')
|
442
|
+
|
443
|
+
percentile.should be_nil
|
444
|
+
end
|
445
|
+
|
446
|
+
it 'should allow you to change the score for a member not in the leaderboard' do
|
447
|
+
@leaderboard.score_for('jones').should == 0.0
|
448
|
+
@leaderboard.change_score_for('jones', 5)
|
449
|
+
@leaderboard.score_for('jones').should == 5.0
|
450
|
+
end
|
451
|
+
|
452
|
+
it 'should return the correct page when calling page_for a given member in the leaderboard' do
|
453
|
+
@leaderboard.page_for('jones').should be(0)
|
454
|
+
|
455
|
+
rank_members_in_leaderboard(20)
|
456
|
+
|
457
|
+
@leaderboard.page_for('member_17').should be(1)
|
458
|
+
@leaderboard.page_for('member_11').should be(1)
|
459
|
+
@leaderboard.page_for('member_10').should be(1)
|
460
|
+
@leaderboard.page_for('member_1').should be(1)
|
461
|
+
|
462
|
+
@leaderboard.page_for('member_17', 10).should be(1)
|
463
|
+
@leaderboard.page_for('member_11', 10).should be(1)
|
464
|
+
@leaderboard.page_for('member_10', 10).should be(2)
|
465
|
+
@leaderboard.page_for('member_1', 10).should be(2)
|
466
|
+
end
|
467
|
+
|
468
|
+
it 'should allow you to rank multiple members with a variable number of arguments' do
|
469
|
+
@leaderboard.total_members.should be(0)
|
470
|
+
@leaderboard.rank_members('member_1', 1, 'member_10', 10)
|
471
|
+
@leaderboard.total_members.should be(2)
|
472
|
+
@leaderboard.leaders(1).first[:member].should == 'member_10'
|
473
|
+
end
|
474
|
+
|
475
|
+
it 'should allow you to rank multiple members with an array' do
|
476
|
+
@leaderboard.total_members.should be(0)
|
477
|
+
@leaderboard.rank_members(['member_1', 1, 'member_10', 10])
|
478
|
+
@leaderboard.total_members.should be(2)
|
479
|
+
@leaderboard.leaders(1).first[:member].should == 'member_10'
|
480
|
+
end
|
481
|
+
|
482
|
+
it 'should allow you to set reverse after creating a leaderboard to see results in highest-to-lowest or lowest-to-highest order' do
|
483
|
+
rank_members_in_leaderboard(25)
|
484
|
+
|
485
|
+
leaders = @leaderboard.leaders(1)
|
486
|
+
|
487
|
+
leaders.size.should be(25)
|
488
|
+
leaders[0][:member].should == 'member_25'
|
489
|
+
leaders[-2][:member].should == 'member_2'
|
490
|
+
leaders[-1][:member].should == 'member_1'
|
491
|
+
leaders[-1][:score].to_i.should be(1)
|
492
|
+
|
493
|
+
@leaderboard.reverse = true
|
494
|
+
|
495
|
+
leaders = @leaderboard.leaders(1)
|
496
|
+
|
497
|
+
leaders.size.should be(25)
|
498
|
+
leaders[0][:member].should == 'member_1'
|
499
|
+
leaders[-2][:member].should == 'member_24'
|
500
|
+
leaders[-1][:member].should == 'member_25'
|
501
|
+
leaders[-1][:score].to_i.should be(25)
|
502
|
+
end
|
503
|
+
end
|