rails_rank 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a226174d165b3f53c80a2220a072dffc7f46e49d
4
+ data.tar.gz: 071e16d3ec71e8b59f9a54d786d43914f8ef9040
5
+ SHA512:
6
+ metadata.gz: daa60282c8d910a6b448aaabf2d38b1406038fce36b5948ba6f6886e0248e4dacd087ab6e8087c79fb0a545f33250fca722440a6d72fc5150bbd4a906b4a8411
7
+ data.tar.gz: b586bd44ae43fc4571e84258837c46c6fd665b3fb4056f7b52d5c17350614ee6286e1312dc6e78a54c867a41722c76284560ed0abe57031d6ecab840f4254741
data/.gitignore ADDED
@@ -0,0 +1,19 @@
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
+ vendor
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
19
+ nbproject/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rails_rank.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Atsushi Nakamura
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,118 @@
1
+ # RailsRank
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'rails_rank'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install rails_rank
18
+
19
+
20
+
21
+ ## Usage: (using redis_driver)
22
+
23
+ ### Install rails\_kvs\_driver
24
+
25
+ ```ruby
26
+ gem "rails_kvs_driver-redis_driver", ">= 0.2.0"
27
+ ```
28
+
29
+ ### Generate a class of ranking
30
+ This code generate access_rank.rb in lib/rankings/ .
31
+
32
+ ```ruby
33
+ bundle exec rails g ranking access_rank
34
+ ```
35
+
36
+ ## Edit generated lib/rankings/access_rank.rb
37
+ add driver setting.
38
+ ```ruby
39
+ def self.rails_kvs_driver
40
+ RailsKvsDriver::RedisDriver::Driver
41
+ end
42
+ ```
43
+
44
+ And override after_table methods.
45
+ This method will call after done tabulation.
46
+ Specifically,
47
+
48
+ - after count hourly.(onece an hour)
49
+ - after count daily. (onece a day)
50
+ - after count monthly.(once a month)
51
+ - after count yearly.(once a year)
52
+
53
+ when table, after_table will be called repeatedly as the number of the data.
54
+
55
+ You should write a code in here, to insert data to database.
56
+
57
+ ```ruby
58
+ # callbacked after table.
59
+ # if use data, override this method.
60
+ #
61
+ # @param date_type [RailsRank::Types::Date] type of tabulation.(HOURLY or DAILY or MONTHLY or YEARLY)
62
+ # @param time [Time] time slot of tabulation.
63
+ # @param value [String] value of tabulation.
64
+ # @param score [Integer] score of value.
65
+ # @param position [Integer] position of value.
66
+ def self.after_table(date_type, time, value, score, position)
67
+ end
68
+ ```
69
+
70
+ For example
71
+
72
+ when there are the next hourly data.
73
+
74
+ |value|score|
75
+ |:----:|---:|
76
+ |'id-1'| 5|
77
+ |'id-2'|10|
78
+ |'id-3'| 8|
79
+
80
+
81
+ after_table will be called 3 times with the next parameter when table the time slot.
82
+
83
+ |data_type|time|value|score|position|
84
+ |:-------:|:--:|:---:|:---:|:------:|
85
+ |RailsRank::Types::Date::HOURLY| data_time|'id-2'|10|0|
86
+ |RailsRank::Types::Date::HOURLY| data_time|'id-3'|8|1|
87
+ |RailsRank::Types::Date::HOURLY| data_time|'id-1'|5|2|
88
+
89
+
90
+
91
+ ### Add autoload setting in application.rb
92
+ If your application.rb include this setting, don't need this step.
93
+
94
+ ```ruby
95
+ config.autoload_paths += %W("#{config.root}/lib")
96
+ config.autoload_paths += Dir["#{config.root}/lib/**/"]
97
+ ```
98
+
99
+ ### Periodical practice
100
+ This task must be called every an hour. use cron.
101
+ ```ruby
102
+ bundle exec rake rails_rank:table
103
+ ```
104
+
105
+ ### How to add and get data.
106
+ When add a data of the ranking, or get data before table. use next methods.
107
+ ```
108
+ Rankings::AccessRank.increment(@hoge.id)
109
+ Rankings::AccessRank.score(@hoge.id)
110
+ ```
111
+
112
+ ## Contributing
113
+
114
+ 1. Fork it
115
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
116
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
117
+ 4. Push to the branch (`git push origin my-new-feature`)
118
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,10 @@
1
+ class RankingGenerator < Rails::Generators::NamedBase
2
+
3
+ source_root File.expand_path("../templates", __FILE__)
4
+
5
+ desc "This generator creates ranking class file in lib/rankings."
6
+
7
+ def create_ranking_file
8
+ template "base.rb.template", "lib/rankings/#{file_name}.rb"
9
+ end
10
+ end
@@ -0,0 +1,46 @@
1
+ require 'rails_rank/base'
2
+
3
+ module Rankings
4
+ class <%= class_name %> < RailsRank::Base
5
+
6
+ # return driver class of rails_kvs_driver.
7
+ #
8
+ # @example use rails_kvs_driver-redis_driver
9
+ # def self.rails_kvs_driver
10
+ # RailsKvsDriver::RedisDriver::Driver
11
+ # end
12
+ #
13
+ # @return [RailsKvsDriver::Base] return driver class of rails_kvs_driver.
14
+ def self.rails_kvs_driver
15
+ raise NoMethodError 'Should override lib/rankings/<%= file_name %>.rb rails_kvs_driver method.'
16
+ end
17
+
18
+ # return driver config of rails_kvs_driver.
19
+ #
20
+ # @return [Hash] return driver config of rails_kvs_driver.
21
+ def self.rails_kvs_driver_config
22
+ {
23
+ :host => 'localhost', # host of KVS.
24
+ :port => 6379, # port of KVS.
25
+ :namespace => 'Ranking::<%= class_name %>', # namespace of avoid a conflict with key
26
+ :timeout_sec => 5, # timeout seconds.
27
+ :pool_size => 5, # connection pool size.
28
+ :config_key => :none # this key is option.(defaults=:none)
29
+ # when set this key.
30
+ # will refer to a connection-pool based on config_key,
31
+ # even if driver setting is the same without this key.
32
+ }
33
+ end
34
+
35
+ # callbacked after table.
36
+ # if use data, override this method.
37
+ #
38
+ # @param date_type [RailsRank::Types::Date] type of tabulation.
39
+ # @param time [Time] time slot of tabulation.
40
+ # @param value [String] value of tabulation.
41
+ # @param score [Integer] score of value.
42
+ # @param position [Integer] position of value.
43
+ def self.after_table(date_type, time, value, score, position)
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,55 @@
1
+ require 'rails_rank/defined_base_methods'
2
+
3
+ module RailsRank
4
+ # @abstract a class of Ranking is override this class.
5
+ class Base
6
+ extend DefinedBaseMethods
7
+
8
+ # return driver class of rails_kvs_driver.
9
+ #
10
+ # @example use rails_kvs_driver-redis_driver
11
+ # def self.rails_kvs_driver
12
+ # RailsKvsDriver::RedisDriver::Driver
13
+ # end
14
+ #
15
+ # @return [RailsKvsDriver::Base] return driver class of rails_kvs_driver.
16
+ # @abstract override and return driver class of rails_kvs_driver.
17
+ def self.rails_kvs_driver
18
+ raise NoMethodError 'Should override rails_kvs_driver method.'
19
+ end
20
+
21
+ # return driver config of rails_kvs_driver.
22
+ #
23
+ # @example
24
+ # def self.rails_kvs_driver_config
25
+ # {
26
+ # :host => 'localhost', # host of KVS.
27
+ # :port => 6379, # port of KVS.
28
+ # :namespace => 'Example', # namespace of avoid a conflict with key
29
+ # :timeout_sec => 5, # timeout seconds.
30
+ # :pool_size => 5, # connection pool size.
31
+ # :config_key => :none # this key is option.(defaults=:none)
32
+ # # when set this key.
33
+ # # will refer to a connection-pool based on config_key,
34
+ # # even if driver setting is the same without this key.
35
+ # }
36
+ # end
37
+ #
38
+ # @return [Hash] return driver config of rails_kvs_driver.
39
+ # @abstract override and return driver config of rails_kvs_driver.
40
+ def self.rails_kvs_driver_config
41
+ raise NoMethodError 'Should override rails_kvs_driver_config method.'
42
+ end
43
+
44
+ # callbacked after table.
45
+ # if use data, override this method.
46
+ #
47
+ # @param date_type [RailsRank::Types::Date] type of tabulation.
48
+ # @param time [Time] time slot of tabulation.
49
+ # @param value [String] value of tabulation.
50
+ # @param score [Integer] score of value.
51
+ # @param position [Integer] position of value.
52
+ def self.after_table(date_type, time, value, score, position)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,149 @@
1
+ require 'rails_rank/types/date'
2
+
3
+ module RailsRank
4
+ module DefinedBaseMethods
5
+
6
+ # get all time slot(s).
7
+ #
8
+ # @param date_type [RailsRank::Types::Date] delete type.(default=HOURLY)
9
+ # @param session [RailsKvsDriver::Base] default is nil. if there's session instance, set it.
10
+ # @return [Array<Time>] all time slot(s).
11
+ def all(date_type=RailsRank::Types::Date::HOURLY, session=nil)
12
+ start_kvs_session(session) do |kvs|
13
+ times = Array.new
14
+ all_key = (date_type == RailsRank::Types::Date::ALL)
15
+
16
+ kvs.sorted_sets.each do |key|
17
+ key_a = key.split('-')
18
+ times.push(Time.local(*key_a)) if all_key or key_a.length == date_type
19
+ end
20
+
21
+ times
22
+ end
23
+ end
24
+
25
+ # delete the data of ranking.
26
+ #
27
+ # @param time [Time] delete time slot.
28
+ # @param date_type [RailsRank::Types::Date] delete type.(default=HOURLY)
29
+ # @param session [RailsKvsDriver::Base] default is nil. if there's session instance, set it.
30
+ def delete(time, date_type=RailsRank::Types::Date::HOURLY, session=nil)
31
+ start_kvs_session(session) do |kvs|
32
+ kvs.delete(key_name(time, date_type))
33
+ end
34
+ end
35
+
36
+ # delete all ranking data.
37
+ # @param session [RailsKvsDriver::Base] default is nil. if there's session instance, set it.
38
+ def delete_all(session=nil)
39
+ start_kvs_session(session) do |kvs|
40
+ kvs.delete_all
41
+ end
42
+ end
43
+
44
+ # execute the block of code for each ranking.
45
+ #
46
+ # @param key [String] key of time slot.
47
+ # @param reverse [Boolean] order desc. [default=asc]
48
+ # @param limit [Integer] The maximum size of the request at once.
49
+ # @param session [RailsKvsDriver::Base] default is nil. if there's session instance, set it.
50
+ # @param &block [{|value, score, absolute_position| ...}] block of exec code.
51
+ def each(key, reverse=false, limit=1000, session=nil, &block)
52
+ start_kvs_session(session) {|kvs| kvs.sorted_sets[key].each(reverse, limit, &block) }
53
+ end
54
+
55
+ # increment this time slot score of a value. (Time slot is hourly.)
56
+ # @note when doesn't exist the value, set 'score' to value of score.
57
+ #
58
+ # @param value [String] value to record the score.
59
+ # @param score [Integer] score to increment.
60
+ # @param session [RailsKvsDriver::Base] default is nil. if there's session instance, set it.
61
+ # @return [Integer] score after increment
62
+ def increment(value, score=1, session=nil)
63
+ start_kvs_session(session) do |kvs|
64
+ kvs.sorted_sets[key_name(Time.now)].increment(value, score).to_i
65
+ end
66
+ end
67
+
68
+ # get ranking key of a time slot.
69
+ #
70
+ # @param time [Time] time of key.
71
+ # @param date_type [RailsRank::Types::Date] type of key.(default=HOURLY)
72
+ # @return [String] key name.
73
+ def key_name(time, date_type=RailsRank::Types::Date::HOURLY)
74
+ case date_type
75
+ when RailsRank::Types::Date::YEARLY
76
+ time.strftime('%Y')
77
+ when RailsRank::Types::Date::MONTHLY
78
+ time.strftime('%Y-%m')
79
+ when RailsRank::Types::Date::DAILY
80
+ time.strftime('%Y-%m-%d')
81
+ else
82
+ time.strftime('%Y-%m-%d-%H')
83
+ end
84
+ end
85
+
86
+ # get this time slot score of a value.(Time slot is hourly.)
87
+ # @note when doesn't exist the value, return 0.
88
+ #
89
+ # @param value [String] value to record the score.
90
+ # @param session [RailsKvsDriver::Base] default is nil. if there's session instance, set it.
91
+ # @return [Integer] score
92
+ def score(value, session=nil)
93
+ start_kvs_session(session) do |kvs|
94
+ score = kvs.sorted_sets[key_name(Time.now)][value]
95
+ (score.nil?) ? 0 : score.to_i
96
+ end
97
+ end
98
+
99
+ # table score.
100
+ # this methods total the calculations done data.
101
+ #
102
+ # @param date_type [RailsRank::Types::Date] type of tabulation.
103
+ # @return [Integer] count tabled data.
104
+ def table(date_type)
105
+ raise ArgumentError if date_type < RailsRank::Types::Date::YEARLY
106
+
107
+ tabled_data_count = 0
108
+ base_time = Time.local(*(Time.now.to_a.reverse[4..(3+date_type)]))
109
+
110
+ start_kvs_session do |kvs|
111
+ all(date_type).each do |data_time|
112
+ next unless data_time < base_time
113
+
114
+ key = key_name(data_time, date_type)
115
+ total_key = key_name(data_time, date_type - 1)
116
+
117
+ each(key, false, 1000, kvs) do |member, score, position|
118
+ if RailsRank::Types::Date::YEARLY < date_type
119
+ kvs.sorted_sets[total_key].increment(member, score)
120
+ end
121
+ after_table(date_type, data_time, member, score.to_i, position)
122
+ end
123
+
124
+ delete(data_time, date_type, kvs)
125
+ tabled_data_count += 1
126
+ end
127
+ end
128
+
129
+ return tabled_data_count
130
+ end
131
+
132
+
133
+ private
134
+ # start key-value store session.
135
+ # if session of params isn't nil, call &block with this session.
136
+ #
137
+ # @params session [RailsKvsDriver::Base] session.
138
+ # @params yield [block] exec block with session.
139
+ # @return [Object] Evaluation of the block.
140
+ def start_kvs_session(session=nil)
141
+ if session.nil?
142
+ rails_kvs_driver::session(rails_kvs_driver_config) {|new_session| yield new_session }
143
+ else
144
+ yield session
145
+ end
146
+ end
147
+
148
+ end
149
+ end
@@ -0,0 +1,11 @@
1
+ module RailsRank
2
+ module Types
3
+ module Date
4
+ ALL = 0
5
+ YEARLY = 1
6
+ MONTHLY = 2
7
+ DAILY = 3
8
+ HOURLY = 4
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module RailsRank
2
+ VERSION = "0.0.1"
3
+ end
data/lib/rails_rank.rb ADDED
@@ -0,0 +1,5 @@
1
+ require "rails_rank/version"
2
+
3
+ module RailsRank
4
+ require "railtie" if defined?(Rails)
5
+ end
data/lib/railtie.rb ADDED
@@ -0,0 +1,9 @@
1
+ module RailsRank
2
+ class Railtie < Rails::Railtie
3
+ railtie_name :rails_rank
4
+
5
+ rake_tasks do
6
+ Dir[File.join(File.dirname(__FILE__),'tasks/*.rake')].each {|file| load file }
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,28 @@
1
+ namespace :rails_rank do
2
+
3
+ desc 'table all the rankings.'
4
+
5
+ task :table => :environment do
6
+ # Load all ranking classes.
7
+ Dir.glob('lib/rankings/*.rb').each {|f| require "rankings/#{File.basename(f, '.rb')}" }
8
+
9
+ if Object.const_defined?('Rankings')
10
+ Rankings::constants.each do |name|
11
+ object = Rankings::const_get(name)
12
+ next unless object.ancestors.include?(RailsRank::Base)
13
+
14
+ puts("#{name} table the ranking...")
15
+
16
+ cnt = object.table(RailsRank::Types::Date::HOURLY)
17
+ puts "- tabled #{cnt} hourly data."
18
+ object.table(RailsRank::Types::Date::DAILY)
19
+ puts "- tabled #{cnt} daily data."
20
+ object.table(RailsRank::Types::Date::MONTHLY)
21
+ puts "- tabled #{cnt} monthly data."
22
+ object.table(RailsRank::Types::Date::YEARLY)
23
+ puts "- tabled #{cnt} yearly data."
24
+ end
25
+ end
26
+ end
27
+
28
+ end
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rails_rank/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "rails_rank"
8
+ spec.version = RailsRank::VERSION
9
+ spec.authors = ["alfa-jpn"]
10
+ spec.email = ["a.nkmr.ja@gmail.com"]
11
+ spec.description = "develop now"
12
+ spec.summary = "develop now"
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ spec.add_development_dependency "yard"
25
+ spec.add_development_dependency "rails_kvs_driver-redis_driver", "0.2.0"
26
+
27
+ spec.add_dependency "rails", ">= 3"
28
+ spec.add_dependency "rails_kvs_driver", "0.2.1"
29
+ end
@@ -0,0 +1,289 @@
1
+ require 'rspec'
2
+ require 'spec_helper'
3
+ require 'rails_rank/defined_base_methods'
4
+
5
+
6
+
7
+ describe RailsRank::DefinedBaseMethods do
8
+
9
+ before(:each) do
10
+ @driver = RailsKvsDriver::RedisDriver::Driver
11
+ @driver_config = {
12
+ :host => 'localhost', # host of KVS.
13
+ :port => 6379, # port of KVS.
14
+ :namespace => 'Spec::RailsRank', # namespace of avoid a conflict with key
15
+ :timeout_sec => 5, # timeout seconds.
16
+ :pool_size => 5, # connection pool size.
17
+ :config_key => :none # this key is option.(defaults=:none)
18
+ # when set this key.
19
+ # will refer to a connection-pool based on config_key,
20
+ # even if driver setting is the same without this key.
21
+ }
22
+
23
+ class IncludeDefinedBaseMethods
24
+ include RailsRank::DefinedBaseMethods
25
+ end
26
+
27
+ @defined_base_methods = IncludeDefinedBaseMethods.new
28
+ @defined_base_methods.stub({ rails_kvs_driver: @driver, rails_kvs_driver_config: @driver_config, after_table: nil })
29
+
30
+ Time.stub({ now: Time.local(2013,11,5) })
31
+
32
+ @driver::session(@driver_config) {|kvs| kvs.delete_all }
33
+ end
34
+
35
+ after(:each) do
36
+ @driver::session(@driver_config) {|kvs| kvs.delete_all }
37
+ end
38
+
39
+ context 'when call all,' do
40
+ before(:each) do
41
+ (0 .. 11).each do |i|
42
+ Time.stub({ now: Time.local(2013,11,5, i) })
43
+ @defined_base_methods.increment("NyarukoSan", 2865)
44
+ end
45
+ @times = @defined_base_methods.all
46
+ end
47
+
48
+ it 'return times' do
49
+ expect(@times[0].instance_of?(Time)).to be_true
50
+
51
+ end
52
+
53
+ it 'return correct length' do
54
+ expect(@times.length).to eq(12)
55
+ end
56
+ end
57
+
58
+ context 'when call delete' do
59
+ before(:each) do
60
+ @defined_base_methods.increment('NyarukoSan',2865)
61
+ end
62
+
63
+ it 'delete ranking data.' do
64
+ @driver::session(@driver_config) do |kvs|
65
+ expect{
66
+ @defined_base_methods.delete(Time.now)
67
+ }.to change{
68
+ kvs.sorted_sets.length
69
+ }.by(-1)
70
+ end
71
+ end
72
+ end
73
+
74
+ context 'when call delete_all' do
75
+ before(:each) do
76
+ (0 .. 23).each do |i|
77
+ Time.stub({ now: Time.local(2013,11,5, i) })
78
+ @defined_base_methods.increment("NyarukoSan", 2865)
79
+ end
80
+ end
81
+
82
+ it 'delete ranking data.' do
83
+ @driver::session(@driver_config) do |kvs|
84
+ expect{
85
+ @defined_base_methods.delete_all
86
+ }.to change{
87
+ kvs.sorted_sets.length
88
+ }.by(-24)
89
+ end
90
+ end
91
+ end
92
+
93
+ context 'when call each' do
94
+ before(:each) do
95
+ @defined_base_methods.increment('be_0',100)
96
+ @defined_base_methods.increment('be_1', 10)
97
+ @defined_base_methods.increment('be_2', 1)
98
+ end
99
+
100
+ it 'return correct data.' do
101
+ key = @defined_base_methods.key_name(Time.now, RailsRank::Types::Date::HOURLY)
102
+ @defined_base_methods.each(key, true) do |value, score, position|
103
+ expect(value).to eq("be_#{position}")
104
+ end
105
+ end
106
+ end
107
+
108
+ context 'when call increment,' do
109
+ before(:each) do
110
+ @key = @defined_base_methods.key_name(Time.now)
111
+ @defined_base_methods.increment('NyarukoSan',2865)
112
+ end
113
+
114
+ it 'create sorted_set, and set score' do
115
+ @driver::session(@driver_config) do |kvs|
116
+ expect(kvs.sorted_sets.length).to eq(1)
117
+ expect(kvs.sorted_sets[@key]['NyarukoSan']).to eq(2865)
118
+ end
119
+ end
120
+
121
+ it 'increment score of value' do
122
+ @driver::session(@driver_config) do |kvs|
123
+ expect{
124
+ @defined_base_methods.increment('NyarukoSan')
125
+ }.to change{
126
+ kvs.sorted_sets[@key]['NyarukoSan']
127
+ }.by(1)
128
+ end
129
+ end
130
+ end
131
+
132
+ context 'when call key_name' do
133
+ it 'return correct key.' do
134
+ expect(@defined_base_methods.key_name(Time.now)).to eq('2013-11-05-00')
135
+ expect(@defined_base_methods.key_name(Time.now, RailsRank::Types::Date::DAILY)).to eq('2013-11-05')
136
+ expect(@defined_base_methods.key_name(Time.now, RailsRank::Types::Date::MONTHLY)).to eq('2013-11')
137
+ end
138
+ end
139
+
140
+ context 'when call score' do
141
+ before(:each) do
142
+ @defined_base_methods.increment('NyarukoSan',2865)
143
+ end
144
+
145
+ it 'return score of value' do
146
+ expect(@defined_base_methods.score('NyarukoSan')).to eq(2865)
147
+ end
148
+
149
+ it 'nothing value, return 0' do
150
+ expect(@defined_base_methods.score('Nothing value')).to eq(0)
151
+ end
152
+ end
153
+
154
+ context 'when call table' do
155
+ before(:each) do
156
+ @defined_base_methods.increment('NyarukoSan',2865)
157
+ end
158
+
159
+ context 'with RailsRank::Types::Date::HOURLY' do
160
+ before(:each) do
161
+ Time.stub({ now: Time.local(2013,11,5,1) })
162
+ @defined_base_methods.increment('NyarukoSan',2865)
163
+ @defined_base_methods.increment('KotouraSan',3000)
164
+ end
165
+
166
+ it 'add previous time slot to DAILY' do
167
+ expect{
168
+ @defined_base_methods.table(RailsRank::Types::Date::HOURLY)
169
+ }.to change{
170
+ @defined_base_methods.all(RailsRank::Types::Date::DAILY).length
171
+ }.by(1)
172
+ end
173
+
174
+ it 'delete previous time slot' do
175
+ expect{
176
+ @defined_base_methods.table(RailsRank::Types::Date::HOURLY)
177
+ }.to change{
178
+ @defined_base_methods.all(RailsRank::Types::Date::HOURLY).length
179
+ }.by(-1)
180
+ end
181
+
182
+ it 'callback with date' do
183
+ args = [RailsRank::Types::Date::HOURLY, Time.local(2013,11,5), 'NyarukoSan', 2865, 0]
184
+ @defined_base_methods.should_receive(:after_table).with(*args)
185
+ @defined_base_methods.table(RailsRank::Types::Date::HOURLY)
186
+ end
187
+
188
+ it 'return tabled data number.' do
189
+ expect(@defined_base_methods.table(RailsRank::Types::Date::HOURLY)). to eq(1)
190
+ end
191
+
192
+ it 'correct data after add up' do
193
+ Time.stub({ now: Time.local(2013,11,5,2) })
194
+ expect(@defined_base_methods.table(RailsRank::Types::Date::HOURLY)). to eq(2)
195
+
196
+ key = @defined_base_methods.key_name(Time.now, RailsRank::Types::Date::DAILY)
197
+ data = Hash.new
198
+ @defined_base_methods.each(key, true) {|value, score, position| data[value] = score }
199
+
200
+ expect(data['NyarukoSan']).to eq(2865*2)
201
+ expect(data['KotouraSan']).to eq(3000)
202
+ end
203
+
204
+ end
205
+
206
+ context 'with RailsRank::Types::Date::DAILY' do
207
+ before(:each) do
208
+ Time.stub({ now: Time.local(2013,11,6) })
209
+ @defined_base_methods.table(RailsRank::Types::Date::HOURLY)
210
+ end
211
+
212
+ it 'add previous time slot to MONTHLY' do
213
+ expect{
214
+ @defined_base_methods.table(RailsRank::Types::Date::DAILY)
215
+ }.to change{
216
+ @defined_base_methods.all(RailsRank::Types::Date::MONTHLY).length
217
+ }.by(1)
218
+ end
219
+
220
+ it 'delete previous time slot' do
221
+ expect{
222
+ @defined_base_methods.table(RailsRank::Types::Date::DAILY)
223
+ }.to change{
224
+ @defined_base_methods.all(RailsRank::Types::Date::DAILY).length
225
+ }.by(-1)
226
+ end
227
+
228
+ it 'callback with date' do
229
+ args = [RailsRank::Types::Date::DAILY, Time.local(2013,11,5), 'NyarukoSan', 2865, 0]
230
+ @defined_base_methods.should_receive(:after_table).with(*args)
231
+ @defined_base_methods.table(RailsRank::Types::Date::DAILY)
232
+ end
233
+ end
234
+
235
+ context 'with RailsRank::Types::Date::MONTHLY' do
236
+ before(:each) do
237
+ Time.stub({ now: Time.local(2013,12) })
238
+ @defined_base_methods.table(RailsRank::Types::Date::HOURLY)
239
+ @defined_base_methods.table(RailsRank::Types::Date::DAILY)
240
+ end
241
+
242
+ it 'add previous time slot to YAERLY' do
243
+ expect{
244
+ @defined_base_methods.table(RailsRank::Types::Date::MONTHLY)
245
+ }.to change{
246
+ @defined_base_methods.all(RailsRank::Types::Date::YEARLY).length
247
+ }.by(1)
248
+ end
249
+
250
+ it 'delete previous time slot' do
251
+ expect{
252
+ @defined_base_methods.table(RailsRank::Types::Date::MONTHLY)
253
+ }.to change{
254
+ @defined_base_methods.all(RailsRank::Types::Date::MONTHLY).length
255
+ }.by(-1)
256
+ end
257
+
258
+ it 'callback with date' do
259
+ args = [RailsRank::Types::Date::MONTHLY, Time.local(2013,11), 'NyarukoSan', 2865, 0]
260
+ @defined_base_methods.should_receive(:after_table).with(*args)
261
+ @defined_base_methods.table(RailsRank::Types::Date::MONTHLY)
262
+ end
263
+ end
264
+
265
+ context 'with RailsRank::Types::Date::YEARLY' do
266
+ before(:each) do
267
+ Time.stub({ now: Time.local(2014,1) })
268
+ @defined_base_methods.table(RailsRank::Types::Date::HOURLY)
269
+ @defined_base_methods.table(RailsRank::Types::Date::DAILY)
270
+ @defined_base_methods.table(RailsRank::Types::Date::MONTHLY)
271
+ end
272
+
273
+ it 'delete previous time slot' do
274
+ expect{
275
+ @defined_base_methods.table(RailsRank::Types::Date::YEARLY)
276
+ }.to change{
277
+ @defined_base_methods.all(RailsRank::Types::Date::YEARLY).length
278
+ }.by(-1)
279
+ end
280
+
281
+ it 'callback with date' do
282
+ args = [RailsRank::Types::Date::YEARLY, Time.local(2013), 'NyarukoSan', 2865, 0]
283
+ @defined_base_methods.should_receive(:after_table).with(*args)
284
+ @defined_base_methods.table(RailsRank::Types::Date::YEARLY)
285
+ end
286
+ end
287
+ end
288
+
289
+ end
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'rake'
4
+ require 'rails_rank'
5
+ require 'rails_kvs_driver/redis_driver'
6
+
7
+ RSpec.configure do |config|
8
+ config.mock_framework = :rspec
9
+ end
@@ -0,0 +1,19 @@
1
+ require 'rspec'
2
+ require 'spec_helper'
3
+
4
+ describe 'tasks' do
5
+
6
+ before(:all) do
7
+ # load all rake tasks.
8
+ @rake = Rake::Application.new
9
+ Rake.application = @rake
10
+ Dir.glob('lib/tasks/*.rake') do |file|
11
+ Rake.application.rake_require(File::basename(file, '.rake'), ['lib/tasks'])
12
+ end
13
+ Rake::Task.define_task(:environment)
14
+ end
15
+
16
+ it 'exec total' do
17
+ @rake["rails_rank:table"].execute
18
+ end
19
+ end
metadata ADDED
@@ -0,0 +1,164 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rails_rank
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - alfa-jpn
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-11-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: yard
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rails_kvs_driver-redis_driver
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '='
74
+ - !ruby/object:Gem::Version
75
+ version: 0.2.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '='
81
+ - !ruby/object:Gem::Version
82
+ version: 0.2.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: rails
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '3'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '3'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rails_kvs_driver
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '='
102
+ - !ruby/object:Gem::Version
103
+ version: 0.2.1
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '='
109
+ - !ruby/object:Gem::Version
110
+ version: 0.2.1
111
+ description: develop now
112
+ email:
113
+ - a.nkmr.ja@gmail.com
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - .gitignore
119
+ - Gemfile
120
+ - LICENSE.txt
121
+ - README.md
122
+ - Rakefile
123
+ - lib/generators/ranking_generator.rb
124
+ - lib/generators/templates/base.rb.template
125
+ - lib/rails_rank.rb
126
+ - lib/rails_rank/base.rb
127
+ - lib/rails_rank/defined_base_methods.rb
128
+ - lib/rails_rank/types/date.rb
129
+ - lib/rails_rank/version.rb
130
+ - lib/railtie.rb
131
+ - lib/tasks/table.rake
132
+ - rails_rank.gemspec
133
+ - spec/rails_rank/defined_base_methods_spec.rb
134
+ - spec/spec_helper.rb
135
+ - spec/tasks/tasks_spec.rb
136
+ homepage: ''
137
+ licenses:
138
+ - MIT
139
+ metadata: {}
140
+ post_install_message:
141
+ rdoc_options: []
142
+ require_paths:
143
+ - lib
144
+ required_ruby_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - '>='
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
149
+ required_rubygems_version: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - '>='
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ requirements: []
155
+ rubyforge_project:
156
+ rubygems_version: 2.0.3
157
+ signing_key:
158
+ specification_version: 4
159
+ summary: develop now
160
+ test_files:
161
+ - spec/rails_rank/defined_base_methods_spec.rb
162
+ - spec/spec_helper.rb
163
+ - spec/tasks/tasks_spec.rb
164
+ has_rdoc: