runt19 0.7.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/.gitignore +17 -0
  2. data/Gemfile +4 -0
  3. data/History.txt +153 -0
  4. data/LICENSE +22 -0
  5. data/LICENSE.txt +44 -0
  6. data/Manifest.txt +112 -0
  7. data/README.md +29 -0
  8. data/README.txt +106 -0
  9. data/Rakefile +2 -0
  10. data/TODO +13 -0
  11. data/examples/payment_report.rb +59 -0
  12. data/examples/payment_reporttest.rb +49 -0
  13. data/examples/reminder.rb +63 -0
  14. data/examples/schedule_tutorial.rb +59 -0
  15. data/examples/schedule_tutorialtest.rb +52 -0
  16. data/lib/runt.rb +249 -0
  17. data/lib/runt/daterange.rb +74 -0
  18. data/lib/runt/dprecision.rb +150 -0
  19. data/lib/runt/expressionbuilder.rb +65 -0
  20. data/lib/runt/pdate.rb +165 -0
  21. data/lib/runt/schedule.rb +88 -0
  22. data/lib/runt/sugar.rb +171 -0
  23. data/lib/runt/temporalexpression.rb +795 -0
  24. data/lib/runt/version.rb +3 -0
  25. data/lib/runt19.rb +1 -0
  26. data/runt19.gemspec +17 -0
  27. data/setup.rb +1331 -0
  28. data/site/blue-robot3.css +132 -0
  29. data/site/dcl-small.gif +0 -0
  30. data/site/index.html +72 -0
  31. data/site/logohover.png +0 -0
  32. data/site/runt-logo.gif +0 -0
  33. data/site/runt-logo.psd +0 -0
  34. data/test/aftertetest.rb +31 -0
  35. data/test/baseexpressiontest.rb +110 -0
  36. data/test/beforetetest.rb +31 -0
  37. data/test/collectiontest.rb +63 -0
  38. data/test/combinedexpressionstest.rb +158 -0
  39. data/test/daterangetest.rb +89 -0
  40. data/test/dayintervaltetest.rb +37 -0
  41. data/test/difftest.rb +37 -0
  42. data/test/dimonthtest.rb +59 -0
  43. data/test/diweektest.rb +32 -0
  44. data/test/dprecisiontest.rb +58 -0
  45. data/test/everytetest.rb +36 -0
  46. data/test/expressionbuildertest.rb +64 -0
  47. data/test/icalendartest.rb +1104 -0
  48. data/test/intersecttest.rb +34 -0
  49. data/test/pdatetest.rb +147 -0
  50. data/test/redaytest.rb +40 -0
  51. data/test/remonthtest.rb +37 -0
  52. data/test/reweektest.rb +51 -0
  53. data/test/reyeartest.rb +99 -0
  54. data/test/rspectest.rb +25 -0
  55. data/test/runttest.rb +98 -0
  56. data/test/scheduletest.rb +148 -0
  57. data/test/spectest.rb +36 -0
  58. data/test/sugartest.rb +104 -0
  59. data/test/temporalexpressiontest.rb +76 -0
  60. data/test/uniontest.rb +36 -0
  61. data/test/wimonthtest.rb +54 -0
  62. data/test/yeartetest.rb +22 -0
  63. metadata +137 -0
