leaderboard 3.8.0 → 3.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.markdown +5 -0
- data/README.markdown +6 -4
- data/lib/leaderboard.rb +27 -3
- data/lib/leaderboard/version.rb +1 -1
- data/spec/competition_ranking_leaderboard_spec.rb +44 -1
- data/spec/leaderboard_spec.rb +49 -1
- data/spec/reverse_leaderboard_spec.rb +43 -1
- data/spec/tie_ranking_leaderboard_spec.rb +64 -1
- data/spec/version_spec.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7f50c3a3b7020a18f0f1748f97bfd562958d13ea
|
4
|
+
data.tar.gz: 3f322fef803e8b098265f4282c2131c93ca75507
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1060d4cc1804f92ca1005bc39e7ecab287faa29e6a926fad090f6403f666b68cde60152d5c93608715484b1094f8608fc15b6798cec0dbe7f926782475de1f23
|
7
|
+
data.tar.gz: 0eca6086b8c7db70f505d933749173c3dc91399c23fe1ee91920f8e7d3b380c2506761d7195af6b84aaecd4d11091fa6ce91d93364cd427f8d3eed43be67c7d7
|
data/CHANGELOG.markdown
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## 3.9.0 (2015-02-15)
|
4
|
+
|
5
|
+
* Add `global_member_data` option that allows multiple leaderboards to share the same set of member_data. [#51](https://github.com/agoragames/leaderboard/pull/51)
|
6
|
+
* Add `top` helper method. [#50](https://github.com/agoragames/leaderboard/pull/50).
|
7
|
+
|
3
8
|
## 3.8.0 (2014-11-07)
|
4
9
|
|
5
10
|
* Add support for `change_score_for(...)` in the `TieRankingLeaderboard` class.
|
data/README.markdown
CHANGED
@@ -52,13 +52,14 @@ DEFAULT_OPTIONS = {
|
|
52
52
|
:rank_key => :rank,
|
53
53
|
:score_key => :score,
|
54
54
|
:member_data_key => :member_data,
|
55
|
-
:member_data_namespace => 'member_data'
|
55
|
+
:member_data_namespace => 'member_data',
|
56
|
+
:global_member_data => false
|
56
57
|
}
|
57
58
|
```
|
58
59
|
|
59
60
|
The `DEFAULT_PAGE_SIZE` is 25.
|
60
61
|
|
61
|
-
You would use the option, `:reverse => true`, if you wanted a leaderboard sorted from lowest-to-highest score. You may also set the `reverse` option on a leaderboard after you have created a new instance of a leaderboard. The various `..._key` options above control what data is returned in the hash of leaderboard data from calls such as `leaders` or `around_me`.
|
62
|
+
You would use the option, `:reverse => true`, if you wanted a leaderboard sorted from lowest-to-highest score. You may also set the `reverse` option on a leaderboard after you have created a new instance of a leaderboard. The various `..._key` options above control what data is returned in the hash of leaderboard data from calls such as `leaders` or `around_me`. Finally, the `global_member_data` option allows you to control whether optional member data is per-leaderboard (`false`) or global (`true`).
|
62
63
|
|
63
64
|
If you need to pass in options for Redis, you can do this in the initializer:
|
64
65
|
|
@@ -131,7 +132,7 @@ encode a Hash of member data. Example:
|
|
131
132
|
|
132
133
|
```ruby
|
133
134
|
require 'json'
|
134
|
-
highscore_lb.rank_member('84849292', 1,
|
135
|
+
highscore_lb.rank_member('84849292', 1, {'username' => 'member_name'}.to_json)
|
135
136
|
```
|
136
137
|
|
137
138
|
You can retrieve, update and remove the optional member data using the
|
@@ -141,7 +142,7 @@ You can retrieve, update and remove the optional member data using the
|
|
141
142
|
JSON.parse(highscore_lb.member_data_for('84849292'))
|
142
143
|
=> {"username"=>"member_name"}
|
143
144
|
|
144
|
-
highscore_lb.update_member_data('84849292',
|
145
|
+
highscore_lb.update_member_data('84849292', {'last_updated' => Time.now, 'username' => 'updated_member_name'}.to_json)
|
145
146
|
=> "OK"
|
146
147
|
JSON.parse(highscore_lb.member_data_for('84849292'))
|
147
148
|
=> {"username"=>"updated_member_name", "last_updated"=>"2012-06-09 09:11:06 -0400"}
|
@@ -360,6 +361,7 @@ Competition ranking: The `CompetitionRankingLeaderboard` subclass of `Leaderboar
|
|
360
361
|
rank_members(members_and_scores): Rank an array of members in the leaderboard where you can call via (member_name, score) or pass in an array of [member_name, score]
|
361
362
|
merge_leaderboards(destination, keys, options = {:aggregate => :min}): Merge leaderboards given by keys with this leaderboard into destination
|
362
363
|
intersect_leaderboards(destination, keys, options = {:aggregate => :min}): Intersect leaderboards given by keys with this leaderboard into destination
|
364
|
+
top(number, options): Retrieve members from the leaderboard within a range from 1 to the number given.
|
363
365
|
```
|
364
366
|
|
365
367
|
Check the [online documentation](http://rubydoc.info/gems/leaderboard/frames) for more detail on each method.
|
data/lib/leaderboard.rb
CHANGED
@@ -15,7 +15,8 @@ class Leaderboard
|
|
15
15
|
:rank_key => :rank,
|
16
16
|
:score_key => :score,
|
17
17
|
:member_data_key => :member_data,
|
18
|
-
:member_data_namespace => 'member_data'
|
18
|
+
:member_data_namespace => 'member_data',
|
19
|
+
:global_member_data => false
|
19
20
|
}
|
20
21
|
|
21
22
|
# Default Redis host: localhost
|
@@ -80,6 +81,7 @@ class Leaderboard
|
|
80
81
|
@score_key = leaderboard_options[:score_key]
|
81
82
|
@member_data_key = leaderboard_options[:member_data_key]
|
82
83
|
@member_data_namespace = leaderboard_options[:member_data_namespace]
|
84
|
+
@global_member_data = leaderboard_options[:global_member_data]
|
83
85
|
|
84
86
|
@redis_connection = redis_options[:redis_connection]
|
85
87
|
unless @redis_connection.nil?
|
@@ -812,6 +814,28 @@ class Leaderboard
|
|
812
814
|
end
|
813
815
|
end
|
814
816
|
|
817
|
+
# Retrieve members from the leaderboard within a range from 1 to the number given.
|
818
|
+
#
|
819
|
+
# @param ending_rank [int] Ending rank (inclusive).
|
820
|
+
# @param options [Hash] Options to be used when retrieving the data from the leaderboard.
|
821
|
+
#
|
822
|
+
# @return number from the leaderboard that fall within the given rank range.
|
823
|
+
def top(number, options = {})
|
824
|
+
top_in(@leaderboard_name, number, options)
|
825
|
+
end
|
826
|
+
|
827
|
+
# Retrieve members from the named leaderboard within a range from 1 to the number given.
|
828
|
+
#
|
829
|
+
# @param leaderboard_name [String] Name of the leaderboard.
|
830
|
+
# @param starting_rank [int] Starting rank (inclusive).
|
831
|
+
# @param ending_rank [int] Ending rank (inclusive).
|
832
|
+
# @param options [Hash] Options to be used when retrieving the data from the leaderboard.
|
833
|
+
#
|
834
|
+
# @return members from the leaderboard that fall within the given rank range.
|
835
|
+
def top_in(leaderboard_name, number, options={})
|
836
|
+
members_from_rank_range_in(leaderboard_name, 1, number, options)
|
837
|
+
end
|
838
|
+
|
815
839
|
# Retrieve a member at the specified index from the leaderboard.
|
816
840
|
#
|
817
841
|
# @param position [int] Position in leaderboard.
|
@@ -974,7 +998,7 @@ class Leaderboard
|
|
974
998
|
#
|
975
999
|
# @return a key in the form of +leaderboard_name:member_data+
|
976
1000
|
def member_data_key(leaderboard_name)
|
977
|
-
"#{leaderboard_name}:#{@member_data_namespace}"
|
1001
|
+
@global_member_data == false ? "#{leaderboard_name}:#{@member_data_namespace}" : @member_data_namespace
|
978
1002
|
end
|
979
1003
|
|
980
1004
|
# Validate and return the page size. Returns the +DEFAULT_PAGE_SIZE+ if the page size is less than 1.
|
@@ -989,4 +1013,4 @@ class Leaderboard
|
|
989
1013
|
|
990
1014
|
page_size
|
991
1015
|
end
|
992
|
-
end
|
1016
|
+
end
|
data/lib/leaderboard/version.rb
CHANGED
@@ -123,5 +123,48 @@ describe 'CompetitionRankingLeaderboard' do
|
|
123
123
|
|
124
124
|
leaderboard.disconnect
|
125
125
|
end
|
126
|
+
|
127
|
+
it 'should allow you to retrieve a given set of members from the leaderboard in a range from 1 to the number given' do
|
128
|
+
@leaderboard = CompetitionRankingLeaderboard.new('ties', Leaderboard::DEFAULT_OPTIONS, {:host => "127.0.0.1", :db => 15})
|
129
|
+
rank_members_in_leaderboard(25)
|
130
|
+
|
131
|
+
members = @leaderboard.top(5)
|
132
|
+
expect(members.size).to be(5)
|
133
|
+
expect(members[0][:member]).to eql('member_25')
|
134
|
+
expect(members[0][:score].to_i).to be(25)
|
135
|
+
expect(members[4][:member]).to eql('member_21')
|
136
|
+
|
137
|
+
members = @leaderboard.top(1)
|
138
|
+
expect(members.size).to be(1)
|
139
|
+
expect(members[0][:member]).to eql('member_25')
|
140
|
+
|
141
|
+
members = @leaderboard.top(26)
|
142
|
+
expect(members.size).to be(25)
|
143
|
+
expect(members[0][:member]).to eql('member_25')
|
144
|
+
expect(members[0][:score].to_i).to be(25)
|
145
|
+
expect(members[24][:member]).to eql('member_1')
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'should allow you to retrieve a given set of members from the named leaderboard in a range from 1 to the number given' do
|
149
|
+
@leaderboard = CompetitionRankingLeaderboard.new('ties', Leaderboard::DEFAULT_OPTIONS, {:host => "127.0.0.1", :db => 15})
|
150
|
+
rank_members_in_leaderboard(25)
|
151
|
+
|
152
|
+
members = @leaderboard.top_in("ties", 5)
|
153
|
+
expect(members.size).to be(5)
|
154
|
+
expect(members[0][:member]).to eql('member_25')
|
155
|
+
expect(members[0][:score].to_i).to be(25)
|
156
|
+
expect(members[4][:member]).to eql('member_21')
|
157
|
+
|
158
|
+
members = @leaderboard.top(1)
|
159
|
+
expect(members.size).to be(1)
|
160
|
+
expect(members[0][:member]).to eql('member_25')
|
161
|
+
|
162
|
+
members = @leaderboard.top(26)
|
163
|
+
expect(members.size).to be(25)
|
164
|
+
expect(members[0][:member]).to eql('member_25')
|
165
|
+
expect(members[0][:score].to_i).to be(25)
|
166
|
+
expect(members[24][:member]).to eql('member_1')
|
167
|
+
end
|
168
|
+
|
126
169
|
end
|
127
|
-
end
|
170
|
+
end
|
data/spec/leaderboard_spec.rb
CHANGED
@@ -626,6 +626,46 @@ describe 'Leaderboard' do
|
|
626
626
|
expect(members[24][:member]).to eql('member_1')
|
627
627
|
end
|
628
628
|
|
629
|
+
it 'should allow you to retrieve a given set of members from the leaderboard in a range from 1 to the number given' do
|
630
|
+
rank_members_in_leaderboard(25)
|
631
|
+
|
632
|
+
members = @leaderboard.top(5)
|
633
|
+
expect(members.size).to be(5)
|
634
|
+
expect(members[0][:member]).to eql('member_25')
|
635
|
+
expect(members[0][:score].to_i).to be(25)
|
636
|
+
expect(members[4][:member]).to eql('member_21')
|
637
|
+
|
638
|
+
members = @leaderboard.top(1)
|
639
|
+
expect(members.size).to be(1)
|
640
|
+
expect(members[0][:member]).to eql('member_25')
|
641
|
+
|
642
|
+
members = @leaderboard.top(26)
|
643
|
+
expect(members.size).to be(25)
|
644
|
+
expect(members[0][:member]).to eql('member_25')
|
645
|
+
expect(members[0][:score].to_i).to be(25)
|
646
|
+
expect(members[24][:member]).to eql('member_1')
|
647
|
+
end
|
648
|
+
|
649
|
+
it 'should allow you to retrieve a given set of members from the named leaderboard in a range from 1 to the number given' do
|
650
|
+
rank_members_in_leaderboard(25)
|
651
|
+
|
652
|
+
members = @leaderboard.top_in("name", 5)
|
653
|
+
expect(members.size).to be(5)
|
654
|
+
expect(members[0][:member]).to eql('member_25')
|
655
|
+
expect(members[0][:score].to_i).to be(25)
|
656
|
+
expect(members[4][:member]).to eql('member_21')
|
657
|
+
|
658
|
+
members = @leaderboard.top(1)
|
659
|
+
expect(members.size).to be(1)
|
660
|
+
expect(members[0][:member]).to eql('member_25')
|
661
|
+
|
662
|
+
members = @leaderboard.top(26)
|
663
|
+
expect(members.size).to be(25)
|
664
|
+
expect(members[0][:member]).to eql('member_25')
|
665
|
+
expect(members[0][:score].to_i).to be(25)
|
666
|
+
expect(members[24][:member]).to eql('member_1')
|
667
|
+
end
|
668
|
+
|
629
669
|
it 'should sort by rank if the :sort_by option is set to :rank' do
|
630
670
|
rank_members_in_leaderboard(25)
|
631
671
|
|
@@ -767,4 +807,12 @@ describe 'Leaderboard' do
|
|
767
807
|
expect(@redis_connection.exists("name:member_data")).to be_falsey
|
768
808
|
expect(@redis_connection.exists("name:md")).to be_truthy
|
769
809
|
end
|
770
|
-
|
810
|
+
|
811
|
+
it 'should allow you to have a global member data namespace' do
|
812
|
+
@leaderboard = Leaderboard.new('name', {:global_member_data => true}, {:host => "127.0.0.1", :db => 15})
|
813
|
+
rank_members_in_leaderboard
|
814
|
+
|
815
|
+
expect(@redis_connection.exists("member_data")).to be_truthy
|
816
|
+
expect(@redis_connection.exists("name:member_data")).to be_falsey
|
817
|
+
end
|
818
|
+
end
|
@@ -335,6 +335,48 @@ describe 'Leaderboard (reverse option)' do
|
|
335
335
|
expect(members[24][:member]).to eql('member_25')
|
336
336
|
end
|
337
337
|
|
338
|
+
it 'should allow you to retrieve a given set of members from the leaderboard in a range from 1 to the number given' do
|
339
|
+
rank_members_in_leaderboard(25)
|
340
|
+
|
341
|
+
members = @leaderboard.top(5)
|
342
|
+
expect(members.size).to be(5)
|
343
|
+
expect(members[0][:member]).to eql('member_1')
|
344
|
+
expect(members[0][:score].to_i).to be(1)
|
345
|
+
expect(members[4][:member]).to eql('member_5')
|
346
|
+
|
347
|
+
members = @leaderboard.top(1)
|
348
|
+
expect(members.size).to be(1)
|
349
|
+
expect(members[0][:member]).to eql('member_1')
|
350
|
+
|
351
|
+
members = @leaderboard.top(26)
|
352
|
+
expect(members.size).to be(25)
|
353
|
+
expect(members[0][:member]).to eql('member_1')
|
354
|
+
expect(members[0][:score].to_i).to be(1)
|
355
|
+
expect(members[24][:member]).to eql('member_25')
|
356
|
+
end
|
357
|
+
|
358
|
+
it 'should allow you to retrieve a given set of members from the named leaderboard in a range from 1 to the number given' do
|
359
|
+
rank_members_in_leaderboard(25)
|
360
|
+
|
361
|
+
members = @leaderboard.top_in("name", 5)
|
362
|
+
expect(members.size).to be(5)
|
363
|
+
expect(members[0][:member]).to eql('member_1')
|
364
|
+
expect(members[0][:score].to_i).to be(1)
|
365
|
+
expect(members[4][:member]).to eql('member_5')
|
366
|
+
|
367
|
+
members = @leaderboard.top(1)
|
368
|
+
expect(members.size).to be(1)
|
369
|
+
expect(members[0][:member]).to eql('member_1')
|
370
|
+
|
371
|
+
members = @leaderboard.top(26)
|
372
|
+
expect(members.size).to be(25)
|
373
|
+
expect(members[0][:member]).to eql('member_1')
|
374
|
+
expect(members[0][:score].to_i).to be(1)
|
375
|
+
expect(members[24][:member]).to eql('member_25')
|
376
|
+
end
|
377
|
+
|
378
|
+
|
379
|
+
|
338
380
|
it 'should sort by rank if the :sort_by option is set to :rank' do
|
339
381
|
rank_members_in_leaderboard(25)
|
340
382
|
|
@@ -370,4 +412,4 @@ describe 'Leaderboard (reverse option)' do
|
|
370
412
|
expect(ranked_members[2][:rank]).to be(10)
|
371
413
|
expect(ranked_members[2][:score]).to eql(10.0)
|
372
414
|
end
|
373
|
-
end
|
415
|
+
end
|
@@ -197,6 +197,69 @@ describe 'TieRankingLeaderboard' do
|
|
197
197
|
end
|
198
198
|
end
|
199
199
|
|
200
|
+
it 'should allow you to retrieve a given set of members from the leaderboard in a rank range' do
|
201
|
+
@leaderboard = TieRankingLeaderboard.new('ties', Leaderboard::DEFAULT_OPTIONS, {:host => "127.0.0.1", :db => 15})
|
202
|
+
rank_members_in_leaderboard(25)
|
203
|
+
|
204
|
+
members = @leaderboard.members_from_rank_range(5, 9)
|
205
|
+
expect(members.size).to be(5)
|
206
|
+
expect(members[0][:member]).to eql('member_21')
|
207
|
+
expect(members[0][:score].to_i).to be(21)
|
208
|
+
expect(members[4][:member]).to eql('member_17')
|
209
|
+
|
210
|
+
members = @leaderboard.members_from_rank_range(1, 1)
|
211
|
+
expect(members.size).to be(1)
|
212
|
+
expect(members[0][:member]).to eql('member_25')
|
213
|
+
|
214
|
+
members = @leaderboard.members_from_rank_range(-1, 26)
|
215
|
+
expect(members.size).to be(25)
|
216
|
+
expect(members[0][:member]).to eql('member_25')
|
217
|
+
expect(members[0][:score].to_i).to be(25)
|
218
|
+
expect(members[24][:member]).to eql('member_1')
|
219
|
+
end
|
220
|
+
|
221
|
+
it 'should allow you to retrieve a given set of members from the leaderboard in a range from 1 to the number given' do
|
222
|
+
@leaderboard = TieRankingLeaderboard.new('ties', Leaderboard::DEFAULT_OPTIONS, {:host => "127.0.0.1", :db => 15})
|
223
|
+
rank_members_in_leaderboard(25)
|
224
|
+
|
225
|
+
members = @leaderboard.top(5)
|
226
|
+
expect(members.size).to be(5)
|
227
|
+
expect(members[0][:member]).to eql('member_25')
|
228
|
+
expect(members[0][:score].to_i).to be(25)
|
229
|
+
expect(members[4][:member]).to eql('member_21')
|
230
|
+
|
231
|
+
members = @leaderboard.top(1)
|
232
|
+
expect(members.size).to be(1)
|
233
|
+
expect(members[0][:member]).to eql('member_25')
|
234
|
+
|
235
|
+
members = @leaderboard.top(26)
|
236
|
+
expect(members.size).to be(25)
|
237
|
+
expect(members[0][:member]).to eql('member_25')
|
238
|
+
expect(members[0][:score].to_i).to be(25)
|
239
|
+
expect(members[24][:member]).to eql('member_1')
|
240
|
+
end
|
241
|
+
|
242
|
+
it 'should allow you to retrieve a given set of members from the named leaderboard in a range from 1 to the number given' do
|
243
|
+
@leaderboard = TieRankingLeaderboard.new('name', Leaderboard::DEFAULT_OPTIONS, {:host => "127.0.0.1", :db => 15})
|
244
|
+
rank_members_in_leaderboard(25)
|
245
|
+
|
246
|
+
members = @leaderboard.top_in("name", 5)
|
247
|
+
expect(members.size).to be(5)
|
248
|
+
expect(members[0][:member]).to eql('member_25')
|
249
|
+
expect(members[0][:score].to_i).to be(25)
|
250
|
+
expect(members[4][:member]).to eql('member_21')
|
251
|
+
|
252
|
+
members = @leaderboard.top(1)
|
253
|
+
expect(members.size).to be(1)
|
254
|
+
expect(members[0][:member]).to eql('member_25')
|
255
|
+
|
256
|
+
members = @leaderboard.top(26)
|
257
|
+
expect(members.size).to be(25)
|
258
|
+
expect(members[0][:member]).to eql('member_25')
|
259
|
+
expect(members[0][:score].to_i).to be(25)
|
260
|
+
expect(members[24][:member]).to eql('member_1')
|
261
|
+
end
|
262
|
+
|
200
263
|
it 'should expire the ties leaderboard in a given number of seconds' do
|
201
264
|
@leaderboard = TieRankingLeaderboard.new('ties', Leaderboard::DEFAULT_OPTIONS, {:host => "127.0.0.1", :db => 15})
|
202
265
|
|
@@ -238,4 +301,4 @@ describe 'TieRankingLeaderboard' do
|
|
238
301
|
end
|
239
302
|
end
|
240
303
|
end
|
241
|
-
end
|
304
|
+
end
|
data/spec/version_spec.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: leaderboard
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Czarnecki
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-02-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|