reportable 1.1.2 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -60,27 +60,9 @@ To install the Reportable gem, simply run
60
60
 
61
61
  [sudo] gem install reportable
62
62
 
63
- ### Rails 2.x
63
+ ### Rails 3.x
64
64
 
65
- To install Reportable for Rails 2.x, add it to your application's dependencies in your `environment.rb`:
66
-
67
- config.gem 'reportable', :lib => 'saulabs/reportable'
68
-
69
- and generate the migration that create reportable's cache table:
70
-
71
- ./script/generate reportable_migration
72
-
73
- If you want to use reportable's JavaScript graph output format, you also have to generate the JavaScript files:
74
-
75
- ./script/generate reportable_raphael_assets
76
-
77
- if you want to use [Raphael](http://raphaeljs.com/) or if you want to use [jQuery](http://jquery.com/) and [flot](http://code.google.com/p/flot/):
78
-
79
- ./script/generate reportable_jquery_flot_assets
80
-
81
- ### Rails 3.0
82
-
83
- To install Reportable for Rails 3.0, add it to your application's Gemfile:
65
+ To install Reportable for Rails 3.x, add it to your application's Gemfile:
84
66
 
85
67
  gem 'reportable', :require => 'saulabs/reportable'
86
68
 
@@ -109,7 +91,7 @@ Plans
109
91
  Authors
110
92
  -------
111
93
 
112
- © 2008-2010 Marco Otte-Witte (<http://simplabs.com>) and Martin Kavalar (<http://www.sauspiel.de>)
94
+ © 2008-2012 Marco Otte-Witte (<http://simplabs.com>) and Martin Kavalar (<http://www.sauspiel.de>)
113
95
 
114
96
  Released under the MIT license
115
97
 
data/Rakefile CHANGED
@@ -12,9 +12,6 @@ task :default => :spec
12
12
 
13
13
  desc 'Run the specs'
14
14
  Spec::Rake::SpecTask.new(:spec) do |t|
15
- t.rcov_opts << '--exclude "gems/*,spec/*,init.rb"'
16
- t.rcov = true
17
- t.rcov_dir = 'doc/coverage'
18
15
  t.spec_files = FileList['spec/**/*_spec.rb']
19
16
  end
20
17
 
@@ -1,37 +1,18 @@
1
- if Saulabs::Reportable::RailsAdapter::IS_RAILS3
2
-
3
- class ReportableJqueryFlotAssetsGenerator < Rails::Generators::Base
4
-
5
- include Rails::Generators::Actions
6
-
7
- def create_jquery_flot_file
8
- empty_directory('public/javascripts')
9
- copy_file(
10
- File.join(File.dirname(__FILE__), 'templates', 'jquery.flot.min.js'),
11
- 'public/javascripts/jquery.flot.min.js'
12
- )
13
- copy_file(
14
- File.join(File.dirname(__FILE__), 'templates', 'excanvas.min.js'),
15
- 'public/javascripts/excanvas.min.js'
16
- )
17
- readme(File.join(File.dirname(__FILE__), 'templates', 'NOTES'))
18
- end
19
-
20
- end
21
-
22
- else
23
-
24
- class ReportableJqueryFlotAssetsGenerator < Rails::Generator::Base
25
-
26
- def manifest
27
- record do |m|
28
- m.directory('public/javascripts')
29
- m.file('jquery.flot.min.js', 'public/javascripts/jquery.flot.min.js')
30
- m.file('excanvas.min.js', 'public/javascripts/excanvas.min.js')
31
- m.readme('NOTES')
32
- end
33
- end
34
-
1
+ class ReportableJqueryFlotAssetsGenerator < Rails::Generators::Base
2
+
3
+ include Rails::Generators::Actions
4
+
5
+ def create_jquery_flot_file
6
+ empty_directory('public/javascripts')
7
+ copy_file(
8
+ File.join(File.dirname(__FILE__), 'templates', 'jquery.flot.min.js'),
9
+ 'public/javascripts/jquery.flot.min.js'
10
+ )
11
+ copy_file(
12
+ File.join(File.dirname(__FILE__), 'templates', 'excanvas.min.js'),
13
+ 'public/javascripts/excanvas.min.js'
14
+ )
15
+ readme(File.join(File.dirname(__FILE__), 'templates', 'NOTES'))
35
16
  end
36
17
 
37
18
  end
@@ -1,40 +1,20 @@
1
- if Saulabs::Reportable::RailsAdapter::IS_RAILS3
1
+ class ReportableMigrationGenerator < Rails::Generators::Base
2
2
 
3
- class ReportableMigrationGenerator < Rails::Generators::Base
4
-
5
- include Rails::Generators::Migration
6
-
7
- def create_migration
8
- migration_template(
9
- File.join(File.dirname(__FILE__), 'templates', 'migration.rb'),
10
- 'db/migrate/create_reportable_cache.rb'
11
- )
12
- end
13
-
14
- def self.next_migration_number(dirname)
15
- if ActiveRecord::Base.timestamped_migrations
16
- Time.now.utc.strftime("%Y%m%d%H%M%S")
17
- else
18
- "%.3d" % (current_migration_number(dirname) + 1)
19
- end
20
- end
3
+ include Rails::Generators::Migration
21
4
 
5
+ def create_migration
6
+ migration_template(
7
+ File.join(File.dirname(__FILE__), 'templates', 'migration.rb'),
8
+ 'db/migrate/create_reportable_cache.rb'
9
+ )
22
10
  end
23
11
 
24
- else
25
-
26
- class ReportableMigrationGenerator < Rails::Generator::Base
27
-
28
- def manifest
29
- record do |m|
30
- m.migration_template('migration.rb', 'db/migrate')
31
- end
12
+ def self.next_migration_number(dirname)
13
+ if ActiveRecord::Base.timestamped_migrations
14
+ Time.now.utc.strftime("%Y%m%d%H%M%S")
15
+ else
16
+ "%.3d" % (current_migration_number(dirname) + 1)
32
17
  end
33
-
34
- def file_name
35
- 'create_reportable_cache'
36
- end
37
-
38
18
  end
39
19
 
40
20
  end
@@ -1,42 +1,22 @@
1
- if Saulabs::Reportable::RailsAdapter::IS_RAILS3
2
-
3
- class ReportableRaphaelAssetsGenerator < Rails::Generators::Base
4
-
5
- include Rails::Generators::Actions
6
-
7
- def create_raphael_file
8
- empty_directory('public/javascripts')
9
- copy_file(
10
- File.join(File.dirname(__FILE__), 'templates', 'raphael.min.js'),
11
- 'public/javascripts/raphael.min.js'
12
- )
13
- copy_file(
14
- File.join(File.dirname(__FILE__), 'templates', 'g.raphael.min.js'),
15
- 'public/javascripts/g.raphael.min.js'
16
- )
17
- copy_file(
18
- File.join(File.dirname(__FILE__), 'templates', 'g.line.min.js'),
19
- 'public/javascripts/g.line.min.js'
20
- )
21
- readme(File.join(File.dirname(__FILE__), 'templates', 'NOTES'))
22
- end
23
-
24
- end
25
-
26
- else
27
-
28
- class ReportableRaphaelAssetsGenerator < Rails::Generator::Base
29
-
30
- def manifest
31
- record do |m|
32
- m.directory('public/javascripts')
33
- m.file('raphael.min.js', 'public/javascripts/raphael.min.js')
34
- m.file('g.raphael.min.js', 'public/javascripts/g.raphael.min.js')
35
- m.file('g.line.min.js', 'public/javascripts/g.line.min.js')
36
- m.readme('NOTES')
37
- end
38
- end
39
-
1
+ class ReportableRaphaelAssetsGenerator < Rails::Generators::Base
2
+
3
+ include Rails::Generators::Actions
4
+
5
+ def create_raphael_file
6
+ empty_directory('public/javascripts')
7
+ copy_file(
8
+ File.join(File.dirname(__FILE__), 'templates', 'raphael.min.js'),
9
+ 'public/javascripts/raphael.min.js'
10
+ )
11
+ copy_file(
12
+ File.join(File.dirname(__FILE__), 'templates', 'g.raphael.min.js'),
13
+ 'public/javascripts/g.raphael.min.js'
14
+ )
15
+ copy_file(
16
+ File.join(File.dirname(__FILE__), 'templates', 'g.line.min.js'),
17
+ 'public/javascripts/g.line.min.js'
18
+ )
19
+ readme(File.join(File.dirname(__FILE__), 'templates', 'NOTES'))
40
20
  end
41
21
 
42
22
  end
@@ -1,5 +1,7 @@
1
+
1
2
  require 'saulabs/reportable/report'
2
3
  require 'saulabs/reportable/cumulated_report'
4
+ require 'saulabs/reportable/railtie'
3
5
 
4
6
  module Saulabs
5
7
 
@@ -9,10 +11,6 @@ module Saulabs
9
11
  #
10
12
  module RailsAdapter
11
13
 
12
- IS_RAILS3 = defined?(Rails) && Rails::VERSION::MAJOR >= 3
13
-
14
- require 'saulabs/reportable/railtie' if IS_RAILS3
15
-
16
14
  # Extends the {Saulabs::Reportable::ClassMethods#reportable} method into +base+.
17
15
  #
18
16
  def self.included(base)
@@ -25,7 +25,7 @@ module Saulabs
25
25
  first_reporting_period = ReportingPeriod.first(options[:grouping], options[:limit], options[:end_date])
26
26
  acc = initial_cumulative_value(first_reporting_period.date_time, options)
27
27
  result = []
28
- data.each do |element|
28
+ data.to_a.each do |element|
29
29
  acc += element[1].to_f
30
30
  result << [element[0], acc]
31
31
  end
@@ -1,4 +1,5 @@
1
1
  require 'saulabs/reportable'
2
+ require 'saulabs/reportable/report_tag_helper'
2
3
  require 'rails'
3
4
 
4
5
  module Saulabs
@@ -10,7 +11,17 @@ module Saulabs
10
11
  GEM_ROOT = File.join(File.dirname(__FILE__), '..', '..', '..')
11
12
 
12
13
  initializer 'saulabs.reportable.initialization' do
13
- require File.join(GEM_ROOT, 'rails', 'init')
14
+ ActiveSupport.on_load :active_record do
15
+ ActiveRecord::Base.class_eval do
16
+ include Saulabs::Reportable::RailsAdapter
17
+ end
18
+ end
19
+ ActiveSupport.on_load :action_view do
20
+ ActionView::Base.class_eval do
21
+ include Saulabs::Reportable::ReportTagHelper
22
+ end
23
+ end
24
+
14
25
  end
15
26
 
16
27
  generators do
@@ -1,5 +1,6 @@
1
1
  require 'saulabs/reportable/reporting_period'
2
2
  require 'saulabs/reportable/result_set'
3
+ require 'active_record'
3
4
 
4
5
  module Saulabs
5
6
 
@@ -10,7 +11,7 @@ module Saulabs
10
11
  #
11
12
  class ReportCache < ActiveRecord::Base
12
13
 
13
- set_table_name :reportable_cache
14
+ self.table_name = :reportable_cache
14
15
 
15
16
  validates_presence_of :model_name
16
17
  validates_presence_of :report_name
@@ -63,7 +64,7 @@ module Saulabs
63
64
  # @option options [DateTime, Boolean] :end_date (false)
64
65
  # when specified, the report will only include data for the +:limit+ reporting periods until this date.
65
66
  #
66
- # @return [Array<Array<DateTime, Float>>]
67
+ # @return [ResultSet<Array<DateTime, Float>>]
67
68
  # the result of the report as pairs of {DateTime}s and {Float}s
68
69
  #
69
70
  def self.process(report, options, &block)
@@ -110,13 +111,24 @@ module Saulabs
110
111
  :report_name => report.name.to_s,
111
112
  :grouping => grouping.identifier.to_s,
112
113
  :aggregation => report.aggregation.to_s,
113
- :conditions => conditions.to_s,
114
+ :conditions => serialize_conditions(conditions),
114
115
  :reporting_period => reporting_period.date_time,
115
116
  :value => value
116
117
  )
117
118
  end
118
119
 
120
+ def self.serialize_conditions(conditions)
121
+ if conditions.is_a?(Array) && conditions.any?
122
+ conditions.join
123
+ elsif conditions.is_a?(Hash) && conditions.any?
124
+ conditions.map.sort{|x,y|x.to_s<=>y.to_s}.flatten.join
125
+ else
126
+ conditions.empty? ? '' : conditions.to_s
127
+ end
128
+ end
129
+
119
130
  def self.read_cached_data(report, options)
131
+ options[:conditions] ||= []
120
132
  conditions = [
121
133
  %w(model_name report_name grouping aggregation conditions).map do |column_name|
122
134
  "#{self.connection.quote_column_name(column_name)} = ?"
@@ -125,7 +137,7 @@ module Saulabs
125
137
  report.name.to_s,
126
138
  options[:grouping].identifier.to_s,
127
139
  report.aggregation.to_s,
128
- options[:conditions].to_s
140
+ serialize_conditions(options[:conditions])
129
141
  ]
130
142
  first_reporting_period = get_first_reporting_period(options)
131
143
  last_reporting_period = get_last_reporting_period(options)
@@ -37,7 +37,7 @@ module Saulabs
37
37
  #
38
38
  def google_report_tag(data, options = {})
39
39
  options.reverse_merge!(Config.google_options)
40
- data = data.collect { |d| d[1] }
40
+ data = data.to_a.collect { |d| d[1] }
41
41
  labels = ''
42
42
  unless options[:labels].empty?
43
43
  chxr = {}
@@ -93,8 +93,8 @@ module Saulabs
93
93
  var graph = Raphael('#{options[:dom_id]}');
94
94
  graph.g.linechart(
95
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},
96
+ #{(0..data.to_a.size).to_a.to_json},
97
+ #{data.to_a.map { |d| d[1].send(:eval, options[:format]) }.to_json},
98
98
  #{raphael_options.to_json}
99
99
  ).hover(function() {
100
100
  this.disc = graph.g.disc(this.x, this.y, 3).attr({fill: "#{options[:hover_fill_color]}", stroke: '#{options[:hover_line_color]}' }).insertBefore(this);
@@ -146,7 +146,7 @@ module Saulabs
146
146
  %Q{<div id="#{options[:dom_id]}" style="width:#{options[:width]}px;height:#{options[:height]}px;"></div>
147
147
  <script type="text\/javascript" charset="utf-8">
148
148
  $(function() {
149
- var set = #{data.map{|d| d[1] }.to_json},
149
+ var set = #{data.to_a.map{|d| d[1] }.to_json},
150
150
  data = [];
151
151
  for (var i = 0; i < set.length; i++) {
152
152
  data.push([i, set[i]]);
@@ -70,7 +70,8 @@ module Saulabs
70
70
  # the reporting period for the {Saulabs::Reportable::Grouping} as parsed from the db string
71
71
  #
72
72
  def self.from_db_string(grouping, db_string)
73
- parts = grouping.date_parts_from_db_string(db_string)
73
+ return self.new(grouping, db_string) if db_string.is_a?(Date)
74
+ parts = grouping.date_parts_from_db_string(db_string.to_s)
74
75
  case grouping.identifier
75
76
  when :hour
76
77
  self.new(grouping, DateTime.new(parts[0], parts[1], parts[2], parts[3], 0, 0))
@@ -8,7 +8,7 @@ module Saulabs
8
8
  # the name of the model and the report the result set
9
9
  # was generated from.
10
10
  #
11
- class ResultSet < ::Array
11
+ class ResultSet
12
12
 
13
13
  # the name of the model the result set is based on
14
14
  #
@@ -18,6 +18,12 @@ module Saulabs
18
18
  #
19
19
  attr_reader :report_name
20
20
 
21
+ # array representation of the result
22
+ #
23
+ def to_a
24
+ @results
25
+ end
26
+
21
27
  # Initializes a new result set.
22
28
  #
23
29
  # @param [Array] array
@@ -28,7 +34,7 @@ module Saulabs
28
34
  # the name of the report the result is based on
29
35
  #
30
36
  def initialize(array, model_name, report_name)
31
- super(array)
37
+ @results = array
32
38
  @model_name = model_name
33
39
  @report_name = report_name.to_s
34
40
  end
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), '..', 'spec_helper')
1
+ require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))),'spec_helper')
2
2
 
3
3
  describe Saulabs::Reportable::CumulatedReport do
4
4
 
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), '..', 'spec_helper')
1
+ require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))),'spec_helper')
2
2
 
3
3
  describe Saulabs::Reportable::Grouping do
4
4
 
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), '..', 'spec_helper')
1
+ require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))),'spec_helper')
2
2
 
3
3
  describe Saulabs::Reportable::ReportCache do
4
4
 
@@ -214,7 +214,7 @@ describe Saulabs::Reportable::ReportCache do
214
214
  @report.name.to_s,
215
215
  @report.options[:grouping].identifier.to_s,
216
216
  @report.aggregation.to_s,
217
- @report.options[:conditions].to_s,
217
+ '',
218
218
  Saulabs::Reportable::ReportingPeriod.first(@report.options[:grouping], 10).date_time
219
219
  ],
220
220
  :limit => 10,
@@ -235,7 +235,7 @@ describe Saulabs::Reportable::ReportCache do
235
235
  @report.name.to_s,
236
236
  @report.options[:grouping].identifier.to_s,
237
237
  @report.aggregation.to_s,
238
- @report.options[:conditions].to_s,
238
+ '',
239
239
  Saulabs::Reportable::ReportingPeriod.first(@report.options[:grouping], 9).date_time,
240
240
  Saulabs::Reportable::ReportingPeriod.new(@report.options[:grouping], end_date).date_time
241
241
  ],
@@ -248,8 +248,7 @@ describe Saulabs::Reportable::ReportCache do
248
248
 