@@ -0,0 +1,148 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require 'runt'
5
+ require 'date'
6
+
7
+ # Unit tests for Schedule classes
8
+ # Author:: Matthew Lipper
9
+ class ScheduleTest < Test::Unit::TestCase
10
+
11
+ include Runt
12
+
13
+ def setup
14
+ # Jane is very busy these days.
15
+ @sched=Schedule.new
16
+ # Elmo's World is on TV: Mon-Fri 8am-8:30am
17
+ @elmo=Event.new("Elmo's World")
18
+ @elmo_broadcast=(REWeek.new(Mon,Fri) & REDay.new(8,00,8,30))
19
+ @sched.add(@elmo,@elmo_broadcast)
20
+ #Oobi's on TV: Thu-Sat 8:30am-9am
21
+ @oobi=Event.new("Oobi")
22
+ @oobi_broadcast=(REWeek.new(Thu,Sat) & REDay.new(8,30,9,00))
23
+ @sched.add(@oobi,@oobi_broadcast)
24
+ @during_elmo=PDate.new(2004,5,4,8,06)
25
+ @not_during_elmo=PDate.new(2004,5,1,8,06)
26
+ @during_oobi=PDate.new(2004,4,30,8,56)
27
+ @not_during_oobi=PDate.new(2004,5,1,8,12)
28
+ end
29
+
30
+ def test_include
31
+ # Check Elmo
32
+ assert(@sched.include?(@elmo, @during_elmo))
33
+ assert(!@sched.include?(@elmo,@not_during_elmo))
34
+ assert(!@sched.include?(@elmo,@during_oobi))
35
+ # Check Oobi
36
+ assert(@sched.include?(@oobi, @during_oobi))
37
+ assert(!@sched.include?(@oobi,@not_during_oobi))
38
+ assert(!@sched.include?(@oobi,@not_during_elmo))
39
+ end
40
+
41
+ def test_select_all
42
+ # select all
43
+ all=@sched.select {|ev,xpr| true; }
44
+ assert all.size==2
45
+ assert all.include?(@elmo)
46
+ assert all.include?(@oobi)
47
+ end
48
+
49
+ def test_select_none
50
+ # select none
51
+ assert((@sched.select {|ev,xpr| false; }).size==0)
52
+ end
53
+
54
+ def test_select_some
55
+ # select oobi only
56
+ some=@sched.select {|ev,xpr| @oobi.eql?(ev); }
57
+ assert some.size==1
58
+ assert !some.include?(@elmo)
59
+ assert some.include?(@oobi)
60
+ some.clear
61
+ # select elmo only
62
+ some=@sched.select {|ev,xpr| @elmo.eql?(ev); }
63
+ assert some.size==1
64
+ assert some.include?(@elmo)
65
+ assert !some.include?(@oobi)
66
+ end
67
+
68
+ def test_events
69
+ events=@sched.events(PDate.new(2006,12,4,11,15))
70
+ assert_equal 0,events.size
71
+ # The Barney power hour which overlaps with Elmo
72
+ barney=Event.new("Barney")
73
+ @sched.add(barney,REDay.new(7,30,8,30))
74
+ events=@sched.events(PDate.new(2006,12,4,8,15))
75
+ assert_equal 2,events.size
76
+ assert events.include?(barney)
77
+ assert events.include?(@elmo)
78
+ end
79
+
80
+ def test_update
81
+ @sched.update(Event.new("aaa")){|ev|assert_nil(ev)}
82
+ @sched.update(@elmo){|ev|assert_equal(@elmo_broadcast,ev)}
83
+ @sched.update(@oobi){|ev|assert_equal(@oobi_broadcast,ev)}
84
+ end
85
+
86
+ def test_select_old
87
+ @sched=Schedule.new
88
+ e1=Event.new("e1")
89
+ assert(!@sched.include?(e1,nil))
90
+ range=RSpec.new(DateRange.new(PDate.new(2006,12,3),PDate.new(2007,1,24)))
91
+ in_range=PDate.new(2007,1,4)
92
+ assert(range.include?(in_range))
93
+ out_of_range=PDate.new(2006,1,4)
94
+ assert(!range.include?(out_of_range))
95
+ @sched.add(e1,range)
96
+ assert(@sched.include?(e1,in_range))
97
+ assert(!@sched.include?(e1,out_of_range))
98
+ end
99
+
100
+ def test_dates
101
+ # range: May 1st, 2004 to May 31st, 2004
102
+ d_range = DateRange.new(PDate.day(2004,5,1), PDate.day(2004,5,31))
103
+ @sched = Schedule.new
104
+ event = Event.new("Visit Ernie")
105
+ # First and last Friday of the month
106
+ expr1 = DIMonth.new(1,Fri) | DIMonth.new(-1,Fri)
107
+ @sched.add(event,expr1)
108
+ dates = @sched.dates(event,d_range)
109
+ expected = [PDate.day(2004,5,7), PDate.day(2004,5,28)]
110
+ assert_equal(expected,dates)
111
+ end
112
+
113
+ def test_using_a_schedule
114
+
115
+ # September 18th - 19th, 2005, 8am - 10am
116
+ expr1=RSpec.new(DateRange.new(PDate.day(2005,9,18),PDate.day(2005,9,19))) & REDay.new(8,0,10,0)
117
+ assert(expr1.include?(PDate.min(2005,9,18,8,15)))
118
+ # September 19th - 20th, 2005, 9am - 11am
119
+ expr2=RSpec.new(DateRange.new(PDate.day(2005,9,19),PDate.day(2005,9,20))) & REDay.new(9,0,11,0)
120
+ # Quick sanuty check
121
+ assert(expr1.overlap?(expr2))
122
+ # Setup a @schedule w/first expression
123
+ @sched = Schedule.new
124
+ @sched.add(Event.new("Snafubar Opening"),expr1)
125
+ resource = Resource.new(@sched)
126
+ # Add a another overlapping event
127
+ resource.add_event(Event.new("Yodeling Lesson"),expr2)
128
+ # Create a new resource using the same schedule
129
+ resource2 = Resource.new(@sched)
130
+ # Add a another overlapping event and pass a block which should complain
131
+ #resource.add_event(Event.new("Yodeling Lesson"),expr2) \
132
+ #{|e,s| raise "Resource not available at requested time(s)." \
133
+ # if (@schedule.overlap?(s))}
134
+ end
135
+ end
136
+
137
+ class Resource
138
+ def initialize(schedule)
139
+ @schedule=schedule
140
+ end
141
+ def add_event(event,expr)
142
+ if(block_given?)
143
+ yield(event,expr)
144
+ else
145
+ @schedule.add(event,expr)
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,36 @@
1
+
2
+ #!/usr/bin/env ruby
3
+
4
+ require 'baseexpressiontest'
5
+
6
+ # Unit tests for Spec class
7
+ # Author:: Matthew Lipper
8
+
9
+ class SpecTest < BaseExpressionTest
10
+
11
+ def setup
12
+ super
13
+ @spec = Spec.new(@stub1)
14
+ end
15
+
16
+ def test_initialize
17
+ assert_same @stub1, @spec.date_expr, "Expected #{@stub1}, instead got #{@spec.date_expr}"
18
+ end
19
+
20
+ def test_include_arg_has_include_method
21
+ assert !@spec.include?(@stub2), "Expression should not include configured stub"
22
+ @stub2.match = true
23
+ assert @spec.include?(@stub2), "Expression should include configured stub"
24
+ end
25
+
26
+ def test_include_arg_without_include_method
27
+ @spec = Spec.new(4)
28
+ assert !@spec.include?(3), "Expression #{@spec.to_s} should not include 3"
29
+ assert @spec.include?(4), "Expression #{@spec.to_s} should include 4"
30
+ end
31
+
32
+ def test_to_s
33
+ assert_equal @stub1.to_s, @spec.to_s
34
+ end
35
+
36
+ end
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require 'runt'
5
+ require 'runt/sugar'
6
+
7
+ class SugarTest < Test::Unit::TestCase
8
+ include Runt
9
+
10
+ def test_build__should_return_nil_when_an_unknown_name_is_given
11
+ assert self.build('duh').nil?
12
+ end
13
+
14
+ def test_method_missing_should_be_called_for_invalid_name
15
+ begin
16
+ self.some_tuesday
17
+ rescue NoMethodError
18
+ # YAY!
19
+ end
20
+ end
21
+
22
+ def test_const_should_return_runt_constant
23
+ assert_equal Runt::Monday, Runt.const('monday'), \
24
+ "Expected #{Runt::Monday} but was #{Runt.const('monday')}"
25
+ end
26
+
27
+ def test_method_missing_should_define_dimonth
28
+ make_ordinals.each do |ordinal|
29
+ make_days.each do |day|
30
+ name = ordinal + '_' + day
31
+ result = self.send(name)
32
+ expected = DIMonth.new(Runt.const(ordinal), Runt.const(day))
33
+ assert_expression expected, result
34
+ end
35
+ end
36
+ end
37
+
38
+ def test_method_missing_should_define_diweek
39
+ assert_expression(DIWeek.new(Monday), self.monday)
40
+ assert_expression(DIWeek.new(Tuesday), self.tuesday)
41
+ assert_expression(DIWeek.new(Wednesday), self.wednesday)
42
+ assert_expression(DIWeek.new(Thursday), self.thursday)
43
+ assert_expression(DIWeek.new(Friday), self.friday)
44
+ assert_expression(DIWeek.new(Saturday), self.saturday)
45
+ assert_expression(DIWeek.new(Sunday), self.sunday)
46
+ end
47
+
48
+ def test_parse_time
49
+ assert_equal [13,2], parse_time('1','02','pm')
50
+ assert_equal [1,2], parse_time('1','02','am')
51
+ end
52
+
53
+ def test_method_missing_should_define_re_day
54
+ assert_expression(REDay.new(8,45,14,00), daily_8_45am_to_2_00pm)
55
+ end
56
+
57
+ def test_method_missing_should_define_re_week
58
+ make_days.each do |st_day|
59
+ make_days.each do |end_day|
60
+ if Runt.const(st_day) <= Runt.const(end_day) then
61
+ assert_expression REWeek.new(Runt.const(st_day), \
62
+ Runt.const(end_day)), self.send('weekly_' + st_day + '_to_' + end_day)
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ def test_method_missing_should_define_re_month
69
+ assert_expression(REMonth.new(3,14), monthly_3rd_to_14th)
70
+ end
71
+ def test_method_missing_should_define_re_year
72
+ # Imperfect but "good enough" for now
73
+ make_months.each do |st_month|
74
+ make_months.each do |end_month|
75
+ st_mon_number = Runt.const(st_month)
76
+ end_mon_number = Runt.const(end_month)
77
+ next if st_mon_number > end_mon_number
78
+ st_day = rand(27) + 1
79
+ end_day = rand(27) + 1
80
+ if st_mon_number == end_mon_number && st_day > end_day then
81
+ st_day, end_day = end_day, st_day
82
+ end
83
+ #puts "Checking #{st_month} #{st_day} - #{end_month} #{end_day}"
84
+ assert_expression REYear.new(st_mon_number, st_day, end_mon_number, end_day), \
85
+ self.send('yearly_' + st_month + '_' + st_day.to_s + '_to_' + end_month + '_' + end_day.to_s)
86
+ end
87
+ end
88
+ end
89
+
90
+ private
91
+ def assert_expression(expected, actual)
92
+ assert_equal expected.to_s, actual.to_s, \
93
+ "Expected #{expected.to_s} but was #{actual.to_s}"
94
+ end
95
+ def make_ordinals
96
+ Runt::WEEK_OF_MONTH_ORDINALS.delete('()').split('|')
97
+ end
98
+ def make_days
99
+ Runt::DAYS.delete('()').split('|')
100
+ end
101
+ def make_months
102
+ Runt::MONTHS.delete('()').split('|')
103
+ end
104
+ end
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'baseexpressiontest'
4
+
5
+ # Unit tests for TExpr classes
6
+ # Author:: Matthew Lipper
7
+
8
+ class TExprTest < BaseExpressionTest
9
+
10
+ include TExpr
11
+
12
+ def test_include
13
+ assert !self.include?(true), "Default include? method should always return false"
14
+ end
15
+
16
+ def test_to_s
17
+ assert_equal self.to_s, 'TExpr', "Default to_s method should always return 'TExpr'"
18
+ end
19
+
20
+ def test_or_from_union
21
+ union = Union.new
22
+ same_union = union.or(@stub1)
23
+ assert_same union, same_union, "Expected same Union instance that received the or method"
24
+ assert_same @stub1, union.expressions.first, "Union instance should have added the stub expression"
25
+ end
26
+
27
+ def test_or_from_nonunion
28
+ result = @stub1.or(@stub2) {|e| e}
29
+ assert_equal Runt::Union, result.class, "Expected an Union instance. Instead got #{result.class}"
30
+ assert_same @stub1, result.expressions.first, "Result should be new Union instance containing both stub expressions"
31
+ assert_same @stub2, result.expressions.last, "Result should be new Union instance containing both stub expressions"
32
+ end
33
+
34
+ def test_and_from_intersect
35
+ intersect = Intersect.new
36
+ result = intersect.and(@stub1)
37
+ assert_same intersect, result, "Expected same Intersect instance that received the and method"
38
+ assert_same @stub1, intersect.expressions.first, "Intersect instance should have added the stub expression"
39
+ end
40
+
41
+ def test_or_from_nonintersect
42
+ result = @stub1.and(@stub2) {|e| e}
43
+ assert_equal Runt::Intersect, result.class, "Expected an Intersect instance. Instead got #{result.class}"
44
+ assert_same @stub1, result.expressions.first, "Result should be new Intersect instance containing both stub expressions"
45
+ assert_same @stub2, result.expressions.last, "Result should be new Intersect instance containing both stub expressions"
46
+ end
47
+
48
+ def test_minus
49
+ result = @stub1.minus(@stub2) {|e| e}
50
+ assert_equal Runt::Diff, result.class, "Expected an Diff instance. Instead got #{result.class}"
51
+ assert_same @stub1, result.expr1, "Expected first stub instance used to create Diff expression"
52
+ assert_same @stub2, result.expr2, "Expected second stub instance used to create Diff expression"
53
+ end
54
+
55
+ def test_dates_no_limit
56
+ # Normally, your range is made up of Date-like Objects
57
+ range = 1..3
58
+ assert @stub1.dates(range).empty?, "Expected empty Array of Objects returned from stub expression"
59
+ @stub1.match = true
60
+ result = @stub1.dates(range)
61
+ assert_equal 1, result[0], "Expected Array of Objects given by range to be returned from stub expression"
62
+ assert_equal 2, result[1], "Expected Array of Objects given by range to be returned from stub expression"
63
+ assert_equal 3, result[2], "Expected Array of Objects given by range to be returned from stub expression"
64
+ end
65
+
66
+ def test_dates_with_limit
67
+ range = 1..3
68
+ assert @stub1.dates(range).empty?, "Expected empty Array of Objects returned from stub expression"
69
+ @stub1.match = true
70
+ result = @stub1.dates(range,2)
71
+ assert_equal 2, result.size, "Expected Array of only 2 Objects. Got #{result.size}"
72
+ assert_equal 1, result[0], "Expected Array of Objects given by range to be returned from stub expression"
73
+ assert_equal 2, result[1], "Expected Array of Objects given by range to be returned from stub expression"
74
+ end
75
+
76
+ end
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'baseexpressiontest'
4
+
5
+ # Unit tests for Union class
6
+ # Author:: Matthew Lipper
7
+
8
+ class UnionTest < BaseExpressionTest
9
+
10
+ def setup
11
+ super
12
+ @union = Union.new
13
+ @date = @pdate_20071028
14
+ end
15
+
16
+ def test_include
17
+ assert !@union.include?(@date), "Empty Union instance should not include any dates"
18
+ @union.add(@stub1).add(@stub2) # both expressions will return false
19
+ assert !@union.include?(@date), "Union instance should not include any dates"
20
+ @stub2.match = true
21
+ assert @union.include?(@date), "Union instance should include any dates"
22
+ @stub2.match = false
23
+ @stub1.match = true
24
+ assert @union.include?(@date), "Union instance should include any dates"
25
+
26
+ end
27
+
28
+ def test_to_s
29
+ assert_equal 'empty', @union.to_s
30
+ @union.add(@stub1)
31
+ assert_equal 'every ' + @stub1.to_s, @union.to_s
32
+ @union.add(@stub2)
33
+ assert_equal 'every ' + @stub1.to_s + ' or ' + @stub2.to_s, @union.to_s
34
+ end
35
+
36
+ end
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'baseexpressiontest'
4
+
5
+ # Unit tests for WIMonth class
6
+ # Author:: Matthew Lipper
7
+
8
+ class WIMonthTest < BaseExpressionTest
9
+
10
+ def setup
11
+ super
12
+ @date_range = @date_20050101..@date_20050228
13
+ end
14
+
15
+
16
+ def test_second_week_in_month
17
+ expr = WIMonth.new(Second)
18
+ assert expr.include?(@pdate_20071008), "#{expr.to_s} should include #{@pdate_20071008.to_s}"
19
+ assert !expr.include?(@pdate_20071030), "#{expr.to_s} should not include #{@pdate_20071030.to_s}"
20
+ end
21
+
22
+ def test_last_week_in_month
23
+ expr = WIMonth.new(Last_of)
24
+ # Make sure of day precision or things will be unusably slow!
25
+ assert expr.include?(@pdate_20071030), "#{expr.to_s} should include #{@pdate_20071030.to_s}"
26
+ assert !expr.include?(@pdate_20071008), "#{expr.to_s} should not include #{@pdate_20071008.to_s}"
27
+ end
28
+
29
+ def test_second_to_last_week_in_month
30
+ expr = WIMonth.new(Second_to_last)
31
+ # Make sure of day precision or things will be unusably slow!
32
+ assert expr.include?(@pdate_20071024), "#{expr.to_s} should include #{@pdate_20071024}"
33
+ assert !expr.include?(@pdate_20071008), "#{expr.to_s} should not include #{@pdate_20071008}"
34
+ end
35
+
36
+ def test_dates_mixin_second_week_in_month
37
+ dates = WIMonth.new(Second).dates(@date_range)
38
+ assert dates.size == 14, "Expected 14 dates, was #{dates.size}"
39
+ assert dates.first.mday == 8, "Expected first date.mday to be 8, was #{dates.first.mday}"
40
+ assert dates.last.mday == 14, "Expected last date.mday to be 14, was #{dates.last.mday}"
41
+ end
42
+
43
+ def test_dates_mixin_last_week_in_month
44
+ dates = WIMonth.new(Last).dates(@date_range)
45
+ assert dates.size == 14, "Expected 14 dates, was #{dates.size}"
46
+ assert dates.first.mday == 25, "Expected first date.mday to be 25, was #{dates.first.mday}"
47
+ assert dates.last.mday == 28, "Expected last date.mday to be 28, was #{dates.last.mday}"
48
+ end
49
+
50
+ def test_week_in_month_to_s
51
+ assert_equal 'last week of any month', WIMonth.new(Last).to_s
52
+ end
53
+
54
+ end