added extension to DateTime to easily convert it into a ReportingPeriod, fixed bugs for MySQL and PostgreSQL, added specs for all groupings - reportable - Fork of reportable required by WarVox, from hdm/reportable.
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
---
(DIR) commit c1e1f6626fa5fb21ddae68c25d89855d1f74f2ef
(DIR) parent 686d110e727d3a6144e037d4791f520c434409df
(HTM) Author: marcoow <marco.otte-witte@simplabs.com>
Date: Wed, 10 Dec 2008 23:05:44 +0800
added extension to DateTime to easily convert it into a ReportingPeriod, fixed bugs for MySQL and PostgreSQL, added specs for all groupings
Signed-off-by: Marco Otte-Witte <marco.otte-witte@simplabs.com>
Diffstat:
A lib/kvlr/core_extensions/date_time… | 19 +++++++++++++++++++
M lib/kvlr/reports_as_sparkline/cumu… | 10 ++++++----
M lib/kvlr/reports_as_sparkline/grou… | 23 +++++++++++++++++++----
M lib/kvlr/reports_as_sparkline/repo… | 2 +-
M lib/kvlr/reports_as_sparkline/repo… | 2 +-
A lib/kvlr/reports_as_sparkline/repo… | 83 +++++++++++++++++++++++++++++++
M spec/boot.rb | 2 +-
M spec/db/schema.rb | 2 +-
M spec/other/cumulated_report_spec.rb | 82 ++++++++++++++++++++-----------
M spec/other/grouping_spec.rb | 43 +++++++++++++++++++++++++++----
M spec/other/report_cache_spec.rb | 18 +++++++++---------
M spec/other/report_spec.rb | 104 ++++++++++++++++++-------------
A spec/other/reporting_period_spec.rb | 208 +++++++++++++++++++++++++++++++
13 files changed, 502 insertions(+), 96 deletions(-)
---
(DIR) diff --git a/lib/kvlr/core_extensions/date_time.rb b/lib/kvlr/core_extensions/date_time.rb
@@ -0,0 +1,19 @@
+module Simplabs
+
+ module CoreExtensions
+
+ module DateTime
+
+ ::DateTime.class_eval do
+
+ def to_reporting_period(grouping)
+ Kvlr::ReportsAsSparkline::ReportsAsSparkline.new(grouping, self)
+ end
+
+ end
+
+ end
+
+ end
+
+end
(DIR) diff --git a/lib/kvlr/reports_as_sparkline/cumulated_report.rb b/lib/kvlr/reports_as_sparkline/cumulated_report.rb
@@ -11,11 +11,13 @@ module Kvlr #:nodoc:
protected
def cumulate(data)
- acc = 0
- data.collect do |element|
- acc += element[1].to_i
- [element[0], acc]
+ acc = 0.0
+ result = []
+ data.reverse_each do |element|
+ acc += element[1].to_f
+ result << [element[0], acc]
end
+ result.reverse
end
end
(DIR) diff --git a/lib/kvlr/reports_as_sparkline/grouping.rb b/lib/kvlr/reports_as_sparkline/grouping.rb
@@ -14,11 +14,26 @@ module Kvlr #:nodoc:
end
def date_parts_from_db_string(db_string)
- parts = db_string.split('/').map(&:to_i)
- if @identifier == :week
- parts[1] += 1
+ if ActiveRecord::Base.connection.class.to_s == 'ActiveRecord::ConnectionAdapters::PostgreSQLAdapter'
+ if @identifier == :hour
+ return (db_string[0..9].split('-') + db_string[11..12]).map(&:to_i)
+ elsif @identifier == :day
+ return db_string[0..9].split('-').map(&:to_i)
+ elsif @identifier == :week
+ parts = db_string[0..9].split('-').map(&:to_i)
+ date = Date.new(parts[0], parts[1], parts[2])
+ return [date.year, date.cweek]
+ elsif @identifier == :month
+ return db_string[0..6].split('-')[0..1].map(&:to_i)
+ end
+ else
+ parts = db_string.split('/').map(&:to_i)
+ return parts if ActiveRecord::Base.connection.class.to_s == 'ActiveRecord::ConnectionAdapters::MysqlAdapter'
+ if @identifier == :week
+ parts[1] += 1
+ end
+ parts
end
- parts
end
def to_sql(date_column_name)
(DIR) diff --git a/lib/kvlr/reports_as_sparkline/report.rb b/lib/kvlr/reports_as_sparkline/report.rb
@@ -25,7 +25,7 @@ module Kvlr #:nodoc:
ensure_valid_options(options, :run)
custom_conditions = options.key?(:conditions)
options.reverse_merge!(@options)
- ReportCache.cached_transaction(self, options[:limit], custom_conditions) do |begin_at|
+ ReportCache.process(self, options[:limit], custom_conditions) do |begin_at|
read_data(begin_at, options[:conditions])
end
end
(DIR) diff --git a/lib/kvlr/reports_as_sparkline/report_cache.rb b/lib/kvlr/reports_as_sparkline/report_cache.rb
@@ -6,7 +6,7 @@ module Kvlr #:nodoc:
serialize :reporting_period, Kvlr::ReportsAsSparkline::ReportingPeriod
- def self.cached_transaction(report, limit, no_cache = false, &block)
+ def self.process(report, limit, no_cache = false, &block)
raise ArgumentError.new('A block must be given') unless block_given?
self.transaction do
cached_data = if no_cache
(DIR) diff --git a/lib/kvlr/reports_as_sparkline/reporting_period.rb b/lib/kvlr/reports_as_sparkline/reporting_period.rb
@@ -0,0 +1,83 @@
+module Kvlr #:nodoc:
+
+ module ReportsAsSparkline #:nodoc:
+
+ class ReportingPeriod
+
+ attr_reader :date_time, :grouping
+
+ def initialize(grouping, date_time = DateTime.now)
+ @grouping = grouping
+ @date_time = parse_date_time(date_time)
+ end
+
+ def self.first(grouping, limit)
+ return case grouping.identifier
+ when :hour
+ self.new(grouping, DateTime.now - limit.hours)
+ when :day
+ self.new(grouping, DateTime.now - limit.days)
+ when :week
+ self.new(grouping, DateTime.now - limit.weeks)
+ when :month
+ date = DateTime.now - limit.months
+ self.new(grouping, Date.new(date.year, date.month, 1))
+ end
+ end
+
+ def self.from_db_string(grouping, db_string)
+ parts = grouping.date_parts_from_db_string(db_string)
+ result = case grouping.identifier
+ when :hour
+ self.new(grouping, DateTime.new(parts[0], parts[1], parts[2], parts[3], 0, 0))
+ when :day
+ self.new(grouping, Date.new(parts[0], parts[1], parts[2]))
+ when :week
+ self.new(grouping, Date.commercial(parts[0], parts[1]))
+ when :month
+ self.new(grouping, Date.new(parts[0], parts[1], 1))
+ end
+ result
+ end
+
+ def previous
+ return case @grouping.identifier
+ when :hour
+ self.class.new(@grouping, @date_time - 1.hour)
+ when :day
+ self.class.new(@grouping, @date_time - 1.day)
+ when :week
+ self.class.new(@grouping, @date_time - 1.week)
+ when :month
+ self.class.new(@grouping, @date_time - 1.month)
+ end
+ end
+
+ def ==(other)
+ if other.class == Kvlr::ReportsAsSparkline::ReportingPeriod
+ return @date_time.to_s == other.date_time.to_s && @grouping.identifier.to_s == other.grouping.identifier.to_s
+ end
+ false
+ end
+
+ private
+
+ def parse_date_time(date_time)
+ return case @grouping.identifier
+ when :hour
+ DateTime.new(date_time.year, date_time.month, date_time.day, date_time.hour)
+ when :day
+ date_time.to_date
+ when :week
+ date_time = (date_time - date_time.wday.days) + 1
+ Date.new(date_time.year, date_time.month, date_time.day)
+ when :month
+ Date.new(date_time.year, date_time.month, 1)
+ end
+ end
+
+ end
+
+ end
+
+end
(DIR) diff --git a/spec/boot.rb b/spec/boot.rb
@@ -19,5 +19,5 @@ FileUtils.mkdir_p File.join(File.dirname(__FILE__), 'log')
ActiveRecord::Base.logger = Logger.new(File.join(File.dirname(__FILE__), 'log', 'spec.log'))
databases = YAML::load(IO.read(File.join(File.dirname(__FILE__), 'db', 'database.yml')))
-ActiveRecord::Base.establish_connection(databases['sqlite3'])
+ActiveRecord::Base.establish_connection(databases['postgresql'])
load(File.join(File.dirname(__FILE__), 'db', 'schema.rb'))
(DIR) diff --git a/spec/db/schema.rb b/spec/db/schema.rb
@@ -14,7 +14,7 @@ ActiveRecord::Schema.define(:version => 1) do
t.string :grouping, :null => false
t.string :aggregation, :null => false
t.float :value, :null => false, :default => 0
- t.datetime :reporting_period, :null => false
+ t.string :reporting_period, :null => false
t.timestamps
end
(DIR) diff --git a/spec/other/cumulated_report_spec.rb b/spec/other/cumulated_report_spec.rb
@@ -8,46 +8,72 @@ describe Kvlr::ReportsAsSparkline::CumulatedReport do
describe '.run' do
- before(:all) do
- User.create!(:login => 'test 1', :created_at => Time.now - 1.week, :profile_visits => 1)
- User.create!(:login => 'test 2', :created_at => Time.now - 2.weeks, :profile_visits => 2)
- User.create!(:login => 'test 3', :created_at => Time.now - 2.weeks, :profile_visits => 3)
- end
-
it 'should cumulate the data' do
@report.should_receive(:cumulate).once
@report.run
end
- it 'should return correct data for :aggregation => :count' do
- result = @report.run.to_a
+ for grouping in [:hour, :day, :week, :month] do
- result[7][1].should == 1
- result[14][1].should == 3
- end
+ describe "for grouping #{grouping.to_s}" do
- it 'should return correct data for :aggregation => :sum' do
- @report = Kvlr::ReportsAsSparkline::CumulatedReport.new(User, :registrations, :aggregation => :sum, :value_column_name => :profile_visits)
- result = @report.run().to_a
+ before(:all) do
+ User.create!(:login => 'test 1', :created_at => Time.now - 1.send(grouping), :profile_visits => 1)
+ User.create!(:login => 'test 2', :created_at => Time.now - 3.send(grouping), :profile_visits => 2)
+ User.create!(:login => 'test 3', :created_at => Time.now - 3.send(grouping), :profile_visits => 3)
+ end
- result[7][1].should == 1
- result[14][1].should == 6
- end
+ it 'should return correct data for :aggregation => :count' do
+ @report = Kvlr::ReportsAsSparkline::CumulatedReport.new(User, :registrations, :aggregation => :count, :grouping => grouping)
+ result = @report.run
- it 'should return correct data with custom conditions' do
- result = @report.run(:conditions => ['login IN (?)', ['test 1', 'test 2']]).to_a
+ result[0][1].should == 3
+ result[1][1].should == 3
+ result[2][1].should == 2
+ result[3][1].should == 2
+ end
- result[7][1].should == 1
- result[14][1].should == 2
- end
+ it 'should return correct data for :aggregation => :sum' do
+ @report = Kvlr::ReportsAsSparkline::CumulatedReport.new(User, :registrations, :aggregation => :sum, :grouping => grouping, :value_column_name => :profile_visits)
+ result = @report.run().to_a
- after(:all) do
- User.destroy_all
- end
+ result[0][1].should == 6
+ result[1][1].should == 6
+ result[2][1].should == 5
+ result[3][1].should == 5
+ end
+
+ it 'should return correct data with custom conditions for :aggregation => :count' do
+ @report = Kvlr::ReportsAsSparkline::CumulatedReport.new(User, :registrations, :aggregation => :count, :grouping => grouping)
+ result = @report.run(:conditions => ['login IN (?)', ['test 1', 'test 2']]).to_a
+
+ result[0][1].should == 2
+ result[1][1].should == 2
+ result[2][1].should == 1
+ result[3][1].should == 1
+ end
+
+ it 'should return correct data with custom conditions for :aggregation => :sum' do
+ @report = Kvlr::ReportsAsSparkline::CumulatedReport.new(User, :registrations, :aggregation => :sum, :grouping => grouping, :value_column_name => :profile_visits)
+ result = @report.run(:conditions => ['login IN (?)', ['test 1', 'test 2']]).to_a
+
+ result[0][1].should == 3
+ result[1][1].should == 3
+ result[2][1].should == 2
+ result[3][1].should == 2
+ end
+
+ after(:all) do
+ User.destroy_all
+ end
+
+ after(:each) do
+ Kvlr::ReportsAsSparkline::ReportCache.destroy_all
+ end
+
+ end
- after do
- Kvlr::ReportsAsSparkline::ReportCache.destroy_all
end
end
@@ -59,7 +85,7 @@ describe Kvlr::ReportsAsSparkline::CumulatedReport do
second = (Time.now - 1.week).to_s
data = [[first, 1], [second, 2]]
- @report.send(:cumulate, data).should == [[first, 1], [second, 3]]
+ @report.send(:cumulate, data).should == [[first, 3.0], [second, 2.0]]
end
end
(DIR) diff --git a/spec/other/grouping_spec.rb b/spec/other/grouping_spec.rb
@@ -87,7 +87,7 @@ describe Kvlr::ReportsAsSparkline::Grouping do
end
describe '#date_parts_from_db_string' do
-
+=begin
for grouping in [[:hour, '2008/12/31/12'], [:day, '2008/12/31'], [:month, '2008/12']] do
it "should split the string with '/' for grouping :#{grouping[0].to_s}" do
@@ -97,12 +97,45 @@ describe Kvlr::ReportsAsSparkline::Grouping do
end
end
+=end
+ describe 'for SQLite3' do
+
+ it 'should split the string with "/" and increment the week by 1 for grouping :week' do
+ ActiveRecord::Base.connection.stub!(:class).and_return(ActiveRecord::ConnectionAdapters::SQLite3Adapter)
+ db_string = '2008/2'
+ expected = [2008, 3]
- it 'should split the string with "/" and increment the week by 1 for grouping :week' do
- db_string = '2008/2'
- expected = [2008, 3]
+ Kvlr::ReportsAsSparkline::Grouping.new(:week).date_parts_from_db_string(db_string).should == expected
+ end
+
+ end
+
+ describe 'for PostgreSQL' do
+
+ before do
+ ActiveRecord::Base.connection.stub!(:class).and_return(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
+ end
+
+ it 'should split the date part of the string with "-" for grouping :day' do
+ Kvlr::ReportsAsSparkline::Grouping.new(:day).date_parts_from_db_string('2008-12-03 00:00:00').should == [2008, 12, 03]
+ end
+
+ it 'should split the date part of the string with "-" for grouping :week' do
+ Kvlr::ReportsAsSparkline::Grouping.new(:week).date_parts_from_db_string('2008-12-01 00:00:00').should == [2008, 49]
+ end
+
+ end
+
+ describe 'for MySQL' do
+
+ it 'should split the string with "/" for grouping :week' do
+ ActiveRecord::Base.connection.stub!(:class).and_return(ActiveRecord::ConnectionAdapters::MysqlAdapter)
+ db_string = '2008/2'
+ expected = [2008, 2]
+
+ Kvlr::ReportsAsSparkline::Grouping.new(:week).date_parts_from_db_string(db_string).should == expected
+ end
- Kvlr::ReportsAsSparkline::Grouping.new(:week).date_parts_from_db_string(db_string).should == expected
end
end
(DIR) diff --git a/spec/other/report_cache_spec.rb b/spec/other/report_cache_spec.rb
@@ -2,7 +2,7 @@ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
describe Kvlr::ReportsAsSparkline::ReportCache do
- describe '#cached_transaction' do
+ describe '#process' do
before do
@report = Kvlr::ReportsAsSparkline::Report.new(User, :registrations)
@@ -12,19 +12,19 @@ describe Kvlr::ReportsAsSparkline::ReportCache do
it 'should raise an ArgumentError if no block is given' do
lambda do
- Kvlr::ReportsAsSparkline::ReportCache.cached_transaction(@report, 100)
+ Kvlr::ReportsAsSparkline::ReportCache.process(@report, 100)
end.should raise_error(ArgumentError)
end
it 'sould start a transaction' do
Kvlr::ReportsAsSparkline::ReportCache.should_receive(:transaction)
- Kvlr::ReportsAsSparkline::ReportCache.cached_transaction(@report, 100) {}
+ Kvlr::ReportsAsSparkline::ReportCache.process(@report, 100) {}
end
it 'should yield to the given block' do
lambda {
- Kvlr::ReportsAsSparkline::ReportCache.cached_transaction(@report, 100) { raise YieldMatchException.new }
+ Kvlr::ReportsAsSparkline::ReportCache.process(@report, 100) { raise YieldMatchException.new }
}.should raise_error(YieldMatchException)
end
@@ -41,17 +41,17 @@ describe Kvlr::ReportsAsSparkline::ReportCache do
:order => "reporting_period DESC"
)
- Kvlr::ReportsAsSparkline::ReportCache.cached_transaction(@report, 100) { [] }
+ Kvlr::ReportsAsSparkline::ReportCache.process(@report, 100) { [] }
end
it 'should update the cache' do
Kvlr::ReportsAsSparkline::ReportCache.should_receive(:update_cache)
- Kvlr::ReportsAsSparkline::ReportCache.cached_transaction(@report, 100) { [] }
+ Kvlr::ReportsAsSparkline::ReportCache.process(@report, 100) { [] }
end
it 'should yield the first reporting period if the cache is empty' do
- Kvlr::ReportsAsSparkline::ReportCache.cached_transaction(@report, 100) do |begin_at|
+ Kvlr::ReportsAsSparkline::ReportCache.process(@report, 100) do |begin_at|
begin_at.should == Kvlr::ReportsAsSparkline::ReportingPeriod.first(@report.grouping, 100).date_time
[]
end
@@ -69,7 +69,7 @@ describe Kvlr::ReportsAsSparkline::ReportCache do
})
Kvlr::ReportsAsSparkline::ReportCache.stub!(:find).and_return([cached])
- Kvlr::ReportsAsSparkline::ReportCache.cached_transaction(@report, 100) do |begin_at|
+ Kvlr::ReportsAsSparkline::ReportCache.process(@report, 100) do |begin_at|
begin_at.should == reporting_period.date_time
[]
end
@@ -80,7 +80,7 @@ describe Kvlr::ReportsAsSparkline::ReportCache do
it 'should not read any data from cache' do
Kvlr::ReportsAsSparkline::ReportCache.should_not_receive(:find)
- Kvlr::ReportsAsSparkline::ReportCache.cached_transaction(@report, 100, true) {}
+ Kvlr::ReportsAsSparkline::ReportCache.process(@report, 100, true) {}
end
end
(DIR) diff --git a/spec/other/report_spec.rb b/spec/other/report_spec.rb
@@ -8,69 +8,82 @@ describe Kvlr::ReportsAsSparkline::Report do
describe '.run' do
- it 'should run a cached transaction' do
- Kvlr::ReportsAsSparkline::ReportCache.should_receive(:cached_transaction).once.with(@report, 100, false)
+ it 'should process the data with the report cache' do
+ Kvlr::ReportsAsSparkline::ReportCache.should_receive(:process).once.with(@report, 100, false)
@report.run
end
- it 'should run a cached transaction but specify no_cache when custom conditions are given' do
- Kvlr::ReportsAsSparkline::ReportCache.should_receive(:cached_transaction).once.with(@report, 100, true)
+ it 'should process the data with the report cache and specify no_cache when custom conditions are given' do
+ Kvlr::ReportsAsSparkline::ReportCache.should_receive(:process).once.with(@report, 100, true)
@report.run(:conditions => { :some => :condition })
end
- describe do
+ it 'should validate the specified options for the :run context' do
+ @report.should_receive(:ensure_valid_options).once.with({ :limit => 3 }, :run)
- before(:all) do
- User.create!(:login => 'test 1', :created_at => Time.now - 1.week, :profile_visits => 1)
- User.create!(:login => 'test 2', :created_at => Time.now - 2.weeks, :profile_visits => 2)
- User.create!(:login => 'test 3', :created_at => Time.now - 2.weeks, :profile_visits => 3)
- end
+ result = @report.run(:limit => 3)
+ end
- it 'should validate the specified options for the :run context' do
- @report.should_receive(:ensure_valid_options).once.with({ :limit => 3 }, :run)
+ for grouping in [:hour, :day, :week, :month] do
- result = @report.run(:limit => 3)
- end
+ describe "for grouping #{grouping.to_s}" do
- it 'should return correct data for :aggregation => :count and grouping :day' do
- @report = Kvlr::ReportsAsSparkline::Report.new(User, :registrations, :aggregation => :count, :grouping => :day)
- result = @report.run.to_a
+ before(:all) do
+ User.create!(:login => 'test 1', :created_at => Time.now - 1.send(grouping), :profile_visits => 1)
+ User.create!(:login => 'test 2', :created_at => Time.now - 3.send(grouping), :profile_visits => 2)
+ User.create!(:login => 'test 3', :created_at => Time.now - 3.send(grouping), :profile_visits => 3)
+ end
- result[7][1].should == 1
- result[14][1].should == 2
- end
+ it 'should return correct data for :aggregation => :count' do
+ @report = Kvlr::ReportsAsSparkline::Report.new(User, :registrations, :aggregation => :count, :grouping => grouping)
+ result = @report.run.to_a
- it 'should return correct data for :aggregation => :count and grouping :week' do
- @report = Kvlr::ReportsAsSparkline::Report.new(User, :registrations, :aggregation => :count, :grouping => :week)
- result = @report.run.to_a
+ result[0][1].should == 0
+ result[1][1].should == 1
+ result[2][1].should == 0
+ result[3][1].should == 2
+ end
- result[1][1].should == 1
- result[2][1].should == 2
- end
+ it 'should return correct data for :aggregation => :sum' do
+ @report = Kvlr::ReportsAsSparkline::Report.new(User, :registrations, :aggregation => :sum, :grouping => grouping, :value_column_name => :profile_visits)
+ result = @report.run().to_a
- it 'should return correct data for :aggregation => :sum' do
- @report = Kvlr::ReportsAsSparkline::Report.new(User, :registrations, :aggregation => :sum, :value_column_name => :profile_visits)
- result = @report.run().to_a
+ result[0][1].should == 0
+ result[1][1].should == 1
+ result[2][1].should == 0
+ result[3][1].should == 5
+ end
- result[7][1].should == 1
- result[14][1].should == 5
- end
+ it 'should return correct data with custom conditions for :aggregation => :count' do
+ @report = Kvlr::ReportsAsSparkline::Report.new(User, :registrations, :aggregation => :count, :grouping => grouping)
+ result = @report.run(:conditions => ['login IN (?)', ['test 1', 'test 2']]).to_a
- it 'should return correct data with custom conditions' do
- result = @report.run(:conditions => ['login IN (?)', ['test 1', 'test 2']]).to_a
+ result[0][1].should == 0
+ result[1][1].should == 1
+ result[2][1].should == 0
+ result[3][1].should == 1
+ end
- result[7][1].should == 1
- result[14][1].should == 1
- end
+ it 'should return correct data with custom conditions for :aggregation => :sum' do
+ @report = Kvlr::ReportsAsSparkline::Report.new(User, :registrations, :aggregation => :sum, :grouping => grouping, :value_column_name => :profile_visits)
+ result = @report.run(:conditions => ['login IN (?)', ['test 1', 'test 2']]).to_a
- after(:all) do
- User.destroy_all
- end
+ result[0][1].should == 0
+ result[1][1].should == 1
+ result[2][1].should == 0
+ result[3][1].should == 2
+ end
+
+ after(:all) do
+ User.destroy_all
+ end
+
+ after(:each) do
+ Kvlr::ReportsAsSparkline::ReportCache.destroy_all
+ end
- after do
- Kvlr::ReportsAsSparkline::ReportCache.destroy_all
end
end
@@ -80,11 +93,18 @@ describe Kvlr::ReportsAsSparkline::Report do
describe '.read_data' do
it 'should invoke the aggregation method on the model' do
+ @report = Kvlr::ReportsAsSparkline::Report.new(User, :registrations, :aggregation => :count)
User.should_receive(:count).once.and_return([])
@report.send(:read_data, Time.now)
end
+ it 'should build the conditions' do
+ @report.should_receive(:setup_conditions).once.and_return([])
+
+ @report.send(:read_data, Time.now)
+ end
+
end
describe '.setup_conditions' do
(DIR) diff --git a/spec/other/reporting_period_spec.rb b/spec/other/reporting_period_spec.rb
@@ -0,0 +1,208 @@
+require File.join(File.dirname(__FILE__), '..', 'spec_helper')
+
+describe Kvlr::ReportsAsSparkline::ReportingPeriod do
+
+ describe '.date_time' do
+
+ describe 'for grouping :hour' do
+
+ it 'should return the date and time with minutes = seconds = 0 for grouping :hour' do
+ date_time = DateTime.now
+ reporting_period = Kvlr::ReportsAsSparkline::ReportingPeriod.new(Kvlr::ReportsAsSparkline::Grouping.new(:hour), date_time)
+
+ reporting_period.date_time.should == DateTime.new(date_time.year, date_time.month, date_time.day, date_time.hour, 0, 0)
+ end
+
+ end
+
+ describe 'for grouping :day' do
+
+ it 'should return the date part only for grouping :day' do
+ date_time = DateTime.now
+ reporting_period = Kvlr::ReportsAsSparkline::ReportingPeriod.new(Kvlr::ReportsAsSparkline::Grouping.new(:day), date_time)
+
+ reporting_period.date_time.should == date_time.to_date
+ end
+
+ end
+
+ describe 'for grouping :week' do
+
+ it 'should return the date of the monday of the week date_time is in for any day in that the week' do
+ date_time = DateTime.new(2008, 11, 27)
+ reporting_period = Kvlr::ReportsAsSparkline::ReportingPeriod.new(Kvlr::ReportsAsSparkline::Grouping.new(:week), date_time)
+
+ reporting_period.date_time.should == DateTime.new(date_time.year, date_time.month, 24)
+ end
+
+ it 'should return the date of the monday of the week date_time is in when the specified date is a monday already' do
+ date_time = DateTime.new(2008, 11, 24) #this is a monday already, should not change
+ reporting_period = Kvlr::ReportsAsSparkline::ReportingPeriod.new(Kvlr::ReportsAsSparkline::Grouping.new(:week), date_time)
+
+ reporting_period.date_time.should == DateTime.new(date_time.year, date_time.month, 24) # expect to get monday 24th again
+ end
+
+ it 'should return the date of the monday of the week date_time is in when the monday is in a different month than the specified date' do
+ date_time = DateTime.new(2008, 11, 1) #this is a saturday
+ reporting_period = Kvlr::ReportsAsSparkline::ReportingPeriod.new(Kvlr::ReportsAsSparkline::Grouping.new(:week), date_time)
+
+ reporting_period.date_time.should == DateTime.new(date_time.year, 10, 27) # expect to get the monday before the 1st, which is in october
+ end
+
+ it 'should return the date of the monday of the week date_time is in when the monday is in a different year than the specified date' do
+ date_time = DateTime.new(2009, 1, 1) #this is a thursday
+ reporting_period = Kvlr::ReportsAsSparkline::ReportingPeriod.new(Kvlr::ReportsAsSparkline::Grouping.new(:week), date_time)
+
+ reporting_period.date_time.should == DateTime.new(2008, 12, 29) # expect to get the monday before the 1st, which is in december 2008
+ end
+
+ end
+
+ describe 'for grouping :month' do
+
+ it 'should return the date with day = 1 for grouping :month' do
+ date_time = Time.now
+ reporting_period = Kvlr::ReportsAsSparkline::ReportingPeriod.new(Kvlr::ReportsAsSparkline::Grouping.new(:month), date_time)
+
+ reporting_period.date_time.should == Date.new(date_time.year, date_time.month, 1)
+ end
+
+ end
+
+ end
+
+ describe '#from_db_string' do
+
+ it 'should return a reporting period with the correct date and time and with minutes = seconds = 0 for grouping :hour' do
+ grouping = Kvlr::ReportsAsSparkline::Grouping.new(:hour)
+ grouping.stub!(:date_parts_from_db_string).and_return([2008, 1, 1, 12])
+
+ Kvlr::ReportsAsSparkline::ReportingPeriod.from_db_string(grouping, '').date_time.should == DateTime.new(2008, 1, 1, 12, 0, 0)
+ end
+
+ it 'should return a reporting period with the date part only for grouping :day' do
+ grouping = Kvlr::ReportsAsSparkline::Grouping.new(:day)
+ grouping.stub!(:date_parts_from_db_string).and_return([2008, 1, 1])
+
+ Kvlr::ReportsAsSparkline::ReportingPeriod.from_db_string(grouping, '').date_time.should == Date.new(2008, 1, 1)
+ end
+
+ it 'should return a reporting period with the date part of the monday of the week the date is in for grouping :week' do
+ grouping = Kvlr::ReportsAsSparkline::Grouping.new(:week)
+ grouping.stub!(:date_parts_from_db_string).and_return([2008, 1])
+
+ Kvlr::ReportsAsSparkline::ReportingPeriod.from_db_string(grouping, '').date_time.should == Date.new(2007, 12, 31)
+ end
+
+ it 'should return a reporting period with the correct date and with day = 1 for grouping :month' do
+ grouping = Kvlr::ReportsAsSparkline::Grouping.new(:month)
+ grouping.stub!(:date_parts_from_db_string).and_return([2008, 1])
+
+ Kvlr::ReportsAsSparkline::ReportingPeriod.from_db_string(grouping, '').date_time.should == Date.new(2008, 1, 1)
+ end
+
+ end
+
+ describe '.previous' do
+
+ describe 'for grouping :hour' do
+
+ it 'should return a reporting period with date and time one hour before the current period' do
+ now = Time.now
+ reporting_period = Kvlr::ReportsAsSparkline::ReportingPeriod.new(Kvlr::ReportsAsSparkline::Grouping.new(:hour), now)
+ expected = now - 1.hour
+
+ reporting_period.previous.date_time.should == DateTime.new(expected.year, expected.month, expected.day, expected.hour)
+ end
+
+ end
+
+ describe 'for grouping :day' do
+
+ it 'should return a reporting period with date one day before the current period' do
+ now = Time.now
+ reporting_period = Kvlr::ReportsAsSparkline::ReportingPeriod.new(Kvlr::ReportsAsSparkline::Grouping.new(:day), now)
+ expected = now - 1.day
+
+ reporting_period.previous.date_time.should == Date.new(expected.year, expected.month, expected.day)
+ end
+
+ end
+
+ describe 'for grouping :week' do
+
+ it 'should return a reporting period with date one week before the current period' do
+ now = DateTime.now
+ reporting_period = Kvlr::ReportsAsSparkline::ReportingPeriod.new(Kvlr::ReportsAsSparkline::Grouping.new(:week), now)
+ expected = reporting_period.date_time - 1.week
+
+ reporting_period.previous.date_time.should == Date.new(expected.year, expected.month, expected.day)
+ end
+
+ end
+
+ describe 'for grouping :month' do
+
+ it 'should return a reporting period with date one month before the current period' do
+ now = Time.now
+ reporting_period = Kvlr::ReportsAsSparkline::ReportingPeriod.new(Kvlr::ReportsAsSparkline::Grouping.new(:month), now)
+ expected = reporting_period.date_time - 1.month
+
+ reporting_period.previous.date_time.should == Date.new(expected.year, expected.month, 1)
+ end
+
+ end
+
+ end
+
+ describe '.==' do
+
+ it 'should return true for 2 reporting periods with the same date_time and grouping' do
+ now = DateTime.now
+ reporting_period1 = Kvlr::ReportsAsSparkline::ReportingPeriod.new(Kvlr::ReportsAsSparkline::Grouping.new(:month), now)
+ reporting_period2 = Kvlr::ReportsAsSparkline::ReportingPeriod.new(Kvlr::ReportsAsSparkline::Grouping.new(:month), now)
+
+ (reporting_period1 == reporting_period2).should == true
+ end
+
+ it 'should return false for 2 reporting periods with the same date_time but different groupings' do
+ now = Time.now
+ reporting_period1 = Kvlr::ReportsAsSparkline::ReportingPeriod.new(Kvlr::ReportsAsSparkline::Grouping.new(:month), now)
+ reporting_period2 = Kvlr::ReportsAsSparkline::ReportingPeriod.new(Kvlr::ReportsAsSparkline::Grouping.new(:day), now)
+
+ (reporting_period1 == reporting_period2).should == false
+ end
+
+ end
+
+ describe '#first' do
+
+ before do
+ @now = DateTime.now
+ DateTime.stub!(:now).and_return(@now)
+ end
+
+ it 'should return a reporting period with the date part of (DateTime.now - limit.hours) for grouping :hour' do
+ reporting_period = Kvlr::ReportsAsSparkline::ReportingPeriod.first(Kvlr::ReportsAsSparkline::Grouping.new(:hour), 3)
+ expected = @now - 3.hours
+
+ reporting_period.date_time.should == DateTime.new(expected.year, expected.month, expected.day, expected.hour, 0, 0)
+ end
+
+ it 'should return a reporting period with the date part of (DateTime.now - limit.days) for grouping :day' do
+ reporting_period = Kvlr::ReportsAsSparkline::ReportingPeriod.first(Kvlr::ReportsAsSparkline::Grouping.new(:day), 3)
+ expected = @now - 3.days
+
+ reporting_period.date_time.should == Date.new(expected.year, expected.month, expected.day)
+ end
+
+ it 'should return a reporting period with the date of monday of the week at (DateTime.now - limit.weeks) for grouping :week' do
+ DateTime.stub!(:now).and_return(DateTime.new(2008, 12, 31, 0, 0, 0)) #wednesday
+ reporting_period = Kvlr::ReportsAsSparkline::ReportingPeriod.first(Kvlr::ReportsAsSparkline::Grouping.new(:week), 3)
+
+ reporting_period.date_time.should == DateTime.new(2008, 12, 8) #the monday 3 weeks earlier
+ end
+
+ end
+
+end