runt 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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: []