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/.gitignore +2 -0
- data/MIT-LICENSE +20 -0
- data/README.markdown +271 -0
- data/Rakefile +50 -0
- data/VERSION +1 -0
- data/by_star.gemspec +57 -0
- data/lib/by_star.rb +316 -0
- data/rails/init.rb +2 -0
- data/spec/by_star_spec.rb +506 -0
- data/spec/fixtures/models.rb +70 -0
- data/spec/fixtures/schema.rb +24 -0
- data/spec/spec_helper.rb +27 -0
- metadata +80 -0
data/rails/init.rb
ADDED
@@ -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
|