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