hiccup 0.0.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +9 -1
- data/hiccup.gemspec +8 -2
- data/lib/hiccup.rb +69 -1
- data/lib/hiccup/convenience.rb +28 -0
- data/lib/hiccup/core_ext/date.rb +29 -0
- data/lib/hiccup/core_ext/duration.rb +25 -0
- data/lib/hiccup/core_ext/fixnum.rb +37 -0
- data/lib/hiccup/enumerable.rb +230 -0
- data/lib/hiccup/humanizable.rb +68 -0
- data/lib/hiccup/schedule.rb +42 -0
- data/lib/hiccup/serializable/ical.rb +39 -0
- data/lib/hiccup/serializers/ical.rb +189 -0
- data/lib/hiccup/validatable.rb +110 -0
- data/lib/hiccup/version.rb +1 -1
- data/test/enumerable_test.rb +283 -0
- data/test/humanizable_test.rb +70 -0
- data/test/ical_serializable_test.rb +92 -0
- data/test/test_helper.rb +6 -0
- data/test/validatable_test.rb +81 -0
- metadata +68 -6
data/lib/hiccup/version.rb
CHANGED
@@ -0,0 +1,283 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
|
4
|
+
class EnumerableTest < ActiveSupport::TestCase
|
5
|
+
include Hiccup
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
def test_occurs_on_annually
|
10
|
+
schedule = Schedule.new({
|
11
|
+
:kind => :annually,
|
12
|
+
:start_date => Date.new(2009,3,15)})
|
13
|
+
assert !schedule.occurs_on(Date.new(1984,3,15)), "Annual schedule starting 3/15/09 should not occur on 3/15/1984"
|
14
|
+
assert schedule.occurs_on(Date.new(2084,3,15)), "Annual schedule starting 3/15/09 should occur on 3/15/2084"
|
15
|
+
assert !schedule.occurs_on(Date.new(2011,4,15)), "Annual schedule starting 3/15/09 should not occur on 4/15/2011"
|
16
|
+
assert !schedule.occurs_on(Date.new(2009,3,17)), "Annual schedule starting 3/15/09 should not occur on 3/17/2009"
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
def test_occurs_on_weekly
|
22
|
+
schedule = Schedule.new({
|
23
|
+
:kind => :weekly,
|
24
|
+
:pattern => %w{Monday Wednesday Friday},
|
25
|
+
:start_date => Date.new(2009,3,15)})
|
26
|
+
assert schedule.occurs_on(Date.new(2009,5,1)), "MWF schedule starting 3/15/09 should occur on 5/1/2009"
|
27
|
+
assert schedule.occurs_on(Date.new(2009,5,11)), "MWF schedule starting 3/15/09 should occur on 5/11/2009"
|
28
|
+
assert schedule.occurs_on(Date.new(2009,5,20)), "MWF schedule starting 3/15/09 should occur on 5/20/2009"
|
29
|
+
assert !schedule.occurs_on(Date.new(2009,3,15)), "MWF schedule starting 3/15/09 should not occur on 3/15/2009"
|
30
|
+
assert schedule.occurs_on(Date.new(2009,3,16)), "MWF schedule starting 3/15/09 should occur on 3/16/2009"
|
31
|
+
assert !schedule.occurs_on(Date.new(2009,3,11)), "MWF schedule starting 3/15/09 should not occur on 3/11/2009"
|
32
|
+
assert schedule.occurs_on(Date.new(2009,3,18)), "MWF schedule starting 3/15/09 should occur on 3/18/2009"
|
33
|
+
|
34
|
+
schedule.end_date = Date.new(2009,4,11)
|
35
|
+
schedule.ends = true
|
36
|
+
assert_equal true, schedule.ends?
|
37
|
+
assert !schedule.occurs_on(Date.new(2009,5,1)), "MWF schedule starting 3/15/09 and ending 4/11/09 should not occur on 5/1/2009"
|
38
|
+
assert !schedule.occurs_on(Date.new(2009,5,11)), "MWF schedule starting 3/15/09 and ending 4/11/09 should not occur on 5/11/2009"
|
39
|
+
assert !schedule.occurs_on(Date.new(2009,5,20)), "MWF schedule starting 3/15/09 and ending 4/11/09 should not occur on 5/20/2009"
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
|
44
|
+
def test_weekly_occurrences_during_month
|
45
|
+
schedule = Schedule.new({
|
46
|
+
:kind => :weekly,
|
47
|
+
:pattern => %w{Monday Wednesday Friday},
|
48
|
+
:start_date => Date.new(2009,3,15),
|
49
|
+
:ends => true,
|
50
|
+
:end_date => Date.new(2009,11,30)})
|
51
|
+
dates = schedule.occurrences_during_month(2009,7).map {|date| date.day}
|
52
|
+
expected_dates = [1,3,6,8,10,13,15,17,20,22,24,27,29,31]
|
53
|
+
assert_equal expected_dates, dates, "occurrences_during_month did not generate expected dates for weekly schedule"
|
54
|
+
|
55
|
+
dates = schedule.occurrences_during_month(2008,7).map {|date| date.day}
|
56
|
+
expected_dates = []
|
57
|
+
assert_equal expected_dates, dates, "occurrences_during_month should generate no occurrences if before start_date"
|
58
|
+
|
59
|
+
schedule = Schedule.new({
|
60
|
+
:kind => :weekly,
|
61
|
+
:pattern => %w{Monday},
|
62
|
+
:start_date => Date.new(2010,6,14),
|
63
|
+
:ends => true,
|
64
|
+
:end_date => Date.new(2010,6,21)})
|
65
|
+
dates = schedule.occurrences_during_month(2010,6).map {|date| date.day}
|
66
|
+
expected_dates = [14,21]
|
67
|
+
assert_equal expected_dates, dates, "occurrences_during_month did not correctly observe end date for weekly schedule"
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
|
72
|
+
def test_monthly_occurrences_during_month
|
73
|
+
schedule = Schedule.new({
|
74
|
+
:kind => :monthly,
|
75
|
+
:pattern => [[2, "Sunday"], [4, "Sunday"]],
|
76
|
+
:start_date => Date.new(2004,3,15)})
|
77
|
+
dates = schedule.occurrences_during_month(2009,12).map {|date| date.day}
|
78
|
+
expected_dates = [13,27]
|
79
|
+
assert_equal expected_dates, dates, "occurrences_during_month did not generate expected dates for monthly schedule"
|
80
|
+
|
81
|
+
dates = schedule.occurrences_during_month(2009,2).map {|date| date.day}
|
82
|
+
expected_dates = [8,22]
|
83
|
+
assert_equal expected_dates, dates, "occurrences_during_month did not generate expected dates for monthly schedule"
|
84
|
+
|
85
|
+
dates = schedule.occurrences_during_month(1991,7).map {|date| date.day}
|
86
|
+
expected_dates = []
|
87
|
+
assert_equal expected_dates, dates, "occurrences_during_month should generate no occurrences if before start_date"
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
|
92
|
+
def test_no_occurrence
|
93
|
+
expected_date = Date.new(2011,3,12)
|
94
|
+
schedule = Schedule.new({:kind => :never, :start_date => expected_date})
|
95
|
+
expected_dates = [expected_date]
|
96
|
+
assert_equal expected_dates, schedule.occurrences_between(Date.new(2011,1,1), Date.new(2011,12,31))
|
97
|
+
assert schedule.contains?(expected_date)
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
|
102
|
+
def test_how_contains_handles_parameter_types
|
103
|
+
date = Date.new(1981,4,23)
|
104
|
+
schedule = Schedule.new({:kind => :annually, :start_date => date})
|
105
|
+
assert schedule.contains?(date)
|
106
|
+
assert schedule.contains?(date.to_time)
|
107
|
+
assert schedule.contains?(date.to_datetime)
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
|
112
|
+
def test_monthly_occurrences
|
113
|
+
occurrence = [1, "Wednesday"]
|
114
|
+
schedule = Schedule.new({
|
115
|
+
:kind => :monthly,
|
116
|
+
:pattern => [occurrence],
|
117
|
+
:start_date => Date.new(2011,1,1)})
|
118
|
+
expected_dates = [[1,5], [2,2], [3,2], [4,6], [5,4], [6,1], [7,6], [8,3], [9,7], [10,5], [11,2], [12,7]]
|
119
|
+
expected_dates.map! {|pair| Date.new(2011, *pair)}
|
120
|
+
assert_equal expected_dates, schedule.occurrences_between(Date.new(2011,1,1), Date.new(2011,12,31))
|
121
|
+
|
122
|
+
(0...(expected_dates.length - 1)).each do |i|
|
123
|
+
assert_equal expected_dates[i+1], schedule.next_occurrence_after(expected_dates[i])
|
124
|
+
assert_equal expected_dates[i], schedule.first_occurrence_before(expected_dates[i + 1])
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
|
130
|
+
def test_weekly_recurrence_and_skip
|
131
|
+
schedule = Schedule.new({
|
132
|
+
:kind => :weekly,
|
133
|
+
:pattern => ["Monday"],
|
134
|
+
:skip => 3,
|
135
|
+
:start_date => Date.new(2011,1,1)})
|
136
|
+
expected_dates = [[1,3], [1,24], [2,14], [3,7], [3,28]]
|
137
|
+
expected_dates.map! {|pair| Date.new(2011, *pair)}
|
138
|
+
assert_equal expected_dates, schedule.occurrences_between(Date.new(2011,1,1), Date.new(2011,3,31))
|
139
|
+
|
140
|
+
(0...(expected_dates.length - 1)).each do |i|
|
141
|
+
assert_equal expected_dates[i+1], schedule.next_occurrence_after(expected_dates[i])
|
142
|
+
assert_equal expected_dates[i], schedule.first_occurrence_before(expected_dates[i + 1])
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
|
148
|
+
def test_monthly_recurrence_and_skip
|
149
|
+
schedule = Schedule.new({
|
150
|
+
:kind => :monthly,
|
151
|
+
:pattern => [[1, "Wednesday"]],
|
152
|
+
:skip => 2,
|
153
|
+
:start_date => Date.new(2011,1,1)})
|
154
|
+
expected_dates = [[1,5], [3,2], [5,4], [7,6], [9,7], [11,2]]
|
155
|
+
expected_dates.map! {|pair| Date.new(2011, *pair)}
|
156
|
+
assert_equal expected_dates, schedule.occurrences_between(Date.new(2011,1,1), Date.new(2011,12,31))
|
157
|
+
|
158
|
+
(0...(expected_dates.length - 1)).each do |i|
|
159
|
+
assert_equal expected_dates[i+1], schedule.next_occurrence_after(expected_dates[i])
|
160
|
+
assert_equal expected_dates[i], schedule.first_occurrence_before(expected_dates[i + 1])
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
|
165
|
+
|
166
|
+
def test_annual_occurrences_during_month
|
167
|
+
schedule = Schedule.new({
|
168
|
+
:kind => :annually,
|
169
|
+
:start_date => Date.new(1981,4,23)})
|
170
|
+
dates = schedule.occurrences_during_month(1981,4).map {|date| date.day}
|
171
|
+
expected_dates = [23]
|
172
|
+
assert_equal expected_dates, dates, "occurrences_during_month did not generate expected dates for annual schedule"
|
173
|
+
|
174
|
+
dates = schedule.occurrences_during_month(1972,4).map {|date| date.day}
|
175
|
+
expected_dates = []
|
176
|
+
assert_equal expected_dates, dates, "occurrences_during_month did not generate expected dates for annual schedule"
|
177
|
+
|
178
|
+
dates = schedule.occurrences_during_month(1984,4).map {|date| date.day}
|
179
|
+
expected_dates = [23]
|
180
|
+
assert_equal expected_dates, dates, "occurrences_during_month did not generate expected dates for annual schedule"
|
181
|
+
|
182
|
+
dates = schedule.occurrences_during_month(1984,3).map {|date| date.day}
|
183
|
+
expected_dates = []
|
184
|
+
assert_equal expected_dates, dates, "occurrences_during_month did not generate expected dates for annual schedule"
|
185
|
+
|
186
|
+
dates = schedule.occurrences_during_month(2009,12).map {|date| date.day}
|
187
|
+
expected_dates = []
|
188
|
+
assert_equal expected_dates, dates, "occurrences_during_month did not generate expected dates for annual schedule"
|
189
|
+
end
|
190
|
+
|
191
|
+
test "When there is no 5th weekday of a month, schedule shouldn't crash" do
|
192
|
+
start = Date.new(2010,6,1)
|
193
|
+
schedule = Schedule.new({
|
194
|
+
:kind => :monthly,
|
195
|
+
:pattern => [[5, "Monday"]],
|
196
|
+
:start_date => start})
|
197
|
+
assert_equal "The fifth Monday of every month", schedule.humanize
|
198
|
+
|
199
|
+
# There are not 5 Mondays during June 2010
|
200
|
+
assert_nothing_raised do
|
201
|
+
assert_equal [], schedule.occurrences_during_month(2010, 6)
|
202
|
+
end
|
203
|
+
|
204
|
+
next_fifth_month = Date.new(2010,8,30)
|
205
|
+
assert_equal next_fifth_month, schedule.first_occurrence_on_or_after(start)
|
206
|
+
end
|
207
|
+
|
208
|
+
|
209
|
+
|
210
|
+
def test_first_occurrence_on_or_after
|
211
|
+
fifth_sunday = Date.new(2010, 8, 29)
|
212
|
+
schedule = Schedule.new({
|
213
|
+
:kind => :monthly,
|
214
|
+
:pattern => [[5, "Sunday"]],
|
215
|
+
:start_date => fifth_sunday})
|
216
|
+
assert_equal "The fifth Sunday of every month", schedule.humanize
|
217
|
+
|
218
|
+
assert_equal fifth_sunday, schedule.first_occurrence_on_or_after(fifth_sunday)
|
219
|
+
assert schedule.contains?(fifth_sunday)
|
220
|
+
end
|
221
|
+
|
222
|
+
|
223
|
+
|
224
|
+
def test_february_29
|
225
|
+
schedule = Schedule.new({
|
226
|
+
:kind => :annually,
|
227
|
+
:start_date => Date.new(2008, 2, 29)
|
228
|
+
});
|
229
|
+
|
230
|
+
assert_equal [Date.new(2010, 2, 28)], schedule.occurrences_during_month(2010, 2)
|
231
|
+
end
|
232
|
+
|
233
|
+
|
234
|
+
|
235
|
+
def test_recurs_on31st
|
236
|
+
schedule = Schedule.new({
|
237
|
+
:kind => :monthly,
|
238
|
+
:pattern => [31],
|
239
|
+
:start_date => Date.new(2008, 2, 29)
|
240
|
+
});
|
241
|
+
|
242
|
+
assert_equal [Date.new(2010, 1, 31)], schedule.occurrences_during_month(2010, 1)
|
243
|
+
assert_equal [], schedule.occurrences_during_month(2010, 2)
|
244
|
+
end
|
245
|
+
|
246
|
+
|
247
|
+
|
248
|
+
# def test_monthly_occurrence_to_date
|
249
|
+
# occurrence = MonthlyOccurrence.new(:ordinal => 3, :kind => "Thursday")
|
250
|
+
# assert_equal 21, occurrence.to_date(2009, 5).day, "The third Thursday in May 2009 should be the 21st"
|
251
|
+
# assert_equal 16, occurrence.to_date(2009, 4).day, "The third Thursday in April 2009 should be the 16th"
|
252
|
+
# assert_equal 15, occurrence.to_date(2012, 11).day, "The third Thursday in November 2012 should be the 15th"
|
253
|
+
#
|
254
|
+
# occurrence = MonthlyOccurrence.new(:ordinal => 1, :kind => "Tuesday")
|
255
|
+
# assert_equal 5, occurrence.to_date(2009, 5).day, "The first Tuesday in May 2009 should be the 5th"
|
256
|
+
# assert_equal 2, occurrence.to_date(2008, 12).day, "The first Tuesday in December 2008 should be the 2nd"
|
257
|
+
# assert_equal 1, occurrence.to_date(2009, 9).day, "The first Tuesday in September 2009 should be the 1st"
|
258
|
+
#
|
259
|
+
# occurrence = MonthlyOccurrence.new(:ordinal => 1, :kind => "Sunday")
|
260
|
+
# assert_equal 3, occurrence.to_date(2009, 5).day, "The first Sunday in May 2009 should be the 3rd"
|
261
|
+
# assert_equal 1, occurrence.to_date(2010, 8).day, "The first Sunday in August 2010 should be the 1st"
|
262
|
+
# assert_equal 7, occurrence.to_date(2009, 6).day, "The first Sunday in June 2009 should be the 7th"
|
263
|
+
#
|
264
|
+
# occurrence = MonthlyOccurrence.new(:ordinal => 1, :kind => "day")
|
265
|
+
# assert_equal 1, occurrence.to_date(2009, 5).day, "The first of May 2009 should be 1"
|
266
|
+
#
|
267
|
+
# occurrence = MonthlyOccurrence.new(:ordinal => 22, :kind => "day")
|
268
|
+
# assert_equal 22, occurrence.to_date(2009, 5).day, "The twenty-second of May 2009 should be 22"
|
269
|
+
#
|
270
|
+
# #occurrence = MonthlyOccurrence.new(:ordinal => -1, :kind => "Sunday")
|
271
|
+
# #assert_equal 31, occurrence.to_date(2009, 5), "The last Sunday in May 2009 should be the 31st"
|
272
|
+
# end
|
273
|
+
#
|
274
|
+
#
|
275
|
+
# test "to_date should return nil if there is no occurrence with the specified parameters" do
|
276
|
+
# mo = MonthlyOccurrence.new(:ordinal => 5, :kind => "Monday")
|
277
|
+
# assert_equal "fifth Monday", mo.to_s
|
278
|
+
# assert_nil mo.to_date(2010, 6)
|
279
|
+
# end
|
280
|
+
|
281
|
+
|
282
|
+
|
283
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
|
4
|
+
class HumanizableTest < ActiveSupport::TestCase
|
5
|
+
include Hiccup
|
6
|
+
|
7
|
+
|
8
|
+
def self.test_humanize(*args)
|
9
|
+
expected_string = args.shift
|
10
|
+
attributes = args.shift
|
11
|
+
|
12
|
+
test(expected_string) do
|
13
|
+
schedule = Schedule.new(attributes)
|
14
|
+
assert_equal expected_string, schedule.humanize
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
test_humanize(
|
21
|
+
"Every Sunday",
|
22
|
+
{:kind => :weekly, :pattern => %w[Sunday]})
|
23
|
+
|
24
|
+
test_humanize(
|
25
|
+
"Every other Sunday",
|
26
|
+
{:kind => :weekly, :pattern => %w[Sunday], :skip => 2})
|
27
|
+
|
28
|
+
test_humanize(
|
29
|
+
"Every Sunday and Monday",
|
30
|
+
{:kind => :weekly, :pattern => %w[Sunday Monday]})
|
31
|
+
|
32
|
+
test_humanize(
|
33
|
+
"Monday, Wednesday, and Friday of every third week",
|
34
|
+
{:kind => :weekly, :pattern => %w[Monday Wednesday Friday], :skip => 3})
|
35
|
+
|
36
|
+
test_humanize(
|
37
|
+
"The 4th of every month",
|
38
|
+
{:kind => :monthly, :pattern => [4]})
|
39
|
+
|
40
|
+
test_humanize(
|
41
|
+
"The 4th and 5th of every month",
|
42
|
+
{:kind => :monthly, :pattern => [4,5]})
|
43
|
+
|
44
|
+
test_humanize(
|
45
|
+
"The first Monday of every month",
|
46
|
+
{:kind => :monthly, :pattern => [[1, "Monday"]]})
|
47
|
+
|
48
|
+
test_humanize(
|
49
|
+
"The last Tuesday of every month",
|
50
|
+
{:kind => :monthly, :pattern => [[-1, "Tuesday"]]})
|
51
|
+
|
52
|
+
test_humanize(
|
53
|
+
"The first Monday and third Monday of every other month",
|
54
|
+
{:kind => :monthly, :pattern => [[1, "Monday"], [3, "Monday"]], :skip => 2})
|
55
|
+
|
56
|
+
test_humanize(
|
57
|
+
"Every year on #{Date.today.strftime('%b %d')}",
|
58
|
+
{:kind => :annually})
|
59
|
+
|
60
|
+
test_humanize(
|
61
|
+
"Every other year on #{Date.today.strftime('%b %d')}",
|
62
|
+
{:kind => :annually, :skip => 2})
|
63
|
+
|
64
|
+
test_humanize(
|
65
|
+
"Every fourth year on #{Date.today.strftime('%b %d')}",
|
66
|
+
{:kind => :annually, :skip => 4})
|
67
|
+
|
68
|
+
|
69
|
+
|
70
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require "test_helper"
|
3
|
+
|
4
|
+
|
5
|
+
class IcalSerializableTest < ActiveSupport::TestCase
|
6
|
+
include Hiccup
|
7
|
+
|
8
|
+
|
9
|
+
def self.test_roundtrip(*args)
|
10
|
+
message = args.shift
|
11
|
+
ics = args.shift
|
12
|
+
attributes = args.shift
|
13
|
+
recurrence = Schedule.new(attributes)
|
14
|
+
test(message) do
|
15
|
+
assert_roundtrip ics, recurrence
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
test_roundtrip(
|
21
|
+
"Simple weekly recurrence",
|
22
|
+
"DTSTART;VALUE=DATE-TIME:20090101T000000Z\nRRULE:FREQ=WEEKLY;BYDAY=SU\n",
|
23
|
+
{ :kind => :weekly,
|
24
|
+
:pattern => %w{Sunday},
|
25
|
+
:start_date => DateTime.new(2009, 1, 1)
|
26
|
+
})
|
27
|
+
|
28
|
+
|
29
|
+
test_roundtrip(
|
30
|
+
"Complex weekly recurrence (with an interval)",
|
31
|
+
"DTSTART;VALUE=DATE-TIME:20090101T000000Z\nRRULE:FREQ=WEEKLY;INTERVAL=2;BYDAY=TU,TH\n",
|
32
|
+
{ :kind => :weekly,
|
33
|
+
:pattern => %w{Tuesday Thursday},
|
34
|
+
:start_date => DateTime.new(2009, 1, 1),
|
35
|
+
:skip => 2
|
36
|
+
})
|
37
|
+
|
38
|
+
|
39
|
+
test_roundtrip(
|
40
|
+
"Simple annual recurrence",
|
41
|
+
"DTSTART;VALUE=DATE-TIME:20090315T000000Z\nRRULE:FREQ=YEARLY\n",
|
42
|
+
{ :kind => :annually,
|
43
|
+
:start_date => DateTime.new(2009, 3, 15)
|
44
|
+
})
|
45
|
+
|
46
|
+
|
47
|
+
test_roundtrip(
|
48
|
+
"Annual recurrence with an end date",
|
49
|
+
"DTSTART;VALUE=DATE-TIME:20090315T000000Z\nRRULE:FREQ=YEARLY;UNTIL=20120315T000000Z\n",
|
50
|
+
{ :kind => :annually,
|
51
|
+
:start_date => DateTime.new(2009, 3, 15),
|
52
|
+
:end_date => DateTime.new(2012, 3, 15), :ends => true
|
53
|
+
})
|
54
|
+
|
55
|
+
|
56
|
+
test_roundtrip(
|
57
|
+
"Simple monthly recurrence",
|
58
|
+
"DTSTART;VALUE=DATE-TIME:20090315T000000Z\nRRULE:FREQ=MONTHLY;BYMONTHDAY=4\n",
|
59
|
+
{ :kind => :monthly,
|
60
|
+
:pattern => [4],
|
61
|
+
:start_date => DateTime.new(2009, 3, 15)
|
62
|
+
})
|
63
|
+
|
64
|
+
|
65
|
+
test_roundtrip(
|
66
|
+
"Monthly recurrence on the last Tuesday of the month",
|
67
|
+
"DTSTART;VALUE=DATE-TIME:20090315T000000Z\nRRULE:FREQ=MONTHLY;BYDAY=-1TU\n",
|
68
|
+
{ :kind => :monthly,
|
69
|
+
:pattern => [[-1, "Tuesday"]],
|
70
|
+
:start_date => DateTime.new(2009, 3, 15)
|
71
|
+
})
|
72
|
+
|
73
|
+
|
74
|
+
test_roundtrip(
|
75
|
+
"Complex monthly recurrence",
|
76
|
+
"DTSTART;VALUE=DATE-TIME:20090315T000000Z\nRRULE:FREQ=MONTHLY;BYDAY=2SU,4SU\n",
|
77
|
+
{ :kind => :monthly,
|
78
|
+
:pattern => [[2, "Sunday"], [4, "Sunday"]],
|
79
|
+
:start_date => DateTime.new(2009, 3, 15)
|
80
|
+
})
|
81
|
+
|
82
|
+
|
83
|
+
protected
|
84
|
+
|
85
|
+
|
86
|
+
def assert_roundtrip(ics, recurrence)
|
87
|
+
assert_equal ics, recurrence.to_ical, "to_ical did not result in the expected ICS"
|
88
|
+
assert_equal recurrence.to_hash, Schedule.from_ical(ics).to_hash, "from_ical did not result in the expected recurrence"
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
end
|