when end date is specified, data for the corresponding reporting period is now always included (:live_data may not be specified anymore in combination with :end_date) (closes #1) - reportable - Fork of reportable required by WarVox, from hdm/reportable.
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
---
(DIR) commit 929610c2345e54b6f1740f0f2e545440d9c2d3a4
(DIR) parent ca12152ec76255deacf609fed517a71f7901013b
(HTM) Author: Marco Otte-Witte <marco.otte-witte@simplabs.com>
Date: Wed, 29 Apr 2009 18:32:17 +0200
when end date is specified, data for the corresponding reporting period is now always included (:live_data may not be specified anymore in combination with :end_date) (closes #1)
Diffstat:
M lib/simplabs/reports_as_sparkline/… | 3 ++-
M lib/simplabs/reports_as_sparkline/… | 10 +++++-----
M lib/simplabs/reports_as_sparkline/… | 16 +++++++++++++++-
M spec/classes/report_cache_spec.rb | 2 +-
M spec/classes/report_spec.rb | 94 ++++++++++++++++++++++++++-----
M spec/classes/reporting_period_spec… | 62 ++++++++++++++++++++++++++++---
6 files changed, 159 insertions(+), 28 deletions(-)
---
(DIR) diff --git a/lib/simplabs/reports_as_sparkline/report.rb b/lib/simplabs/reports_as_sparkline/report.rb
@@ -108,7 +108,8 @@ module Simplabs #:nodoc:
raise ArgumentError.new('Options :live_data and :end_date may not both be specified!') if options[:live_data] && options[:end_date]
raise ArgumentError.new("Invalid grouping #{options[:grouping]}!") if options[:grouping] && ![:hour, :day, :week, :month].include?(options[:grouping])
raise ArgumentError.new("Invalid conditions: #{options[:conditions].inspect}!") if options[:conditions] && !options[:conditions].is_a?(Array) && !options[:conditions].is_a?(Hash)
- raise ArgumentError.new("Invalid end date: #{options[:end_date].inspect}; must be a DateTime!") if options[:end_date] && !options[:end_date].is_a?(DateTime)
+ raise ArgumentError.new("Invalid end date: #{options[:end_date].inspect}; must be a DateTime!") if options[:end_date] && !options[:end_date].is_a?(DateTime) && !options[:end_date].is_a?(Time)
+ raise ArgumentError.new('End date may not be in the future!') if options[:end_date] && options[:end_date] > DateTime.now
end
end
(DIR) diff --git a/lib/simplabs/reports_as_sparkline/report_cache.rb b/lib/simplabs/reports_as_sparkline/report_cache.rb
@@ -10,7 +10,7 @@ module Simplabs #:nodoc:
raise ArgumentError.new('A block must be given') unless block_given?
self.transaction do
cached_data = []
- first_reporting_period = ReportingPeriod.first(options[:grouping], options[:limit], options[:end_date])
+ first_reporting_period = ReportingPeriod.first(options[:grouping], (options[:end_date] ? options[:limit] - 1 : options[:limit]), options[:end_date])
last_reporting_period = options[:end_date] ? ReportingPeriod.new(options[:grouping], options[:end_date]) : nil
if cache
@@ -22,7 +22,7 @@ module Simplabs #:nodoc:
new_data = if !options[:live_data] && last_cached_reporting_period == ReportingPeriod.new(options[:grouping]).previous
[]
else
- end_date = options[:live_data] ? nil : last_reporting_period && last_reporting_period.date_time
+ end_date = options[:live_data] ? nil : (options[:end_date] ? last_reporting_period.last_date_time : nil)
yield((last_cached_reporting_period.next rescue first_reporting_period).date_time, end_date)
end
@@ -35,9 +35,9 @@ module Simplabs #:nodoc:
def self.prepare_result(new_data, cached_data, report, options, cache = true)
new_data = new_data.map { |data| [ReportingPeriod.from_db_string(options[:grouping], data[0]), data[1]] }
result = cached_data.map { |cached| [cached.reporting_period, cached.value] }
- last_reporting_period = ReportingPeriod.new(options[:grouping], options[:end_date])
- reporting_period = cached_data.empty? ? ReportingPeriod.first(options[:grouping], options[:limit], options[:end_date]) : ReportingPeriod.new(options[:grouping], cached_data.last.reporting_period).next
- while reporting_period < last_reporting_period
+ last_reporting_period = ReportingPeriod.new(options[:grouping])
+ reporting_period = cached_data.empty? ? ReportingPeriod.first(options[:grouping], (options[:end_date] ? options[:limit] - 1 : options[:limit]), options[:end_date]) : ReportingPeriod.new(options[:grouping], cached_data.last.reporting_period).next
+ while reporting_period < (options[:end_date] ? ReportingPeriod.new(options[:grouping], options[:end_date]).next : last_reporting_period)
cached = build_cached_data(report, options[:grouping], options[:limit], reporting_period, find_value(new_data, reporting_period))
cached.save! if cache
result << [reporting_period.date_time, cached.value]
(DIR) diff --git a/lib/simplabs/reports_as_sparkline/reporting_period.rb b/lib/simplabs/reports_as_sparkline/reporting_period.rb
@@ -71,10 +71,24 @@ module Simplabs #:nodoc:
raise ArgumentError.new("Can only compare instances of #{Simplabs::ReportsAsSparkline::ReportingPeriod.klass}")
end
+ def last_date_time #:nodoc:
+ case @grouping.identifier
+ when :hour
+ DateTime.new(@date_time.year, @date_time.month, @date_time.day, @date_time.hour, 59, 59)
+ when :day
+ DateTime.new(@date_time.year, @date_time.month, @date_time.day, 23, 59, 59)
+ when :week
+ date_time = (@date_time - @date_time.wday.days) + 7.days
+ Date.new(date_time.year, date_time.month, date_time.day)
+ when :month
+ Date.new(@date_time.year, @date_time.month, (Date.new(@date_time.year, 12, 31) << (12 - @date_time.month)).day)
+ end
+ end
+
private
def parse_date_time(date_time)
- return case @grouping.identifier
+ case @grouping.identifier
when :hour
DateTime.new(date_time.year, date_time.month, date_time.day, date_time.hour)
when :day
(DIR) diff --git a/spec/classes/report_cache_spec.rb b/spec/classes/report_cache_spec.rb
@@ -120,7 +120,7 @@ describe Simplabs::ReportsAsSparkline::ReportCache do
@report.options[:grouping].identifier.to_s,
@report.aggregation.to_s,
10,
- Simplabs::ReportsAsSparkline::ReportingPeriod.first(@report.options[:grouping], 10).date_time,
+ Simplabs::ReportsAsSparkline::ReportingPeriod.first(@report.options[:grouping], 9).date_time,
Simplabs::ReportsAsSparkline::ReportingPeriod.new(@report.options[:grouping], end_date).date_time
],
:limit => 10,
(DIR) diff --git a/spec/classes/report_spec.rb b/spec/classes/report_spec.rb
@@ -70,26 +70,53 @@ describe Simplabs::ReportsAsSparkline::Report do
for grouping in [:hour, :day, :week, :month] do
- describe "for grouping #{grouping.to_s}" do
+ describe "for grouping :#{grouping.to_s}" do
- [true, false].each do |live_data|
+ before(:all) do
+ User.create!(:login => 'test 1', :created_at => Time.now, :profile_visits => 2)
+ User.create!(:login => 'test 2', :created_at => Time.now - 1.send(grouping), :profile_visits => 1)
+ User.create!(:login => 'test 3', :created_at => Time.now - 3.send(grouping), :profile_visits => 2)
+ User.create!(:login => 'test 4', :created_at => Time.now - 3.send(grouping), :profile_visits => 3)
+ end
- describe "with :live_data = #{live_data}" do
+ describe 'when :end_date is specified' do
+
+ describe 'the returned result' do
+
+ before do
+ @end_date = DateTime.now - 1.send(grouping)
+ @grouping = Simplabs::ReportsAsSparkline::Grouping.new(grouping)
+ @report = Simplabs::ReportsAsSparkline::Report.new(User, :registrations,
+ :grouping => grouping,
+ :limit => 10,
+ :end_date => @end_date
+ )
+ @result = @report.run
+ end
- before(:all) do
- User.create!(:login => 'test 1', :created_at => Time.now, :profile_visits => 2)
- User.create!(:login => 'test 2', :created_at => Time.now - 1.send(grouping), :profile_visits => 1)
- User.create!(:login => 'test 3', :created_at => Time.now - 3.send(grouping), :profile_visits => 2)
- User.create!(:login => 'test 4', :created_at => Time.now - 3.send(grouping), :profile_visits => 3)
+ it "should start with the reporting period (end_date - limit.#{grouping.to_s})" do
+ @result.first[0].should == Simplabs::ReportsAsSparkline::ReportingPeriod.new(@grouping, @end_date - 9.send(grouping)).date_time
end
+ it "should end with the reporting period of the specified end date" do
+ @result.last[0].should == Simplabs::ReportsAsSparkline::ReportingPeriod.new(@grouping, @end_date).date_time
+ end
+
+ end
+
+ end
+
+ [true, false].each do |live_data|
+
+ describe "with :live_data = #{live_data}" do
+
describe 'the returned result' do
before do
@grouping = Simplabs::ReportsAsSparkline::Grouping.new(grouping)
@report = Simplabs::ReportsAsSparkline::Report.new(User, :registrations,
- :grouping => grouping,
- :limit => 10,
+ :grouping => grouping,
+ :limit => 10,
:live_data => live_data
)
@result = @report.run
@@ -228,7 +255,7 @@ describe Simplabs::ReportsAsSparkline::Report do
result[6][1].should == 0.0
end
- it 'should return correct results when run twice with different limits' do
+ it 'should return correct results when run twice in a row with a higher limit on the second run' do
@report = Simplabs::ReportsAsSparkline::Report.new(User, :registrations,
:aggregation => :count,
:grouping => grouping,
@@ -250,14 +277,49 @@ describe Simplabs::ReportsAsSparkline::Report do
result[6][1].should == 0.0
end
- end
+ unless live_data
+
+ it 'should return correct data for aggregation :count when :end_date is specified' do
+ @report = Simplabs::ReportsAsSparkline::Report.new(User, :registrations,
+ :aggregation => :count,
+ :grouping => grouping,
+ :limit => 10,
+ :end_date => Time.now - 3.send(grouping)
+ )
+ result = @report.run.to_a
+
+ result[9][1].should == 2.0
+ result[8][1].should == 0.0
+ result[7][1].should == 0.0
+ result[6][1].should == 0.0
+ end
+
+ it 'should return correct data for aggregation :sum when :end_date is specified' do
+ @report = Simplabs::ReportsAsSparkline::Report.new(User, :registrations,
+ :aggregation => :sum,
+ :grouping => grouping,
+ :value_column => :profile_visits,
+ :limit => 10,
+ :end_date => Time.now - 3.send(grouping)
+ )
+ result = @report.run.to_a
+
+ result[9][1].should == 5.0
+ result[8][1].should == 0.0
+ result[7][1].should == 0.0
+ result[6][1].should == 0.0
+ end
+
+ end
- after(:all) do
- User.destroy_all
end
end
+ after(:all) do
+ User.destroy_all
+ end
+
end
end
@@ -425,6 +487,10 @@ describe Simplabs::ReportsAsSparkline::Report do
lambda { @report.send(:ensure_valid_options, { :end_date => 'today' }) }.should raise_error(ArgumentError)
end
+ it 'should raise an error if an end date is specified that is in the future' do
+ lambda { @report.send(:ensure_valid_options, { :end_date => (DateTime.now + 1.month) }) }.should raise_error(ArgumentError)
+ end
+
it 'should raise an error if both an end date and :live_data = true are specified' do
lambda { @report.send(:ensure_valid_options, { :end_date => DateTime.now, :live_data => true }) }.should raise_error(ArgumentError)
end
(DIR) diff --git a/spec/classes/reporting_period_spec.rb b/spec/classes/reporting_period_spec.rb
@@ -28,24 +28,24 @@ describe Simplabs::ReportsAsSparkline::ReportingPeriod do
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
+ date_time = DateTime.new(2008, 11, 24)
reporting_period = Simplabs::ReportsAsSparkline::ReportingPeriod.new(Simplabs::ReportsAsSparkline::Grouping.new(:week), date_time)
- reporting_period.date_time.should == Date.new(date_time.year, date_time.month, 24) # expect to get monday 24th again
+ reporting_period.date_time.should == Date.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 monday is in a different month than the specified date' do
- date_time = DateTime.new(2008, 11, 1) #this is a saturday
+ date_time = DateTime.new(2008, 11, 1)
reporting_period = Simplabs::ReportsAsSparkline::ReportingPeriod.new(Simplabs::ReportsAsSparkline::Grouping.new(:week), date_time)
- reporting_period.date_time.should == Date.new(2008, 10, 27) # expect to get the monday before the 1st, which is in october
+ reporting_period.date_time.should == Date.new(2008, 10, 27)
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
+ date_time = DateTime.new(2009, 1, 1)
reporting_period = Simplabs::ReportsAsSparkline::ReportingPeriod.new(Simplabs::ReportsAsSparkline::Grouping.new(:week), date_time)
- reporting_period.date_time.should == Date.new(2008, 12, 29) # expect to get the monday before the 1st, which is in december 2008
+ reporting_period.date_time.should == Date.new(2008, 12, 29)
end
end
@@ -59,6 +59,56 @@ describe Simplabs::ReportsAsSparkline::ReportingPeriod do
end
+ describe '#last_date_time' do
+
+ it 'should return the date and time with minutes = seconds = 59 for grouping :hour' do
+ date_time = DateTime.now
+ reporting_period = Simplabs::ReportsAsSparkline::ReportingPeriod.new(Simplabs::ReportsAsSparkline::Grouping.new(:hour), date_time)
+
+ reporting_period.last_date_time.should == DateTime.new(date_time.year, date_time.month, date_time.day, date_time.hour, 59, 59)
+ end
+
+ it 'should return the date part with hour = 23 and minute = seconds = 59 for grouping :day' do
+ date_time = DateTime.now
+ reporting_period = Simplabs::ReportsAsSparkline::ReportingPeriod.new(Simplabs::ReportsAsSparkline::Grouping.new(:day), date_time)
+
+ reporting_period.last_date_time.should == DateTime.new(date_time.year, date_time.month, date_time.day, 23, 59, 59)
+ end
+
+ describe 'for grouping :week' do
+
+ it 'should return the date of the sunday of the week date_time is in for any day in that week' do
+ date_time = DateTime.new(2008, 11, 27)
+ reporting_period = Simplabs::ReportsAsSparkline::ReportingPeriod.new(Simplabs::ReportsAsSparkline::Grouping.new(:week), date_time)
+
+ reporting_period.last_date_time.should == Date.new(date_time.year, date_time.month, 30)
+ end
+
+ it 'should return the date of the sunday of the week date_time is in when the sunday is in a different month than the specified date' do
+ date_time = DateTime.new(2008, 10, 30)
+ reporting_period = Simplabs::ReportsAsSparkline::ReportingPeriod.new(Simplabs::ReportsAsSparkline::Grouping.new(:week), date_time)
+
+ reporting_period.last_date_time.should == Date.new(2008, 11, 2)
+ end
+
+ it 'should return the date of the sunday of the week date_time is in when the sunday is in a different year than the specified date' do
+ date_time = DateTime.new(2008, 12, 29)
+ reporting_period = Simplabs::ReportsAsSparkline::ReportingPeriod.new(Simplabs::ReportsAsSparkline::Grouping.new(:week), date_time)
+
+ reporting_period.last_date_time.should == Date.new(2009, 1, 4)
+ end
+
+ end
+
+ it 'should return the date of the last day of the month for grouping :month' do
+ date_time = DateTime.new(2009, 4, 29)
+ reporting_period = Simplabs::ReportsAsSparkline::ReportingPeriod.new(Simplabs::ReportsAsSparkline::Grouping.new(:month), date_time)
+
+ reporting_period.last_date_time.should == Date.new(date_time.year, date_time.month, 30)
+ 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