reportable 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY.md +4 -0
- data/MIT-LICENSE +20 -0
- data/README.md +88 -0
- data/Rakefile +29 -0
- data/generators/reportable_migration/reportable_migration_generator.rb +9 -0
- data/generators/reportable_migration/templates/migration.erb +40 -0
- data/lib/saulabs/reportable.rb +63 -0
- data/lib/saulabs/reportable/cumulated_report.rb +42 -0
- data/lib/saulabs/reportable/grouping.rb +140 -0
- data/lib/saulabs/reportable/report.rb +165 -0
- data/lib/saulabs/reportable/report_cache.rb +163 -0
- data/lib/saulabs/reportable/reporting_period.rb +181 -0
- data/lib/saulabs/reportable/sparkline_tag_helper.rb +62 -0
- data/rails/init.rb +9 -0
- data/spec/boot.rb +25 -0
- data/spec/classes/cumulated_report_spec.rb +169 -0
- data/spec/classes/grouping_spec.rb +155 -0
- data/spec/classes/report_cache_spec.rb +296 -0
- data/spec/classes/report_spec.rb +574 -0
- data/spec/classes/reporting_period_spec.rb +335 -0
- data/spec/db/database.yml +15 -0
- data/spec/db/schema.rb +38 -0
- data/spec/other/report_method_spec.rb +44 -0
- data/spec/other/sparkline_tag_helper_spec.rb +64 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +23 -0
- metadata +100 -0
@@ -0,0 +1,574 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
|
+
|
3
|
+
describe Saulabs::Reportable::Report do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@report = Saulabs::Reportable::Report.new(User, :registrations)
|
7
|
+
@now = Time.now
|
8
|
+
DateTime.stub!(:now).and_return(@now)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '#options' do
|
12
|
+
|
13
|
+
it 'should be frozen' do
|
14
|
+
@report.options.should be_frozen
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#run' do
|
20
|
+
|
21
|
+
it 'should process the data with the report cache' do
|
22
|
+
Saulabs::Reportable::ReportCache.should_receive(:process).once.with(
|
23
|
+
@report,
|
24
|
+
{ :limit => 100, :grouping => @report.options[:grouping], :conditions => [], :live_data => false, :end_date => false }
|
25
|
+
)
|
26
|
+
|
27
|
+
@report.run
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should process the data with the report cache when custom conditions are given' do
|
31
|
+
Saulabs::Reportable::ReportCache.should_receive(:process).once.with(
|
32
|
+
@report,
|
33
|
+
{ :limit => 100, :grouping => @report.options[:grouping], :conditions => { :some => :condition }, :live_data => false, :end_date => false }
|
34
|
+
)
|
35
|
+
|
36
|
+
@report.run(:conditions => { :some => :condition })
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should validate the specified options for the :run context' do
|
40
|
+
@report.should_receive(:ensure_valid_options).once.with({ :limit => 3 }, :run)
|
41
|
+
|
42
|
+
result = @report.run(:limit => 3)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should use a custom grouping if one is specified' do
|
46
|
+
grouping = Saulabs::Reportable::Grouping.new(:month)
|
47
|
+
Saulabs::Reportable::Grouping.should_receive(:new).once.with(:month).and_return(grouping)
|
48
|
+
Saulabs::Reportable::ReportCache.should_receive(:process).once.with(
|
49
|
+
@report,
|
50
|
+
{ :limit => 100, :grouping => grouping, :conditions => [], :live_data => false, :end_date => false }
|
51
|
+
)
|
52
|
+
|
53
|
+
@report.run(:grouping => :month)
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should return an array of the same length as the specified limit when :live_data is false' do
|
57
|
+
@report = Saulabs::Reportable::Report.new(User, :cumulated_registrations, :limit => 10, :live_data => false)
|
58
|
+
|
59
|
+
@report.run.length.should == 10
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should return an array of the same length as the specified limit + 1 when :live_data is true' do
|
63
|
+
@report = Saulabs::Reportable::Report.new(User, :cumulated_registrations, :limit => 10, :live_data => true)
|
64
|
+
|
65
|
+
@report.run.length.should == 11
|
66
|
+
end
|
67
|
+
|
68
|
+
for grouping in [:hour, :day, :week, :month] do
|
69
|
+
|
70
|
+
describe "for grouping :#{grouping.to_s}" do
|
71
|
+
|
72
|
+
before(:all) do
|
73
|
+
User.create!(:login => 'test 1', :created_at => Time.now, :profile_visits => 2)
|
74
|
+
User.create!(:login => 'test 2', :created_at => Time.now - 1.send(grouping), :profile_visits => 1)
|
75
|
+
User.create!(:login => 'test 3', :created_at => Time.now - 3.send(grouping), :profile_visits => 2)
|
76
|
+
User.create!(:login => 'test 4', :created_at => Time.now - 3.send(grouping), :profile_visits => 3)
|
77
|
+
end
|
78
|
+
|
79
|
+
describe 'when :end_date is specified' do
|
80
|
+
|
81
|
+
it 'should not raise a SQL duplicate key error after multiple runs' do
|
82
|
+
@report = Saulabs::Reportable::Report.new(User, :registrations,
|
83
|
+
:limit => 2,
|
84
|
+
:grouping => grouping,
|
85
|
+
:end_date => Date.yesterday.to_datetime
|
86
|
+
)
|
87
|
+
@report.run
|
88
|
+
lambda { @report.run }.should_not raise_error
|
89
|
+
end
|
90
|
+
|
91
|
+
describe 'the returned result' do
|
92
|
+
|
93
|
+
before do
|
94
|
+
@end_date = DateTime.now - 1.send(grouping)
|
95
|
+
@grouping = Saulabs::Reportable::Grouping.new(grouping)
|
96
|
+
@report = Saulabs::Reportable::Report.new(User, :registrations,
|
97
|
+
:grouping => grouping,
|
98
|
+
:limit => 10,
|
99
|
+
:end_date => @end_date
|
100
|
+
)
|
101
|
+
@result = @report.run
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should start with the reporting period (end_date - limit.#{grouping.to_s})" do
|
105
|
+
@result.first[0].should == Saulabs::Reportable::ReportingPeriod.new(@grouping, @end_date - 9.send(grouping)).date_time
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should end with the reporting period of the specified end date" do
|
109
|
+
@result.last[0].should == Saulabs::Reportable::ReportingPeriod.new(@grouping, @end_date).date_time
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
[true, false].each do |live_data|
|
117
|
+
|
118
|
+
describe "with :live_data = #{live_data}" do
|
119
|
+
|
120
|
+
describe 'the returned result' do
|
121
|
+
|
122
|
+
before do
|
123
|
+
Saulabs::Reportable::ReportCache.delete_all
|
124
|
+
@grouping = Saulabs::Reportable::Grouping.new(grouping)
|
125
|
+
@report = Saulabs::Reportable::Report.new(User, :registrations,
|
126
|
+
:grouping => grouping,
|
127
|
+
:limit => 10,
|
128
|
+
:live_data => live_data
|
129
|
+
)
|
130
|
+
@result = @report.run
|
131
|
+
end
|
132
|
+
|
133
|
+
it "should be an array starting reporting period (Time.now - limit.#{grouping.to_s})" do
|
134
|
+
@result.first[0].should == Saulabs::Reportable::ReportingPeriod.new(@grouping, Time.now - 10.send(grouping)).date_time
|
135
|
+
end
|
136
|
+
|
137
|
+
if live_data
|
138
|
+
it "should be data ending with the current reporting period" do
|
139
|
+
@result.last[0].should == Saulabs::Reportable::ReportingPeriod.new(@grouping).date_time
|
140
|
+
end
|
141
|
+
else
|
142
|
+
it "should be data ending with the reporting period before the current" do
|
143
|
+
@result.last[0].should == Saulabs::Reportable::ReportingPeriod.new(@grouping).previous.date_time
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'should return correct data for aggregation :count' do
|
150
|
+
@report = Saulabs::Reportable::Report.new(User, :registrations,
|
151
|
+
:aggregation => :count,
|
152
|
+
:grouping => grouping,
|
153
|
+
:limit => 10,
|
154
|
+
:live_data => live_data
|
155
|
+
)
|
156
|
+
result = @report.run.to_a
|
157
|
+
|
158
|
+
result[10][1].should == 1.0 if live_data
|
159
|
+
result[9][1].should == 1.0
|
160
|
+
result[8][1].should == 0.0
|
161
|
+
result[7][1].should == 2.0
|
162
|
+
result[6][1].should == 0.0
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'should return correct data for aggregation :sum' do
|
166
|
+
@report = Saulabs::Reportable::Report.new(User, :registrations,
|
167
|
+
:aggregation => :sum,
|
168
|
+
:grouping => grouping,
|
169
|
+
:value_column => :profile_visits,
|
170
|
+
:limit => 10,
|
171
|
+
:live_data => live_data
|
172
|
+
)
|
173
|
+
result = @report.run().to_a
|
174
|
+
|
175
|
+
result[10][1].should == 2.0 if live_data
|
176
|
+
result[9][1].should == 1.0
|
177
|
+
result[8][1].should == 0.0
|
178
|
+
result[7][1].should == 5.0
|
179
|
+
result[6][1].should == 0.0
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'should return correct data for aggregation :maximum' do
|
183
|
+
@report = Saulabs::Reportable::Report.new(User, :registrations,
|
184
|
+
:aggregation => :maximum,
|
185
|
+
:grouping => grouping,
|
186
|
+
:value_column => :profile_visits,
|
187
|
+
:limit => 10,
|
188
|
+
:live_data => live_data
|
189
|
+
)
|
190
|
+
result = @report.run().to_a
|
191
|
+
|
192
|
+
result[10][1].should == 2.0 if live_data
|
193
|
+
result[9][1].should == 1.0
|
194
|
+
result[8][1].should == 0.0
|
195
|
+
result[7][1].should == 3.0
|
196
|
+
result[6][1].should == 0.0
|
197
|
+
end
|
198
|
+
|
199
|
+
it 'should return correct data for aggregation :minimum' do
|
200
|
+
@report = Saulabs::Reportable::Report.new(User, :registrations,
|
201
|
+
:aggregation => :minimum,
|
202
|
+
:grouping => grouping,
|
203
|
+
:value_column => :profile_visits,
|
204
|
+
:limit => 10,
|
205
|
+
:live_data => live_data
|
206
|
+
)
|
207
|
+
result = @report.run().to_a
|
208
|
+
|
209
|
+
result[10][1].should == 2.0 if live_data
|
210
|
+
result[9][1].should == 1.0
|
211
|
+
result[8][1].should == 0.0
|
212
|
+
result[7][1].should == 2.0
|
213
|
+
result[6][1].should == 0.0
|
214
|
+
end
|
215
|
+
|
216
|
+
it 'should return correct data for aggregation :average' do
|
217
|
+
@report = Saulabs::Reportable::Report.new(User, :registrations,
|
218
|
+
:aggregation => :average,
|
219
|
+
:grouping => grouping,
|
220
|
+
:value_column => :profile_visits,
|
221
|
+
:limit => 10,
|
222
|
+
:live_data => live_data
|
223
|
+
)
|
224
|
+
result = @report.run().to_a
|
225
|
+
|
226
|
+
result[10][1].should == 2.0 if live_data
|
227
|
+
result[9][1].should == 1.0
|
228
|
+
result[8][1].should == 0.0
|
229
|
+
result[7][1].should == 2.5
|
230
|
+
result[6][1].should == 0.0
|
231
|
+
end
|
232
|
+
|
233
|
+
it 'should return correct data for aggregation :count when custom conditions are specified' do
|
234
|
+
@report = Saulabs::Reportable::Report.new(User, :registrations,
|
235
|
+
:aggregation => :count,
|
236
|
+
:grouping => grouping,
|
237
|
+
:limit => 10,
|
238
|
+
:live_data => live_data
|
239
|
+
)
|
240
|
+
result = @report.run(:conditions => ['login IN (?)', ['test 1', 'test 2', 'test 4']]).to_a
|
241
|
+
|
242
|
+
result[10][1].should == 1.0 if live_data
|
243
|
+
result[9][1].should == 1.0
|
244
|
+
result[8][1].should == 0.0
|
245
|
+
result[7][1].should == 1.0
|
246
|
+
result[6][1].should == 0.0
|
247
|
+
end
|
248
|
+
|
249
|
+
it 'should return correct data for aggregation :sum when custom conditions are specified' do
|
250
|
+
@report = Saulabs::Reportable::Report.new(User, :registrations,
|
251
|
+
:aggregation => :sum,
|
252
|
+
:grouping => grouping,
|
253
|
+
:value_column => :profile_visits,
|
254
|
+
:limit => 10,
|
255
|
+
:live_data => live_data
|
256
|
+
)
|
257
|
+
result = @report.run(:conditions => ['login IN (?)', ['test 1', 'test 2', 'test 4']]).to_a
|
258
|
+
|
259
|
+
result[10][1].should == 2.0 if live_data
|
260
|
+
result[9][1].should == 1.0
|
261
|
+
result[8][1].should == 0.0
|
262
|
+
result[7][1].should == 3.0
|
263
|
+
result[6][1].should == 0.0
|
264
|
+
end
|
265
|
+
|
266
|
+
it 'should return correct results when run twice in a row with a higher limit on the second run' do
|
267
|
+
@report = Saulabs::Reportable::Report.new(User, :registrations,
|
268
|
+
:aggregation => :count,
|
269
|
+
:grouping => grouping,
|
270
|
+
:limit => 10,
|
271
|
+
:live_data => live_data
|
272
|
+
)
|
273
|
+
result = @report.run(:limit => 2).to_a
|
274
|
+
|
275
|
+
result[2][1].should == 1.0 if live_data
|
276
|
+
result[1][1].should == 1.0
|
277
|
+
result[0][1].should == 0.0
|
278
|
+
|
279
|
+
result = @report.run(:limit => 10).to_a
|
280
|
+
|
281
|
+
result[10][1].should == 1.0 if live_data
|
282
|
+
result[9][1].should == 1.0
|
283
|
+
result[8][1].should == 0.0
|
284
|
+
result[7][1].should == 2.0
|
285
|
+
result[6][1].should == 0.0
|
286
|
+
end
|
287
|
+
|
288
|
+
unless live_data
|
289
|
+
|
290
|
+
it 'should return correct data for aggregation :count when :end_date is specified' do
|
291
|
+
@report = Saulabs::Reportable::Report.new(User, :registrations,
|
292
|
+
:aggregation => :count,
|
293
|
+
:grouping => grouping,
|
294
|
+
:limit => 10,
|
295
|
+
:end_date => Time.now - 3.send(grouping)
|
296
|
+
)
|
297
|
+
result = @report.run.to_a
|
298
|
+
|
299
|
+
result[9][1].should == 2.0
|
300
|
+
result[8][1].should == 0.0
|
301
|
+
result[7][1].should == 0.0
|
302
|
+
result[6][1].should == 0.0
|
303
|
+
end
|
304
|
+
|
305
|
+
it 'should return correct data for aggregation :sum when :end_date is specified' do
|
306
|
+
@report = Saulabs::Reportable::Report.new(User, :registrations,
|
307
|
+
:aggregation => :sum,
|
308
|
+
:grouping => grouping,
|
309
|
+
:value_column => :profile_visits,
|
310
|
+
:limit => 10,
|
311
|
+
:end_date => Time.now - 3.send(grouping)
|
312
|
+
)
|
313
|
+
result = @report.run.to_a
|
314
|
+
|
315
|
+
result[9][1].should == 5.0
|
316
|
+
result[8][1].should == 0.0
|
317
|
+
result[7][1].should == 0.0
|
318
|
+
result[6][1].should == 0.0
|
319
|
+
end
|
320
|
+
|
321
|
+
it 'should return correct results when run twice in a row with an end date further in the past on the second run' do
|
322
|
+
@report = Saulabs::Reportable::Report.new(User, :registrations,
|
323
|
+
:aggregation => :count,
|
324
|
+
:grouping => grouping,
|
325
|
+
:limit => 10,
|
326
|
+
:live_data => live_data
|
327
|
+
)
|
328
|
+
result = @report.run(:end_date => Time.now - 1.send(grouping)).to_a
|
329
|
+
|
330
|
+
result[9][1].should == 1.0
|
331
|
+
result[8][1].should == 0.0
|
332
|
+
result[7][1].should == 2.0
|
333
|
+
|
334
|
+
result = @report.run(:end_date => Time.now - 3.send(grouping)).to_a
|
335
|
+
|
336
|
+
result[9][1].should == 2.0
|
337
|
+
result[8][1].should == 0.0
|
338
|
+
result[7][1].should == 0.0
|
339
|
+
end
|
340
|
+
|
341
|
+
end
|
342
|
+
|
343
|
+
end
|
344
|
+
|
345
|
+
end
|
346
|
+
|
347
|
+
after(:all) do
|
348
|
+
User.destroy_all
|
349
|
+
end
|
350
|
+
|
351
|
+
end
|
352
|
+
|
353
|
+
end
|
354
|
+
|
355
|
+
describe 'for grouping week with data ranging over two years' do
|
356
|
+
|
357
|
+
describe 'with the first week of the second year belonging to the first year' do
|
358
|
+
|
359
|
+
before(:all) do
|
360
|
+
User.create!(:login => 'test 1', :created_at => DateTime.new(2008, 12, 22))
|
361
|
+
User.create!(:login => 'test 2', :created_at => DateTime.new(2008, 12, 29))
|
362
|
+
User.create!(:login => 'test 3', :created_at => DateTime.new(2009, 1, 4))
|
363
|
+
User.create!(:login => 'test 4', :created_at => DateTime.new(2009, 1, 5))
|
364
|
+
User.create!(:login => 'test 5', :created_at => DateTime.new(2009, 1, 12))
|
365
|
+
|
366
|
+
Time.stub!(:now).and_return(DateTime.new(2009, 1, 25))
|
367
|
+
end
|
368
|
+
|
369
|
+
it 'should return correct data for aggregation :count' do
|
370
|
+
@report = Saulabs::Reportable::Report.new(User, :registrations,
|
371
|
+
:aggregation => :count,
|
372
|
+
:grouping => :week,
|
373
|
+
:limit => 10
|
374
|
+
)
|
375
|
+
result = @report.run.to_a
|
376
|
+
|
377
|
+
result[9][1].should == 0.0
|
378
|
+
result[8][1].should == 1.0
|
379
|
+
result[7][1].should == 1.0
|
380
|
+
result[6][1].should == 2.0
|
381
|
+
result[5][1].should == 1.0
|
382
|
+
end
|
383
|
+
|
384
|
+
end
|
385
|
+
|
386
|
+
describe 'with the first week of the second year belonging to the second year' do
|
387
|
+
|
388
|
+
before(:all) do
|
389
|
+
User.create!(:login => 'test 1', :created_at => DateTime.new(2009, 12, 21))
|
390
|
+
User.create!(:login => 'test 2', :created_at => DateTime.new(2009, 12, 28))
|
391
|
+
User.create!(:login => 'test 3', :created_at => DateTime.new(2010, 1, 3))
|
392
|
+
User.create!(:login => 'test 4', :created_at => DateTime.new(2010, 1, 4))
|
393
|
+
User.create!(:login => 'test 5', :created_at => DateTime.new(2010, 1, 11))
|
394
|
+
|
395
|
+
Time.stub!(:now).and_return(DateTime.new(2010, 1, 25))
|
396
|
+
end
|
397
|
+
|
398
|
+
it 'should return correct data for aggregation :count' do
|
399
|
+
@report = Saulabs::Reportable::Report.new(User, :registrations,
|
400
|
+
:aggregation => :count,
|
401
|
+
:grouping => :week,
|
402
|
+
:limit => 10
|
403
|
+
)
|
404
|
+
result = @report.run.to_a
|
405
|
+
|
406
|
+
result[9][1].should == 0.0
|
407
|
+
result[8][1].should == 1.0
|
408
|
+
result[7][1].should == 1.0
|
409
|
+
result[6][1].should == 2.0
|
410
|
+
result[5][1].should == 1.0
|
411
|
+
end
|
412
|
+
|
413
|
+
end
|
414
|
+
|
415
|
+
end
|
416
|
+
|
417
|
+
after do
|
418
|
+
Saulabs::Reportable::ReportCache.destroy_all
|
419
|
+
end
|
420
|
+
|
421
|
+
after(:all) do
|
422
|
+
User.destroy_all
|
423
|
+
end
|
424
|
+
|
425
|
+
end
|
426
|
+
|
427
|
+
describe '#read_data' do
|
428
|
+
|
429
|
+
it 'should invoke the aggregation method on the model' do
|
430
|
+
@report = Saulabs::Reportable::Report.new(User, :registrations, :aggregation => :count)
|
431
|
+
User.should_receive(:count).once.and_return([])
|
432
|
+
|
433
|
+
@report.send(:read_data, Time.now, 5.days.from_now, { :grouping => @report.options[:grouping], :conditions => [] })
|
434
|
+
end
|
435
|
+
|
436
|
+
it 'should setup the conditions' do
|
437
|
+
@report.should_receive(:setup_conditions).once.and_return([])
|
438
|
+
|
439
|
+
@report.send(:read_data, Time.now, 5.days.from_now, { :grouping => @report.options[:grouping], :conditions => [] })
|
440
|
+
end
|
441
|
+
|
442
|
+
end
|
443
|
+
|
444
|
+
describe '#setup_conditions' do
|
445
|
+
|
446
|
+
before do
|
447
|
+
@begin_at = Time.now
|
448
|
+
@end_at = 5.days.from_now
|
449
|
+
@created_at_column_clause = "#{ActiveRecord::Base.connection.quote_table_name('users')}.#{ActiveRecord::Base.connection.quote_column_name('created_at')}"
|
450
|
+
end
|
451
|
+
|
452
|
+
it 'should return conditions for date_column BETWEEN begin_at and end_at only when no custom conditions are specified and both begin and end date are specified' do
|
453
|
+
@report.send(:setup_conditions, @begin_at, @end_at).should == ["#{@created_at_column_clause} BETWEEN ? AND ?", @begin_at, @end_at]
|
454
|
+
end
|
455
|
+
|
456
|
+
it 'should return conditions for date_column >= begin_at when no custom conditions and a begin_at are specified' do
|
457
|
+
@report.send(:setup_conditions, @begin_at, nil).should == ["#{@created_at_column_clause} >= ?", @begin_at]
|
458
|
+
end
|
459
|
+
|
460
|
+
it 'should return conditions for date_column <= end_at when no custom conditions and a end_at are specified' do
|
461
|
+
@report.send(:setup_conditions, nil, @end_at).should == ["#{@created_at_column_clause} <= ?", @end_at]
|
462
|
+
end
|
463
|
+
|
464
|
+
it 'should raise an argument error when neither begin_at or end_at are specified' do
|
465
|
+
lambda {@report.send(:setup_conditions, nil, nil)}.should raise_error(ArgumentError)
|
466
|
+
end
|
467
|
+
|
468
|
+
it 'should return conditions for date_column BETWEEN begin_at and end_date only when an empty Hash of custom conditions is specified' do
|
469
|
+
@report.send(:setup_conditions, @begin_at, @end_at, {}).should == ["#{@created_at_column_clause} BETWEEN ? AND ?", @begin_at, @end_at]
|
470
|
+
end
|
471
|
+
|
472
|
+
it 'should return conditions for date_column BETWEEN begin_at and end_date only when an empty Array of custom conditions is specified' do
|
473
|
+
@report.send(:setup_conditions, @begin_at, @end_at, []).should == ["#{@created_at_column_clause} BETWEEN ? AND ?", @begin_at, @end_at]
|
474
|
+
end
|
475
|
+
|
476
|
+
it 'should correctly include custom conditions if they are specified as a Hash' do
|
477
|
+
custom_conditions = { :first_name => 'first name', :last_name => 'last name' }
|
478
|
+
|
479
|
+
conditions = @report.send(:setup_conditions, @begin_at, @end_at, custom_conditions)
|
480
|
+
# cannot directly check for string equqlity here since hashes are not ordered and so there is no way to now in which order the conditions are added to the SQL clause
|
481
|
+
conditions[0].should =~ (/#{ActiveRecord::Base.connection.quote_table_name('users')}.#{ActiveRecord::Base.connection.quote_column_name('first_name')} = #{ActiveRecord::Base.connection.quote('first name')}/)
|
482
|
+
conditions[0].should =~ (/#{ActiveRecord::Base.connection.quote_table_name('users')}.#{ActiveRecord::Base.connection.quote_column_name('last_name')} = #{ActiveRecord::Base.connection.quote('last name')}/)
|
483
|
+
conditions[0].should =~ (/#{@created_at_column_clause} BETWEEN \? AND \?/)
|
484
|
+
conditions[1].should == @begin_at
|
485
|
+
conditions[2].should == @end_at
|
486
|
+
end
|
487
|
+
|
488
|
+
it 'should correctly include custom conditions if they are specified as an Array' do
|
489
|
+
custom_conditions = ['first_name = ? AND last_name = ?', 'first name', 'last name']
|
490
|
+
|
491
|
+
@report.send(:setup_conditions, @begin_at, @end_at, custom_conditions).should == ["first_name = #{ActiveRecord::Base.connection.quote('first name')} AND last_name = #{ActiveRecord::Base.connection.quote('last name')} AND #{@created_at_column_clause} BETWEEN ? AND ?", @begin_at, @end_at]
|
492
|
+
end
|
493
|
+
|
494
|
+
end
|
495
|
+
|
496
|
+
describe '#ensure_valid_options' do
|
497
|
+
|
498
|
+
it 'should raise an error if malformed conditions are specified' do
|
499
|
+
lambda { @report.send(:ensure_valid_options, { :conditions => 1 }) }.should raise_error(ArgumentError)
|
500
|
+
end
|
501
|
+
|
502
|
+
it 'should not raise an error if conditions are specified as an Array' do
|
503
|
+
lambda { @report.send(:ensure_valid_options, { :conditions => ['first_name = ?', 'first name'] }) }.should_not raise_error(ArgumentError)
|
504
|
+
end
|
505
|
+
|
506
|
+
it 'should not raise an error if conditions are specified as a Hash' do
|
507
|
+
lambda { @report.send(:ensure_valid_options, { :conditions => { :first_name => 'first name' } }) }.should_not raise_error(ArgumentError)
|
508
|
+
end
|
509
|
+
|
510
|
+
it 'should raise an error if an invalid grouping is specified' do
|
511
|
+
lambda { @report.send(:ensure_valid_options, { :grouping => :decade }) }.should raise_error(ArgumentError)
|
512
|
+
end
|
513
|
+
|
514
|
+
it 'should raise an error if an end date is specified that is not a DateTime' do
|
515
|
+
lambda { @report.send(:ensure_valid_options, { :end_date => 'today' }) }.should raise_error(ArgumentError)
|
516
|
+
end
|
517
|
+
|
518
|
+
it 'should raise an error if an end date is specified that is in the future' do
|
519
|
+
lambda { @report.send(:ensure_valid_options, { :end_date => (DateTime.now + 1.month) }) }.should raise_error(ArgumentError)
|
520
|
+
end
|
521
|
+
|
522
|
+
it 'should raise an error if both an end date and :live_data = true are specified' do
|
523
|
+
lambda { @report.send(:ensure_valid_options, { :end_date => DateTime.now, :live_data => true }) }.should raise_error(ArgumentError)
|
524
|
+
end
|
525
|
+
|
526
|
+
it 'should not raise an error if both an end date and :live_data = false are specified' do
|
527
|
+
lambda { @report.send(:ensure_valid_options, { :end_date => DateTime.now, :live_data => false }) }.should_not raise_error
|
528
|
+
end
|
529
|
+
|
530
|
+
describe 'for context :initialize' do
|
531
|
+
|
532
|
+
it 'should not raise an error if valid options are specified' do
|
533
|
+
lambda { @report.send(:ensure_valid_options, {
|
534
|
+
:limit => 100,
|
535
|
+
:aggregation => :count,
|
536
|
+
:grouping => :day,
|
537
|
+
:date_column => :created_at,
|
538
|
+
:value_column => :id,
|
539
|
+
:conditions => [],
|
540
|
+
:live_data => true
|
541
|
+
})
|
542
|
+
}.should_not raise_error(ArgumentError)
|
543
|
+
end
|
544
|
+
|
545
|
+
it 'should raise an error if an unsupported option is specified' do
|
546
|
+
lambda { @report.send(:ensure_valid_options, { :invalid => :option }) }.should raise_error(ArgumentError)
|
547
|
+
end
|
548
|
+
|
549
|
+
it 'should raise an error if an invalid aggregation is specified' do
|
550
|
+
lambda { @report.send(:ensure_valid_options, { :aggregation => :invalid }) }.should raise_error(ArgumentError)
|
551
|
+
end
|
552
|
+
|
553
|
+
it 'should raise an error if aggregation :sum is spesicied but no :value_column' do
|
554
|
+
lambda { @report.send(:ensure_valid_options, { :aggregation => :sum }) }.should raise_error(ArgumentError)
|
555
|
+
end
|
556
|
+
|
557
|
+
end
|
558
|
+
|
559
|
+
describe 'for context :run' do
|
560
|
+
|
561
|
+
it 'should not raise an error if valid options are specified' do
|
562
|
+
lambda { @report.send(:ensure_valid_options, { :limit => 100, :conditions => [], :grouping => :week, :live_data => true }, :run)
|
563
|
+
}.should_not raise_error(ArgumentError)
|
564
|
+
end
|
565
|
+
|
566
|
+
it 'should raise an error if an unsupported option is specified' do
|
567
|
+
lambda { @report.send(:ensure_valid_options, { :aggregation => :sum }, :run) }.should raise_error(ArgumentError)
|
568
|
+
end
|
569
|
+
|
570
|
+
end
|
571
|
+
|
572
|
+
end
|
573
|
+
|
574
|
+
end
|