by_star 1.0.1 → 2.0.0.beta1

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/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