more cleanup and specs - reportable - Fork of reportable required by WarVox, from hdm/reportable.
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
---
(DIR) commit ce341dcb125a1b76ce526cd545a84ba52fed0e41
(DIR) parent a7042b3435edfcf4e0cc128e73da54b56b01125f
(HTM) Author: marcoow <marco.otte-witte@simplabs.com>
Date: Sat, 6 Dec 2008 01:49:21 +0800
more cleanup and specs
Signed-off-by: Marco Otte-Witte <marco.otte-witte@simplabs.com>
Diffstat:
M lib/kvlr/reports_as_sparkline/repo… | 21 +++++++++++----------
M lib/kvlr/reports_as_sparkline/repo… | 18 +++---------------
M spec/other/report_cache_spec.rb | 99 ++++++++++++++++++++++---------
M spec/other/report_spec.rb | 66 ++++++++++++++++++++++---------
M spec/spec_helper.rb | 2 ++
5 files changed, 136 insertions(+), 70 deletions(-)
---
(DIR) diff --git a/lib/kvlr/reports_as_sparkline/report.rb b/lib/kvlr/reports_as_sparkline/report.rb
@@ -54,16 +54,17 @@ module Kvlr #:nodoc:
end
def ensure_valid_options(options, context = :initialize)
- options.each_key do |k|
- raise ArgumentError.new("Invalid option #{k}") unless [:limit, :aggregation, :grouping, :date_column_name, :value_column_name, :conditions].include?(k)
- end
- allowed_aggregations = [:count, :sum]
- if options[:aggregation] && !allowed_aggregations.include?(options[:aggregation])
- raise ArgumentError.new("Invalid aggregation #{options[:aggregation]}; use either #{allowed_aggregations.map(&:to_s).join(' or ')}")
- end
- allowed_groupings = [:hour, :day, :month, :year]
- if options[:grouping] && !allowed_groupings.include?(options[:grouping])
- raise ArgumentError.new("Invalid grouping #{options[:grouping]}; use one of #{allowed_groupings.join(', ')}")
+ case context
+ when :initialize
+ options.each_key do |k|
+ raise ArgumentError.new("Invalid option #{k}") unless [:limit, :aggregation, :grouping, :date_column_name, :value_column_name, :conditions].include?(k)
+ end
+ raise ArgumentError.new("Invalid aggregation #{options[:aggregation]}") if options[:aggregation] && ![:count, :sum].include?(options[:aggregation])
+ raise ArgumentError.new("Invalid grouping #{options[:grouping]}") if options[:grouping] && ![:hour, :day, :week, :month].include?(options[:grouping])
+ when :run
+ options.each_key do |k|
+ raise ArgumentError.new("Invalid option #{k}") unless [:limit, :conditions].include?(k)
+ end
end
if options[:conditions] && !options[:conditions].is_a?(Array) && !options[:conditions].is_a?(Hash)
raise ArgumentError.new("Invalid conditions: conditions must be specified as an Array or a Hash")
(DIR) diff --git a/lib/kvlr/reports_as_sparkline/report_cache.rb b/lib/kvlr/reports_as_sparkline/report_cache.rb
@@ -12,9 +12,9 @@ module Kvlr #:nodoc:
:all,
:conditions => { :model_name => report.klass.to_s, :report_name => report.name.to_s, :grouping => report.grouping.identifier.to_s, :aggregation => report.aggregation.to_s },
:limit => limit,
- :order => "#{report.date_column_name.to_s} DESC"
+ :order => 'reporting_period DESC'
)
- last_reporting_period_to_read = get_last_reporting_period(cached_data, report.grouping, limit)
+ last_reporting_period_to_read = cached_data.empty? ? report.grouping.first_reporting_period(limit) : report.grouping.to_reporting_period(cached_data.last.reporting_period)
new_data = yield(last_reporting_period_to_read)
return update_cache(new_data, cached_data, report)
end
@@ -22,18 +22,6 @@ module Kvlr #:nodoc:
private
- def self.get_last_reporting_period(cached_data, grouping, limit)
- return grouping.first_reporting_period(limit) if cached_data.empty?
- puts cached_data[0].reporting_period.class.inspect
- period = grouping.to_reporting_period(cached_data[0].reporting_period)
- cached_data[1..-2].each_with_index do |cached, i|
- if grouping.next_reporting_period(grouping.to_reporting_period(DateTime.parse(cached.reporting_period))) != grouping.to_reporting_period(DateTime.parse(cached_data[i + 1].reporting_period))
- return cached
- end
- end
- return grouping.to_reporting_period(cached_data[-1].reporting_period)
- end
-
def self.update_cache(new_data, cached_data, report)
rows_to_write = (0..-1)
if cached_data.size > 0 && new_data.size > 0
@@ -50,7 +38,7 @@ module Kvlr #:nodoc:
:value => row[1]
)
end
- result = cached_data.map { |cached| [Datetime.parse(cached.reporting_period), cached.value] }
+ result = cached_data.map { |cached| [cached.reporting_period, cached.value] }
result += new_data.map { |data| [DateTime.parse(data[0]), data[1]] }
end
(DIR) diff --git a/spec/other/report_cache_spec.rb b/spec/other/report_cache_spec.rb
@@ -6,6 +6,8 @@ describe Kvlr::ReportsAsSparkline::ReportCache do
before do
@report = Kvlr::ReportsAsSparkline::Report.new(User, :registrations)
+ Kvlr::ReportsAsSparkline::ReportCache.stub!(:find).and_return([])
+ Kvlr::ReportsAsSparkline::ReportCache.stub!(:update_cache).and_return([])
end
it 'should raise an ArgumentError if no block is given' do
@@ -20,35 +22,78 @@ describe Kvlr::ReportsAsSparkline::ReportCache do
Kvlr::ReportsAsSparkline::ReportCache.cached_transaction(@report, 100) {}
end
- end
+ it 'should yield to the given block' do
+ lambda {
+ Kvlr::ReportsAsSparkline::ReportCache.cached_transaction(@report, 100) { raise YieldMatchException.new }
+ }.should raise_error(YieldMatchException)
+ end
- describe '#get_last_period_to_read' do
+ it 'should read existing data for the report from cache' do
+ Kvlr::ReportsAsSparkline::ReportCache.should_receive(:find).once.with(
+ :all,
+ :conditions => {
+ :model_name => @report.klass.to_s,
+ :report_name => @report.name.to_s,
+ :grouping => @report.grouping.identifier.to_s,
+ :aggregation => @report.aggregation.to_s
+ },
+ :limit => 100,
+ :order => "reporting_period DESC"
+ )
+
+ Kvlr::ReportsAsSparkline::ReportCache.cached_transaction(@report, 100) { [] }
+ end
+
+ it 'should update the cache' do
+ Kvlr::ReportsAsSparkline::ReportCache.should_receive(:update_cache)
+
+ Kvlr::ReportsAsSparkline::ReportCache.cached_transaction(@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|
+ begin_at.should == @report.grouping.first_reporting_period(100)
+ []
+ end
+ end
+
+ it 'should yield the last reporting period in the cache if the cache is not empty' do
+ cached = Kvlr::ReportsAsSparkline::ReportCache.new({
+ :model_name => @report.klass,
+ :report_name => @report.name,
+ :grouping => @report.grouping.identifier.to_s,
+ :aggregation => @report.aggregation.to_s,
+ :value => 1,
+ :reporting_period => DateTime.now
+ })
+ Kvlr::ReportsAsSparkline::ReportCache.stub!(:find).and_return([cached])
+
+ Kvlr::ReportsAsSparkline::ReportCache.cached_transaction(@report, 100) do |begin_at|
+ begin_at.should == @report.grouping.to_reporting_period(cached.reporting_period)
+ []
+ end
+ end
+
+ describe 'with no_cache = true' do
+
+ it 'should not start a transaction' do
+ Kvlr::ReportsAsSparkline::ReportCache.should_not_receive(:transaction)
+
+ Kvlr::ReportsAsSparkline::ReportCache.cached_transaction(@report, 100, true) {}
+ end
+
+ it 'should not read any data from cache' do
+ Kvlr::ReportsAsSparkline::ReportCache.should_not_receive(:find)
+
+ Kvlr::ReportsAsSparkline::ReportCache.cached_transaction(@report, 100, true) {}
+ end
+
+ it 'should not update the cache' do
+ Kvlr::ReportsAsSparkline::ReportCache.should_not_receive(:update_cache)
+
+ Kvlr::ReportsAsSparkline::ReportCache.cached_transaction(@report, 100, true) {}
+ end
- before do
- @grouping = Kvlr::ReportsAsSparkline::Grouping.new(:day)
- end
-
- it 'should correctly return the last reporting period that is in the cache' do
- cached_data = [
- Kvlr::ReportsAsSparkline::ReportCache.new(:reporting_period => (Time.now - 3.days).to_date.to_formatted_s(:db)),
- Kvlr::ReportsAsSparkline::ReportCache.new(:reporting_period => (Time.now - 2.days).to_date.to_formatted_s(:db))
- ]
-
- Kvlr::ReportsAsSparkline::ReportCache.send(
- :get_last_reporting_period,
- cached_data,
- @grouping,
- 10
- ).should == @grouping.to_reporting_period(Time.now - 2.days)
- end
-
- it 'should return the first reporting period for (Time.now - limit * day/week/month/year) if the cache is empty' do
- Kvlr::ReportsAsSparkline::ReportCache.send(
- :get_last_reporting_period,
- [],
- @grouping,
- 10
- ).should == @grouping.to_reporting_period(Time.now - 10.days)
end
end
(DIR) diff --git a/spec/other/report_spec.rb b/spec/other/report_spec.rb
@@ -125,33 +125,63 @@ describe Kvlr::ReportsAsSparkline::Report do
describe '.ensure_valid_options' do
- it 'should not raise an error if valid options are specified' do
- lambda { @report.send(:ensure_valid_options, {
- :limit => 100,
- :aggregation => :count,
- :grouping => :day,
- :date_column_name => 'created_at',
- :value_column_name => 'id',
- :conditions => []
- }) }.should_not raise_error(ArgumentError)
+ it 'should raise an error if malformed conditions are specified' do
+ lambda { @report.send(:ensure_valid_options, { :conditions => 1 }) }.should raise_error(ArgumentError)
end
- it 'should raise an error if an unsupported option is specified' do
- lambda { @report.send(:ensure_valid_options, { :invalid => :option }) }.should raise_error(ArgumentError)
+ it 'should not raise an error if conditions are specified as an Array' do
+ lambda { @report.send(:ensure_valid_options, { :conditions => ['first_name = ?', 'first name'] }) }.should_not raise_error(ArgumentError)
end
- it 'should raise an error if an invalid aggregation is specified' do
- lambda { @report.send(:ensure_valid_options, { :aggregation => :invalid }) }.should raise_error(ArgumentError)
+ it 'should not raise an error if conditions are specified as a Hash' do
+ lambda { @report.send(:ensure_valid_options, { :conditions => { :first_name => 'first name' } }) }.should_not raise_error(ArgumentError)
end
- it 'should raise an error if an invalid grouping is specified' do
- lambda { @report.send(:ensure_valid_options, { :aggregation => :invalid }) }.should raise_error(ArgumentError)
- end
+ describe 'for context :initialize' do
+
+ it 'should not raise an error if valid options are specified' do
+ lambda { @report.send(:ensure_valid_options, {
+ :limit => 100,
+ :aggregation => :count,
+ :grouping => :day,
+ :date_column_name => 'created_at',
+ :value_column_name => 'id',
+ :conditions => []
+ })
+ }.should_not raise_error(ArgumentError)
+ end
+
+ it 'should raise an error if an unsupported option is specified' do
+ lambda { @report.send(:ensure_valid_options, { :invalid => :option }) }.should raise_error(ArgumentError)
+ end
+
+ it 'should raise an error if an invalid aggregation is specified' do
+ lambda { @report.send(:ensure_valid_options, { :aggregation => :invalid }) }.should raise_error(ArgumentError)
+ end
+
+ it 'should raise an error if an invalid grouping is specified' do
+ lambda { @report.send(:ensure_valid_options, { :grouping => :decade }) }.should raise_error(ArgumentError)
+ end
- it 'should raise an error if malformed conditions are specified' do
- lambda { @report.send(:ensure_valid_options, { :conditions => 1 }) }.should raise_error(ArgumentError)
end
+ describe 'for context :run' do
+
+ it 'should not raise an error if valid options are specified' do
+ lambda { @report.send(:ensure_valid_options, {
+ :limit => 100,
+ :conditions => []
+ },
+ :run)
+ }.should_not raise_error(ArgumentError)
+ end
+
+ it 'should raise an error if an unsupported option is specified' do
+ lambda { @report.send(:ensure_valid_options, { :aggregation => :sum }, :run) }.should raise_error(ArgumentError)
+ end
+
+ end
+
end
end
(DIR) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
@@ -11,3 +11,5 @@ require 'initializer'
require File.join(File.dirname(__FILE__), 'boot') unless defined?(ActiveRecord)
class User < ActiveRecord::Base; end
+
+class YieldMatchException < Exception; end