almicube 0.0.6 → 0.1.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 +4 -4
- data/Gemfile.lock +9 -1
- data/almicube.gemspec +1 -0
- data/lib/almicube/aggregator/base.rb +0 -2
- data/lib/almicube/bundler/today_bundler.rb +0 -3
- data/lib/almicube/cog.rb +6 -0
- data/lib/almicube/key.rb +12 -1
- data/lib/almicube/model.rb +8 -6
- data/lib/almicube/ranking/base.rb +42 -8
- data/lib/almicube/ranking/data_ranking.rb +0 -40
- data/lib/almicube/ranking/sub_ranking.rb +1 -14
- data/lib/almicube/version.rb +1 -1
- data/spec/almicube/aggregator/sum_aggregator_spec.rb +44 -22
- data/spec/almicube/builder/today_bundler_spec.rb +8 -0
- data/spec/almicube/ranking/base_spec.rb +54 -0
- data/spec/almicube/ranking/data_ranking_spec.rb +90 -2
- data/spec/almicube/selector/all_selector_spec.rb +5 -0
- data/spec/almicube/selector/has_many_selector_spec.rb +27 -0
- data/spec/spec_helper.rb +6 -0
- metadata +20 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: eb295b819df1854c96c9b2fbf911ab09b5063f8f
         | 
| 4 | 
            +
              data.tar.gz: 861bf7962f333e61d85bd695c9d3ab92a8611fbd
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 191a40acc01416bf0b3f4b50ff9601939f679dbe10c212a0eb4f4ebe82631f42d635988945cb3d0b3969511e6bfb41c592351be108b54da8923f1ac345c2fc72
         | 
| 7 | 
            +
              data.tar.gz: 1acffa0eeaed6337e4a8601b0df6890b57363594fe29c6faa1d6cf175a00cf61f727d32cf9b60944e3355666dfa3470781b34b77cf4ff425e3ff155a00dc8d6c
         | 
    
        data/Gemfile.lock
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            PATH
         | 
| 2 2 | 
             
              remote: .
         | 
| 3 3 | 
             
              specs:
         | 
| 4 | 
            -
                almicube (0.0. | 
| 4 | 
            +
                almicube (0.0.7)
         | 
| 5 5 | 
             
                  activemodel (~> 4.0)
         | 
| 6 6 | 
             
                  activesupport (~> 4.0)
         | 
| 7 7 | 
             
                  redis (~> 3.0)
         | 
| @@ -20,9 +20,11 @@ GEM | |
| 20 20 | 
             
                  tzinfo (~> 1.1)
         | 
| 21 21 | 
             
                builder (3.2.2)
         | 
| 22 22 | 
             
                diff-lcs (1.2.5)
         | 
| 23 | 
            +
                docile (1.1.3)
         | 
| 23 24 | 
             
                i18n (0.6.9)
         | 
| 24 25 | 
             
                json (1.8.1)
         | 
| 25 26 | 
             
                minitest (5.3.3)
         | 
| 27 | 
            +
                multi_json (1.10.0)
         | 
| 26 28 | 
             
                redis (3.0.7)
         | 
| 27 29 | 
             
                rspec (2.14.1)
         | 
| 28 30 | 
             
                  rspec-core (~> 2.14.0)
         | 
| @@ -32,6 +34,11 @@ GEM | |
| 32 34 | 
             
                rspec-expectations (2.14.5)
         | 
| 33 35 | 
             
                  diff-lcs (>= 1.1.3, < 2.0)
         | 
| 34 36 | 
             
                rspec-mocks (2.14.6)
         | 
| 37 | 
            +
                simplecov (0.8.2)
         | 
| 38 | 
            +
                  docile (~> 1.1.0)
         | 
| 39 | 
            +
                  multi_json
         | 
| 40 | 
            +
                  simplecov-html (~> 0.8.0)
         | 
| 41 | 
            +
                simplecov-html (0.8.0)
         | 
| 35 42 | 
             
                thread_safe (0.3.3)
         | 
| 36 43 | 
             
                tzinfo (1.1.0)
         | 
| 37 44 | 
             
                  thread_safe (~> 0.1)
         | 
| @@ -42,3 +49,4 @@ PLATFORMS | |
| 42 49 | 
             
            DEPENDENCIES
         | 
| 43 50 | 
             
              almicube!
         | 
| 44 51 | 
             
              rspec (~> 2.0)
         | 
| 52 | 
            +
              simplecov
         | 
    
        data/almicube.gemspec
    CHANGED
    
    
    
        data/lib/almicube/cog.rb
    CHANGED
    
    
    
        data/lib/almicube/key.rb
    CHANGED
    
    | @@ -10,10 +10,15 @@ module Almicube | |
| 10 10 |  | 
| 11 11 | 
             
                def initialize(ranking, options={})
         | 
| 12 12 | 
             
                  @ranking = ranking
         | 
| 13 | 
            -
                  @options = ranking.options.merge(options) | 
| 13 | 
            +
                  @options = select ranking.options.merge(options)
         | 
| 14 14 | 
             
                  @config ||= Config.config
         | 
| 15 15 | 
             
                end
         | 
| 16 16 |  | 
| 17 | 
            +
                def merge!(options={})
         | 
| 18 | 
            +
                  @options = select @options.merge(options)
         | 
| 19 | 
            +
                  self
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
             | 
| 17 22 | 
             
                def [](name)
         | 
| 18 23 | 
             
                  options[name.to_sym]
         | 
| 19 24 | 
             
                end
         | 
| @@ -43,5 +48,11 @@ module Almicube | |
| 43 48 |  | 
| 44 49 | 
             
                alias :to_s :to_str
         | 
| 45 50 | 
             
                alias :inspect :to_str
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                protected
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                def select(options={})
         | 
| 55 | 
            +
                  options.select { |k| self.class::ALLOWED_OPTIONS.include? k.to_sym }
         | 
| 56 | 
            +
                end
         | 
| 46 57 | 
             
              end
         | 
| 47 58 | 
             
            end
         | 
    
        data/lib/almicube/model.rb
    CHANGED
    
    | @@ -23,16 +23,18 @@ module Almicube | |
| 23 23 | 
             
                            Almicube::AssociationProxy.new(self.class.#{ranker}_ranking(date), self)
         | 
| 24 24 | 
             
                          end
         | 
| 25 25 |  | 
| 26 | 
            -
                           | 
| 27 | 
            -
             | 
| 26 | 
            +
                          attr_accessor :current_ranking
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                          def #{ranker}_rank
         | 
| 29 | 
            +
                            @current_ranking.rank(self)
         | 
| 28 30 | 
             
                          end
         | 
| 29 31 |  | 
| 30 | 
            -
                          def #{ranker}_score | 
| 31 | 
            -
                            self | 
| 32 | 
            +
                          def #{ranker}_score
         | 
| 33 | 
            +
                            @current_ranking.score(self)
         | 
| 32 34 | 
             
                          end
         | 
| 33 35 |  | 
| 34 | 
            -
                          def #{ranker}_incr | 
| 35 | 
            -
                             | 
| 36 | 
            +
                          def #{ranker}_incr
         | 
| 37 | 
            +
                            @current_ranking.incr(score)
         | 
| 36 38 | 
             
                          end
         | 
| 37 39 | 
             
                        EVAL
         | 
| 38 40 | 
             
                      end
         | 
| @@ -5,19 +5,15 @@ module Almicube | |
| 5 5 | 
             
                  attr_accessor :per_page
         | 
| 6 6 |  | 
| 7 7 | 
             
                  def initialize(options={})
         | 
| 8 | 
            -
                     | 
| 9 | 
            -
                     | 
| 10 | 
            -
                     | 
| 8 | 
            +
                    self.selector = options[:selector]
         | 
| 9 | 
            +
                    self.aggregator = options[:aggregator] || Aggregator::SumAggregator.new
         | 
| 10 | 
            +
                    self.bundler = options[:bundler]
         | 
| 11 11 | 
             
                    @prefix = options[:prefix]
         | 
| 12 12 | 
             
                    @suffix = options[:suffix]
         | 
| 13 13 | 
             
                    @date = options[:date] || Date.today
         | 
| 14 14 | 
             
                    @class_name = options[:class_name]
         | 
| 15 15 | 
             
                    @class_name = @class_name.constantize if @class_name.is_a? String
         | 
| 16 16 | 
             
                    @per_page = options[:per_page] || 10
         | 
| 17 | 
            -
             | 
| 18 | 
            -
                    @selector.ranking = self unless @selector.nil?
         | 
| 19 | 
            -
                    @aggregator.ranking = self unless @aggregator.nil?
         | 
| 20 | 
            -
                    @bundler.ranking = self unless @bundler.nil?
         | 
| 21 17 | 
             
                  end
         | 
| 22 18 |  | 
| 23 19 | 
             
                  def records
         | 
| @@ -35,12 +31,38 @@ module Almicube | |
| 35 31 | 
             
                  def page(page=1)
         | 
| 36 32 | 
             
                    page = [1, page.to_i].max
         | 
| 37 33 | 
             
                    revrange = connection.zrevrange(key, (page - 1) * per_page, page * per_page - 1)
         | 
| 38 | 
            -
                    records = class_name.where("id IN (?)", revrange) | 
| 34 | 
            +
                    records = class_name.where("id IN (?)", revrange)
         | 
| 35 | 
            +
                    records.each { |record| record.current_ranking = self }
         | 
| 39 36 | 
             
                    revrange.inject([]) { |l, v| l << records.detect { |r| r.to_param == v } }
         | 
| 40 37 | 
             
                  end
         | 
| 41 38 |  | 
| 39 | 
            +
                  def selector=(value)
         | 
| 40 | 
            +
                    @selector = value
         | 
| 41 | 
            +
                    @selector.ranking = self unless @selector.nil?
         | 
| 42 | 
            +
                  end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                  def aggregator=(value)
         | 
| 45 | 
            +
                    @aggregator = value
         | 
| 46 | 
            +
                    @aggregator.ranking = self unless @aggregator.nil?
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                  def bundler=(value)
         | 
| 50 | 
            +
                    @bundler = value
         | 
| 51 | 
            +
                    @bundler.ranking = self unless @bundler.nil?
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  def cogs
         | 
| 55 | 
            +
                    cogs = []
         | 
| 56 | 
            +
                    cogs << @selector unless @selector.nil?
         | 
| 57 | 
            +
                    cogs << @aggregator unless @aggregator.nil?
         | 
| 58 | 
            +
                    cogs << @bundler unless @bundler.nil?
         | 
| 59 | 
            +
                    cogs
         | 
| 60 | 
            +
                  end
         | 
| 61 | 
            +
             | 
| 42 62 | 
             
                  def aggregate!(options = {})
         | 
| 63 | 
            +
                    cogs.each { |cog| cog.before_aggregate }
         | 
| 43 64 | 
             
                    @aggregator.aggregate self
         | 
| 65 | 
            +
                    cogs.each { |cog| cog.after_aggregate }
         | 
| 44 66 | 
             
                  end
         | 
| 45 67 |  | 
| 46 68 | 
             
                  def aggregate(options = {})
         | 
| @@ -54,6 +76,18 @@ module Almicube | |
| 54 76 | 
             
                    false
         | 
| 55 77 | 
             
                  end
         | 
| 56 78 |  | 
| 79 | 
            +
                  def score(item)
         | 
| 80 | 
            +
                    ( connection.zscore key, item.to_param ) || @options.fetch(:default_score, 0)
         | 
| 81 | 
            +
                  end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                  def rank(item)
         | 
| 84 | 
            +
                    connection.zrevrank(key, item.to_param) + 1
         | 
| 85 | 
            +
                  end
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                  def incr(item, score = 1)
         | 
| 88 | 
            +
                    connection.zincrby key, score, item.to_param
         | 
| 89 | 
            +
                  end
         | 
| 90 | 
            +
             | 
| 57 91 | 
             
                  protected
         | 
| 58 92 |  | 
| 59 93 | 
             
                  attr_reader :prefix, :suffix
         | 
| @@ -17,10 +17,6 @@ module Almicube | |
| 17 17 | 
             
                        default_score: 0,
         | 
| 18 18 | 
             
                        class_name: nil }
         | 
| 19 19 | 
             
                    end
         | 
| 20 | 
            -
             | 
| 21 | 
            -
                    def build(options={})
         | 
| 22 | 
            -
                      self.new options
         | 
| 23 | 
            -
                    end
         | 
| 24 20 | 
             
                  end
         | 
| 25 21 |  | 
| 26 22 | 
             
                  def initialize(options={})
         | 
| @@ -72,10 +68,6 @@ module Almicube | |
| 72 68 | 
             
                    SubRanking.new(self).ranged(name)
         | 
| 73 69 | 
             
                  end
         | 
| 74 70 |  | 
| 75 | 
            -
                  def per_page=(value)
         | 
| 76 | 
            -
                    @options[:per_page] = value
         | 
| 77 | 
            -
                  end
         | 
| 78 | 
            -
             | 
| 79 71 | 
             
                  def options
         | 
| 80 72 | 
             
                    @options.select{ |k| k != :type }.merge({ selector: selector, aggregator: aggregator })
         | 
| 81 73 | 
             
                  end
         | 
| @@ -91,38 +83,6 @@ module Almicube | |
| 91 83 | 
             
                  def default_score
         | 
| 92 84 | 
             
                    @options.fetch(:default_score, 0)
         | 
| 93 85 | 
             
                  end
         | 
| 94 | 
            -
             | 
| 95 | 
            -
                  def score(item)
         | 
| 96 | 
            -
                    actual_score = ( connection.zscore key, item.to_param ) || @options.fetch(:default_score, 0)
         | 
| 97 | 
            -
                    case @options[:as].to_s
         | 
| 98 | 
            -
                    when "Integer"
         | 
| 99 | 
            -
                      actual_score.to_i
         | 
| 100 | 
            -
                    when "Float"
         | 
| 101 | 
            -
                      actual_score.to_f
         | 
| 102 | 
            -
                    else
         | 
| 103 | 
            -
                      actual_score
         | 
| 104 | 
            -
                    end
         | 
| 105 | 
            -
                  end
         | 
| 106 | 
            -
             | 
| 107 | 
            -
                  def rank(item)
         | 
| 108 | 
            -
                    connection.zrevrank(key, item.to_param) + 1
         | 
| 109 | 
            -
                  end
         | 
| 110 | 
            -
             | 
| 111 | 
            -
                  def incr(item, score = 1)
         | 
| 112 | 
            -
                    connection.zincrby key, score, item.to_param
         | 
| 113 | 
            -
                  end
         | 
| 114 | 
            -
             | 
| 115 | 
            -
                  protected
         | 
| 116 | 
            -
             | 
| 117 | 
            -
                  def key_format(key_base, options)
         | 
| 118 | 
            -
                    key = key_base.to_s.clone
         | 
| 119 | 
            -
                    tmp_options = options.merge date: options.fetch(:date, Date.today).strftime(@options[:date_format])
         | 
| 120 | 
            -
                    tmp_options[:type] ||= :data
         | 
| 121 | 
            -
                    key.match( self.class::KEY_PATTERN ) do |m|
         | 
| 122 | 
            -
                      key.gsub! m[0], tmp_options.fetch(m[1].to_sym, '').to_s
         | 
| 123 | 
            -
                    end while key =~ self.class::KEY_PATTERN
         | 
| 124 | 
            -
                    key
         | 
| 125 | 
            -
                  end
         | 
| 126 86 | 
             
                end
         | 
| 127 87 | 
             
              end
         | 
| 128 88 | 
             
            end
         | 
| @@ -13,10 +13,7 @@ module Almicube | |
| 13 13 | 
             
                  end
         | 
| 14 14 |  | 
| 15 15 | 
             
                  def key
         | 
| 16 | 
            -
                    key = ranking.key
         | 
| 17 | 
            -
                    key[:type] = :built
         | 
| 18 | 
            -
                    key[:suffix] = suffix
         | 
| 19 | 
            -
                    key[:selector] = selector
         | 
| 16 | 
            +
                    key = ranking.key.merge!( type: :built, suffix: suffix, selector: selector )
         | 
| 20 17 | 
             
                    key[:distinction] = "%{date}:in-%{selector}" unless selector.is_a? Selector::AllSelector
         | 
| 21 18 | 
             
                    key
         | 
| 22 19 | 
             
                  end
         | 
| @@ -25,16 +22,6 @@ module Almicube | |
| 25 22 | 
             
                    ranking.key
         | 
| 26 23 | 
             
                  end
         | 
| 27 24 |  | 
| 28 | 
            -
                  def bundler=(value)
         | 
| 29 | 
            -
                    @bundler = value
         | 
| 30 | 
            -
                    value.ranking = self
         | 
| 31 | 
            -
                  end
         | 
| 32 | 
            -
             | 
| 33 | 
            -
                  def selector=(value)
         | 
| 34 | 
            -
                    @selector = value
         | 
| 35 | 
            -
                    value.ranking = self
         | 
| 36 | 
            -
                  end
         | 
| 37 | 
            -
             | 
| 38 25 | 
             
                  def ranged(name)
         | 
| 39 26 | 
             
                    bundler_class = "Almicube::Bundler::#{name.to_s.classify}Bundler".constantize
         | 
| 40 27 | 
             
                    self.bundler = bundler_class.new if bundler_class.is_a? Class
         | 
    
        data/lib/almicube/version.rb
    CHANGED
    
    
| @@ -8,31 +8,53 @@ describe Almicube::Aggregator::SumAggregator do | |
| 8 8 | 
             
              end
         | 
| 9 9 |  | 
| 10 10 | 
             
              describe "#aggregate" do
         | 
| 11 | 
            -
                 | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 14 | 
            -
             | 
| 15 | 
            -
             | 
| 16 | 
            -
             | 
| 17 | 
            -
                     | 
| 18 | 
            -
             | 
| 19 | 
            -
             | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
                    it { expect{ aggregator.aggregate }.not_to raise_error }
         | 
| 23 | 
            -
                    it { expect{ aggregator.aggregate }.to change{ @connection.zcard(key) }.by size }
         | 
| 24 | 
            -
             | 
| 25 | 
            -
                    describe "for score" do
         | 
| 26 | 
            -
                      before { aggregator.aggregate }
         | 
| 27 | 
            -
                      it { records.each { |record| expect(@connection.zscore(key, record.to_param)).to eq 100 } }
         | 
| 28 | 
            -
                    end
         | 
| 11 | 
            +
                let(:key) { "sample" }
         | 
| 12 | 
            +
                let(:aggregator) { described_class.new }
         | 
| 13 | 
            +
                let(:attribute) { :score }
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                context "with data ranking" do
         | 
| 16 | 
            +
                  [10, 100, 300].each do |size|
         | 
| 17 | 
            +
                    describe "and #{size} records" do
         | 
| 18 | 
            +
                      let(:ranking) { double( records: records, selector: nil, data?: true, key: key, attribute_name: attribute ) }
         | 
| 19 | 
            +
                      let(:records) { size.times.map { |i| double( to_param: i+1, score: 100, access: (i + 2) * 12 ) } }
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                      before { aggregator.ranking = ranking }
         | 
| 29 22 |  | 
| 30 | 
            -
             | 
| 31 | 
            -
                       | 
| 32 | 
            -
                       | 
| 33 | 
            -
             | 
| 23 | 
            +
                      it { expect(records.length).to eq size }
         | 
| 24 | 
            +
                      it { expect{ aggregator.aggregate }.not_to raise_error }
         | 
| 25 | 
            +
                      it { expect{ aggregator.aggregate }.to change{ @connection.zcard(key) }.by size }
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                      describe "for score" do
         | 
| 28 | 
            +
                        before { aggregator.aggregate }
         | 
| 29 | 
            +
                        it { records.each { |record| expect(@connection.zscore(key, record.to_param)).to eq 100 } }
         | 
| 30 | 
            +
                      end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                      describe "for access" do
         | 
| 33 | 
            +
                        let(:attribute) { :access }
         | 
| 34 | 
            +
                        before { aggregator.aggregate }
         | 
| 35 | 
            +
                        it { records.each { |record| expect(@connection.zscore(key, record.to_param)).to eq (record.to_param+1)*12} }
         | 
| 36 | 
            +
                      end
         | 
| 34 37 | 
             
                    end
         | 
| 35 38 | 
             
                  end
         | 
| 36 39 | 
             
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                context "with sub ranking" do
         | 
| 42 | 
            +
                  let(:size) { 10 }
         | 
| 43 | 
            +
                  let(:keys) { ["sample1", "sample2"] }
         | 
| 44 | 
            +
                  let(:selector) { double( interstore: nil, before_aggregate: nil ) }
         | 
| 45 | 
            +
                  let(:ranking) { double( bundled_keys: keys, selector: selector, data?: false, key: key ) }
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                  before do
         | 
| 48 | 
            +
                    keys.each { |key| size.times { |i| @connection.zadd(key, 10, i) } }
         | 
| 49 | 
            +
                    aggregator.ranking = ranking
         | 
| 50 | 
            +
                  end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                  it { expect{ aggregator.aggregate }.to change{ @connection.zcard(key) }.by size }
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  describe "for score" do
         | 
| 55 | 
            +
                    before { aggregator.aggregate }
         | 
| 56 | 
            +
                    it { size.times { |i| expect(@connection.zscore(key, i)).to eq 20 } }
         | 
| 57 | 
            +
                  end
         | 
| 58 | 
            +
                end
         | 
| 37 59 | 
             
              end
         | 
| 38 60 | 
             
            end
         | 
| @@ -1,9 +1,63 @@ | |
| 1 1 | 
             
            require 'spec_helper'
         | 
| 2 2 |  | 
| 3 3 | 
             
            describe Almicube::Ranking::Base do
         | 
| 4 | 
            +
              before { @connection = Redis.new }
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              def setup_datastore(key)
         | 
| 7 | 
            +
                @connection.del key
         | 
| 8 | 
            +
                @connection.zadd key, 10, 1
         | 
| 9 | 
            +
                @connection.zadd key, 20, 2
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
             | 
| 4 12 | 
             
              describe "#bundled_keys" do
         | 
| 5 13 | 
             
                let(:bundler) { double( keys: ["1", "2"], :"ranking=" => nil ) }
         | 
| 6 14 | 
             
                let(:ranking) { described_class.new bundler: bundler }
         | 
| 7 15 | 
             
                it { expect(ranking.bundled_keys).to eq ["1", "2"] }
         | 
| 8 16 | 
             
              end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              describe "#page" do
         | 
| 19 | 
            +
                let(:ranking) { described_class.new class_name: MockModel }
         | 
| 20 | 
            +
                before do
         | 
| 21 | 
            +
                  ranking.stub(:key) { "sample" }
         | 
| 22 | 
            +
                  setup_datastore "sample"
         | 
| 23 | 
            +
                  Almicube::Config.config.stub(:connection) { @connection }
         | 
| 24 | 
            +
                  MockModel.should_receive(:where).with("id IN (?)", ["2", "1"]) { [] }
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
                it { ranking.page 1 }
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              describe "#data?" do
         | 
| 30 | 
            +
                let(:ranking) { described_class.new }
         | 
| 31 | 
            +
                it { expect(ranking).not_to be_data }
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
              describe "score" do
         | 
| 35 | 
            +
                let(:ranking) { described_class.new class_name: MockModel }
         | 
| 36 | 
            +
                before do
         | 
| 37 | 
            +
                  ranking.stub(:key) { "sample" }
         | 
| 38 | 
            +
                  setup_datastore "sample"
         | 
| 39 | 
            +
                  Almicube::Config.config.stub(:connection) { @connection }
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
                it { expect(ranking.score(1)).to eq 10 }
         | 
| 42 | 
            +
                it { expect(ranking.score(2)).to eq 20 }
         | 
| 43 | 
            +
              end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
              describe "rank" do
         | 
| 46 | 
            +
                let(:ranking) { described_class.new class_name: MockModel }
         | 
| 47 | 
            +
                before do
         | 
| 48 | 
            +
                  ranking.stub(:key) { "sample" }
         | 
| 49 | 
            +
                  setup_datastore "sample"
         | 
| 50 | 
            +
                  Almicube::Config.config.stub(:connection) { @connection }
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
                it { expect(ranking.rank(1)).to eq 2 }
         | 
| 53 | 
            +
                it { expect(ranking.rank(2)).to eq 1 }
         | 
| 54 | 
            +
              end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
              describe "#aggregate" do
         | 
| 57 | 
            +
                context "raises exception from aggregator" do
         | 
| 58 | 
            +
                  let(:ranking) { described_class.new class_name: MockModel }
         | 
| 59 | 
            +
                  before { ranking.stub(:aggregate!).and_raise "exception" }
         | 
| 60 | 
            +
                  it { expect(ranking.aggregate).to eq false }
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
              end
         | 
| 9 63 | 
             
            end
         | 
| @@ -35,6 +35,47 @@ describe Almicube::Ranking::DataRanking do | |
| 35 35 | 
             
                it { expect(ranking.per_page).to eq 10 }
         | 
| 36 36 | 
             
              end
         | 
| 37 37 |  | 
| 38 | 
            +
              describe "#default_score" do
         | 
| 39 | 
            +
                context "don't set default_score" do
         | 
| 40 | 
            +
                  let(:ranking) { described_class.new }
         | 
| 41 | 
            +
                  it { expect(ranking.default_score).to eq 0 }
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                context "sets default_score by options" do
         | 
| 45 | 
            +
                  let(:ranking) { described_class.new default_score: 0 }
         | 
| 46 | 
            +
                  it { expect(ranking.default_score).to eq 0 }
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
              end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
              describe "#attribute_name" do
         | 
| 51 | 
            +
                context "don't set attribute_name" do
         | 
| 52 | 
            +
                  let(:ranking) { described_class.new }
         | 
| 53 | 
            +
                  it { expect(ranking.attribute_name).to eq :score }
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                context "sets attribute_name by options" do
         | 
| 57 | 
            +
                  %i[score access].each do |name|
         | 
| 58 | 
            +
                    describe "to #{name}" do
         | 
| 59 | 
            +
                      let(:ranking) { described_class.new attribute_name: :score }
         | 
| 60 | 
            +
                      it { expect(ranking.attribute_name).to eq :score }
         | 
| 61 | 
            +
                    end
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
              end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
              describe "#date" do
         | 
| 67 | 
            +
                context "don't set date" do
         | 
| 68 | 
            +
                  let(:ranking) { described_class.new }
         | 
| 69 | 
            +
                  it { expect(ranking.date).to eq Date.today }
         | 
| 70 | 
            +
                end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                context "sets date by options" do
         | 
| 73 | 
            +
                  let(:date) { Date.today - 12.days }
         | 
| 74 | 
            +
                  let(:ranking) { described_class.new date: date }
         | 
| 75 | 
            +
                  it { expect(ranking.date).to eq date }
         | 
| 76 | 
            +
                end
         | 
| 77 | 
            +
              end
         | 
| 78 | 
            +
             | 
| 38 79 | 
             
              describe "#class_name" do
         | 
| 39 80 | 
             
                let(:ranking) { described_class.new class_name: MockModel }
         | 
| 40 81 | 
             
                it { expect(ranking.class_name).to eq MockModel }
         | 
| @@ -96,8 +137,55 @@ describe Almicube::Ranking::DataRanking do | |
| 96 137 | 
             
                  it { expect(options).to have_key key }
         | 
| 97 138 | 
             
                end
         | 
| 98 139 |  | 
| 99 | 
            -
                %i[type].each  | 
| 100 | 
            -
             | 
| 140 | 
            +
                %i[type].each { |key| it { expect(options).not_to have_key key } }
         | 
| 141 | 
            +
              end
         | 
| 142 | 
            +
             | 
| 143 | 
            +
              describe "#in" do
         | 
| 144 | 
            +
                context "with correct instance" do
         | 
| 145 | 
            +
                  let(:ranking) { described_class.new class_name: MockModel }
         | 
| 146 | 
            +
                  let(:target) { double( mock_models: [] ) }
         | 
| 147 | 
            +
             | 
| 148 | 
            +
                  before do
         | 
| 149 | 
            +
                    Almicube::Selector::HasManySelector.any_instance.stub(:"ranking=")
         | 
| 150 | 
            +
                  end
         | 
| 151 | 
            +
             | 
| 152 | 
            +
                  it { expect(ranking.in(target)).to be_kind_of Almicube::Ranking::SubRanking }
         | 
| 153 | 
            +
                end
         | 
| 154 | 
            +
             | 
| 155 | 
            +
                context "without correct instance" do
         | 
| 156 | 
            +
                  let(:ranking) { described_class.new }
         | 
| 157 | 
            +
                  let(:target) { double() }
         | 
| 158 | 
            +
             | 
| 159 | 
            +
                  before do
         | 
| 160 | 
            +
                    Almicube::Selector::HasManySelector.any_instance.stub(:"ranking=")
         | 
| 161 | 
            +
                  end
         | 
| 162 | 
            +
             | 
| 163 | 
            +
                  it { expect(ranking.in(target)).not_to be_kind_of Almicube::Ranking::SubRanking }
         | 
| 101 164 | 
             
                end
         | 
| 102 165 | 
             
              end
         | 
| 166 | 
            +
             | 
| 167 | 
            +
              describe "#exists?" do
         | 
| 168 | 
            +
                let(:ranking) { described_class.new }
         | 
| 169 | 
            +
                let(:key) { "sample" }
         | 
| 170 | 
            +
                before do
         | 
| 171 | 
            +
                  @connection = Redis.new
         | 
| 172 | 
            +
                  Almicube::Config.config.stub(:connection) { @connection }
         | 
| 173 | 
            +
                  ranking.stub(:key).and_return(key)
         | 
| 174 | 
            +
                end
         | 
| 175 | 
            +
             | 
| 176 | 
            +
                context "exists key in redis" do
         | 
| 177 | 
            +
                  before { @connection.del key }
         | 
| 178 | 
            +
                  it { expect(ranking).not_to be_exists }
         | 
| 179 | 
            +
                end
         | 
| 180 | 
            +
             | 
| 181 | 
            +
                context "don't exist key in redis" do
         | 
| 182 | 
            +
                  before { @connection.zadd key, 10, 10 }
         | 
| 183 | 
            +
                  it { expect(ranking).to be_exists }
         | 
| 184 | 
            +
                end
         | 
| 185 | 
            +
              end
         | 
| 186 | 
            +
             | 
| 187 | 
            +
              describe "#ranged" do
         | 
| 188 | 
            +
                let(:ranking) { described_class.new }
         | 
| 189 | 
            +
                it { expect(ranking.ranged(:yesterday)).to be_kind_of Almicube::Ranking::SubRanking }
         | 
| 190 | 
            +
              end
         | 
| 103 191 | 
             
            end
         | 
| @@ -16,6 +16,11 @@ describe Almicube::Selector::AllSelector do | |
| 16 16 | 
             
                end
         | 
| 17 17 | 
             
              end
         | 
| 18 18 |  | 
| 19 | 
            +
              describe "#label" do
         | 
| 20 | 
            +
                let(:selector) { described_class.new }
         | 
| 21 | 
            +
                it { expect(selector.label).to eq :data }
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
             | 
| 19 24 | 
             
              it_behaves_like "ranking cog" do
         | 
| 20 25 | 
             
                let(:target) { described_class.new }
         | 
| 21 26 | 
             
              end
         | 
| @@ -0,0 +1,27 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Almicube::Selector::HasManySelector do
         | 
| 4 | 
            +
              before { @connection = Redis.new }
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              describe "#before_aggregate" do
         | 
| 7 | 
            +
                let(:target) { double( items: [double(to_param: 10)] ) }
         | 
| 8 | 
            +
                let(:selector) { described_class.new target: target, association_name: :items }
         | 
| 9 | 
            +
                before { Almicube::Config.config.stub(:connection) { @connection } }
         | 
| 10 | 
            +
                before { selector.stub(:interstore_key) { "sample-has-many-selector" } }
         | 
| 11 | 
            +
                it { expect{ selector.before_aggregate }.to change{ @connection.zcard("sample-has-many-selector") }.by 1 }
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              describe "#label" do
         | 
| 15 | 
            +
                let(:target) { double( items: [double(to_param: 10)], to_param: 10) }
         | 
| 16 | 
            +
                let(:selector) { described_class.new target: target, association_name: :items }
         | 
| 17 | 
            +
                it { expect(selector.label).to eq "r_spec/mocks/mock-10" }
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              describe "#interstore" do
         | 
| 21 | 
            +
                let(:target) { double( items: [double(to_param: 10)], to_param: 10) }
         | 
| 22 | 
            +
                let(:key) { Almicube::Key.new double(options: {}), {} }
         | 
| 23 | 
            +
                let(:selector) { described_class.new target: target, association_name: :items }
         | 
| 24 | 
            +
                before { selector.ranking = double(key: key) }
         | 
| 25 | 
            +
                it { expect(selector.interstore.to_s).to match /r_spec\/mocks\/mock-10/ }
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
            end
         | 
    
        data/spec/spec_helper.rb
    CHANGED
    
    | @@ -4,6 +4,12 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__))) | |
