rails_rank 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: