runt 0.2.0 → 0.3.0

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/CHANGES CHANGED
@@ -1,5 +1,28 @@
1
1
  = Runt Changelog
2
2
 
3
+ == Version 0.3.0
4
+
5
+ * TExpr (finally!) becomes a Module instead of a superclass
6
+
7
+ * Added overlap? method for all temporal expressions and DateRange
8
+
9
+ * Added REMonth expression which matches a range of dates each month
10
+
11
+ * Contributed by Emmett Shear: TExpr#dates method which returns an array of dates occurring within the supplied DateRange
12
+
13
+ * Rakefile fixes:
14
+ - test path allow gem to be installed with -t switch
15
+ - usage of gzip which will break on Win32
16
+
17
+ * Removed and then subsequently restored SpecTE
18
+
19
+ * General clean-up, including:
20
+ - renamed several methods on PDate
21
+ - renamed 'dateprecisiontest.rb' to 'dprecisiontest.rb'
22
+
23
+ * Fixed Object.id deprecation warning
24
+
25
+
3
26
  == Version 0.2.0
4
27
 
5
28
  * Fixed Schedule class
data/README CHANGED
@@ -8,6 +8,10 @@
8
8
 
9
9
  = INSTALL
10
10
 
11
+ * gem install runt
12
+
13
+ <b>or</b>
14
+
11
15
  * Unpack the Runt distribution.
12
16
 
13
17
  $ tar -xzvf runt-<version>.tar.gz
@@ -32,7 +36,7 @@
32
36
 
33
37
  * require 'runt'
34
38
 
35
- * See http://runt.rubyforge.org/doc/index.html
39
+ * See Runt website[http://runt.rubyforge.org].
36
40
 
37
41
  * See $UNPACK_DIR/runt/test/*.rb for example usage.
38
42
 
@@ -66,7 +70,9 @@ The ruby-nyc user's group for their suggestions and feedback.
66
70
 
67
71
  BlueRobot[http://www.bluerobot.com/web/layouts/] for the CSS used to prettify the Runt website.
68
72
 
69
- The number 12, and the letters E and J.
73
+ Emmett Shear for contributed TExpr#dates code and several thought-provoking feature requests.
74
+
75
+ The number 12, and the letters E, J, and B.
70
76
 
71
77
  ---
72
78
 
@@ -85,4 +91,4 @@ implied warranties, including, without limitation, the implied
85
91
  warranties of merchantibility and fitness for a particular
86
92
  purpose.
87
93
 
88
- link://../dcl-small.gif
94
+ link://../dcl-small.gif
data/Rakefile CHANGED
@@ -10,15 +10,17 @@ require 'rake'
10
10
  require 'rake/clean'
11
11
  require 'rake/testtask'
12
12
  require 'rake/rdoctask'
13
- #require 'rake/packagetask'
14
-
15
13
  require 'rake/contrib/sshpublisher'
16
14
  require 'rake/contrib/rubyforgepublisher'
17
15
  require 'fileutils'
18
16
 
17
+ #####################################################################
18
+ # Constants
19
+ #####################################################################
20
+
19
21
  # Build Settings
20
- PKG_VERSION = "0.2.0"
21
- # 'gem_install_bin.rb',
22
+ PKG_VERSION = "0.3.0"
23
+
22
24
  # Files to be included in Runt distribution
23
25
  PKG_FILES = FileList[
24
26
  'setup.rb',
@@ -29,10 +31,19 @@ PKG_FILES = FileList[
29
31
  'site/**/*'
30
32
  ].exclude("*.ses")
31
33
 
34
+ if(RUBY_PLATFORM =~ /win32/i)
35
+ PKG_EXEC_TAR = false
36
+ else
37
+ PKG_EXEC_TAR = true
38
+ end
39
+
32
40
  # build directory
33
41
  TARGET_DIR = "target"
34
42
 
43
+ #####################################################################
35
44
  # Targets
45
+ #####################################################################
46
+
36
47
  task :default => [:test]
37
48
  task :clobber => [:clobber_build_dir]
38
49
 
@@ -55,14 +66,7 @@ end
55
66
  Rake::TestTask.new do |t|
56
67
  t.libs << "test"
57
68
  t.pattern = 'test/alltests.rb'
58
- t.verbose = true
59
- end
60
-
61
- Rake::PackageTask.new("runt", PKG_VERSION) do |p|
62
- p.package_dir="#{TARGET_DIR}/#{p.package_dir}"
63
- p.need_tar = true
64
- p.need_zip = true
65
- p.package_files.include(PKG_FILES)
69
+ t.verbose = false
66
70
  end
67
71
 
68
72
  desc "Copy html files for the Runt website to the build directory."
@@ -79,7 +83,7 @@ task :publish => [:rdoc,:copy_site,:clobber_package] do |t|
79
83
  end
80
84
 
81
85
  desc "Publish the Documentation to the build dir."
