by_star 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
data/rails/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'by_star'
2
+ ActiveRecord::Base.send :include, ByStar
@@ -0,0 +1,506 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+ require 'by_star'
3
+
4
+ describe Post do
5
+
6
+ def stub_time(day=15, month=5, year=Time.zone.now.year, hour=0, minute=0)
7
+ stub = "#{day}-#{month}-#{year} #{hour}:#{minute}".to_time
8
+ Time.stub!(:now).and_return(stub)
9
+ Time.zone.stub!(:now).and_return(stub)
10
+ end
11
+
12
+ def range_test(&block)
13
+ (1..31).to_a.each do |d|
14
+ stub_time(d, 07, 2009, 05, 05)
15
+ block.call
16
+ end
17
+ end
18
+
19
+ def find(*args)
20
+ method = description_args.first.sub(' ', '_')
21
+ Post.send(method, *args)
22
+ end
23
+
24
+ def size(*args)
25
+ method = description_args.first.sub(' ', '_')
26
+ Post.send(method, *args).size
27
+ end
28
+
29
+
30
+ describe "by year" do
31
+ it "should be able to find all the posts in the current year" do
32
+ size.should eql(Post.count - 1)
33
+ end
34
+
35
+ it "should be able to find if given a string" do
36
+ size(Time.zone.now.year.to_s).should eql(Post.count - 1)
37
+ end
38
+
39
+ it "should be able to find a single post from last year" do
40
+ size(Time.zone.now.year-1).should eql(1)
41
+ end
42
+
43
+ it "should error when given an invalid year" do
44
+ # This is broken on 1.8.6 (and previous versions), any patchlevel after & before 111
45
+ major, minor, trivial = RUBY_VERSION.split(".").map(&:to_i)
46
+ if major == 1 && ((minor == 8 && trivial <= 6) || (minor <= 8)) && RUBY_PATCHLEVEL.to_i > 111
47
+ lambda { find(1901) }.should raise_error(ByStar::ParseError, "Invalid arguments detected, year may possibly be outside of valid range (1902-2039)")
48
+ lambda { find(2039) }.should raise_error(ByStar::ParseError, "Invalid arguments detected, year may possibly be outside of valid range (1902-2039)")
49
+ else
50
+ find(1456).should be_empty
51
+ find(1901).should be_empty
52
+ find(2039).should be_empty
53
+ end
54
+ end
55
+
56
+ it "should be able to use an alternative field" do
57
+ Event.by_year(nil, :field => "start_time").size.should eql(8)
58
+ end
59
+ end
60
+
61
+ describe "by month" do
62
+
63
+ it "should be able to find posts for the current month" do
64
+ stub_time
65
+ size.should eql(8)
66
+ end
67
+
68
+ it "should be able to find a single post for January" do
69
+ size("January").should eql(1)
70
+ end
71
+
72
+ it "should be able to find two posts for the 2nd month" do
73
+ size(2).should eql(2)
74
+ end
75
+
76
+ it "should be able to find three posts for the 3rd month, using time instance" do
77
+ # Hack... if we're running this test during march there's going to be more posts than usual.
78
+ # This is due to the #today, #yesterday and #tomorrow methods.
79
+
80
+ size(Time.local(Time.zone.now.year, 3, 1)).should eql(3)
81
+ end
82
+
83
+ it "should be able to find a single post from January last year" do
84
+ size("January", :year => Time.zone.now.year - 1).should eql(1)
85
+ end
86
+
87
+ it "should fail when given incorrect months" do
88
+ lambda { find(0) }.should raise_error(ByStar::ParseError)
89
+ lambda { find(13) }.should raise_error(ByStar::ParseError)
90
+ lambda { find("Ryan") }.should raise_error(ByStar::ParseError)
91
+ lambda { find([1,2,3]) }.should raise_error(ByStar::ParseError)
92
+ end
93
+
94
+ it "should be able to take decimals" do
95
+ size(1.5).should eql(1)
96
+ end
97
+
98
+ it "should be able to use an alternative field" do
99
+ stub_time(1, 12)
100
+ Event.by_month(nil, :field => "start_time").size.should eql(1)
101
+ end
102
+
103
+ it "should be able to specify the year as a string" do
104
+ size(1, :year => (Time.zone.now.year - 1).to_s).should eql(1)
105
+ end
106
+
107
+ end
108
+
109
+ describe "by fortnight" do
110
+
111
+ it "should be able to find posts in the current fortnight" do
112
+ stub_time
113
+ size.should eql(3)
114
+ end
115
+
116
+ it "should be able to find posts in the 1st fortnight" do
117
+ size(0).should eql(1)
118
+ end
119
+
120
+ it "should be able to find posts for a fortnight ago" do
121
+ stub_time
122
+ size(2.weeks.ago).should eql(5)
123
+ end
124
+
125
+ it "should raise an error when given an invalid argument" do
126
+ 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.")
127
+ end
128
+
129
+ it "should be able to use an alternative field" do
130
+ stub_time
131
+ Event.by_fortnight(nil, :field => "start_time").size.should eql(0)
132
+ end
133
+ end
134
+
135
+ describe "by week" do
136
+
137
+ it "should be able to find posts in the current week" do
138
+ stub_time
139
+ size.should eql(3)
140
+ end
141
+
142
+ it "should be able to find posts in the 1st week" do
143
+ size(0).should eql(1)
144
+ end
145
+
146
+ it "should be able to find posts in the 1st week of last year" do
147
+ size(0, :year => Time.zone.now.year-1).should eql(1)
148
+ end
149
+
150
+ it "should not find any posts from a week ago" do
151
+ stub_time
152
+ size(1.week.ago).should eql(0)
153
+ end
154
+
155
+ it "should be able to find posts by a given date" do
156
+ stub_time
157
+ size(1.week.ago.to_date).should eql(0)
158
+ end
159
+
160
+ it "should find, not size the posts for the current week" do
161
+ stub_time
162
+ find.map(&:text).include?("The 'Current' Week")
163
+ find.map(&:text).include?("Weekend of May")
164
+ end
165
+
166
+ it "should raise an error when given an invalid argument" do
167
+ 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.")
168
+ end
169
+
170
+ it "should be able to use an alternative field" do
171
+ stub_time
172
+ Event.by_week(nil, :field => "start_time").size.should eql(0)
173
+ end
174
+
175
+ it "should find posts at the start of the year" do
176
+ size(0).should eql(1)
177
+ end
178
+
179
+ it "should find posts at the end of the year" do
180
+ size(Time.zone.now.end_of_year).should eql(1)
181
+ end
182
+
183
+ end
184
+
185
+ describe "by weekend" do
186
+ it "should be able to find the posts on the weekend of the 1st May" do
187
+ stub_time(1, 8)
188
+ size.should eql(8)
189
+ end
190
+
191
+ it "should be able to use an alternative field" do
192
+ year = Time.zone.now.year
193
+ stub_time(1, 8)
194
+ Event.by_weekend(nil, :field => "start_time").size.should eql(1)
195
+ end
196
+ end
197
+
198
+ describe "by current weekend" do
199
+ it "should work" do
200
+ range_test do
201
+ Post.by_current_weekend
202
+ end
203
+ end
204
+ end
205
+
206
+ describe "by current work week" do
207
+ it "should work" do
208
+ range_test do
209
+ Post.by_current_work_week
210
+ end
211
+ end
212
+ end
213
+
214
+ describe "by day" do
215
+ it "should be able to find a post for today" do
216
+ stub_time
217
+ size.should eql(2)
218
+ end
219
+
220
+ it "should be able to find a post by a given date" do
221
+ stub_time
222
+ size(Date.today).should eql(2)
223
+ end
224
+
225
+ it "should be able to use an alternative field" do
226
+ Event.by_day(nil, :field => "start_time").size.should eql(1)
227
+ end
228
+ end
229
+
230
+ describe "today" do
231
+ it "should show the post for today" do
232
+ find.map(&:text).should include("Today's post")
233
+ end
234
+
235
+ it "should be able to use an alternative field" do
236
+ # Test may occur on an event day.
237
+ stub_time
238
+ Event.today(nil, :field => "start_time").size.should eql(0)
239
+ end
240
+
241
+ end
242
+
243
+ describe "tomorrow" do
244
+ it "should show the post for tomorrow" do
245
+ find.map(&:text).should include("Tomorrow's post")
246
+ end
247
+ end
248
+
249
+ describe "yesterday" do
250
+ it "should show the post for yesterday" do
251
+ find.map(&:text).should include("Yesterday's post")
252
+ end
253
+
254
+ it "should be able find yesterday, given a Date" do
255
+ find(Time.now).map(&:text).should include("Yesterday's post")
256
+ end
257
+
258
+ it "should be able to use an alternative field" do
259
+ # Test may occur on an event day.
260
+ stub_time
261
+ Event.yesterday(nil, :field => "start_time").size.should eql(0)
262
+ end
263
+
264
+ end
265
+
266
+ describe "tomorrow" do
267
+ it "should show the post for tomorrow" do
268
+ find.map(&:text).should include("Tomorrow's post")
269
+ end
270
+
271
+ it "should be able find tomorrow, given a Date" do
272
+ find(Time.now).map(&:text).should include("Tomorrow's post")
273
+ end
274
+
275
+ it "should be able to use an alternative field" do
276
+ # Test may occur on an event day.
277
+ stub_time
278
+ Event.tomorrow(nil, :field => "start_time").size.should eql(0)
279
+ end
280
+ end
281
+
282
+ describe "past" do
283
+
284
+ before do
285
+ stub_time
286
+ end
287
+
288
+ it "should show the correct number of posts in the past" do
289
+ size.should eql(16)
290
+ end
291
+
292
+ it "should find for a given time" do
293
+ size(Time.zone.now - 2.days).should eql(16)
294
+ end
295
+
296
+ it "should find for a given date" do
297
+ size(Date.today - 2).should eql(16)
298
+ end
299
+
300
+ it "should find for a given string" do
301
+ size("next tuesday").should eql(19)
302
+ end
303
+
304
+ it "should be able to find all events before Ryan's birthday using a non-standard field" do
305
+ Event.past("04-12-#{Time.zone.now.year}".to_time, :field => "start_time").size.should eql(7)
306
+ end
307
+
308
+ end
309
+
310
+ describe "future" do
311
+ before do
312
+ stub_time
313
+ end
314
+
315
+ it "should show the correct number of posts in the future" do
316
+ size.should eql(71)
317
+ end
318
+
319
+ it "should find for a given date" do
320
+ size(Date.today - 2).should eql(73)
321
+ end
322
+
323
+ it "should find for a given string" do
324
+ size("next tuesday").should eql(70)
325
+ end
326
+
327
+ it "should be able to find all events after Dad's birthday using a non-standard field" do
328
+ Event.past("05-07-#{Time.zone.now.year}".to_time, :field => "start_time").size.should eql(1)
329
+ end
330
+ end
331
+
332
+ describe "as of" do
333
+ it "should be able to find posts as of 2 weeks ago" do
334
+ stub_time
335
+ Post.as_of_2_weeks_ago.size.should eql(7)
336
+ end
337
+
338
+ it "should be able to find posts as of 2 weeks before a given time" do
339
+ stub_time
340
+ Post.as_of_2_weeks_ago(Time.zone.now + 1.month).size.should eql(14)
341
+ end
342
+
343
+ it "should error if given a date in the past far enough back" do
344
+ 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.")
345
+ end
346
+
347
+ it "should not do anything if given an invalid date" do
348
+ lambda { Post.as_of_ryans_birthday }.should raise_error(ByStar::ParseError, "Chronic couldn't work out \"Ryans birthday\"; please be more precise.")
349
+ end
350
+ end
351
+
352
+ describe "between" do
353
+ it "should find posts between last tuesday and next tuesday" do
354
+ stub_time
355
+ size("last tuesday", "next tuesday").should eql(3)
356
+ end
357
+
358
+ it "should find between two times" do
359
+ stub_time
360
+ size(Time.zone.now - 5.days, Time.zone.now + 5.days).should eql(3)
361
+ end
362
+
363
+ it "should find between two dates" do
364
+ stub_time
365
+ size(Date.today, Date.today + 5).should eql(3)
366
+ end
367
+ end
368
+
369
+ describe "up to" do
370
+ it "should be able to find posts up to 2 weeks from now" do
371
+ stub_time
372
+ Post.up_to_6_weeks_from_now.size.should eql(9)
373
+ end
374
+
375
+ it "should be able to find posts up to 2 weeks from a given time" do
376
+ stub_time
377
+ Post.up_to_6_weeks_from_now(Time.zone.now - 1.month).size.should eql(14)
378
+ end
379
+
380
+ it "should error if given a date in the past" do
381
+ 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.")
382
+ end
383
+
384
+ it "should not do anything if given an invalid date" do
385
+ lambda { Post.up_to_ryans_birthday }.should raise_error(ByStar::ParseError, "Chronic couldn't work out \"Ryans birthday\"; please be more precise.")
386
+ end
387
+
388
+ end
389
+
390
+ # Because we override method_missing, we ensure that it still works as it should with this test.
391
+ describe "method_missing" do
392
+ it "should still work" do
393
+ Post.find_by_text("Today's post").should_not be_nil
394
+ end
395
+
396
+ it "should raise a proper NoMethodError" do
397
+ lambda { Post.idontexist }.should raise_error(NoMethodError, %r(^undefined method `idontexist'))
398
+ end
399
+ end
400
+
401
+ describe "named_scopes" do
402
+ it "should be compatible" do
403
+ Event.private.by_year(nil, :field => "start_time").size.should eql(1)
404
+ end
405
+ end
406
+
407
+ describe "joins" do
408
+ it "should not have ambiguous column names" do
409
+ lambda { Post.by_month do
410
+ { :joins => :tags }
411
+ end }.should_not raise_error
412
+ end
413
+ end
414
+
415
+
416
+ describe "nested find" do
417
+
418
+ it "should be able to find posts after right now" do
419
+ stub_time
420
+ Post.by_current_work_week.size.should eql(2)
421
+ Post.by_current_work_week do
422
+ { :conditions => ["created_at > ?", Time.now] }
423
+ end.size.should eql(0)
424
+ end
425
+
426
+ it "should be able to find a single post from last year with the tag 'ruby'" do
427
+ Post.by_year(Time.zone.now.year - 1) do
428
+ { :include => :tags, :conditions => ["tags.name = ?", 'ruby'] }
429
+ end.size.should eql(1)
430
+ end
431
+
432
+ it "should be able to find a single post from January last year with the tag 'ruby'" do
433
+ Post.by_month("January", :year => Time.zone.now.year - 1) do
434
+ { :include => :tags, :conditions => ["tags.name = ?", 'ruby'] }
435
+ end.size.should eql(1)
436
+ end
437
+
438
+ it "should be able to find a single post from the current fortnight with the tag 'may2'" do
439
+ stub_time
440
+ Post.by_fortnight do
441
+ { :include => :tags, :conditions => ["tags.name = ?", 'may2'] }
442
+ end.size.should eql(1)
443
+ end
444
+
445
+ it "should be able to find a single post from the current week with the tag 'may2'" do
446
+ stub_time
447
+ Post.by_week do
448
+ { :include => :tags, :conditions => ["tags.name = ?", 'may2'] }
449
+ end.size.should eql(1)
450
+ end
451
+
452
+ it "should be able to find a single post from the current weekend with the tag 'weekend'" do
453
+ stub_time
454
+ Post.by_weekend do
455
+ { :include => :tags, :conditions => ["tags.name = ?", 'weekend'] }
456
+ end.size.should eql(1)
457
+ end
458
+
459
+ it "should be able to find a single post from the current day with the tag 'today'" do
460
+ Post.by_day do
461
+ { :include => :tags, :conditions => ["tags.name = ?", 'today'] }
462
+ end.size.should eql(1)
463
+ end
464
+
465
+ it "should be able to find a single post from yesterday with the tag 'yesterday'" do
466
+ Post.yesterday do
467
+ { :include => :tags, :conditions => ["tags.name = ?", 'yesterday'] }
468
+ end.size.should eql(1)
469
+ end
470
+
471
+
472
+ it "should be able to find a single post from tomorrow with the tag 'tomorrow'" do
473
+ Post.tomorrow do
474
+ { :include => :tags, :conditions => ["tags.name = ?", 'tomorrow'] }
475
+ end.size.should eql(1)
476
+ end
477
+
478
+ it "should be able to find a single post from the past with the tag 'yesterday'" do
479
+ Post.past do
480
+ { :include => :tags, :conditions => ["tags.name = ?", 'yesterday'] }
481
+ end.size.should eql(1)
482
+ end
483
+
484
+ it "should be able to find a single post from the future with the tag 'tomorrow'" do
485
+ Post.future do
486
+ { :include => :tags, :conditions => ["tags.name = ?", 'tomorrow'] }
487
+ end.size.should eql(1)
488
+ end
489
+
490
+ end
491
+
492
+ describe Time do
493
+ it "should work out the beginning of a weekend (Friday 3pm)" do
494
+ range_test do
495
+ Time.now.beginning_of_weekend.strftime("%A %I:%M%p").should eql("Friday 03:00PM")
496
+ end
497
+ end
498
+
499
+ it "should work out the end of a weekend (Monday 3am)" do
500
+ range_test do
501
+ Time.now.end_of_weekend.strftime("%A %I:%M%p").should eql("Monday 03:00AM")
502
+ end
503
+ end
504
+ end
505
+
506
+ end