249
249
  it "should read existing data from the cache for the correct grouping if one other than the report's default grouping is specified" do
250
250
  grouping = Saulabs::Reportable::Grouping.new(:month)
251
- Saulabs::Reportable::ReportCache.should_receive(:find).once.with(
252
- :all,
251
+ Saulabs::Reportable::ReportCache.should_receive(:all).once.with(
253
252
  :conditions => [
254
253
  %w(model_name report_name grouping aggregation conditions).map do |column_name|
255
254
  "#{Saulabs::Reportable::ReportCache.connection.quote_column_name(column_name)} = ?"
@@ -258,7 +257,7 @@ describe Saulabs::Reportable::ReportCache do
258
257
  @report.name.to_s,
259
258
  grouping.identifier.to_s,
260
259
  @report.aggregation.to_s,
261
- @report.options[:conditions].to_s,
260
+ '',
262
261
  Saulabs::Reportable::ReportingPeriod.first(grouping, 10).date_time
263
262
  ],
264
263
  :limit => 10,
@@ -276,6 +275,25 @@ describe Saulabs::Reportable::ReportCache do
276
275
  end
277
276
  end
278
277
  end
278
+
279
+ describe '.serialize_conditions' do
280
+
281
+ it 'should serialize empty conditions correctly' do
282
+ result = Saulabs::Reportable::ReportCache.send(:serialize_conditions, [])
283
+ result.should eql('')
284
+ end
285
+
286
+ it 'should serialize a conditions array correctly' do
287
+ result = Saulabs::Reportable::ReportCache.send(:serialize_conditions, ['active = ? AND gender = ?', true, 'male'])
288
+ result.should eql('active = ? AND gender = ?truemale')
289
+ end
290
+
291
+ it 'should serialize a conditions hash correctly' do
292
+ result = Saulabs::Reportable::ReportCache.send(:serialize_conditions, { :gender => 'male', :active => true })
293
+ result.should eql('activetruegendermale')
294
+ end
295
+
296
+ end
279
297
 
280
298
  describe '.prepare_result' do
281
299
 
@@ -320,7 +338,7 @@ describe Saulabs::Reportable::ReportCache do
320
338
  end
321
339
 
322
340
  it 'should save the created Saulabs::Reportable::ReportCache' do
323
- @cached.should_receive(:save!).once
341
+ @cached.should_receive(:save!)
324
342
 
325
343
  Saulabs::Reportable::ReportCache.send(:prepare_result, @new_data, [], @report, @report.options)
326
344
  end
@@ -328,16 +346,17 @@ describe Saulabs::Reportable::ReportCache do
328
346
  it 'should return an array of arrays of Dates and Floats' do
329
347
  result = Saulabs::Reportable::ReportCache.send(:prepare_result, @new_data, [], @report, @report.options)
330
348
 
331
- result.should be_kind_of(Array)
332
- result[0].should be_kind_of(Array)
333
- result[0][0].should be_kind_of(Date)
334
- result[0][1].should be_kind_of(Float)
349
+ result.should be_kind_of(Saulabs::Reportable::ResultSet)
350
+ result.to_a.should be_kind_of(Array)
351
+ result.to_a[0].should be_kind_of(Array)
352
+ result.to_a[0][0].should be_kind_of(Date)
353
+ result.to_a[0][1].should be_kind_of(Float)
335
354
  end
336
355
 
337
356
  describe 'with :live_data = false' do
338
357
 
339
358
  before do
340
- @result = Saulabs::Reportable::ReportCache.send(:prepare_result, @new_data, [], @report, @report.options)
359
+ @result = Saulabs::Reportable::ReportCache.send(:prepare_result, @new_data, [], @report, @report.options).to_a
341
360
  end
342
361
 
343
362
  it 'should return an array of length :limit' do
@@ -354,7 +373,7 @@ describe Saulabs::Reportable::ReportCache do
354
373
 
355
374
  before do
356
375
  options = @report.options.merge(:live_data => true)
357
- @result = Saulabs::Reportable::ReportCache.send(:prepare_result, @new_data, [], @report, options)
376
+ @result = Saulabs::Reportable::ReportCache.send(:prepare_result, @new_data, [], @report, options).to_a
358
377
  end
359
378
 
360
379
  it 'should return an array of length (:limit + 1)' do
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), '..', 'spec_helper')
1
+ require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))),'spec_helper')
2
2
 
