reportable 1.0.3 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/HISTORY.md +10 -0
- data/README.md +49 -10
- data/Rakefile +0 -1
- data/generators/reportable_jquery_flot_assets/reportable_jquery_flot_assets_generator.rb +37 -0
- data/generators/reportable_jquery_flot_assets/templates/NOTES +7 -0
- data/generators/reportable_jquery_flot_assets/templates/excanvas.min.js +1 -0
- data/generators/reportable_jquery_flot_assets/templates/jquery.flot.min.js +1 -0
- data/generators/reportable_migration/reportable_migration_generator.rb +35 -4
- data/generators/reportable_migration/templates/{migration.erb → migration.rb} +7 -7
- data/generators/reportable_raphael_assets/reportable_raphael_assets_generator.rb +42 -0
- data/generators/reportable_raphael_assets/templates/NOTES +6 -0
- data/generators/reportable_raphael_assets/templates/g.line.min.js +7 -0
- data/generators/reportable_raphael_assets/templates/g.raphael.min.js +7 -0
- data/generators/reportable_raphael_assets/templates/raphael.min.js +113 -0
- data/lib/saulabs/reportable.rb +7 -0
- data/lib/saulabs/reportable/config.rb +55 -0
- data/lib/saulabs/reportable/cumulated_report.rb +2 -0
- data/lib/saulabs/reportable/grouping.rb +2 -2
- data/lib/saulabs/reportable/railtie.rb +26 -0
- data/lib/saulabs/reportable/report.rb +3 -0
- data/lib/saulabs/reportable/report_cache.rb +13 -1
- data/lib/saulabs/reportable/report_tag_helper.rb +162 -0
- data/lib/saulabs/reportable/reporting_period.rb +2 -3
- data/lib/saulabs/reportable/result_set.rb +40 -0
- data/rails/init.rb +3 -1
- data/spec/boot.rb +4 -7
- data/spec/classes/grouping_spec.rb +1 -1
- data/spec/classes/report_cache_spec.rb +85 -0
- data/spec/db/schema.rb +6 -6
- data/spec/other/report_method_spec.rb +27 -3
- data/spec/other/report_tag_helper_spec.rb +118 -0
- data/spec/spec_helper.rb +3 -7
- metadata +54 -18
- data/lib/saulabs/reportable/sparkline_tag_helper.rb +0 -62
- data/spec/other/sparkline_tag_helper_spec.rb +0 -64
|
@@ -66,7 +66,7 @@ module Saulabs
|
|
|
66
66
|
if @identifier == :week
|
|
67
67
|
parts = [db_string[0..3], db_string[4..5]].map(&:to_i)
|
|
68
68
|
else
|
|
69
|
-
db_string.split('/').map(&:to_i)
|
|
69
|
+
db_string.split(@identifier == :day ? '-' : '/').map(&:to_i)
|
|
70
70
|
end
|
|
71
71
|
end
|
|
72
72
|
|
|
@@ -99,7 +99,7 @@ module Saulabs
|
|
|
99
99
|
when :hour
|
|
100
100
|
"DATE_FORMAT(#{date_column}, '%Y/%m/%d/%H')"
|
|
101
101
|
when :day
|
|
102
|
-
"
|
|
102
|
+
"DATE(#{date_column})"
|
|
103
103
|
when :week
|
|
104
104
|
"YEARWEEK(#{date_column}, 3)"
|
|
105
105
|
when :month
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require 'saulabs/reportable'
|
|
2
|
+
require 'rails'
|
|
3
|
+
|
|
4
|
+
module Saulabs
|
|
5
|
+
|
|
6
|
+
module Reportable
|
|
7
|
+
|
|
8
|
+
class Railtie < Rails::Railtie
|
|
9
|
+
|
|
10
|
+
GEM_ROOT = File.join(File.dirname(__FILE__), '..', '..', '..')
|
|
11
|
+
|
|
12
|
+
initializer 'saulabs.reportable.initialization' do
|
|
13
|
+
require File.join(GEM_ROOT, 'rails', 'init')
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
generators do
|
|
17
|
+
require File.join(GEM_ROOT, 'generators', 'reportable_migration', 'reportable_migration_generator')
|
|
18
|
+
require File.join(GEM_ROOT, 'generators', 'reportable_raphael_assets', 'reportable_raphael_assets_generator')
|
|
19
|
+
require File.join(GEM_ROOT, 'generators', 'reportable_jquery_flot_assets', 'reportable_jquery_flot_assets_generator')
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
require 'saulabs/reportable/reporting_period'
|
|
2
|
+
require 'saulabs/reportable/result_set'
|
|
3
|
+
|
|
1
4
|
module Saulabs
|
|
2
5
|
|
|
3
6
|
module Reportable
|
|
@@ -9,6 +12,15 @@ module Saulabs
|
|
|
9
12
|
|
|
10
13
|
set_table_name :reportable_cache
|
|
11
14
|
|
|
15
|
+
validates_presence_of :model_name
|
|
16
|
+
validates_presence_of :report_name
|
|
17
|
+
validates_presence_of :grouping
|
|
18
|
+
validates_presence_of :aggregation
|
|
19
|
+
validates_presence_of :value
|
|
20
|
+
validates_presence_of :reporting_period
|
|
21
|
+
|
|
22
|
+
attr_accessible :model_name, :report_name, :grouping, :aggregation, :value, :reporting_period, :conditions
|
|
23
|
+
|
|
12
24
|
self.skip_time_zone_conversion_for_attributes = [:reporting_period]
|
|
13
25
|
|
|
14
26
|
# Clears the cache for the specified +klass+ and +report+
|
|
@@ -84,7 +96,7 @@ module Saulabs
|
|
|
84
96
|
if options[:live_data]
|
|
85
97
|
result << [current_reporting_period.date_time, find_value(new_data, current_reporting_period)]
|
|
86
98
|
end
|
|
87
|
-
result
|
|
99
|
+
Saulabs::Reportable::ResultSet.new(result, report.klass.name, report.name)
|
|
88
100
|
end
|
|
89
101
|
|
|
90
102
|
def self.find_value(data, reporting_period)
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
require 'saulabs/reportable/config'
|
|
2
|
+
|
|
3
|
+
module Saulabs
|
|
4
|
+
|
|
5
|
+
module Reportable
|
|
6
|
+
|
|
7
|
+
module ReportTagHelper
|
|
8
|
+
|
|
9
|
+
# Renders a sparkline with the given data using the google drawing api.
|
|
10
|
+
#
|
|
11
|
+
# @param [Array<Array<DateTime, Float>>] data
|
|
12
|
+
# an array of report data as returned by {Saulabs::Reportable::Report#run}
|
|
13
|
+
# @param [Hash] options
|
|
14
|
+
# options for the sparkline
|
|
15
|
+
#
|
|
16
|
+
# @option options [Fixnum] :width (300)
|
|
17
|
+
# the width of the generated image
|
|
18
|
+
# @option options [Fixnum] :height (34)
|
|
19
|
+
# the height of the generated image
|
|
20
|
+
# @option options [String] :line_color ('0077cc')
|
|
21
|
+
# the line color of the generated image
|
|
22
|
+
# @option options [String] :fill_color ('e6f2fa')
|
|
23
|
+
# the fill color of the generated image
|
|
24
|
+
# @option options [Array<Symbol>] :labels ([])
|
|
25
|
+
# the axes to render lables for (Array of +:x+, +:y+, +:r+, +:t+; this is x axis, y axis, right, top)
|
|
26
|
+
# @option options [String] :alt ('')
|
|
27
|
+
# the alt attribute for the generated image
|
|
28
|
+
# @option options [String] :title ('')
|
|
29
|
+
# the title attribute for the generated image
|
|
30
|
+
#
|
|
31
|
+
# @return [String]
|
|
32
|
+
# an image tag showing a sparkline for the passed +data+
|
|
33
|
+
#
|
|
34
|
+
# @example Rendering a sparkline tag for report data
|
|
35
|
+
#
|
|
36
|
+
# <%= google_report_tag(User.registrations_report, :width => 200, :height => 100, :color => '000') %>
|
|
37
|
+
#
|
|
38
|
+
def google_report_tag(data, options = {})
|
|
39
|
+
options.reverse_merge!(Config.google_options)
|
|
40
|
+
data = data.collect { |d| d[1] }
|
|
41
|
+
labels = ''
|
|
42
|
+
unless options[:labels].empty?
|
|
43
|
+
chxr = {}
|
|
44
|
+
options[:labels].each_with_index do |l, i|
|
|
45
|
+
chxr[l] = "#{i}," + ([:x, :t].include?(l) ? "0,#{data.length}" : "#{[data.min, 0].min},#{data.max}")
|
|
46
|
+
end
|
|
47
|
+
labels = "&chxt=#{options[:labels].map(&:to_s).join(',')}&chxr=#{options[:labels].collect{|l| chxr[l]}.join('|')}"
|
|
48
|
+
end
|
|
49
|
+
title = ''
|
|
50
|
+
unless options[:title].blank?
|
|
51
|
+
title = "&chtt=#{options[:title]}"
|
|
52
|
+
end
|
|
53
|
+
image_tag(
|
|
54
|
+
"http://chart.apis.google.com/chart?cht=ls&chs=#{options[:width]}x#{options[:height]}&chd=t:#{data.join(',')}&chco=#{options[:line_color]}&chm=B,#{options[:fill_color]},0,0,0&chls=1,0,0&chds=#{data.min},#{data.max}#{labels}#{title}",
|
|
55
|
+
:alt => options[:alt],
|
|
56
|
+
:title => options[:title]
|
|
57
|
+
)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
# Renders a sparkline with the given data using Raphael.
|
|
62
|
+
#
|
|
63
|
+
# @param [Array<Array<DateTime, Float>>] data
|
|
64
|
+
# an array of report data as returned by {Saulabs::Reportable::Report#run}
|
|
65
|
+
# @param [Hash] options
|
|
66
|
+
# options for width, height, the dom id and the format
|
|
67
|
+
# @param [Hash] raphael_options
|
|
68
|
+
# options that are passed directly to Raphael as JSON
|
|
69
|
+
#
|
|
70
|
+
# @option options [Fixnum] :width (300)
|
|
71
|
+
# the width of the generated graph
|
|
72
|
+
# @option options [Fixnum] :height (34)
|
|
73
|
+
# the height of the generated graph
|
|
74
|
+
# @option options [Array<Symbol>] :dom_id ("reportable_#{Time.now.to_i}")
|
|
75
|
+
# the dom id of the generated div
|
|
76
|
+
#
|
|
77
|
+
# @return [String]
|
|
78
|
+
# an div tag and the javascript code showing a sparkline for the passed +data+
|
|
79
|
+
#
|
|
80
|
+
# @example Rendering a sparkline tag for report data
|
|
81
|
+
#
|
|
82
|
+
# <%= raphael_report_tag(User.registrations_report, { :width => 200, :height => 100, :format => 'div(100).to_i' }, { :vertical_label_unit => 'registrations' }) %>
|
|
83
|
+
#
|
|
84
|
+
def raphael_report_tag(data, options = {}, raphael_options = {})
|
|
85
|
+
@__raphael_report_tag_count ||= -1
|
|
86
|
+
@__raphael_report_tag_count += 1
|
|
87
|
+
default_dom_id = "#{data.model_name.downcase}_#{data.report_name}#{@__raphael_report_tag_count > 0 ? @__raphael_report_tag_count : ''}"
|
|
88
|
+
options.reverse_merge!(Config.raphael_options.slice(:width, :height, :format))
|
|
89
|
+
options.reverse_merge!(:dom_id => default_dom_id)
|
|
90
|
+
raphael_options.reverse_merge!(Config.raphael_options.except(:width, :height, :format))
|
|
91
|
+
%Q{<div id="#{options[:dom_id]}" style="width:#{options[:width]}px;height:#{options[:height]}px;"></div>
|
|
92
|
+
<script type="text\/javascript" charset="utf-8">
|
|
93
|
+
var graph = Raphael('#{options[:dom_id]}');
|
|
94
|
+
graph.g.linechart(
|
|
95
|
+
-10, 4, #{options[:width]}, #{options[:height]},
|
|
96
|
+
#{(0..data.size).to_a.to_json},
|
|
97
|
+
#{data.map { |d| eval options[:format], d[1].send(:binding) }.to_json},
|
|
98
|
+
#{raphael_options.to_json}
|
|
99
|
+
).hover(function() {
|
|
100
|
+
this.disc = graph.g.disc(this.x, this.y, 3).attr({fill: "#{options[:hover_fill_color]}", stroke: '#{options[:hover_line_color]}' }).insertBefore(this);
|
|
101
|
+
this.flag = graph.g.flag(this.x, this.y, this.value || "0", 0).insertBefore(this);
|
|
102
|
+
if (this.x + this.flag.getBBox().width > this.paper.width) {
|
|
103
|
+
this.flag.rotate(-180);
|
|
104
|
+
this.flag.translate(-this.flag.getBBox().width, 0);
|
|
105
|
+
this.flag.items[1].rotate(180);
|
|
106
|
+
this.flag.items[1].translate(-5, 0);
|
|
107
|
+
}
|
|
108
|
+
}, function() {
|
|
109
|
+
this.disc.remove();
|
|
110
|
+
this.flag.remove();
|
|
111
|
+
});
|
|
112
|
+
</script>}
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Renders a sparkline with the given data using the jquery flot plugin.
|
|
116
|
+
#
|
|
117
|
+
# @param [Array<Array<DateTime, Float>>] data
|
|
118
|
+
# an array of report data as returned by {Saulabs::Reportable::Report#run}
|
|
119
|
+
# @param [Hash] options
|
|
120
|
+
# options for width, height, the dom id and the format
|
|
121
|
+
# @param [Hash] flot_options
|
|
122
|
+
# options that are passed directly to Raphael as JSON
|
|
123
|
+
#
|
|
124
|
+
# @option options [Fixnum] :width (300)
|
|
125
|
+
# the width of the generated graph
|
|
126
|
+
# @option options [Fixnum] :height (34)
|
|
127
|
+
# the height of the generated graph
|
|
128
|
+
# @option options [Array<Symbol>] :dom_id ("reportable_#{Time.now.to_i}")
|
|
129
|
+
# the dom id of the generated div
|
|
130
|
+
#
|
|
131
|
+
# @return [String]
|
|
132
|
+
# an div tag and the javascript code showing a sparkline for the passed +data+
|
|
133
|
+
#
|
|
134
|
+
# @example Rendering a sparkline tag for report data
|
|
135
|
+
#
|
|
136
|
+
# <%= flot_report_tag(User.registrations_report) %>
|
|
137
|
+
#
|
|
138
|
+
|
|
139
|
+
def flot_report_tag(data, options = {}, flot_options = {})
|
|
140
|
+
@__flot_report_tag_count ||= -1
|
|
141
|
+
@__flot_report_tag_count += 1
|
|
142
|
+
default_dom_id = "#{data.model_name.downcase}_#{data.report_name}#{@__flot_report_tag_count > 0 ? @__flot_report_tag_count : ''}"
|
|
143
|
+
options.reverse_merge!(Config.flot_options.slice(:width, :height, :format))
|
|
144
|
+
options.reverse_merge!(:dom_id => default_dom_id)
|
|
145
|
+
flot_options.reverse_merge!(Config.flot_options.except(:width, :height, :format))
|
|
146
|
+
%Q{<div id="#{options[:dom_id]}" style="width:#{options[:width]}px;height:#{options[:height]}px;"></div>
|
|
147
|
+
<script type="text\/javascript" charset="utf-8">
|
|
148
|
+
$(function() {
|
|
149
|
+
var set = #{data.map{|d| d[1] }.to_json},
|
|
150
|
+
data = [];
|
|
151
|
+
for (var i = 0; i < set.length; i++) {
|
|
152
|
+
data.push([i, set[i]]);
|
|
153
|
+
}
|
|
154
|
+
$.plot($('##{options[:dom_id]}'), [data], #{flot_options.to_json});
|
|
155
|
+
});
|
|
156
|
+
</script>}
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
end
|
|
@@ -71,7 +71,7 @@ module Saulabs
|
|
|
71
71
|
#
|
|
72
72
|
def self.from_db_string(grouping, db_string)
|
|
73
73
|
parts = grouping.date_parts_from_db_string(db_string)
|
|
74
|
-
|
|
74
|
+
case grouping.identifier
|
|
75
75
|
when :hour
|
|
76
76
|
self.new(grouping, DateTime.new(parts[0], parts[1], parts[2], parts[3], 0, 0))
|
|
77
77
|
when :day
|
|
@@ -81,7 +81,6 @@ module Saulabs
|
|
|
81
81
|
when :month
|
|
82
82
|
self.new(grouping, Date.new(parts[0], parts[1], 1))
|
|
83
83
|
end
|
|
84
|
-
result
|
|
85
84
|
end
|
|
86
85
|
|
|
87
86
|
# Gets the next reporting period.
|
|
@@ -112,7 +111,7 @@ module Saulabs
|
|
|
112
111
|
#
|
|
113
112
|
def ==(other)
|
|
114
113
|
if other.is_a?(Saulabs::Reportable::ReportingPeriod)
|
|
115
|
-
@date_time
|
|
114
|
+
@date_time == other.date_time && @grouping.identifier == other.grouping.identifier
|
|
116
115
|
elsif other.is_a?(Time) || other.is_a?(DateTime)
|
|
117
116
|
@date_time == parse_date_time(other)
|
|
118
117
|
else
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Saulabs
|
|
2
|
+
|
|
3
|
+
module Reportable
|
|
4
|
+
|
|
5
|
+
# A result set as it is returned by the report methods.
|
|
6
|
+
# This is basically a subclass of +Array+ that adds two
|
|
7
|
+
# attributes, +model_name+ and +report_name+ that store
|
|
8
|
+
# the name of the model and the report the result set
|
|
9
|
+
# was generated from.
|
|
10
|
+
#
|
|
11
|
+
class ResultSet < ::Array
|
|
12
|
+
|
|
13
|
+
# the name of the model the result set is based on
|
|
14
|
+
#
|
|
15
|
+
attr_reader :model_name
|
|
16
|
+
|
|
17
|
+
# the name of the report the result is based on
|
|
18
|
+
#
|
|
19
|
+
attr_reader :report_name
|
|
20
|
+
|
|
21
|
+
# Initializes a new result set.
|
|
22
|
+
#
|
|
23
|
+
# @param [Array] array
|
|
24
|
+
# the array that is the actual result
|
|
25
|
+
# @param [String] model_name
|
|
26
|
+
# the name of the model the result set is based on
|
|
27
|
+
# @param [String] report_name
|
|
28
|
+
# the name of the report the result is based on
|
|
29
|
+
#
|
|
30
|
+
def initialize(array, model_name, report_name)
|
|
31
|
+
super(array)
|
|
32
|
+
@model_name = model_name
|
|
33
|
+
@report_name = report_name.to_s
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
data/rails/init.rb
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
require 'action_view'
|
|
1
2
|
require 'saulabs/reportable'
|
|
3
|
+
require 'saulabs/reportable/report_tag_helper'
|
|
2
4
|
|
|
3
5
|
ActiveRecord::Base.class_eval do
|
|
4
6
|
include Saulabs::Reportable
|
|
5
7
|
end
|
|
6
8
|
|
|
7
9
|
ActionView::Base.class_eval do
|
|
8
|
-
include Saulabs::Reportable::
|
|
10
|
+
include Saulabs::Reportable::ReportTagHelper
|
|
9
11
|
end
|
data/spec/boot.rb
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
plugin_root = File.join(File.dirname(__FILE__), '..')
|
|
2
2
|
|
|
3
|
-
gem 'rails'
|
|
4
|
-
require 'active_record'
|
|
5
|
-
require 'active_support'
|
|
6
|
-
require 'action_controller'
|
|
7
|
-
require 'action_view'
|
|
8
|
-
|
|
9
3
|
$:.unshift "#{plugin_root}/lib"
|
|
10
4
|
|
|
11
|
-
|
|
5
|
+
Bundler.require
|
|
6
|
+
require 'initializer'
|
|
7
|
+
|
|
8
|
+
RAILS_ROOT = File.expand_path(File.dirname(__FILE__) + '/../') unless defined?(RAILS_ROOT)
|
|
12
9
|
Rails::Initializer.run(:set_load_path)
|
|
13
10
|
Rails::Initializer.run(:set_autoload_paths)
|
|
14
11
|
Rails::Initializer.run(:initialize_time_zone) do |config|
|
|
@@ -23,7 +23,7 @@ describe Saulabs::Reportable::Grouping do
|
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
it 'should use DATE_FORMAT with format string "%Y/%m/%d" for grouping :day' do
|
|
26
|
-
Saulabs::Reportable::Grouping.new(:day).send(:to_sql, 'created_at').should == "
|
|
26
|
+
Saulabs::Reportable::Grouping.new(:day).send(:to_sql, 'created_at').should == "DATE(created_at)"
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
it 'should use YEARWEEK with mode 3 for grouping :week' do
|
|
@@ -6,6 +6,91 @@ describe Saulabs::Reportable::ReportCache do
|
|
|
6
6
|
@report = Saulabs::Reportable::Report.new(User, :registrations, :limit => 10)
|
|
7
7
|
end
|
|
8
8
|
|
|
9
|
+
describe 'validations' do
|
|
10
|
+
|
|
11
|
+
before do
|
|
12
|
+
@report_cache = Saulabs::Reportable::ReportCache.new(
|
|
13
|
+
:model_name => User.name,
|
|
14
|
+
:report_name => 'registrations',
|
|
15
|
+
:grouping => 'date',
|
|
16
|
+
:aggregation => 'count',
|
|
17
|
+
:value => 1.0,
|
|
18
|
+
:reporting_period => '2070/03/23'
|
|
19
|
+
)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'should succeed when all required attributes are set' do
|
|
23
|
+
@report_cache.should be_valid
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'should not succeed when no model_name is set' do
|
|
27
|
+
@report_cache.model_name = nil
|
|
28
|
+
|
|
29
|
+
@report_cache.should_not be_valid
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'should not succeed when a blank model_name is set' do
|
|
33
|
+
@report_cache.model_name = ''
|
|
34
|
+
|
|
35
|
+
@report_cache.should_not be_valid
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'should not succeed when no report_name is set' do
|
|
39
|
+
@report_cache.report_name = nil
|
|
40
|
+
|
|
41
|
+
@report_cache.should_not be_valid
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it 'should not succeed when a blank report_name is set' do
|
|
45
|
+
@report_cache.report_name = ''
|
|
46
|
+
|
|
47
|
+
@report_cache.should_not be_valid
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it 'should not succeed when no grouping is set' do
|
|
51
|
+
@report_cache.grouping = nil
|
|
52
|
+
|
|
53
|
+
@report_cache.should_not be_valid
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it 'should not succeed when a blank grouping is set' do
|
|
57
|
+
@report_cache.grouping = ''
|
|
58
|
+
|
|
59
|
+
@report_cache.should_not be_valid
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it 'should not succeed when no aggregation is set' do
|
|
63
|
+
@report_cache.aggregation = nil
|
|
64
|
+
|
|
65
|
+
@report_cache.should_not be_valid
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it 'should not succeed when a blank aggregation is set' do
|
|
69
|
+
@report_cache.aggregation = ''
|
|
70
|
+
|
|
71
|
+
@report_cache.should_not be_valid
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it 'should not succeed when no value is set' do
|
|
75
|
+
@report_cache.value = nil
|
|
76
|
+
|
|
77
|
+
@report_cache.should_not be_valid
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it 'should not succeed when no reporting_period is set' do
|
|
81
|
+
@report_cache.reporting_period = nil
|
|
82
|
+
|
|
83
|
+
@report_cache.should_not be_valid
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it 'should not succeed when a blank reporting_period is set' do
|
|
87
|
+
@report_cache.reporting_period = ''
|
|
88
|
+
|
|
89
|
+
@report_cache.should_not be_valid
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
end
|
|
93
|
+
|
|
9
94
|
describe '.clear_for' do
|
|
10
95
|
|
|
11
96
|
it 'should delete all entries in the cache for the klass and report name' do
|