by_star 0.2.5

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