leaderboard 3.8.0 → 3.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7bde8fa5f70279295659c4d1d2eff551c105ccf8
4
- data.tar.gz: 0de720bc5a777acb6c568ebcd5a62d99490b799f
3
+ metadata.gz: 7f50c3a3b7020a18f0f1748f97bfd562958d13ea
4
+ data.tar.gz: 3f322fef803e8b098265f4282c2131c93ca75507
5
5
  SHA512:
6
- metadata.gz: 237db7f422c2df67dc63040304a49efc806ce716e4976d5f2b68c36c70c6fa42b9fdd349237376a998430fd9ccd5faed03c0bd2ba075a1650dcb34f0aa153d66
7
- data.tar.gz: 26c645596ea59bc82c738e16d1c8313b2c87753ccc1936dff64d4a2a70277683eac8e5479844467815a7d68824432736e95ebbdf7960aadb8846ac39d012a6bf
6
+ metadata.gz: 1060d4cc1804f92ca1005bc39e7ecab287faa29e6a926fad090f6403f666b68cde60152d5c93608715484b1094f8608fc15b6798cec0dbe7f926782475de1f23
7
+ data.tar.gz: 0eca6086b8c7db70f505d933749173c3dc91399c23fe1ee91920f8e7d3b380c2506761d7195af6b84aaecd4d11091fa6ce91d93364cd427f8d3eed43be67c7d7
@@ -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.
@@ -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, JSON.generate({'username' => 'member_name'}))
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', JSON.generate({'last_updated' => Time.now, 'username' => 'updated_member_name'}))
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.
@@ -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
@@ -1,3 +1,3 @@
1
1
  class Leaderboard
2
- VERSION = '3.8.0'.freeze
2
+ VERSION = '3.9.0'.freeze
3
3
  end
@@ -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
@@ -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
- end
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
@@ -2,6 +2,6 @@ require 'spec_helper'
2
2
 
3
3
  describe 'Leaderboard::VERSION' do
4
4
  it 'should be the correct version' do
5
- expect(Leaderboard::VERSION).to eq('3.8.0')
5
+ expect(Leaderboard::VERSION).to eq('3.9.0')
6
6
  end
7
7
  end
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.8.0
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: 2014-11-08 00:00:00.000000000 Z
11
+ date: 2015-02-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis