Redistat::Finder returns collections with results

within it properly, and all specs passing
This commit is contained in:
2010-11-07 23:37:17 +00:00
parent 426f006426
commit 6d04d58d82
6 changed files with 102 additions and 37 deletions

View File

@@ -1,7 +1,16 @@
module Redistat
class Collection < Array
class Collection < ::Array
attr_accessor :from
attr_accessor :till
attr_accessor :depth
attr_accessor :total
def initialize(options = {})
@from = options[:from] ||= nil
@till = options[:till] ||= nil
@depth = options[:depth] ||= nil
end
end
end

View File

@@ -26,27 +26,47 @@ module Redistat
def find_by_interval(options = {})
@options.merge!(options)
raise InvalidOptions.new if !valid_options?
date_sets = Finder::DateSet.new(@options[:from], @options[:till], @options[:depth], @options[:interval])
key = build_key
col = Collection.new(@options)
col.total = Result.new(@options)
build_date_sets.each do |set|
set[:add].each do |date|
result = Result.new
result.date = Date.new(date).to_time
db.hgetall("#{key.prefix}#{date}").each do |k, v|
result[k] = v
col.total.set_or_incr(k, v.to_i)
end
col << result
end
end
col
end
def find_by_magic(options = {})
@options.merge!(options)
raise InvalidOptions.new if !valid_options?
date_sets = Finder::DateSet.new(@options[:from], @options[:till], @options[:depth], @options[:interval])
key = Key.new(@options[:scope], @options[:label])
total_sum = Result.new
date_sets.each do |set|
col = Collection.new(@options)
col.total = Result.new(@options)
col << col.total
build_date_sets.each do |set|
sum = Result.new
sum = summarize_add_keys(set[:add], key, sum)
sum = summarize_rem_keys(set[:rem], key, sum)
sum.each do |k, v|
total_sum.set_or_incr(k, v.to_i)
col.total.set_or_incr(k, v.to_i)
end
end
total_sum.date = Date.new(@options[:from], @options[:depth])
total_sum.till = Date.new(@options[:till], @options[:depth])
total_sum
col
end
def build_date_sets
Finder::DateSet.new(@options[:from], @options[:till], @options[:depth], @options[:interval])
end
def build_key
Key.new(@options[:scope], @options[:label])
end
def summarize_add_keys(sets, key, sum)

View File

@@ -1,9 +1,18 @@
module Redistat
class Result < ::Hash
attr_accessor :date
attr_accessor :from
attr_accessor :till
alias :date :from
alias :date= :from=
def initialize(options = {})
@from = options[:from] ||= nil
@till = options[:till] ||= nil
end
def set_or_incr(key, value)
self[key] = 0 if !self.has_key?(key)
self[key] += value

13
spec/collection_spec.rb Normal file
View File

@@ -0,0 +1,13 @@
require "spec_helper"
describe Redistat::Collection do
it "should should initialize properly" do
options = {:from => "from", :till => "till", :depth => "depth"}
result = Redistat::Collection.new(options)
result.from.should == options[:from]
result.till.should == options[:till]
result.depth.should == options[:depth]
end
end

View File

@@ -44,32 +44,41 @@ describe Redistat::Finder do
end
it "should fetch stats properly" do
create_example_stats
first_stat, last_stat = create_example_stats
three_hours_ago = 3.hours.ago
two_hours_from_now = 2.hours.from_now
depth = :hour
stats = Redistat::Finder.find({:from => first_stat, :till => last_stat, :scope => @scope, :label => @label, :depth => :hour})
stats.from.should == first_stat
stats.till.should == last_stat
stats.depth.should == :hour
stats = Redistat::Finder.find({:from => three_hours_ago, :till => two_hours_from_now, :scope => @scope, :label => @label, :depth => depth})
stats.should == { "views" => 9, "visitors" => 6 }
stats.date.to_s.should == three_hours_ago.to_rs.to_s(depth)
stats.till.to_s.should == two_hours_from_now.to_rs.to_s(depth)
stats.total.should == { "views" => 12, "visitors" => 8 }
stats.total.from.should == first_stat
stats.total.till.should == last_stat
stats.first.should == stats.total
end
it "should fetch data per unit when interval option is specified" do
first_stat, last_stat = create_example_stats
stats = Redistat::Finder.find(:from => first_stat, :till => last_stat, :scope => @scope, :label => @label, :depth => :hour, :interval => :hour)
stats.from.should == first_stat
stats.till.should == last_stat
stats.total.should == { "views" => 12, "visitors" => 8 }
stats[0].should == {}
stats[0].date.should == Time.parse("2010-05-14 12:00")
stats[1].should == {"visitors"=>"4", "views"=>"6"}
stats[1].date.should == Time.parse("2010-05-14 13:00")
stats[2].should == {"visitors"=>"2", "views"=>"3"}
stats[2].date.should == Time.parse("2010-05-14 14:00")
stats[3].should == {"visitors"=>"2", "views"=>"3"}
stats[3].date.should == Time.parse("2010-05-14 15:00")
stats[4].should == {}
stats[4].date.should == Time.parse("2010-05-14 16:00")
end
it "should return empty hash when attempting to fetch non-existent results" do
stats = Redistat::Finder.find({:from => 3.hours.ago, :till => 2.hours.from_now, :scope => @scope, :label => @label, :depth => :hour})
stats.should == {}
end
it "should fetch data per unit when interval option is specified" do
create_example_stats
three_hours_ago = 3.hours.ago
two_hours_from_now = 2.hours.from_now
depth = :hour
stats = Redistat::Finder.find(:from => 3.hours.ago, :till => 2.hours.ago, :scope => @scope, :label => @label, :depth => :hour, :interval => :hour)
puts "\n>>>>>> stats: " + stats.inspect + "\n"
stats.total.should == {}
end
it "should throw error on invalid options" do
@@ -84,12 +93,15 @@ describe Redistat::Finder do
# helper methods
def create_example_stats
key = Redistat::Key.new(@scope, @label, 2.hours.ago)
key = Redistat::Key.new(@scope, @label, (first = Time.parse("2010-05-14 13:43")))
Redistat::Summary.update(key, @stats, :hour)
key = Redistat::Key.new(@scope, @label, 1.hours.ago)
key = Redistat::Key.new(@scope, @label, Time.parse("2010-05-14 13:53"))
Redistat::Summary.update(key, @stats, :hour)
key = Redistat::Key.new(@scope, @label, 24.minutes.ago)
key = Redistat::Key.new(@scope, @label, Time.parse("2010-05-14 14:32"))
Redistat::Summary.update(key, @stats, :hour)
key = Redistat::Key.new(@scope, @label, (last = Time.parse("2010-05-14 15:02")))
Redistat::Summary.update(key, @stats, :hour)
[first - 1.hour, last + 1.hour]
end
end

View File

@@ -2,9 +2,11 @@ require "spec_helper"
describe Redistat::Result do
before(:each) do
@name = "PageViews"
@scope = Redistat::Scope.new(@name)
it "should should initialize properly" do
options = {:from => "from", :till => "till"}
result = Redistat::Result.new(options)
result.from.should == "from"
result.till.should == "till"
end
it "should have set_or_incr method" do