demingfactor-ri_cal 0.9.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.
Files changed (167) hide show
  1. checksums.yaml +7 -0
  2. data/History.txt +402 -0
  3. data/Manifest.txt +161 -0
  4. data/README.txt +410 -0
  5. data/Rakefile +69 -0
  6. data/VERSION +1 -0
  7. data/bin/ri_cal +8 -0
  8. data/component_attributes/alarm.yml +10 -0
  9. data/component_attributes/calendar.yml +4 -0
  10. data/component_attributes/component_property_defs.yml +180 -0
  11. data/component_attributes/event.yml +45 -0
  12. data/component_attributes/freebusy.yml +16 -0
  13. data/component_attributes/journal.yml +35 -0
  14. data/component_attributes/timezone.yml +3 -0
  15. data/component_attributes/timezone_period.yml +11 -0
  16. data/component_attributes/todo.yml +46 -0
  17. data/copyrights.txt +1 -0
  18. data/docs/draft-ietf-calsify-2446bis-08.txt +7280 -0
  19. data/docs/draft-ietf-calsify-rfc2445bis-09.txt +10416 -0
  20. data/docs/incrementers.txt +7 -0
  21. data/docs/rfc2445.pdf +0 -0
  22. data/lib/ri_cal/component/alarm.rb +19 -0
  23. data/lib/ri_cal/component/calendar.rb +257 -0
  24. data/lib/ri_cal/component/event.rb +58 -0
  25. data/lib/ri_cal/component/freebusy.rb +16 -0
  26. data/lib/ri_cal/component/journal.rb +27 -0
  27. data/lib/ri_cal/component/non_standard.rb +33 -0
  28. data/lib/ri_cal/component/t_z_info_timezone.rb +153 -0
  29. data/lib/ri_cal/component/timezone/daylight_period.rb +25 -0
  30. data/lib/ri_cal/component/timezone/standard_period.rb +23 -0
  31. data/lib/ri_cal/component/timezone/timezone_period.rb +76 -0
  32. data/lib/ri_cal/component/timezone.rb +197 -0
  33. data/lib/ri_cal/component/todo.rb +42 -0
  34. data/lib/ri_cal/component.rb +256 -0
  35. data/lib/ri_cal/core_extensions/array/conversions.rb +15 -0
  36. data/lib/ri_cal/core_extensions/array.rb +7 -0
  37. data/lib/ri_cal/core_extensions/date/conversions.rb +56 -0
  38. data/lib/ri_cal/core_extensions/date.rb +13 -0
  39. data/lib/ri_cal/core_extensions/date_time/conversions.rb +50 -0
  40. data/lib/ri_cal/core_extensions/date_time.rb +15 -0
  41. data/lib/ri_cal/core_extensions/object/conversions.rb +20 -0
  42. data/lib/ri_cal/core_extensions/object.rb +8 -0
  43. data/lib/ri_cal/core_extensions/string/conversions.rb +57 -0
  44. data/lib/ri_cal/core_extensions/string.rb +8 -0
  45. data/lib/ri_cal/core_extensions/time/calculations.rb +153 -0
  46. data/lib/ri_cal/core_extensions/time/conversions.rb +42 -0
  47. data/lib/ri_cal/core_extensions/time/tzid_access.rb +50 -0
  48. data/lib/ri_cal/core_extensions/time/week_day_predicates.rb +55 -0
  49. data/lib/ri_cal/core_extensions/time.rb +14 -0
  50. data/lib/ri_cal/core_extensions.rb +11 -0
  51. data/lib/ri_cal/fast_date_time.rb +234 -0
  52. data/lib/ri_cal/floating_timezone.rb +32 -0
  53. data/lib/ri_cal/invalid_property_value.rb +8 -0
  54. data/lib/ri_cal/invalid_timezone_identifier.rb +20 -0
  55. data/lib/ri_cal/occurrence_enumerator.rb +265 -0
  56. data/lib/ri_cal/occurrence_period.rb +17 -0
  57. data/lib/ri_cal/parser.rb +148 -0
  58. data/lib/ri_cal/properties/alarm.rb +390 -0
  59. data/lib/ri_cal/properties/calendar.rb +164 -0
  60. data/lib/ri_cal/properties/event.rb +1523 -0
  61. data/lib/ri_cal/properties/freebusy.rb +593 -0
  62. data/lib/ri_cal/properties/journal.rb +1237 -0
  63. data/lib/ri_cal/properties/timezone.rb +150 -0
  64. data/lib/ri_cal/properties/timezone_period.rb +416 -0
  65. data/lib/ri_cal/properties/todo.rb +1559 -0
  66. data/lib/ri_cal/properties.rb +12 -0
  67. data/lib/ri_cal/property_value/array.rb +27 -0
  68. data/lib/ri_cal/property_value/cal_address.rb +11 -0
  69. data/lib/ri_cal/property_value/date.rb +184 -0
  70. data/lib/ri_cal/property_value/date_time/additive_methods.rb +44 -0
  71. data/lib/ri_cal/property_value/date_time/time_machine.rb +159 -0
  72. data/lib/ri_cal/property_value/date_time/timezone_support.rb +100 -0
  73. data/lib/ri_cal/property_value/date_time.rb +359 -0
  74. data/lib/ri_cal/property_value/duration.rb +110 -0
  75. data/lib/ri_cal/property_value/geo.rb +11 -0
  76. data/lib/ri_cal/property_value/integer.rb +12 -0
  77. data/lib/ri_cal/property_value/occurrence_list.rb +144 -0
  78. data/lib/ri_cal/property_value/period.rb +86 -0
  79. data/lib/ri_cal/property_value/recurrence_rule/enumeration_support_methods.rb +100 -0
  80. data/lib/ri_cal/property_value/recurrence_rule/enumerator.rb +79 -0
  81. data/lib/ri_cal/property_value/recurrence_rule/initialization_methods.rb +148 -0
  82. data/lib/ri_cal/property_value/recurrence_rule/negative_setpos_enumerator.rb +53 -0
  83. data/lib/ri_cal/property_value/recurrence_rule/numbered_span.rb +31 -0
  84. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_day_incrementer.rb +86 -0
  85. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_hour_incrementer.rb +31 -0
  86. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_minute_incrementer.rb +32 -0
  87. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_month_incrementer.rb +52 -0
  88. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_monthday_incrementer.rb +31 -0
  89. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_numbered_day_incrementer.rb +38 -0
  90. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_second_incrementer.rb +32 -0
  91. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_weekno_incrementer.rb +69 -0
  92. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_yearday_incrementer.rb +31 -0
  93. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/daily_incrementer.rb +28 -0
  94. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/frequency_incrementer.rb +80 -0
  95. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/hourly_incrementer.rb +23 -0
  96. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/list_incrementer.rb +106 -0
  97. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/minutely_incrementer.rb +23 -0
  98. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/monthly_incrementer.rb +33 -0
  99. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/null_sub_cycle_incrementer.rb +43 -0
  100. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/secondly_incrementer.rb +28 -0
  101. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/weekly_incrementer.rb +37 -0
  102. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/yearly_incrementer.rb +57 -0
  103. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer.rb +135 -0
  104. data/lib/ri_cal/property_value/recurrence_rule/recurring_day.rb +131 -0
  105. data/lib/ri_cal/property_value/recurrence_rule/recurring_month_day.rb +64 -0
  106. data/lib/ri_cal/property_value/recurrence_rule/recurring_numbered_week.rb +33 -0
  107. data/lib/ri_cal/property_value/recurrence_rule/recurring_year_day.rb +53 -0
  108. data/lib/ri_cal/property_value/recurrence_rule/time_manipulation.rb +42 -0
  109. data/lib/ri_cal/property_value/recurrence_rule/validations.rb +125 -0
  110. data/lib/ri_cal/property_value/recurrence_rule.rb +154 -0
  111. data/lib/ri_cal/property_value/text.rb +44 -0
  112. data/lib/ri_cal/property_value/uri.rb +11 -0
  113. data/lib/ri_cal/property_value/utc_offset.rb +33 -0
  114. data/lib/ri_cal/property_value/zulu_date_time.rb +34 -0
  115. data/lib/ri_cal/property_value.rb +159 -0
  116. data/lib/ri_cal/required_timezones.rb +55 -0
  117. data/lib/ri_cal.rb +187 -0
  118. data/parked_specs/ri_cal/claudio_a_bug_spec.rb +100 -0
  119. data/performance/empty_propval/subject.rb +43 -0
  120. data/performance/paris_eastern/subject.rb +90 -0
  121. data/performance/penultimate_weekday/subject.rb +15 -0
  122. data/performance/psm_big_enum/ical.ics +3171 -0
  123. data/performance/psm_big_enum/subject.rb +16 -0
  124. data/performance/utah_cycling/subject.rb +55 -0
  125. data/ri_cal.gemspec +244 -0
  126. data/script/benchmark_subject +23 -0
  127. data/script/console +10 -0
  128. data/script/destroy +14 -0
  129. data/script/generate +14 -0
  130. data/script/profile_subject +29 -0
  131. data/script/txt2html +71 -0
  132. data/spec/ri_cal/bugreports_spec.rb +276 -0
  133. data/spec/ri_cal/component/alarm_spec.rb +12 -0
  134. data/spec/ri_cal/component/calendar_spec.rb +88 -0
  135. data/spec/ri_cal/component/event_spec.rb +735 -0
  136. data/spec/ri_cal/component/freebusy_spec.rb +12 -0
  137. data/spec/ri_cal/component/journal_spec.rb +37 -0
  138. data/spec/ri_cal/component/t_z_info_timezone_spec.rb +60 -0
  139. data/spec/ri_cal/component/timezone_spec.rb +236 -0
  140. data/spec/ri_cal/component/todo_spec.rb +112 -0
  141. data/spec/ri_cal/component_spec.rb +224 -0
  142. data/spec/ri_cal/core_extensions/string/conversions_spec.rb +78 -0
  143. data/spec/ri_cal/core_extensions/time/calculations_spec.rb +188 -0
  144. data/spec/ri_cal/core_extensions/time/week_day_predicates_spec.rb +45 -0
  145. data/spec/ri_cal/fast_date_time_spec.rb +77 -0
  146. data/spec/ri_cal/inf_loop_spec.rb +78 -0
  147. data/spec/ri_cal/occurrence_enumerator_spec.rb +611 -0
  148. data/spec/ri_cal/parser_spec.rb +337 -0
  149. data/spec/ri_cal/property_value/date_spec.rb +53 -0
  150. data/spec/ri_cal/property_value/date_time_spec.rb +383 -0
  151. data/spec/ri_cal/property_value/duration_spec.rb +126 -0
  152. data/spec/ri_cal/property_value/occurrence_list_spec.rb +72 -0
  153. data/spec/ri_cal/property_value/period_spec.rb +63 -0
  154. data/spec/ri_cal/property_value/recurrence_rule/recurring_year_day_spec.rb +21 -0
  155. data/spec/ri_cal/property_value/recurrence_rule_spec.rb +1814 -0
  156. data/spec/ri_cal/property_value/text_spec.rb +25 -0
  157. data/spec/ri_cal/property_value/utc_offset_spec.rb +48 -0
  158. data/spec/ri_cal/property_value_spec.rb +125 -0
  159. data/spec/ri_cal/required_timezones_spec.rb +67 -0
  160. data/spec/ri_cal_spec.rb +53 -0
  161. data/spec/spec.opts +4 -0
  162. data/spec/spec_helper.rb +50 -0
  163. data/tasks/gem_loader/load_active_support.rb +3 -0
  164. data/tasks/gem_loader/load_tzinfo_gem.rb +2 -0
  165. data/tasks/ri_cal.rake +412 -0
  166. data/tasks/spec.rake +102 -0
  167. metadata +246 -0
