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