| 4 4 | 
             
            require 'bundler/setup'
         | 
| 5 5 | 
             
            Bundler.require
         | 
| 6 6 |  | 
| 7 | 
            +
            require 'simplecov'
         | 
| 8 | 
            +
            SimpleCov.start 'rails' do
         | 
| 9 | 
            +
              add_filter '/tmp/'
         | 
| 10 | 
            +
              add_filter '/spec/'
         | 
| 11 | 
            +
            end
         | 
| 12 | 
            +
             | 
| 7 13 | 
             
            Dir[File.join(File.dirname(__FILE__), "supports", "*.rb")].each {|f| require f}
         | 
| 8 14 | 
             
            Dir[File.join(File.dirname(__FILE__), "mocks", "*.rb")].each {|f| require f}
         | 
| 9 15 |  | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: almicube
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.0 | 
| 4 | 
            +
              version: 0.1.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - niaeashes
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2014-05- | 
| 11 | 
            +
            date: 2014-05-15 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: redis
         | 
| @@ -66,6 +66,20 @@ dependencies: | |
| 66 66 | 
             
                - - ~>
         | 
| 67 67 | 
             
                  - !ruby/object:Gem::Version
         | 
| 68 68 | 
             
                    version: '2.0'
         | 
| 69 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 70 | 
            +
              name: simplecov
         | 
| 71 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 72 | 
            +
                requirements:
         | 
| 73 | 
            +
                - - '>='
         | 
| 74 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 75 | 
            +
                    version: '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'
         | 
| 69 83 | 
             
            description: Provide raking system for your ActiveRecord Model on Rails 4 with SortedSet
         | 
| 70 84 | 
             
              of Redis DataBase.
         | 
| 71 85 | 
             
            email:
         | 
| @@ -106,6 +120,7 @@ files: | |
| 106 120 | 
             
            - lib/almicube/selector/method_selector.rb
         | 
| 107 121 | 
             
            - lib/almicube/version.rb
         | 
| 108 122 | 
             
            - spec/almicube/aggregator/sum_aggregator_spec.rb
         | 
| 123 | 
            +
            - spec/almicube/builder/today_bundler_spec.rb
         | 
| 109 124 | 
             
            - spec/almicube/builder_sprc.rb
         | 
| 110 125 | 
             
            - spec/almicube/bundler/days_ago_bundler_spec.rb
         | 
| 111 126 | 
             
            - spec/almicube/bundler/today_bundler_spec.rb
         | 
| @@ -116,6 +131,7 @@ files: | |
| 116 131 | 
             
            - spec/almicube/ranking/data_ranking_spec.rb
         | 
| 117 132 | 
             
            - spec/almicube/ranking/sub_ranking_spec.rb
         | 
| 118 133 | 
             
            - spec/almicube/selector/all_selector_spec.rb
         | 
| 134 | 
            +
            - spec/almicube/selector/has_many_selector_spec.rb
         | 
| 119 135 | 
             
            - spec/almicube/selector/method_selector_spec.rb
         | 
| 120 136 | 
             
            - spec/almicube/selector/mock_spec.rb
         | 
| 121 137 | 
             
            - spec/mocks/aggregator.rb
         | 
| @@ -150,6 +166,7 @@ specification_version: 4 | |
| 150 166 | 
             
            summary: Ranking extension for your model
         | 
| 151 167 | 
             
            test_files:
         | 
| 152 168 | 
             
            - spec/almicube/aggregator/sum_aggregator_spec.rb
         | 
| 169 | 
            +
            - spec/almicube/builder/today_bundler_spec.rb
         | 
| 153 170 | 
             
            - spec/almicube/builder_sprc.rb
         | 
| 154 171 | 
             
            - spec/almicube/bundler/days_ago_bundler_spec.rb
         | 
| 155 172 | 
             
            - spec/almicube/bundler/today_bundler_spec.rb
         | 
| @@ -160,6 +177,7 @@ test_files: | |
| 160 177 | 
             
            - spec/almicube/ranking/data_ranking_spec.rb
         | 
| 161 178 | 
             
            - spec/almicube/ranking/sub_ranking_spec.rb
         | 
| 162 179 | 
             
            - spec/almicube/selector/all_selector_spec.rb
         | 
| 180 | 
            +
            - spec/almicube/selector/has_many_selector_spec.rb
         | 
| 163 181 | 
             
            - spec/almicube/selector/method_selector_spec.rb
         | 
| 164 182 | 
             
            - spec/almicube/selector/mock_spec.rb
         | 
| 165 183 | 
             
            - spec/mocks/aggregator.rb
         |