@@ -0,0 +1,1814 @@
1
+ #- ©2009 Rick DeNatale, All rights reserved. Refer to the file README.txt for the license
2
+
3
+ require File.join(File.dirname(__FILE__), %w[.. .. spec_helper])
4
+
5
+ require 'rubygems'
6
+
7
+ FirstOfMonth = RiCal::PropertyValue::RecurrenceRule::RecurringMonthDay.new(1)
8
+ TenthOfMonth = RiCal::PropertyValue::RecurrenceRule::RecurringMonthDay.new(10)
9
+ FirstOfYear = RiCal::PropertyValue::RecurrenceRule::RecurringYearDay.new(1)
10
+ TenthOfYear = RiCal::PropertyValue::RecurrenceRule::RecurringYearDay.new(10)
11
+ SecondWeekOfYear = RiCal::PropertyValue::RecurrenceRule::RecurringNumberedWeek.new(2)
12
+ LastWeekOfYear = RiCal::PropertyValue::RecurrenceRule::RecurringNumberedWeek.new(-1)
13
+
14
+ # rfc 2445 4.3.10 p.40
15
+ describe RiCal::PropertyValue::RecurrenceRule do
16
+
17
+ describe "initialized from hash" do
18
+ it "should require a frequency" do
19
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, {})
20
+ @it.should_not be_valid
21
+ @it.errors.should include("RecurrenceRule must have a value for FREQ")
22
+ end
23
+
24
+ it "accept reject an invalid frequency" do
25
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "blort")
26
+ @it.should_not be_valid
27
+ @it.errors.should include("Invalid frequency 'blort'")
28
+ end
29
+
30
+ %w{secondly SECONDLY minutely MINUTELY hourly HOURLY daily DAILY weekly WEEKLY monthly MONTHLY
31
+ yearly YEARLY
32
+ }.each do | freq_val |
33
+ it "should accept a frequency of #{freq_val}" do
34
+ RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => freq_val).should be_valid
35
+ end
36
+ end
37
+
38
+ it "should reject setting both until and count" do
39
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :until => Time.now, :count => 10)
40
+ @it.should_not be_valid
41
+ @it.errors.should include("COUNT and UNTIL cannot both be specified")
42
+ end
43
+
44
+ describe "interval parameter" do
45
+
46
+ # p 42
47
+ it "should default to 1" do
48
+ RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily").interval.should == 1
49
+ end
50
+
51
+ it "should accept an explicit value" do
52
+ RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :interval => 42).interval.should == 42
53
+ end
54
+
55
+ it "should reject a negative value" do
56
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :interval => -1)
57
+ @it.should_not be_valid
58
+ end
59
+ end
60
+
61
+ describe "bysecond parameter" do
62
+
63
+ it "should accept a single integer" do
64
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :bysecond => 10)
65
+ @it.send(:by_list)[:bysecond].should == [10]
66
+ end
67
+
68
+ it "should accept an array of integers" do
69
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :bysecond => [10, 20])
70
+ @it.send(:by_list)[:bysecond].should == [10, 20]
71
+ end
72
+
73
+ it "should reject invalid values" do
74
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :bysecond => [-1, 0, 59, 60])
75
+ @it.should_not be_valid
76
+ @it.errors.should == ['-1 is invalid for bysecond', '60 is invalid for bysecond']
77
+ end
78
+ end
79
+
80
+ describe "byminute parameter" do
81
+
82
+ it "should accept a single integer" do
83
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :byminute => 10)
84
+ @it.send(:by_list)[:byminute].should == [10]
85
+ end
86
+
87
+ it "should accept an array of integers" do
88
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :byminute => [10, 20])
89
+ @it.send(:by_list)[:byminute].should == [10, 20]
90
+ end
91
+
92
+ it "should reject invalid values" do
93
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :byminute => [-1, 0, 59, 60])
94
+ @it.should_not be_valid
95
+ @it.errors.should == ['-1 is invalid for byminute', '60 is invalid for byminute']
96
+ end
97
+ end
98
+
99
+ describe "byhour parameter" do
100
+
101
+ it "should accept a single integer" do
102
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :byhour => 10)
103
+ @it.send(:by_list)[:byhour].should == [10]
104
+ end
105
+
106
+ it "should accept an array of integers" do
107
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :byhour => [10, 12])
108
+ @it.send(:by_list)[:byhour].should == [10, 12]
109
+ end
110
+
111
+ it "should reject invalid values" do
112
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :byhour => [-1, 0, 23, 24])
113
+ @it.should_not be_valid
114
+ @it.errors.should == ['-1 is invalid for byhour', '24 is invalid for byhour']
115
+ end
116
+ end
117
+
118
+ describe "byday parameter" do
119
+
120
+ def anyMonday(rule)
121
+ RiCal::PropertyValue::RecurrenceRule::RecurringDay.new("MO", rule)
122
+ end
123
+
124
+ def anyWednesday(rule)
125
+ RiCal::PropertyValue::RecurrenceRule::RecurringDay.new("WE", rule)
126
+ end
127
+
128
+
129
+ it "should accept a single value" do
130
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :byday => 'MO')
131
+ @it.send(:by_list)[:byday].should == [anyMonday(@it)]
132
+ end
133
+
134
+ it "should accept an array of values" do
135
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :byday => ['MO', 'WE'])
136
+ @it.send(:by_list)[:byday].should == [anyMonday(@it), anyWednesday(@it)]
137
+ end
138
+
139
+ it "should reject invalid values" do
140
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :byday => ['VE'])
141
+ @it.should_not be_valid
142
+ @it.errors.should == ['"VE" is not a valid day']
143
+ end
144
+ end
145
+
146
+ describe "bymonthday parameter" do
147
+
148
+ it "should accept a single value" do
149
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :bymonthday => 1)
150
+ @it.send(:by_list)[:bymonthday].should == [FirstOfMonth]
151
+ end
152
+
153
+ it "should accept an array of values" do
154
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :bymonthday => [1, 10])
155
+ @it.send(:by_list)[:bymonthday].should == [FirstOfMonth, TenthOfMonth]
156
+ end
157
+
158
+ it "should reject invalid values" do
159
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :bymonthday => [0, 32, 'VE'])
160
+ @it.should_not be_valid
161
+ @it.errors.should == ['0 is not a valid month day','32 is not a valid month day', '"VE" is not a valid month day']
162
+ end
163
+ end
164
+
165
+ describe "byyearday parameter" do
166
+
167
+ it "should accept a single value" do
168
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :byyearday => 1)
169
+ @it.send(:by_list)[:byyearday].should == [FirstOfYear]
170
+ end
171
+
172
+ it "should accept an array of values" do
173
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :byyearday => [1, 10])
174
+ @it.send(:by_list)[:byyearday].should == [FirstOfYear, TenthOfYear]
175
+ end
176
+
177
+ it "should reject invalid values" do
178
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :byyearday => [0, 370, 'VE'])
179
+ @it.should_not be_valid
180
+ @it.errors.should == ['0 is not a valid year day', '370 is not a valid year day', '"VE" is not a valid year day']
181
+ end
182
+ end
183
+
184
+ describe "byweekno parameter" do
185
+
186
+ it "should accept a single value" do
187
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :byweekno => 2)
188
+ @it.send(:by_list)[:byweekno].should == [SecondWeekOfYear]
189
+ end
190
+
191
+ it "should accept an array of values" do
192
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :byweekno => [2, -1])
193
+ @it.send(:by_list)[:byweekno].should == [SecondWeekOfYear, LastWeekOfYear]
194
+ end
195
+
196
+ it "should reject invalid values" do
197
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :byweekno => [0, 54, 'VE'])
198
+ @it.should_not be_valid
199
+ @it.errors.should == ['0 is not a valid week number', '54 is not a valid week number', '"VE" is not a valid week number']
200
+ end
201
+ end
202
+
203
+ describe "bymonth parameter" do
204
+
205
+ it "should accept a single integer" do
206
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :bymonth => 10)
207
+ @it.send(:by_list)[:bymonth].should == [10]
208
+ end
209
+
210
+ it "should accept an array of integers" do
211
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :bymonth => [10, 12])
212
+ @it.send(:by_list)[:bymonth].should == [10, 12]
213
+ end
214
+
215
+ it "should reject invalid values" do
216
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :bymonth => [-1, 0, 1, 12, 13])
217
+ @it.should_not be_valid
218
+ @it.errors.should == ['-1 is invalid for bymonth', '0 is invalid for bymonth', '13 is invalid for bymonth']
219
+ end
220
+ end
221
+
222
+ describe "bysetpos parameter" do
223
+
224
+ it "should accept a single integer" do
225
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :bymonth => 10, :bysetpos => 2)
226
+ @it.send(:by_list)[:bysetpos].should == [2]
227
+ end
228
+
229
+ it "should accept an array of integers" do
230
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :bymonth => 10, :bysetpos => [2, 3])
231
+ @it.send(:by_list)[:bysetpos].should == [2, 3]
232
+ end
233
+
234
+ it "should reject invalid values" do
235
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :bymonth => 10, :bysetpos => [-367, -366, -1, 0, 1, 366, 367])
236
+ @it.should_not be_valid
237
+ @it.errors.should == ['-367 is invalid for bysetpos', '0 is invalid for bysetpos', '367 is invalid for bysetpos']
238
+ end
239
+
240
+ it "should require another BYxxx rule part" do
241
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :bysetpos => 2)
242
+ @it.should_not be_valid
243
+ @it.errors.should == ['bysetpos cannot be used without another by_xxx rule part']
244
+ end
245
+ end
246
+
247
+ describe "wkst parameter" do
248
+
249
+ it "should default to MO" do
250
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily")
251
+ @it.wkst.should == 'MO'
252
+ end
253
+
254
+ it "should accept a single string" do
255
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :wkst => 'SU')
256
+ @it.wkst.should == 'SU'
257
+ end
258
+
259
+ %w{MO TU WE TH FR SA SU}.each do |valid|
260
+ it "should accept #{valid} as a valid value" do
261
+ RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :wkst => valid).should be_valid
262
+ end
263
+ end
264
+
265
+ it "should reject invalid values" do
266
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :wkst => "bogus")
267
+ @it.should_not be_valid
268
+ @it.errors.should == ['"bogus" is invalid for wkst']
269
+ end
270
+ end
271
+
272
+ describe "freq accessors" do
273
+ before(:each) do
274
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => 'daily')
275
+ end
276
+
277
+ it "should convert the initial value to uppercase" do
278
+ @it.freq.should == 'DAILY'
279
+ end
280
+
281
+ it "should convert the setter value to uppercase " do
282
+ @it.freq = 'weekly'
283
+ @it.freq.should == 'WEEKLY'
284
+ end
285
+
286
+ it "should not accept an invalid value" do
287
+ @it.freq = 'bogus'
288
+ @it.should_not be_valid
289
+ end
290
+ end
291
+ end
292
+
293
+ describe "initialized from parser" do
294
+
295
+ describe "from 'FREQ=YEARLY;INTERVAL=2;BYMONTH=1;BYDAY=SU;BYHOUR=8,9;BYMINUTE=30'" do
296
+
297
+ before(:all) do
298
+ lambda {
299
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :value => 'FREQ=YEARLY;INTERVAL=2;BYMONTH=1;BYDAY=SU;BYHOUR=8,9;BYMINUTE=30')
300
+ }.should_not raise_error
301
+ end
302
+
303
+ it "should have a frequency of yearly" do
304
+ @it.freq.should == "YEARLY"
305
+ end
306
+
307
+ it "should have an interval of 2" do
308
+ @it.interval.should == 2
309
+ end
310
+ end
311
+ end
312
+
313
+ describe "to_ical" do
314
+
315
+ it "should handle basic cases" do
316
+ RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily").to_ical.should == "FREQ=DAILY"
317
+ end
318
+
319
+ it "should handle multiple parts" do
320
+ @it = RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :count => 10, :interval => 2).to_ical
321
+ @it.should match(/^FREQ=DAILY;/)
322
+ parts = @it.split(';')
323
+ parts.should include("COUNT=10")
324
+ parts.should include("INTERVAL=2")
325
+ end
326
+
327
+ it "should supress the default interval value" do
328
+ RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :interval => 1).to_ical.should_not match(/INTERVAL=/)
329
+ end
330
+
331
+ it "should support the wkst value" do
332
+ RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :wkst => 'SU').to_ical.split(";").should include("WKST=SU")
333
+ end
334
+
335
+ it "should supress the default wkst value" do
336
+ RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :wkst => 'MO').to_ical.split(";").should_not include("WKST=SU")
337
+ end
338
+
339
+ it "should handle a scalar bysecond" do
340
+ RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :bysecond => 15).to_ical.split(";").should include("BYSECOND=15")
341
+ end
342
+
343
+ it "should handle an array bysecond" do
344
+ RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :bysecond => [15, 45]).to_ical.split(";").should include("BYSECOND=15,45")
345
+ end
346
+
347
+ it "should handle a scalar byday" do
348
+ RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "monthly", :byday => 'MO').to_ical.split(";").should include("BYDAY=MO")
349
+ end
350
+
351
+ it "should handle an array byday" do
352
+ RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :byday => ["MO", "-3SU"]).to_ical.split(";").should include("BYDAY=MO,-3SU")
353
+ end
354
+
355
+ it "should handle a scalar bymonthday" do
356
+ RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "monthly", :bymonthday => 14).to_ical.split(";").should include("BYMONTHDAY=14")
357
+ end
358
+
359
+ it "should handle an array bymonthday" do
360
+ RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :bymonthday => [15, -10]).to_ical.split(";").should include("BYMONTHDAY=15,-10")
361
+ end
362
+
363
+ it "should handle a scalar byyearday" do
364
+ RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "monthly", :byyearday => 14).to_ical.split(";").should include("BYYEARDAY=14")
365
+ end
366
+
367
+ it "should handle an array byyearday" do
368
+ RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :byyearday => [15, -10]).to_ical.split(";").should include("BYYEARDAY=15,-10")
369
+ end
370
+
371
+ it "should handle a scalar byweekno" do
372
+ RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "monthly", :byweekno => 14).to_ical.split(";").should include("BYWEEKNO=14")
373
+ end
374
+
375
+ it "should handle an array byyearday" do
376
+ RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :byweekno => [15, -10]).to_ical.split(";").should include("BYWEEKNO=15,-10")
377
+ end
378
+
379
+ it "should handle a scalar bymonth" do
380
+ RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "monthly", :bymonth => 2).to_ical.split(";").should include("BYMONTH=2")
381
+ end
382
+
383
+ it "should handle an array bymonth" do
384
+ RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :bymonth => [5, 6]).to_ical.split(";").should include("BYMONTH=5,6")
385
+ end
386
+
387
+ it "should handle a scalar bysetpos" do
388
+ RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "monthly", :byday => %w{MO TU WE TH FR}, :bysetpos => -1).to_ical.split(";").should include("BYSETPOS=-1")
389
+ end
390
+
391
+ it "should handle an array bysetpos" do
392
+ RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "monthly", :byday => %w{MO TU WE TH FR}, :bysetpos => [2, -1]).to_ical.split(";").should include("BYSETPOS=-1,2")
393
+ end
394
+
395
+ it "should handle until as a date" do
396
+ RiCal::PropertyValue::RecurrenceRule.new(nil, :freq => "daily", :until => Date.new(2009,10,17)).to_ical.should include("UNTIL=20091017")
397
+ end
398
+ end
399
+
400
+ def ruby19_date_str_fix(string)
401
+ end
402
+
403
+ describe "#enumerator" do
404
+
405
+ def self.enumeration_spec(description, dtstart_string, tzid, rrule_string, expectation, debug=false)
406
+ if expectation.last == "..."
407
+ expectation = expectation[0..-2]
408
+ iterations = expectation.length
409
+ else
410
+ iterations = expectation.length + 1
411
+ end
412
+
413
+ describe description do
414
+ before(:each) do
415
+ RiCal.debug = debug
416
+ rrule = RiCal::PropertyValue::RecurrenceRule.new(nil, :value => rrule_string)
417
+ default_start_time = RiCal::PropertyValue::DateTime.new(nil, :value => dtstart_string, :tzid => tzid)
418
+ @enum = rrule.enumerator(mock("EventValue", :default_start_time => default_start_time, :default_duration => nil))
419
+ @expectations = (expectation.map {|str| RiCal::PropertyValue::DateTime.new(nil, :value => str.gsub(/E.T$/,''), :tzid => tzid)})
420
+ end
421
+
422
+ after(:each) do
423
+ RiCal.debug = false
424
+ end
425
+
426
+ after(:each) do
427
+ RiCal.debug = false
428
+ end
429
+
430
+ it "should produce the correct occurrences" do
431
+ actuals = []
432
+ (0..(iterations-1)).each do |i|
433
+ occurrence = @enum.next_occurrence
434
+ break if occurrence.nil?
435
+ actuals << occurrence.dtstart
436
+ # This is a little strange, we do this to avoid O(n*2)
437
+ unless actuals.last == @expectations[i]
438
+ actuals.should == @expectations[0,actuals.length]
439
+ end
440
+ end
441
+ actuals.length.should == @expectations.length
442
+ end
443
+ end
444
+ end
445
+
446
+ enumeration_spec(
447
+ "Daily for 10 occurrences (RFC 2445 p 118)",
448
+ "19970902T090000",
449
+ "US-Eastern",
450
+ "FREQ=DAILY;COUNT=10",
451
+ [
452
+ "Sep 2, 1997 9:00 AM EDT",
453
+ "Sep 3, 1997 9:00 AM EDT",
454
+ "Sep 4, 1997 9:00 AM EDT",
455
+ "Sep 5, 1997 9:00 AM EDT",
456
+ "Sep 6, 1997 9:00 AM EDT",
457
+ "Sep 7, 1997 9:00 AM EDT",
458
+ "Sep 8, 1997 9:00 AM EDT",
459
+ "Sep 9, 1997 9:00 AM EDT",
460
+ "Sep 10, 1997 9:00 AM EDT",
461
+ "Sep 11, 1997 9:00 AM EDT"
462
+ ]
463
+ )
464
+
465
+ enumeration_spec(
466
+ "Daily until December 24, 1997 (RFC 2445 p 118)",
467
+ "19970902T090000",
468
+ "US-Eastern",
469
+ "FREQ=DAILY;UNTIL=19971224T000000Z",
470
+ [
471
+ "Sep 2, 1997 9:00 AM EDT",
472
+ "Sep 3, 1997 9:00 AM EDT",
473
+ "Sep 4, 1997 9:00 AM EDT",
474
+ "Sep 5, 1997 9:00 AM EDT",
475
+ "Sep 6, 1997 9:00 AM EDT",
476
+ "Sep 7, 1997 9:00 AM EDT",
477
+ "Sep 8, 1997 9:00 AM EDT",
478
+ "Sep 9, 1997 9:00 AM EDT",
479
+ "Sep 10, 1997 9:00 AM EDT",
480
+ "Sep 11, 1997 9:00 AM EDT",
481
+ "Sep 12, 1997 9:00 AM EDT",
482
+ "Sep 13, 1997 9:00 AM EDT",
483
+ "Sep 14, 1997 9:00 AM EDT",
484
+ "Sep 15, 1997 9:00 AM EDT",
485
+ "Sep 16, 1997 9:00 AM EDT",
486
+ "Sep 17, 1997 9:00 AM EDT",
487
+ "Sep 18, 1997 9:00 AM EDT",
488
+ "Sep 19, 1997 9:00 AM EDT",
489
+ "Sep 20, 1997 9:00 AM EDT",
490
+ "Sep 21, 1997 9:00 AM EDT",
491
+ "Sep 22, 1997 9:00 AM EDT",
492
+ "Sep 23, 1997 9:00 AM EDT",
493
+ "Sep 24, 1997 9:00 AM EDT",
494
+ "Sep 25, 1997 9:00 AM EDT",
495
+ "Sep 26, 1997 9:00 AM EDT",
496
+ "Sep 27, 1997 9:00 AM EDT",
497
+ "Sep 28, 1997 9:00 AM EDT",
498
+ "Sep 29, 1997 9:00 AM EDT",
499
+ "Sep 30, 1997 9:00 AM EDT",
500
+ "Oct 1, 1997 9:00 AM EDT",
501
+ "Oct 2, 1997 9:00 AM EDT",
502
+ "Oct 3, 1997 9:00 AM EDT",
503
+ "Oct 4, 1997 9:00 AM EDT",
504
+ "Oct 5, 1997 9:00 AM EDT",
505
+ "Oct 6, 1997 9:00 AM EDT",
506
+ "Oct 7, 1997 9:00 AM EDT",
507
+ "Oct 8, 1997 9:00 AM EDT",
508
+ "Oct 9, 1997 9:00 AM EDT",
509
+ "Oct 10, 1997 9:00 AM EDT",
510
+ "Oct 11, 1997 9:00 AM EDT",
511
+ "Oct 12, 1997 9:00 AM EDT",
512
+ "Oct 13, 1997 9:00 AM EDT",
513
+ "Oct 14, 1997 9:00 AM EDT",
514
+ "Oct 15, 1997 9:00 AM EDT",
515
+ "Oct 16, 1997 9:00 AM EDT",
516
+ "Oct 17, 1997 9:00 AM EDT",
517
+ "Oct 18, 1997 9:00 AM EDT",
518
+ "Oct 19, 1997 9:00 AM EDT",
519
+ "Oct 20, 1997 9:00 AM EDT",
520
+ "Oct 21, 1997 9:00 AM EDT",
521
+ "Oct 22, 1997 9:00 AM EDT",
522
+ "Oct 23, 1997 9:00 AM EDT",
523
+ "Oct 24, 1997 9:00 AM EDT",
524
+ "Oct 25, 1997 9:00 AM EDT",
525
+ "Oct 26, 1997 9:00 AM EST",
526
+ "Oct 27, 1997 9:00 AM EST",
527
+ "Oct 28, 1997 9:00 AM EST",
528
+ "Oct 29, 1997 9:00 AM EST",
529
+ "Oct 30, 1997 9:00 AM EST",
530
+ "Oct 31, 1997 9:00 AM EST",
531
+ "Nov 01, 1997 9:00 AM EST",
532
+ "Nov 02, 1997 9:00 AM EST",
533
+ "Nov 03, 1997 9:00 AM EST",
534
+ "Nov 04, 1997 9:00 AM EST",
535
+ "Nov 05, 1997 9:00 AM EST",
536
+ "Nov 06, 1997 9:00 AM EST",
537
+ "Nov 07, 1997 9:00 AM EST",
538
+ "Nov 08, 1997 9:00 AM EST",
539
+ "Nov 09, 1997 9:00 AM EST",
540
+ "Nov 10, 1997 9:00 AM EST",
541
+ "Nov 11, 1997 9:00 AM EST",
542
+ "Nov 12, 1997 9:00 AM EST",
543
+ "Nov 13, 1997 9:00 AM EST",
544
+ "Nov 14, 1997 9:00 AM EST",
545
+ "Nov 15, 1997 9:00 AM EST",
546
+ "Nov 16, 1997 9:00 AM EST",
547
+ "Nov 17, 1997 9:00 AM EST",
548
+ "Nov 18, 1997 9:00 AM EST",
549
+ "Nov 19, 1997 9:00 AM EST",
550
+ "Nov 20, 1997 9:00 AM EST",
551
+ "Nov 21, 1997 9:00 AM EST",
552
+ "Nov 22, 1997 9:00 AM EST",
553
+ "Nov 23, 1997 9:00 AM EST",
554
+ "Nov 24, 1997 9:00 AM EST",
555
+ "Nov 25, 1997 9:00 AM EST",
556
+ "Nov 26, 1997 9:00 AM EST",
557
+ "Nov 27, 1997 9:00 AM EST",
558
+ "Nov 28, 1997 9:00 AM EST",
559
+ "Nov 29, 1997 9:00 AM EST",
560
+ "Nov 30, 1997 9:00 AM EST",
561
+ "Dec 01, 1997 9:00 AM EST",
562
+ "Dec 02, 1997 9:00 AM EST",
563
+ "Dec 03, 1997 9:00 AM EST",
564
+ "Dec 04, 1997 9:00 AM EST",
565
+ "Dec 05, 1997 9:00 AM EST",
566
+ "Dec 06, 1997 9:00 AM EST",
567
+ "Dec 07, 1997 9:00 AM EST",
568
+ "Dec 08, 1997 9:00 AM EST",
569
+ "Dec 09, 1997 9:00 AM EST",
570
+ "Dec 10, 1997 9:00 AM EST",
571
+ "Dec 11, 1997 9:00 AM EST",
572
+ "Dec 12, 1997 9:00 AM EST",
573
+ "Dec 13, 1997 9:00 AM EST",
574
+ "Dec 14, 1997 9:00 AM EST",
575
+ "Dec 15, 1997 9:00 AM EST",
576
+ "Dec 16, 1997 9:00 AM EST",
577
+ "Dec 17, 1997 9:00 AM EST",
578
+ "Dec 18, 1997 9:00 AM EST",
579
+ "Dec 19, 1997 9:00 AM EST",
580
+ "Dec 20, 1997 9:00 AM EST",
581
+ "Dec 21, 1997 9:00 AM EST",
582
+ "Dec 22, 1997 9:00 AM EST",
583
+ "Dec 23, 1997 9:00 AM EST",
584
+ ]
585
+ )
586
+
587
+ enumeration_spec(
588
+ "Every other day - forever (RFC 2445 p 118)",
589
+ "19970902T090000",
590
+ "US-Eastern",
591
+ "FREQ=DAILY;INTERVAL=2",
592
+ [
593
+ "Sep 2, 1997 9:00 AM EDT",
594
+ "Sep 4, 1997 9:00 AM EDT",
595
+ "Sep 6, 1997 9:00 AM EDT",
596
+ "Sep 8, 1997 9:00 AM EDT",
597
+ "Sep 10, 1997 9:00 AM EDT",
598
+ "Sep 12, 1997 9:00 AM EDT",
599
+ "Sep 14, 1997 9:00 AM EDT",
600
+ "Sep 16, 1997 9:00 AM EDT",
601
+ "Sep 18, 1997 9:00 AM EDT",
602
+ "Sep 20, 1997 9:00 AM EDT",
603
+ "Sep 22, 1997 9:00 AM EDT",
604
+ "Sep 24, 1997 9:00 AM EDT",
605
+ "Sep 26, 1997 9:00 AM EDT",
606
+ "Sep 28, 1997 9:00 AM EDT",
607
+ "Sep 30, 1997 9:00 AM EDT",
608
+ "Oct 2, 1997 9:00 AM EDT",
609
+ "Oct 4, 1997 9:00 AM EDT",
610
+ "Oct 6, 1997 9:00 AM EDT",
611
+ "Oct 8, 1997 9:00 AM EDT",
612
+ "Oct 10, 1997 9:00 AM EDT",
613
+ "Oct 12, 1997 9:00 AM EDT",
614
+ "Oct 14, 1997 9:00 AM EDT",
615
+ "Oct 16, 1997 9:00 AM EDT",
616
+ "Oct 18, 1997 9:00 AM EDT",
617
+ "Oct 20, 1997 9:00 AM EDT",
618
+ "Oct 22, 1997 9:00 AM EDT",
619
+ "Oct 24, 1997 9:00 AM EDT",
620
+ "Oct 26, 1997 9:00 AM EST",
621
+ "Oct 28, 1997 9:00 AM EST",
622
+ "Oct 30, 1997 9:00 AM EST",
623
+ "Nov 01, 1997 9:00 AM EST",
624
+ "Nov 03, 1997 9:00 AM EST",
625
+ "Nov 05, 1997 9:00 AM EST",
626
+ "Nov 07, 1997 9:00 AM EST",
627
+ "Nov 09, 1997 9:00 AM EST",
628
+ "Nov 11, 1997 9:00 AM EST",
629
+ "Nov 13, 1997 9:00 AM EST",
630
+ "Nov 15, 1997 9:00 AM EST",
631
+ "Nov 17, 1997 9:00 AM EST",
632
+ "Nov 19, 1997 9:00 AM EST",
633
+ "Nov 21, 1997 9:00 AM EST",
634
+ "Nov 23, 1997 9:00 AM EST",
635
+ "Nov 25, 1997 9:00 AM EST",
636
+ "Nov 27, 1997 9:00 AM EST",
637
+ "Nov 29, 1997 9:00 AM EST",
638
+ "Dec 01, 1997 9:00 AM EST",
639
+ "Dec 03, 1997 9:00 AM EST",
640
+ "..."
641
+ ]
642
+ )
643
+
644
+ enumeration_spec(
645
+ "Every 10 days, 5 occurrences (RFC 2445 p 118-19)",
646
+ "19970902T090000",
647
+ "US-Eastern",
648
+ "FREQ=DAILY;INTERVAL=10;COUNT=5",
649
+ [
650
+ "Sep 2, 1997 9:00 AM EDT",
651
+ "Sep 12, 1997 9:00 AM EDT",
652
+ "Sep 22, 1997 9:00 AM EDT",
653
+ "Oct 2, 1997 9:00 AM EDT",
654
+ "Oct 12, 1997 9:00 AM EDT"
655
+ ]
656
+ )
657
+
658
+ enumeration_spec(
659
+ "Everyday in January, for 3 years (RFC 2445 p 119)",
660
+ "19980101T090000",
661
+ "US-Eastern",
662
+ "FREQ=DAILY;UNTIL=20000131T090000Z;BYMONTH=1",
663
+ [
664
+ "Jan 01, 1998 9:00 AM EST",
665
+ "Jan 02, 1998 9:00 AM EST",
666
+ "Jan 03, 1998 9:00 AM EST",
667
+ "Jan 04, 1998 9:00 AM EST",
668
+ "Jan 05, 1998 9:00 AM EST",
669
+ "Jan 06, 1998 9:00 AM EST",
670
+ "Jan 07, 1998 9:00 AM EST",
671
+ "Jan 08, 1998 9:00 AM EST",
672
+ "Jan 09, 1998 9:00 AM EST",
673
+ "Jan 10, 1998 9:00 AM EST",
674
+ "Jan 11, 1998 9:00 AM EST",
675
+ "Jan 12, 1998 9:00 AM EST",
676
+ "Jan 13, 1998 9:00 AM EST",
677
+ "Jan 14, 1998 9:00 AM EST",
678
+ "Jan 15, 1998 9:00 AM EST",
679
+ "Jan 16, 1998 9:00 AM EST",
680
+ "Jan 17, 1998 9:00 AM EST",
681
+ "Jan 18, 1998 9:00 AM EST",
682
+ "Jan 19, 1998 9:00 AM EST",
683
+ "Jan 20, 1998 9:00 AM EST",
684
+ "Jan 21, 1998 9:00 AM EST",
685
+ "Jan 22, 1998 9:00 AM EST",
686
+ "Jan 23, 1998 9:00 AM EST",
687
+ "Jan 24, 1998 9:00 AM EST",
688
+ "Jan 25, 1998 9:00 AM EST",
689
+ "Jan 26, 1998 9:00 AM EST",
690
+ "Jan 27, 1998 9:00 AM EST",
691
+ "Jan 28, 1998 9:00 AM EST",
692
+ "Jan 29, 1998 9:00 AM EST",
693
+ "Jan 30, 1998 9:00 AM EST",
694
+ "Jan 31, 1998 9:00 AM EST",
695
+ "Jan 01, 1999 9:00 AM EST",
696
+ "Jan 02, 1999 9:00 AM EST",
697
+ "Jan 03, 1999 9:00 AM EST",
698
+ "Jan 04, 1999 9:00 AM EST",
699
+ "Jan 05, 1999 9:00 AM EST",
700
+ "Jan 06, 1999 9:00 AM EST",
701
+ "Jan 07, 1999 9:00 AM EST",
702
+ "Jan 08, 1999 9:00 AM EST",
703
+ "Jan 09, 1999 9:00 AM EST",
704
+ "Jan 10, 1999 9:00 AM EST",
705
+ "Jan 11, 1999 9:00 AM EST",
706
+ "Jan 12, 1999 9:00 AM EST",
707
+ "Jan 13, 1999 9:00 AM EST",
708
+ "Jan 14, 1999 9:00 AM EST",
709
+ "Jan 15, 1999 9:00 AM EST",
710
+ "Jan 16, 1999 9:00 AM EST",
711
+ "Jan 17, 1999 9:00 AM EST",
712
+ "Jan 18, 1999 9:00 AM EST",
713
+ "Jan 19, 1999 9:00 AM EST",
714
+ "Jan 20, 1999 9:00 AM EST",
715
+ "Jan 21, 1999 9:00 AM EST",
716
+ "Jan 22, 1999 9:00 AM EST",
717
+ "Jan 23, 1999 9:00 AM EST",
718
+ "Jan 24, 1999 9:00 AM EST",
719
+ "Jan 25, 1999 9:00 AM EST",
720
+ "Jan 26, 1999 9:00 AM EST",
721
+ "Jan 27, 1999 9:00 AM EST",
722
+ "Jan 28, 1999 9:00 AM EST",
723
+ "Jan 29, 1999 9:00 AM EST",
724
+ "Jan 30, 1999 9:00 AM EST",
725
+ "Jan 31, 1999 9:00 AM EST",
726
+ "Jan 01, 2000 9:00 AM EST",
727
+ "Jan 02, 2000 9:00 AM EST",
728
+ "Jan 03, 2000 9:00 AM EST",
729
+ "Jan 04, 2000 9:00 AM EST",
730
+ "Jan 05, 2000 9:00 AM EST",
731
+ "Jan 06, 2000 9:00 AM EST",
732
+ "Jan 07, 2000 9:00 AM EST",
733
+ "Jan 08, 2000 9:00 AM EST",
734
+ "Jan 09, 2000 9:00 AM EST",
735
+ "Jan 10, 2000 9:00 AM EST",
736
+ "Jan 11, 2000 9:00 AM EST",
737
+ "Jan 12, 2000 9:00 AM EST",
738
+ "Jan 13, 2000 9:00 AM EST",
739
+ "Jan 14, 2000 9:00 AM EST",
740
+ "Jan 15, 2000 9:00 AM EST",
741
+ "Jan 16, 2000 9:00 AM EST",
742
+ "Jan 17, 2000 9:00 AM EST",
743
+ "Jan 18, 2000 9:00 AM EST",
744
+ "Jan 19, 2000 9:00 AM EST",
745
+ "Jan 20, 2000 9:00 AM EST",
746
+ "Jan 21, 2000 9:00 AM EST",
747
+ "Jan 22, 2000 9:00 AM EST",
748
+ "Jan 23, 2000 9:00 AM EST",
749
+ "Jan 24, 2000 9:00 AM EST",
750
+ "Jan 25, 2000 9:00 AM EST",
751
+ "Jan 26, 2000 9:00 AM EST",
752
+ "Jan 27, 2000 9:00 AM EST",
753
+ "Jan 28, 2000 9:00 AM EST",
754
+ "Jan 29, 2000 9:00 AM EST",
755
+ "Jan 30, 2000 9:00 AM EST",
756
+ "Jan 31, 2000 9:00 AM EST"
757
+ ], true
758
+ )
759
+
760
+ enumeration_spec(
761
+ "Weekly for 10 occurrences (RFC 2445 p 119)",
762
+ "19970902T090000",
763
+ "US-Eastern",
764
+ "FREQ=WEEKLY;COUNT=10",
765
+ [
766
+ "Sep 2, 1997 9:00 AM EDT",
767
+ "Sep 9, 1997 9:00 AM EDT",
768
+ "Sep 16, 1997 9:00 AM EDT",
769
+ "Sep 23, 1997 9:00 AM EDT",
770
+ "Sep 30, 1997 9:00 AM EDT",
771
+ "Oct 7, 1997 9:00 AM EDT",
772
+ "Oct 14, 1997 9:00 AM EDT",
773
+ "Oct 21, 1997 9:00 AM EDT",
774
+ "Oct 28, 1997 9:00 AM EST",
775
+ "Nov 4, 1997 9:00 AM EST"
776
+ ]
777
+ )
778
+
779
+ enumeration_spec(
780
+ "Weekly until December 24, 1997 (RFC 2445 p 119)",
781
+ "19970902T090000",
782
+ "US-Eastern",
783
+ "FREQ=WEEKLY;UNTIL=19971224T000000Z",
784
+ [
785
+ "Sep 2, 1997 9:00 AM EDT",
786
+ "Sep 9, 1997 9:00 AM EDT",
787
+ "Sep 16, 1997 9:00 AM EDT",
788
+ "Sep 23, 1997 9:00 AM EDT",
789
+ "Sep 30, 1997 9:00 AM EDT",
790
+ "Oct 7, 1997 9:00 AM EDT",
791
+ "Oct 14, 1997 9:00 AM EDT",
792
+ "Oct 21, 1997 9:00 AM EDT",
793
+ "Oct 28, 1997 9:00 AM EST",
794
+ "Nov 4, 1997 9:00 AM EST",
795
+ "Nov 11, 1997 9:00 AM EST",
796
+ "Nov 18, 1997 9:00 AM EST",
797
+ "Nov 25, 1997 9:00 AM EST",
798
+ "Dec 2, 1997 9:00 AM EST",
799
+ "Dec 9, 1997 9:00 AM EST",
800
+ "Dec 16, 1997 9:00 AM EST",
801
+ "Dec 23, 1997 9:00 AM EST"
802
+ ]
803
+ )
804
+
805
+ enumeration_spec(
806
+ "Every other week - forever (RFC 2445 p 119)",
807
+ "19970902T090000",
808
+ "US-Eastern",
809
+ "FREQ=WEEKLY;INTERVAL=2;WKST=SU",
810
+ [
811
+ "Sep 2, 1997 9:00 AM EDT",
812
+ "Sep 16, 1997 9:00 AM EDT",
813
+ "Sep 30, 1997 9:00 AM EDT",
814
+ "Oct 14, 1997 9:00 AM EDT",
815
+ "Oct 28, 1997 9:00 AM EST",
816
+ "Nov 11, 1997 9:00 AM EST",
817
+ "Nov 25, 1997 9:00 AM EST",
818
+ "Dec 9, 1997 9:00 AM EST",
819
+ "Dec 23, 1997 9:00 AM EST",
820
+ "Jan 6, 1998 9:00 AM EST",
821
+ "Jan 20, 1998 9:00 AM EST",
822
+ "Feb 3, 1998 9:00 AM EST",
823
+ "..."
824
+ ]
825
+ )
826
+
827
+ enumeration_spec(
828
+ "Weekly on Tuesday and Thursday for 5 weeks, Alternative 1 (RFC 2445 p 119)",
829
+ "19970902T090000",
830
+ "US-Eastern",
831
+ "FREQ=WEEKLY;UNTIL=19971007T000000Z;WKST=SU;BYDAY=TU,TH",
832
+ [
833
+ "Sep 2, 1997 9:00 AM EDT",
834
+ "Sep 4, 1997 9:00 AM EDT",
835
+ "Sep 9, 1997 9:00 AM EDT",
836
+ "Sep 11, 1997 9:00 AM EDT",
837
+ "Sep 16, 1997 9:00 AM EST",
838
+ "Sep 18, 1997 9:00 AM EST",
839
+ "Sep 23, 1997 9:00 AM EST",
840
+ "Sep 25, 1997 9:00 AM EST",
841
+ "Sep 30, 1997 9:00 AM EST",
842
+ "Oct 2, 1997 9:00 AM EST"
843
+ ]
844
+ )
845
+
846
+ enumeration_spec(
847
+ "Weekly on Tuesday and Thursday for 5 weeks, Alternative 2 (RFC 2445 p 120)",
848
+ "19970902T090000",
849
+ "US-Eastern",
850
+ "FREQ=WEEKLY;COUNT=10;WKST=SU;BYDAY=TU,TH",
851
+ [
852
+ "Sep 2, 1997 9:00 AM EDT",
853
+ "Sep 4, 1997 9:00 AM EDT",
854
+ "Sep 9, 1997 9:00 AM EDT",
855
+ "Sep 11, 1997 9:00 AM EDT",
856
+ "Sep 16, 1997 9:00 AM EST",
857
+ "Sep 18, 1997 9:00 AM EST",
858
+ "Sep 23, 1997 9:00 AM EST",
859
+ "Sep 25, 1997 9:00 AM EST",
860
+ "Sep 30, 1997 9:00 AM EST",
861
+ "Oct 2, 1997 9:00 AM EST"
862
+ ]
863
+ )
864
+
865
+ enumeration_spec(
866
+ "Every other week on Monday, Wednesday and Friday until December 24,1997, but starting on Tuesday, September 2, 1997 (RFC 2445 p 120)",
867
+ "19970902T090000",
868
+ "US-Eastern",
869
+ "FREQ=WEEKLY;INTERVAL=2;UNTIL=19971224T000000Z;WKST=SU;BYDAY=MO,WE,FR",
870
+ [
871
+ "Sep 2, 1997 9:00 AM EDT",
872
+ "Sep 3, 1997 9:00 AM EDT",
873
+ "Sep 5, 1997 9:00 AM EDT",
874
+ "Sep 15, 1997 9:00 AM EDT",
875
+ "Sep 17, 1997 9:00 AM EDT",
876
+ "Sep 19, 1997 9:00 AM EDT",
877
+ "Sep 29, 1997 9:00 AM EDT",
878
+ "Oct 1, 1997 9:00 AM EDT",
879
+ "Oct 3, 1997 9:00 AM EDT",
880
+ "Oct 13, 1997 9:00 AM EDT",
881
+ "Oct 15, 1997 9:00 AM EDT",
882
+ "Oct 17, 1997 9:00 AM EDT",
883
+ "Oct 27, 1997 9:00 AM EST",
884
+ "Oct 29, 1997 9:00 AM EST",
885
+ "Oct 31, 1997 9:00 AM EST",
886
+ "Nov 10, 1997 9:00 AM EST",
887
+ "Nov 12, 1997 9:00 AM EST",
888
+ "Nov 14, 1997 9:00 AM EST",
889
+ "Nov 24, 1997 9:00 AM EST",
890
+ "Nov 26, 1997 9:00 AM EST",
891
+ "Nov 28, 1997 9:00 AM EST",
892
+ "Dec 8, 1997 9:00 AM EST",
893
+ "Dec 10, 1997 9:00 AM EST",
894
+ "Dec 12, 1997 9:00 AM EST",
895
+ "Dec 22, 1997 9:00 AM EST"
896
+ ], true
897
+ )
898
+
899
+ enumeration_spec(
900
+ "Every other week on TU and TH for 8 occurrences (RFC 2445 p 120)",
901
+ "19970902T090000",
902
+ "US-Eastern",
903
+ "FREQ=WEEKLY;INTERVAL=2;COUNT=8;WKST=SU;BYDAY=TU,TH",
904
+ [
905
+ "Sep 2, 1997 9:00 AM EDT",
906
+ "Sep 4, 1997 9:00 AM EDT",
907
+ "Sep 16, 1997 9:00 AM EDT",
908
+ "Sep 18, 1997 9:00 AM EDT",
909
+ "Sep 30, 1997 9:00 AM EDT",
910
+ "Oct 2, 1997 9:00 AM EDT",
911
+ "Oct 14, 1997 9:00 AM EDT",
912
+ "Oct 16, 1997 9:00 AM EDT"
913
+ ], true
914
+ )
915
+
916
+ enumeration_spec(
917
+ "Monthly on the 1st Friday for ten occurrences (RFC 2445 p 120)",
918
+ "19970905T090000",
919
+ "US-Eastern",
920
+ "FREQ=MONTHLY;COUNT=10;BYDAY=1FR",
921
+ [
922
+ "Sep 5, 1997 9:00 AM EDT",
923
+ "Oct 3, 1997 9:00 AM EDT",
924
+ "Nov 7, 1997 9:00 AM EST",
925
+ "Dec 5, 1997 9:00 AM EST",
926
+ "Jan 2, 1998 9:00 AM EST",
927
+ "Feb 6, 1998 9:00 AM EST",
928
+ "Mar 6, 1998 9:00 AM EST",
929
+ "Apr 3, 1998 9:00 AM EST",
930
+ "May 1, 1998 9:00 AM EDT",
931
+ "Jun 5, 1998 9:00 AM EDT",
932
+ ]
933
+ )
934
+
935
+ enumeration_spec(
936
+ "Monthly on the 1st Friday until December 24, 1997 (RFC 2445 p 120)",
937
+ "19970905T090000",
938
+ "US-Eastern",
939
+ "FREQ=MONTHLY;UNTIL=19971224T000000Z;BYDAY=1FR",
940
+ [
941
+ "Sep 5, 1997 9:00 AM EDT",
942
+ "Oct 3, 1997 9:00 AM EDT",
943
+ "Nov 7, 1997 9:00 AM EST",
944
+ "Dec 5, 1997 9:00 AM EST"
945
+ ]
946
+ )
947
+
948
+ enumeration_spec(
949
+ "Every other month on the 1st and last Sunday of the month for 10 occurrences (RFC 2445 p 120)",
950
+ "19970907T090000",
951
+ "US-Eastern",
952
+ "FREQ=MONTHLY;INTERVAL=2;COUNT=10;BYDAY=1SU,-1SU",
953
+ [
954
+ "Sep 7, 1997 9:00 AM EDT",
955
+ "Sep 28, 1997 9:00 AM EDT",
956
+ "Nov 2, 1997 9:00 AM EST",
957
+ "Nov 30, 1997 9:00 AM EST",
958
+ "Jan 4, 1998 9:00 AM EST",
959
+ "Jan 25, 1998 9:00 AM EST",
960
+ "Mar 1, 1998 9:00 AM EST",
961
+ "Mar 29, 1998 9:00 AM EST",
962
+ "May 3, 1998 9:00 AM EDT",
963
+ "May 31, 1998 9:00 AM EST"
964
+ ]
965
+ )
966
+
967
+ enumeration_spec(
968
+ "Monthly on the second to last Monday of the month for 6 months (RFC 2445 p 121)",
969
+ "19970922T090000",
970
+ "US-Eastern",
971
+ "FREQ=MONTHLY;COUNT=6;BYDAY=-2MO",
972
+ [
973
+ "Sep 22, 1997 9:00 AM EDT",
974
+ "Oct 20, 1997 9:00 AM EDT",
975
+ "Nov 17, 1997 9:00 AM EST",
976
+ "Dec 22, 1997 9:00 AM EST",
977
+ "Jan 19, 1998 9:00 AM EST",
978
+ "Feb 16, 1998 9:00 AM EST"
979
+ ]
980
+ )
981
+
982
+ enumeration_spec(
983
+ "Monthly on the third the to last day of the month forever (RFC 2445 p 121)",
984
+ "19970928T090000",
985
+ "US-Eastern",
986
+ "FREQ=MONTHLY;BYMONTHDAY=-3",
987
+ [
988
+ "Sep 28, 1997 9:00 AM EDT",
989
+ "Oct 29, 1997 9:00 AM EDT",
990
+ "Nov 28, 1997 9:00 AM EST",
991
+ "Dec 29, 1997 9:00 AM EST",
992
+ "Jan 29, 1998 9:00 AM EST",
993
+ "Feb 26, 1998 9:00 AM EST",
994
+ "..."
995
+ ]
996
+ )
997
+
998
+ enumeration_spec(
999
+ "Monthly on the first and last day of the month for 10 occurrences (RFC 2445 p 121)",
1000
+ "19970930T090000",
1001
+ "US-Eastern",
1002
+ "FREQ=MONTHLY;COUNT=10;BYMONTHDAY=1,-1",
1003
+ [
1004
+ "Sep 30, 1997 9:00 AM EDT",
1005
+ "Oct 1, 1997 9:00 AM EDT",
1006
+ "Oct 31, 1997 9:00 AM EST",
1007
+ "Nov 1, 1997 9:00 AM EST",
1008
+ "Nov 30, 1997 9:00 AM EST",
1009
+ "Dec 1, 1997 9:00 AM EST",
1010
+ "Dec 31, 1997 9:00 AM EST",
1011
+ "Jan 1, 1998 9:00 AM EST",
1012
+ "Jan 31, 1998 9:00 AM EST",
1013
+ "Feb 1, 1998 9:00 AM EST"
1014
+ ]
1015
+ )
1016
+
1017
+ enumeration_spec(
1018
+ "Every 18 months on the 10th thru 15th of the month for 10 occurrences (RFC 2445 p 121)",
1019
+ "19970910T090000",
1020
+ "US-Eastern",
1021
+ "FREQ=MONTHLY;INTERVAL=18;COUNT=10;BYMONTHDAY=10,11,12,13,14,15",
1022
+ [
1023
+ "Sep 10, 1997 9:00 AM EDT",
1024
+ "Sep 11, 1997 9:00 AM EDT",
1025
+ "Sep 12, 1997 9:00 AM EDT",
1026
+ "Sep 13, 1997 9:00 AM EDT",
1027
+ "Sep 14, 1997 9:00 AM EDT",
1028
+ "Sep 15, 1997 9:00 AM EDT",
1029
+ "Mar 10, 1999 9:00 AM EDT",
1030
+ "Mar 11, 1999 9:00 AM EDT",
1031
+ "Mar 12, 1999 9:00 AM EDT",
1032
+ "Mar 13, 1999 9:00 AM EDT"
1033
+ ]
1034
+ )
1035
+
1036
+ enumeration_spec(
1037
+ "Every Tuesday, every other month (RFC 2445 p 122)",
1038
+ "19970902T090000",
1039
+ "US-Eastern",
1040
+ "FREQ=MONTHLY;INTERVAL=2;BYDAY=TU",
1041
+ [
1042
+ "Sep 2, 1997 9:00 AM EDT",
1043
+ "Sep 9, 1997 9:00 AM EDT",
1044
+ "Sep 16, 1997 9:00 AM EDT",
1045
+ "Sep 23, 1997 9:00 AM EDT",
1046
+ "Sep 30, 1997 9:00 AM EDT",
1047
+ "Nov 4, 1997 9:00 AM EST",
1048
+ "Nov 11, 1997 9:00 AM EST",
1049
+ "Nov 18, 1997 9:00 AM EST",
1050
+ "Nov 25, 1997 9:00 AM EST",
1051
+ "Jan 6, 1998 9:00 AM EST",
1052
+ "Jan 13, 1998 9:00 AM EST",
1053
+ "Jan 20, 1998 9:00 AM EST",
1054
+ "Jan 27, 1998 9:00 AM EST",
1055
+ "Mar 3, 1998 9:00 AM EST",
1056
+ "Mar 10, 1998 9:00 AM EST",
1057
+ "Mar 17, 1998 9:00 AM EST",
1058
+ "Mar 24, 1998 9:00 AM EST",
1059
+ "Mar 31, 1998 9:00 AM EST",
1060
+ "..."
1061
+ ]
1062
+ )
1063
+
1064
+ enumeration_spec(
1065
+ "Yearly in June and July for 10 occurrences (RFC 2445 p 122)",
1066
+ "19970610T090000",
1067
+ "US-Eastern",
1068
+ "FREQ=YEARLY;COUNT=10;BYMONTH=6,7",
1069
+ [
1070
+ "Jun 10, 1997 9:00 AM EDT",
1071
+ "Jul 10, 1997 9:00 AM EDT",
1072
+ "Jun 10, 1998 9:00 AM EDT",
1073
+ "Jul 10, 1998 9:00 AM EDT",
1074
+ "Jun 10, 1999 9:00 AM EDT",
1075
+ "Jul 10, 1999 9:00 AM EDT",
1076
+ "Jun 10, 2000 9:00 AM EDT",
1077
+ "Jul 10, 2000 9:00 AM EDT",
1078
+ "Jun 10, 2001 9:00 AM EDT",
1079
+ "Jul 10, 2001 9:00 AM EDT"
1080
+ ]
1081
+ )
1082
+
1083
+ enumeration_spec(
1084
+ "Every other year on January, February, and March for 10 occurrences (RFC 2445 p 122)",
1085
+ "19970310T090000",
1086
+ "US-Eastern",
1087
+ "FREQ=YEARLY;INTERVAL=2;COUNT=10;BYMONTH=1,2,3",
1088
+ [
1089
+ "Mar 10, 1997 9:00 AM EST",
1090
+ "Jan 10, 1999 9:00 AM EST",
1091
+ "Feb 10, 1999 9:00 AM EST",
1092
+ "Mar 10, 1999 9:00 AM EST",
1093
+ "Jan 10, 2001 9:00 AM EST",
1094
+ "Feb 10, 2001 9:00 AM EST",
1095
+ "Mar 10, 2001 9:00 AM EST",
1096
+ "Jan 10, 2003 9:00 AM EST",
1097
+ "Feb 10, 2003 9:00 AM EST",
1098
+ "Mar 10, 2003 9:00 AM EST",
1099
+ ]
1100
+ )
1101
+
1102
+ enumeration_spec(
1103
+ "Every 3rd year on the 1st, 100th and 200th day for 10 occurrences (RFC 2445 p 122)",
1104
+ "19970101T090000",
1105
+ "US-Eastern",
1106
+ "FREQ=YEARLY;INTERVAL=3;COUNT=10;BYYEARDAY=1,100,200",
1107
+ [
1108
+ "Jan 1, 1997 9:00 AM EST",
1109
+ "Apr 10, 1997 9:00 AM EDT",
1110
+ "Jul 19, 1997 9:00 AM EDT",
1111
+ "Jan 1, 2000 9:00 AM EST",
1112
+ "Apr 9, 2000 9:00 AM EDT",
1113
+ "Jul 18, 2000 9:00 AM EDT",
1114
+ "Jan 1, 2003 9:00 AM EST",
1115
+ "Apr 10, 2003 9:00 AM EDT",
1116
+ "Jul 19, 2003 9:00 AM EDT",
1117
+ "Jan 1, 2006 9:00 AM EST"
1118
+ ]
1119
+ )
1120
+
1121
+ enumeration_spec(
1122
+ "Every 20th Monday of the year, forever (RFC 2445 p 122-3)",
1123
+ "19970519T090000",
1124
+ "US-Eastern",
1125
+ "FREQ=YEARLY;BYDAY=20MO",
1126
+ [
1127
+ "May 19, 1997 9:00 AM EDT",
1128
+ "May 18, 1998 9:00 AM EDT",
1129
+ "May 17, 1999 9:00 AM EDT",
1130
+ "..."
1131
+ ]
1132
+ )
1133
+
1134
+ enumeration_spec(
1135
+ "Every second to last Wednesday of the year, forever",
1136
+ "19971224T090000",
1137
+ "US-Eastern",
1138
+ "FREQ=YEARLY;BYDAY=-2WE",
1139
+ [
1140
+ "Dec 24, 1997 9:00 AM EDT",
1141
+ "Dec 23, 1998 9:00 AM EDT",
1142
+ "Dec 22, 1999 9:00 AM EDT",
1143
+ "Dec 20, 2000 9:00 AM EDT",
1144
+ "..."
1145
+ ]
1146
+ )
1147
+
1148
+ enumeration_spec(
1149
+ "Monday of week number 20 (where the default start of the week is Monday), forever (RFC 2445 p 123)",
1150
+ "19970512T090000",
1151
+ "US-Eastern",
1152
+ "FREQ=YEARLY;BYWEEKNO=20;BYDAY=MO",
1153
+ [
1154
+ "May 12, 1997 9:00 AM EDT",
1155
+ "May 11, 1998 9:00 AM EDT",
1156
+ "May 17, 1999 9:00 AM EDT",
1157
+ "..."
1158
+ ]
1159
+ )
1160
+
1161
+ enumeration_spec(
1162
+ "Every Thursday in March, forever (RFC 2445 p 123)",
1163
+ "19970313T090000",
1164
+ "US-Eastern",
1165
+ "FREQ=YEARLY;BYMONTH=3;BYDAY=TH",
1166
+ [
1167
+ "Mar 13, 1997 9:00 AM EST",
1168
+ "Mar 20, 1997 9:00 AM EST",
1169
+ "Mar 27, 1997 9:00 AM EST",
1170
+ "Mar 5, 1998 9:00 AM EST",
1171
+ "Mar 12, 1998 9:00 AM EST",
1172
+ "Mar 19, 1998 9:00 AM EST",
1173
+ "Mar 26, 1998 9:00 AM EST",
1174
+ "Mar 4, 1999 9:00 AM EST",
1175
+ "Mar 11, 1999 9:00 AM EST",
1176
+ "Mar 18, 1999 9:00 AM EST",
1177
+ "Mar 25, 1999 9:00 AM EST",
1178
+ "..."
1179
+ ]
1180
+ )
1181
+
1182
+ enumeration_spec(
1183
+ "Every Thursday, but only during June, July, and August, forever (RFC 2445 p 123)",
1184
+ "19970605T090000",
1185
+ "US-Eastern",
1186
+ "FREQ=YEARLY;BYDAY=TH;BYMONTH=6,7,8",
1187
+ [
1188
+ "Jun 05, 1997 9:00 AM EDT",
1189
+ "Jun 12, 1997 9:00 AM EDT",
1190
+ "Jun 19, 1997 9:00 AM EDT",
1191
+ "Jun 26, 1997 9:00 AM EDT",
1192
+ "Jul 03, 1997 9:00 AM EDT",
1193
+ "Jul 10, 1997 9:00 AM EDT",
1194
+ "Jul 17, 1997 9:00 AM EDT",
1195
+ "Jul 24, 1997 9:00 AM EDT",
1196
+ "Jul 31, 1997 9:00 AM EDT",
1197
+ "Aug 07, 1997 9:00 AM EDT",
1198
+ "Aug 14, 1997 9:00 AM EDT",
1199
+ "Aug 21, 1997 9:00 AM EDT",
1200
+ "Aug 28, 1997 9:00 AM EDT",
1201
+ "Jun 04, 1998 9:00 AM EDT",
1202
+ "Jun 11, 1998 9:00 AM EDT",
1203
+ "Jun 18, 1998 9:00 AM EDT",
1204
+ "Jun 25, 1998 9:00 AM EDT",
1205
+ "Jul 02, 1998 9:00 AM EDT",
1206
+ "Jul 09, 1998 9:00 AM EDT",
1207
+ "Jul 16, 1998 9:00 AM EDT",
1208
+ "Jul 23, 1998 9:00 AM EDT",
1209
+ "Jul 30, 1998 9:00 AM EDT",
1210
+ "Aug 06, 1998 9:00 AM EDT",
1211
+ "Aug 13, 1998 9:00 AM EDT",
1212
+ "Aug 20, 1998 9:00 AM EDT",
1213
+ "Aug 27, 1998 9:00 AM EDT",
1214
+ "Jun 03, 1999 9:00 AM EDT",
1215
+ "Jun 10, 1999 9:00 AM EDT",
1216
+ "Jun 17, 1999 9:00 AM EDT",
1217
+ "Jun 24, 1999 9:00 AM EDT",
1218
+ "Jul 01, 1999 9:00 AM EDT",
1219
+ "Jul 08, 1999 9:00 AM EDT",
1220
+ "Jul 15, 1999 9:00 AM EDT",
1221
+ "Jul 22, 1999 9:00 AM EDT",
1222
+ "Jul 29, 1999 9:00 AM EDT",
1223
+ "Aug 05, 1999 9:00 AM EDT",
1224
+ "Aug 12, 1999 9:00 AM EDT",
1225
+ "Aug 19, 1999 9:00 AM EDT",
1226
+ "Aug 26, 1999 9:00 AM EDT",
1227
+ "..."
1228
+ ]
1229
+ )
1230
+
1231
+ enumeration_spec(
1232
+ "Every Friday the 13th, forever (RFC 2445 p 123-4)",
1233
+ "19970902T090000",
1234
+ "US-Eastern",
1235
+ "FREQ=MONTHLY;BYDAY=FR;BYMONTHDAY=13",
1236
+ [
1237
+ # The RFC example uses exdate to exclude the start date, this is a slightly altered
1238
+ # use case
1239
+ "Sep 2, 1997 9:00 AM EST",
1240
+ "Feb 13, 1998 9:00 AM EST",
1241
+ "Mar 13, 1998 9:00 AM EST",
1242
+ "Nov 13, 1998 9:00 AM EST",
1243
+ "Aug 13, 1999 9:00 AM EDT",
1244
+ "Oct 13, 2000 9:00 AM EST",
1245
+ "..."
1246
+ ]
1247
+ )
1248
+
1249
+ enumeration_spec(
1250
+ "The first Saturday that follows the first Sunday of the month, forever (RFC 2445 p 124)",
1251
+ "19970913T090000",
1252
+ "US-Eastern",
1253
+ "FREQ=MONTHLY;BYDAY=SA;BYMONTHDAY=7,8,9,10,11,12,13",
1254
+ [
1255
+ "Sep 13, 1997 9:00 AM EDT",
1256
+ "Oct 11, 1997 9:00 AM EDT",
1257
+ "Nov 8, 1997 9:00 AM EST",
1258
+ "Dec 13, 1997 9:00 AM EST",
1259
+ "Jan 10, 1998 9:00 AM EST",
1260
+ "Feb 7, 1998 9:00 AM EST",
1261
+ "Mar 7, 1998 9:00 AM EST",
1262
+ "Apr 11, 1998 9:00 AM EDT",
1263
+ "May 9, 1998 9:00 AM EDT",
1264
+ "Jun 13, 1998 9:00 AM EDT",
1265
+ "..."
1266
+ ]
1267
+ )
1268
+
1269
+ enumeration_spec(
1270
+ "Every four years, the first Tuesday after a Monday in November, forever(U.S. Presidential Election day) (RFC 2445 p 124)",
1271
+ "19961105T090000",
1272
+ "US-Eastern",
1273
+ "FREQ=YEARLY;INTERVAL=4;BYMONTH=11;BYDAY=TU;BYMONTHDAY=2,3,4,5,6,7,8",
1274
+ [
1275
+ "Nov 5, 1996 9:00 AM EDT",
1276
+ "Nov 7, 2000 9:00 AM EDT",
1277
+ "Nov 2, 2004 9:00 AM EDT",
1278
+ "..."
1279
+ ]
1280
+ )
1281
+
1282
+ enumeration_spec(
1283
+ "3rd instance into the month of one of Tuesday, Wednesday or Thursday, for the next 3 months (RFC 2445 p 124)",
1284
+ "19970904T090000",
1285
+ "US-Eastern",
1286
+ "FREQ=MONTHLY;COUNT=3;BYDAY=TU,WE,TH;BYSETPOS=3",
1287
+ [
1288
+ "Sep 4, 1997 9:00 AM EDT",
1289
+ "Oct 7, 1997 9:00 AM EDT",
1290
+ "Nov 6, 1997 9:00 AM EST",
1291
+ ]
1292
+ )
1293
+
1294
+ enumeration_spec(
1295
+ "The 2nd to last weekday of the month (RFC 2445 p 124)",
1296
+ "19970929T090000",
1297
+ "US-Eastern",
1298
+ "FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-2",
1299
+ [
1300
+ "Sep 29, 1997 9:00 AM EDT",
1301
+ "Oct 30, 1997 9:00 AM EST",
1302
+ "Nov 27, 1997 9:00 AM EST",
1303
+ "Dec 30, 1997 9:00 AM EST",
1304
+ "Jan 29, 1998 9:00 AM EST",
1305
+ "Feb 26, 1998 9:00 AM EST",
1306
+ "Mar 30, 1998 9:00 AM EST",
1307
+ "..."
1308
+ ]
1309
+ )
1310
+
1311
+ enumeration_spec(
1312
+ "Every 3 hours from 9:00 AM to 5:00 PM on a specific day (RFC 2445 p 125)",
1313
+ "19970902T090000",
1314
+ "US-Eastern",
1315
+ "FREQ=HOURLY;INTERVAL=3;UNTIL=19970902T170000Z",
1316
+ [
1317
+ "Sep 2, 1997 9:00 EDT",
1318
+ "Sep 2, 1997 12:00 EDT",
1319
+ "Sep 2, 1997 15:00 EDT",
1320
+ ]
1321
+ )
1322
+
1323
+ enumeration_spec(
1324
+ "Every 15 minutes for 6 occurrences (RFC 2445 p 125)",
1325
+ "19970902T090000",
1326
+ "US-Eastern",
1327
+ "FREQ=MINUTELY;INTERVAL=15;COUNT=6",
1328
+ [
1329
+ "Sep 2, 1997 09:00 EDT",
1330
+ "Sep 2, 1997 09:15 EDT",
1331
+ "Sep 2, 1997 09:30 EDT",
1332
+ "Sep 2, 1997 09:45 EDT",
1333
+ "Sep 2, 1997 10:00 EDT",
1334
+ "Sep 2, 1997 10:15 EDT",
1335
+ ]
1336
+ )
1337
+
1338
+ enumeration_spec(
1339
+ "Every hour and a half for 4 occurrences (RFC 2445 p 125)",
1340
+ "19970902T090000",
1341
+ "US-Eastern",
1342
+ "FREQ=MINUTELY;INTERVAL=90;COUNT=4",
1343
+ [
1344
+ "Sep 2, 1997 09:00 EDT",
1345
+ "Sep 2, 1997 10:30 EDT",
1346
+ "Sep 2, 1997 12:00 EDT",
1347
+ "Sep 2, 1997 13:30 EDT",
1348
+ ]
1349
+ )
1350
+
1351
+ enumeration_spec(
1352
+ "Every 20 minutes from 9:00 AM to 4:40 PM every day - alternative 1 (RFC 2445 p 125)",
1353
+ "19970902T090000",
1354
+ "US-Eastern",
1355
+ "FREQ=DAILY;BYHOUR=9,10,11,12,13,14,15,16;BYMINUTE=0,20,40",
1356
+ [
1357
+ "Sep 2, 1997 09:00 EDT",
1358
+ "Sep 2, 1997 09:20 EDT",
1359
+ "Sep 2, 1997 09:40 EDT",
1360
+ "Sep 2, 1997 10:00 EDT",
1361
+ "Sep 2, 1997 10:20 EDT",
1362
+ "Sep 2, 1997 10:40 EDT",
1363
+ "Sep 2, 1997 11:00 EDT",
1364
+ "Sep 2, 1997 11:20 EDT",
1365
+ "Sep 2, 1997 11:40 EDT",
1366
+ "Sep 2, 1997 12:00 EDT",
1367
+ "Sep 2, 1997 12:20 EDT",
1368
+ "Sep 2, 1997 12:40 EDT",
1369
+ "Sep 2, 1997 13:00 EDT",
1370
+ "Sep 2, 1997 13:20 EDT",
1371
+ "Sep 2, 1997 13:40 EDT",
1372
+ "Sep 2, 1997 14:00 EDT",
1373
+ "Sep 2, 1997 14:20 EDT",
1374
+ "Sep 2, 1997 14:40 EDT",
1375
+ "Sep 2, 1997 15:00 EDT",
1376
+ "Sep 2, 1997 15:20 EDT",
1377
+ "Sep 2, 1997 15:40 EDT",
1378
+ "Sep 2, 1997 16:00 EDT",
1379
+ "Sep 2, 1997 16:20 EDT",
1380
+ "Sep 2, 1997 16:40 EDT",
1381
+ "Sep 3, 1997 09:00 EDT",
1382
+ "Sep 3, 1997 09:20 EDT",
1383
+ "Sep 3, 1997 09:40 EDT",
1384
+ "Sep 3, 1997 10:00 EDT",
1385
+ "Sep 3, 1997 10:20 EDT",
1386
+ "Sep 3, 1997 10:40 EDT",
1387
+ "Sep 3, 1997 11:00 EDT",
1388
+ "Sep 3, 1997 11:20 EDT",
1389
+ "Sep 3, 1997 11:40 EDT",
1390
+ "Sep 3, 1997 12:00 EDT",
1391
+ "Sep 3, 1997 12:20 EDT",
1392
+ "Sep 3, 1997 12:40 EDT",
1393
+ "Sep 3, 1997 13:00 EDT",
1394
+ "Sep 3, 1997 13:20 EDT",
1395
+ "Sep 3, 1997 13:40 EDT",
1396
+ "Sep 3, 1997 14:00 EDT",
1397
+ "Sep 3, 1997 14:20 EDT",
1398
+ "Sep 3, 1997 14:40 EDT",
1399
+ "Sep 3, 1997 15:00 EDT",
1400
+ "Sep 3, 1997 15:20 EDT",
1401
+ "Sep 3, 1997 15:40 EDT",
1402
+ "Sep 3, 1997 16:00 EDT",
1403
+ "Sep 3, 1997 16:20 EDT",
1404
+ "Sep 3, 1997 16:40 EDT",
1405
+ "..."
1406
+ ]
1407
+ )
1408
+
1409
+ enumeration_spec(
1410
+ "Every 20 minutes from 9:00 AM to 4:40 PM every day - alternative 2 (RFC 2445 p 125)",
1411
+ "19970902T090000",
1412
+ "US-Eastern",
1413
+ "FREQ=MINUTELY;INTERVAL=20;BYHOUR=9,10,11,12,13,14,15,16",
1414
+ [
1415
+ "Sep 2, 1997 09:00 EDT",
1416
+ "Sep 2, 1997 09:20 EDT",
1417
+ "Sep 2, 1997 09:40 EDT",
1418
+ "Sep 2, 1997 10:00 EDT",
1419
+ "Sep 2, 1997 10:20 EDT",
1420
+ "Sep 2, 1997 10:40 EDT",
1421
+ "Sep 2, 1997 11:00 EDT",
1422
+ "Sep 2, 1997 11:20 EDT",
1423
+ "Sep 2, 1997 11:40 EDT",
1424
+ "Sep 2, 1997 12:00 EDT",
1425
+ "Sep 2, 1997 12:20 EDT",
1426
+ "Sep 2, 1997 12:40 EDT",
1427
+ "Sep 2, 1997 13:00 EDT",
1428
+ "Sep 2, 1997 13:20 EDT",
1429
+ "Sep 2, 1997 13:40 EDT",
1430
+ "Sep 2, 1997 14:00 EDT",
1431
+ "Sep 2, 1997 14:20 EDT",
1432
+ "Sep 2, 1997 14:40 EDT",
1433
+ "Sep 2, 1997 15:00 EDT",
1434
+ "Sep 2, 1997 15:20 EDT",
1435
+ "Sep 2, 1997 15:40 EDT",
1436
+ "Sep 2, 1997 16:00 EDT",
1437
+ "Sep 2, 1997 16:20 EDT",
1438
+ "Sep 2, 1997 16:40 EDT",
1439
+ "Sep 3, 1997 09:00 EDT",
1440
+ "Sep 3, 1997 09:20 EDT",
1441
+ "Sep 3, 1997 09:40 EDT",
1442
+ "Sep 3, 1997 10:00 EDT",
1443
+ "Sep 3, 1997 10:20 EDT",
1444
+ "Sep 3, 1997 10:40 EDT",
1445
+ "Sep 3, 1997 11:00 EDT",
1446
+ "Sep 3, 1997 11:20 EDT",
1447
+ "Sep 3, 1997 11:40 EDT",
1448
+ "Sep 3, 1997 12:00 EDT",
1449
+ "Sep 3, 1997 12:20 EDT",
1450
+ "Sep 3, 1997 12:40 EDT",
1451
+ "Sep 3, 1997 13:00 EDT",
1452
+ "Sep 3, 1997 13:20 EDT",
1453
+ "Sep 3, 1997 13:40 EDT",
1454
+ "Sep 3, 1997 14:00 EDT",
1455
+ "Sep 3, 1997 14:20 EDT",
1456
+ "Sep 3, 1997 14:40 EDT",
1457
+ "Sep 3, 1997 15:00 EDT",
1458
+ "Sep 3, 1997 15:20 EDT",
1459
+ "Sep 3, 1997 15:40 EDT",
1460
+ "Sep 3, 1997 16:00 EDT",
1461
+ "Sep 3, 1997 16:20 EDT",
1462
+ "Sep 3, 1997 16:40 EDT",
1463
+ "..."
1464
+ ]
1465
+ )
1466
+
1467
+ enumeration_spec(
1468
+ "An example where the days generated makes a difference because of WKST (MO case) (RFC 2445 p 125)",
1469
+ "19970805T090000",
1470
+ "US-Eastern",
1471
+ "FREQ=WEEKLY;INTERVAL=2;COUNT=4;BYDAY=TU,SU;WKST=MO",
1472
+ [
1473
+ "Aug 05, 1997 09:00 EDT",
1474
+ "Aug 10, 1997 09:00 EDT",
1475
+ "Aug 19, 1997 09:00 EDT",
1476
+ "Aug 24, 1997 09:00 EDT"
1477
+ ]
1478
+ )
1479
+
1480
+ enumeration_spec(
1481
+ "An example where the days generated makes a difference because of WKST (MO case) (RFC 2445 p 125)",
1482
+ "19970805T090000",
1483
+ "US-Eastern",
1484
+ "FREQ=WEEKLY;INTERVAL=2;COUNT=4;BYDAY=TU,SU;WKST=SU",
1485
+ [
1486
+ "Aug 05, 1997 09:00 EDT",
1487
+ "Aug 17, 1997 09:00 EDT",
1488
+ "Aug 19, 1997 09:00 EDT",
1489
+ "Aug 31, 1997 09:00 EDT"
1490
+ ]
1491
+ )
1492
+ end
1493
+ end
1494
+
1495
+ describe RiCal::PropertyValue::RecurrenceRule::RecurringDay do
1496
+
1497
+ def recurring(day)
1498
+ RiCal::PropertyValue::RecurrenceRule::RecurringDay.new(day, RiCal::PropertyValue::RecurrenceRule.new(nil, :value => "FREQ=MONTHLY"))
1499
+ end
1500
+
1501
+ describe "MO - any monday" do
1502
+ before(:each) do
1503
+ @it= recurring("MO")
1504
+ end
1505
+
1506
+ it "should include all Mondays" do
1507
+ [1, 8, 15, 22, 29].each do | day |
1508
+ @it.should include(Date.parse("Dec #{day} 2008"))
1509
+ end
1510
+ end
1511
+
1512
+ it "should not include non-Mondays" do
1513
+ (9..14).each do | day |
1514
+ @it.should_not include(Date.parse("Dec #{day} 2008"))
1515
+ end
1516
+ end
1517
+ end
1518
+
1519
+ describe "TU - any Tuesday" do
1520
+ before(:each) do
1521
+ @it= recurring("TU")
1522
+ end
1523
+
1524
+ it "should include all Tuesdays" do
1525
+ [2, 9, 16, 23, 30].each do | day |
1526
+ @it.should include(Date.parse("Dec #{day} 2008"))
1527
+ end
1528
+ end
1529
+
1530
+ it "should not include non-Tuesdays" do
1531
+ (10..15).each do | day |
1532
+ @it.should_not include(Date.parse("Dec #{day} 2008"))
1533
+ end
1534
+ end
1535
+ end
1536
+
1537
+ describe "WE - any Wednesday" do
1538
+ before(:each) do
1539
+ @it= recurring("WE")
1540
+ end
1541
+
1542
+ it "should include all Wednesdays" do
1543
+ [3, 10, 17, 24, 31].each do | day |
1544
+ @it.should include(Date.parse("Dec #{day} 2008"))
1545
+ end
1546
+ end
1547
+
1548
+ it "should not include non-Wednesdays" do
1549
+ (11..16).each do | day |
1550
+ @it.should_not include(Date.parse("Dec #{day} 2008"))
1551
+ end
1552
+ end
1553
+ end
1554
+
1555
+ describe "TH - any Thursday" do
1556
+ before(:each) do
1557
+ @it= recurring("TH")
1558
+ end
1559
+
1560
+ it "should include all Thursdays" do
1561
+ [4, 11, 18, 25].each do | day |
1562
+ @it.should include(Date.parse("Dec #{day} 2008"))
1563
+ end
1564
+ end
1565
+
1566
+ it "should not include non-Thursdays" do
1567
+ (5..10).each do | day |
1568
+ @it.should_not include(Date.parse("Dec #{day} 2008"))
1569
+ end
1570
+ end
1571
+ end
1572
+
1573
+ describe "FR - any Friday" do
1574
+ before(:each) do
1575
+ @it= recurring("FR")
1576
+ end
1577
+
1578
+ it "should include all Fridays" do
1579
+ [5, 12, 19, 26].each do | day |
1580
+ @it.should include(Date.parse("Dec #{day} 2008"))
1581
+ end
1582
+ end
1583
+
1584
+ it "should not include non-Fridays" do
1585
+ (6..11).each do | day |
1586
+ @it.should_not include(Date.parse("Dec #{day} 2008"))
1587
+ end
1588
+ end
1589
+ end
1590
+
1591
+ describe "SA - any Saturday" do
1592
+ before(:each) do
1593
+ @it= recurring("SA")
1594
+ end
1595
+
1596
+ it "should include all Saturdays" do
1597
+ [6, 13, 20, 27].each do | day |
1598
+ @it.should include(Date.parse("Dec #{day} 2008"))
1599
+ end
1600
+ end
1601
+
1602
+ it "should not include non-Saturdays" do
1603
+ (7..12).each do | day |
1604
+ @it.should_not include(Date.parse("Dec #{day} 2008"))
1605
+ end
1606
+ end
1607
+ end
1608
+
1609
+ describe "SU - any Sunday" do
1610
+ before(:each) do
1611
+ @it= recurring("SU")
1612
+ end
1613
+
1614
+ it "should include all Sundays" do
1615
+ [7, 14, 21, 28].each do | day |
1616
+ @it.should include(Date.parse("Dec #{day} 2008"))
1617
+ end
1618
+ end
1619
+
1620
+ it "should not include non-Saturdays" do
1621
+ (8..13).each do | day |
1622
+ @it.should_not include(Date.parse("Dec #{day} 2008"))
1623
+ end
1624
+ end
1625
+ end
1626
+
1627
+ describe "1MO - first Monday" do
1628
+ before(:each) do
1629
+ @it = recurring("1MO")
1630
+ end
1631
+
1632
+ it "should match the first Monday of the month" do
1633
+ @it.should include(Date.parse("Nov 3 2008"))
1634
+ end
1635
+
1636
+ it "should not include other Mondays" do
1637
+ [10, 17, 24].each do |day|
1638
+ @it.should_not include(Date.parse("Nov #{day} 2008"))
1639
+ end
1640
+ end
1641
+ end
1642
+
1643
+ describe "5MO - Fifth Monday" do
1644
+ before(:each) do
1645
+ @it = recurring("5MO")
1646
+ end
1647
+
1648
+ it "should match the fifth Monday of a month with five Mondays" do
1649
+ @it.should include(Date.parse("Dec 29 2008"))
1650
+ end
1651
+ end
1652
+
1653
+ describe "-1MO - last Monday" do
1654
+ before(:each) do
1655
+ @it = recurring("-1MO")
1656
+ end
1657
+
1658
+ it "should match the last Monday of the month" do
1659
+ @it.should include(Date.parse("Dec 29 2008"))
1660
+ end
1661
+
1662
+ it "should not include other Mondays" do
1663
+ [1, 8, 15, 22].each do |day|
1664
+ @it.should_not include(Date.parse("Dec #{day} 2008"))
1665
+ end
1666
+ end
1667
+
1668
+ it "should match February 28 for a non leap year when appropriate" do
1669
+ @it.should include(Date.parse("Feb 28 2005"))
1670
+ end
1671
+
1672
+ it "should match February 29 for a non leap year when appropriate" do
1673
+ @it.should include(Date.parse("Feb 29 1988"))
1674
+ end
1675
+ end
1676
+ end
1677
+
1678
+ describe RiCal::PropertyValue::RecurrenceRule::RecurringMonthDay do
1679
+
1680
+ describe "with a value of 1" do
1681
+ before(:each) do
1682
+ @it = RiCal::PropertyValue::RecurrenceRule::RecurringMonthDay.new(1)
1683
+ end
1684
+
1685
+ it "should match the first of each month" do
1686
+ (1..12).each do |month|
1687
+ @it.should include(Date.new(2008, month, 1))
1688
+ end
1689
+ end
1690
+
1691
+ it "should not match other days of the month" do
1692
+ (2..31).each do |day|
1693
+ @it.should_not include(Date.new(2008, 1, day))
1694
+ end
1695
+ end
1696
+
1697
+ describe "with a value of -1" do
1698
+ before(:each) do
1699
+ @it = RiCal::PropertyValue::RecurrenceRule::RecurringMonthDay.new(-1)
1700
+ end
1701
+
1702
+ it "should match the last of each month" do
1703
+ {
1704
+ 1 => 31, 2 => 29, 3 => 31, 4 => 30, 5 => 31, 6 => 30, 7 => 31,
1705
+ 8 => 31, 9 => 30, 10 => 31, 11 => 30, 12 => 31
1706
+ }.each do |month, last|
1707
+ @it.should include(Date.new(2008, month, last))
1708
+ end
1709
+ @it.should include(Date.new(2007, 2, 28))
1710
+ end
1711
+
1712
+ it "should not match other days of the month" do
1713
+ (1..30).each do |day|
1714
+ @it.should_not include(Date.new(2008, 1, day))
1715
+ end
1716
+ end
1717
+ end
1718
+ end
1719
+ end
1720
+
1721
+ describe RiCal::PropertyValue::RecurrenceRule::RecurringYearDay do
1722
+
1723
+ describe "with a value of 20" do
1724
+ before(:each) do
1725
+ @it = RiCal::PropertyValue::RecurrenceRule::RecurringYearDay.new(20)
1726
+ end
1727
+
1728
+ it "should include January 20 in a non-leap year" do
1729
+ @it.should include(Date.new(2007, 1, 20))
1730
+ end
1731
+
1732
+ it "should include January 20 in a leap year" do
1733
+ @it.should include(Date.new(2008, 1, 20))
1734
+ end
1735
+ end
1736
+
1737
+ describe "with a value of 60" do
1738
+ before(:each) do
1739
+ @it = RiCal::PropertyValue::RecurrenceRule::RecurringYearDay.new(60)
1740
+ end
1741
+
1742
+ it "should include March 1 in a non-leap year" do
1743
+ @it.should include(Date.new(2007, 3, 1))
1744
+ end
1745
+
1746
+ it "should include February 29 in a leap year" do
1747
+ @it.should include(Date.new(2008, 2, 29))
1748
+ end
1749
+ end
1750
+
1751
+ describe "with a value of -1" do
1752
+ before(:each) do
1753
+ @it = RiCal::PropertyValue::RecurrenceRule::RecurringYearDay.new(-1)
1754
+ end
1755
+
1756
+ it "should include December 31 in a non-leap year" do
1757
+ @it.should include(Date.new(2007,12, 31))
1758
+ end
1759
+
1760
+ it "should include December 31 in a leap year" do
1761
+ @it.should include(Date.new(2008,12, 31))
1762
+ end
1763
+ end
1764
+
1765
+ describe "with a value of -365" do
1766
+ before(:each) do
1767
+ @it = RiCal::PropertyValue::RecurrenceRule::RecurringYearDay.new(-365)
1768
+ end
1769
+
1770
+ it "should include January 1 in a non-leap year" do
1771
+ @it.should include(Date.new(2007,1, 1))
1772
+ end
1773
+
1774
+ it "should include January 2 in a leap year" do
1775
+ @it.should include(Date.new(2008,1, 2))
1776
+ end
1777
+ end
1778
+
1779
+ describe "with a value of -366" do
1780
+ before(:each) do
1781
+ @it = RiCal::PropertyValue::RecurrenceRule::RecurringYearDay.new(-366)
1782
+ end
1783
+
1784
+ it "should not include January 1 in a non-leap year" do
1785
+ @it.should_not include(Date.new(2007,1, 1))
1786
+ end
1787
+
1788
+ it "should include January 1 in a leap year" do
1789
+ @it.should include(Date.new(2008,1, 1))
1790
+ end
1791
+ end
1792
+ end
1793
+
1794
+ describe RiCal::PropertyValue::RecurrenceRule::RecurringNumberedWeek do
1795
+ before(:each) do
1796
+ @it = RiCal::PropertyValue::RecurrenceRule::RecurringNumberedWeek.new(50)
1797
+ end
1798
+
1799
+ it "should not include Dec 10, 2000" do
1800
+ @it.should_not include(Date.new(2000, 12, 10))
1801
+ end
1802
+
1803
+ it "should include Dec 11, 2000" do
1804
+ @it.should include(Date.new(2000, 12, 11))
1805
+ end
1806
+
1807
+ it "should include Dec 17, 2000" do
1808
+ @it.should include(Date.new(2000, 12, 17))
1809
+ end
1810
+
1811
+ it "should not include Dec 18, 2000" do
1812
+ @it.should_not include(Date.new(2000, 12, 18))
1813
+ end
1814
+ end