3
3
  describe Saulabs::Reportable::Report do
4
4
 
@@ -56,13 +56,13 @@ describe Saulabs::Reportable::Report do
56
56
  it 'should return an array of the same length as the specified limit when :live_data is false' do
57
57
  @report = Saulabs::Reportable::Report.new(User, :cumulated_registrations, :limit => 10, :live_data => false)
58
58
 
59
- @report.run.length.should == 10
59
+ @report.run.to_a.length.should == 10
60
60
  end
61
61
 
62
62
  it 'should return an array of the same length as the specified limit + 1 when :live_data is true' do
63
63
  @report = Saulabs::Reportable::Report.new(User, :cumulated_registrations, :limit => 10, :live_data => true)
64
64
 
65
- @report.run.length.should == 11
65
+ @report.run.to_a.length.should == 11
66
66
  end
67
67
 
68
68
  for grouping in [:hour, :day, :week, :month] do
@@ -98,7 +98,7 @@ describe Saulabs::Reportable::Report do
98
98
  :limit => 10,
99
99
  :end_date => @end_date
100
100
  )
101
- @result = @report.run
101
+ @result = @report.run.to_a
102
102
  end
103
103
 
104
104
  it "should start with the reporting period (end_date - limit.#{grouping.to_s})" do
@@ -127,7 +127,7 @@ describe Saulabs::Reportable::Report do
127
127
  :limit => 10,