82
- task :test_publish => [:rerdoc,:copy_site,:clobber_package] do |t|
86
+ task :test_publish => [:rdoc,:copy_site,:clobber_package] do |t|
83
87
  puts "YAY! We've tested publish! YAY!"
84
88
  end
85
89
 
@@ -100,8 +104,7 @@ else
100
104
  s.email = 'matt@digitalclash.com'
101
105
  s.homepage = 'http://runt.rubyforge.org'
102
106
  s.has_rdoc = true
103
- # s.rdoc_files = rd.rdoc_files
104
- # s.rdoc_options = rd.option_list
107
+ s.test_files = Dir['test/*test.rb']
105
108
  s.rubyforge_project = 'runt'
106
109
  s.description = <<EOF
107
110
  Runt is a Ruby version of temporal patterns by
@@ -112,6 +115,6 @@ EOF
112
115
 
113
116
  Rake::GemPackageTask.new(spec) do |pkg|
114
117
  pkg.need_zip = true
115
- pkg.need_tar = true
118
+ pkg.need_tar = PKG_EXEC_TAR
116
119
  end
117
120
  end
data/TODO CHANGED
@@ -4,16 +4,17 @@ Send suggestions, questions, threats, etc. for this list to Matt[mailto:matt@dig
4
4
 
5
5
  === To Do
6
6
 
7
- * Fix REWeek so that ordinal day values where the end day < start day does not fail
7
+ * Schedule tutorial
8
8
 
9
- * Make Schedule a Module instead of a class
9
+ * Example usage with Rails
10
10
 
11
- * Schedule tutorial
11
+ * Persistence strategy:
12
+ - Marshall
13
+ - database...create storable grammar, expression stack?
12
14
 
13
- * Better RDoc's which include usage examples
15
+ * Fix REWeek so that ordinal day values where the end day < start day does not fail
14
16
 
15
- * Properly implement/test Range functionality in DateRange
17
+ * Make Schedule a Module instead of a class
16
18
 
17
19
  * Address performance issues due to implementation (in particular, PDate#<=>)
18
20
 
19
- * Use RDoc properly so Runt website and README don't cause DRY violations
@@ -48,4 +48,4 @@ We created a temporal expression to match this time period, like so:
48
48
 
49
49
  * Fowler's recurring event pattern[http://martinfowler.com/apsupp/recurring.pdf]
50
50
 
51
- * Other temporal patterns[http://martinfowler.com/ap2/timeNarrative.html]
51
+ * Other temporal patterns[http://martinfowler.com/ap2/timeNarrative.html]
@@ -181,10 +181,10 @@ easy to write your own.
181
181
 
182
182
  Fowler's paper[http://martinfowler.com/apsupp/recurring.pdf] also goes
183
183
  on to describe another element of this pattern: the <tt>Schedule</tt>.
184
- See the schedule tutorial[http://runt.rubyforge.org/doc/files/doc/schedule_te.html] for details.
184
+ See the schedule tutorial[http://runt.rubyforge.org/doc/files/doc/tutorial_schedule_rdoc.html] for details.
185
185
 
186
186
  <em>See Also:</em>
187
187
 
188
188
  * Fowler's recurring event pattern[http://martinfowler.com/apsupp/recurring.pdf]
189
189
 
190
- * Other temporal patterns[http://martinfowler.com/ap2/timeNarrative.html]
190
+ * Other temporal patterns[http://martinfowler.com/ap2/timeNarrative.html]
@@ -84,10 +84,27 @@ module Runt
84
84
  @negate.call(arg)
85
85
  end
86
86
  end
87
+ LastProc = ApplyLast.new
87
88
 
88
89
  public
89
- Last = ApplyLast.new
90
- Last_of = Last[First]
91
- Second_to_last = Last[Second]
90
+ Last = LastProc[First]
91
+ Last_of = LastProc[First]
92
+ Second_to_last = LastProc[Second]
92
93
 
93
- end
94
+ end
95
+
96
+ #
97
+ # Add precision +Runt::DPrecision+ to standard library classes Date and DateTime
98
+ # (which is a subclass of Date).
99
+ #
100
+ class Date
101
+
102
+ include Runt::DPrecision
103
+
104
+ attr_accessor :date_precision
105
+
106
+ def date_precision
107
+ return @date_precision unless @date_precision.nil?
108
+ return Runt::DPrecision::DEFAULT
109
+ end
110
+ end
@@ -31,9 +31,9 @@ module Runt
31
31
  end
32
32
 
33
33
  def overlap?(obj)
34
- return true if( include?(obj.min) || include?(obj.max) )
35
- return true if( obj.kind_of?(Range) && obj.include?(self) )
36
- false
34
+ return true if( member?(obj) || include?(obj.min) || include?(obj.max) )
35
+ return true if( obj.kind_of?(Range) && obj.include?(self) )
36
+ false
37
37
  end
38
38
 
39
39
  def empty?
@@ -71,4 +71,4 @@ module Runt
71
71
  EMPTY = DateRange.new(PDate.day(2004,2,2),PDate.day(2004,2,1))
72
72
 
73
73
  end
74
- end
74
+ end
@@ -123,5 +123,4 @@ module Runt
123
123
  end
124
124
 
125
125
  end
126
-
127
126
  end
@@ -2,19 +2,13 @@
2
2
 
3
3
  require 'date'
4
4
  require 'runt/dprecision'
5
+ require 'runt/pdate'
5
6
 
6
7
  #
7
8
  # Author:: Matthew Lipper
8
9
 
9
10
  module Runt
10
11
 
11
- # FKA = 'Formally Known As'
12
-
13
-
14
- # FKA: TemporalExpression
15
- #
16
- # Base class for all TExpr classes that has proved itself usefull enough to
17
- # avoid O's Razor, but that may wind up as a module.
18
12
  #
19
13
  # 'TExpr' is short for 'TemporalExpression' and are inspired by the recurring event
20
14
  # <tt>pattern</tt>[http://martinfowler.com/apsupp/recurring.pdf]
@@ -22,11 +16,12 @@ module Runt
22
16
  # specifying recurring events using set expressions.
23
17
  #
24
18
  # See also [tutorial_te.rdoc]
25
- class TExpr
19
+ module TExpr
26
20
 
27
21
  # Returns true or false depending on whether this TExpr includes the supplied
28
22
  # date expression.
29
23
  def include?(date_expr); false end
24
+
30
25
  def to_s; "TExpr" end
31
26
 
32
27
  def or (arg)
@@ -65,44 +60,25 @@ class TExpr
65
60
  self.minus(expr){|adjusted| adjusted }
66
61
  end
67
62
 
68
- protected
69
- def week_in_month(day_in_month)
70
- ((day_in_month - 1) / 7) + 1
71
- end
72
-
73
- def days_left_in_month(date)
74
- return max_day_of_month(date) - date.day
75
- end
76
-
77
- def max_day_of_month(date)
78
- result = 1
79
- date.step( Date.new(date.year,date.mon+1,1), 1 ){ |d| result=d.day unless d.day < result }
80
- result
81
- end
82
-
83
- def week_matches?(index,date)
84
- if(index > 0)
85
- return week_from_start_matches?(index,date)
86
- else
87
- return week_from_end_matches?(index,date)
63
+ # Contributed by Emmett Shear:
64
+ # Returns an Array of Date-like objects which occur within the supplied
65
+ # DateRange.
66
+ def dates(date_range)
67
+ result = []
68
+ date_range.each do |date|
69
+ result << date if self.include? date
88
70
  end
89
- end
90
-
91
- def week_from_start_matches?(index,date)
92
- week_in_month(date.day)==index
93
- end
94
-
95
- def week_from_end_matches?(index,date)
96
- n = days_left_in_month(date) + 1
97
- week_in_month(n)==index.abs
71
+ result
98
72
  end
99
73
 
100
74
  end
101
75
 
102
76
  # Base class for TExpr classes that can be composed of other
103
77
  # TExpr objects imlpemented using the <tt>Composite(GoF)</tt> pattern.
104
- class Collection < TExpr
105
-
78
+ class Collection
79
+
80
+ include TExpr
81
+
106
82
  attr_reader :expressions
107
83
  protected :expressions
108
84
 
@@ -115,6 +91,16 @@ class Collection < TExpr
115
91
  self
116
92
  end
117
93
 
94
+ # Will return true if the supplied object overlaps with the range used to
95
+ # create this instance
96
+ def overlap?(date_expr)
97
+ @expressions.each do | interval |
98
+ return true if date_expr.overlap?(interval)
99
+ end
100
+ false
101
+ end
102
+
103
+
118
104
  def to_s; "Collection:" + @expressions.to_s end
119
105
  end
120
106
 
@@ -137,7 +123,6 @@ end
137
123
  class Intersect < Collection
138
124
 
139
125
  def include?(aDate)
140
- #Handle @expressions.size==0
141
126
  result = false
142
127
  @expressions.each do |expr|
143
128
  return false unless (result = expr.include?(aDate))
@@ -149,8 +134,10 @@ class Intersect < Collection
149
134
  end
150
135
 
151
136
  # TExpr that will be true only if the first of
152
- # it's two contained expressions is true and the second is false.
153
- class Diff < TExpr
137
+ # its two contained expressions is true and the second is false.
138
+ class Diff
139
+
140
+ include TExpr
154
141
 
155
142
  def initialize(expr1, expr2)
156
143
  @expr1 = expr1
@@ -166,8 +153,10 @@ class Diff < TExpr
166
153
  end
167
154
 
168
155
  # TExpr that provides for inclusion of an arbitrary date.
169
- class Spec < TExpr
170
-
156
+ class Spec
157
+
158
+ include TExpr
159
+
171
160
  def initialize(date_expr)
172
161
  @date_expr = date_expr
173
162
  end
@@ -187,10 +176,11 @@ end
187
176
  # facilitating inclusion of an arbitrary range in a temporal expression.
188
177
  #
189
178
  # See also: Range
190
- class RSpec < TExpr
179
+ class RSpec
180
+
181
+ include TExpr
191
182
 
192
183
  def initialize(date_expr)
193
- raise TypeError, 'expected range' unless date_expr.kind_of?(Range)
194
184
  @date_expr = date_expr
195
185
  end
196
186
 
@@ -199,10 +189,62 @@ class RSpec < TExpr
199
189
  def include?(date_expr)
200
190
  return @date_expr.include?(date_expr)
201
191
  end
192
+
193
+ # Will return true if the supplied object overlaps with the range used to
194
+ # create this instance
195
+ def overlap?(date_expr)
196
+ @date_expr.each do | interval |
197
+ return true if date_expr.include?(interval)
198
+ end
199
+ false
200
+ end
202
201
 
203
202
  def to_s; "RSpec" end
204
203
  end
205
204
 
205
+ #######################################################################
206
+ # Utility methods common to some expressions
207
+
208
+ module TExprUtils
209
+ def week_in_month(day_in_month)
210
+ ((day_in_month - 1) / 7) + 1
211
+ end
212
+
213
+ def days_left_in_month(date)
214
+ return max_day_of_month(date) - date.day
215
+ end
216
+
217
+ def max_day_of_month(date)
218
+ result = 1
219
+ next_month = nil
220
+ if(date.mon==12)
221
+ next_month = Date.new(date.year+1,1,1)
222
+ else
223
+ next_month = Date.new(date.year,date.mon+1,1)
224
+ end
225
+ date.step(next_month,1){ |d| result=d.day unless d.day < result }
226
+ result
227
+ end
228
+
229
+ def week_matches?(index,date)
230
+ if(index > 0)
231
+ return week_from_start_matches?(index,date)
232
+ else
233
+ return week_from_end_matches?(index,date)
234
+ end
235
+ end
236
+
237
+ def week_from_start_matches?(index,date)
238
+ week_in_month(date.day)==index
239
+ end
240
+
241
+ def week_from_end_matches?(index,date)
242
+ n = days_left_in_month(date) + 1
243
+ week_in_month(n)==index.abs
244
+ end
245
+
246
+ end
247
+
206
248
  # TExpr that provides support for building a temporal
207
249
  # expression using the form:
208
250
  #
@@ -228,7 +270,10 @@ end
228
270
  # DIMonth.new(Last,Saturday)
229
271
  #
230
272
  # See also: Date, Runt
231
- class DIMonth < TExpr
273
+ class DIMonth
274
+
275
+ include TExpr
276
+ include TExprUtils
232
277
 
233
278
  def initialize(week_of_month_index,day_index)
234
279
  @day_index = day_index
@@ -243,17 +288,6 @@ class DIMonth < TExpr
243
288
  "DIMonth"
244
289
  end
245
290
 
246
- def print(date)
247
- puts "DIMonth: #{date}"
248
- puts "include? == #{include?(date)}"
249
- puts "day_matches? == #{day_matches?(date)}"
250
- puts "week_matches? == #{week_matches?(date)}"
251
- puts "week_from_start_matches? == #{week_from_start_matches?(date)}"
252
- puts "week_from_end_matches? == #{week_from_end_matches?(date)}"
253
- puts "days_left_in_month == #{days_left_in_month(date)}"
254
- puts "max_day_of_month == #{max_day_of_month(date)}"
255
- end
256
-
257
291
  private
258
292
  def day_matches?(date)
259
293
  @day_index == date.wday
@@ -275,7 +309,9 @@ end
275
309
  # DIWeek.new(Sunday)
276
310
  #
277
311
  # See also: Date, Runt
278
- class DIWeek < TExpr
312
+ class DIWeek
313
+
314
+ include TExpr
279
315
 
280
316
  VALID_RANGE = 0..6
281
317
 
@@ -298,20 +334,21 @@ end
298
334
  # If start and end day are equal, the entire week will match true.
299
335
  #
300
336
  # See also: Date
301
- class REWeek < TExpr
337
+ class REWeek
338
+
339
+ include TExpr
302
340
 
303
341
  VALID_RANGE = 0..6
304
342
 
305
- # Creates a REWeek using the supplied start
343
+ # Creates a REWeek using the supplied start
306
344
  # day(range = 0..6, where 0=>Sunday) and an optional end
307
345
  # day. If an end day is not supplied, the maximum value
308
346
  # (6 => Saturday) is assumed.
309
347
  #
310
348
  # If the start day is greater than the end day, an
311
- # ArgumentError will be raised
312
- def initialize(start_day,end_day=6)
313
- super()
314
- validate(start_day,end_day)
349
+ # ArgumentError will be raised
350
+ def initialize(start_day,end_day=6)
351
+ validate(start_day,end_day)
315
352
  @start_day = start_day
316
353
  @end_day = end_day
317
354
  end
@@ -325,7 +362,7 @@ class REWeek < TExpr
325
362
  "REWeek"
326
363
  end
327
364
 
328
- private
365
+ private
329
366
  def validate(start_day,end_day)
330
367
  unless start_day<=end_day
331
368
  raise ArgumentError, 'end day of week must be greater than start day'
@@ -336,10 +373,11 @@ class REWeek < TExpr
336
373
  end
337
374
  end
338
375
 
339
- class REYear < TExpr
376
+ class REYear
340
377
 
378
+ include TExpr
379
+
341
380
  def initialize(start_month, start_day=0, end_month=start_month, end_day=0)
342
- super()
343
381
  @start_month = start_month
344
382
  @start_day = start_day
345
383
  @end_month = end_month
@@ -356,14 +394,6 @@ class REYear < TExpr
356
394
  "REYear"
357
395
  end
358
396
 
359
- def print(date)
360
- puts "DIMonth: #{date}"
361
- puts "include? == #{include?(date)}"
362
- puts "months_include? == #{months_include?(date)}"
363
- puts "end_month_include? == #{end_month_include?(date)}"
364
- puts "start_month_include? == #{start_month_include?(date)}"
365
- end
366
-
367
397
  private
368
398
  def months_include?(date)
369
399
  (date.mon > @start_month) && (date.mon < @end_month)
@@ -385,7 +415,9 @@ end
385
415
  # is assumed to be on the following day.
386
416
  #
387
417
  # See also: Date
388
- class REDay < TExpr
418
+ class REDay
419
+
420
+ include TExpr
389
421
 
390
422
  CURRENT=28
391
423
  NEXT=29
@@ -406,8 +438,9 @@ class REDay < TExpr
406
438
  end
407
439
 
408
440
  def include?(date)
409
- raise TypeError, 'expected date' unless date.kind_of?(Date)
410
-
441
+ # If precision is day or greater, then the result is always true
442
+ return true if date.date_precision <= DPrecision::DAY
443
+
411
444
  if(@spans_midnight&&date.hour<12) then
412
445
  #Assume next day
413
446
  return @range.include?(get_next(date.hour,date.min))
@@ -421,17 +454,11 @@ class REDay < TExpr
421
454
  "REDay"
422
455
  end
423
456
 
424
- def print(date)
425
- puts "DIMonth: #{date}"
426
- puts "include? == #{include?(date)}"
427
- end
428
-
429
457
  private
430
458
  def spans_midnight?(start_hour, end_hour)
431
459
  return end_hour <= start_hour
432
460
  end
433
461
 
434
- private
435
462
  def get_current(hour,minute)
436
463
  PDate.min(ANY_DATE.year,ANY_DATE.month,CURRENT,hour,minute)
437
464
  end
@@ -447,7 +474,10 @@ end
447
474
  # WIMonth.new(1)
448
475
  #
449
476
  # See also: Date
450
- class WIMonth < TExpr
477
+ class WIMonth
478
+
479
+ include TExpr
480
+ include TExprUtils
451
481
 
452
482
  VALID_RANGE = -2..5
453
483
 
@@ -464,4 +494,31 @@ class WIMonth < TExpr
464
494
 
465
495
  end
466
496
 
497
+ # TExpr that matches a range of dates within a month. For example:
498
+ #
499
+ # REMonth.(12,28)
500
+ #
501
+ # matches from the 12th thru the 28th of any month. If end_day==0
502
+ # or is not given, start_day will define the range with that single day.
503
+ #
504
+ # See also: Date
505
+ class REMonth
506
+
507
+ include TExpr
508
+
509
+ def initialize(start_day, end_day=0)
510
+ end_day=start_day if end_day==0
511
+ @range = start_day..end_day
512
+ end
513
+
514
+ def include?(date)
515
+ @range.include? date.mday
516
+ end
517
+
518
+ def to_s
519
+ "REMonth"
520
+ end
521
+
522
+ end
523
+
467
524
  end
@@ -49,6 +49,7 @@
49
49
  ideas off-line.
50
50
  </li>
51
51
  <li><a href="http://www.bluerobot.com/web/layouts/">Blue Robot</a> for the CSS</li>
52
+ <li>Emmett Shear for contributed <a href="http://runt.rubyforge.org/doc/classes/Runt/TExpr.html">TExpr#dates</a> code and several thought-provoking feature requests.</li>
52
53
  </ul>
53
54
  </p>
54
55
  </div>
@@ -89,4 +90,4 @@
89
90
  <!-- BlueRobot was here. -->
90
91
 
91
92
  </body>
92
- </html>
93
+ </html>
@@ -1,7 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $:<<'../lib'
4
-
5
3
  # All Runt unit tests
6
4
  #
7
5
  # Author:: Matthew Lipper
@@ -1,7 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $:<<'../lib'
4
-
5
3
  require 'test/unit'
6
4
  require 'runt'
7
5
  require 'date'
@@ -57,6 +55,13 @@ class DateRangeTest < Test::Unit::TestCase
57
55
  assert(o_range.overlap?(range))
58
56
  assert(o_range.overlap?(DateRange.new(r_start,o_end)))
59
57
  assert(o_range.overlap?(DateRange.new(o_start,r_end)))
58
+
59
+ # September 18th - 19th, 2005, 8am - 10am
60
+ expr1=DateRange.new(PDate.day(2005,9,18),PDate.day(2005,9,19))
61
+ # September 19th - 20th, 2005, 9am - 11am
62
+ expr2=DateRange.new(PDate.day(2005,9,19),PDate.day(2005,9,20))
63
+
64
+ assert(expr1.overlap?(expr2))
60
65
  end
61
66
 
62
67
  def test_empty
@@ -1,7 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $:<<'../lib'
4
-
5
3
  require 'test/unit'
6
4
  require 'runt'
7
5
  require 'date'
@@ -9,6 +7,7 @@ require 'date'
9
7
  # Unit tests for DPrecision class
10
8
  #
11
9
  # Author:: Matthew Lipper
10
+
12
11
  class DPrecisionTest < Test::Unit::TestCase
13
12
 
14
13
  include Runt
@@ -23,13 +22,13 @@ class DPrecisionTest < Test::Unit::TestCase
23
22
  end
24
23
 
25
24
  def test_pseudo_singleton_instance
26
- assert(DPrecision::YEAR.id==DPrecision::YEAR.id, "Object Id's not equal.")
27
- assert(DPrecision::MONTH.id==DPrecision::MONTH.id, "Object Id's not equal.")
28
- assert(DPrecision::DAY.id==DPrecision::DAY.id, "Object Id's not equal.")
29
- assert(DPrecision::HOUR.id==DPrecision::HOUR.id, "Object Id's not equal.")
30
- assert(DPrecision::MIN.id==DPrecision::MIN.id, "Object Id's not equal.")
31
- assert(DPrecision::SEC.id==DPrecision::SEC.id, "Object Id's not equal.")
32
- assert(DPrecision::MILLI.id==DPrecision::MILLI.id, "Object Id's not equal.")
25
+ assert(DPrecision::YEAR.object_id==DPrecision::YEAR.object_id, "Object Id's not equal.")
26
+ assert(DPrecision::MONTH.object_id==DPrecision::MONTH.object_id, "Object Id's not equal.")
27
+ assert(DPrecision::DAY.object_id==DPrecision::DAY.object_id, "Object Id's not equal.")
28
+ assert(DPrecision::HOUR.object_id==DPrecision::HOUR.object_id, "Object Id's not equal.")
29
+ assert(DPrecision::MIN.object_id==DPrecision::MIN.object_id, "Object Id's not equal.")
30
+ assert(DPrecision::SEC.object_id==DPrecision::SEC.object_id, "Object Id's not equal.")
31
+ assert(DPrecision::MILLI.object_id==DPrecision::MILLI.object_id, "Object Id's not equal.")
33
32
  end
34
33
 
35
34
  def test_to_precision
@@ -1,6 +1,4 @@
1
- #!/usr/bin/env ruby
2
-
3
- $:<<'../lib'
1
+ #!/usr/bin/env ruby
4
2
 
5
3
  require 'test/unit'
6
4
  require 'date'
@@ -1,7 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $:<<'../lib'
4
-
5
3
  require 'test/unit'
6
4
  require 'runt'
7
5
  require 'date'
@@ -52,5 +50,39 @@ class ScheduleTest < Test::Unit::TestCase
52
50
  assert_equal(expected,dates)
53
51
  end
54
52
 
53
+ def test_using_a_schedule
54
+
55
+ # September 18th - 19th, 2005, 8am - 10am
56
+ expr1=RSpec.new(DateRange.new(PDate.day(2005,9,18),PDate.day(2005,9,19))) & REDay.new(8,0,10,0)
57
+ assert(expr1.include?(PDate.min(2005,9,18,8,15)))
58
+ # September 19th - 20th, 2005, 9am - 11am
59
+ expr2=RSpec.new(DateRange.new(PDate.day(2005,9,19),PDate.day(2005,9,20))) & REDay.new(9,0,11,0)
60
+ # Quick sanuty check
61
+ assert(expr1.overlap?(expr2))
62
+ # Setup a schedule w/first expression
63
+ sched = Schedule.new
64
+ sched.add(Event.new("Snafubar Opening"),expr1)
65
+ resource = Resource.new(sched)
66
+ # Add a another overlapping event
67
+ resource.add_event(Event.new("Yodeling Lesson"),expr2)
68
+ # Create a new resource using the same schedule
69
+ resource2 = Resource.new(sched)
70
+ # Add a another overlapping event and pass a block which should complain
71
+ #resource.add_event(Event.new("Yodeling Lesson"),expr2) \
72
+ #{|e,s| raise "Resource not available at requested time(s)." \
73
+ # if (@schedule.overlap?(s))}
74
+ end
55
75
  end
56
76
 
77
+ class Resource
78
+ def initialize(schedule)
79
+ @schedule=schedule
80
+ end
81
+ def add_event(event,expr)
82
+ if(block_given?)
83
+ yield(event,expr)
84
+ else
85
+ @schedule.add(event,expr)
86
+ end
87
+ end
88
+ end
@@ -1,7 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $:<<'../lib'
4
-
5
3
  require 'test/unit'
6
4
  require 'runt'
7
5
  require 'date'
@@ -10,11 +8,13 @@ $DEBUG=false
10
8
 
11
9
  # Unit tests for TExpr classes
12
10
  # Author:: Matthew Lipper
11
+
13
12
  class TExprTest < Test::Unit::TestCase
14
13
 
15
14
  include Runt
16
15
  include DPrecision
17
16
 
17
+
18
18
  def test_collection_te
19
19
  #base class that should always return false
20
20
  expr = Collection.new
@@ -166,19 +166,28 @@ class TExprTest < Test::Unit::TestCase
166
166
  #12:01 am (January 28th, 2004 - ignored)
167
167
  assert(!expr2.include?(PDate.min(2004,1,28,0,01)))
168
168
  end
169
- def test_range_each_week_te
170
169
 
171
- assert_raises(ArgumentError){ expr = REWeek.new(10,4) }
170
+ def test_range_each_day_te_again
171
+ dr = DateRange.new(PDate.day(2005,9,19),PDate.day(2005,9,20))
172
+ red = REDay.new(8,0,10,0)
173
+ result = false
174
+ dr.each do |interval|
175
+ result = red.include?(interval)
176
+ break if result
177
+ end
178
+ assert(result)
179
+ end
172
180
 
181
+ def test_range_each_week_te
182
+ assert_raises(ArgumentError){ expr = REWeek.new(10,4) }
173
183
  expr1 = REWeek.new(Mon,Fri) & REDay.new(8,00,8,30)
174
184
  assert(!expr1.include?(PDate.new(2004,5,1,8,06)))
175
-
176
-
177
185
  #Sunday through Thursday
178
186
  expr2 = REWeek.new(0,4)
179
187
  assert(expr2.include?(PDate.min(2004,2,19,23,59,59)))
180
188
  assert(!expr2.include?(PDate.min(2004,2,20,0,0,0)))
181
189
  end
190
+
182
191
  def test_combined_te
183
192
  #This is a hack.....
184
193
  #In the U.S., Memorial Day begins the last Monday of May
@@ -279,4 +288,115 @@ class TExprTest < Test::Unit::TestCase
279
288
  assert(!ticket.include?(DateTime.new(2004,3,11,1,15)))
280
289
  end
281
290
 
291
+ def test_re_month_te
292
+ # October 22nd, 2005
293
+ dt1 = Date.civil(2005,10,22)
294
+ # The 20th through the 29th of any month
295
+ expr1 = REMonth.new(20,29)
296
+ assert(expr1.include?(dt1))
297
+ assert(!expr1.include?(PDate.new(2010,12,12)))
298
+ # August 17th, 1975
299
+ dt2 = Date.civil(1975,8,17)
300
+ # The 17th of any month
301
+ expr2 = REMonth.new(17)
302
+ assert(expr2.include?(dt2))
303
+ assert(!expr2.include?(dt1))
304
+ end
305
+
306
+ ###
307
+ # Dates functionality & tests contributed by Emmett Shear
308
+ ###
309
+ def test_day_in_month_dates
310
+ date_range = Date.civil(2005, 1, 1)..Date.civil(2005, 12, 31)
311
+ month_days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
312
+ expr = DIMonth.new(First, Tuesday)
313
+ dates = expr.dates(date_range)
314
+ assert dates.size == 12
315
+ dates.each do |d|
316
+ assert d.wday == 2 # tuesday
317
+ assert d.day < 8 # in the first week
318
+ end
319
+ expr2 = DIMonth.new(Last, Friday)
320
+ dates2 = expr2.dates(date_range)
321
+ assert dates2.size == 12
322
+ dates2.each do |d|
323
+ assert d.wday == 5 # friday
324
+ assert d.day > month_days[d.month-1] - 8 # last week
325
+ end
326
+ end
327
+
328
+ def test_day_in_week_dates
329
+ date_range = Date.civil(2005, 1, 1)..Date.civil(2005, 1, 31)
330
+ expr = DIWeek.new(Sunday)
331
+ dates = expr.dates(date_range)
332
+ assert( dates.size == 5 )
333
+ assert( dates.include?( Date.civil(2005, 1, 16) ) )
334
+ assert( dates.include?( Date.civil(2005, 1, 30) ) )
335
+ end
336
+
337
+ def test_union_dates
338
+ date_range = Date.civil(2005, 1, 1)..Date.civil(2005, 12, 31)
339
+ month_days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
340
+ expr = DIMonth.new(Last, Friday) | DIMonth.new(1, Tuesday)
341
+ dates = expr.dates(date_range)
342
+ assert dates.size == 24
343
+ dates.each do |d|
344
+ unless (d.wday == 2 and d.day < 8) or \
345
+ (d.wday == 5 and d.day > month_days[d.month-1] - 8)
346
+ assert false, d.to_s
347
+ end
348
+ end
349
+ end
350
+
351
+ def test_intersection_dates
352
+ date_range = Date.civil(2005, 1, 1)..Date.civil(2005, 12, 31)
353
+ expr = DIWeek.new(Sunday) & DIMonth.new(Second, Sunday)
354
+ dates = expr.dates(date_range)
355
+ assert( dates.size == 12 )
356
+ other_dates = DIMonth.new(Second, Sunday).dates(date_range)
357
+ dates.each { |d| assert( other_dates.include?(d) ) }
358
+ end
359
+
360
+ def test_range_each_week_dates
361
+ date_range = Date.civil(2005, 1, 1)..Date.civil(2005, 1, 31)
362
+ expr = REWeek.new(3, 5)
363
+ dates = expr.dates(date_range)
364
+ assert dates.size == 12
365
+ end
366
+
367
+ def test_range_each_year_dates
368
+ date_range = Date.civil(2004, 5, 1)..Date.civil(2006, 5, 4)
369
+ expr = REYear.new(4, 28, 5, 6)
370
+ dates = expr.dates(date_range)
371
+ assert dates.size == 22, dates.size
372
+ end
373
+
374
+ def test_week_in_month_dates
375
+ date_range = Date.civil(2005, 1, 1)..Date.civil(2005, 2, 28)
376
+ expr = WIMonth.new(2)
377
+ dates = expr.dates(date_range)
378
+ assert dates.size == 14, dates.size
379
+ assert dates.first.mday == 8
380
+ assert dates.last.mday == 14
381
+ expr_2 = WIMonth.new(Last)
382
+ dates_2 = expr_2.dates(date_range)
383
+ assert dates_2.size == 14, dates_2.size
384
+ assert dates_2.first.mday == 25
385
+ assert dates_2.last.mday == 28
386
+ end
387
+
388
+ def test_range_each_month_dates
389
+ date_range = Date.civil(2005, 1, 7)..Date.civil(2005, 1, 15)
390
+ expr = REMonth.new(5, 9)
391
+ dates = expr.dates(date_range)
392
+ assert dates.size == 3, dates.size
393
+ assert false if dates.include? Date.civil(2005, 1, 6)
394
+ end
395
+
396
+ def test_diff_dates
397
+ date_range = Date.civil(2005, 1, 1)..Date.civil(2005, 1, 31)
398
+ expr = REYear.new(1, 1, 1, 31) - REMonth.new(7, 15)
399
+ dates = expr.dates(date_range)
400
+ assert dates.size == 22, dates.size
401
+ end
282
402
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.8.1
2
+ rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: runt
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.2.0
7
- date: 2004-11-29
6
+ version: 0.3.0
7
+ date: 2005-10-22 00:00:00 -04:00
8
8
  summary: Ruby Temporal Expressions.
9
9
  require_paths:
10
10
  - lib
11
- author: Matthew Lipper
12
11
  email: matt@digitalclash.com
13
12
  homepage: http://runt.rubyforge.org
14
13
  rubyforge_project: runt
@@ -25,6 +24,10 @@ required_ruby_version: !ruby/object:Gem::Version::Requirement
25
24
  version: 0.0.0
26
25
  version:
27
26
  platform: ruby
27
+ signing_key:
28
+ cert_chain:
29
+ authors:
30
+ - Matthew Lipper
28
31
  files:
29
32
  - setup.rb
30
33
  - CHANGES
@@ -52,7 +55,12 @@ files:
52
55
  - site/logohover.png
53
56
  - site/runt-logo.gif
54
57
  - site/runt-logo.psd
55
- test_files: []
58
+ test_files:
59
+ - test/daterangetest.rb
60
+ - test/dprecisiontest.rb
61
+ - test/pdatetest.rb
62
+ - test/scheduletest.rb
63
+ - test/temporalexpressiontest.rb
56
64
  rdoc_options: []
57
65
  extra_rdoc_files: []
58
66
  executables: []