leaderboard_factory 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format nested
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm --create 1.9.3@leaderboard_factory_gem
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ # CHANGELOG
2
+
3
+ ## leaderboard_factory 0.0.1 (2012-08-03)
4
+
5
+ * initial extraction from project.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Matt Wilson
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,81 @@
1
+ # LeaderboardFactory
2
+
3
+ Helpful tools for defining a bunch of leaderboards associated with your objects. Builds on the [leaderboard](https://github.com/agoragames/leaderboard) gem.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'leaderboard_factory'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install leaderboard_factory
18
+
19
+ You'll need to tell it how to find Redis. Configure this on the module:
20
+
21
+ ```ruby
22
+ LeaderboardFactory.redis = Redis.new
23
+ # or
24
+ LeaderboardFactory.configure do |c|
25
+ c.redis = Redis.new(db: 15)
26
+ end
27
+ ```
28
+
29
+ ## Usage
30
+
31
+ Let's start with an example:
32
+
33
+ ```ruby
34
+ class Player
35
+ include LeaderboardFactory
36
+
37
+ attr_accessor :id
38
+
39
+ leaderboard 'game_duration', :id
40
+ leaderboard 'maps_by_wins', :id
41
+ collection_leaderboard 'best_finishes', { reverse: true }
42
+ end
43
+ ```
44
+
45
+ What we've done here is define two leaderboards that are scoped to a player's ID, and one that applies to the entire collection of players. This latter one also ranks things in reverse order--there are two optional parameters to both methods, both hashes, and both are simply passed along to the leaderboard gem. The first is the leaderboard options, the second any specific redis options--if you need to pass along something specific for, say, a leaderboard in a different Redis instance. Check out the [leaderboard](https://github.com/agoragames/leaderboard) gem documentation for more details.
46
+
47
+ Let's look at how to use these.
48
+
49
+ ```ruby
50
+ p = Player.new
51
+ p.id = 1234
52
+
53
+ p.game_duration # => <Leaderboard @leaderboard_name="game-duration-1234">
54
+ game_id = 1234
55
+ game_duration = 2345
56
+ p.rank_game_duration game_id, game_duration # => ["OK"]
57
+ p.game_duration.all_members # => [...]
58
+
59
+ Player.best_finishes # => <Leaderboard @leaderboard_name="best-finishes">
60
+ Player.rank_best_finishes p.id, 3, { player_name: "Bob" } # => ["OK", true]
61
+ Player.best_finishes.all_members(with_member_data: true) # etc etc
62
+ ```
63
+
64
+ As you can see, we have a handy accessor that returns our leaderboard, and we even have a handy shortcut to add (*rank* in leaderboard parlance) new items to the board.
65
+
66
+ You can examine the options for any defined leaderboard via `Player.leaderboard_specs`.
67
+
68
+ There is a nascent and evolving set of helpers that you can access via `Player.leaderboards`--check out the helpers.rb file for more details there. These helpers will probably change.
69
+
70
+
71
+ ## Contributing
72
+
73
+ 1. Fork it
74
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
75
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
76
+ 4. Push to the branch (`git push origin my-new-feature`)
77
+ 5. Create new Pull Request
78
+
79
+ ## Copyright
80
+
81
+ Copyright (c) 2012 Matt Wilson. See LICENSE for further details.
data/Rakefile ADDED
@@ -0,0 +1,12 @@
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
+ end
11
+
12
+ task default: :spec
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require 'leaderboard_factory/version'
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.authors = ["Matt Wilson"]
7
+ gem.email = ["mwilson@majorleaguegaming.com"]
8
+ gem.description = %q{Helps you define and work with a bunch of leaderboards, from, e.g. an ActiveModel object}
9
+ gem.summary = %q{Helps you define and work with a bunch of leaderboards, from, e.g. an ActiveModel object}
10
+ gem.homepage = "https://github.com/agoragames/leaderboard_factory"
11
+
12
+ gem.files = `git ls-files`.split($\)
13
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
14
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
15
+ gem.name = "leaderboard_factory"
16
+ gem.require_paths = ["lib"]
17
+ gem.version = LeaderboardFactory::VERSION
18
+
19
+ gem.add_dependency('leaderboard')
20
+ gem.add_dependency('active_support')
21
+ gem.add_development_dependency('rake')
22
+ gem.add_development_dependency('rspec')
23
+ end
@@ -0,0 +1,13 @@
1
+ module LeaderboardFactory
2
+ module Configuration
3
+ # Redis instance
4
+ attr_accessor :redis
5
+
6
+ # yield self for block-style config
7
+ #
8
+ # LeaderboardFactory.configure { |c| c.redis = Redis.new(db: 15) }
9
+ def configure
10
+ yield self
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,21 @@
1
+ require 'leaderboard_factory/helpers'
2
+
3
+ module LeaderboardFactory
4
+ class HelperProxy
5
+ include LeaderboardFactory::Helpers
6
+
7
+ attr_accessor :context
8
+
9
+ def initialize context
10
+ self.context = context
11
+ end
12
+
13
+ end
14
+
15
+ module HelperProxyMethods
16
+ # Returns a contextualized helper instance so that one can use the helpers.
17
+ def leaderboards
18
+ HelperProxy.new(self)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,85 @@
1
+ module LeaderboardFactory
2
+ # This system is in the most flux. These are some helpers that I found very, ahem, *helpful*.
3
+ # I'm just not sure I'm sold on the API, and I know that there will be more.
4
+ module Helpers
5
+ def board_name name, key = nil
6
+ name = name.gsub('_', '-')
7
+ name += "-#{context.send(key)}" if key
8
+ name
9
+ end
10
+
11
+ # Takes the top item off of the pivot and optionally passes the result through a callable mapper.
12
+ #
13
+ # @param leaderboard [Symbol] the name of the leaderboard
14
+ # @param options [Hash] +:mapper+ is the only unique option, other per +#pivot+
15
+ #
16
+ # Example
17
+ #
18
+ # leaderboards.top(:personal_bests) # => [16.0, ['Event ID 1', 'Event ID 3']]
19
+ # leaderboards.top(:personal_bests, mapper: Proc.new do |score, bests|
20
+ # { high_score: score.to_i, tied: bests.size, best_events: bests }
21
+ # end) # => { high_score: 16, tied: 2, best_events: ['Event ID 1', 'Event ID 3'] }
22
+ def top leaderboard, options = {}
23
+ result = pivot(leaderboard, options).first
24
+ if options[:mapper]
25
+ options[:mapper].call(*result)
26
+ else
27
+ result
28
+ end
29
+ end
30
+
31
+ # Take the leaderboard and pivot the data by the score.
32
+ # By default it will group the members by their score.
33
+ #
34
+ # @param leaderboard [Symbol] the name of the leaderboard you want to pivot
35
+ # @param options [Hash] (optional) tweak the output
36
+ #
37
+ # Available options
38
+ #
39
+ # +:member_data+ whether or not to include member data
40
+ # +:score+ a callable object that will transform the score
41
+ # +:pluck+ the name of a +member_data+ attribute. If you don't want all of the data.
42
+ #
43
+ # Examples
44
+ #
45
+ # leaderboards.pivot(:personal_bests) # => { 16.0 => ['Event ID 1', 'Event ID 3'], 14.2 => ['Event ID 2'] }
46
+ # leaderboards.pivot(:personal_bests, member_data: true)
47
+ # # => { 16.0 => [{ 'event_name' => 'My Event Name', 'timestamp' => '12323425' },
48
+ # { 'event_name' => 'My Third Attempt', 'timestamp' => '12323488' } ], ...
49
+ # leaderboards.pivot(:personal_bests, member_data: true, pluck: 'event_name')
50
+ # # => { 16.0 => ['My Event Name', 'My Third Attempt'], 14.2 => ['Followup'] }
51
+ # leaderboards.pivot(:personal_bests, score: Proc.new { |s| s.to_i })
52
+ # # => { 16 => ['Event ID 1', 'Event ID 3'], 14 => ['Event ID 2'] }
53
+ def pivot leaderboard, options
54
+ lb_options = {}
55
+ if options[:member_data]
56
+ lb_options.merge!(with_member_data: true)
57
+ end
58
+ context.send(leaderboard).all_members(lb_options).inject({}) do |buf, member|
59
+ key = options[:score] ? options[:score].call(member[:score]) : member[:score]
60
+ buf[key] ||= []
61
+ item = if options[:pluck]
62
+ member[:member_data][options[:pluck]]
63
+ elsif options[:member_data]
64
+ member[:member_data]
65
+ else
66
+ member[:member]
67
+ end
68
+ buf[key] << item
69
+ buf
70
+ end
71
+ end
72
+
73
+ # returns the given leaderboard
74
+ #
75
+ # @param leaderboard [Symbol] the name of the leaderboard you want
76
+ #
77
+ # Example
78
+ #
79
+ # leaderboards.get(:personal_bests) # => Leaderboard
80
+ def get leaderboard
81
+ context.send(leaderboard)
82
+ end
83
+
84
+ end
85
+ end
@@ -0,0 +1,3 @@
1
+ module LeaderboardFactory
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,113 @@
1
+ require 'leaderboard'
2
+ require 'leaderboard_factory/configuration'
3
+ require 'leaderboard_factory/helper_proxy'
4
+ require 'leaderboard_factory/version'
5
+ require 'active_support/inflector'
6
+ require 'active_support/concern'
7
+ require 'active_support/core_ext/class/attribute'
8
+
9
+ module LeaderboardFactory
10
+ extend Configuration
11
+ extend ActiveSupport::Concern
12
+
13
+ included do
14
+ class_attribute :leaderboard_specs
15
+ self.leaderboard_specs = {
16
+ instance: {},
17
+ collection: {}
18
+ }
19
+
20
+ include HelperProxyMethods
21
+ extend HelperProxyMethods
22
+ end
23
+
24
+ module ClassMethods
25
+ # Defines a new leaderboard that will be scoped to some unique property on the object instance.
26
+ # Use this if you want to, say, track a specific player's personal bests, or some other
27
+ # stat that is specific to the individual.
28
+ # This method defines an accessor that will return the leaderboard, as well as a shorthand
29
+ # method for ranking a new item in the leaderboard
30
+ #
31
+ # @param board [String] the name of the leaderboard
32
+ # @param scope_key [String/Symbol] the name of an attribute on the instance that will scope the leaderboard.
33
+ # @param options [Hash] optional; these are passed along to the leaderboard object
34
+ # @param redis_options [Hash] optional; these are also passed along to the leaderboard object
35
+ #
36
+ # Example
37
+ #
38
+ # class Player < ActiveRecord::Base
39
+ # include LeaderboardFactory
40
+ # leaderboard 'maps_by_wins', :id
41
+ # end
42
+ #
43
+ # p = Player.new(id: 77)
44
+ # p.maps_by_wins # => the player's personal maps leaderboard
45
+ # p.rank_map_by_wins map.name, 33, { map_id: 42 } # => ["OK", true]
46
+ def leaderboard board, scope_key, options = {}, redis_options = {}
47
+ self.leaderboard_specs[:instance][board] = {
48
+ key: scope_key,
49
+ options: options,
50
+ redis_options: redis_options
51
+ }
52
+
53
+ define_methods board, :instance
54
+ end
55
+
56
+ # As +leaderboard+, but on the class rather than the instance.
57
+ # it does not take a +scope_key+ parameter, but all other functionality is the same.
58
+ #
59
+ # @param board [String] the name of the leaderboard
60
+ # @param scope_key [String/Symbol] the name of an attribute on the instance that will scope the leaderboard.
61
+ # @param options [Hash] optional; these are passed along to the leaderboard object
62
+ # @param redis_options [Hash] optional; these are also passed along to the leaderboard object
63
+ #
64
+ # Example
65
+ #
66
+ # class Player < ActiveRecord::Base
67
+ # include LeaderboardFactory
68
+ # collection_leaderboard 'strength_of_schedule'
69
+ # end
70
+ #
71
+ # Player.strength_of_schedule # => the leaderboard object
72
+ # Player.rank_strength_of_schedule 232, 66.3, { player_name: 'Bob' } # => ["OK", true]
73
+ def collection_leaderboard board, options = {}, redis_options = {}
74
+ self.leaderboard_specs[:collection][board] = {
75
+ options: options,
76
+ redis_options: redis_options
77
+ }
78
+
79
+ define_methods board, :collection, 'self.'
80
+ end
81
+
82
+ # Method what actually does the defining.
83
+ def define_methods board, type = :instance, prefix = ''
84
+ singluar_object, *remainder_of_name = board.split("_")
85
+ singluar_object = singluar_object.singularize
86
+ accessor_method_name = ([singluar_object] + remainder_of_name).join("_")
87
+
88
+ class_eval <<-METHODS, __FILE__, __LINE__
89
+ def #{prefix}#{board}
90
+ return @#{board} if @#{board}
91
+ options = leaderboard_specs[:#{type}]['#{board}'][:options]
92
+ redis_options = leaderboard_specs[:#{type}]['#{board}'][:redis_options]
93
+ redis_key = leaderboard_specs[:#{type}]['#{board}'][:key]
94
+
95
+ redis_options.merge!({
96
+ redis_connection: LeaderboardFactory.redis
97
+ })
98
+
99
+ @#{board} = Leaderboard.new( leaderboards.board_name('#{board}', redis_key),
100
+ Leaderboard::DEFAULT_OPTIONS.merge(options),
101
+ redis_options )
102
+ end
103
+
104
+ def #{prefix}rank_#{accessor_method_name} object, rank, member_data = nil
105
+ #{board}.rank_member object, rank, member_data
106
+ end
107
+ METHODS
108
+ end
109
+ end
110
+
111
+ # instance methods would go here...
112
+
113
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ module LeaderboardFactory
4
+ describe HelperProxy do
5
+ it "takes on parameter to initialize, the context" do
6
+ foo = mock
7
+ proxy = HelperProxy.new(foo)
8
+ proxy.context.should === foo
9
+ end
10
+ it "includes the actual helpers" do
11
+ HelperProxy.included_modules.should include(LeaderboardFactory::Helpers)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ module LeaderboardFactory
4
+ describe Helpers do
5
+ let(:kontext) {
6
+ mock
7
+ }
8
+ let(:proxy) {
9
+ LeaderboardFactory::HelperProxy.new(kontext)
10
+ }
11
+
12
+ describe "#board_name" do
13
+ it "returns a good name for the leaderboard" do
14
+ proxy.board_name('garlics_by_weight').should == 'garlics-by-weight'
15
+ end
16
+ it "takes an optional second parameter which will be used to uniqify the name" do
17
+ kontext.should_receive(:id).and_return(1234)
18
+ proxy.board_name('personal_best_garlics', :id).should == 'personal-best-garlics-1234'
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,129 @@
1
+ require 'spec_helper'
2
+
3
+ describe LeaderboardFactory do
4
+ let(:test_harness) {
5
+ Class.new do
6
+ attr_accessor :id
7
+ include LeaderboardFactory
8
+ end
9
+ }
10
+
11
+ it "isn't borked" do
12
+ test_harness.included_modules.should include(LeaderboardFactory)
13
+ end
14
+
15
+ context 'configuration' do
16
+ it 'has a redis accessor' do
17
+ LeaderboardFactory.should respond_to(:redis)
18
+ end
19
+ it "uses the redis that is configured" do
20
+ LeaderboardFactory.redis.client.db.should == 15
21
+ end
22
+ end
23
+
24
+ describe ".leaderboard" do
25
+ it "defines a connection to a leaderboard object" do
26
+ test_harness.should respond_to(:leaderboard)
27
+ test_harness.class_eval do
28
+ leaderboard 'fu_manchu', :id
29
+ end
30
+ test_harness.leaderboard_specs[:instance]['fu_manchu'].should include({
31
+ key: :id,
32
+ options: {}
33
+ })
34
+ end
35
+ it "creates a factory method that returns said leaderboard" do
36
+ test_harness.class_eval do
37
+ leaderboard 'fu_manchu', :id
38
+ end
39
+ instance = test_harness.new
40
+
41
+ instance.fu_manchu.should be_a_kind_of(Leaderboard)
42
+ end
43
+ it "uses the second parameter to namespace the leaderboard" do
44
+ test_harness.class_eval do
45
+ leaderboard 'fu_manchu', :id
46
+ end
47
+ instance = test_harness.new
48
+ instance.id = 'haha'
49
+ leaderboard = instance.fu_manchu
50
+ leaderboard.leaderboard_name.should == 'fu-manchu-haha'
51
+ end
52
+ it "doesn't leak the abstraction" do
53
+ klass = Class.new do
54
+ attr_accessor :id
55
+ include LeaderboardFactory
56
+ leaderboard 'garlic', :id
57
+ end
58
+
59
+ klass.new.leaderboard_specs[:instance].keys.should include('garlic')
60
+ test_harness.new.leaderboard_specs[:instance].should be_empty
61
+ end
62
+ it "is connected to the configured redis instance" do
63
+ test_harness.class_eval do
64
+ leaderboard 'fu_manchu', :id
65
+ end
66
+ redis = test_harness.new.fu_manchu.instance_variable_get(:@redis_connection)
67
+ redis.should === LeaderboardFactory.redis
68
+ end
69
+ it "adds a convience accessor based on the singularized object name, e.g. maps_by_wins => rank_map_by_wins" do
70
+ test_harness.class_eval do
71
+ leaderboard 'maps_by_wins', :id
72
+ end
73
+ instance = test_harness.new
74
+
75
+ instance.should respond_to(:rank_map_by_wins)
76
+ instance.rank_map_by_wins 'map', 3
77
+ instance.maps_by_wins.all_members.should include({:member=>"map", :rank=>1, :score=>3.0})
78
+ end
79
+ describe "this convience accessor" do
80
+ it "accepts an optional third parameter, which is member data" do
81
+ test_harness.class_eval do
82
+ leaderboard 'maps_by_wins', :id
83
+ end
84
+ instance = test_harness.new
85
+
86
+ instance.rank_map_by_wins 'map', 3, { event_name: 'framulator 5000' }
87
+ instance.maps_by_wins.all_members(with_member_data: true).should include({
88
+ member: "map",
89
+ rank: 1,
90
+ score: 3.0,
91
+ member_data: {"event_name"=>"framulator 5000"}
92
+ })
93
+ end
94
+ end
95
+ it "can be overriden in the class" do
96
+ klass = Class.new do
97
+ attr_accessor :id
98
+ include LeaderboardFactory
99
+ leaderboard 'garlics_by_weight', :id
100
+
101
+ def rank_garlic_by_weight
102
+ "HA! HA!"
103
+ end
104
+ end
105
+
106
+ klass.new.rank_garlic_by_weight.should == "HA! HA!"
107
+ end
108
+ end
109
+
110
+ describe ".collection_leaderboard" do
111
+ it "defines a connection to a leaderboard object" do
112
+ test_harness.should respond_to(:collection_leaderboard)
113
+ test_harness.class_eval do
114
+ collection_leaderboard 'greatest_of_all_time'
115
+ end
116
+ test_harness.leaderboard_specs[:collection]['greatest_of_all_time'].should include({
117
+ options: {}
118
+ })
119
+ end
120
+ it "creates a factory method that returns said leaderboard" do
121
+ test_harness.class_eval do
122
+ collection_leaderboard 'greatest_of_all_time'
123
+ end
124
+
125
+ test_harness.greatest_of_all_time.should be_a_kind_of(Leaderboard)
126
+ end
127
+ end
128
+
129
+ end
@@ -0,0 +1,9 @@
1
+ require 'rspec'
2
+ require 'leaderboard_factory'
3
+ LeaderboardFactory.redis = Redis.new(db: 15)
4
+
5
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
6
+
7
+ RSpec.configure do |config|
8
+
9
+ end
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: leaderboard_factory
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Matt Wilson
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-03 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: leaderboard
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: active_support
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rake
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rspec
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description: Helps you define and work with a bunch of leaderboards, from, e.g. an
79
+ ActiveModel object
80
+ email:
81
+ - mwilson@majorleaguegaming.com
82
+ executables: []
83
+ extensions: []
84
+ extra_rdoc_files: []
85
+ files:
86
+ - .gitignore
87
+ - .rspec
88
+ - .rvmrc
89
+ - CHANGELOG.md
90
+ - Gemfile
91
+ - LICENSE
92
+ - README.md
93
+ - Rakefile
94
+ - leaderboard_factory.gemspec
95
+ - lib/leaderboard_factory.rb
96
+ - lib/leaderboard_factory/configuration.rb
97
+ - lib/leaderboard_factory/helper_proxy.rb
98
+ - lib/leaderboard_factory/helpers.rb
99
+ - lib/leaderboard_factory/version.rb
100
+ - spec/helper_proxy_spec.rb
101
+ - spec/helpers_spec.rb
102
+ - spec/leaderboard_factory_spec.rb
103
+ - spec/spec_helper.rb
104
+ homepage: https://github.com/agoragames/leaderboard_factory
105
+ licenses: []
106
+ post_install_message:
107
+ rdoc_options: []
108
+ require_paths:
109
+ - lib
110
+ required_ruby_version: !ruby/object:Gem::Requirement
111
+ none: false
112
+ requirements:
113
+ - - ! '>='
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ required_rubygems_version: !ruby/object:Gem::Requirement
117
+ none: false
118
+ requirements:
119
+ - - ! '>='
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ requirements: []
123
+ rubyforge_project:
124
+ rubygems_version: 1.8.24
125
+ signing_key:
126
+ specification_version: 3
127
+ summary: Helps you define and work with a bunch of leaderboards, from, e.g. an ActiveModel
128
+ object
129
+ test_files:
130
+ - spec/helper_proxy_spec.rb
131
+ - spec/helpers_spec.rb
132
+ - spec/leaderboard_factory_spec.rb
133
+ - spec/spec_helper.rb