128
128
  :live_data => live_data
129
129
  )
130
- @result = @report.run
130
+ @result = @report.run.to_a
131
131
  end
132
132
 
133
133
  it "should be an array starting reporting period (Time.now - limit.#{grouping.to_s})" do
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), '..', 'spec_helper')
1
+ require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))),'spec_helper')
2
2
 
3
3
  describe Saulabs::Reportable::ReportingPeriod do
4
4
 
@@ -138,6 +138,16 @@ describe Saulabs::Reportable::ReportingPeriod do
138
138
 
139
139
  Saulabs::Reportable::ReportingPeriod.from_db_string(grouping, '').date_time.should == Date.new(2008, 1, 1)
140
140
  end
141
+
142
+ it "should return a reporting period with the correct date when a Date object is passed" do
143
+ grouping = Saulabs::Reportable::Grouping.new(:day)
144
+ Saulabs::Reportable::ReportingPeriod.from_db_string(grouping, Date.new(2008, 1, 1)).date_time.should == Date.new(2008, 1, 1)
145
+ end
146
+
147
+ it "should return a reporting period with the correct date when a DateTime object is passed" do
148
+ grouping = Saulabs::Reportable::Grouping.new(:hour)
149
+ Saulabs::Reportable::ReportingPeriod.from_db_string(grouping, DateTime.new(2008, 1, 1, 12, 0, 0)).date_time.should == DateTime.new(2008, 1, 1, 12, 0, 0)
150
+ end
141
151
 
142
152
  end
143
153
 
@@ -1,6 +1,6 @@
1
1
  sqlite3:
2
2
  adapter: sqlite3
3
- database: spec/db/reportable.sqlite3.db
3
+ database: ":memory:"
4
4
  mysql:
5
5
  adapter: mysql
6
6
  database: reportable_test
@@ -12,4 +12,4 @@ postgresql:
12
12
  database: reportable_test
13
13
  username: reportable
14
14
  password: reportable
15
- host: localhost
15
+ host: localhost
@@ -1,7 +1,17 @@
1
- require File.join(File.dirname(__FILE__), '..', 'spec_helper')
1
+ require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))),'spec_helper')
2
2
 
3
3
  describe Saulabs::Reportable do
4
+
5
+ ActiveRecord::Base.class_eval do
6
+ include Saulabs::Reportable::RailsAdapter
7
+ end
8
+
9
+ class User < ActiveRecord::Base
10
+ reportable :registrations, :limit => 10
11
+ end
4
12
 
13
+ class SpecialUser < User; end
14
+
5
15
  before(:all) do
6
16
  User.create!(:login => 'test 1', :created_at => Time.now - 1.days, :profile_visits => 1)
7
17
  User.create!(:login => 'test 2', :created_at => Time.now - 2.days, :profile_visits => 2)
@@ -59,10 +69,3 @@ describe Saulabs::Reportable do
59
69
 
60
70
  end
61
71
 
62
- class User < ActiveRecord::Base
63
-
64
- reportable :registrations, :limit => 10
65
-
66
- end
67
-
68
- class SpecialUser < User; end
@@ -1,4 +1,6 @@
1
- require File.join(File.dirname(__FILE__), '..', 'spec_helper')
1
+ require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))),'spec_helper')
2
+
3
+ require 'reportable/report_tag_helper'
2
4
 
3
5
  describe Saulabs::Reportable::ReportTagHelper do
4
6
 
@@ -30,6 +32,10 @@ describe Saulabs::Reportable::ReportTagHelper do
30
32
  @helper.raphael_report_tag(data_set).should =~ /^<div id="#{data_set.model_name.downcase}_#{data_set.report_name}".*<\/div>/
31
33
  @helper.raphael_report_tag(data_set).should =~ /^<div id="#{data_set.model_name.downcase}_#{data_set.report_name}1".*<\/div>/
32
34
  end
35
+
36
+ it 'should include the data [1,3]' do
37
+ @helper.raphael_report_tag(data_set).should =~ /\[1,3\]/
38
+ end
33
39
 
34
40
  end
35
41
 
@@ -1,19 +1,39 @@
1
1
  ENV['RAILS_ENV'] = 'test'
2
2
 
3
3
  require 'rubygems'
