by_star 1.0.1 → 2.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
data/spec/by_star_spec.rb DELETED
@@ -1,722 +0,0 @@
1
- require File.join(File.dirname(__FILE__), 'spec_helper')
2
- require 'by_star'
3
-
4
- describe Post do
5
- # Posts from the 1st January this year.
6
- # 12 posts for the year.
7
- # + 2 for today
8
- # + 2 for yesterday
9
- # + 2 for tomorrow
10
- # + 1 for current week
11
- # + 1 for current weekend
12
- # + 1 for current fortnight
13
- # + 1 for the end of year
14
- # = 22
15
- def this_years_posts
16
- 22
17
- end
18
-
19
- def stub_time(day=1, month=1, year=Time.zone.now.year, hour=0, minute=0)
20
- stub = "#{day}-#{month}-#{year} #{hour}:#{minute}".to_time
21
- Time.stub!(:now).and_return(stub)
22
- Time.zone.stub!(:now).and_return(stub)
23
- end
24
-
25
- def range_test(&block)
26
- (1..31).to_a.each do |d|
27
- stub_time(d, 07, 2009, 05, 05)
28
- block.call
29
- end
30
- end
31
-
32
- def find(*args)
33
- Post.send(subject, *args)
34
- end
35
-
36
- def size(*args)
37
- Post.send(subject, *args).size
38
- end
39
-
40
- ["mysql", "sqlite3"].each do |adapter|
41
- ActiveRecord::Base.establish_connection(YAML::load_file(File.dirname(__FILE__) + "/database.yml")[adapter])
42
-
43
- describe "by year" do
44
- subject { "by_year" }
45
- it "should be able to find all the posts in the current year" do
46
- size.should eql(this_years_posts)
47
- end
48
-
49
- it "should be able to find if given a string" do
50
- size(Time.zone.now.year.to_s).should eql(this_years_posts)
51
- end
52
-
53
- it "should be able to find a single post from last year" do
54
- size(Time.zone.now.year-1).should eql(2)
55
- end
56
-
57
- it "knows what last year's posts were" do
58
- find(Time.zone.now.year-1).map(&:text).should eql(["Last year", "End of last year"])
59
- end
60
-
61
- it "should error when given an invalid year" do
62
- if RUBY_VERSION < "1.8.7"
63
- lambda { find(1901) }.should raise_error(ByStar::ParseError, "Invalid arguments detected, year may possibly be outside of valid range (1902-2039)")
64
- lambda { find(2039) }.should raise_error(ByStar::ParseError, "Invalid arguments detected, year may possibly be outside of valid range (1902-2039)")
65
- else
66
- find(1456).should be_empty
67
- find(1901).should be_empty
68
- find(2039).should be_empty
69
- end
70
- end
71
-
72
- it "should be able to use an alternative field (string)" do
73
- Event.by_year(nil, :field => "start_time").size.should eql(8)
74
- end
75
-
76
- it "should be able to use an alternative field (symbol)" do
77
- Event.by_year(nil, :field => :start_time).size.should eql(8)
78
- end
79
-
80
- it "should not have to specify the field when using by_star_field" do
81
- Event.by_year.size.should eql(8)
82
- end
83
-
84
- it "should be able to use an alternative field (symbol) with directional searching" do
85
- stub_time
86
- Event.past(nil, :field => :start_time).size.should eql(1)
87
- end
88
-
89
- it "should be able to order the result set" do
90
- find(Time.zone.now.year, :order => "created_at DESC").first.text.should eql("That's it!")
91
- end
92
- end
93
-
94
- describe "by month" do
95
- subject { "by_month" }
96
-
97
- it "should be able to find posts for the current month" do
98
- size.should eql(10)
99
- end
100
-
101
- it "should be able to find a single post for January" do
102
- # If it is January we'll have all the "current" posts in there.
103
- # This makes the count 10.
104
- # I'm sure you can guess what happens when it's not January.
105
- size("January").should eql(Time.now.month == 1 ? 10 : 1)
106
- end
107
-
108
- it "should be able to find two posts for the 2nd month" do
109
- # If it is February we'll have all the "current" posts in there.
110
- # This makes the count 10.
111
- # I'm sure you can guess what happens when it's not February.
112
- size(2).should eql(Time.now.month == 2 ? 10 : 1)
113
- end
114
-
115
- it "should be able to find three posts for the 3rd month, using time instance" do
116
- # If it is March we'll have all the "current" posts in there.
117
- # This makes the count 10.
118
- # I'm sure you can guess what happens when it's not March.
119
- time = Time.local(Time.zone.now.year, 3, 1)
120
- size(time).should eql(Time.now.month == 3 ? 10 : 1)
121
- end
122
-
123
- it "should be able to find a single post from January last year" do
124
- size("January", :year => Time.zone.now.year - 1).should eql(1)
125
- end
126
-
127
- it "should fail when given incorrect months" do
128
- lambda { find(0) }.should raise_error(ByStar::ParseError)
129
- lambda { find(13) }.should raise_error(ByStar::ParseError)
130
- lambda { find("Ryan") }.should raise_error(ByStar::ParseError)
131
- lambda { find([1,2,3]) }.should raise_error(ByStar::ParseError)
132
- end
133
-
134
- it "should be able to take decimals" do
135
- size(1.5).should eql(1)
136
- end
137
-
138
- it "should be able to use an alternative field" do
139
- if Time.zone.now.month == 12
140
- Event.by_month(nil, :field => "start_time").size.should eql(4)
141
- else
142
- stub_time(1, 12)
143
- Event.by_month(nil, :field => "start_time").size.should eql(1)
144
- end
145
- end
146
-
147
- it "should be able to specify the year as a string" do
148
- size(1, :year => (Time.zone.now.year - 1).to_s).should eql(1)
149
- end
150
-
151
- end
152
-
153
- describe "by fortnight" do
154
- subject { "by_fortnight" }
155
-
156
- it "should be able to find posts in the current fortnight" do
157
- size.should eql(10)
158
- end
159
-
160
- it "should be able to find posts in the 1st fortnight" do
161
- size(0).should eql(2)
162
- end
163
-
164
- it "should be able to find posts for a fortnight ago" do
165
- stub_time
166
- size(2.weeks.ago).should eql(0)
167
- end
168
-
169
- it "should raise an error when given an invalid argument" do
170
- lambda { find(27) }.should raise_error(ByStar::ParseError, "by_fortnight takes only a Time or Date object, a Fixnum (less than or equal to 26) or a Chronicable string.")
171
- end
172
-
173
- it "should be able to use an alternative field" do
174
- stub_time
175
- Event.by_fortnight(nil, :field => "start_time").size.should eql(0)
176
- end
177
- end
178
-
179
- describe "by week" do
180
- subject { "by_week" }
181
-
182
- it "should be able to find posts in the current week" do
183
- stub_time
184
- size.should eql(2)
185
- end
186
-
187
- it "should be able to find posts in the 1st week" do
188
- size(0).should eql(1)
189
- end
190
-
191
- it "should be able to find posts in the 1st week of last year" do
192
- size(0, :year => Time.zone.now.year-1).should eql(1)
193
- end
194
-
195
- it "should not find any posts from a week ago" do
196
- stub_time
197
- size(1.week.ago).should eql(0)
198
- end
199
-
200
- it "should be able to find posts by a given date" do
201
- stub_time
202
- size(1.week.ago.to_date).should eql(0)
203
- end
204
-
205
- it "should find, not size the posts for the current week" do
206
- stub_time
207
- find.map(&:text).include?("The 'Current' Week")
208
- find.map(&:text).include?("Weekend of May")
209
- end
210
-
211
- it "should raise an error when given an invalid argument" do
212
- lambda { find(54) }.should raise_error(ByStar::ParseError, "by_week takes only a Time or Date object, a Fixnum (less than or equal to 53) or a Chronicable string.")
213
- end
214
-
215
- it "should be able to use an alternative field" do
216
- stub_time
217
- Event.by_week(nil, :field => "start_time").size.should eql(0)
218
- end
219
-
220
- it "should find posts at the start of the year" do
221
- size(0).should eql(1)
222
- end
223
-
224
- it "should find posts at the end of the year" do
225
- size(Time.zone.now.end_of_year).should eql(1)
226
- end
227
-
228
- end
229
-
230
- describe "by weekend" do
231
- subject { "by_weekend" }
232
-
233
- it "should be able to find the posts on the weekend of the 1st of January" do
234
- case Time.zone.now.wday
235
- when 5 # Friday
236
- size.should eql(3)
237
- when 6 # Saturday
238
- size.should eql(5)
239
- else
240
- size.should eql(3)
241
- end
242
- end
243
-
244
- it "should be able to use an alternative field" do
245
- year = Time.zone.now.year
246
- stub_time(1, 8)
247
- Event.by_weekend(nil, :field => "start_time").size.should eql(0)
248
- end
249
- end
250
-
251
- describe "by current weekend" do
252
- it "should work" do
253
- range_test do
254
- Post.by_current_weekend
255
- end
256
- end
257
- end
258
-
259
- describe "by current work week" do
260
- it "should work" do
261
- range_test do
262
- Post.by_current_work_week
263
- end
264
- end
265
- end
266
-
267
- describe "by day" do
268
- subject { "by_day" }
269
- it "should be able to find a post for today" do
270
- stub_time
271
- size.should eql(1)
272
- end
273
-
274
- it "should be able to find a post by a given date" do
275
- stub_time
276
- size(Date.today).should eql(1)
277
- end
278
-
279
- it "should be able to use an alternative field" do
280
- Event.by_day(Time.now - 1.day, :field => "start_time").size.should eql(1)
281
- end
282
- end
283
-
284
- describe "today" do
285
- subject { "today" }
286
- it "should show the post for today" do
287
- find.map(&:text).should include("Today's post")
288
- end
289
-
290
- it "should be able to use an alternative field" do
291
- # Test may occur on an event day.
292
- stub_time
293
- Event.today(nil, :field => "start_time").size.should eql(0)
294
- end
295
-
296
- end
297
-
298
- describe "tomorrow" do
299
- subject { "tomorrow" }
300
- it "should show the post for tomorrow" do
301
- find.map(&:text).should include("Tomorrow's post")
302
- end
303
- end
304
-
305
- describe "yesterday" do
306
- subject { "yesterday" }
307
-
308
- it "should show the post for yesterday" do
309
- find.map(&:text).should include("Yesterday")
310
- end
311
-
312
- it "should be able find yesterday, given a Date" do
313
- find(Time.now).map(&:text).should include("Yesterday")
314
- end
315
-
316
- it "should be able to use an alternative field" do
317
- # Test may occur on an event day.
318
- stub_time
319
- Event.yesterday(nil, :field => "start_time").size.should eql(0)
320
- end
321
-
322
- end
323
-
324
- describe "tomorrow" do
325
- subject { "tomorrow" }
326
- it "should show the post for tomorrow" do
327
- find.map(&:text).should include("Tomorrow's post")
328
- end
329
-
330
- it "should be able find tomorrow, given a Date" do
331
- find(Time.now).map(&:text).should include("Tomorrow's post")
332
- end
333
-
334
- it "should be able to use an alternative field" do
335
- # Test may occur on an event day.
336
- stub_time
337
- Event.tomorrow(nil, :field => "start_time").size.should eql(0)
338
- end
339
- end
340
-
341
- describe "past" do
342
- subject { "past" }
343
-
344
- before do
345
- stub_time
346
- end
347
-
348
- it "should show the correct number of posts in the past" do
349
- size.should eql(2)
350
- end
351
-
352
- it "should find for a given time" do
353
- size(Time.zone.now - 2.days).should eql(1)
354
- end
355
-
356
- it "should find for a given date" do
357
- size(Date.today - 2).should eql(1)
358
- end
359
-
360
- it "should find for a given string" do
361
- size("next tuesday").should eql(3)
362
- end
363
-
364
- it "should be able to find all events before Ryan's birthday using a non-standard field" do
365
- Event.past("01-01-#{Time.zone.now.year+2}".to_time, :field => "start_time").size.should eql(9)
366
- end
367
-
368
- it "should be able to order the find" do
369
- stub_time(2,1)
370
- find(Date.today, :order => "created_at ASC").first.text.should eql("Last year")
371
- find(Date.today, :order => "created_at DESC").first.text.should eql("post 1")
372
- end
373
-
374
- end
375
-
376
- describe "future" do
377
- subject { "future" }
378
- before do
379
- stub_time
380
- end
381
-
382
- it "should show the correct number of posts in the future" do
383
- size.should eql(21)
384
- end
385
-
386
- it "should find for a given date" do
387
- size(Date.today - 2).should eql(23)
388
- end
389
-
390
- it "should find for a given string" do
391
- size("next tuesday").should eql(21)
392
- end
393
-
394
- it "should be able to find all events before Dad's birthday using a non-standard field" do
395
- # TODO: This will change in May. Figure out how to fix.
396
- Event.past("05-07-#{Time.zone.now.year}".to_time, :field => "start_time").size.should eql(5)
397
- end
398
- end
399
-
400
- describe "as of" do
401
- it "should be able to find posts as of 2 weeks ago" do
402
- stub_time
403
- Post.as_of_2_weeks_ago.size.should eql(2)
404
- end
405
-
406
- it "should be able to find posts as of 2 weeks before a given time" do
407
- stub_time
408
- Post.as_of_2_weeks_ago(Time.zone.now + 1.month).size.should eql(3)
409
- end
410
-
411
- it "should error if given a date in the past far enough back" do
412
- lambda { Post.as_of_6_weeks_ago(Time.zone.now - 2.months) }.should raise_error(ByStar::ParseError, "End time is before start time, searching like this will return no results.")
413
- end
414
-
415
- it "should not do anything if given an invalid date" do
416
- lambda { Post.as_of_ryans_birthday }.should raise_error(ByStar::ParseError, "Chronic couldn't work out \"Ryans birthday\"; please be more precise.")
417
- end
418
- end
419
-
420
- describe "between" do
421
- subject { "between" }
422
- it "should find posts between last tuesday and next tuesday" do
423
- stub_time
424
- size("last tuesday", "next tuesday").should eql(2)
425
- end
426
-
427
- it "should find between two times" do
428
- stub_time
429
- size(Time.zone.now - 5.days, Time.zone.now + 5.days).should eql(2)
430
- end
431
-
432
- it "should find between two dates" do
433
- stub_time
434
- size(Date.today, Date.today + 5).should eql(1)
435
- end
436
- end
437
-
438
- describe "up to" do
439
- it "should be able to find posts up to 6 weeks from now" do
440
- stub_time
441
- Post.up_to_6_weeks_from_now.size.should eql(2)
442
- end
443
-
444
- it "should be able to find posts up to 6 weeks from a given time" do
445
- stub_time
446
- Post.up_to_6_weeks_from_now(Time.zone.now - 1.month).size.should eql(3)
447
- end
448
-
449
- it "should error if given a date in the past" do
450
- lambda { Post.up_to_6_weeks_from_now(Time.zone.now + 2.months) }.should raise_error(ByStar::ParseError, "End time is before start time, searching like this will return no results.")
451
- end
452
-
453
- it "should not do anything if given an invalid date" do
454
- lambda { Post.up_to_ryans_birthday }.should raise_error(ByStar::ParseError, "Chronic couldn't work out \"Ryans birthday\"; please be more precise.")
455
- end
456
-
457
- end
458
-
459
- # Because we override method_missing, we ensure that it still works as it should with this test.
460
- describe "method_missing" do
461
- it "should still work" do
462
- Post.find_by_text("Today's post").should_not be_nil
463
- end
464
-
465
- it "should raise a proper NoMethodError" do
466
- lambda { Post.idontexist }.should raise_error(NoMethodError, %r(^undefined method `idontexist'))
467
- end
468
- end
469
-
470
- describe "named_scopes" do
471
- it "should be compatible" do
472
- Event.secret.by_year(nil, :field => "start_time").size.should eql(1)
473
- end
474
- end
475
-
476
- describe "joins" do
477
- it "should not have ambiguous column names" do
478
- lambda { Post.by_month do
479
- { :joins => :tags }
480
- end }.should_not raise_error
481
- end
482
- end
483
-
484
-
485
- describe "nested find" do
486
-
487
- it "should be able to find posts after right now" do
488
- stub_time
489
- # The post at the end of last year
490
- # + The first post of this year
491
- # = 2
492
- Post.by_current_work_week.size.should eql(2)
493
- Post.by_current_work_week do
494
- { :conditions => ["created_at > ?", Time.now] }
495
- end.size.should eql(0)
496
- end
497
-
498
- it "should be able to find a single post from last year with the tag 'ruby'" do
499
- Post.by_year(Time.zone.now.year - 1) do
500
- { :include => :tags, :conditions => ["tags.name = ?", 'ruby'] }
501
- end.size.should eql(1)
502
- end
503
-
504
- it "should be able to find a single post from January last year with the tag 'ruby'" do
505
- Post.by_month("January", :year => Time.zone.now.year - 1) do
506
- { :include => :tags, :conditions => ["tags.name = ?", 'ruby'] }
507
- end.size.should eql(1)
508
- end
509
-
510
- it "should be able to find a single post from the current fortnight with the tag 'fortnight'" do
511
- Post.by_fortnight do
512
- { :include => :tags, :conditions => ["tags.name = ?", 'fortnight'] }
513
- end.size.should eql(1)
514
- end
515
-
516
- it "should be able to find a single post from the current week with the tag 'week'" do
517
- Post.by_week do
518
- { :include => :tags, :conditions => ["tags.name = ?", 'week'] }
519
- end.size.should eql(1)
520
- end
521
-
522
- it "should be able to find a single pot from the last week of last year with the tag 'final'" do
523
- Post.by_week(52, :year => Time.zone.now.year - 1) do
524
- { :include => :tags, :conditions => ["tags.name = ?", 'final'] }
525
- end.size.should eql(1)
526
- end
527
-
528
- it "should be able to find a single post from the current weekend with the tag 'weekend'" do
529
- Post.by_weekend do
530
- { :include => :tags, :conditions => ["tags.name = ?", 'weekend'] }
531
- end.size.should eql(1)
532
- end
533
-
534
- it "should be able to find a single post from the current day with the tag 'today'" do
535
- Post.by_day do
536
- { :include => :tags, :conditions => ["tags.name = ?", 'today'] }
537
- end.size.should eql(1)
538
- end
539
-
540
- it "should be able to find a single post from yesterday with the tag 'yesterday'" do
541
- Post.yesterday do
542
- { :include => :tags, :conditions => ["tags.name = ?", 'yesterday'] }
543
- end.size.should eql(1)
544
- end
545
-
546
-
547
- it "should be able to find a single post from tomorrow with the tag 'tomorrow'" do
548
- Post.tomorrow do
549
- { :include => :tags, :conditions => ["tags.name = ?", 'tomorrow'] }
550
- end.size.should eql(1)
551
- end
552
-
553
- it "should be able to find a single post from the past with the tag 'yesterday'" do
554
- Post.past do
555
- { :include => :tags, :conditions => ["tags.name = ?", 'yesterday'] }
556
- end.size.should eql(1)
557
- end
558
-
559
- it "should be able to find a single post from the future with the tag 'tomorrow'" do
560
- Post.future do
561
- { :include => :tags, :conditions => ["tags.name = ?", 'tomorrow'] }
562
- end.size.should eql(1)
563
- end
564
-
565
- it "should work when block is empty" do
566
- stub_time
567
- # This will not find the post on the 1st January.
568
- # future uses > rather than >=.
569
- Post.future { }.size.should eql(this_years_posts - 1)
570
- end
571
-
572
- it "should be able to find a single post from the future with the tag 'tomorrow' (redux)" do
573
- Post.future(Time.zone.now, :include => :tags, :conditions => ["tags.name = ?", 'tomorrow']).size.should eql(1)
574
- end
575
-
576
- end
577
-
578
- describe "Calculations" do
579
- describe "Sum" do
580
- describe "by year" do
581
- it "current year" do
582
- stub_time
583
- # 13 invoices, all of them $10000.
584
- # +1 of $5500 (2nd January)
585
- # = $13550
586
- Invoice.sum_by_year(:value).should eql(135500)
587
- end
588
- end
589
-
590
- describe "by month" do
591
- it "current month" do
592
- stub_time
593
- # 1 invoice per month, just $10000.
594
- Invoice.sum_by_month(:value).should eql(15500)
595
- end
596
- end
597
-
598
- describe "by day" do
599
- it "current day" do
600
- stub_time(2, 1) # 2nd January
601
- Invoice.sum_by_day(:value).should eql(5500)
602
- end
603
- end
604
- end
605
-
606
- describe "Count" do
607
- describe "by year" do
608
- it "current year" do
609
- # 13 invoices, 1 for every month + 1 for this month.
610
- Invoice.count_by_year.should eql(14)
611
- end
612
-
613
- it "using a field" do
614
- # 12 invoices, as we have a single invoice without a number.
615
- Invoice.count_by_year(:number).should eql(Invoice.by_year.size-1)
616
- end
617
-
618
- it "different year" do
619
- # 1 invoice from last year
620
- Invoice.count_by_year(:all, Time.zone.now.year-1).should eql(1)
621
- end
622
-
623
- it "current year with the given tag" do
624
- # BROKEN: Due to time range looking up from beginning of current year to end of next
625
- Post.count_by_year do
626
- { :include => :tags, :conditions => ["tags.name = ?", 'tomorrow'] }
627
- end.should eql(1)
628
- end
629
- end
630
-
631
- describe "by month" do
632
- it "current month" do
633
- Invoice.count_by_month
634
- end
635
-
636
- it "using a field" do
637
- Invoice.count_by_month(:number).should eql(Invoice.by_month.size-1)
638
- end
639
-
640
- it "different month" do
641
- stub_time
642
- Invoice.count_by_month(:all, 9)
643
- end
644
-
645
- it "current month with the given tag" do
646
- Post.count_by_month(:all, Time.zone.now) do
647
- { :include => :tags, :conditions => ["tags.name = ?", 'tomorrow'] }
648
- end.should eql(1)
649
- end
650
-
651
- it "current month with blank block" do
652
- Post.count_by_month(:all, Time.zone.now) { }.should eql(10)
653
- end
654
- end
655
- end
656
-
657
- end
658
-
659
- describe "directional finders" do
660
- subject { Post.today.first }
661
- let(:event) { Event.last }
662
-
663
- describe "previous" do
664
- it "should find the post previous to it" do
665
- subject.previous.text.should eql("Yesterday")
666
- end
667
-
668
- it "should find the previous event" do
669
- event.previous.name.should eql("Ryan's birthday, last year!")
670
- end
671
- end
672
-
673
-
674
- describe "next" do
675
- let(:event) { Event.first }
676
- it "should find the post next to it" do
677
- subject.next.text.should eql("Tomorrow's post")
678
- end
679
-
680
- it "should find the next event" do
681
- event.next.should be_nil
682
- end
683
- end
684
- end
685
-
686
- describe "chaining of methods" do
687
- # a by_star and a by_direction method, in that order
688
- it "should be able to chain today and past" do
689
- Post.today.past.size.should eql(5)
690
- end
691
-
692
- # a by_direction and by_star method, in that order
693
- it "should be able to chain together past and today" do
694
- Post.past.today.size.should eql(5)
695
- end
696
-
697
- end
698
-
699
- describe "edge cases" do
700
- # This method previously generated sql like: `day_entries`.`spent_at`.`spent_at`.`spent_at`.`spent_at`
701
- # Which is *obviously* incorrect and #omg worthy.
702
- it "should not spam the field name when using a different field" do
703
- Invoice.first.day_entries.between((Time.zone.now - 3.days).to_date, Time.zone.now.to_date, :field => "spent_at")
704
- end
705
- end
706
-
707
- describe Time do
708
- it "should work out the beginning of a weekend (Friday 3pm)" do
709
- range_test do
710
- Time.now.beginning_of_weekend.strftime("%A %I:%M%p").should eql("Friday 03:00PM")
711
- end
712
- end
713
-
714
- it "should work out the end of a weekend (Monday 3am)" do
715
- range_test do
716
- Time.now.end_of_weekend.strftime("%A %I:%M%p").should eql("Monday 03:00AM")
717
- end
718
- end
719
- end
720
- end
721
-
722
- end