runt 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +48 -0
- data/LICENSE.txt +44 -0
- data/README +88 -0
- data/Rakefile +117 -0
- data/TODO +19 -0
- data/doc/tutorial_schedule.rdoc +51 -0
- data/doc/tutorial_te.rdoc +190 -0
- data/lib/runt.rb +93 -0
- data/lib/runt/daterange.rb +74 -0
- data/lib/runt/dprecision.rb +137 -0
- data/lib/runt/pdate.rb +127 -0
- data/lib/runt/schedule.rb +89 -0
- data/lib/runt/temporalexpression.rb +467 -0
- data/setup.rb +1331 -0
- data/site/blue-robot3.css +132 -0
- data/site/dcl-small.gif +0 -0
- data/site/index.html +92 -0
- data/site/logohover.png +0 -0
- data/site/runt-logo.gif +0 -0
- data/site/runt-logo.psd +0 -0
- data/test/alltests.rb +12 -0
- data/test/daterangetest.rb +82 -0
- data/test/dprecisiontest.rb +46 -0
- data/test/pdatetest.rb +106 -0
- data/test/scheduletest.rb +56 -0
- data/test/temporalexpressiontest.rb +282 -0
- metadata +62 -0
@@ -0,0 +1,56 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:<<'../lib'
|
4
|
+
|
5
|
+
require 'test/unit'
|
6
|
+
require 'runt'
|
7
|
+
require 'date'
|
8
|
+
|
9
|
+
# Unit tests for Schedule classes
|
10
|
+
# Author:: Matthew Lipper
|
11
|
+
class ScheduleTest < Test::Unit::TestCase
|
12
|
+
|
13
|
+
include Runt
|
14
|
+
|
15
|
+
def test_add
|
16
|
+
|
17
|
+
#Jane is very busy these days.
|
18
|
+
j_sched = Schedule.new
|
19
|
+
|
20
|
+
#Elmo's World is on TV: Mon-Fri 8am-8:30am
|
21
|
+
elmo = Event.new("Elmo's World")
|
22
|
+
|
23
|
+
j_sched.add(elmo,(REWeek.new(Mon,Fri) & REDay.new(8,00,8,30)))
|
24
|
+
assert(j_sched.include?(elmo, PDate.new(2004,5,4,8,06)))
|
25
|
+
assert(!j_sched.include?(elmo, PDate.new(2004,5,1,8,06)))
|
26
|
+
assert(!j_sched.include?(elmo, PDate.new(2004,5,3,9,06)))
|
27
|
+
|
28
|
+
#Oobi's on TV: Thu-Sat 8:30am-9am
|
29
|
+
oobi = Event.new("Oobi")
|
30
|
+
|
31
|
+
j_sched.add(oobi,(REWeek.new(Thu,Sat) & REDay.new(8,30,9,00)))
|
32
|
+
|
33
|
+
assert(j_sched.include?(oobi, PDate.new(2004,4,30,8,56)))
|
34
|
+
assert(!j_sched.include?(oobi, PDate.new(2004,5,1,8,12)))
|
35
|
+
assert(!j_sched.include?(oobi, PDate.new(2004,5,5,8,50)))
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_dates
|
40
|
+
|
41
|
+
# range: May 1st, 2004 to May 31st, 2004
|
42
|
+
d_range = DateRange.new(PDate.day(2004,5,1), PDate.day(2004,5,31))
|
43
|
+
sched = Schedule.new
|
44
|
+
event = Event.new("Visit Ernie")
|
45
|
+
|
46
|
+
# First and last Friday of the month
|
47
|
+
expr1 = DIMonth.new(1,Fri) | DIMonth.new(-1,Fri)
|
48
|
+
sched.add(event,expr1)
|
49
|
+
|
50
|
+
dates = sched.dates(event,d_range)
|
51
|
+
expected = [PDate.day(2004,5,7), PDate.day(2004,5,28)]
|
52
|
+
assert_equal(expected,dates)
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
@@ -0,0 +1,282 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:<<'../lib'
|
4
|
+
|
5
|
+
require 'test/unit'
|
6
|
+
require 'runt'
|
7
|
+
require 'date'
|
8
|
+
|
9
|
+
$DEBUG=false
|
10
|
+
|
11
|
+
# Unit tests for TExpr classes
|
12
|
+
# Author:: Matthew Lipper
|
13
|
+
class TExprTest < Test::Unit::TestCase
|
14
|
+
|
15
|
+
include Runt
|
16
|
+
include DPrecision
|
17
|
+
|
18
|
+
def test_collection_te
|
19
|
+
#base class that should always return false
|
20
|
+
expr = Collection.new
|
21
|
+
assert(!expr.include?(Date.today))
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_union_te
|
25
|
+
#midnight to 6:30am AND/OR first Tuesday of the month
|
26
|
+
expr = REDay.new(0,0,6,30) | DIMonth.new(First,Tuesday)
|
27
|
+
assert(expr.include?(PDate.day(2004,1,6))) #January 6th, 2004 (First Tuesday)
|
28
|
+
assert(expr.include?(PDate.hour(1966,2,8,4))) #4am (February, 8th, 1966 - ignored)
|
29
|
+
assert(!expr.include?(PDate.min(2030,7,4,6,31))) #6:31am, July, 4th, 2030
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_arbitrary_te
|
33
|
+
expr1 = Spec.new(PDate.day(2003,12,30))
|
34
|
+
expr2 = Spec.new(PDate.day(2004,1,1))
|
35
|
+
assert(expr1.include?(Date.new(2003,12,30)))
|
36
|
+
assert(!expr1.include?(Date.new(2003,12,31)))
|
37
|
+
assert(expr2.include?(Date.new(2004,1,1)))
|
38
|
+
assert(!expr2.include?(Date.new(2003,1,1)))
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_arbitrary_range_te
|
42
|
+
#NOTE:
|
43
|
+
#Using standard range functionality like the following:
|
44
|
+
#... expr1 = RSpec.new(r_start..r_end)
|
45
|
+
#... assert(expr1.include?((r_start+10)..(r_end-10)))
|
46
|
+
#will work. However, it takes a LONG time to evaluate if range is large
|
47
|
+
#and/or precision is small. Use DateRange instead
|
48
|
+
|
49
|
+
r_start = PDate.sec(2004,2,29,16,24,12)
|
50
|
+
r_end = PDate.sec(2004,3,2,4,22,58)
|
51
|
+
#inclusive range equivalent to r_start..r_end
|
52
|
+
expr1 = RSpec.new(DateRange.new(r_start,r_end))
|
53
|
+
assert(expr1.include?(PDate.sec(2004,2,29,16,24,12)))
|
54
|
+
assert(expr1.include?(PDate.sec(2004,3,2,4,22,58)))
|
55
|
+
assert(expr1.include?(DateTime.new(2004,3,1,23,00)))
|
56
|
+
assert(!expr1.include?(DateTime.new(2004,3,2,4,22,59)))
|
57
|
+
assert(!expr1.include?(Date.new(2003,3,1)))
|
58
|
+
#exclusive range equivalent to r_start...r_end
|
59
|
+
expr2 = RSpec.new(DateRange.new(r_start,r_end,true))
|
60
|
+
assert(expr2.include?(PDate.sec(2004,2,29,16,24,12)))
|
61
|
+
assert(!expr2.include?(PDate.sec(2004,3,2,4,22,58)))
|
62
|
+
r_sub = DateRange.new( (r_start+10), (r_end-10) )
|
63
|
+
assert(expr1.include?(r_sub))
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_intersection_te
|
67
|
+
#Should match the first Sunday of March and April
|
68
|
+
expr1 = REYear.new(3,4) & DIMonth.new(First,Sunday)
|
69
|
+
assert(expr1.include?(PDate.new(2004,3,7))) #Sunday, March 7th, 2004
|
70
|
+
assert(!expr1.include?(PDate.new(2004,4,1))) #First Sunday in February, 2004
|
71
|
+
expr2 = REWeek.new(Mon,Fri) & REDay.new(8,00,8,30)
|
72
|
+
assert(expr2.include?( PDate.new(2004,5,4,8,06)))
|
73
|
+
assert(!expr2.include?(PDate.new(2004,5,1,8,06)))
|
74
|
+
assert(!expr2.include?(PDate.new(2004,5,3,9,06)))
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_difference_te
|
78
|
+
#Should match for 8:30 pm to 11:04 pm
|
79
|
+
diff_expr = REDay.new(20,30,00,00) - REDay.new(23,04,6,20)
|
80
|
+
#8:45 pm (May 1st, 2003 - ignored)
|
81
|
+
assert(diff_expr.include?(PDate.new(2003,5,1,20,45)))
|
82
|
+
#11:05 pm (February 1st, 2004 - ignored)
|
83
|
+
assert(!diff_expr.include?(PDate.new(2004,2,1,23,05)))
|
84
|
+
#8:00 pm (May 1st, 2003 - ignored)
|
85
|
+
assert(!diff_expr.include?(PDate.new(2003,5,1,20,00)))
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_day_in_month_te
|
89
|
+
#Friday, January 16th 2004
|
90
|
+
dt1 = Date.civil(2004,1,16)
|
91
|
+
#Friday, January 9th 2004
|
92
|
+
dt2 = Date.civil(2004,1,9)
|
93
|
+
#third Friday of the month
|
94
|
+
expr1 = DIMonth.new(Third,Friday)
|
95
|
+
#second Friday of the month
|
96
|
+
expr2 = DIMonth.new(Second,Friday)
|
97
|
+
assert(expr1.include?(dt1))
|
98
|
+
assert(!expr1.include?(dt2))
|
99
|
+
assert(expr2.include?(dt2))
|
100
|
+
assert(!expr2.include?(dt1))
|
101
|
+
#Sunday, January 25th 2004
|
102
|
+
dt3 = Date.civil(2004,1,25)
|
103
|
+
#last Sunday of the month
|
104
|
+
expr3 = DIMonth.new(Last_of,Sunday)
|
105
|
+
assert(expr3.include?(dt3))
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_day_in_week_te
|
109
|
+
#Friday (woo-hoo!)
|
110
|
+
expr = DIWeek.new(Friday)
|
111
|
+
#Friday, January 9th 2004
|
112
|
+
assert(expr.include?(PDate.new(2004,1,9)))
|
113
|
+
#Friday, January 16th 2004
|
114
|
+
assert(expr.include?(PDate.new(2004,1,16)))
|
115
|
+
#Monday, January 12th 2004
|
116
|
+
assert(!expr.include?(PDate.new(2004,1,12)))
|
117
|
+
end
|
118
|
+
def test_week_in_month_te
|
119
|
+
expr = WIMonth.new(Third)
|
120
|
+
assert(expr.include?(PDate.day(2004,2,19)))
|
121
|
+
assert(!expr.include?(PDate.day(2004,2,29)))
|
122
|
+
expr2 = WIMonth.new(Last_of)
|
123
|
+
assert(expr2.include?(PDate.day(2004,2,29)))
|
124
|
+
expr3 = WIMonth.new(Second_to_last)
|
125
|
+
assert(expr3.include?(PDate.day(2004,2,22)))
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_range_each_year_te
|
129
|
+
# November 1st, 1961
|
130
|
+
dt1 = Date.civil(1961,11,1)
|
131
|
+
#June, 1986
|
132
|
+
dt2 = PDate::month(1986,6)
|
133
|
+
#November and December
|
134
|
+
expr1 = REYear.new(11,12)
|
135
|
+
#May 31st through and September 6th
|
136
|
+
expr2 = REYear.new(5,31,9,6)
|
137
|
+
assert(expr1.include?(dt1))
|
138
|
+
assert(!expr1.include?(dt2))
|
139
|
+
assert(expr2.include?(dt2))
|
140
|
+
#August
|
141
|
+
expr3 = REYear.new(8)
|
142
|
+
assert(!expr3.include?(dt1))
|
143
|
+
assert(!expr3.include?(dt2))
|
144
|
+
#August 6th, 2004
|
145
|
+
dt3 = Date::new(2004,8,6)
|
146
|
+
assert(expr3.include?(dt3))
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_range_each_day_te
|
150
|
+
#noon to 4:30pm
|
151
|
+
expr1 = REDay.new(12,0,16,30)
|
152
|
+
#3:15 pm (May 8th, 2012 - ignored)
|
153
|
+
assert(expr1.include?(PDate.hour(2012,5,8,15,15)))
|
154
|
+
#4:30 pm (April 18th, 1922 - ignored)
|
155
|
+
assert(expr1.include?(PDate.hour(1922,4,18,16,30)))
|
156
|
+
#noon (June 5th, 1975 - ignored)
|
157
|
+
assert(expr1.include?(PDate.hour(1975,6,5,12,0)))
|
158
|
+
#3:15 am (May 8th, 2012 - ignored)
|
159
|
+
assert(!expr1.include?(PDate.hour(2012,5,8,3,15)))
|
160
|
+
#8:30pm to 12:00 midnite
|
161
|
+
expr2 = REDay.new(20,30,00,00)
|
162
|
+
#9:00 pm (January 28th, 2004 - ignored)
|
163
|
+
assert(expr2.include?(PDate.min(2004,1,28,21,00)))
|
164
|
+
#12:00 am (January 28th, 2004 - ignored)
|
165
|
+
assert(expr2.include?(PDate.min(2004,1,28,0,0)))
|
166
|
+
#12:01 am (January 28th, 2004 - ignored)
|
167
|
+
assert(!expr2.include?(PDate.min(2004,1,28,0,01)))
|
168
|
+
end
|
169
|
+
def test_range_each_week_te
|
170
|
+
|
171
|
+
assert_raises(ArgumentError){ expr = REWeek.new(10,4) }
|
172
|
+
|
173
|
+
expr1 = REWeek.new(Mon,Fri) & REDay.new(8,00,8,30)
|
174
|
+
assert(!expr1.include?(PDate.new(2004,5,1,8,06)))
|
175
|
+
|
176
|
+
|
177
|
+
#Sunday through Thursday
|
178
|
+
expr2 = REWeek.new(0,4)
|
179
|
+
assert(expr2.include?(PDate.min(2004,2,19,23,59,59)))
|
180
|
+
assert(!expr2.include?(PDate.min(2004,2,20,0,0,0)))
|
181
|
+
end
|
182
|
+
def test_combined_te
|
183
|
+
#This is a hack.....
|
184
|
+
#In the U.S., Memorial Day begins the last Monday of May
|
185
|
+
#
|
186
|
+
#The month of May
|
187
|
+
may=REYear.new(5)
|
188
|
+
#Monday through Saturday
|
189
|
+
monday_to_saturday = REWeek.new(1,6)
|
190
|
+
#Last week of (any) month
|
191
|
+
last_week_in = WIMonth.new(Last_of)
|
192
|
+
#So, to say 'starting from the last Monday in May',
|
193
|
+
#we need to select just that last week of May begining with
|
194
|
+
#the Monday of that week
|
195
|
+
last_week_of_may = may & monday_to_saturday & last_week_in
|
196
|
+
|
197
|
+
#This is another hack similar to the above, except instead of selecting a range
|
198
|
+
#starting at the begining of the month, we need to select only the time period in
|
199
|
+
#September up until Labor Day.
|
200
|
+
#
|
201
|
+
#In the U.S., Labor Day is the first Monday in September
|
202
|
+
#
|
203
|
+
#The month of September
|
204
|
+
september=REYear.new(9)
|
205
|
+
#First week of (any) month
|
206
|
+
first_week_in = WIMonth.new(First)
|
207
|
+
entire_first_week_of_september = september & first_week_in
|
208
|
+
#To exclude everything in the first week which occurs on or after Monday.
|
209
|
+
first_week_of_september=entire_first_week_of_september - monday_to_saturday
|
210
|
+
#June through August
|
211
|
+
june_through_august=REYear.new(6,First,8)
|
212
|
+
assert(june_through_august.include?(PDate.day(2004,7,4)))
|
213
|
+
#Finally!
|
214
|
+
summer_time = last_week_of_may | first_week_of_september | june_through_august
|
215
|
+
|
216
|
+
#Will work, but will be incredibly slow:
|
217
|
+
# assert(summer_time.include?(PDate.min(2004,5,31,0,0)))
|
218
|
+
assert(summer_time.include?(PDate.day(2004,5,31,0,0)))
|
219
|
+
assert(summer_time.include?(PDate.day(2004,7,4)))
|
220
|
+
#also works...also slow:
|
221
|
+
# assert(!summer_time.include?(PDate.min(2004,9,6,0,0)))
|
222
|
+
assert(!summer_time.include?(PDate.hour(2004,9,6,0,0)))
|
223
|
+
|
224
|
+
end
|
225
|
+
def test_nyc_parking_te
|
226
|
+
|
227
|
+
#Monday, Wednesday, Friday
|
228
|
+
mon_wed_fri = DIWeek.new(Mon) | \
|
229
|
+
DIWeek.new(Wed) | \
|
230
|
+
DIWeek.new(Fri)
|
231
|
+
|
232
|
+
|
233
|
+
#Wednesday (at 7:15pm - ignored)
|
234
|
+
assert(mon_wed_fri.include?(DateTime.new(2004,3,10,19,15)))
|
235
|
+
|
236
|
+
#Sunday (at 9:00am - ignored)
|
237
|
+
assert(!mon_wed_fri.include?(DateTime.new(2004,3,14,9,00)))
|
238
|
+
|
239
|
+
#8am to 11am
|
240
|
+
eight_to_eleven = REDay.new(8,00,11,00)
|
241
|
+
|
242
|
+
#=> Mon,Wed,Fri - 8am to 11am
|
243
|
+
expr1 = mon_wed_fri & eight_to_eleven
|
244
|
+
|
245
|
+
#Tuesdays, Thursdays
|
246
|
+
tues_thurs = DIWeek.new(Tue) | DIWeek.new(Thu)
|
247
|
+
|
248
|
+
#11:30am to 2pm
|
249
|
+
eleven_thirty_to_two = REDay.new(11,30,14,00)
|
250
|
+
|
251
|
+
#Noon (on Monday - ignored)
|
252
|
+
assert(eleven_thirty_to_two.include?(DateTime.new(2004,3,8,12,00)))
|
253
|
+
|
254
|
+
#Midnite (on Thursday - ignored)
|
255
|
+
assert(!eleven_thirty_to_two.include?(DateTime.new(2004,3,11,00,00)))
|
256
|
+
|
257
|
+
|
258
|
+
#=> Tues,Thurs - 11:30am to 2pm
|
259
|
+
expr2 = tues_thurs & eleven_thirty_to_two
|
260
|
+
|
261
|
+
#
|
262
|
+
#Sigh...now if I can only get my dad to remember this...
|
263
|
+
#
|
264
|
+
parking_ticket = expr1 | expr2
|
265
|
+
|
266
|
+
assert(parking_ticket.include?(DateTime.new(2004,3,11,12,15)))
|
267
|
+
assert(parking_ticket.include?(DateTime.new(2004,3,10,9,15)))
|
268
|
+
assert(parking_ticket.include?(DateTime.new(2004,3,10,8,00)))
|
269
|
+
|
270
|
+
assert(!parking_ticket.include?(DateTime.new(2004,3,11,1,15)))
|
271
|
+
|
272
|
+
# Simplified
|
273
|
+
e1 = (DIWeek.new(Mon) | DIWeek.new(Wed) | DIWeek.new(Fri)) & REDay.new(8,00,11,00)
|
274
|
+
e2 = (DIWeek.new(Tue) | DIWeek.new(Thu)) & REDay.new(11,30,14,00)
|
275
|
+
ticket = expr1 | expr2
|
276
|
+
assert(ticket.include?(DateTime.new(2004,3,11,12,15)))
|
277
|
+
assert(ticket.include?(DateTime.new(2004,3,10,9,15)))
|
278
|
+
assert(ticket.include?(DateTime.new(2004,3,10,8,00)))
|
279
|
+
assert(!ticket.include?(DateTime.new(2004,3,11,1,15)))
|
280
|
+
end
|
281
|
+
|
282
|
+
end
|
metadata
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.8.1
|
3
|
+
specification_version: 1
|
4
|
+
name: runt
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.2.0
|
7
|
+
date: 2004-11-29
|
8
|
+
summary: Ruby Temporal Expressions.
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
author: Matthew Lipper
|
12
|
+
email: matt@digitalclash.com
|
13
|
+
homepage: http://runt.rubyforge.org
|
14
|
+
rubyforge_project: runt
|
15
|
+
description: Runt is a Ruby version of temporal patterns by Martin Fowler. Runt provides an API for scheduling recurring events using set-like semantics.
|
16
|
+
autorequire: runt
|
17
|
+
default_executable:
|
18
|
+
bindir: bin
|
19
|
+
has_rdoc: true
|
20
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
21
|
+
requirements:
|
22
|
+
-
|
23
|
+
- ">"
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: 0.0.0
|
26
|
+
version:
|
27
|
+
platform: ruby
|
28
|
+
files:
|
29
|
+
- setup.rb
|
30
|
+
- CHANGES
|
31
|
+
- LICENSE.txt
|
32
|
+
- Rakefile
|
33
|
+
- README
|
34
|
+
- TODO
|
35
|
+
- lib/runt.rb
|
36
|
+
- lib/runt/daterange.rb
|
37
|
+
- lib/runt/dprecision.rb
|
38
|
+
- lib/runt/pdate.rb
|
39
|
+
- lib/runt/schedule.rb
|
40
|
+
- lib/runt/temporalexpression.rb
|
41
|
+
- test/alltests.rb
|
42
|
+
- test/daterangetest.rb
|
43
|
+
- test/dprecisiontest.rb
|
44
|
+
- test/pdatetest.rb
|
45
|
+
- test/scheduletest.rb
|
46
|
+
- test/temporalexpressiontest.rb
|
47
|
+
- doc/tutorial_schedule.rdoc
|
48
|
+
- doc/tutorial_te.rdoc
|
49
|
+
- site/blue-robot3.css
|
50
|
+
- site/dcl-small.gif
|
51
|
+
- site/index.html
|
52
|
+
- site/logohover.png
|
53
|
+
- site/runt-logo.gif
|
54
|
+
- site/runt-logo.psd
|
55
|
+
test_files: []
|
56
|
+
rdoc_options: []
|
57
|
+
extra_rdoc_files: []
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
requirements:
|
61
|
+
- none
|
62
|
+
dependencies: []
|