4
- require 'bundler'
5
- Bundler.setup
6
-
7
- require File.join(File.dirname(__FILE__), 'boot')
8
-
9
- class User < ActiveRecord::Base; end
10
-
11
- class YieldMatchException < Exception; end
4
+ require 'bundler/setup'
5
+ require 'active_record'
6
+ require 'active_record/version'
7
+ require 'active_support'
12
8
 
13
9
  begin
14
10
  require 'ruby-debug'
15
- Debugger.start
16
- Debugger.settings[:autoeval] = true if Debugger.respond_to?(:settings)
11
+ # Debugger.start
12
+ # Debugger.settings[:autoeval] = true if Debugger.respond_to?(:settings)
17
13
  rescue LoadError
18
14
  # ruby-debug wasn't available so neither can the debugging be
19
- end
15
+ end
16
+
17
+ ROOT = Pathname(File.expand_path(File.join(File.dirname(__FILE__), '..')))
18
+
19
+ $LOAD_PATH << File.join(ROOT, 'lib')
20
+ $LOAD_PATH << File.join(ROOT, 'lib/saulabs')
21
+
22
+ require File.join(ROOT, 'lib', 'saulabs', 'reportable.rb')
23
+
24
+ # Rails::Initializer.run(:set_load_path)
25
+ # Rails::Initializer.run(:set_autoload_paths)
26
+ # Rails::Initializer.run(:initialize_time_zone) do |config|
27
+ # config.time_zone = 'Pacific Time (US & Canada)'
28
+ # end
29
+
30
+ FileUtils.mkdir_p File.join(File.dirname(__FILE__), 'log')
31
+ ActiveRecord::Base.logger = ActiveSupport::BufferedLogger.new(File.dirname(__FILE__) + "/log/spec.log")
32
+
33
+ databases = YAML::load(IO.read(File.join(File.dirname(__FILE__), 'db', 'database.yml')))
34
+ ActiveRecord::Base.establish_connection(databases[ENV['DB'] || 'sqlite3'])
35
+ load(File.join(File.dirname(__FILE__), 'db', 'schema.rb'))
36
+
37
+ class User < ActiveRecord::Base; end
38
+
39
+ class YieldMatchException < Exception; end
metadata CHANGED
@@ -1,79 +1,60 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: reportable
3
- version: !ruby/object:Gem::Version
4
- hash: 23
5
- prerelease: false
6
- segments:
7
- - 1
8
- - 1
9
- - 2
10
- version: 1.1.2
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.2.0
5
+ prerelease:
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Marco Otte-Witte
14
9
  - Martin Kavalar
15
10
  autorequire:
16
11
  bindir: bin
17
12
  cert_chain: []
18
-
19
- date: 2010-06-28 00:00:00 +02:00
20
- default_executable:
21
- dependencies:
22
- - !ruby/object:Gem::Dependency
13
+ date: 2012-02-14 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
23
16
  name: activerecord
24
- prerelease: false
25
- requirement: &id001 !ruby/object:Gem::Requirement
17
+ requirement: &70168900389180 !ruby/object:Gem::Requirement
26
18
  none: false
27
- requirements:
28
- - - ">="
29
- - !ruby/object:Gem::Version
30
- hash: 15
31
- segments:
32
- - 2
33
- - 0
34
- - 0
35
- version: 2.0.0
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '3.0'
36
23
  type: :runtime
37
- version_requirements: *id001
38
- - !ruby/object:Gem::Dependency
39
- name: activesupport
40
24
  prerelease: false
41
- requirement: &id002 !ruby/object:Gem::Requirement
25
+ version_requirements: *70168900389180
26
+ - !ruby/object:Gem::Dependency
27
+ name: activesupport
28
+ requirement: &70168900388200 !ruby/object:Gem::Requirement
42
29
  none: false
43
- requirements:
44
- - - ">="
45
- - !ruby/object:Gem::Version
46
- hash: 15
47
- segments:
48
- - 2
49
- - 0
50
- - 0
51
- version: 2.0.0
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: 3.0.0
52
34
  type: :runtime
53
- version_requirements: *id002
54
- description: Reportable allows for easy report generation from ActiveRecord models by the addition of the reportable method.
35
+ prerelease: false
36
+ version_requirements: *70168900388200
37
+ description: Reportable allows for easy report generation from ActiveRecord models
38
+ by the addition of the reportable method.
55
39
  email: reportable@saulabs.com
56
40
  executables: []
57
-
58
41
  extensions: []
59
-
60
42
  extra_rdoc_files: []
61
-
62
- files:
43
+ files:
63
44
  - README.md
64
45
  - HISTORY.md
65
46
  - Rakefile
66
47
  - MIT-LICENSE
67
48
  - generators/reportable_jquery_flot_assets/reportable_jquery_flot_assets_generator.rb
68
- - generators/reportable_jquery_flot_assets/templates/NOTES
69
49
  - generators/reportable_jquery_flot_assets/templates/excanvas.min.js
70
50
  - generators/reportable_jquery_flot_assets/templates/jquery.flot.min.js
51
+ - generators/reportable_jquery_flot_assets/templates/NOTES
71
52
  - generators/reportable_migration/reportable_migration_generator.rb
72
53
  - generators/reportable_migration/templates/migration.rb
73
54
  - generators/reportable_raphael_assets/reportable_raphael_assets_generator.rb
74
- - generators/reportable_raphael_assets/templates/NOTES
75
55
  - generators/reportable_raphael_assets/templates/g.line.min.js
76
56
  - generators/reportable_raphael_assets/templates/g.raphael.min.js
57
+ - generators/reportable_raphael_assets/templates/NOTES
77
58
  - generators/reportable_raphael_assets/templates/raphael.min.js
78
59
  - lib/saulabs/reportable/config.rb
79
60
  - lib/saulabs/reportable/cumulated_report.rb
@@ -85,8 +66,6 @@ files:
85
66
  - lib/saulabs/reportable/reporting_period.rb
86
67
  - lib/saulabs/reportable/result_set.rb
87
68
  - lib/saulabs/reportable.rb
88
- - rails/init.rb
89
- - spec/boot.rb
90
69
  - spec/classes/cumulated_report_spec.rb
91
70
  - spec/classes/grouping_spec.rb
92
71
  - spec/classes/report_cache_spec.rb
@@ -98,39 +77,29 @@ files:
98
77
  - spec/spec_helper.rb
99
78
  - spec/db/database.yml
100
79
  - spec/spec.opts
101
- has_rdoc: true
102
80
  homepage: http://github.com/saulabs/reportable
103
81
  licenses: []
104
-
105
82
  post_install_message:
106
83
  rdoc_options: []
107
-
108
- require_paths:
84
+ require_paths:
109
85
  - lib
110
- required_ruby_version: !ruby/object:Gem::Requirement
86
+ required_ruby_version: !ruby/object:Gem::Requirement
111
87
  none: false
112
- requirements:
113
- - - ">="
114
- - !ruby/object:Gem::Version
115
- hash: 3
116
- segments:
117
- - 0
118
- version: "0"
119
- required_rubygems_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ! '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
120
93
  none: false
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- hash: 3
125
- segments:
126
- - 0
127
- version: "0"
94
+ requirements:
95
+ - - ! '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
128
98
  requirements: []
129
-
130
99
  rubyforge_project:
131
- rubygems_version: 1.3.7
100
+ rubygems_version: 1.8.11
132
101
  signing_key:
133
- specification_version: 2
102
+ specification_version: 3
134
103
  summary: Easy report generation for Ruby on Rails
135
104
  test_files: []
136
-
105
+ has_rdoc: false
@@ -1,11 +0,0 @@
1
- require 'action_view'
2
- require 'saulabs/reportable'
3
- require 'saulabs/reportable/report_tag_helper'
4
-
5
- ActiveRecord::Base.class_eval do
6
- include Saulabs::Reportable::RailsAdapter
7
- end
8
-
9
- ActionView::Base.class_eval do
10
- include Saulabs::Reportable::ReportTagHelper
11
- end
@@ -1,22 +0,0 @@
1
- plugin_root = File.join(File.dirname(__FILE__), '..')
2
-
3
- $:.unshift "#{plugin_root}/lib"
4
-
5
- Bundler.require
6
- require 'initializer'
7
-
8
- RAILS_ROOT = File.expand_path(File.dirname(__FILE__) + '/../') unless defined?(RAILS_ROOT)
9
- Rails::Initializer.run(:set_load_path)
10
- Rails::Initializer.run(:set_autoload_paths)
11
- Rails::Initializer.run(:initialize_time_zone) do |config|
12
- config.time_zone = 'Pacific Time (US & Canada)'
13
- end
14
-
15
- require File.join(File.dirname(__FILE__), '..', 'rails', 'init.rb')
16
-
17
- FileUtils.mkdir_p File.join(File.dirname(__FILE__), 'log')
18
- ActiveRecord::Base.logger = Logger.new(File.join(File.dirname(__FILE__), 'log', 'spec.log'))
19
-
20
- databases = YAML::load(IO.read(File.join(File.dirname(__FILE__), 'db', 'database.yml')))
21
- ActiveRecord::Base.establish_connection(databases[ENV['DB'] || 'sqlite3'])
22
- load(File.join(File.dirname(__FILE__), 'db', 'schema.rb'))