• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# -*- coding: utf-8 -*-
2from __future__ import unicode_literals
3from ._common import WarningTestMixin
4
5from datetime import datetime, date
6import unittest
7from six import PY3
8
9from dateutil import tz
10from dateutil.rrule import (
11    rrule, rruleset, rrulestr,
12    YEARLY, MONTHLY, WEEKLY, DAILY,
13    HOURLY, MINUTELY, SECONDLY,
14    MO, TU, WE, TH, FR, SA, SU
15)
16
17from freezegun import freeze_time
18
19import pytest
20
21
22@pytest.mark.rrule
23class RRuleTest(WarningTestMixin, unittest.TestCase):
24    def _rrulestr_reverse_test(self, rule):
25        """
26        Call with an `rrule` and it will test that `str(rrule)` generates a
27        string which generates the same `rrule` as the input when passed to
28        `rrulestr()`
29        """
30        rr_str = str(rule)
31        rrulestr_rrule = rrulestr(rr_str)
32
33        self.assertEqual(list(rule), list(rrulestr_rrule))
34
35    def testStrAppendRRULEToken(self):
36        # `_rrulestr_reverse_test` does not check if the "RRULE:" prefix
37        # property is appended properly, so give it a dedicated test
38        self.assertEqual(str(rrule(YEARLY,
39                             count=5,
40                             dtstart=datetime(1997, 9, 2, 9, 0))),
41                         "DTSTART:19970902T090000\n"
42                         "RRULE:FREQ=YEARLY;COUNT=5")
43
44        rr_str = (
45          'DTSTART:19970105T083000\nRRULE:FREQ=YEARLY;INTERVAL=2'
46        )
47        self.assertEqual(str(rrulestr(rr_str)), rr_str)
48
49    def testYearly(self):
50        self.assertEqual(list(rrule(YEARLY,
51                              count=3,
52                              dtstart=datetime(1997, 9, 2, 9, 0))),
53                         [datetime(1997, 9, 2, 9, 0),
54                          datetime(1998, 9, 2, 9, 0),
55                          datetime(1999, 9, 2, 9, 0)])
56
57    def testYearlyInterval(self):
58        self.assertEqual(list(rrule(YEARLY,
59                              count=3,
60                              interval=2,
61                              dtstart=datetime(1997, 9, 2, 9, 0))),
62                         [datetime(1997, 9, 2, 9, 0),
63                          datetime(1999, 9, 2, 9, 0),
64                          datetime(2001, 9, 2, 9, 0)])
65
66    def testYearlyIntervalLarge(self):
67        self.assertEqual(list(rrule(YEARLY,
68                              count=3,
69                              interval=100,
70                              dtstart=datetime(1997, 9, 2, 9, 0))),
71                         [datetime(1997, 9, 2, 9, 0),
72                          datetime(2097, 9, 2, 9, 0),
73                          datetime(2197, 9, 2, 9, 0)])
74
75    def testYearlyByMonth(self):
76        self.assertEqual(list(rrule(YEARLY,
77                              count=3,
78                              bymonth=(1, 3),
79                              dtstart=datetime(1997, 9, 2, 9, 0))),
80                         [datetime(1998, 1, 2, 9, 0),
81                          datetime(1998, 3, 2, 9, 0),
82                          datetime(1999, 1, 2, 9, 0)])
83
84    def testYearlyByMonthDay(self):
85        self.assertEqual(list(rrule(YEARLY,
86                              count=3,
87                              bymonthday=(1, 3),
88                              dtstart=datetime(1997, 9, 2, 9, 0))),
89                         [datetime(1997, 9, 3, 9, 0),
90                          datetime(1997, 10, 1, 9, 0),
91                          datetime(1997, 10, 3, 9, 0)])
92
93    def testYearlyByMonthAndMonthDay(self):
94        self.assertEqual(list(rrule(YEARLY,
95                              count=3,
96                              bymonth=(1, 3),
97                              bymonthday=(5, 7),
98                              dtstart=datetime(1997, 9, 2, 9, 0))),
99                         [datetime(1998, 1, 5, 9, 0),
100                          datetime(1998, 1, 7, 9, 0),
101                          datetime(1998, 3, 5, 9, 0)])
102
103    def testYearlyByWeekDay(self):
104        self.assertEqual(list(rrule(YEARLY,
105                              count=3,
106                              byweekday=(TU, TH),
107                              dtstart=datetime(1997, 9, 2, 9, 0))),
108                         [datetime(1997, 9, 2, 9, 0),
109                          datetime(1997, 9, 4, 9, 0),
110                          datetime(1997, 9, 9, 9, 0)])
111
112    def testYearlyByNWeekDay(self):
113        self.assertEqual(list(rrule(YEARLY,
114                              count=3,
115                              byweekday=(TU(1), TH(-1)),
116                              dtstart=datetime(1997, 9, 2, 9, 0))),
117                         [datetime(1997, 12, 25, 9, 0),
118                          datetime(1998, 1, 6, 9, 0),
119                          datetime(1998, 12, 31, 9, 0)])
120
121    def testYearlyByNWeekDayLarge(self):
122        self.assertEqual(list(rrule(YEARLY,
123                              count=3,
124                              byweekday=(TU(3), TH(-3)),
125                              dtstart=datetime(1997, 9, 2, 9, 0))),
126                         [datetime(1997, 12, 11, 9, 0),
127                          datetime(1998, 1, 20, 9, 0),
128                          datetime(1998, 12, 17, 9, 0)])
129
130    def testYearlyByMonthAndWeekDay(self):
131        self.assertEqual(list(rrule(YEARLY,
132                              count=3,
133                              bymonth=(1, 3),
134                              byweekday=(TU, TH),
135                              dtstart=datetime(1997, 9, 2, 9, 0))),
136                         [datetime(1998, 1, 1, 9, 0),
137                          datetime(1998, 1, 6, 9, 0),
138                          datetime(1998, 1, 8, 9, 0)])
139
140    def testYearlyByMonthAndNWeekDay(self):
141        self.assertEqual(list(rrule(YEARLY,
142                              count=3,
143                              bymonth=(1, 3),
144                              byweekday=(TU(1), TH(-1)),
145                              dtstart=datetime(1997, 9, 2, 9, 0))),
146                         [datetime(1998, 1, 6, 9, 0),
147                          datetime(1998, 1, 29, 9, 0),
148                          datetime(1998, 3, 3, 9, 0)])
149
150    def testYearlyByMonthAndNWeekDayLarge(self):
151        # This is interesting because the TH(-3) ends up before
152        # the TU(3).
153        self.assertEqual(list(rrule(YEARLY,
154                              count=3,
155                              bymonth=(1, 3),
156                              byweekday=(TU(3), TH(-3)),
157                              dtstart=datetime(1997, 9, 2, 9, 0))),
158                         [datetime(1998, 1, 15, 9, 0),
159                          datetime(1998, 1, 20, 9, 0),
160                          datetime(1998, 3, 12, 9, 0)])
161
162    def testYearlyByMonthDayAndWeekDay(self):
163        self.assertEqual(list(rrule(YEARLY,
164                              count=3,
165                              bymonthday=(1, 3),
166                              byweekday=(TU, TH),
167                              dtstart=datetime(1997, 9, 2, 9, 0))),
168                         [datetime(1998, 1, 1, 9, 0),
169                          datetime(1998, 2, 3, 9, 0),
170                          datetime(1998, 3, 3, 9, 0)])
171
172    def testYearlyByMonthAndMonthDayAndWeekDay(self):
173        self.assertEqual(list(rrule(YEARLY,
174                              count=3,
175                              bymonth=(1, 3),
176                              bymonthday=(1, 3),
177                              byweekday=(TU, TH),
178                              dtstart=datetime(1997, 9, 2, 9, 0))),
179                         [datetime(1998, 1, 1, 9, 0),
180                          datetime(1998, 3, 3, 9, 0),
181                          datetime(2001, 3, 1, 9, 0)])
182
183    def testYearlyByYearDay(self):
184        self.assertEqual(list(rrule(YEARLY,
185                              count=4,
186                              byyearday=(1, 100, 200, 365),
187                              dtstart=datetime(1997, 9, 2, 9, 0))),
188                         [datetime(1997, 12, 31, 9, 0),
189                          datetime(1998, 1, 1, 9, 0),
190                          datetime(1998, 4, 10, 9, 0),
191                          datetime(1998, 7, 19, 9, 0)])
192
193    def testYearlyByYearDayNeg(self):
194        self.assertEqual(list(rrule(YEARLY,
195                              count=4,
196                              byyearday=(-365, -266, -166, -1),
197                              dtstart=datetime(1997, 9, 2, 9, 0))),
198                         [datetime(1997, 12, 31, 9, 0),
199                          datetime(1998, 1, 1, 9, 0),
200                          datetime(1998, 4, 10, 9, 0),
201                          datetime(1998, 7, 19, 9, 0)])
202
203    def testYearlyByMonthAndYearDay(self):
204        self.assertEqual(list(rrule(YEARLY,
205                              count=4,
206                              bymonth=(4, 7),
207                              byyearday=(1, 100, 200, 365),
208                              dtstart=datetime(1997, 9, 2, 9, 0))),
209                         [datetime(1998, 4, 10, 9, 0),
210                          datetime(1998, 7, 19, 9, 0),
211                          datetime(1999, 4, 10, 9, 0),
212                          datetime(1999, 7, 19, 9, 0)])
213
214    def testYearlyByMonthAndYearDayNeg(self):
215        self.assertEqual(list(rrule(YEARLY,
216                              count=4,
217                              bymonth=(4, 7),
218                              byyearday=(-365, -266, -166, -1),
219                              dtstart=datetime(1997, 9, 2, 9, 0))),
220                         [datetime(1998, 4, 10, 9, 0),
221                          datetime(1998, 7, 19, 9, 0),
222                          datetime(1999, 4, 10, 9, 0),
223                          datetime(1999, 7, 19, 9, 0)])
224
225    def testYearlyByWeekNo(self):
226        self.assertEqual(list(rrule(YEARLY,
227                              count=3,
228                              byweekno=20,
229                              dtstart=datetime(1997, 9, 2, 9, 0))),
230                         [datetime(1998, 5, 11, 9, 0),
231                          datetime(1998, 5, 12, 9, 0),
232                          datetime(1998, 5, 13, 9, 0)])
233
234    def testYearlyByWeekNoAndWeekDay(self):
235        # That's a nice one. The first days of week number one
236        # may be in the last year.
237        self.assertEqual(list(rrule(YEARLY,
238                              count=3,
239                              byweekno=1,
240                              byweekday=MO,
241                              dtstart=datetime(1997, 9, 2, 9, 0))),
242                         [datetime(1997, 12, 29, 9, 0),
243                          datetime(1999, 1, 4, 9, 0),
244                          datetime(2000, 1, 3, 9, 0)])
245
246    def testYearlyByWeekNoAndWeekDayLarge(self):
247        # Another nice test. The last days of week number 52/53
248        # may be in the next year.
249        self.assertEqual(list(rrule(YEARLY,
250                              count=3,
251                              byweekno=52,
252                              byweekday=SU,
253                              dtstart=datetime(1997, 9, 2, 9, 0))),
254                         [datetime(1997, 12, 28, 9, 0),
255                          datetime(1998, 12, 27, 9, 0),
256                          datetime(2000, 1, 2, 9, 0)])
257
258    def testYearlyByWeekNoAndWeekDayLast(self):
259        self.assertEqual(list(rrule(YEARLY,
260                              count=3,
261                              byweekno=-1,
262                              byweekday=SU,
263                              dtstart=datetime(1997, 9, 2, 9, 0))),
264                         [datetime(1997, 12, 28, 9, 0),
265                          datetime(1999, 1, 3, 9, 0),
266                          datetime(2000, 1, 2, 9, 0)])
267
268    def testYearlyByEaster(self):
269        self.assertEqual(list(rrule(YEARLY,
270                              count=3,
271                              byeaster=0,
272                              dtstart=datetime(1997, 9, 2, 9, 0))),
273                         [datetime(1998, 4, 12, 9, 0),
274                          datetime(1999, 4, 4, 9, 0),
275                          datetime(2000, 4, 23, 9, 0)])
276
277    def testYearlyByEasterPos(self):
278        self.assertEqual(list(rrule(YEARLY,
279                              count=3,
280                              byeaster=1,
281                              dtstart=datetime(1997, 9, 2, 9, 0))),
282                         [datetime(1998, 4, 13, 9, 0),
283                          datetime(1999, 4, 5, 9, 0),
284                          datetime(2000, 4, 24, 9, 0)])
285
286    def testYearlyByEasterNeg(self):
287        self.assertEqual(list(rrule(YEARLY,
288                              count=3,
289                              byeaster=-1,
290                              dtstart=datetime(1997, 9, 2, 9, 0))),
291                         [datetime(1998, 4, 11, 9, 0),
292                          datetime(1999, 4, 3, 9, 0),
293                          datetime(2000, 4, 22, 9, 0)])
294
295    def testYearlyByWeekNoAndWeekDay53(self):
296        self.assertEqual(list(rrule(YEARLY,
297                              count=3,
298                              byweekno=53,
299                              byweekday=MO,
300                              dtstart=datetime(1997, 9, 2, 9, 0))),
301                         [datetime(1998, 12, 28, 9, 0),
302                          datetime(2004, 12, 27, 9, 0),
303                          datetime(2009, 12, 28, 9, 0)])
304
305    def testYearlyByHour(self):
306        self.assertEqual(list(rrule(YEARLY,
307                              count=3,
308                              byhour=(6, 18),
309                              dtstart=datetime(1997, 9, 2, 9, 0))),
310                         [datetime(1997, 9, 2, 18, 0),
311                          datetime(1998, 9, 2, 6, 0),
312                          datetime(1998, 9, 2, 18, 0)])
313
314    def testYearlyByMinute(self):
315        self.assertEqual(list(rrule(YEARLY,
316                              count=3,
317                              byminute=(6, 18),
318                              dtstart=datetime(1997, 9, 2, 9, 0))),
319                         [datetime(1997, 9, 2, 9, 6),
320                          datetime(1997, 9, 2, 9, 18),
321                          datetime(1998, 9, 2, 9, 6)])
322
323    def testYearlyBySecond(self):
324        self.assertEqual(list(rrule(YEARLY,
325                              count=3,
326                              bysecond=(6, 18),
327                              dtstart=datetime(1997, 9, 2, 9, 0))),
328                         [datetime(1997, 9, 2, 9, 0, 6),
329                          datetime(1997, 9, 2, 9, 0, 18),
330                          datetime(1998, 9, 2, 9, 0, 6)])
331
332    def testYearlyByHourAndMinute(self):
333        self.assertEqual(list(rrule(YEARLY,
334                              count=3,
335                              byhour=(6, 18),
336                              byminute=(6, 18),
337                              dtstart=datetime(1997, 9, 2, 9, 0))),
338                         [datetime(1997, 9, 2, 18, 6),
339                          datetime(1997, 9, 2, 18, 18),
340                          datetime(1998, 9, 2, 6, 6)])
341
342    def testYearlyByHourAndSecond(self):
343        self.assertEqual(list(rrule(YEARLY,
344                              count=3,
345                              byhour=(6, 18),
346                              bysecond=(6, 18),
347                              dtstart=datetime(1997, 9, 2, 9, 0))),
348                         [datetime(1997, 9, 2, 18, 0, 6),
349                          datetime(1997, 9, 2, 18, 0, 18),
350                          datetime(1998, 9, 2, 6, 0, 6)])
351
352    def testYearlyByMinuteAndSecond(self):
353        self.assertEqual(list(rrule(YEARLY,
354                              count=3,
355                              byminute=(6, 18),
356                              bysecond=(6, 18),
357                              dtstart=datetime(1997, 9, 2, 9, 0))),
358                         [datetime(1997, 9, 2, 9, 6, 6),
359                          datetime(1997, 9, 2, 9, 6, 18),
360                          datetime(1997, 9, 2, 9, 18, 6)])
361
362    def testYearlyByHourAndMinuteAndSecond(self):
363        self.assertEqual(list(rrule(YEARLY,
364                              count=3,
365                              byhour=(6, 18),
366                              byminute=(6, 18),
367                              bysecond=(6, 18),
368                              dtstart=datetime(1997, 9, 2, 9, 0))),
369                         [datetime(1997, 9, 2, 18, 6, 6),
370                          datetime(1997, 9, 2, 18, 6, 18),
371                          datetime(1997, 9, 2, 18, 18, 6)])
372
373    def testYearlyBySetPos(self):
374        self.assertEqual(list(rrule(YEARLY,
375                              count=3,
376                              bymonthday=15,
377                              byhour=(6, 18),
378                              bysetpos=(3, -3),
379                              dtstart=datetime(1997, 9, 2, 9, 0))),
380                         [datetime(1997, 11, 15, 18, 0),
381                          datetime(1998, 2, 15, 6, 0),
382                          datetime(1998, 11, 15, 18, 0)])
383
384    def testMonthly(self):
385        self.assertEqual(list(rrule(MONTHLY,
386                              count=3,
387                              dtstart=datetime(1997, 9, 2, 9, 0))),
388                         [datetime(1997, 9, 2, 9, 0),
389                          datetime(1997, 10, 2, 9, 0),
390                          datetime(1997, 11, 2, 9, 0)])
391
392    def testMonthlyInterval(self):
393        self.assertEqual(list(rrule(MONTHLY,
394                              count=3,
395                              interval=2,
396                              dtstart=datetime(1997, 9, 2, 9, 0))),
397                         [datetime(1997, 9, 2, 9, 0),
398                          datetime(1997, 11, 2, 9, 0),
399                          datetime(1998, 1, 2, 9, 0)])
400
401    def testMonthlyIntervalLarge(self):
402        self.assertEqual(list(rrule(MONTHLY,
403                              count=3,
404                              interval=18,
405                              dtstart=datetime(1997, 9, 2, 9, 0))),
406                         [datetime(1997, 9, 2, 9, 0),
407                          datetime(1999, 3, 2, 9, 0),
408                          datetime(2000, 9, 2, 9, 0)])
409
410    def testMonthlyByMonth(self):
411        self.assertEqual(list(rrule(MONTHLY,
412                              count=3,
413                              bymonth=(1, 3),
414                              dtstart=datetime(1997, 9, 2, 9, 0))),
415                         [datetime(1998, 1, 2, 9, 0),
416                          datetime(1998, 3, 2, 9, 0),
417                          datetime(1999, 1, 2, 9, 0)])
418
419    def testMonthlyByMonthDay(self):
420        self.assertEqual(list(rrule(MONTHLY,
421                              count=3,
422                              bymonthday=(1, 3),
423                              dtstart=datetime(1997, 9, 2, 9, 0))),
424                         [datetime(1997, 9, 3, 9, 0),
425                          datetime(1997, 10, 1, 9, 0),
426                          datetime(1997, 10, 3, 9, 0)])
427
428    def testMonthlyByMonthAndMonthDay(self):
429        self.assertEqual(list(rrule(MONTHLY,
430                              count=3,
431                              bymonth=(1, 3),
432                              bymonthday=(5, 7),
433                              dtstart=datetime(1997, 9, 2, 9, 0))),
434                         [datetime(1998, 1, 5, 9, 0),
435                          datetime(1998, 1, 7, 9, 0),
436                          datetime(1998, 3, 5, 9, 0)])
437
438    def testMonthlyByWeekDay(self):
439        self.assertEqual(list(rrule(MONTHLY,
440                              count=3,
441                              byweekday=(TU, TH),
442                              dtstart=datetime(1997, 9, 2, 9, 0))),
443                         [datetime(1997, 9, 2, 9, 0),
444                          datetime(1997, 9, 4, 9, 0),
445                          datetime(1997, 9, 9, 9, 0)])
446
447        # Third Monday of the month
448        self.assertEqual(rrule(MONTHLY,
449                         byweekday=(MO(+3)),
450                         dtstart=datetime(1997, 9, 1)).between(datetime(1997, 9, 1),
451                                                               datetime(1997, 12, 1)),
452                         [datetime(1997, 9, 15, 0, 0),
453                          datetime(1997, 10, 20, 0, 0),
454                          datetime(1997, 11, 17, 0, 0)])
455
456    def testMonthlyByNWeekDay(self):
457        self.assertEqual(list(rrule(MONTHLY,
458                              count=3,
459                              byweekday=(TU(1), TH(-1)),
460                              dtstart=datetime(1997, 9, 2, 9, 0))),
461                         [datetime(1997, 9, 2, 9, 0),
462                          datetime(1997, 9, 25, 9, 0),
463                          datetime(1997, 10, 7, 9, 0)])
464
465    def testMonthlyByNWeekDayLarge(self):
466        self.assertEqual(list(rrule(MONTHLY,
467                              count=3,
468                              byweekday=(TU(3), TH(-3)),
469                              dtstart=datetime(1997, 9, 2, 9, 0))),
470                         [datetime(1997, 9, 11, 9, 0),
471                          datetime(1997, 9, 16, 9, 0),
472                          datetime(1997, 10, 16, 9, 0)])
473
474    def testMonthlyByMonthAndWeekDay(self):
475        self.assertEqual(list(rrule(MONTHLY,
476                              count=3,
477                              bymonth=(1, 3),
478                              byweekday=(TU, TH),
479                              dtstart=datetime(1997, 9, 2, 9, 0))),
480                         [datetime(1998, 1, 1, 9, 0),
481                          datetime(1998, 1, 6, 9, 0),
482                          datetime(1998, 1, 8, 9, 0)])
483
484    def testMonthlyByMonthAndNWeekDay(self):
485        self.assertEqual(list(rrule(MONTHLY,
486                              count=3,
487                              bymonth=(1, 3),
488                              byweekday=(TU(1), TH(-1)),
489                              dtstart=datetime(1997, 9, 2, 9, 0))),
490                         [datetime(1998, 1, 6, 9, 0),
491                          datetime(1998, 1, 29, 9, 0),
492                          datetime(1998, 3, 3, 9, 0)])
493
494    def testMonthlyByMonthAndNWeekDayLarge(self):
495        self.assertEqual(list(rrule(MONTHLY,
496                              count=3,
497                              bymonth=(1, 3),
498                              byweekday=(TU(3), TH(-3)),
499                              dtstart=datetime(1997, 9, 2, 9, 0))),
500                         [datetime(1998, 1, 15, 9, 0),
501                          datetime(1998, 1, 20, 9, 0),
502                          datetime(1998, 3, 12, 9, 0)])
503
504    def testMonthlyByMonthDayAndWeekDay(self):
505        self.assertEqual(list(rrule(MONTHLY,
506                              count=3,
507                              bymonthday=(1, 3),
508                              byweekday=(TU, TH),
509                              dtstart=datetime(1997, 9, 2, 9, 0))),
510                         [datetime(1998, 1, 1, 9, 0),
511                          datetime(1998, 2, 3, 9, 0),
512                          datetime(1998, 3, 3, 9, 0)])
513
514    def testMonthlyByMonthAndMonthDayAndWeekDay(self):
515        self.assertEqual(list(rrule(MONTHLY,
516                              count=3,
517                              bymonth=(1, 3),
518                              bymonthday=(1, 3),
519                              byweekday=(TU, TH),
520                              dtstart=datetime(1997, 9, 2, 9, 0))),
521                         [datetime(1998, 1, 1, 9, 0),
522                          datetime(1998, 3, 3, 9, 0),
523                          datetime(2001, 3, 1, 9, 0)])
524
525    def testMonthlyByYearDay(self):
526        self.assertEqual(list(rrule(MONTHLY,
527                              count=4,
528                              byyearday=(1, 100, 200, 365),
529                              dtstart=datetime(1997, 9, 2, 9, 0))),
530                         [datetime(1997, 12, 31, 9, 0),
531                          datetime(1998, 1, 1, 9, 0),
532                          datetime(1998, 4, 10, 9, 0),
533                          datetime(1998, 7, 19, 9, 0)])
534
535    def testMonthlyByYearDayNeg(self):
536        self.assertEqual(list(rrule(MONTHLY,
537                              count=4,
538                              byyearday=(-365, -266, -166, -1),
539                              dtstart=datetime(1997, 9, 2, 9, 0))),
540                         [datetime(1997, 12, 31, 9, 0),
541                          datetime(1998, 1, 1, 9, 0),
542                          datetime(1998, 4, 10, 9, 0),
543                          datetime(1998, 7, 19, 9, 0)])
544
545    def testMonthlyByMonthAndYearDay(self):
546        self.assertEqual(list(rrule(MONTHLY,
547                              count=4,
548                              bymonth=(4, 7),
549                              byyearday=(1, 100, 200, 365),
550                              dtstart=datetime(1997, 9, 2, 9, 0))),
551                         [datetime(1998, 4, 10, 9, 0),
552                          datetime(1998, 7, 19, 9, 0),
553                          datetime(1999, 4, 10, 9, 0),
554                          datetime(1999, 7, 19, 9, 0)])
555
556    def testMonthlyByMonthAndYearDayNeg(self):
557        self.assertEqual(list(rrule(MONTHLY,
558                              count=4,
559                              bymonth=(4, 7),
560                              byyearday=(-365, -266, -166, -1),
561                              dtstart=datetime(1997, 9, 2, 9, 0))),
562                         [datetime(1998, 4, 10, 9, 0),
563                          datetime(1998, 7, 19, 9, 0),
564                          datetime(1999, 4, 10, 9, 0),
565                          datetime(1999, 7, 19, 9, 0)])
566
567    def testMonthlyByWeekNo(self):
568        self.assertEqual(list(rrule(MONTHLY,
569                              count=3,
570                              byweekno=20,
571                              dtstart=datetime(1997, 9, 2, 9, 0))),
572                         [datetime(1998, 5, 11, 9, 0),
573                          datetime(1998, 5, 12, 9, 0),
574                          datetime(1998, 5, 13, 9, 0)])
575
576    def testMonthlyByWeekNoAndWeekDay(self):
577        # That's a nice one. The first days of week number one
578        # may be in the last year.
579        self.assertEqual(list(rrule(MONTHLY,
580                              count=3,
581                              byweekno=1,
582                              byweekday=MO,
583                              dtstart=datetime(1997, 9, 2, 9, 0))),
584                         [datetime(1997, 12, 29, 9, 0),
585                          datetime(1999, 1, 4, 9, 0),
586                          datetime(2000, 1, 3, 9, 0)])
587
588    def testMonthlyByWeekNoAndWeekDayLarge(self):
589        # Another nice test. The last days of week number 52/53
590        # may be in the next year.
591        self.assertEqual(list(rrule(MONTHLY,
592                              count=3,
593                              byweekno=52,
594                              byweekday=SU,
595                              dtstart=datetime(1997, 9, 2, 9, 0))),
596                         [datetime(1997, 12, 28, 9, 0),
597                          datetime(1998, 12, 27, 9, 0),
598                          datetime(2000, 1, 2, 9, 0)])
599
600    def testMonthlyByWeekNoAndWeekDayLast(self):
601        self.assertEqual(list(rrule(MONTHLY,
602                              count=3,
603                              byweekno=-1,
604                              byweekday=SU,
605                              dtstart=datetime(1997, 9, 2, 9, 0))),
606                         [datetime(1997, 12, 28, 9, 0),
607                          datetime(1999, 1, 3, 9, 0),
608                          datetime(2000, 1, 2, 9, 0)])
609
610    def testMonthlyByWeekNoAndWeekDay53(self):
611        self.assertEqual(list(rrule(MONTHLY,
612                              count=3,
613                              byweekno=53,
614                              byweekday=MO,
615                              dtstart=datetime(1997, 9, 2, 9, 0))),
616                         [datetime(1998, 12, 28, 9, 0),
617                          datetime(2004, 12, 27, 9, 0),
618                          datetime(2009, 12, 28, 9, 0)])
619
620    def testMonthlyByEaster(self):
621        self.assertEqual(list(rrule(MONTHLY,
622                              count=3,
623                              byeaster=0,
624                              dtstart=datetime(1997, 9, 2, 9, 0))),
625                         [datetime(1998, 4, 12, 9, 0),
626                          datetime(1999, 4, 4, 9, 0),
627                          datetime(2000, 4, 23, 9, 0)])
628
629    def testMonthlyByEasterPos(self):
630        self.assertEqual(list(rrule(MONTHLY,
631                              count=3,
632                              byeaster=1,
633                              dtstart=datetime(1997, 9, 2, 9, 0))),
634                         [datetime(1998, 4, 13, 9, 0),
635                          datetime(1999, 4, 5, 9, 0),
636                          datetime(2000, 4, 24, 9, 0)])
637
638    def testMonthlyByEasterNeg(self):
639        self.assertEqual(list(rrule(MONTHLY,
640                              count=3,
641                              byeaster=-1,
642                              dtstart=datetime(1997, 9, 2, 9, 0))),
643                         [datetime(1998, 4, 11, 9, 0),
644                          datetime(1999, 4, 3, 9, 0),
645                          datetime(2000, 4, 22, 9, 0)])
646
647    def testMonthlyByHour(self):
648        self.assertEqual(list(rrule(MONTHLY,
649                              count=3,
650                              byhour=(6, 18),
651                              dtstart=datetime(1997, 9, 2, 9, 0))),
652                         [datetime(1997, 9, 2, 18, 0),
653                          datetime(1997, 10, 2, 6, 0),
654                          datetime(1997, 10, 2, 18, 0)])
655
656    def testMonthlyByMinute(self):
657        self.assertEqual(list(rrule(MONTHLY,
658                              count=3,
659                              byminute=(6, 18),
660                              dtstart=datetime(1997, 9, 2, 9, 0))),
661                         [datetime(1997, 9, 2, 9, 6),
662                          datetime(1997, 9, 2, 9, 18),
663                          datetime(1997, 10, 2, 9, 6)])
664
665    def testMonthlyBySecond(self):
666        self.assertEqual(list(rrule(MONTHLY,
667                              count=3,
668                              bysecond=(6, 18),
669                              dtstart=datetime(1997, 9, 2, 9, 0))),
670                         [datetime(1997, 9, 2, 9, 0, 6),
671                          datetime(1997, 9, 2, 9, 0, 18),
672                          datetime(1997, 10, 2, 9, 0, 6)])
673
674    def testMonthlyByHourAndMinute(self):
675        self.assertEqual(list(rrule(MONTHLY,
676                              count=3,
677                              byhour=(6, 18),
678                              byminute=(6, 18),
679                              dtstart=datetime(1997, 9, 2, 9, 0))),
680                         [datetime(1997, 9, 2, 18, 6),
681                          datetime(1997, 9, 2, 18, 18),
682                          datetime(1997, 10, 2, 6, 6)])
683
684    def testMonthlyByHourAndSecond(self):
685        self.assertEqual(list(rrule(MONTHLY,
686                              count=3,
687                              byhour=(6, 18),
688                              bysecond=(6, 18),
689                              dtstart=datetime(1997, 9, 2, 9, 0))),
690                         [datetime(1997, 9, 2, 18, 0, 6),
691                          datetime(1997, 9, 2, 18, 0, 18),
692                          datetime(1997, 10, 2, 6, 0, 6)])
693
694    def testMonthlyByMinuteAndSecond(self):
695        self.assertEqual(list(rrule(MONTHLY,
696                              count=3,
697                              byminute=(6, 18),
698                              bysecond=(6, 18),
699                              dtstart=datetime(1997, 9, 2, 9, 0))),
700                         [datetime(1997, 9, 2, 9, 6, 6),
701                          datetime(1997, 9, 2, 9, 6, 18),
702                          datetime(1997, 9, 2, 9, 18, 6)])
703
704    def testMonthlyByHourAndMinuteAndSecond(self):
705        self.assertEqual(list(rrule(MONTHLY,
706                              count=3,
707                              byhour=(6, 18),
708                              byminute=(6, 18),
709                              bysecond=(6, 18),
710                              dtstart=datetime(1997, 9, 2, 9, 0))),
711                         [datetime(1997, 9, 2, 18, 6, 6),
712                          datetime(1997, 9, 2, 18, 6, 18),
713                          datetime(1997, 9, 2, 18, 18, 6)])
714
715    def testMonthlyBySetPos(self):
716        self.assertEqual(list(rrule(MONTHLY,
717                              count=3,
718                              bymonthday=(13, 17),
719                              byhour=(6, 18),
720                              bysetpos=(3, -3),
721                              dtstart=datetime(1997, 9, 2, 9, 0))),
722                         [datetime(1997, 9, 13, 18, 0),
723                          datetime(1997, 9, 17, 6, 0),
724                          datetime(1997, 10, 13, 18, 0)])
725
726    def testWeekly(self):
727        self.assertEqual(list(rrule(WEEKLY,
728                              count=3,
729                              dtstart=datetime(1997, 9, 2, 9, 0))),
730                         [datetime(1997, 9, 2, 9, 0),
731                          datetime(1997, 9, 9, 9, 0),
732                          datetime(1997, 9, 16, 9, 0)])
733
734    def testWeeklyInterval(self):
735        self.assertEqual(list(rrule(WEEKLY,
736                              count=3,
737                              interval=2,
738                              dtstart=datetime(1997, 9, 2, 9, 0))),
739                         [datetime(1997, 9, 2, 9, 0),
740                          datetime(1997, 9, 16, 9, 0),
741                          datetime(1997, 9, 30, 9, 0)])
742
743    def testWeeklyIntervalLarge(self):
744        self.assertEqual(list(rrule(WEEKLY,
745                              count=3,
746                              interval=20,
747                              dtstart=datetime(1997, 9, 2, 9, 0))),
748                         [datetime(1997, 9, 2, 9, 0),
749                          datetime(1998, 1, 20, 9, 0),
750                          datetime(1998, 6, 9, 9, 0)])
751
752    def testWeeklyByMonth(self):
753        self.assertEqual(list(rrule(WEEKLY,
754                              count=3,
755                              bymonth=(1, 3),
756                              dtstart=datetime(1997, 9, 2, 9, 0))),
757                         [datetime(1998, 1, 6, 9, 0),
758                          datetime(1998, 1, 13, 9, 0),
759                          datetime(1998, 1, 20, 9, 0)])
760
761    def testWeeklyByMonthDay(self):
762        self.assertEqual(list(rrule(WEEKLY,
763                              count=3,
764                              bymonthday=(1, 3),
765                              dtstart=datetime(1997, 9, 2, 9, 0))),
766                         [datetime(1997, 9, 3, 9, 0),
767                          datetime(1997, 10, 1, 9, 0),
768                          datetime(1997, 10, 3, 9, 0)])
769
770    def testWeeklyByMonthAndMonthDay(self):
771        self.assertEqual(list(rrule(WEEKLY,
772                              count=3,
773                              bymonth=(1, 3),
774                              bymonthday=(5, 7),
775                              dtstart=datetime(1997, 9, 2, 9, 0))),
776                         [datetime(1998, 1, 5, 9, 0),
777                          datetime(1998, 1, 7, 9, 0),
778                          datetime(1998, 3, 5, 9, 0)])
779
780    def testWeeklyByWeekDay(self):
781        self.assertEqual(list(rrule(WEEKLY,
782                              count=3,
783                              byweekday=(TU, TH),
784                              dtstart=datetime(1997, 9, 2, 9, 0))),
785                         [datetime(1997, 9, 2, 9, 0),
786                          datetime(1997, 9, 4, 9, 0),
787                          datetime(1997, 9, 9, 9, 0)])
788
789    def testWeeklyByNWeekDay(self):
790        self.assertEqual(list(rrule(WEEKLY,
791                              count=3,
792                              byweekday=(TU(1), TH(-1)),
793                              dtstart=datetime(1997, 9, 2, 9, 0))),
794                         [datetime(1997, 9, 2, 9, 0),
795                          datetime(1997, 9, 4, 9, 0),
796                          datetime(1997, 9, 9, 9, 0)])
797
798    def testWeeklyByMonthAndWeekDay(self):
799        # This test is interesting, because it crosses the year
800        # boundary in a weekly period to find day '1' as a
801        # valid recurrence.
802        self.assertEqual(list(rrule(WEEKLY,
803                              count=3,
804                              bymonth=(1, 3),
805                              byweekday=(TU, TH),
806                              dtstart=datetime(1997, 9, 2, 9, 0))),
807                         [datetime(1998, 1, 1, 9, 0),
808                          datetime(1998, 1, 6, 9, 0),
809                          datetime(1998, 1, 8, 9, 0)])
810
811    def testWeeklyByMonthAndNWeekDay(self):
812        self.assertEqual(list(rrule(WEEKLY,
813                              count=3,
814                              bymonth=(1, 3),
815                              byweekday=(TU(1), TH(-1)),
816                              dtstart=datetime(1997, 9, 2, 9, 0))),
817                         [datetime(1998, 1, 1, 9, 0),
818                          datetime(1998, 1, 6, 9, 0),
819                          datetime(1998, 1, 8, 9, 0)])
820
821    def testWeeklyByMonthDayAndWeekDay(self):
822        self.assertEqual(list(rrule(WEEKLY,
823                              count=3,
824                              bymonthday=(1, 3),
825                              byweekday=(TU, TH),
826                              dtstart=datetime(1997, 9, 2, 9, 0))),
827                         [datetime(1998, 1, 1, 9, 0),
828                          datetime(1998, 2, 3, 9, 0),
829                          datetime(1998, 3, 3, 9, 0)])
830
831    def testWeeklyByMonthAndMonthDayAndWeekDay(self):
832        self.assertEqual(list(rrule(WEEKLY,
833                              count=3,
834                              bymonth=(1, 3),
835                              bymonthday=(1, 3),
836                              byweekday=(TU, TH),
837                              dtstart=datetime(1997, 9, 2, 9, 0))),
838                         [datetime(1998, 1, 1, 9, 0),
839                          datetime(1998, 3, 3, 9, 0),
840                          datetime(2001, 3, 1, 9, 0)])
841
842    def testWeeklyByYearDay(self):
843        self.assertEqual(list(rrule(WEEKLY,
844                              count=4,
845                              byyearday=(1, 100, 200, 365),
846                              dtstart=datetime(1997, 9, 2, 9, 0))),
847                         [datetime(1997, 12, 31, 9, 0),
848                          datetime(1998, 1, 1, 9, 0),
849                          datetime(1998, 4, 10, 9, 0),
850                          datetime(1998, 7, 19, 9, 0)])
851
852    def testWeeklyByYearDayNeg(self):
853        self.assertEqual(list(rrule(WEEKLY,
854                              count=4,
855                              byyearday=(-365, -266, -166, -1),
856                              dtstart=datetime(1997, 9, 2, 9, 0))),
857                         [datetime(1997, 12, 31, 9, 0),
858                          datetime(1998, 1, 1, 9, 0),
859                          datetime(1998, 4, 10, 9, 0),
860                          datetime(1998, 7, 19, 9, 0)])
861
862    def testWeeklyByMonthAndYearDay(self):
863        self.assertEqual(list(rrule(WEEKLY,
864                              count=4,
865                              bymonth=(1, 7),
866                              byyearday=(1, 100, 200, 365),
867                              dtstart=datetime(1997, 9, 2, 9, 0))),
868                         [datetime(1998, 1, 1, 9, 0),
869                          datetime(1998, 7, 19, 9, 0),
870                          datetime(1999, 1, 1, 9, 0),
871                          datetime(1999, 7, 19, 9, 0)])
872
873    def testWeeklyByMonthAndYearDayNeg(self):
874        self.assertEqual(list(rrule(WEEKLY,
875                              count=4,
876                              bymonth=(1, 7),
877                              byyearday=(-365, -266, -166, -1),
878                              dtstart=datetime(1997, 9, 2, 9, 0))),
879                         [datetime(1998, 1, 1, 9, 0),
880                          datetime(1998, 7, 19, 9, 0),
881                          datetime(1999, 1, 1, 9, 0),
882                          datetime(1999, 7, 19, 9, 0)])
883
884    def testWeeklyByWeekNo(self):
885        self.assertEqual(list(rrule(WEEKLY,
886                              count=3,
887                              byweekno=20,
888                              dtstart=datetime(1997, 9, 2, 9, 0))),
889                         [datetime(1998, 5, 11, 9, 0),
890                          datetime(1998, 5, 12, 9, 0),
891                          datetime(1998, 5, 13, 9, 0)])
892
893    def testWeeklyByWeekNoAndWeekDay(self):
894        # That's a nice one. The first days of week number one
895        # may be in the last year.
896        self.assertEqual(list(rrule(WEEKLY,
897                              count=3,
898                              byweekno=1,
899                              byweekday=MO,
900                              dtstart=datetime(1997, 9, 2, 9, 0))),
901                         [datetime(1997, 12, 29, 9, 0),
902                          datetime(1999, 1, 4, 9, 0),
903                          datetime(2000, 1, 3, 9, 0)])
904
905    def testWeeklyByWeekNoAndWeekDayLarge(self):
906        # Another nice test. The last days of week number 52/53
907        # may be in the next year.
908        self.assertEqual(list(rrule(WEEKLY,
909                              count=3,
910                              byweekno=52,
911                              byweekday=SU,
912                              dtstart=datetime(1997, 9, 2, 9, 0))),
913                         [datetime(1997, 12, 28, 9, 0),
914                          datetime(1998, 12, 27, 9, 0),
915                          datetime(2000, 1, 2, 9, 0)])
916
917    def testWeeklyByWeekNoAndWeekDayLast(self):
918        self.assertEqual(list(rrule(WEEKLY,
919                              count=3,
920                              byweekno=-1,
921                              byweekday=SU,
922                              dtstart=datetime(1997, 9, 2, 9, 0))),
923                         [datetime(1997, 12, 28, 9, 0),
924                          datetime(1999, 1, 3, 9, 0),
925                          datetime(2000, 1, 2, 9, 0)])
926
927    def testWeeklyByWeekNoAndWeekDay53(self):
928        self.assertEqual(list(rrule(WEEKLY,
929                              count=3,
930                              byweekno=53,
931                              byweekday=MO,
932                              dtstart=datetime(1997, 9, 2, 9, 0))),
933                         [datetime(1998, 12, 28, 9, 0),
934                          datetime(2004, 12, 27, 9, 0),
935                          datetime(2009, 12, 28, 9, 0)])
936
937    def testWeeklyByEaster(self):
938        self.assertEqual(list(rrule(WEEKLY,
939                              count=3,
940                              byeaster=0,
941                              dtstart=datetime(1997, 9, 2, 9, 0))),
942                         [datetime(1998, 4, 12, 9, 0),
943                          datetime(1999, 4, 4, 9, 0),
944                          datetime(2000, 4, 23, 9, 0)])
945
946    def testWeeklyByEasterPos(self):
947        self.assertEqual(list(rrule(WEEKLY,
948                              count=3,
949                              byeaster=1,
950                              dtstart=datetime(1997, 9, 2, 9, 0))),
951                         [datetime(1998, 4, 13, 9, 0),
952                          datetime(1999, 4, 5, 9, 0),
953                          datetime(2000, 4, 24, 9, 0)])
954
955    def testWeeklyByEasterNeg(self):
956        self.assertEqual(list(rrule(WEEKLY,
957                              count=3,
958                              byeaster=-1,
959                              dtstart=datetime(1997, 9, 2, 9, 0))),
960                         [datetime(1998, 4, 11, 9, 0),
961                          datetime(1999, 4, 3, 9, 0),
962                          datetime(2000, 4, 22, 9, 0)])
963
964    def testWeeklyByHour(self):
965        self.assertEqual(list(rrule(WEEKLY,
966                              count=3,
967                              byhour=(6, 18),
968                              dtstart=datetime(1997, 9, 2, 9, 0))),
969                         [datetime(1997, 9, 2, 18, 0),
970                          datetime(1997, 9, 9, 6, 0),
971                          datetime(1997, 9, 9, 18, 0)])
972
973    def testWeeklyByMinute(self):
974        self.assertEqual(list(rrule(WEEKLY,
975                              count=3,
976                              byminute=(6, 18),
977                              dtstart=datetime(1997, 9, 2, 9, 0))),
978                         [datetime(1997, 9, 2, 9, 6),
979                          datetime(1997, 9, 2, 9, 18),
980                          datetime(1997, 9, 9, 9, 6)])
981
982    def testWeeklyBySecond(self):
983        self.assertEqual(list(rrule(WEEKLY,
984                              count=3,
985                              bysecond=(6, 18),
986                              dtstart=datetime(1997, 9, 2, 9, 0))),
987                         [datetime(1997, 9, 2, 9, 0, 6),
988                          datetime(1997, 9, 2, 9, 0, 18),
989                          datetime(1997, 9, 9, 9, 0, 6)])
990
991    def testWeeklyByHourAndMinute(self):
992        self.assertEqual(list(rrule(WEEKLY,
993                              count=3,
994                              byhour=(6, 18),
995                              byminute=(6, 18),
996                              dtstart=datetime(1997, 9, 2, 9, 0))),
997                         [datetime(1997, 9, 2, 18, 6),
998                          datetime(1997, 9, 2, 18, 18),
999                          datetime(1997, 9, 9, 6, 6)])
1000
1001    def testWeeklyByHourAndSecond(self):
1002        self.assertEqual(list(rrule(WEEKLY,
1003                              count=3,
1004                              byhour=(6, 18),
1005                              bysecond=(6, 18),
1006                              dtstart=datetime(1997, 9, 2, 9, 0))),
1007                         [datetime(1997, 9, 2, 18, 0, 6),
1008                          datetime(1997, 9, 2, 18, 0, 18),
1009                          datetime(1997, 9, 9, 6, 0, 6)])
1010
1011    def testWeeklyByMinuteAndSecond(self):
1012        self.assertEqual(list(rrule(WEEKLY,
1013                              count=3,
1014                              byminute=(6, 18),
1015                              bysecond=(6, 18),
1016                              dtstart=datetime(1997, 9, 2, 9, 0))),
1017                         [datetime(1997, 9, 2, 9, 6, 6),
1018                          datetime(1997, 9, 2, 9, 6, 18),
1019                          datetime(1997, 9, 2, 9, 18, 6)])
1020
1021    def testWeeklyByHourAndMinuteAndSecond(self):
1022        self.assertEqual(list(rrule(WEEKLY,
1023                              count=3,
1024                              byhour=(6, 18),
1025                              byminute=(6, 18),
1026                              bysecond=(6, 18),
1027                              dtstart=datetime(1997, 9, 2, 9, 0))),
1028                         [datetime(1997, 9, 2, 18, 6, 6),
1029                          datetime(1997, 9, 2, 18, 6, 18),
1030                          datetime(1997, 9, 2, 18, 18, 6)])
1031
1032    def testWeeklyBySetPos(self):
1033        self.assertEqual(list(rrule(WEEKLY,
1034                              count=3,
1035                              byweekday=(TU, TH),
1036                              byhour=(6, 18),
1037                              bysetpos=(3, -3),
1038                              dtstart=datetime(1997, 9, 2, 9, 0))),
1039                         [datetime(1997, 9, 2, 18, 0),
1040                          datetime(1997, 9, 4, 6, 0),
1041                          datetime(1997, 9, 9, 18, 0)])
1042
1043    def testDaily(self):
1044        self.assertEqual(list(rrule(DAILY,
1045                              count=3,
1046                              dtstart=datetime(1997, 9, 2, 9, 0))),
1047                         [datetime(1997, 9, 2, 9, 0),
1048                          datetime(1997, 9, 3, 9, 0),
1049                          datetime(1997, 9, 4, 9, 0)])
1050
1051    def testDailyInterval(self):
1052        self.assertEqual(list(rrule(DAILY,
1053                              count=3,
1054                              interval=2,
1055                              dtstart=datetime(1997, 9, 2, 9, 0))),
1056                         [datetime(1997, 9, 2, 9, 0),
1057                          datetime(1997, 9, 4, 9, 0),
1058                          datetime(1997, 9, 6, 9, 0)])
1059
1060    def testDailyIntervalLarge(self):
1061        self.assertEqual(list(rrule(DAILY,
1062                              count=3,
1063                              interval=92,
1064                              dtstart=datetime(1997, 9, 2, 9, 0))),
1065                         [datetime(1997, 9, 2, 9, 0),
1066                          datetime(1997, 12, 3, 9, 0),
1067                          datetime(1998, 3, 5, 9, 0)])
1068
1069    def testDailyByMonth(self):
1070        self.assertEqual(list(rrule(DAILY,
1071                              count=3,
1072                              bymonth=(1, 3),
1073                              dtstart=datetime(1997, 9, 2, 9, 0))),
1074                         [datetime(1998, 1, 1, 9, 0),
1075                          datetime(1998, 1, 2, 9, 0),
1076                          datetime(1998, 1, 3, 9, 0)])
1077
1078    def testDailyByMonthDay(self):
1079        self.assertEqual(list(rrule(DAILY,
1080                              count=3,
1081                              bymonthday=(1, 3),
1082                              dtstart=datetime(1997, 9, 2, 9, 0))),
1083                         [datetime(1997, 9, 3, 9, 0),
1084                          datetime(1997, 10, 1, 9, 0),
1085                          datetime(1997, 10, 3, 9, 0)])
1086
1087    def testDailyByMonthAndMonthDay(self):
1088        self.assertEqual(list(rrule(DAILY,
1089                              count=3,
1090                              bymonth=(1, 3),
1091                              bymonthday=(5, 7),
1092                              dtstart=datetime(1997, 9, 2, 9, 0))),
1093                         [datetime(1998, 1, 5, 9, 0),
1094                          datetime(1998, 1, 7, 9, 0),
1095                          datetime(1998, 3, 5, 9, 0)])
1096
1097    def testDailyByWeekDay(self):
1098        self.assertEqual(list(rrule(DAILY,
1099                              count=3,
1100                              byweekday=(TU, TH),
1101                              dtstart=datetime(1997, 9, 2, 9, 0))),
1102                         [datetime(1997, 9, 2, 9, 0),
1103                          datetime(1997, 9, 4, 9, 0),
1104                          datetime(1997, 9, 9, 9, 0)])
1105
1106    def testDailyByNWeekDay(self):
1107        self.assertEqual(list(rrule(DAILY,
1108                              count=3,
1109                              byweekday=(TU(1), TH(-1)),
1110                              dtstart=datetime(1997, 9, 2, 9, 0))),
1111                         [datetime(1997, 9, 2, 9, 0),
1112                          datetime(1997, 9, 4, 9, 0),
1113                          datetime(1997, 9, 9, 9, 0)])
1114
1115    def testDailyByMonthAndWeekDay(self):
1116        self.assertEqual(list(rrule(DAILY,
1117                              count=3,
1118                              bymonth=(1, 3),
1119                              byweekday=(TU, TH),
1120                              dtstart=datetime(1997, 9, 2, 9, 0))),
1121                         [datetime(1998, 1, 1, 9, 0),
1122                          datetime(1998, 1, 6, 9, 0),
1123                          datetime(1998, 1, 8, 9, 0)])
1124
1125    def testDailyByMonthAndNWeekDay(self):
1126        self.assertEqual(list(rrule(DAILY,
1127                              count=3,
1128                              bymonth=(1, 3),
1129                              byweekday=(TU(1), TH(-1)),
1130                              dtstart=datetime(1997, 9, 2, 9, 0))),
1131                         [datetime(1998, 1, 1, 9, 0),
1132                          datetime(1998, 1, 6, 9, 0),
1133                          datetime(1998, 1, 8, 9, 0)])
1134
1135    def testDailyByMonthDayAndWeekDay(self):
1136        self.assertEqual(list(rrule(DAILY,
1137                              count=3,
1138                              bymonthday=(1, 3),
1139                              byweekday=(TU, TH),
1140                              dtstart=datetime(1997, 9, 2, 9, 0))),
1141                         [datetime(1998, 1, 1, 9, 0),
1142                          datetime(1998, 2, 3, 9, 0),
1143                          datetime(1998, 3, 3, 9, 0)])
1144
1145    def testDailyByMonthAndMonthDayAndWeekDay(self):
1146        self.assertEqual(list(rrule(DAILY,
1147                              count=3,
1148                              bymonth=(1, 3),
1149                              bymonthday=(1, 3),
1150                              byweekday=(TU, TH),
1151                              dtstart=datetime(1997, 9, 2, 9, 0))),
1152                         [datetime(1998, 1, 1, 9, 0),
1153                          datetime(1998, 3, 3, 9, 0),
1154                          datetime(2001, 3, 1, 9, 0)])
1155
1156    def testDailyByYearDay(self):
1157        self.assertEqual(list(rrule(DAILY,
1158                              count=4,
1159                              byyearday=(1, 100, 200, 365),
1160                              dtstart=datetime(1997, 9, 2, 9, 0))),
1161                         [datetime(1997, 12, 31, 9, 0),
1162                          datetime(1998, 1, 1, 9, 0),
1163                          datetime(1998, 4, 10, 9, 0),
1164                          datetime(1998, 7, 19, 9, 0)])
1165
1166    def testDailyByYearDayNeg(self):
1167        self.assertEqual(list(rrule(DAILY,
1168                              count=4,
1169                              byyearday=(-365, -266, -166, -1),
1170                              dtstart=datetime(1997, 9, 2, 9, 0))),
1171                         [datetime(1997, 12, 31, 9, 0),
1172                          datetime(1998, 1, 1, 9, 0),
1173                          datetime(1998, 4, 10, 9, 0),
1174                          datetime(1998, 7, 19, 9, 0)])
1175
1176    def testDailyByMonthAndYearDay(self):
1177        self.assertEqual(list(rrule(DAILY,
1178                              count=4,
1179                              bymonth=(1, 7),
1180                              byyearday=(1, 100, 200, 365),
1181                              dtstart=datetime(1997, 9, 2, 9, 0))),
1182                         [datetime(1998, 1, 1, 9, 0),
1183                          datetime(1998, 7, 19, 9, 0),
1184                          datetime(1999, 1, 1, 9, 0),
1185                          datetime(1999, 7, 19, 9, 0)])
1186
1187    def testDailyByMonthAndYearDayNeg(self):
1188        self.assertEqual(list(rrule(DAILY,
1189                              count=4,
1190                              bymonth=(1, 7),
1191                              byyearday=(-365, -266, -166, -1),
1192                              dtstart=datetime(1997, 9, 2, 9, 0))),
1193                         [datetime(1998, 1, 1, 9, 0),
1194                          datetime(1998, 7, 19, 9, 0),
1195                          datetime(1999, 1, 1, 9, 0),
1196                          datetime(1999, 7, 19, 9, 0)])
1197
1198    def testDailyByWeekNo(self):
1199        self.assertEqual(list(rrule(DAILY,
1200                              count=3,
1201                              byweekno=20,
1202                              dtstart=datetime(1997, 9, 2, 9, 0))),
1203                         [datetime(1998, 5, 11, 9, 0),
1204                          datetime(1998, 5, 12, 9, 0),
1205                          datetime(1998, 5, 13, 9, 0)])
1206
1207    def testDailyByWeekNoAndWeekDay(self):
1208        # That's a nice one. The first days of week number one
1209        # may be in the last year.
1210        self.assertEqual(list(rrule(DAILY,
1211                              count=3,
1212                              byweekno=1,
1213                              byweekday=MO,
1214                              dtstart=datetime(1997, 9, 2, 9, 0))),
1215                         [datetime(1997, 12, 29, 9, 0),
1216                          datetime(1999, 1, 4, 9, 0),
1217                          datetime(2000, 1, 3, 9, 0)])
1218
1219    def testDailyByWeekNoAndWeekDayLarge(self):
1220        # Another nice test. The last days of week number 52/53
1221        # may be in the next year.
1222        self.assertEqual(list(rrule(DAILY,
1223                              count=3,
1224                              byweekno=52,
1225                              byweekday=SU,
1226                              dtstart=datetime(1997, 9, 2, 9, 0))),
1227                         [datetime(1997, 12, 28, 9, 0),
1228                          datetime(1998, 12, 27, 9, 0),
1229                          datetime(2000, 1, 2, 9, 0)])
1230
1231    def testDailyByWeekNoAndWeekDayLast(self):
1232        self.assertEqual(list(rrule(DAILY,
1233                              count=3,
1234                              byweekno=-1,
1235                              byweekday=SU,
1236                              dtstart=datetime(1997, 9, 2, 9, 0))),
1237                         [datetime(1997, 12, 28, 9, 0),
1238                          datetime(1999, 1, 3, 9, 0),
1239                          datetime(2000, 1, 2, 9, 0)])
1240
1241    def testDailyByWeekNoAndWeekDay53(self):
1242        self.assertEqual(list(rrule(DAILY,
1243                              count=3,
1244                              byweekno=53,
1245                              byweekday=MO,
1246                              dtstart=datetime(1997, 9, 2, 9, 0))),
1247                         [datetime(1998, 12, 28, 9, 0),
1248                          datetime(2004, 12, 27, 9, 0),
1249                          datetime(2009, 12, 28, 9, 0)])
1250
1251    def testDailyByEaster(self):
1252        self.assertEqual(list(rrule(DAILY,
1253                              count=3,
1254                              byeaster=0,
1255                              dtstart=datetime(1997, 9, 2, 9, 0))),
1256                         [datetime(1998, 4, 12, 9, 0),
1257                          datetime(1999, 4, 4, 9, 0),
1258                          datetime(2000, 4, 23, 9, 0)])
1259
1260    def testDailyByEasterPos(self):
1261        self.assertEqual(list(rrule(DAILY,
1262                              count=3,
1263                              byeaster=1,
1264                              dtstart=datetime(1997, 9, 2, 9, 0))),
1265                         [datetime(1998, 4, 13, 9, 0),
1266                          datetime(1999, 4, 5, 9, 0),
1267                          datetime(2000, 4, 24, 9, 0)])
1268
1269    def testDailyByEasterNeg(self):
1270        self.assertEqual(list(rrule(DAILY,
1271                              count=3,
1272                              byeaster=-1,
1273                              dtstart=datetime(1997, 9, 2, 9, 0))),
1274                         [datetime(1998, 4, 11, 9, 0),
1275                          datetime(1999, 4, 3, 9, 0),
1276                          datetime(2000, 4, 22, 9, 0)])
1277
1278    def testDailyByHour(self):
1279        self.assertEqual(list(rrule(DAILY,
1280                              count=3,
1281                              byhour=(6, 18),
1282                              dtstart=datetime(1997, 9, 2, 9, 0))),
1283                         [datetime(1997, 9, 2, 18, 0),
1284                          datetime(1997, 9, 3, 6, 0),
1285                          datetime(1997, 9, 3, 18, 0)])
1286
1287    def testDailyByMinute(self):
1288        self.assertEqual(list(rrule(DAILY,
1289                              count=3,
1290                              byminute=(6, 18),
1291                              dtstart=datetime(1997, 9, 2, 9, 0))),
1292                         [datetime(1997, 9, 2, 9, 6),
1293                          datetime(1997, 9, 2, 9, 18),
1294                          datetime(1997, 9, 3, 9, 6)])
1295
1296    def testDailyBySecond(self):
1297        self.assertEqual(list(rrule(DAILY,
1298                              count=3,
1299                              bysecond=(6, 18),
1300                              dtstart=datetime(1997, 9, 2, 9, 0))),
1301                         [datetime(1997, 9, 2, 9, 0, 6),
1302                          datetime(1997, 9, 2, 9, 0, 18),
1303                          datetime(1997, 9, 3, 9, 0, 6)])
1304
1305    def testDailyByHourAndMinute(self):
1306        self.assertEqual(list(rrule(DAILY,
1307                              count=3,
1308                              byhour=(6, 18),
1309                              byminute=(6, 18),
1310                              dtstart=datetime(1997, 9, 2, 9, 0))),
1311                         [datetime(1997, 9, 2, 18, 6),
1312                          datetime(1997, 9, 2, 18, 18),
1313                          datetime(1997, 9, 3, 6, 6)])
1314
1315    def testDailyByHourAndSecond(self):
1316        self.assertEqual(list(rrule(DAILY,
1317                              count=3,
1318                              byhour=(6, 18),
1319                              bysecond=(6, 18),
1320                              dtstart=datetime(1997, 9, 2, 9, 0))),
1321                         [datetime(1997, 9, 2, 18, 0, 6),
1322                          datetime(1997, 9, 2, 18, 0, 18),
1323                          datetime(1997, 9, 3, 6, 0, 6)])
1324
1325    def testDailyByMinuteAndSecond(self):
1326        self.assertEqual(list(rrule(DAILY,
1327                              count=3,
1328                              byminute=(6, 18),
1329                              bysecond=(6, 18),
1330                              dtstart=datetime(1997, 9, 2, 9, 0))),
1331                         [datetime(1997, 9, 2, 9, 6, 6),
1332                          datetime(1997, 9, 2, 9, 6, 18),
1333                          datetime(1997, 9, 2, 9, 18, 6)])
1334
1335    def testDailyByHourAndMinuteAndSecond(self):
1336        self.assertEqual(list(rrule(DAILY,
1337                              count=3,
1338                              byhour=(6, 18),
1339                              byminute=(6, 18),
1340                              bysecond=(6, 18),
1341                              dtstart=datetime(1997, 9, 2, 9, 0))),
1342                         [datetime(1997, 9, 2, 18, 6, 6),
1343                          datetime(1997, 9, 2, 18, 6, 18),
1344                          datetime(1997, 9, 2, 18, 18, 6)])
1345
1346    def testDailyBySetPos(self):
1347        self.assertEqual(list(rrule(DAILY,
1348                              count=3,
1349                              byhour=(6, 18),
1350                              byminute=(15, 45),
1351                              bysetpos=(3, -3),
1352                              dtstart=datetime(1997, 9, 2, 9, 0))),
1353                         [datetime(1997, 9, 2, 18, 15),
1354                          datetime(1997, 9, 3, 6, 45),
1355                          datetime(1997, 9, 3, 18, 15)])
1356
1357    def testHourly(self):
1358        self.assertEqual(list(rrule(HOURLY,
1359                              count=3,
1360                              dtstart=datetime(1997, 9, 2, 9, 0))),
1361                         [datetime(1997, 9, 2, 9, 0),
1362                          datetime(1997, 9, 2, 10, 0),
1363                          datetime(1997, 9, 2, 11, 0)])
1364
1365    def testHourlyInterval(self):
1366        self.assertEqual(list(rrule(HOURLY,
1367                              count=3,
1368                              interval=2,
1369                              dtstart=datetime(1997, 9, 2, 9, 0))),
1370                         [datetime(1997, 9, 2, 9, 0),
1371                          datetime(1997, 9, 2, 11, 0),
1372                          datetime(1997, 9, 2, 13, 0)])
1373
1374    def testHourlyIntervalLarge(self):
1375        self.assertEqual(list(rrule(HOURLY,
1376                              count=3,
1377                              interval=769,
1378                              dtstart=datetime(1997, 9, 2, 9, 0))),
1379                         [datetime(1997, 9, 2, 9, 0),
1380                          datetime(1997, 10, 4, 10, 0),
1381                          datetime(1997, 11, 5, 11, 0)])
1382
1383    def testHourlyByMonth(self):
1384        self.assertEqual(list(rrule(HOURLY,
1385                              count=3,
1386                              bymonth=(1, 3),
1387                              dtstart=datetime(1997, 9, 2, 9, 0))),
1388                         [datetime(1998, 1, 1, 0, 0),
1389                          datetime(1998, 1, 1, 1, 0),
1390                          datetime(1998, 1, 1, 2, 0)])
1391
1392    def testHourlyByMonthDay(self):
1393        self.assertEqual(list(rrule(HOURLY,
1394                              count=3,
1395                              bymonthday=(1, 3),
1396                              dtstart=datetime(1997, 9, 2, 9, 0))),
1397                         [datetime(1997, 9, 3, 0, 0),
1398                          datetime(1997, 9, 3, 1, 0),
1399                          datetime(1997, 9, 3, 2, 0)])
1400
1401    def testHourlyByMonthAndMonthDay(self):
1402        self.assertEqual(list(rrule(HOURLY,
1403                              count=3,
1404                              bymonth=(1, 3),
1405                              bymonthday=(5, 7),
1406                              dtstart=datetime(1997, 9, 2, 9, 0))),
1407                         [datetime(1998, 1, 5, 0, 0),
1408                          datetime(1998, 1, 5, 1, 0),
1409                          datetime(1998, 1, 5, 2, 0)])
1410
1411    def testHourlyByWeekDay(self):
1412        self.assertEqual(list(rrule(HOURLY,
1413                              count=3,
1414                              byweekday=(TU, TH),
1415                              dtstart=datetime(1997, 9, 2, 9, 0))),
1416                         [datetime(1997, 9, 2, 9, 0),
1417                          datetime(1997, 9, 2, 10, 0),
1418                          datetime(1997, 9, 2, 11, 0)])
1419
1420    def testHourlyByNWeekDay(self):
1421        self.assertEqual(list(rrule(HOURLY,
1422                              count=3,
1423                              byweekday=(TU(1), TH(-1)),
1424                              dtstart=datetime(1997, 9, 2, 9, 0))),
1425                         [datetime(1997, 9, 2, 9, 0),
1426                          datetime(1997, 9, 2, 10, 0),
1427                          datetime(1997, 9, 2, 11, 0)])
1428
1429    def testHourlyByMonthAndWeekDay(self):
1430        self.assertEqual(list(rrule(HOURLY,
1431                              count=3,
1432                              bymonth=(1, 3),
1433                              byweekday=(TU, TH),
1434                              dtstart=datetime(1997, 9, 2, 9, 0))),
1435                         [datetime(1998, 1, 1, 0, 0),
1436                          datetime(1998, 1, 1, 1, 0),
1437                          datetime(1998, 1, 1, 2, 0)])
1438
1439    def testHourlyByMonthAndNWeekDay(self):
1440        self.assertEqual(list(rrule(HOURLY,
1441                              count=3,
1442                              bymonth=(1, 3),
1443                              byweekday=(TU(1), TH(-1)),
1444                              dtstart=datetime(1997, 9, 2, 9, 0))),
1445                         [datetime(1998, 1, 1, 0, 0),
1446                          datetime(1998, 1, 1, 1, 0),
1447                          datetime(1998, 1, 1, 2, 0)])
1448
1449    def testHourlyByMonthDayAndWeekDay(self):
1450        self.assertEqual(list(rrule(HOURLY,
1451                              count=3,
1452                              bymonthday=(1, 3),
1453                              byweekday=(TU, TH),
1454                              dtstart=datetime(1997, 9, 2, 9, 0))),
1455                         [datetime(1998, 1, 1, 0, 0),
1456                          datetime(1998, 1, 1, 1, 0),
1457                          datetime(1998, 1, 1, 2, 0)])
1458
1459    def testHourlyByMonthAndMonthDayAndWeekDay(self):
1460        self.assertEqual(list(rrule(HOURLY,
1461                              count=3,
1462                              bymonth=(1, 3),
1463                              bymonthday=(1, 3),
1464                              byweekday=(TU, TH),
1465                              dtstart=datetime(1997, 9, 2, 9, 0))),
1466                         [datetime(1998, 1, 1, 0, 0),
1467                          datetime(1998, 1, 1, 1, 0),
1468                          datetime(1998, 1, 1, 2, 0)])
1469
1470    def testHourlyByYearDay(self):
1471        self.assertEqual(list(rrule(HOURLY,
1472                              count=4,
1473                              byyearday=(1, 100, 200, 365),
1474                              dtstart=datetime(1997, 9, 2, 9, 0))),
1475                         [datetime(1997, 12, 31, 0, 0),
1476                          datetime(1997, 12, 31, 1, 0),
1477                          datetime(1997, 12, 31, 2, 0),
1478                          datetime(1997, 12, 31, 3, 0)])
1479
1480    def testHourlyByYearDayNeg(self):
1481        self.assertEqual(list(rrule(HOURLY,
1482                              count=4,
1483                              byyearday=(-365, -266, -166, -1),
1484                              dtstart=datetime(1997, 9, 2, 9, 0))),
1485                         [datetime(1997, 12, 31, 0, 0),
1486                          datetime(1997, 12, 31, 1, 0),
1487                          datetime(1997, 12, 31, 2, 0),
1488                          datetime(1997, 12, 31, 3, 0)])
1489
1490    def testHourlyByMonthAndYearDay(self):
1491        self.assertEqual(list(rrule(HOURLY,
1492                              count=4,
1493                              bymonth=(4, 7),
1494                              byyearday=(1, 100, 200, 365),
1495                              dtstart=datetime(1997, 9, 2, 9, 0))),
1496                         [datetime(1998, 4, 10, 0, 0),
1497                          datetime(1998, 4, 10, 1, 0),
1498                          datetime(1998, 4, 10, 2, 0),
1499                          datetime(1998, 4, 10, 3, 0)])
1500
1501    def testHourlyByMonthAndYearDayNeg(self):
1502        self.assertEqual(list(rrule(HOURLY,
1503                              count=4,
1504                              bymonth=(4, 7),
1505                              byyearday=(-365, -266, -166, -1),
1506                              dtstart=datetime(1997, 9, 2, 9, 0))),
1507                         [datetime(1998, 4, 10, 0, 0),
1508                          datetime(1998, 4, 10, 1, 0),
1509                          datetime(1998, 4, 10, 2, 0),
1510                          datetime(1998, 4, 10, 3, 0)])
1511
1512    def testHourlyByWeekNo(self):
1513        self.assertEqual(list(rrule(HOURLY,
1514                              count=3,
1515                              byweekno=20,
1516                              dtstart=datetime(1997, 9, 2, 9, 0))),
1517                         [datetime(1998, 5, 11, 0, 0),
1518                          datetime(1998, 5, 11, 1, 0),
1519                          datetime(1998, 5, 11, 2, 0)])
1520
1521    def testHourlyByWeekNoAndWeekDay(self):
1522        self.assertEqual(list(rrule(HOURLY,
1523                              count=3,
1524                              byweekno=1,
1525                              byweekday=MO,
1526                              dtstart=datetime(1997, 9, 2, 9, 0))),
1527                         [datetime(1997, 12, 29, 0, 0),
1528                          datetime(1997, 12, 29, 1, 0),
1529                          datetime(1997, 12, 29, 2, 0)])
1530
1531    def testHourlyByWeekNoAndWeekDayLarge(self):
1532        self.assertEqual(list(rrule(HOURLY,
1533                              count=3,
1534                              byweekno=52,
1535                              byweekday=SU,
1536                              dtstart=datetime(1997, 9, 2, 9, 0))),
1537                         [datetime(1997, 12, 28, 0, 0),
1538                          datetime(1997, 12, 28, 1, 0),
1539                          datetime(1997, 12, 28, 2, 0)])
1540
1541    def testHourlyByWeekNoAndWeekDayLast(self):
1542        self.assertEqual(list(rrule(HOURLY,
1543                              count=3,
1544                              byweekno=-1,
1545                              byweekday=SU,
1546                              dtstart=datetime(1997, 9, 2, 9, 0))),
1547                         [datetime(1997, 12, 28, 0, 0),
1548                          datetime(1997, 12, 28, 1, 0),
1549                          datetime(1997, 12, 28, 2, 0)])
1550
1551    def testHourlyByWeekNoAndWeekDay53(self):
1552        self.assertEqual(list(rrule(HOURLY,
1553                              count=3,
1554                              byweekno=53,
1555                              byweekday=MO,
1556                              dtstart=datetime(1997, 9, 2, 9, 0))),
1557                         [datetime(1998, 12, 28, 0, 0),
1558                          datetime(1998, 12, 28, 1, 0),
1559                          datetime(1998, 12, 28, 2, 0)])
1560
1561    def testHourlyByEaster(self):
1562        self.assertEqual(list(rrule(HOURLY,
1563                              count=3,
1564                              byeaster=0,
1565                              dtstart=datetime(1997, 9, 2, 9, 0))),
1566                         [datetime(1998, 4, 12, 0, 0),
1567                          datetime(1998, 4, 12, 1, 0),
1568                          datetime(1998, 4, 12, 2, 0)])
1569
1570    def testHourlyByEasterPos(self):
1571        self.assertEqual(list(rrule(HOURLY,
1572                              count=3,
1573                              byeaster=1,
1574                              dtstart=datetime(1997, 9, 2, 9, 0))),
1575                         [datetime(1998, 4, 13, 0, 0),
1576                          datetime(1998, 4, 13, 1, 0),
1577                          datetime(1998, 4, 13, 2, 0)])
1578
1579    def testHourlyByEasterNeg(self):
1580        self.assertEqual(list(rrule(HOURLY,
1581                              count=3,
1582                              byeaster=-1,
1583                              dtstart=datetime(1997, 9, 2, 9, 0))),
1584                         [datetime(1998, 4, 11, 0, 0),
1585                          datetime(1998, 4, 11, 1, 0),
1586                          datetime(1998, 4, 11, 2, 0)])
1587
1588    def testHourlyByHour(self):
1589        self.assertEqual(list(rrule(HOURLY,
1590                              count=3,
1591                              byhour=(6, 18),
1592                              dtstart=datetime(1997, 9, 2, 9, 0))),
1593                         [datetime(1997, 9, 2, 18, 0),
1594                          datetime(1997, 9, 3, 6, 0),
1595                          datetime(1997, 9, 3, 18, 0)])
1596
1597    def testHourlyByMinute(self):
1598        self.assertEqual(list(rrule(HOURLY,
1599                              count=3,
1600                              byminute=(6, 18),
1601                              dtstart=datetime(1997, 9, 2, 9, 0))),
1602                         [datetime(1997, 9, 2, 9, 6),
1603                          datetime(1997, 9, 2, 9, 18),
1604                          datetime(1997, 9, 2, 10, 6)])
1605
1606    def testHourlyBySecond(self):
1607        self.assertEqual(list(rrule(HOURLY,
1608                              count=3,
1609                              bysecond=(6, 18),
1610                              dtstart=datetime(1997, 9, 2, 9, 0))),
1611                         [datetime(1997, 9, 2, 9, 0, 6),
1612                          datetime(1997, 9, 2, 9, 0, 18),
1613                          datetime(1997, 9, 2, 10, 0, 6)])
1614
1615    def testHourlyByHourAndMinute(self):
1616        self.assertEqual(list(rrule(HOURLY,
1617                              count=3,
1618                              byhour=(6, 18),
1619                              byminute=(6, 18),
1620                              dtstart=datetime(1997, 9, 2, 9, 0))),
1621                         [datetime(1997, 9, 2, 18, 6),
1622                          datetime(1997, 9, 2, 18, 18),
1623                          datetime(1997, 9, 3, 6, 6)])
1624
1625    def testHourlyByHourAndSecond(self):
1626        self.assertEqual(list(rrule(HOURLY,
1627                              count=3,
1628                              byhour=(6, 18),
1629                              bysecond=(6, 18),
1630                              dtstart=datetime(1997, 9, 2, 9, 0))),
1631                         [datetime(1997, 9, 2, 18, 0, 6),
1632                          datetime(1997, 9, 2, 18, 0, 18),
1633                          datetime(1997, 9, 3, 6, 0, 6)])
1634
1635    def testHourlyByMinuteAndSecond(self):
1636        self.assertEqual(list(rrule(HOURLY,
1637                              count=3,
1638                              byminute=(6, 18),
1639                              bysecond=(6, 18),
1640                              dtstart=datetime(1997, 9, 2, 9, 0))),
1641                         [datetime(1997, 9, 2, 9, 6, 6),
1642                          datetime(1997, 9, 2, 9, 6, 18),
1643                          datetime(1997, 9, 2, 9, 18, 6)])
1644
1645    def testHourlyByHourAndMinuteAndSecond(self):
1646        self.assertEqual(list(rrule(HOURLY,
1647                              count=3,
1648                              byhour=(6, 18),
1649                              byminute=(6, 18),
1650                              bysecond=(6, 18),
1651                              dtstart=datetime(1997, 9, 2, 9, 0))),
1652                         [datetime(1997, 9, 2, 18, 6, 6),
1653                          datetime(1997, 9, 2, 18, 6, 18),
1654                          datetime(1997, 9, 2, 18, 18, 6)])
1655
1656    def testHourlyBySetPos(self):
1657        self.assertEqual(list(rrule(HOURLY,
1658                              count=3,
1659                              byminute=(15, 45),
1660                              bysecond=(15, 45),
1661                              bysetpos=(3, -3),
1662                              dtstart=datetime(1997, 9, 2, 9, 0))),
1663                         [datetime(1997, 9, 2, 9, 15, 45),
1664                          datetime(1997, 9, 2, 9, 45, 15),
1665                          datetime(1997, 9, 2, 10, 15, 45)])
1666
1667    def testMinutely(self):
1668        self.assertEqual(list(rrule(MINUTELY,
1669                              count=3,
1670                              dtstart=datetime(1997, 9, 2, 9, 0))),
1671                         [datetime(1997, 9, 2, 9, 0),
1672                          datetime(1997, 9, 2, 9, 1),
1673                          datetime(1997, 9, 2, 9, 2)])
1674
1675    def testMinutelyInterval(self):
1676        self.assertEqual(list(rrule(MINUTELY,
1677                              count=3,
1678                              interval=2,
1679                              dtstart=datetime(1997, 9, 2, 9, 0))),
1680                         [datetime(1997, 9, 2, 9, 0),
1681                          datetime(1997, 9, 2, 9, 2),
1682                          datetime(1997, 9, 2, 9, 4)])
1683
1684    def testMinutelyIntervalLarge(self):
1685        self.assertEqual(list(rrule(MINUTELY,
1686                              count=3,
1687                              interval=1501,
1688                              dtstart=datetime(1997, 9, 2, 9, 0))),
1689                         [datetime(1997, 9, 2, 9, 0),
1690                          datetime(1997, 9, 3, 10, 1),
1691                          datetime(1997, 9, 4, 11, 2)])
1692
1693    def testMinutelyByMonth(self):
1694        self.assertEqual(list(rrule(MINUTELY,
1695                              count=3,
1696                              bymonth=(1, 3),
1697                              dtstart=datetime(1997, 9, 2, 9, 0))),
1698                         [datetime(1998, 1, 1, 0, 0),
1699                          datetime(1998, 1, 1, 0, 1),
1700                          datetime(1998, 1, 1, 0, 2)])
1701
1702    def testMinutelyByMonthDay(self):
1703        self.assertEqual(list(rrule(MINUTELY,
1704                              count=3,
1705                              bymonthday=(1, 3),
1706                              dtstart=datetime(1997, 9, 2, 9, 0))),
1707                         [datetime(1997, 9, 3, 0, 0),
1708                          datetime(1997, 9, 3, 0, 1),
1709                          datetime(1997, 9, 3, 0, 2)])
1710
1711    def testMinutelyByMonthAndMonthDay(self):
1712        self.assertEqual(list(rrule(MINUTELY,
1713                              count=3,
1714                              bymonth=(1, 3),
1715                              bymonthday=(5, 7),
1716                              dtstart=datetime(1997, 9, 2, 9, 0))),
1717                         [datetime(1998, 1, 5, 0, 0),
1718                          datetime(1998, 1, 5, 0, 1),
1719                          datetime(1998, 1, 5, 0, 2)])
1720
1721    def testMinutelyByWeekDay(self):
1722        self.assertEqual(list(rrule(MINUTELY,
1723                              count=3,
1724                              byweekday=(TU, TH),
1725                              dtstart=datetime(1997, 9, 2, 9, 0))),
1726                         [datetime(1997, 9, 2, 9, 0),
1727                          datetime(1997, 9, 2, 9, 1),
1728                          datetime(1997, 9, 2, 9, 2)])
1729
1730    def testMinutelyByNWeekDay(self):
1731        self.assertEqual(list(rrule(MINUTELY,
1732                              count=3,
1733                              byweekday=(TU(1), TH(-1)),
1734                              dtstart=datetime(1997, 9, 2, 9, 0))),
1735                         [datetime(1997, 9, 2, 9, 0),
1736                          datetime(1997, 9, 2, 9, 1),
1737                          datetime(1997, 9, 2, 9, 2)])
1738
1739    def testMinutelyByMonthAndWeekDay(self):
1740        self.assertEqual(list(rrule(MINUTELY,
1741                              count=3,
1742                              bymonth=(1, 3),
1743                              byweekday=(TU, TH),
1744                              dtstart=datetime(1997, 9, 2, 9, 0))),
1745                         [datetime(1998, 1, 1, 0, 0),
1746                          datetime(1998, 1, 1, 0, 1),
1747                          datetime(1998, 1, 1, 0, 2)])
1748
1749    def testMinutelyByMonthAndNWeekDay(self):
1750        self.assertEqual(list(rrule(MINUTELY,
1751                              count=3,
1752                              bymonth=(1, 3),
1753                              byweekday=(TU(1), TH(-1)),
1754                              dtstart=datetime(1997, 9, 2, 9, 0))),
1755                         [datetime(1998, 1, 1, 0, 0),
1756                          datetime(1998, 1, 1, 0, 1),
1757                          datetime(1998, 1, 1, 0, 2)])
1758
1759    def testMinutelyByMonthDayAndWeekDay(self):
1760        self.assertEqual(list(rrule(MINUTELY,
1761                              count=3,
1762                              bymonthday=(1, 3),
1763                              byweekday=(TU, TH),
1764                              dtstart=datetime(1997, 9, 2, 9, 0))),
1765                         [datetime(1998, 1, 1, 0, 0),
1766                          datetime(1998, 1, 1, 0, 1),
1767                          datetime(1998, 1, 1, 0, 2)])
1768
1769    def testMinutelyByMonthAndMonthDayAndWeekDay(self):
1770        self.assertEqual(list(rrule(MINUTELY,
1771                              count=3,
1772                              bymonth=(1, 3),
1773                              bymonthday=(1, 3),
1774                              byweekday=(TU, TH),
1775                              dtstart=datetime(1997, 9, 2, 9, 0))),
1776                         [datetime(1998, 1, 1, 0, 0),
1777                          datetime(1998, 1, 1, 0, 1),
1778                          datetime(1998, 1, 1, 0, 2)])
1779
1780    def testMinutelyByYearDay(self):
1781        self.assertEqual(list(rrule(MINUTELY,
1782                              count=4,
1783                              byyearday=(1, 100, 200, 365),
1784                              dtstart=datetime(1997, 9, 2, 9, 0))),
1785                         [datetime(1997, 12, 31, 0, 0),
1786                          datetime(1997, 12, 31, 0, 1),
1787                          datetime(1997, 12, 31, 0, 2),
1788                          datetime(1997, 12, 31, 0, 3)])
1789
1790    def testMinutelyByYearDayNeg(self):
1791        self.assertEqual(list(rrule(MINUTELY,
1792                              count=4,
1793                              byyearday=(-365, -266, -166, -1),
1794                              dtstart=datetime(1997, 9, 2, 9, 0))),
1795                         [datetime(1997, 12, 31, 0, 0),
1796                          datetime(1997, 12, 31, 0, 1),
1797                          datetime(1997, 12, 31, 0, 2),
1798                          datetime(1997, 12, 31, 0, 3)])
1799
1800    def testMinutelyByMonthAndYearDay(self):
1801        self.assertEqual(list(rrule(MINUTELY,
1802                              count=4,
1803                              bymonth=(4, 7),
1804                              byyearday=(1, 100, 200, 365),
1805                              dtstart=datetime(1997, 9, 2, 9, 0))),
1806                         [datetime(1998, 4, 10, 0, 0),
1807                          datetime(1998, 4, 10, 0, 1),
1808                          datetime(1998, 4, 10, 0, 2),
1809                          datetime(1998, 4, 10, 0, 3)])
1810
1811    def testMinutelyByMonthAndYearDayNeg(self):
1812        self.assertEqual(list(rrule(MINUTELY,
1813                              count=4,
1814                              bymonth=(4, 7),
1815                              byyearday=(-365, -266, -166, -1),
1816                              dtstart=datetime(1997, 9, 2, 9, 0))),
1817                         [datetime(1998, 4, 10, 0, 0),
1818                          datetime(1998, 4, 10, 0, 1),
1819                          datetime(1998, 4, 10, 0, 2),
1820                          datetime(1998, 4, 10, 0, 3)])
1821
1822    def testMinutelyByWeekNo(self):
1823        self.assertEqual(list(rrule(MINUTELY,
1824                              count=3,
1825                              byweekno=20,
1826                              dtstart=datetime(1997, 9, 2, 9, 0))),
1827                         [datetime(1998, 5, 11, 0, 0),
1828                          datetime(1998, 5, 11, 0, 1),
1829                          datetime(1998, 5, 11, 0, 2)])
1830
1831    def testMinutelyByWeekNoAndWeekDay(self):
1832        self.assertEqual(list(rrule(MINUTELY,
1833                              count=3,
1834                              byweekno=1,
1835                              byweekday=MO,
1836                              dtstart=datetime(1997, 9, 2, 9, 0))),
1837                         [datetime(1997, 12, 29, 0, 0),
1838                          datetime(1997, 12, 29, 0, 1),
1839                          datetime(1997, 12, 29, 0, 2)])
1840
1841    def testMinutelyByWeekNoAndWeekDayLarge(self):
1842        self.assertEqual(list(rrule(MINUTELY,
1843                              count=3,
1844                              byweekno=52,
1845                              byweekday=SU,
1846                              dtstart=datetime(1997, 9, 2, 9, 0))),
1847                         [datetime(1997, 12, 28, 0, 0),
1848                          datetime(1997, 12, 28, 0, 1),
1849                          datetime(1997, 12, 28, 0, 2)])
1850
1851    def testMinutelyByWeekNoAndWeekDayLast(self):
1852        self.assertEqual(list(rrule(MINUTELY,
1853                              count=3,
1854                              byweekno=-1,
1855                              byweekday=SU,
1856                              dtstart=datetime(1997, 9, 2, 9, 0))),
1857                         [datetime(1997, 12, 28, 0, 0),
1858                          datetime(1997, 12, 28, 0, 1),
1859                          datetime(1997, 12, 28, 0, 2)])
1860
1861    def testMinutelyByWeekNoAndWeekDay53(self):
1862        self.assertEqual(list(rrule(MINUTELY,
1863                              count=3,
1864                              byweekno=53,
1865                              byweekday=MO,
1866                              dtstart=datetime(1997, 9, 2, 9, 0))),
1867                         [datetime(1998, 12, 28, 0, 0),
1868                          datetime(1998, 12, 28, 0, 1),
1869                          datetime(1998, 12, 28, 0, 2)])
1870
1871    def testMinutelyByEaster(self):
1872        self.assertEqual(list(rrule(MINUTELY,
1873                              count=3,
1874                              byeaster=0,
1875                              dtstart=datetime(1997, 9, 2, 9, 0))),
1876                         [datetime(1998, 4, 12, 0, 0),
1877                          datetime(1998, 4, 12, 0, 1),
1878                          datetime(1998, 4, 12, 0, 2)])
1879
1880    def testMinutelyByEasterPos(self):
1881        self.assertEqual(list(rrule(MINUTELY,
1882                              count=3,
1883                              byeaster=1,
1884                              dtstart=datetime(1997, 9, 2, 9, 0))),
1885                         [datetime(1998, 4, 13, 0, 0),
1886                          datetime(1998, 4, 13, 0, 1),
1887                          datetime(1998, 4, 13, 0, 2)])
1888
1889    def testMinutelyByEasterNeg(self):
1890        self.assertEqual(list(rrule(MINUTELY,
1891                              count=3,
1892                              byeaster=-1,
1893                              dtstart=datetime(1997, 9, 2, 9, 0))),
1894                         [datetime(1998, 4, 11, 0, 0),
1895                          datetime(1998, 4, 11, 0, 1),
1896                          datetime(1998, 4, 11, 0, 2)])
1897
1898    def testMinutelyByHour(self):
1899        self.assertEqual(list(rrule(MINUTELY,
1900                              count=3,
1901                              byhour=(6, 18),
1902                              dtstart=datetime(1997, 9, 2, 9, 0))),
1903                         [datetime(1997, 9, 2, 18, 0),
1904                          datetime(1997, 9, 2, 18, 1),
1905                          datetime(1997, 9, 2, 18, 2)])
1906
1907    def testMinutelyByMinute(self):
1908        self.assertEqual(list(rrule(MINUTELY,
1909                              count=3,
1910                              byminute=(6, 18),
1911                              dtstart=datetime(1997, 9, 2, 9, 0))),
1912                         [datetime(1997, 9, 2, 9, 6),
1913                          datetime(1997, 9, 2, 9, 18),
1914                          datetime(1997, 9, 2, 10, 6)])
1915
1916    def testMinutelyBySecond(self):
1917        self.assertEqual(list(rrule(MINUTELY,
1918                              count=3,
1919                              bysecond=(6, 18),
1920                              dtstart=datetime(1997, 9, 2, 9, 0))),
1921                         [datetime(1997, 9, 2, 9, 0, 6),
1922                          datetime(1997, 9, 2, 9, 0, 18),
1923                          datetime(1997, 9, 2, 9, 1, 6)])
1924
1925    def testMinutelyByHourAndMinute(self):
1926        self.assertEqual(list(rrule(MINUTELY,
1927                              count=3,
1928                              byhour=(6, 18),
1929                              byminute=(6, 18),
1930                              dtstart=datetime(1997, 9, 2, 9, 0))),
1931                         [datetime(1997, 9, 2, 18, 6),
1932                          datetime(1997, 9, 2, 18, 18),
1933                          datetime(1997, 9, 3, 6, 6)])
1934
1935    def testMinutelyByHourAndSecond(self):
1936        self.assertEqual(list(rrule(MINUTELY,
1937                              count=3,
1938                              byhour=(6, 18),
1939                              bysecond=(6, 18),
1940                              dtstart=datetime(1997, 9, 2, 9, 0))),
1941                         [datetime(1997, 9, 2, 18, 0, 6),
1942                          datetime(1997, 9, 2, 18, 0, 18),
1943                          datetime(1997, 9, 2, 18, 1, 6)])
1944
1945    def testMinutelyByMinuteAndSecond(self):
1946        self.assertEqual(list(rrule(MINUTELY,
1947                              count=3,
1948                              byminute=(6, 18),
1949                              bysecond=(6, 18),
1950                              dtstart=datetime(1997, 9, 2, 9, 0))),
1951                         [datetime(1997, 9, 2, 9, 6, 6),
1952                          datetime(1997, 9, 2, 9, 6, 18),
1953                          datetime(1997, 9, 2, 9, 18, 6)])
1954
1955    def testMinutelyByHourAndMinuteAndSecond(self):
1956        self.assertEqual(list(rrule(MINUTELY,
1957                              count=3,
1958                              byhour=(6, 18),
1959                              byminute=(6, 18),
1960                              bysecond=(6, 18),
1961                              dtstart=datetime(1997, 9, 2, 9, 0))),
1962                         [datetime(1997, 9, 2, 18, 6, 6),
1963                          datetime(1997, 9, 2, 18, 6, 18),
1964                          datetime(1997, 9, 2, 18, 18, 6)])
1965
1966    def testMinutelyBySetPos(self):
1967        self.assertEqual(list(rrule(MINUTELY,
1968                              count=3,
1969                              bysecond=(15, 30, 45),
1970                              bysetpos=(3, -3),
1971                              dtstart=datetime(1997, 9, 2, 9, 0))),
1972                         [datetime(1997, 9, 2, 9, 0, 15),
1973                          datetime(1997, 9, 2, 9, 0, 45),
1974                          datetime(1997, 9, 2, 9, 1, 15)])
1975
1976    def testSecondly(self):
1977        self.assertEqual(list(rrule(SECONDLY,
1978                              count=3,
1979                              dtstart=datetime(1997, 9, 2, 9, 0))),
1980                         [datetime(1997, 9, 2, 9, 0, 0),
1981                          datetime(1997, 9, 2, 9, 0, 1),
1982                          datetime(1997, 9, 2, 9, 0, 2)])
1983
1984    def testSecondlyInterval(self):
1985        self.assertEqual(list(rrule(SECONDLY,
1986                              count=3,
1987                              interval=2,
1988                              dtstart=datetime(1997, 9, 2, 9, 0))),
1989                         [datetime(1997, 9, 2, 9, 0, 0),
1990                          datetime(1997, 9, 2, 9, 0, 2),
1991                          datetime(1997, 9, 2, 9, 0, 4)])
1992
1993    def testSecondlyIntervalLarge(self):
1994        self.assertEqual(list(rrule(SECONDLY,
1995                              count=3,
1996                              interval=90061,
1997                              dtstart=datetime(1997, 9, 2, 9, 0))),
1998                         [datetime(1997, 9, 2, 9, 0, 0),
1999                          datetime(1997, 9, 3, 10, 1, 1),
2000                          datetime(1997, 9, 4, 11, 2, 2)])
2001
2002    def testSecondlyByMonth(self):
2003        self.assertEqual(list(rrule(SECONDLY,
2004                              count=3,
2005                              bymonth=(1, 3),
2006                              dtstart=datetime(1997, 9, 2, 9, 0))),
2007                         [datetime(1998, 1, 1, 0, 0, 0),
2008                          datetime(1998, 1, 1, 0, 0, 1),
2009                          datetime(1998, 1, 1, 0, 0, 2)])
2010
2011    def testSecondlyByMonthDay(self):
2012        self.assertEqual(list(rrule(SECONDLY,
2013                              count=3,
2014                              bymonthday=(1, 3),
2015                              dtstart=datetime(1997, 9, 2, 9, 0))),
2016                         [datetime(1997, 9, 3, 0, 0, 0),
2017                          datetime(1997, 9, 3, 0, 0, 1),
2018                          datetime(1997, 9, 3, 0, 0, 2)])
2019
2020    def testSecondlyByMonthAndMonthDay(self):
2021        self.assertEqual(list(rrule(SECONDLY,
2022                              count=3,
2023                              bymonth=(1, 3),
2024                              bymonthday=(5, 7),
2025                              dtstart=datetime(1997, 9, 2, 9, 0))),
2026                         [datetime(1998, 1, 5, 0, 0, 0),
2027                          datetime(1998, 1, 5, 0, 0, 1),
2028                          datetime(1998, 1, 5, 0, 0, 2)])
2029
2030    def testSecondlyByWeekDay(self):
2031        self.assertEqual(list(rrule(SECONDLY,
2032                              count=3,
2033                              byweekday=(TU, TH),
2034                              dtstart=datetime(1997, 9, 2, 9, 0))),
2035                         [datetime(1997, 9, 2, 9, 0, 0),
2036                          datetime(1997, 9, 2, 9, 0, 1),
2037                          datetime(1997, 9, 2, 9, 0, 2)])
2038
2039    def testSecondlyByNWeekDay(self):
2040        self.assertEqual(list(rrule(SECONDLY,
2041                              count=3,
2042                              byweekday=(TU(1), TH(-1)),
2043                              dtstart=datetime(1997, 9, 2, 9, 0))),
2044                         [datetime(1997, 9, 2, 9, 0, 0),
2045                          datetime(1997, 9, 2, 9, 0, 1),
2046                          datetime(1997, 9, 2, 9, 0, 2)])
2047
2048    def testSecondlyByMonthAndWeekDay(self):
2049        self.assertEqual(list(rrule(SECONDLY,
2050                              count=3,
2051                              bymonth=(1, 3),
2052                              byweekday=(TU, TH),
2053                              dtstart=datetime(1997, 9, 2, 9, 0))),
2054                         [datetime(1998, 1, 1, 0, 0, 0),
2055                          datetime(1998, 1, 1, 0, 0, 1),
2056                          datetime(1998, 1, 1, 0, 0, 2)])
2057
2058    def testSecondlyByMonthAndNWeekDay(self):
2059        self.assertEqual(list(rrule(SECONDLY,
2060                              count=3,
2061                              bymonth=(1, 3),
2062                              byweekday=(TU(1), TH(-1)),
2063                              dtstart=datetime(1997, 9, 2, 9, 0))),
2064                         [datetime(1998, 1, 1, 0, 0, 0),
2065                          datetime(1998, 1, 1, 0, 0, 1),
2066                          datetime(1998, 1, 1, 0, 0, 2)])
2067
2068    def testSecondlyByMonthDayAndWeekDay(self):
2069        self.assertEqual(list(rrule(SECONDLY,
2070                              count=3,
2071                              bymonthday=(1, 3),
2072                              byweekday=(TU, TH),
2073                              dtstart=datetime(1997, 9, 2, 9, 0))),
2074                         [datetime(1998, 1, 1, 0, 0, 0),
2075                          datetime(1998, 1, 1, 0, 0, 1),
2076                          datetime(1998, 1, 1, 0, 0, 2)])
2077
2078    def testSecondlyByMonthAndMonthDayAndWeekDay(self):
2079        self.assertEqual(list(rrule(SECONDLY,
2080                              count=3,
2081                              bymonth=(1, 3),
2082                              bymonthday=(1, 3),
2083                              byweekday=(TU, TH),
2084                              dtstart=datetime(1997, 9, 2, 9, 0))),
2085                         [datetime(1998, 1, 1, 0, 0, 0),
2086                          datetime(1998, 1, 1, 0, 0, 1),
2087                          datetime(1998, 1, 1, 0, 0, 2)])
2088
2089    def testSecondlyByYearDay(self):
2090        self.assertEqual(list(rrule(SECONDLY,
2091                              count=4,
2092                              byyearday=(1, 100, 200, 365),
2093                              dtstart=datetime(1997, 9, 2, 9, 0))),
2094                         [datetime(1997, 12, 31, 0, 0, 0),
2095                          datetime(1997, 12, 31, 0, 0, 1),
2096                          datetime(1997, 12, 31, 0, 0, 2),
2097                          datetime(1997, 12, 31, 0, 0, 3)])
2098
2099    def testSecondlyByYearDayNeg(self):
2100        self.assertEqual(list(rrule(SECONDLY,
2101                              count=4,
2102                              byyearday=(-365, -266, -166, -1),
2103                              dtstart=datetime(1997, 9, 2, 9, 0))),
2104                         [datetime(1997, 12, 31, 0, 0, 0),
2105                          datetime(1997, 12, 31, 0, 0, 1),
2106                          datetime(1997, 12, 31, 0, 0, 2),
2107                          datetime(1997, 12, 31, 0, 0, 3)])
2108
2109    def testSecondlyByMonthAndYearDay(self):
2110        self.assertEqual(list(rrule(SECONDLY,
2111                              count=4,
2112                              bymonth=(4, 7),
2113                              byyearday=(1, 100, 200, 365),
2114                              dtstart=datetime(1997, 9, 2, 9, 0))),
2115                         [datetime(1998, 4, 10, 0, 0, 0),
2116                          datetime(1998, 4, 10, 0, 0, 1),
2117                          datetime(1998, 4, 10, 0, 0, 2),
2118                          datetime(1998, 4, 10, 0, 0, 3)])
2119
2120    def testSecondlyByMonthAndYearDayNeg(self):
2121        self.assertEqual(list(rrule(SECONDLY,
2122                              count=4,
2123                              bymonth=(4, 7),
2124                              byyearday=(-365, -266, -166, -1),
2125                              dtstart=datetime(1997, 9, 2, 9, 0))),
2126                         [datetime(1998, 4, 10, 0, 0, 0),
2127                          datetime(1998, 4, 10, 0, 0, 1),
2128                          datetime(1998, 4, 10, 0, 0, 2),
2129                          datetime(1998, 4, 10, 0, 0, 3)])
2130
2131    def testSecondlyByWeekNo(self):
2132        self.assertEqual(list(rrule(SECONDLY,
2133                              count=3,
2134                              byweekno=20,
2135                              dtstart=datetime(1997, 9, 2, 9, 0))),
2136                         [datetime(1998, 5, 11, 0, 0, 0),
2137                          datetime(1998, 5, 11, 0, 0, 1),
2138                          datetime(1998, 5, 11, 0, 0, 2)])
2139
2140    def testSecondlyByWeekNoAndWeekDay(self):
2141        self.assertEqual(list(rrule(SECONDLY,
2142                              count=3,
2143                              byweekno=1,
2144                              byweekday=MO,
2145                              dtstart=datetime(1997, 9, 2, 9, 0))),
2146                         [datetime(1997, 12, 29, 0, 0, 0),
2147                          datetime(1997, 12, 29, 0, 0, 1),
2148                          datetime(1997, 12, 29, 0, 0, 2)])
2149
2150    def testSecondlyByWeekNoAndWeekDayLarge(self):
2151        self.assertEqual(list(rrule(SECONDLY,
2152                              count=3,
2153                              byweekno=52,
2154                              byweekday=SU,
2155                              dtstart=datetime(1997, 9, 2, 9, 0))),
2156                         [datetime(1997, 12, 28, 0, 0, 0),
2157                          datetime(1997, 12, 28, 0, 0, 1),
2158                          datetime(1997, 12, 28, 0, 0, 2)])
2159
2160    def testSecondlyByWeekNoAndWeekDayLast(self):
2161        self.assertEqual(list(rrule(SECONDLY,
2162                              count=3,
2163                              byweekno=-1,
2164                              byweekday=SU,
2165                              dtstart=datetime(1997, 9, 2, 9, 0))),
2166                         [datetime(1997, 12, 28, 0, 0, 0),
2167                          datetime(1997, 12, 28, 0, 0, 1),
2168                          datetime(1997, 12, 28, 0, 0, 2)])
2169
2170    def testSecondlyByWeekNoAndWeekDay53(self):
2171        self.assertEqual(list(rrule(SECONDLY,
2172                              count=3,
2173                              byweekno=53,
2174                              byweekday=MO,
2175                              dtstart=datetime(1997, 9, 2, 9, 0))),
2176                         [datetime(1998, 12, 28, 0, 0, 0),
2177                          datetime(1998, 12, 28, 0, 0, 1),
2178                          datetime(1998, 12, 28, 0, 0, 2)])
2179
2180    def testSecondlyByEaster(self):
2181        self.assertEqual(list(rrule(SECONDLY,
2182                              count=3,
2183                              byeaster=0,
2184                              dtstart=datetime(1997, 9, 2, 9, 0))),
2185                         [datetime(1998, 4, 12, 0, 0, 0),
2186                          datetime(1998, 4, 12, 0, 0, 1),
2187                          datetime(1998, 4, 12, 0, 0, 2)])
2188
2189    def testSecondlyByEasterPos(self):
2190        self.assertEqual(list(rrule(SECONDLY,
2191                              count=3,
2192                              byeaster=1,
2193                              dtstart=datetime(1997, 9, 2, 9, 0))),
2194                         [datetime(1998, 4, 13, 0, 0, 0),
2195                          datetime(1998, 4, 13, 0, 0, 1),
2196                          datetime(1998, 4, 13, 0, 0, 2)])
2197
2198    def testSecondlyByEasterNeg(self):
2199        self.assertEqual(list(rrule(SECONDLY,
2200                              count=3,
2201                              byeaster=-1,
2202                              dtstart=datetime(1997, 9, 2, 9, 0))),
2203                         [datetime(1998, 4, 11, 0, 0, 0),
2204                          datetime(1998, 4, 11, 0, 0, 1),
2205                          datetime(1998, 4, 11, 0, 0, 2)])
2206
2207    def testSecondlyByHour(self):
2208        self.assertEqual(list(rrule(SECONDLY,
2209                              count=3,
2210                              byhour=(6, 18),
2211                              dtstart=datetime(1997, 9, 2, 9, 0))),
2212                         [datetime(1997, 9, 2, 18, 0, 0),
2213                          datetime(1997, 9, 2, 18, 0, 1),
2214                          datetime(1997, 9, 2, 18, 0, 2)])
2215
2216    def testSecondlyByMinute(self):
2217        self.assertEqual(list(rrule(SECONDLY,
2218                              count=3,
2219                              byminute=(6, 18),
2220                              dtstart=datetime(1997, 9, 2, 9, 0))),
2221                         [datetime(1997, 9, 2, 9, 6, 0),
2222                          datetime(1997, 9, 2, 9, 6, 1),
2223                          datetime(1997, 9, 2, 9, 6, 2)])
2224
2225    def testSecondlyBySecond(self):
2226        self.assertEqual(list(rrule(SECONDLY,
2227                              count=3,
2228                              bysecond=(6, 18),
2229                              dtstart=datetime(1997, 9, 2, 9, 0))),
2230                         [datetime(1997, 9, 2, 9, 0, 6),
2231                          datetime(1997, 9, 2, 9, 0, 18),
2232                          datetime(1997, 9, 2, 9, 1, 6)])
2233
2234    def testSecondlyByHourAndMinute(self):
2235        self.assertEqual(list(rrule(SECONDLY,
2236                              count=3,
2237                              byhour=(6, 18),
2238                              byminute=(6, 18),
2239                              dtstart=datetime(1997, 9, 2, 9, 0))),
2240                         [datetime(1997, 9, 2, 18, 6, 0),
2241                          datetime(1997, 9, 2, 18, 6, 1),
2242                          datetime(1997, 9, 2, 18, 6, 2)])
2243
2244    def testSecondlyByHourAndSecond(self):
2245        self.assertEqual(list(rrule(SECONDLY,
2246                              count=3,
2247                              byhour=(6, 18),
2248                              bysecond=(6, 18),
2249                              dtstart=datetime(1997, 9, 2, 9, 0))),
2250                         [datetime(1997, 9, 2, 18, 0, 6),
2251                          datetime(1997, 9, 2, 18, 0, 18),
2252                          datetime(1997, 9, 2, 18, 1, 6)])
2253
2254    def testSecondlyByMinuteAndSecond(self):
2255        self.assertEqual(list(rrule(SECONDLY,
2256                              count=3,
2257                              byminute=(6, 18),
2258                              bysecond=(6, 18),
2259                              dtstart=datetime(1997, 9, 2, 9, 0))),
2260                         [datetime(1997, 9, 2, 9, 6, 6),
2261                          datetime(1997, 9, 2, 9, 6, 18),
2262                          datetime(1997, 9, 2, 9, 18, 6)])
2263
2264    def testSecondlyByHourAndMinuteAndSecond(self):
2265        self.assertEqual(list(rrule(SECONDLY,
2266                              count=3,
2267                              byhour=(6, 18),
2268                              byminute=(6, 18),
2269                              bysecond=(6, 18),
2270                              dtstart=datetime(1997, 9, 2, 9, 0))),
2271                         [datetime(1997, 9, 2, 18, 6, 6),
2272                          datetime(1997, 9, 2, 18, 6, 18),
2273                          datetime(1997, 9, 2, 18, 18, 6)])
2274
2275    def testSecondlyByHourAndMinuteAndSecondBug(self):
2276        # This explores a bug found by Mathieu Bridon.
2277        self.assertEqual(list(rrule(SECONDLY,
2278                              count=3,
2279                              bysecond=(0,),
2280                              byminute=(1,),
2281                              dtstart=datetime(2010, 3, 22, 12, 1))),
2282                         [datetime(2010, 3, 22, 12, 1),
2283                          datetime(2010, 3, 22, 13, 1),
2284                          datetime(2010, 3, 22, 14, 1)])
2285
2286    def testLongIntegers(self):
2287        if not PY3:  # There is no longs in python3
2288            self.assertEqual(list(rrule(MINUTELY,
2289                                  count=long(2),
2290                                  interval=long(2),
2291                                  bymonth=long(2),
2292                                  byweekday=long(3),
2293                                  byhour=long(6),
2294                                  byminute=long(6),
2295                                  bysecond=long(6),
2296                                  dtstart=datetime(1997, 9, 2, 9, 0))),
2297                             [datetime(1998, 2, 5, 6, 6, 6),
2298                              datetime(1998, 2, 12, 6, 6, 6)])
2299            self.assertEqual(list(rrule(YEARLY,
2300                                  count=long(2),
2301                                  bymonthday=long(5),
2302                                  byweekno=long(2),
2303                                  dtstart=datetime(1997, 9, 2, 9, 0))),
2304                             [datetime(1998, 1, 5, 9, 0),
2305                              datetime(2004, 1, 5, 9, 0)])
2306
2307    def testHourlyBadRRule(self):
2308        """
2309        When `byhour` is specified with `freq=HOURLY`, there are certain
2310        combinations of `dtstart` and `byhour` which result in an rrule with no
2311        valid values.
2312
2313        See https://github.com/dateutil/dateutil/issues/4
2314        """
2315
2316        self.assertRaises(ValueError, rrule, HOURLY,
2317                          **dict(interval=4, byhour=(7, 11, 15, 19),
2318                                 dtstart=datetime(1997, 9, 2, 9, 0)))
2319
2320    def testMinutelyBadRRule(self):
2321        """
2322        See :func:`testHourlyBadRRule` for details.
2323        """
2324
2325        self.assertRaises(ValueError, rrule, MINUTELY,
2326                          **dict(interval=12, byminute=(10, 11, 25, 39, 50),
2327                                 dtstart=datetime(1997, 9, 2, 9, 0)))
2328
2329    def testSecondlyBadRRule(self):
2330        """
2331        See :func:`testHourlyBadRRule` for details.
2332        """
2333
2334        self.assertRaises(ValueError, rrule, SECONDLY,
2335                          **dict(interval=10, bysecond=(2, 15, 37, 42, 59),
2336                                 dtstart=datetime(1997, 9, 2, 9, 0)))
2337
2338    def testMinutelyBadComboRRule(self):
2339        """
2340        Certain values of :param:`interval` in :class:`rrule`, when combined
2341        with certain values of :param:`byhour` create rules which apply to no
2342        valid dates. The library should detect this case in the iterator and
2343        raise a :exception:`ValueError`.
2344        """
2345
2346        # In Python 2.7 you can use a context manager for this.
2347        def make_bad_rrule():
2348            list(rrule(MINUTELY, interval=120, byhour=(10, 12, 14, 16),
2349                 count=2, dtstart=datetime(1997, 9, 2, 9, 0)))
2350
2351        self.assertRaises(ValueError, make_bad_rrule)
2352
2353    def testSecondlyBadComboRRule(self):
2354        """
2355        See :func:`testMinutelyBadComboRRule' for details.
2356        """
2357
2358        # In Python 2.7 you can use a context manager for this.
2359        def make_bad_minute_rrule():
2360            list(rrule(SECONDLY, interval=360, byminute=(10, 28, 49),
2361                 count=4, dtstart=datetime(1997, 9, 2, 9, 0)))
2362
2363        def make_bad_hour_rrule():
2364            list(rrule(SECONDLY, interval=43200, byhour=(2, 10, 18, 23),
2365                 count=4, dtstart=datetime(1997, 9, 2, 9, 0)))
2366
2367        self.assertRaises(ValueError, make_bad_minute_rrule)
2368        self.assertRaises(ValueError, make_bad_hour_rrule)
2369
2370    def testBadUntilCountRRule(self):
2371        """
2372        See rfc-5545 3.3.10 - This checks for the deprecation warning, and will
2373        eventually check for an error.
2374        """
2375        with self.assertWarns(DeprecationWarning):
2376            rrule(DAILY, dtstart=datetime(1997, 9, 2, 9, 0),
2377                         count=3, until=datetime(1997, 9, 4, 9, 0))
2378
2379    def testUntilNotMatching(self):
2380        self.assertEqual(list(rrule(DAILY,
2381                              dtstart=datetime(1997, 9, 2, 9, 0),
2382                              until=datetime(1997, 9, 5, 8, 0))),
2383                         [datetime(1997, 9, 2, 9, 0),
2384                          datetime(1997, 9, 3, 9, 0),
2385                          datetime(1997, 9, 4, 9, 0)])
2386
2387    def testUntilMatching(self):
2388        self.assertEqual(list(rrule(DAILY,
2389                              dtstart=datetime(1997, 9, 2, 9, 0),
2390                              until=datetime(1997, 9, 4, 9, 0))),
2391                         [datetime(1997, 9, 2, 9, 0),
2392                          datetime(1997, 9, 3, 9, 0),
2393                          datetime(1997, 9, 4, 9, 0)])
2394
2395    def testUntilSingle(self):
2396        self.assertEqual(list(rrule(DAILY,
2397                              dtstart=datetime(1997, 9, 2, 9, 0),
2398                              until=datetime(1997, 9, 2, 9, 0))),
2399                         [datetime(1997, 9, 2, 9, 0)])
2400
2401    def testUntilEmpty(self):
2402        self.assertEqual(list(rrule(DAILY,
2403                              dtstart=datetime(1997, 9, 2, 9, 0),
2404                              until=datetime(1997, 9, 1, 9, 0))),
2405                         [])
2406
2407    def testUntilWithDate(self):
2408        self.assertEqual(list(rrule(DAILY,
2409                              dtstart=datetime(1997, 9, 2, 9, 0),
2410                              until=date(1997, 9, 5))),
2411                         [datetime(1997, 9, 2, 9, 0),
2412                          datetime(1997, 9, 3, 9, 0),
2413                          datetime(1997, 9, 4, 9, 0)])
2414
2415    def testWkStIntervalMO(self):
2416        self.assertEqual(list(rrule(WEEKLY,
2417                              count=3,
2418                              interval=2,
2419                              byweekday=(TU, SU),
2420                              wkst=MO,
2421                              dtstart=datetime(1997, 9, 2, 9, 0))),
2422                         [datetime(1997, 9, 2, 9, 0),
2423                          datetime(1997, 9, 7, 9, 0),
2424                          datetime(1997, 9, 16, 9, 0)])
2425
2426    def testWkStIntervalSU(self):
2427        self.assertEqual(list(rrule(WEEKLY,
2428                              count=3,
2429                              interval=2,
2430                              byweekday=(TU, SU),
2431                              wkst=SU,
2432                              dtstart=datetime(1997, 9, 2, 9, 0))),
2433                         [datetime(1997, 9, 2, 9, 0),
2434                          datetime(1997, 9, 14, 9, 0),
2435                          datetime(1997, 9, 16, 9, 0)])
2436
2437    def testDTStartIsDate(self):
2438        self.assertEqual(list(rrule(DAILY,
2439                              count=3,
2440                              dtstart=date(1997, 9, 2))),
2441                         [datetime(1997, 9, 2, 0, 0),
2442                          datetime(1997, 9, 3, 0, 0),
2443                          datetime(1997, 9, 4, 0, 0)])
2444
2445    def testDTStartWithMicroseconds(self):
2446        self.assertEqual(list(rrule(DAILY,
2447                              count=3,
2448                              dtstart=datetime(1997, 9, 2, 9, 0, 0, 500000))),
2449                         [datetime(1997, 9, 2, 9, 0),
2450                          datetime(1997, 9, 3, 9, 0),
2451                          datetime(1997, 9, 4, 9, 0)])
2452
2453    def testMaxYear(self):
2454        self.assertEqual(list(rrule(YEARLY,
2455                              count=3,
2456                              bymonth=2,
2457                              bymonthday=31,
2458                              dtstart=datetime(9997, 9, 2, 9, 0, 0))),
2459                         [])
2460
2461    def testGetItem(self):
2462        self.assertEqual(rrule(DAILY,
2463                               count=3,
2464                               dtstart=datetime(1997, 9, 2, 9, 0))[0],
2465                         datetime(1997, 9, 2, 9, 0))
2466
2467    def testGetItemNeg(self):
2468        self.assertEqual(rrule(DAILY,
2469                               count=3,
2470                               dtstart=datetime(1997, 9, 2, 9, 0))[-1],
2471                         datetime(1997, 9, 4, 9, 0))
2472
2473    def testGetItemSlice(self):
2474        self.assertEqual(rrule(DAILY,
2475                               # count=3,
2476                               dtstart=datetime(1997, 9, 2, 9, 0))[1:2],
2477                         [datetime(1997, 9, 3, 9, 0)])
2478
2479    def testGetItemSliceEmpty(self):
2480        self.assertEqual(rrule(DAILY,
2481                               count=3,
2482                               dtstart=datetime(1997, 9, 2, 9, 0))[:],
2483                         [datetime(1997, 9, 2, 9, 0),
2484                          datetime(1997, 9, 3, 9, 0),
2485                          datetime(1997, 9, 4, 9, 0)])
2486
2487    def testGetItemSliceStep(self):
2488        self.assertEqual(rrule(DAILY,
2489                               count=3,
2490                               dtstart=datetime(1997, 9, 2, 9, 0))[::-2],
2491                         [datetime(1997, 9, 4, 9, 0),
2492                          datetime(1997, 9, 2, 9, 0)])
2493
2494    def testCount(self):
2495        self.assertEqual(rrule(DAILY,
2496                               count=3,
2497                               dtstart=datetime(1997, 9, 2, 9, 0)).count(),
2498                         3)
2499
2500    def testCountZero(self):
2501        self.assertEqual(rrule(YEARLY,
2502                               count=0,
2503                               dtstart=datetime(1997, 9, 2, 9, 0)).count(),
2504                         0)
2505
2506    def testContains(self):
2507        rr = rrule(DAILY, count=3, dtstart=datetime(1997, 9, 2, 9, 0))
2508        self.assertEqual(datetime(1997, 9, 3, 9, 0) in rr, True)
2509
2510    def testContainsNot(self):
2511        rr = rrule(DAILY, count=3, dtstart=datetime(1997, 9, 2, 9, 0))
2512        self.assertEqual(datetime(1997, 9, 3, 9, 0) not in rr, False)
2513
2514    def testBefore(self):
2515        self.assertEqual(rrule(DAILY,  # count=5
2516            dtstart=datetime(1997, 9, 2, 9, 0)).before(datetime(1997, 9, 5, 9, 0)),
2517                         datetime(1997, 9, 4, 9, 0))
2518
2519    def testBeforeInc(self):
2520        self.assertEqual(rrule(DAILY,
2521                               #count=5,
2522                               dtstart=datetime(1997, 9, 2, 9, 0))
2523                               .before(datetime(1997, 9, 5, 9, 0), inc=True),
2524                         datetime(1997, 9, 5, 9, 0))
2525
2526    def testAfter(self):
2527        self.assertEqual(rrule(DAILY,
2528                               #count=5,
2529                               dtstart=datetime(1997, 9, 2, 9, 0))
2530                               .after(datetime(1997, 9, 4, 9, 0)),
2531                         datetime(1997, 9, 5, 9, 0))
2532
2533    def testAfterInc(self):
2534        self.assertEqual(rrule(DAILY,
2535                               #count=5,
2536                               dtstart=datetime(1997, 9, 2, 9, 0))
2537                               .after(datetime(1997, 9, 4, 9, 0), inc=True),
2538                         datetime(1997, 9, 4, 9, 0))
2539
2540    def testXAfter(self):
2541        self.assertEqual(list(rrule(DAILY,
2542                                    dtstart=datetime(1997, 9, 2, 9, 0))
2543                                    .xafter(datetime(1997, 9, 8, 9, 0), count=12)),
2544                                    [datetime(1997, 9, 9, 9, 0),
2545                                     datetime(1997, 9, 10, 9, 0),
2546                                     datetime(1997, 9, 11, 9, 0),
2547                                     datetime(1997, 9, 12, 9, 0),
2548                                     datetime(1997, 9, 13, 9, 0),
2549                                     datetime(1997, 9, 14, 9, 0),
2550                                     datetime(1997, 9, 15, 9, 0),
2551                                     datetime(1997, 9, 16, 9, 0),
2552                                     datetime(1997, 9, 17, 9, 0),
2553                                     datetime(1997, 9, 18, 9, 0),
2554                                     datetime(1997, 9, 19, 9, 0),
2555                                     datetime(1997, 9, 20, 9, 0)])
2556
2557    def testXAfterInc(self):
2558        self.assertEqual(list(rrule(DAILY,
2559                                    dtstart=datetime(1997, 9, 2, 9, 0))
2560                                    .xafter(datetime(1997, 9, 8, 9, 0), count=12, inc=True)),
2561                                    [datetime(1997, 9, 8, 9, 0),
2562                                     datetime(1997, 9, 9, 9, 0),
2563                                     datetime(1997, 9, 10, 9, 0),
2564                                     datetime(1997, 9, 11, 9, 0),
2565                                     datetime(1997, 9, 12, 9, 0),
2566                                     datetime(1997, 9, 13, 9, 0),
2567                                     datetime(1997, 9, 14, 9, 0),
2568                                     datetime(1997, 9, 15, 9, 0),
2569                                     datetime(1997, 9, 16, 9, 0),
2570                                     datetime(1997, 9, 17, 9, 0),
2571                                     datetime(1997, 9, 18, 9, 0),
2572                                     datetime(1997, 9, 19, 9, 0)])
2573
2574    def testBetween(self):
2575        self.assertEqual(rrule(DAILY,
2576                               #count=5,
2577                               dtstart=datetime(1997, 9, 2, 9, 0))
2578                               .between(datetime(1997, 9, 2, 9, 0),
2579                                        datetime(1997, 9, 6, 9, 0)),
2580                         [datetime(1997, 9, 3, 9, 0),
2581                          datetime(1997, 9, 4, 9, 0),
2582                          datetime(1997, 9, 5, 9, 0)])
2583
2584    def testBetweenInc(self):
2585        self.assertEqual(rrule(DAILY,
2586                               #count=5,
2587                               dtstart=datetime(1997, 9, 2, 9, 0))
2588                               .between(datetime(1997, 9, 2, 9, 0),
2589                                        datetime(1997, 9, 6, 9, 0), inc=True),
2590                         [datetime(1997, 9, 2, 9, 0),
2591                          datetime(1997, 9, 3, 9, 0),
2592                          datetime(1997, 9, 4, 9, 0),
2593                          datetime(1997, 9, 5, 9, 0),
2594                          datetime(1997, 9, 6, 9, 0)])
2595
2596    def testCachePre(self):
2597        rr = rrule(DAILY, count=15, cache=True,
2598                   dtstart=datetime(1997, 9, 2, 9, 0))
2599        self.assertEqual(list(rr),
2600                         [datetime(1997, 9, 2, 9, 0),
2601                          datetime(1997, 9, 3, 9, 0),
2602                          datetime(1997, 9, 4, 9, 0),
2603                          datetime(1997, 9, 5, 9, 0),
2604                          datetime(1997, 9, 6, 9, 0),
2605                          datetime(1997, 9, 7, 9, 0),
2606                          datetime(1997, 9, 8, 9, 0),
2607                          datetime(1997, 9, 9, 9, 0),
2608                          datetime(1997, 9, 10, 9, 0),
2609                          datetime(1997, 9, 11, 9, 0),
2610                          datetime(1997, 9, 12, 9, 0),
2611                          datetime(1997, 9, 13, 9, 0),
2612                          datetime(1997, 9, 14, 9, 0),
2613                          datetime(1997, 9, 15, 9, 0),
2614                          datetime(1997, 9, 16, 9, 0)])
2615
2616    def testCachePost(self):
2617        rr = rrule(DAILY, count=15, cache=True,
2618                   dtstart=datetime(1997, 9, 2, 9, 0))
2619        for x in rr: pass
2620        self.assertEqual(list(rr),
2621                         [datetime(1997, 9, 2, 9, 0),
2622                          datetime(1997, 9, 3, 9, 0),
2623                          datetime(1997, 9, 4, 9, 0),
2624                          datetime(1997, 9, 5, 9, 0),
2625                          datetime(1997, 9, 6, 9, 0),
2626                          datetime(1997, 9, 7, 9, 0),
2627                          datetime(1997, 9, 8, 9, 0),
2628                          datetime(1997, 9, 9, 9, 0),
2629                          datetime(1997, 9, 10, 9, 0),
2630                          datetime(1997, 9, 11, 9, 0),
2631                          datetime(1997, 9, 12, 9, 0),
2632                          datetime(1997, 9, 13, 9, 0),
2633                          datetime(1997, 9, 14, 9, 0),
2634                          datetime(1997, 9, 15, 9, 0),
2635                          datetime(1997, 9, 16, 9, 0)])
2636
2637    def testCachePostInternal(self):
2638        rr = rrule(DAILY, count=15, cache=True,
2639                   dtstart=datetime(1997, 9, 2, 9, 0))
2640        for x in rr: pass
2641        self.assertEqual(rr._cache,
2642                         [datetime(1997, 9, 2, 9, 0),
2643                          datetime(1997, 9, 3, 9, 0),
2644                          datetime(1997, 9, 4, 9, 0),
2645                          datetime(1997, 9, 5, 9, 0),
2646                          datetime(1997, 9, 6, 9, 0),
2647                          datetime(1997, 9, 7, 9, 0),
2648                          datetime(1997, 9, 8, 9, 0),
2649                          datetime(1997, 9, 9, 9, 0),
2650                          datetime(1997, 9, 10, 9, 0),
2651                          datetime(1997, 9, 11, 9, 0),
2652                          datetime(1997, 9, 12, 9, 0),
2653                          datetime(1997, 9, 13, 9, 0),
2654                          datetime(1997, 9, 14, 9, 0),
2655                          datetime(1997, 9, 15, 9, 0),
2656                          datetime(1997, 9, 16, 9, 0)])
2657
2658    def testCachePreContains(self):
2659        rr = rrule(DAILY, count=3, cache=True,
2660                   dtstart=datetime(1997, 9, 2, 9, 0))
2661        self.assertEqual(datetime(1997, 9, 3, 9, 0) in rr, True)
2662
2663    def testCachePostContains(self):
2664        rr = rrule(DAILY, count=3, cache=True,
2665                   dtstart=datetime(1997, 9, 2, 9, 0))
2666        for x in rr: pass
2667        self.assertEqual(datetime(1997, 9, 3, 9, 0) in rr, True)
2668
2669    def testStr(self):
2670        self.assertEqual(list(rrulestr(
2671                              "DTSTART:19970902T090000\n"
2672                              "RRULE:FREQ=YEARLY;COUNT=3\n"
2673                              )),
2674                         [datetime(1997, 9, 2, 9, 0),
2675                          datetime(1998, 9, 2, 9, 0),
2676                          datetime(1999, 9, 2, 9, 0)])
2677
2678    def testStrWithTZID(self):
2679        NYC = tz.gettz('America/New_York')
2680        self.assertEqual(list(rrulestr(
2681                              "DTSTART;TZID=America/New_York:19970902T090000\n"
2682                              "RRULE:FREQ=YEARLY;COUNT=3\n"
2683                              )),
2684                         [datetime(1997, 9, 2, 9, 0, tzinfo=NYC),
2685                          datetime(1998, 9, 2, 9, 0, tzinfo=NYC),
2686                          datetime(1999, 9, 2, 9, 0, tzinfo=NYC)])
2687
2688    def testStrWithTZIDMapping(self):
2689        rrstr = ("DTSTART;TZID=Eastern:19970902T090000\n" +
2690                 "RRULE:FREQ=YEARLY;COUNT=3")
2691
2692        NYC = tz.gettz('America/New_York')
2693        rr = rrulestr(rrstr, tzids={'Eastern': NYC})
2694        exp = [datetime(1997, 9, 2, 9, 0, tzinfo=NYC),
2695               datetime(1998, 9, 2, 9, 0, tzinfo=NYC),
2696               datetime(1999, 9, 2, 9, 0, tzinfo=NYC)]
2697
2698        self.assertEqual(list(rr), exp)
2699
2700    def testStrWithTZIDCallable(self):
2701        rrstr = ('DTSTART;TZID=UTC+04:19970902T090000\n' +
2702                 'RRULE:FREQ=YEARLY;COUNT=3')
2703
2704        TZ = tz.tzstr('UTC+04')
2705        def parse_tzstr(tzstr):
2706            if tzstr is None:
2707                raise ValueError('Invalid tzstr')
2708
2709            return tz.tzstr(tzstr)
2710
2711        rr = rrulestr(rrstr, tzids=parse_tzstr)
2712
2713        exp = [datetime(1997, 9, 2, 9, 0, tzinfo=TZ),
2714               datetime(1998, 9, 2, 9, 0, tzinfo=TZ),
2715               datetime(1999, 9, 2, 9, 0, tzinfo=TZ),]
2716
2717        self.assertEqual(list(rr), exp)
2718
2719    def testStrWithTZIDCallableFailure(self):
2720        rrstr = ('DTSTART;TZID=America/New_York:19970902T090000\n' +
2721                 'RRULE:FREQ=YEARLY;COUNT=3')
2722
2723        class TzInfoError(Exception):
2724            pass
2725
2726        def tzinfos(tzstr):
2727            if tzstr == 'America/New_York':
2728                raise TzInfoError('Invalid!')
2729            return None
2730
2731        with self.assertRaises(TzInfoError):
2732            rrulestr(rrstr, tzids=tzinfos)
2733
2734    def testStrWithConflictingTZID(self):
2735        # RFC 5545 Section 3.3.5, FORM #2: DATE WITH UTC TIME
2736        # https://tools.ietf.org/html/rfc5545#section-3.3.5
2737        # The "TZID" property parameter MUST NOT be applied to DATE-TIME
2738        with self.assertRaises(ValueError):
2739            rrulestr("DTSTART;TZID=America/New_York:19970902T090000Z\n"+
2740                     "RRULE:FREQ=YEARLY;COUNT=3\n")
2741
2742    def testStrType(self):
2743        self.assertEqual(isinstance(rrulestr(
2744                              "DTSTART:19970902T090000\n"
2745                              "RRULE:FREQ=YEARLY;COUNT=3\n"
2746                              ), rrule), True)
2747
2748    def testStrForceSetType(self):
2749        self.assertEqual(isinstance(rrulestr(
2750                              "DTSTART:19970902T090000\n"
2751                              "RRULE:FREQ=YEARLY;COUNT=3\n"
2752                              , forceset=True), rruleset), True)
2753
2754    def testStrSetType(self):
2755        self.assertEqual(isinstance(rrulestr(
2756                              "DTSTART:19970902T090000\n"
2757                              "RRULE:FREQ=YEARLY;COUNT=2;BYDAY=TU\n"
2758                              "RRULE:FREQ=YEARLY;COUNT=1;BYDAY=TH\n"
2759                              ), rruleset), True)
2760
2761    def testStrCase(self):
2762        self.assertEqual(list(rrulestr(
2763                              "dtstart:19970902T090000\n"
2764                              "rrule:freq=yearly;count=3\n"
2765                              )),
2766                         [datetime(1997, 9, 2, 9, 0),
2767                          datetime(1998, 9, 2, 9, 0),
2768                          datetime(1999, 9, 2, 9, 0)])
2769
2770    def testStrSpaces(self):
2771        self.assertEqual(list(rrulestr(
2772                              " DTSTART:19970902T090000 "
2773                              " RRULE:FREQ=YEARLY;COUNT=3 "
2774                              )),
2775                         [datetime(1997, 9, 2, 9, 0),
2776                          datetime(1998, 9, 2, 9, 0),
2777                          datetime(1999, 9, 2, 9, 0)])
2778
2779    def testStrSpacesAndLines(self):
2780        self.assertEqual(list(rrulestr(
2781                              " DTSTART:19970902T090000 \n"
2782                              " \n"
2783                              " RRULE:FREQ=YEARLY;COUNT=3 \n"
2784                              )),
2785                         [datetime(1997, 9, 2, 9, 0),
2786                          datetime(1998, 9, 2, 9, 0),
2787                          datetime(1999, 9, 2, 9, 0)])
2788
2789    def testStrNoDTStart(self):
2790        self.assertEqual(list(rrulestr(
2791                              "RRULE:FREQ=YEARLY;COUNT=3\n"
2792                              , dtstart=datetime(1997, 9, 2, 9, 0))),
2793                         [datetime(1997, 9, 2, 9, 0),
2794                          datetime(1998, 9, 2, 9, 0),
2795                          datetime(1999, 9, 2, 9, 0)])
2796
2797    def testStrValueOnly(self):
2798        self.assertEqual(list(rrulestr(
2799                              "FREQ=YEARLY;COUNT=3\n"
2800                              , dtstart=datetime(1997, 9, 2, 9, 0))),
2801                         [datetime(1997, 9, 2, 9, 0),
2802                          datetime(1998, 9, 2, 9, 0),
2803                          datetime(1999, 9, 2, 9, 0)])
2804
2805    def testStrUnfold(self):
2806        self.assertEqual(list(rrulestr(
2807                              "FREQ=YEA\n RLY;COUNT=3\n", unfold=True,
2808                              dtstart=datetime(1997, 9, 2, 9, 0))),
2809                         [datetime(1997, 9, 2, 9, 0),
2810                          datetime(1998, 9, 2, 9, 0),
2811                          datetime(1999, 9, 2, 9, 0)])
2812
2813    def testStrSet(self):
2814        self.assertEqual(list(rrulestr(
2815                              "DTSTART:19970902T090000\n"
2816                              "RRULE:FREQ=YEARLY;COUNT=2;BYDAY=TU\n"
2817                              "RRULE:FREQ=YEARLY;COUNT=1;BYDAY=TH\n"
2818                              )),
2819                         [datetime(1997, 9, 2, 9, 0),
2820                          datetime(1997, 9, 4, 9, 0),
2821                          datetime(1997, 9, 9, 9, 0)])
2822
2823    def testStrSetDate(self):
2824        self.assertEqual(list(rrulestr(
2825                              "DTSTART:19970902T090000\n"
2826                              "RRULE:FREQ=YEARLY;COUNT=1;BYDAY=TU\n"
2827                              "RDATE:19970904T090000\n"
2828                              "RDATE:19970909T090000\n"
2829                              )),
2830                         [datetime(1997, 9, 2, 9, 0),
2831                          datetime(1997, 9, 4, 9, 0),
2832                          datetime(1997, 9, 9, 9, 0)])
2833
2834    def testStrSetExRule(self):
2835        self.assertEqual(list(rrulestr(
2836                              "DTSTART:19970902T090000\n"
2837                              "RRULE:FREQ=YEARLY;COUNT=6;BYDAY=TU,TH\n"
2838                              "EXRULE:FREQ=YEARLY;COUNT=3;BYDAY=TH\n"
2839                              )),
2840                         [datetime(1997, 9, 2, 9, 0),
2841                          datetime(1997, 9, 9, 9, 0),
2842                          datetime(1997, 9, 16, 9, 0)])
2843
2844    def testStrSetExDate(self):
2845        self.assertEqual(list(rrulestr(
2846                              "DTSTART:19970902T090000\n"
2847                              "RRULE:FREQ=YEARLY;COUNT=6;BYDAY=TU,TH\n"
2848                              "EXDATE:19970904T090000\n"
2849                              "EXDATE:19970911T090000\n"
2850                              "EXDATE:19970918T090000\n"
2851                              )),
2852                         [datetime(1997, 9, 2, 9, 0),
2853                          datetime(1997, 9, 9, 9, 0),
2854                          datetime(1997, 9, 16, 9, 0)])
2855
2856    def testStrSetExDateMultiple(self):
2857        rrstr = ("DTSTART:19970902T090000\n"
2858                 "RRULE:FREQ=YEARLY;COUNT=6;BYDAY=TU,TH\n"
2859                 "EXDATE:19970904T090000,19970911T090000,19970918T090000\n")
2860
2861        rr = rrulestr(rrstr)
2862        assert list(rr) == [datetime(1997, 9, 2, 9, 0),
2863                            datetime(1997, 9, 9, 9, 0),
2864                            datetime(1997, 9, 16, 9, 0)]
2865
2866    def testStrSetExDateWithTZID(self):
2867        BXL = tz.gettz('Europe/Brussels')
2868        rr = rrulestr("DTSTART;TZID=Europe/Brussels:19970902T090000\n"
2869                      "RRULE:FREQ=YEARLY;COUNT=6;BYDAY=TU,TH\n"
2870                      "EXDATE;TZID=Europe/Brussels:19970904T090000\n"
2871                      "EXDATE;TZID=Europe/Brussels:19970911T090000\n"
2872                      "EXDATE;TZID=Europe/Brussels:19970918T090000\n")
2873
2874        assert list(rr) == [datetime(1997, 9, 2, 9, 0, tzinfo=BXL),
2875                            datetime(1997, 9, 9, 9, 0, tzinfo=BXL),
2876                            datetime(1997, 9, 16, 9, 0, tzinfo=BXL)]
2877
2878    def testStrSetExDateValueDateTimeNoTZID(self):
2879        rrstr = '\n'.join([
2880            "DTSTART:19970902T090000",
2881            "RRULE:FREQ=YEARLY;COUNT=4;BYDAY=TU,TH",
2882            "EXDATE;VALUE=DATE-TIME:19970902T090000",
2883            "EXDATE;VALUE=DATE-TIME:19970909T090000",
2884        ])
2885
2886        rr = rrulestr(rrstr)
2887        assert list(rr) == [datetime(1997, 9, 4, 9), datetime(1997, 9, 11, 9)]
2888
2889    def testStrSetExDateValueMixDateTimeNoTZID(self):
2890        rrstr = '\n'.join([
2891            "DTSTART:19970902T090000",
2892            "RRULE:FREQ=YEARLY;COUNT=4;BYDAY=TU,TH",
2893            "EXDATE;VALUE=DATE-TIME:19970902T090000",
2894            "EXDATE:19970909T090000",
2895        ])
2896
2897        rr = rrulestr(rrstr)
2898        assert list(rr) == [datetime(1997, 9, 4, 9), datetime(1997, 9, 11, 9)]
2899
2900    def testStrSetExDateValueDateTimeWithTZID(self):
2901        BXL = tz.gettz('Europe/Brussels')
2902        rrstr = '\n'.join([
2903            "DTSTART;VALUE=DATE-TIME;TZID=Europe/Brussels:19970902T090000",
2904            "RRULE:FREQ=YEARLY;COUNT=4;BYDAY=TU,TH",
2905            "EXDATE;VALUE=DATE-TIME;TZID=Europe/Brussels:19970902T090000",
2906            "EXDATE;VALUE=DATE-TIME;TZID=Europe/Brussels:19970909T090000",
2907        ])
2908
2909        rr = rrulestr(rrstr)
2910        assert list(rr) == [datetime(1997, 9, 4, 9, tzinfo=BXL),
2911                            datetime(1997, 9, 11, 9, tzinfo=BXL)]
2912
2913    def testStrSetExDateValueDate(self):
2914        rrstr = '\n'.join([
2915            "DTSTART;VALUE=DATE:19970902",
2916            "RRULE:FREQ=YEARLY;COUNT=4;BYDAY=TU,TH",
2917            "EXDATE;VALUE=DATE:19970902",
2918            "EXDATE;VALUE=DATE:19970909",
2919        ])
2920
2921        rr = rrulestr(rrstr)
2922        assert list(rr) == [datetime(1997, 9, 4), datetime(1997, 9, 11)]
2923
2924    def testStrSetDateAndExDate(self):
2925        self.assertEqual(list(rrulestr(
2926                              "DTSTART:19970902T090000\n"
2927                              "RDATE:19970902T090000\n"
2928                              "RDATE:19970904T090000\n"
2929                              "RDATE:19970909T090000\n"
2930                              "RDATE:19970911T090000\n"
2931                              "RDATE:19970916T090000\n"
2932                              "RDATE:19970918T090000\n"
2933                              "EXDATE:19970904T090000\n"
2934                              "EXDATE:19970911T090000\n"
2935                              "EXDATE:19970918T090000\n"
2936                              )),
2937                         [datetime(1997, 9, 2, 9, 0),
2938                          datetime(1997, 9, 9, 9, 0),
2939                          datetime(1997, 9, 16, 9, 0)])
2940
2941    def testStrSetDateAndExRule(self):
2942        self.assertEqual(list(rrulestr(
2943                              "DTSTART:19970902T090000\n"
2944                              "RDATE:19970902T090000\n"
2945                              "RDATE:19970904T090000\n"
2946                              "RDATE:19970909T090000\n"
2947                              "RDATE:19970911T090000\n"
2948                              "RDATE:19970916T090000\n"
2949                              "RDATE:19970918T090000\n"
2950                              "EXRULE:FREQ=YEARLY;COUNT=3;BYDAY=TH\n"
2951                              )),
2952                         [datetime(1997, 9, 2, 9, 0),
2953                          datetime(1997, 9, 9, 9, 0),
2954                          datetime(1997, 9, 16, 9, 0)])
2955
2956    def testStrKeywords(self):
2957        self.assertEqual(list(rrulestr(
2958                              "DTSTART:19970902T090000\n"
2959                              "RRULE:FREQ=YEARLY;COUNT=3;INTERVAL=3;"
2960                                    "BYMONTH=3;BYWEEKDAY=TH;BYMONTHDAY=3;"
2961                                    "BYHOUR=3;BYMINUTE=3;BYSECOND=3\n"
2962                              )),
2963                         [datetime(2033, 3, 3, 3, 3, 3),
2964                          datetime(2039, 3, 3, 3, 3, 3),
2965                          datetime(2072, 3, 3, 3, 3, 3)])
2966
2967    def testStrNWeekDay(self):
2968        self.assertEqual(list(rrulestr(
2969                              "DTSTART:19970902T090000\n"
2970                              "RRULE:FREQ=YEARLY;COUNT=3;BYDAY=1TU,-1TH\n"
2971                              )),
2972                         [datetime(1997, 12, 25, 9, 0),
2973                          datetime(1998, 1, 6, 9, 0),
2974                          datetime(1998, 12, 31, 9, 0)])
2975
2976    def testStrUntil(self):
2977        self.assertEqual(list(rrulestr(
2978                              "DTSTART:19970902T090000\n"
2979                              "RRULE:FREQ=YEARLY;"
2980                              "UNTIL=19990101T000000;BYDAY=1TU,-1TH\n"
2981                              )),
2982                         [datetime(1997, 12, 25, 9, 0),
2983                          datetime(1998, 1, 6, 9, 0),
2984                          datetime(1998, 12, 31, 9, 0)])
2985
2986    def testStrValueDatetime(self):
2987        rr = rrulestr("DTSTART;VALUE=DATE-TIME:19970902T090000\n"
2988                       "RRULE:FREQ=YEARLY;COUNT=2")
2989
2990        self.assertEqual(list(rr), [datetime(1997, 9, 2, 9, 0, 0),
2991                                    datetime(1998, 9, 2, 9, 0, 0)])
2992
2993    def testStrValueDate(self):
2994        rr = rrulestr("DTSTART;VALUE=DATE:19970902\n"
2995                       "RRULE:FREQ=YEARLY;COUNT=2")
2996
2997        self.assertEqual(list(rr), [datetime(1997, 9, 2, 0, 0, 0),
2998                                    datetime(1998, 9, 2, 0, 0, 0)])
2999
3000    def testStrMultipleDTStartComma(self):
3001        with pytest.raises(ValueError):
3002            rr = rrulestr("DTSTART:19970101T000000,19970202T000000\n"
3003                          "RRULE:FREQ=YEARLY;COUNT=1")
3004
3005    def testStrInvalidUntil(self):
3006        with self.assertRaises(ValueError):
3007            list(rrulestr("DTSTART:19970902T090000\n"
3008                          "RRULE:FREQ=YEARLY;"
3009                          "UNTIL=TheCowsComeHome;BYDAY=1TU,-1TH\n"))
3010
3011    def testStrUntilMustBeUTC(self):
3012        with self.assertRaises(ValueError):
3013            list(rrulestr("DTSTART;TZID=America/New_York:19970902T090000\n"
3014                          "RRULE:FREQ=YEARLY;"
3015                          "UNTIL=19990101T000000;BYDAY=1TU,-1TH\n"))
3016
3017    def testStrUntilWithTZ(self):
3018        NYC = tz.gettz('America/New_York')
3019        rr = list(rrulestr("DTSTART;TZID=America/New_York:19970101T000000\n"
3020                          "RRULE:FREQ=YEARLY;"
3021                          "UNTIL=19990101T000000Z\n"))
3022        self.assertEqual(list(rr), [datetime(1997, 1, 1, 0, 0, 0, tzinfo=NYC),
3023                                    datetime(1998, 1, 1, 0, 0, 0, tzinfo=NYC)])
3024
3025    def testStrEmptyByDay(self):
3026        with self.assertRaises(ValueError):
3027            list(rrulestr("DTSTART:19970902T090000\n"
3028                          "FREQ=WEEKLY;"
3029                          "BYDAY=;"         # This part is invalid
3030                          "WKST=SU"))
3031
3032    def testStrInvalidByDay(self):
3033        with self.assertRaises(ValueError):
3034            list(rrulestr("DTSTART:19970902T090000\n"
3035                          "FREQ=WEEKLY;"
3036                          "BYDAY=-1OK;"         # This part is invalid
3037                          "WKST=SU"))
3038
3039    def testBadBySetPos(self):
3040        self.assertRaises(ValueError,
3041                          rrule, MONTHLY,
3042                                 count=1,
3043                                 bysetpos=0,
3044                                 dtstart=datetime(1997, 9, 2, 9, 0))
3045
3046    def testBadBySetPosMany(self):
3047        self.assertRaises(ValueError,
3048                          rrule, MONTHLY,
3049                                 count=1,
3050                                 bysetpos=(-1, 0, 1),
3051                                 dtstart=datetime(1997, 9, 2, 9, 0))
3052
3053    # Tests to ensure that str(rrule) works
3054    def testToStrYearly(self):
3055        rule = rrule(YEARLY, count=3, dtstart=datetime(1997, 9, 2, 9, 0))
3056        self._rrulestr_reverse_test(rule)
3057
3058    def testToStrYearlyInterval(self):
3059        rule = rrule(YEARLY, count=3, interval=2,
3060                     dtstart=datetime(1997, 9, 2, 9, 0))
3061        self._rrulestr_reverse_test(rule)
3062
3063    def testToStrYearlyByMonth(self):
3064        self._rrulestr_reverse_test(rrule(YEARLY,
3065                                          count=3,
3066                                          bymonth=(1, 3),
3067                                          dtstart=datetime(1997, 9, 2, 9, 0)))
3068
3069    def testToStrYearlyByMonthDay(self):
3070        self._rrulestr_reverse_test(rrule(YEARLY,
3071                                          count=3,
3072                                          bymonthday=(1, 3),
3073                                          dtstart=datetime(1997, 9, 2, 9, 0)))
3074
3075    def testToStrYearlyByMonthAndMonthDay(self):
3076        self._rrulestr_reverse_test(rrule(YEARLY,
3077                                          count=3,
3078                                          bymonth=(1, 3),
3079                                          bymonthday=(5, 7),
3080                                          dtstart=datetime(1997, 9, 2, 9, 0)))
3081
3082    def testToStrYearlyByWeekDay(self):
3083        self._rrulestr_reverse_test(rrule(YEARLY,
3084                                          count=3,
3085                                          byweekday=(TU, TH),
3086                                          dtstart=datetime(1997, 9, 2, 9, 0)))
3087
3088    def testToStrYearlyByNWeekDay(self):
3089        self._rrulestr_reverse_test(rrule(YEARLY,
3090                                          count=3,
3091                                          byweekday=(TU(1), TH(-1)),
3092                                          dtstart=datetime(1997, 9, 2, 9, 0)))
3093
3094    def testToStrYearlyByNWeekDayLarge(self):
3095        self._rrulestr_reverse_test(rrule(YEARLY,
3096                              count=3,
3097                              byweekday=(TU(3), TH(-3)),
3098                              dtstart=datetime(1997, 9, 2, 9, 0)))
3099
3100    def testToStrYearlyByMonthAndWeekDay(self):
3101        self._rrulestr_reverse_test(rrule(YEARLY,
3102                              count=3,
3103                              bymonth=(1, 3),
3104                              byweekday=(TU, TH),
3105                              dtstart=datetime(1997, 9, 2, 9, 0)))
3106
3107    def testToStrYearlyByMonthAndNWeekDay(self):
3108        self._rrulestr_reverse_test(rrule(YEARLY,
3109                              count=3,
3110                              bymonth=(1, 3),
3111                              byweekday=(TU(1), TH(-1)),
3112                              dtstart=datetime(1997, 9, 2, 9, 0)))
3113
3114    def testToStrYearlyByMonthAndNWeekDayLarge(self):
3115        # This is interesting because the TH(-3) ends up before
3116        # the TU(3).
3117        self._rrulestr_reverse_test(rrule(YEARLY,
3118                              count=3,
3119                              bymonth=(1, 3),
3120                              byweekday=(TU(3), TH(-3)),
3121                              dtstart=datetime(1997, 9, 2, 9, 0)))
3122
3123    def testToStrYearlyByMonthDayAndWeekDay(self):
3124        self._rrulestr_reverse_test(rrule(YEARLY,
3125                              count=3,
3126                              bymonthday=(1, 3),
3127                              byweekday=(TU, TH),
3128                              dtstart=datetime(1997, 9, 2, 9, 0)))
3129
3130    def testToStrYearlyByMonthAndMonthDayAndWeekDay(self):
3131        self._rrulestr_reverse_test(rrule(YEARLY,
3132                              count=3,
3133                              bymonth=(1, 3),
3134                              bymonthday=(1, 3),
3135                              byweekday=(TU, TH),
3136                              dtstart=datetime(1997, 9, 2, 9, 0)))
3137
3138    def testToStrYearlyByYearDay(self):
3139        self._rrulestr_reverse_test(rrule(YEARLY,
3140                              count=4,
3141                              byyearday=(1, 100, 200, 365),
3142                              dtstart=datetime(1997, 9, 2, 9, 0)))
3143
3144    def testToStrYearlyByYearDayNeg(self):
3145        self._rrulestr_reverse_test(rrule(YEARLY,
3146                              count=4,
3147                              byyearday=(-365, -266, -166, -1),
3148                              dtstart=datetime(1997, 9, 2, 9, 0)))
3149
3150    def testToStrYearlyByMonthAndYearDay(self):
3151        self._rrulestr_reverse_test(rrule(YEARLY,
3152                              count=4,
3153                              bymonth=(4, 7),
3154                              byyearday=(1, 100, 200, 365),
3155                              dtstart=datetime(1997, 9, 2, 9, 0)))
3156
3157    def testToStrYearlyByMonthAndYearDayNeg(self):
3158        self._rrulestr_reverse_test(rrule(YEARLY,
3159                              count=4,
3160                              bymonth=(4, 7),
3161                              byyearday=(-365, -266, -166, -1),
3162                              dtstart=datetime(1997, 9, 2, 9, 0)))
3163
3164    def testToStrYearlyByWeekNo(self):
3165        self._rrulestr_reverse_test(rrule(YEARLY,
3166                              count=3,
3167                              byweekno=20,
3168                              dtstart=datetime(1997, 9, 2, 9, 0)))
3169
3170    def testToStrYearlyByWeekNoAndWeekDay(self):
3171        # That's a nice one. The first days of week number one
3172        # may be in the last year.
3173        self._rrulestr_reverse_test(rrule(YEARLY,
3174                              count=3,
3175                              byweekno=1,
3176                              byweekday=MO,
3177                              dtstart=datetime(1997, 9, 2, 9, 0)))
3178
3179    def testToStrYearlyByWeekNoAndWeekDayLarge(self):
3180        # Another nice test. The last days of week number 52/53
3181        # may be in the next year.
3182        self._rrulestr_reverse_test(rrule(YEARLY,
3183                              count=3,
3184                              byweekno=52,
3185                              byweekday=SU,
3186                              dtstart=datetime(1997, 9, 2, 9, 0)))
3187
3188    def testToStrYearlyByWeekNoAndWeekDayLast(self):
3189        self._rrulestr_reverse_test(rrule(YEARLY,
3190                              count=3,
3191                              byweekno=-1,
3192                              byweekday=SU,
3193                              dtstart=datetime(1997, 9, 2, 9, 0)))
3194
3195    def testToStrYearlyByEaster(self):
3196        self._rrulestr_reverse_test(rrule(YEARLY,
3197                              count=3,
3198                              byeaster=0,
3199                              dtstart=datetime(1997, 9, 2, 9, 0)))
3200
3201    def testToStrYearlyByEasterPos(self):
3202        self._rrulestr_reverse_test(rrule(YEARLY,
3203                              count=3,
3204                              byeaster=1,
3205                              dtstart=datetime(1997, 9, 2, 9, 0)))
3206
3207    def testToStrYearlyByEasterNeg(self):
3208        self._rrulestr_reverse_test(rrule(YEARLY,
3209                              count=3,
3210                              byeaster=-1,
3211                              dtstart=datetime(1997, 9, 2, 9, 0)))
3212
3213    def testToStrYearlyByWeekNoAndWeekDay53(self):
3214        self._rrulestr_reverse_test(rrule(YEARLY,
3215                              count=3,
3216                              byweekno=53,
3217                              byweekday=MO,
3218                              dtstart=datetime(1997, 9, 2, 9, 0)))
3219
3220    def testToStrYearlyByHour(self):
3221        self._rrulestr_reverse_test(rrule(YEARLY,
3222                              count=3,
3223                              byhour=(6, 18),
3224                              dtstart=datetime(1997, 9, 2, 9, 0)))
3225
3226    def testToStrYearlyByMinute(self):
3227        self._rrulestr_reverse_test(rrule(YEARLY,
3228                              count=3,
3229                              byminute=(6, 18),
3230                              dtstart=datetime(1997, 9, 2, 9, 0)))
3231
3232    def testToStrYearlyBySecond(self):
3233        self._rrulestr_reverse_test(rrule(YEARLY,
3234                              count=3,
3235                              bysecond=(6, 18),
3236                              dtstart=datetime(1997, 9, 2, 9, 0)))
3237
3238    def testToStrYearlyByHourAndMinute(self):
3239        self._rrulestr_reverse_test(rrule(YEARLY,
3240                              count=3,
3241                              byhour=(6, 18),
3242                              byminute=(6, 18),
3243                              dtstart=datetime(1997, 9, 2, 9, 0)))
3244
3245    def testToStrYearlyByHourAndSecond(self):
3246        self._rrulestr_reverse_test(rrule(YEARLY,
3247                              count=3,
3248                              byhour=(6, 18),
3249                              bysecond=(6, 18),
3250                              dtstart=datetime(1997, 9, 2, 9, 0)))
3251
3252    def testToStrYearlyByMinuteAndSecond(self):
3253        self._rrulestr_reverse_test(rrule(YEARLY,
3254                              count=3,
3255                              byminute=(6, 18),
3256                              bysecond=(6, 18),
3257                              dtstart=datetime(1997, 9, 2, 9, 0)))
3258
3259    def testToStrYearlyByHourAndMinuteAndSecond(self):
3260        self._rrulestr_reverse_test(rrule(YEARLY,
3261                              count=3,
3262                              byhour=(6, 18),
3263                              byminute=(6, 18),
3264                              bysecond=(6, 18),
3265                              dtstart=datetime(1997, 9, 2, 9, 0)))
3266
3267    def testToStrYearlyBySetPos(self):
3268        self._rrulestr_reverse_test(rrule(YEARLY,
3269                              count=3,
3270                              bymonthday=15,
3271                              byhour=(6, 18),
3272                              bysetpos=(3, -3),
3273                              dtstart=datetime(1997, 9, 2, 9, 0)))
3274
3275    def testToStrMonthly(self):
3276        self._rrulestr_reverse_test(rrule(MONTHLY,
3277                              count=3,
3278                              dtstart=datetime(1997, 9, 2, 9, 0)))
3279
3280    def testToStrMonthlyInterval(self):
3281        self._rrulestr_reverse_test(rrule(MONTHLY,
3282                              count=3,
3283                              interval=2,
3284                              dtstart=datetime(1997, 9, 2, 9, 0)))
3285
3286    def testToStrMonthlyIntervalLarge(self):
3287        self._rrulestr_reverse_test(rrule(MONTHLY,
3288                              count=3,
3289                              interval=18,
3290                              dtstart=datetime(1997, 9, 2, 9, 0)))
3291
3292    def testToStrMonthlyByMonth(self):
3293        self._rrulestr_reverse_test(rrule(MONTHLY,
3294                              count=3,
3295                              bymonth=(1, 3),
3296                              dtstart=datetime(1997, 9, 2, 9, 0)))
3297
3298    def testToStrMonthlyByMonthDay(self):
3299        self._rrulestr_reverse_test(rrule(MONTHLY,
3300                              count=3,
3301                              bymonthday=(1, 3),
3302                              dtstart=datetime(1997, 9, 2, 9, 0)))
3303
3304    def testToStrMonthlyByMonthAndMonthDay(self):
3305        self._rrulestr_reverse_test(rrule(MONTHLY,
3306                              count=3,
3307                              bymonth=(1, 3),
3308                              bymonthday=(5, 7),
3309                              dtstart=datetime(1997, 9, 2, 9, 0)))
3310
3311    def testToStrMonthlyByWeekDay(self):
3312        self._rrulestr_reverse_test(rrule(MONTHLY,
3313                              count=3,
3314                              byweekday=(TU, TH),
3315                              dtstart=datetime(1997, 9, 2, 9, 0)))
3316
3317        # Third Monday of the month
3318        self.assertEqual(rrule(MONTHLY,
3319                         byweekday=(MO(+3)),
3320                         dtstart=datetime(1997, 9, 1)).between(datetime(1997,
3321                                                                        9,
3322                                                                        1),
3323                                                               datetime(1997,
3324                                                                        12,
3325                                                                        1)),
3326                         [datetime(1997, 9, 15, 0, 0),
3327                          datetime(1997, 10, 20, 0, 0),
3328                          datetime(1997, 11, 17, 0, 0)])
3329
3330    def testToStrMonthlyByNWeekDay(self):
3331        self._rrulestr_reverse_test(rrule(MONTHLY,
3332                              count=3,
3333                              byweekday=(TU(1), TH(-1)),
3334                              dtstart=datetime(1997, 9, 2, 9, 0)))
3335
3336    def testToStrMonthlyByNWeekDayLarge(self):
3337        self._rrulestr_reverse_test(rrule(MONTHLY,
3338                              count=3,
3339                              byweekday=(TU(3), TH(-3)),
3340                              dtstart=datetime(1997, 9, 2, 9, 0)))
3341
3342    def testToStrMonthlyByMonthAndWeekDay(self):
3343        self._rrulestr_reverse_test(rrule(MONTHLY,
3344                              count=3,
3345                              bymonth=(1, 3),
3346                              byweekday=(TU, TH),
3347                              dtstart=datetime(1997, 9, 2, 9, 0)))
3348
3349    def testToStrMonthlyByMonthAndNWeekDay(self):
3350        self._rrulestr_reverse_test(rrule(MONTHLY,
3351                              count=3,
3352                              bymonth=(1, 3),
3353                              byweekday=(TU(1), TH(-1)),
3354                              dtstart=datetime(1997, 9, 2, 9, 0)))
3355
3356    def testToStrMonthlyByMonthAndNWeekDayLarge(self):
3357        self._rrulestr_reverse_test(rrule(MONTHLY,
3358                              count=3,
3359                              bymonth=(1, 3),
3360                              byweekday=(TU(3), TH(-3)),
3361                              dtstart=datetime(1997, 9, 2, 9, 0)))
3362
3363    def testToStrMonthlyByMonthDayAndWeekDay(self):
3364        self._rrulestr_reverse_test(rrule(MONTHLY,
3365                              count=3,
3366                              bymonthday=(1, 3),
3367                              byweekday=(TU, TH),
3368                              dtstart=datetime(1997, 9, 2, 9, 0)))
3369
3370    def testToStrMonthlyByMonthAndMonthDayAndWeekDay(self):
3371        self._rrulestr_reverse_test(rrule(MONTHLY,
3372                              count=3,
3373                              bymonth=(1, 3),
3374                              bymonthday=(1, 3),
3375                              byweekday=(TU, TH),
3376                              dtstart=datetime(1997, 9, 2, 9, 0)))
3377
3378    def testToStrMonthlyByYearDay(self):
3379        self._rrulestr_reverse_test(rrule(MONTHLY,
3380                              count=4,
3381                              byyearday=(1, 100, 200, 365),
3382                              dtstart=datetime(1997, 9, 2, 9, 0)))
3383
3384    def testToStrMonthlyByYearDayNeg(self):
3385        self._rrulestr_reverse_test(rrule(MONTHLY,
3386                              count=4,
3387                              byyearday=(-365, -266, -166, -1),
3388                              dtstart=datetime(1997, 9, 2, 9, 0)))
3389
3390    def testToStrMonthlyByMonthAndYearDay(self):
3391        self._rrulestr_reverse_test(rrule(MONTHLY,
3392                              count=4,
3393                              bymonth=(4, 7),
3394                              byyearday=(1, 100, 200, 365),
3395                              dtstart=datetime(1997, 9, 2, 9, 0)))
3396
3397    def testToStrMonthlyByMonthAndYearDayNeg(self):
3398        self._rrulestr_reverse_test(rrule(MONTHLY,
3399                              count=4,
3400                              bymonth=(4, 7),
3401                              byyearday=(-365, -266, -166, -1),
3402                              dtstart=datetime(1997, 9, 2, 9, 0)))
3403
3404    def testToStrMonthlyByWeekNo(self):
3405        self._rrulestr_reverse_test(rrule(MONTHLY,
3406                              count=3,
3407                              byweekno=20,
3408                              dtstart=datetime(1997, 9, 2, 9, 0)))
3409
3410    def testToStrMonthlyByWeekNoAndWeekDay(self):
3411        # That's a nice one. The first days of week number one
3412        # may be in the last year.
3413        self._rrulestr_reverse_test(rrule(MONTHLY,
3414                              count=3,
3415                              byweekno=1,
3416                              byweekday=MO,
3417                              dtstart=datetime(1997, 9, 2, 9, 0)))
3418
3419    def testToStrMonthlyByWeekNoAndWeekDayLarge(self):
3420        # Another nice test. The last days of week number 52/53
3421        # may be in the next year.
3422        self._rrulestr_reverse_test(rrule(MONTHLY,
3423                              count=3,
3424                              byweekno=52,
3425                              byweekday=SU,
3426                              dtstart=datetime(1997, 9, 2, 9, 0)))
3427
3428    def testToStrMonthlyByWeekNoAndWeekDayLast(self):
3429        self._rrulestr_reverse_test(rrule(MONTHLY,
3430                              count=3,
3431                              byweekno=-1,
3432                              byweekday=SU,
3433                              dtstart=datetime(1997, 9, 2, 9, 0)))
3434
3435    def testToStrMonthlyByWeekNoAndWeekDay53(self):
3436        self._rrulestr_reverse_test(rrule(MONTHLY,
3437                              count=3,
3438                              byweekno=53,
3439                              byweekday=MO,
3440                              dtstart=datetime(1997, 9, 2, 9, 0)))
3441
3442    def testToStrMonthlyByEaster(self):
3443        self._rrulestr_reverse_test(rrule(MONTHLY,
3444                              count=3,
3445                              byeaster=0,
3446                              dtstart=datetime(1997, 9, 2, 9, 0)))
3447
3448    def testToStrMonthlyByEasterPos(self):
3449        self._rrulestr_reverse_test(rrule(MONTHLY,
3450                              count=3,
3451                              byeaster=1,
3452                              dtstart=datetime(1997, 9, 2, 9, 0)))
3453
3454    def testToStrMonthlyByEasterNeg(self):
3455        self._rrulestr_reverse_test(rrule(MONTHLY,
3456                              count=3,
3457                              byeaster=-1,
3458                              dtstart=datetime(1997, 9, 2, 9, 0)))
3459
3460    def testToStrMonthlyByHour(self):
3461        self._rrulestr_reverse_test(rrule(MONTHLY,
3462                              count=3,
3463                              byhour=(6, 18),
3464                              dtstart=datetime(1997, 9, 2, 9, 0)))
3465
3466    def testToStrMonthlyByMinute(self):
3467        self._rrulestr_reverse_test(rrule(MONTHLY,
3468                              count=3,
3469                              byminute=(6, 18),
3470                              dtstart=datetime(1997, 9, 2, 9, 0)))
3471
3472    def testToStrMonthlyBySecond(self):
3473        self._rrulestr_reverse_test(rrule(MONTHLY,
3474                              count=3,
3475                              bysecond=(6, 18),
3476                              dtstart=datetime(1997, 9, 2, 9, 0)))
3477
3478    def testToStrMonthlyByHourAndMinute(self):
3479        self._rrulestr_reverse_test(rrule(MONTHLY,
3480                              count=3,
3481                              byhour=(6, 18),
3482                              byminute=(6, 18),
3483                              dtstart=datetime(1997, 9, 2, 9, 0)))
3484
3485    def testToStrMonthlyByHourAndSecond(self):
3486        self._rrulestr_reverse_test(rrule(MONTHLY,
3487                              count=3,
3488                              byhour=(6, 18),
3489                              bysecond=(6, 18),
3490                              dtstart=datetime(1997, 9, 2, 9, 0)))
3491
3492    def testToStrMonthlyByMinuteAndSecond(self):
3493        self._rrulestr_reverse_test(rrule(MONTHLY,
3494                              count=3,
3495                              byminute=(6, 18),
3496                              bysecond=(6, 18),
3497                              dtstart=datetime(1997, 9, 2, 9, 0)))
3498
3499    def testToStrMonthlyByHourAndMinuteAndSecond(self):
3500        self._rrulestr_reverse_test(rrule(MONTHLY,
3501                              count=3,
3502                              byhour=(6, 18),
3503                              byminute=(6, 18),
3504                              bysecond=(6, 18),
3505                              dtstart=datetime(1997, 9, 2, 9, 0)))
3506
3507    def testToStrMonthlyBySetPos(self):
3508        self._rrulestr_reverse_test(rrule(MONTHLY,
3509                              count=3,
3510                              bymonthday=(13, 17),
3511                              byhour=(6, 18),
3512                              bysetpos=(3, -3),
3513                              dtstart=datetime(1997, 9, 2, 9, 0)))
3514
3515    def testToStrWeekly(self):
3516        self._rrulestr_reverse_test(rrule(WEEKLY,
3517                              count=3,
3518                              dtstart=datetime(1997, 9, 2, 9, 0)))
3519
3520    def testToStrWeeklyInterval(self):
3521        self._rrulestr_reverse_test(rrule(WEEKLY,
3522                              count=3,
3523                              interval=2,
3524                              dtstart=datetime(1997, 9, 2, 9, 0)))
3525
3526    def testToStrWeeklyIntervalLarge(self):
3527        self._rrulestr_reverse_test(rrule(WEEKLY,
3528                              count=3,
3529                              interval=20,
3530                              dtstart=datetime(1997, 9, 2, 9, 0)))
3531
3532    def testToStrWeeklyByMonth(self):
3533        self._rrulestr_reverse_test(rrule(WEEKLY,
3534                              count=3,
3535                              bymonth=(1, 3),
3536                              dtstart=datetime(1997, 9, 2, 9, 0)))
3537
3538    def testToStrWeeklyByMonthDay(self):
3539        self._rrulestr_reverse_test(rrule(WEEKLY,
3540                              count=3,
3541                              bymonthday=(1, 3),
3542                              dtstart=datetime(1997, 9, 2, 9, 0)))
3543
3544    def testToStrWeeklyByMonthAndMonthDay(self):
3545        self._rrulestr_reverse_test(rrule(WEEKLY,
3546                              count=3,
3547                              bymonth=(1, 3),
3548                              bymonthday=(5, 7),
3549                              dtstart=datetime(1997, 9, 2, 9, 0)))
3550
3551    def testToStrWeeklyByWeekDay(self):
3552        self._rrulestr_reverse_test(rrule(WEEKLY,
3553                              count=3,
3554                              byweekday=(TU, TH),
3555                              dtstart=datetime(1997, 9, 2, 9, 0)))
3556
3557    def testToStrWeeklyByNWeekDay(self):
3558        self._rrulestr_reverse_test(rrule(WEEKLY,
3559                              count=3,
3560                              byweekday=(TU(1), TH(-1)),
3561                              dtstart=datetime(1997, 9, 2, 9, 0)))
3562
3563    def testToStrWeeklyByMonthAndWeekDay(self):
3564        # This test is interesting, because it crosses the year
3565        # boundary in a weekly period to find day '1' as a
3566        # valid recurrence.
3567        self._rrulestr_reverse_test(rrule(WEEKLY,
3568                              count=3,
3569                              bymonth=(1, 3),
3570                              byweekday=(TU, TH),
3571                              dtstart=datetime(1997, 9, 2, 9, 0)))
3572
3573    def testToStrWeeklyByMonthAndNWeekDay(self):
3574        self._rrulestr_reverse_test(rrule(WEEKLY,
3575                              count=3,
3576                              bymonth=(1, 3),
3577                              byweekday=(TU(1), TH(-1)),
3578                              dtstart=datetime(1997, 9, 2, 9, 0)))
3579
3580    def testToStrWeeklyByMonthDayAndWeekDay(self):
3581        self._rrulestr_reverse_test(rrule(WEEKLY,
3582                              count=3,
3583                              bymonthday=(1, 3),
3584                              byweekday=(TU, TH),
3585                              dtstart=datetime(1997, 9, 2, 9, 0)))
3586
3587    def testToStrWeeklyByMonthAndMonthDayAndWeekDay(self):
3588        self._rrulestr_reverse_test(rrule(WEEKLY,
3589                              count=3,
3590                              bymonth=(1, 3),
3591                              bymonthday=(1, 3),
3592                              byweekday=(TU, TH),
3593                              dtstart=datetime(1997, 9, 2, 9, 0)))
3594
3595    def testToStrWeeklyByYearDay(self):
3596        self._rrulestr_reverse_test(rrule(WEEKLY,
3597                              count=4,
3598                              byyearday=(1, 100, 200, 365),
3599                              dtstart=datetime(1997, 9, 2, 9, 0)))
3600
3601    def testToStrWeeklyByYearDayNeg(self):
3602        self._rrulestr_reverse_test(rrule(WEEKLY,
3603                              count=4,
3604                              byyearday=(-365, -266, -166, -1),
3605                              dtstart=datetime(1997, 9, 2, 9, 0)))
3606
3607    def testToStrWeeklyByMonthAndYearDay(self):
3608        self._rrulestr_reverse_test(rrule(WEEKLY,
3609                              count=4,
3610                              bymonth=(1, 7),
3611                              byyearday=(1, 100, 200, 365),
3612                              dtstart=datetime(1997, 9, 2, 9, 0)))
3613
3614    def testToStrWeeklyByMonthAndYearDayNeg(self):
3615        self._rrulestr_reverse_test(rrule(WEEKLY,
3616                              count=4,
3617                              bymonth=(1, 7),
3618                              byyearday=(-365, -266, -166, -1),
3619                              dtstart=datetime(1997, 9, 2, 9, 0)))
3620
3621    def testToStrWeeklyByWeekNo(self):
3622        self._rrulestr_reverse_test(rrule(WEEKLY,
3623                              count=3,
3624                              byweekno=20,
3625                              dtstart=datetime(1997, 9, 2, 9, 0)))
3626
3627    def testToStrWeeklyByWeekNoAndWeekDay(self):
3628        # That's a nice one. The first days of week number one
3629        # may be in the last year.
3630        self._rrulestr_reverse_test(rrule(WEEKLY,
3631                              count=3,
3632                              byweekno=1,
3633                              byweekday=MO,
3634                              dtstart=datetime(1997, 9, 2, 9, 0)))
3635
3636    def testToStrWeeklyByWeekNoAndWeekDayLarge(self):
3637        # Another nice test. The last days of week number 52/53
3638        # may be in the next year.
3639        self._rrulestr_reverse_test(rrule(WEEKLY,
3640                              count=3,
3641                              byweekno=52,
3642                              byweekday=SU,
3643                              dtstart=datetime(1997, 9, 2, 9, 0)))
3644
3645    def testToStrWeeklyByWeekNoAndWeekDayLast(self):
3646        self._rrulestr_reverse_test(rrule(WEEKLY,
3647                              count=3,
3648                              byweekno=-1,
3649                              byweekday=SU,
3650                              dtstart=datetime(1997, 9, 2, 9, 0)))
3651
3652    def testToStrWeeklyByWeekNoAndWeekDay53(self):
3653        self._rrulestr_reverse_test(rrule(WEEKLY,
3654                              count=3,
3655                              byweekno=53,
3656                              byweekday=MO,
3657                              dtstart=datetime(1997, 9, 2, 9, 0)))
3658
3659    def testToStrWeeklyByEaster(self):
3660        self._rrulestr_reverse_test(rrule(WEEKLY,
3661                              count=3,
3662                              byeaster=0,
3663                              dtstart=datetime(1997, 9, 2, 9, 0)))
3664
3665    def testToStrWeeklyByEasterPos(self):
3666        self._rrulestr_reverse_test(rrule(WEEKLY,
3667                              count=3,
3668                              byeaster=1,
3669                              dtstart=datetime(1997, 9, 2, 9, 0)))
3670
3671    def testToStrWeeklyByEasterNeg(self):
3672        self._rrulestr_reverse_test(rrule(WEEKLY,
3673                              count=3,
3674                              byeaster=-1,
3675                              dtstart=datetime(1997, 9, 2, 9, 0)))
3676
3677    def testToStrWeeklyByHour(self):
3678        self._rrulestr_reverse_test(rrule(WEEKLY,
3679                              count=3,
3680                              byhour=(6, 18),
3681                              dtstart=datetime(1997, 9, 2, 9, 0)))
3682
3683    def testToStrWeeklyByMinute(self):
3684        self._rrulestr_reverse_test(rrule(WEEKLY,
3685                              count=3,
3686                              byminute=(6, 18),
3687                              dtstart=datetime(1997, 9, 2, 9, 0)))
3688
3689    def testToStrWeeklyBySecond(self):
3690        self._rrulestr_reverse_test(rrule(WEEKLY,
3691                              count=3,
3692                              bysecond=(6, 18),
3693                              dtstart=datetime(1997, 9, 2, 9, 0)))
3694
3695    def testToStrWeeklyByHourAndMinute(self):
3696        self._rrulestr_reverse_test(rrule(WEEKLY,
3697                              count=3,
3698                              byhour=(6, 18),
3699                              byminute=(6, 18),
3700                              dtstart=datetime(1997, 9, 2, 9, 0)))
3701
3702    def testToStrWeeklyByHourAndSecond(self):
3703        self._rrulestr_reverse_test(rrule(WEEKLY,
3704                              count=3,
3705                              byhour=(6, 18),
3706                              bysecond=(6, 18),
3707                              dtstart=datetime(1997, 9, 2, 9, 0)))
3708
3709    def testToStrWeeklyByMinuteAndSecond(self):
3710        self._rrulestr_reverse_test(rrule(WEEKLY,
3711                              count=3,
3712                              byminute=(6, 18),
3713                              bysecond=(6, 18),
3714                              dtstart=datetime(1997, 9, 2, 9, 0)))
3715
3716    def testToStrWeeklyByHourAndMinuteAndSecond(self):
3717        self._rrulestr_reverse_test(rrule(WEEKLY,
3718                              count=3,
3719                              byhour=(6, 18),
3720                              byminute=(6, 18),
3721                              bysecond=(6, 18),
3722                              dtstart=datetime(1997, 9, 2, 9, 0)))
3723
3724    def testToStrWeeklyBySetPos(self):
3725        self._rrulestr_reverse_test(rrule(WEEKLY,
3726                              count=3,
3727                              byweekday=(TU, TH),
3728                              byhour=(6, 18),
3729                              bysetpos=(3, -3),
3730                              dtstart=datetime(1997, 9, 2, 9, 0)))
3731
3732    def testToStrDaily(self):
3733        self._rrulestr_reverse_test(rrule(DAILY,
3734                              count=3,
3735                              dtstart=datetime(1997, 9, 2, 9, 0)))
3736
3737    def testToStrDailyInterval(self):
3738        self._rrulestr_reverse_test(rrule(DAILY,
3739                              count=3,
3740                              interval=2,
3741                              dtstart=datetime(1997, 9, 2, 9, 0)))
3742
3743    def testToStrDailyIntervalLarge(self):
3744        self._rrulestr_reverse_test(rrule(DAILY,
3745                              count=3,
3746                              interval=92,
3747                              dtstart=datetime(1997, 9, 2, 9, 0)))
3748
3749    def testToStrDailyByMonth(self):
3750        self._rrulestr_reverse_test(rrule(DAILY,
3751                              count=3,
3752                              bymonth=(1, 3),
3753                              dtstart=datetime(1997, 9, 2, 9, 0)))
3754
3755    def testToStrDailyByMonthDay(self):
3756        self._rrulestr_reverse_test(rrule(DAILY,
3757                              count=3,
3758                              bymonthday=(1, 3),
3759                              dtstart=datetime(1997, 9, 2, 9, 0)))
3760
3761    def testToStrDailyByMonthAndMonthDay(self):
3762        self._rrulestr_reverse_test(rrule(DAILY,
3763                              count=3,
3764                              bymonth=(1, 3),
3765                              bymonthday=(5, 7),
3766                              dtstart=datetime(1997, 9, 2, 9, 0)))
3767
3768    def testToStrDailyByWeekDay(self):
3769        self._rrulestr_reverse_test(rrule(DAILY,
3770                              count=3,
3771                              byweekday=(TU, TH),
3772                              dtstart=datetime(1997, 9, 2, 9, 0)))
3773
3774    def testToStrDailyByNWeekDay(self):
3775        self._rrulestr_reverse_test(rrule(DAILY,
3776                              count=3,
3777                              byweekday=(TU(1), TH(-1)),
3778                              dtstart=datetime(1997, 9, 2, 9, 0)))
3779
3780    def testToStrDailyByMonthAndWeekDay(self):
3781        self._rrulestr_reverse_test(rrule(DAILY,
3782                              count=3,
3783                              bymonth=(1, 3),
3784                              byweekday=(TU, TH),
3785                              dtstart=datetime(1997, 9, 2, 9, 0)))
3786
3787    def testToStrDailyByMonthAndNWeekDay(self):
3788        self._rrulestr_reverse_test(rrule(DAILY,
3789                              count=3,
3790                              bymonth=(1, 3),
3791                              byweekday=(TU(1), TH(-1)),
3792                              dtstart=datetime(1997, 9, 2, 9, 0)))
3793
3794    def testToStrDailyByMonthDayAndWeekDay(self):
3795        self._rrulestr_reverse_test(rrule(DAILY,
3796                              count=3,
3797                              bymonthday=(1, 3),
3798                              byweekday=(TU, TH),
3799                              dtstart=datetime(1997, 9, 2, 9, 0)))
3800
3801    def testToStrDailyByMonthAndMonthDayAndWeekDay(self):
3802        self._rrulestr_reverse_test(rrule(DAILY,
3803                              count=3,
3804                              bymonth=(1, 3),
3805                              bymonthday=(1, 3),
3806                              byweekday=(TU, TH),
3807                              dtstart=datetime(1997, 9, 2, 9, 0)))
3808
3809    def testToStrDailyByYearDay(self):
3810        self._rrulestr_reverse_test(rrule(DAILY,
3811                              count=4,
3812                              byyearday=(1, 100, 200, 365),
3813                              dtstart=datetime(1997, 9, 2, 9, 0)))
3814
3815    def testToStrDailyByYearDayNeg(self):
3816        self._rrulestr_reverse_test(rrule(DAILY,
3817                              count=4,
3818                              byyearday=(-365, -266, -166, -1),
3819                              dtstart=datetime(1997, 9, 2, 9, 0)))
3820
3821    def testToStrDailyByMonthAndYearDay(self):
3822        self._rrulestr_reverse_test(rrule(DAILY,
3823                              count=4,
3824                              bymonth=(1, 7),
3825                              byyearday=(1, 100, 200, 365),
3826                              dtstart=datetime(1997, 9, 2, 9, 0)))
3827
3828    def testToStrDailyByMonthAndYearDayNeg(self):
3829        self._rrulestr_reverse_test(rrule(DAILY,
3830                              count=4,
3831                              bymonth=(1, 7),
3832                              byyearday=(-365, -266, -166, -1),
3833                              dtstart=datetime(1997, 9, 2, 9, 0)))
3834
3835    def testToStrDailyByWeekNo(self):
3836        self._rrulestr_reverse_test(rrule(DAILY,
3837                              count=3,
3838                              byweekno=20,
3839                              dtstart=datetime(1997, 9, 2, 9, 0)))
3840
3841    def testToStrDailyByWeekNoAndWeekDay(self):
3842        # That's a nice one. The first days of week number one
3843        # may be in the last year.
3844        self._rrulestr_reverse_test(rrule(DAILY,
3845                              count=3,
3846                              byweekno=1,
3847                              byweekday=MO,
3848                              dtstart=datetime(1997, 9, 2, 9, 0)))
3849
3850    def testToStrDailyByWeekNoAndWeekDayLarge(self):
3851        # Another nice test. The last days of week number 52/53
3852        # may be in the next year.
3853        self._rrulestr_reverse_test(rrule(DAILY,
3854                              count=3,
3855                              byweekno=52,
3856                              byweekday=SU,
3857                              dtstart=datetime(1997, 9, 2, 9, 0)))
3858
3859    def testToStrDailyByWeekNoAndWeekDayLast(self):
3860        self._rrulestr_reverse_test(rrule(DAILY,
3861                              count=3,
3862                              byweekno=-1,
3863                              byweekday=SU,
3864                              dtstart=datetime(1997, 9, 2, 9, 0)))
3865
3866    def testToStrDailyByWeekNoAndWeekDay53(self):
3867        self._rrulestr_reverse_test(rrule(DAILY,
3868                              count=3,
3869                              byweekno=53,
3870                              byweekday=MO,
3871                              dtstart=datetime(1997, 9, 2, 9, 0)))
3872
3873    def testToStrDailyByEaster(self):
3874        self._rrulestr_reverse_test(rrule(DAILY,
3875                              count=3,
3876                              byeaster=0,
3877                              dtstart=datetime(1997, 9, 2, 9, 0)))
3878
3879    def testToStrDailyByEasterPos(self):
3880        self._rrulestr_reverse_test(rrule(DAILY,
3881                              count=3,
3882                              byeaster=1,
3883                              dtstart=datetime(1997, 9, 2, 9, 0)))
3884
3885    def testToStrDailyByEasterNeg(self):
3886        self._rrulestr_reverse_test(rrule(DAILY,
3887                              count=3,
3888                              byeaster=-1,
3889                              dtstart=datetime(1997, 9, 2, 9, 0)))
3890
3891    def testToStrDailyByHour(self):
3892        self._rrulestr_reverse_test(rrule(DAILY,
3893                              count=3,
3894                              byhour=(6, 18),
3895                              dtstart=datetime(1997, 9, 2, 9, 0)))
3896
3897    def testToStrDailyByMinute(self):
3898        self._rrulestr_reverse_test(rrule(DAILY,
3899                              count=3,
3900                              byminute=(6, 18),
3901                              dtstart=datetime(1997, 9, 2, 9, 0)))
3902
3903    def testToStrDailyBySecond(self):
3904        self._rrulestr_reverse_test(rrule(DAILY,
3905                              count=3,
3906                              bysecond=(6, 18),
3907                              dtstart=datetime(1997, 9, 2, 9, 0)))
3908
3909    def testToStrDailyByHourAndMinute(self):
3910        self._rrulestr_reverse_test(rrule(DAILY,
3911                              count=3,
3912                              byhour=(6, 18),
3913                              byminute=(6, 18),
3914                              dtstart=datetime(1997, 9, 2, 9, 0)))
3915
3916    def testToStrDailyByHourAndSecond(self):
3917        self._rrulestr_reverse_test(rrule(DAILY,
3918                              count=3,
3919                              byhour=(6, 18),
3920                              bysecond=(6, 18),
3921                              dtstart=datetime(1997, 9, 2, 9, 0)))
3922
3923    def testToStrDailyByMinuteAndSecond(self):
3924        self._rrulestr_reverse_test(rrule(DAILY,
3925                              count=3,
3926                              byminute=(6, 18),
3927                              bysecond=(6, 18),
3928                              dtstart=datetime(1997, 9, 2, 9, 0)))
3929
3930    def testToStrDailyByHourAndMinuteAndSecond(self):
3931        self._rrulestr_reverse_test(rrule(DAILY,
3932                              count=3,
3933                              byhour=(6, 18),
3934                              byminute=(6, 18),
3935                              bysecond=(6, 18),
3936                              dtstart=datetime(1997, 9, 2, 9, 0)))
3937
3938    def testToStrDailyBySetPos(self):
3939        self._rrulestr_reverse_test(rrule(DAILY,
3940                              count=3,
3941                              byhour=(6, 18),
3942                              byminute=(15, 45),
3943                              bysetpos=(3, -3),
3944                              dtstart=datetime(1997, 9, 2, 9, 0)))
3945
3946    def testToStrHourly(self):
3947        self._rrulestr_reverse_test(rrule(HOURLY,
3948                              count=3,
3949                              dtstart=datetime(1997, 9, 2, 9, 0)))
3950
3951    def testToStrHourlyInterval(self):
3952        self._rrulestr_reverse_test(rrule(HOURLY,
3953                              count=3,
3954                              interval=2,
3955                              dtstart=datetime(1997, 9, 2, 9, 0)))
3956
3957    def testToStrHourlyIntervalLarge(self):
3958        self._rrulestr_reverse_test(rrule(HOURLY,
3959                              count=3,
3960                              interval=769,
3961                              dtstart=datetime(1997, 9, 2, 9, 0)))
3962
3963    def testToStrHourlyByMonth(self):
3964        self._rrulestr_reverse_test(rrule(HOURLY,
3965                              count=3,
3966                              bymonth=(1, 3),
3967                              dtstart=datetime(1997, 9, 2, 9, 0)))
3968
3969    def testToStrHourlyByMonthDay(self):
3970        self._rrulestr_reverse_test(rrule(HOURLY,
3971                              count=3,
3972                              bymonthday=(1, 3),
3973                              dtstart=datetime(1997, 9, 2, 9, 0)))
3974
3975    def testToStrHourlyByMonthAndMonthDay(self):
3976        self._rrulestr_reverse_test(rrule(HOURLY,
3977                              count=3,
3978                              bymonth=(1, 3),
3979                              bymonthday=(5, 7),
3980                              dtstart=datetime(1997, 9, 2, 9, 0)))
3981
3982    def testToStrHourlyByWeekDay(self):
3983        self._rrulestr_reverse_test(rrule(HOURLY,
3984                              count=3,
3985                              byweekday=(TU, TH),
3986                              dtstart=datetime(1997, 9, 2, 9, 0)))
3987
3988    def testToStrHourlyByNWeekDay(self):
3989        self._rrulestr_reverse_test(rrule(HOURLY,
3990                              count=3,
3991                              byweekday=(TU(1), TH(-1)),
3992                              dtstart=datetime(1997, 9, 2, 9, 0)))
3993
3994    def testToStrHourlyByMonthAndWeekDay(self):
3995        self._rrulestr_reverse_test(rrule(HOURLY,
3996                              count=3,
3997                              bymonth=(1, 3),
3998                              byweekday=(TU, TH),
3999                              dtstart=datetime(1997, 9, 2, 9, 0)))
4000
4001    def testToStrHourlyByMonthAndNWeekDay(self):
4002        self._rrulestr_reverse_test(rrule(HOURLY,
4003                              count=3,
4004                              bymonth=(1, 3),
4005                              byweekday=(TU(1), TH(-1)),
4006                              dtstart=datetime(1997, 9, 2, 9, 0)))
4007
4008    def testToStrHourlyByMonthDayAndWeekDay(self):
4009        self._rrulestr_reverse_test(rrule(HOURLY,
4010                              count=3,
4011                              bymonthday=(1, 3),
4012                              byweekday=(TU, TH),
4013                              dtstart=datetime(1997, 9, 2, 9, 0)))
4014
4015    def testToStrHourlyByMonthAndMonthDayAndWeekDay(self):
4016        self._rrulestr_reverse_test(rrule(HOURLY,
4017                              count=3,
4018                              bymonth=(1, 3),
4019                              bymonthday=(1, 3),
4020                              byweekday=(TU, TH),
4021                              dtstart=datetime(1997, 9, 2, 9, 0)))
4022
4023    def testToStrHourlyByYearDay(self):
4024        self._rrulestr_reverse_test(rrule(HOURLY,
4025                              count=4,
4026                              byyearday=(1, 100, 200, 365),
4027                              dtstart=datetime(1997, 9, 2, 9, 0)))
4028
4029    def testToStrHourlyByYearDayNeg(self):
4030        self._rrulestr_reverse_test(rrule(HOURLY,
4031                              count=4,
4032                              byyearday=(-365, -266, -166, -1),
4033                              dtstart=datetime(1997, 9, 2, 9, 0)))
4034
4035    def testToStrHourlyByMonthAndYearDay(self):
4036        self._rrulestr_reverse_test(rrule(HOURLY,
4037                              count=4,
4038                              bymonth=(4, 7),
4039                              byyearday=(1, 100, 200, 365),
4040                              dtstart=datetime(1997, 9, 2, 9, 0)))
4041
4042    def testToStrHourlyByMonthAndYearDayNeg(self):
4043        self._rrulestr_reverse_test(rrule(HOURLY,
4044                              count=4,
4045                              bymonth=(4, 7),
4046                              byyearday=(-365, -266, -166, -1),
4047                              dtstart=datetime(1997, 9, 2, 9, 0)))
4048
4049    def testToStrHourlyByWeekNo(self):
4050        self._rrulestr_reverse_test(rrule(HOURLY,
4051                              count=3,
4052                              byweekno=20,
4053                              dtstart=datetime(1997, 9, 2, 9, 0)))
4054
4055    def testToStrHourlyByWeekNoAndWeekDay(self):
4056        self._rrulestr_reverse_test(rrule(HOURLY,
4057                              count=3,
4058                              byweekno=1,
4059                              byweekday=MO,
4060                              dtstart=datetime(1997, 9, 2, 9, 0)))
4061
4062    def testToStrHourlyByWeekNoAndWeekDayLarge(self):
4063        self._rrulestr_reverse_test(rrule(HOURLY,
4064                              count=3,
4065                              byweekno=52,
4066                              byweekday=SU,
4067                              dtstart=datetime(1997, 9, 2, 9, 0)))
4068
4069    def testToStrHourlyByWeekNoAndWeekDayLast(self):
4070        self._rrulestr_reverse_test(rrule(HOURLY,
4071                              count=3,
4072                              byweekno=-1,
4073                              byweekday=SU,
4074                              dtstart=datetime(1997, 9, 2, 9, 0)))
4075
4076    def testToStrHourlyByWeekNoAndWeekDay53(self):
4077        self._rrulestr_reverse_test(rrule(HOURLY,
4078                              count=3,
4079                              byweekno=53,
4080                              byweekday=MO,
4081                              dtstart=datetime(1997, 9, 2, 9, 0)))
4082
4083    def testToStrHourlyByEaster(self):
4084        self._rrulestr_reverse_test(rrule(HOURLY,
4085                              count=3,
4086                              byeaster=0,
4087                              dtstart=datetime(1997, 9, 2, 9, 0)))
4088
4089    def testToStrHourlyByEasterPos(self):
4090        self._rrulestr_reverse_test(rrule(HOURLY,
4091                              count=3,
4092                              byeaster=1,
4093                              dtstart=datetime(1997, 9, 2, 9, 0)))
4094
4095    def testToStrHourlyByEasterNeg(self):
4096        self._rrulestr_reverse_test(rrule(HOURLY,
4097                              count=3,
4098                              byeaster=-1,
4099                              dtstart=datetime(1997, 9, 2, 9, 0)))
4100
4101    def testToStrHourlyByHour(self):
4102        self._rrulestr_reverse_test(rrule(HOURLY,
4103                              count=3,
4104                              byhour=(6, 18),
4105                              dtstart=datetime(1997, 9, 2, 9, 0)))
4106
4107    def testToStrHourlyByMinute(self):
4108        self._rrulestr_reverse_test(rrule(HOURLY,
4109                              count=3,
4110                              byminute=(6, 18),
4111                              dtstart=datetime(1997, 9, 2, 9, 0)))
4112
4113    def testToStrHourlyBySecond(self):
4114        self._rrulestr_reverse_test(rrule(HOURLY,
4115                              count=3,
4116                              bysecond=(6, 18),
4117                              dtstart=datetime(1997, 9, 2, 9, 0)))
4118
4119    def testToStrHourlyByHourAndMinute(self):
4120        self._rrulestr_reverse_test(rrule(HOURLY,
4121                              count=3,
4122                              byhour=(6, 18),
4123                              byminute=(6, 18),
4124                              dtstart=datetime(1997, 9, 2, 9, 0)))
4125
4126    def testToStrHourlyByHourAndSecond(self):
4127        self._rrulestr_reverse_test(rrule(HOURLY,
4128                              count=3,
4129                              byhour=(6, 18),
4130                              bysecond=(6, 18),
4131                              dtstart=datetime(1997, 9, 2, 9, 0)))
4132
4133    def testToStrHourlyByMinuteAndSecond(self):
4134        self._rrulestr_reverse_test(rrule(HOURLY,
4135                              count=3,
4136                              byminute=(6, 18),
4137                              bysecond=(6, 18),
4138                              dtstart=datetime(1997, 9, 2, 9, 0)))
4139
4140    def testToStrHourlyByHourAndMinuteAndSecond(self):
4141        self._rrulestr_reverse_test(rrule(HOURLY,
4142                              count=3,
4143                              byhour=(6, 18),
4144                              byminute=(6, 18),
4145                              bysecond=(6, 18),
4146                              dtstart=datetime(1997, 9, 2, 9, 0)))
4147
4148    def testToStrHourlyBySetPos(self):
4149        self._rrulestr_reverse_test(rrule(HOURLY,
4150                              count=3,
4151                              byminute=(15, 45),
4152                              bysecond=(15, 45),
4153                              bysetpos=(3, -3),
4154                              dtstart=datetime(1997, 9, 2, 9, 0)))
4155
4156    def testToStrMinutely(self):
4157        self._rrulestr_reverse_test(rrule(MINUTELY,
4158                              count=3,
4159                              dtstart=datetime(1997, 9, 2, 9, 0)))
4160
4161    def testToStrMinutelyInterval(self):
4162        self._rrulestr_reverse_test(rrule(MINUTELY,
4163                              count=3,
4164                              interval=2,
4165                              dtstart=datetime(1997, 9, 2, 9, 0)))
4166
4167    def testToStrMinutelyIntervalLarge(self):
4168        self._rrulestr_reverse_test(rrule(MINUTELY,
4169                              count=3,
4170                              interval=1501,
4171                              dtstart=datetime(1997, 9, 2, 9, 0)))
4172
4173    def testToStrMinutelyByMonth(self):
4174        self._rrulestr_reverse_test(rrule(MINUTELY,
4175                              count=3,
4176                              bymonth=(1, 3),
4177                              dtstart=datetime(1997, 9, 2, 9, 0)))
4178
4179    def testToStrMinutelyByMonthDay(self):
4180        self._rrulestr_reverse_test(rrule(MINUTELY,
4181                              count=3,
4182                              bymonthday=(1, 3),
4183                              dtstart=datetime(1997, 9, 2, 9, 0)))
4184
4185    def testToStrMinutelyByMonthAndMonthDay(self):
4186        self._rrulestr_reverse_test(rrule(MINUTELY,
4187                              count=3,
4188                              bymonth=(1, 3),
4189                              bymonthday=(5, 7),
4190                              dtstart=datetime(1997, 9, 2, 9, 0)))
4191
4192    def testToStrMinutelyByWeekDay(self):
4193        self._rrulestr_reverse_test(rrule(MINUTELY,
4194                              count=3,
4195                              byweekday=(TU, TH),
4196                              dtstart=datetime(1997, 9, 2, 9, 0)))
4197
4198    def testToStrMinutelyByNWeekDay(self):
4199        self._rrulestr_reverse_test(rrule(MINUTELY,
4200                              count=3,
4201                              byweekday=(TU(1), TH(-1)),
4202                              dtstart=datetime(1997, 9, 2, 9, 0)))
4203
4204    def testToStrMinutelyByMonthAndWeekDay(self):
4205        self._rrulestr_reverse_test(rrule(MINUTELY,
4206                              count=3,
4207                              bymonth=(1, 3),
4208                              byweekday=(TU, TH),
4209                              dtstart=datetime(1997, 9, 2, 9, 0)))
4210
4211    def testToStrMinutelyByMonthAndNWeekDay(self):
4212        self._rrulestr_reverse_test(rrule(MINUTELY,
4213                              count=3,
4214                              bymonth=(1, 3),
4215                              byweekday=(TU(1), TH(-1)),
4216                              dtstart=datetime(1997, 9, 2, 9, 0)))
4217
4218    def testToStrMinutelyByMonthDayAndWeekDay(self):
4219        self._rrulestr_reverse_test(rrule(MINUTELY,
4220                              count=3,
4221                              bymonthday=(1, 3),
4222                              byweekday=(TU, TH),
4223                              dtstart=datetime(1997, 9, 2, 9, 0)))
4224
4225    def testToStrMinutelyByMonthAndMonthDayAndWeekDay(self):
4226        self._rrulestr_reverse_test(rrule(MINUTELY,
4227                              count=3,
4228                              bymonth=(1, 3),
4229                              bymonthday=(1, 3),
4230                              byweekday=(TU, TH),
4231                              dtstart=datetime(1997, 9, 2, 9, 0)))
4232
4233    def testToStrMinutelyByYearDay(self):
4234        self._rrulestr_reverse_test(rrule(MINUTELY,
4235                              count=4,
4236                              byyearday=(1, 100, 200, 365),
4237                              dtstart=datetime(1997, 9, 2, 9, 0)))
4238
4239    def testToStrMinutelyByYearDayNeg(self):
4240        self._rrulestr_reverse_test(rrule(MINUTELY,
4241                              count=4,
4242                              byyearday=(-365, -266, -166, -1),
4243                              dtstart=datetime(1997, 9, 2, 9, 0)))
4244
4245    def testToStrMinutelyByMonthAndYearDay(self):
4246        self._rrulestr_reverse_test(rrule(MINUTELY,
4247                              count=4,
4248                              bymonth=(4, 7),
4249                              byyearday=(1, 100, 200, 365),
4250                              dtstart=datetime(1997, 9, 2, 9, 0)))
4251
4252    def testToStrMinutelyByMonthAndYearDayNeg(self):
4253        self._rrulestr_reverse_test(rrule(MINUTELY,
4254                              count=4,
4255                              bymonth=(4, 7),
4256                              byyearday=(-365, -266, -166, -1),
4257                              dtstart=datetime(1997, 9, 2, 9, 0)))
4258
4259    def testToStrMinutelyByWeekNo(self):
4260        self._rrulestr_reverse_test(rrule(MINUTELY,
4261                              count=3,
4262                              byweekno=20,
4263                              dtstart=datetime(1997, 9, 2, 9, 0)))
4264
4265    def testToStrMinutelyByWeekNoAndWeekDay(self):
4266        self._rrulestr_reverse_test(rrule(MINUTELY,
4267                              count=3,
4268                              byweekno=1,
4269                              byweekday=MO,
4270                              dtstart=datetime(1997, 9, 2, 9, 0)))
4271
4272    def testToStrMinutelyByWeekNoAndWeekDayLarge(self):
4273        self._rrulestr_reverse_test(rrule(MINUTELY,
4274                              count=3,
4275                              byweekno=52,
4276                              byweekday=SU,
4277                              dtstart=datetime(1997, 9, 2, 9, 0)))
4278
4279    def testToStrMinutelyByWeekNoAndWeekDayLast(self):
4280        self._rrulestr_reverse_test(rrule(MINUTELY,
4281                              count=3,
4282                              byweekno=-1,
4283                              byweekday=SU,
4284                              dtstart=datetime(1997, 9, 2, 9, 0)))
4285
4286    def testToStrMinutelyByWeekNoAndWeekDay53(self):
4287        self._rrulestr_reverse_test(rrule(MINUTELY,
4288                              count=3,
4289                              byweekno=53,
4290                              byweekday=MO,
4291                              dtstart=datetime(1997, 9, 2, 9, 0)))
4292
4293    def testToStrMinutelyByEaster(self):
4294        self._rrulestr_reverse_test(rrule(MINUTELY,
4295                              count=3,
4296                              byeaster=0,
4297                              dtstart=datetime(1997, 9, 2, 9, 0)))
4298
4299    def testToStrMinutelyByEasterPos(self):
4300        self._rrulestr_reverse_test(rrule(MINUTELY,
4301                              count=3,
4302                              byeaster=1,
4303                              dtstart=datetime(1997, 9, 2, 9, 0)))
4304
4305    def testToStrMinutelyByEasterNeg(self):
4306        self._rrulestr_reverse_test(rrule(MINUTELY,
4307                              count=3,
4308                              byeaster=-1,
4309                              dtstart=datetime(1997, 9, 2, 9, 0)))
4310
4311    def testToStrMinutelyByHour(self):
4312        self._rrulestr_reverse_test(rrule(MINUTELY,
4313                              count=3,
4314                              byhour=(6, 18),
4315                              dtstart=datetime(1997, 9, 2, 9, 0)))
4316
4317    def testToStrMinutelyByMinute(self):
4318        self._rrulestr_reverse_test(rrule(MINUTELY,
4319                              count=3,
4320                              byminute=(6, 18),
4321                              dtstart=datetime(1997, 9, 2, 9, 0)))
4322
4323    def testToStrMinutelyBySecond(self):
4324        self._rrulestr_reverse_test(rrule(MINUTELY,
4325                              count=3,
4326                              bysecond=(6, 18),
4327                              dtstart=datetime(1997, 9, 2, 9, 0)))
4328
4329    def testToStrMinutelyByHourAndMinute(self):
4330        self._rrulestr_reverse_test(rrule(MINUTELY,
4331                              count=3,
4332                              byhour=(6, 18),
4333                              byminute=(6, 18),
4334                              dtstart=datetime(1997, 9, 2, 9, 0)))
4335
4336    def testToStrMinutelyByHourAndSecond(self):
4337        self._rrulestr_reverse_test(rrule(MINUTELY,
4338                              count=3,
4339                              byhour=(6, 18),
4340                              bysecond=(6, 18),
4341                              dtstart=datetime(1997, 9, 2, 9, 0)))
4342
4343    def testToStrMinutelyByMinuteAndSecond(self):
4344        self._rrulestr_reverse_test(rrule(MINUTELY,
4345                              count=3,
4346                              byminute=(6, 18),
4347                              bysecond=(6, 18),
4348                              dtstart=datetime(1997, 9, 2, 9, 0)))
4349
4350    def testToStrMinutelyByHourAndMinuteAndSecond(self):
4351        self._rrulestr_reverse_test(rrule(MINUTELY,
4352                              count=3,
4353                              byhour=(6, 18),
4354                              byminute=(6, 18),
4355                              bysecond=(6, 18),
4356                              dtstart=datetime(1997, 9, 2, 9, 0)))
4357
4358    def testToStrMinutelyBySetPos(self):
4359        self._rrulestr_reverse_test(rrule(MINUTELY,
4360                              count=3,
4361                              bysecond=(15, 30, 45),
4362                              bysetpos=(3, -3),
4363                              dtstart=datetime(1997, 9, 2, 9, 0)))
4364
4365    def testToStrSecondly(self):
4366        self._rrulestr_reverse_test(rrule(SECONDLY,
4367                              count=3,
4368                              dtstart=datetime(1997, 9, 2, 9, 0)))
4369
4370    def testToStrSecondlyInterval(self):
4371        self._rrulestr_reverse_test(rrule(SECONDLY,
4372                              count=3,
4373                              interval=2,
4374                              dtstart=datetime(1997, 9, 2, 9, 0)))
4375
4376    def testToStrSecondlyIntervalLarge(self):
4377        self._rrulestr_reverse_test(rrule(SECONDLY,
4378                              count=3,
4379                              interval=90061,
4380                              dtstart=datetime(1997, 9, 2, 9, 0)))
4381
4382    def testToStrSecondlyByMonth(self):
4383        self._rrulestr_reverse_test(rrule(SECONDLY,
4384                              count=3,
4385                              bymonth=(1, 3),
4386                              dtstart=datetime(1997, 9, 2, 9, 0)))
4387
4388    def testToStrSecondlyByMonthDay(self):
4389        self._rrulestr_reverse_test(rrule(SECONDLY,
4390                              count=3,
4391                              bymonthday=(1, 3),
4392                              dtstart=datetime(1997, 9, 2, 9, 0)))
4393
4394    def testToStrSecondlyByMonthAndMonthDay(self):
4395        self._rrulestr_reverse_test(rrule(SECONDLY,
4396                              count=3,
4397                              bymonth=(1, 3),
4398                              bymonthday=(5, 7),
4399                              dtstart=datetime(1997, 9, 2, 9, 0)))
4400
4401    def testToStrSecondlyByWeekDay(self):
4402        self._rrulestr_reverse_test(rrule(SECONDLY,
4403                              count=3,
4404                              byweekday=(TU, TH),
4405                              dtstart=datetime(1997, 9, 2, 9, 0)))
4406
4407    def testToStrSecondlyByNWeekDay(self):
4408        self._rrulestr_reverse_test(rrule(SECONDLY,
4409                              count=3,
4410                              byweekday=(TU(1), TH(-1)),
4411                              dtstart=datetime(1997, 9, 2, 9, 0)))
4412
4413    def testToStrSecondlyByMonthAndWeekDay(self):
4414        self._rrulestr_reverse_test(rrule(SECONDLY,
4415                              count=3,
4416                              bymonth=(1, 3),
4417                              byweekday=(TU, TH),
4418                              dtstart=datetime(1997, 9, 2, 9, 0)))
4419
4420    def testToStrSecondlyByMonthAndNWeekDay(self):
4421        self._rrulestr_reverse_test(rrule(SECONDLY,
4422                              count=3,
4423                              bymonth=(1, 3),
4424                              byweekday=(TU(1), TH(-1)),
4425                              dtstart=datetime(1997, 9, 2, 9, 0)))
4426
4427    def testToStrSecondlyByMonthDayAndWeekDay(self):
4428        self._rrulestr_reverse_test(rrule(SECONDLY,
4429                              count=3,
4430                              bymonthday=(1, 3),
4431                              byweekday=(TU, TH),
4432                              dtstart=datetime(1997, 9, 2, 9, 0)))
4433
4434    def testToStrSecondlyByMonthAndMonthDayAndWeekDay(self):
4435        self._rrulestr_reverse_test(rrule(SECONDLY,
4436                              count=3,
4437                              bymonth=(1, 3),
4438                              bymonthday=(1, 3),
4439                              byweekday=(TU, TH),
4440                              dtstart=datetime(1997, 9, 2, 9, 0)))
4441
4442    def testToStrSecondlyByYearDay(self):
4443        self._rrulestr_reverse_test(rrule(SECONDLY,
4444                              count=4,
4445                              byyearday=(1, 100, 200, 365),
4446                              dtstart=datetime(1997, 9, 2, 9, 0)))
4447
4448    def testToStrSecondlyByYearDayNeg(self):
4449        self._rrulestr_reverse_test(rrule(SECONDLY,
4450                              count=4,
4451                              byyearday=(-365, -266, -166, -1),
4452                              dtstart=datetime(1997, 9, 2, 9, 0)))
4453
4454    def testToStrSecondlyByMonthAndYearDay(self):
4455        self._rrulestr_reverse_test(rrule(SECONDLY,
4456                              count=4,
4457                              bymonth=(4, 7),
4458                              byyearday=(1, 100, 200, 365),
4459                              dtstart=datetime(1997, 9, 2, 9, 0)))
4460
4461    def testToStrSecondlyByMonthAndYearDayNeg(self):
4462        self._rrulestr_reverse_test(rrule(SECONDLY,
4463                              count=4,
4464                              bymonth=(4, 7),
4465                              byyearday=(-365, -266, -166, -1),
4466                              dtstart=datetime(1997, 9, 2, 9, 0)))
4467
4468    def testToStrSecondlyByWeekNo(self):
4469        self._rrulestr_reverse_test(rrule(SECONDLY,
4470                              count=3,
4471                              byweekno=20,
4472                              dtstart=datetime(1997, 9, 2, 9, 0)))
4473
4474    def testToStrSecondlyByWeekNoAndWeekDay(self):
4475        self._rrulestr_reverse_test(rrule(SECONDLY,
4476                              count=3,
4477                              byweekno=1,
4478                              byweekday=MO,
4479                              dtstart=datetime(1997, 9, 2, 9, 0)))
4480
4481    def testToStrSecondlyByWeekNoAndWeekDayLarge(self):
4482        self._rrulestr_reverse_test(rrule(SECONDLY,
4483                              count=3,
4484                              byweekno=52,
4485                              byweekday=SU,
4486                              dtstart=datetime(1997, 9, 2, 9, 0)))
4487
4488    def testToStrSecondlyByWeekNoAndWeekDayLast(self):
4489        self._rrulestr_reverse_test(rrule(SECONDLY,
4490                              count=3,
4491                              byweekno=-1,
4492                              byweekday=SU,
4493                              dtstart=datetime(1997, 9, 2, 9, 0)))
4494
4495    def testToStrSecondlyByWeekNoAndWeekDay53(self):
4496        self._rrulestr_reverse_test(rrule(SECONDLY,
4497                              count=3,
4498                              byweekno=53,
4499                              byweekday=MO,
4500                              dtstart=datetime(1997, 9, 2, 9, 0)))
4501
4502    def testToStrSecondlyByEaster(self):
4503        self._rrulestr_reverse_test(rrule(SECONDLY,
4504                              count=3,
4505                              byeaster=0,
4506                              dtstart=datetime(1997, 9, 2, 9, 0)))
4507
4508    def testToStrSecondlyByEasterPos(self):
4509        self._rrulestr_reverse_test(rrule(SECONDLY,
4510                              count=3,
4511                              byeaster=1,
4512                              dtstart=datetime(1997, 9, 2, 9, 0)))
4513
4514    def testToStrSecondlyByEasterNeg(self):
4515        self._rrulestr_reverse_test(rrule(SECONDLY,
4516                              count=3,
4517                              byeaster=-1,
4518                              dtstart=datetime(1997, 9, 2, 9, 0)))
4519
4520    def testToStrSecondlyByHour(self):
4521        self._rrulestr_reverse_test(rrule(SECONDLY,
4522                              count=3,
4523                              byhour=(6, 18),
4524                              dtstart=datetime(1997, 9, 2, 9, 0)))
4525
4526    def testToStrSecondlyByMinute(self):
4527        self._rrulestr_reverse_test(rrule(SECONDLY,
4528                              count=3,
4529                              byminute=(6, 18),
4530                              dtstart=datetime(1997, 9, 2, 9, 0)))
4531
4532    def testToStrSecondlyBySecond(self):
4533        self._rrulestr_reverse_test(rrule(SECONDLY,
4534                              count=3,
4535                              bysecond=(6, 18),
4536                              dtstart=datetime(1997, 9, 2, 9, 0)))
4537
4538    def testToStrSecondlyByHourAndMinute(self):
4539        self._rrulestr_reverse_test(rrule(SECONDLY,
4540                              count=3,
4541                              byhour=(6, 18),
4542                              byminute=(6, 18),
4543                              dtstart=datetime(1997, 9, 2, 9, 0)))
4544
4545    def testToStrSecondlyByHourAndSecond(self):
4546        self._rrulestr_reverse_test(rrule(SECONDLY,
4547                              count=3,
4548                              byhour=(6, 18),
4549                              bysecond=(6, 18),
4550                              dtstart=datetime(1997, 9, 2, 9, 0)))
4551
4552    def testToStrSecondlyByMinuteAndSecond(self):
4553        self._rrulestr_reverse_test(rrule(SECONDLY,
4554                              count=3,
4555                              byminute=(6, 18),
4556                              bysecond=(6, 18),
4557                              dtstart=datetime(1997, 9, 2, 9, 0)))
4558
4559    def testToStrSecondlyByHourAndMinuteAndSecond(self):
4560        self._rrulestr_reverse_test(rrule(SECONDLY,
4561                              count=3,
4562                              byhour=(6, 18),
4563                              byminute=(6, 18),
4564                              bysecond=(6, 18),
4565                              dtstart=datetime(1997, 9, 2, 9, 0)))
4566
4567    def testToStrSecondlyByHourAndMinuteAndSecondBug(self):
4568        # This explores a bug found by Mathieu Bridon.
4569        self._rrulestr_reverse_test(rrule(SECONDLY,
4570                              count=3,
4571                              bysecond=(0,),
4572                              byminute=(1,),
4573                              dtstart=datetime(2010, 3, 22, 12, 1)))
4574
4575    def testToStrWithWkSt(self):
4576        self._rrulestr_reverse_test(rrule(WEEKLY,
4577                              count=3,
4578                              wkst=SU,
4579                              dtstart=datetime(1997, 9, 2, 9, 0)))
4580
4581    def testToStrLongIntegers(self):
4582        if not PY3:  # There is no longs in python3
4583            self._rrulestr_reverse_test(rrule(MINUTELY,
4584                                  count=long(2),
4585                                  interval=long(2),
4586                                  bymonth=long(2),
4587                                  byweekday=long(3),
4588                                  byhour=long(6),
4589                                  byminute=long(6),
4590                                  bysecond=long(6),
4591                                  dtstart=datetime(1997, 9, 2, 9, 0)))
4592
4593            self._rrulestr_reverse_test(rrule(YEARLY,
4594                                  count=long(2),
4595                                  bymonthday=long(5),
4596                                  byweekno=long(2),
4597                                  dtstart=datetime(1997, 9, 2, 9, 0)))
4598
4599    def testReplaceIfSet(self):
4600        rr = rrule(YEARLY,
4601                   count=1,
4602                   bymonthday=5,
4603                   dtstart=datetime(1997, 1, 1))
4604        newrr = rr.replace(bymonthday=6)
4605        self.assertEqual(list(rr), [datetime(1997, 1, 5)])
4606        self.assertEqual(list(newrr),
4607                             [datetime(1997, 1, 6)])
4608
4609    def testReplaceIfNotSet(self):
4610        rr = rrule(YEARLY,
4611           count=1,
4612           dtstart=datetime(1997, 1, 1))
4613        newrr = rr.replace(bymonthday=6)
4614        self.assertEqual(list(rr), [datetime(1997, 1, 1)])
4615        self.assertEqual(list(newrr),
4616                             [datetime(1997, 1, 6)])
4617
4618
4619@pytest.mark.rrule
4620@freeze_time(datetime(2018, 3, 6, 5, 36, tzinfo=tz.UTC))
4621def test_generated_aware_dtstart():
4622    dtstart_exp = datetime(2018, 3, 6, 5, 36, tzinfo=tz.UTC)
4623    UNTIL = datetime(2018, 3, 6, 8, 0, tzinfo=tz.UTC)
4624
4625    rule_without_dtstart = rrule(freq=HOURLY, until=UNTIL)
4626    rule_with_dtstart = rrule(freq=HOURLY, dtstart=dtstart_exp, until=UNTIL)
4627    assert list(rule_without_dtstart) == list(rule_with_dtstart)
4628
4629
4630@pytest.mark.rrule
4631@pytest.mark.rrulestr
4632@pytest.mark.xfail(reason="rrulestr loses time zone, gh issue #637")
4633@freeze_time(datetime(2018, 3, 6, 5, 36, tzinfo=tz.UTC))
4634def test_generated_aware_dtstart_rrulestr():
4635    rrule_without_dtstart = rrule(freq=HOURLY,
4636                                  until=datetime(2018, 3, 6, 8, 0,
4637                                                 tzinfo=tz.UTC))
4638    rrule_r = rrulestr(str(rrule_without_dtstart))
4639
4640    assert list(rrule_r) == list(rrule_without_dtstart)
4641
4642
4643@pytest.mark.rruleset
4644class RRuleSetTest(unittest.TestCase):
4645    def testSet(self):
4646        rrset = rruleset()
4647        rrset.rrule(rrule(YEARLY, count=2, byweekday=TU,
4648                          dtstart=datetime(1997, 9, 2, 9, 0)))
4649        rrset.rrule(rrule(YEARLY, count=1, byweekday=TH,
4650                          dtstart=datetime(1997, 9, 2, 9, 0)))
4651        self.assertEqual(list(rrset),
4652                         [datetime(1997, 9, 2, 9, 0),
4653                          datetime(1997, 9, 4, 9, 0),
4654                          datetime(1997, 9, 9, 9, 0)])
4655
4656    def testSetDate(self):
4657        rrset = rruleset()
4658        rrset.rrule(rrule(YEARLY, count=1, byweekday=TU,
4659                          dtstart=datetime(1997, 9, 2, 9, 0)))
4660        rrset.rdate(datetime(1997, 9, 4, 9))
4661        rrset.rdate(datetime(1997, 9, 9, 9))
4662        self.assertEqual(list(rrset),
4663                         [datetime(1997, 9, 2, 9, 0),
4664                          datetime(1997, 9, 4, 9, 0),
4665                          datetime(1997, 9, 9, 9, 0)])
4666
4667    def testSetExRule(self):
4668        rrset = rruleset()
4669        rrset.rrule(rrule(YEARLY, count=6, byweekday=(TU, TH),
4670                          dtstart=datetime(1997, 9, 2, 9, 0)))
4671        rrset.exrule(rrule(YEARLY, count=3, byweekday=TH,
4672                          dtstart=datetime(1997, 9, 2, 9, 0)))
4673        self.assertEqual(list(rrset),
4674                         [datetime(1997, 9, 2, 9, 0),
4675                          datetime(1997, 9, 9, 9, 0),
4676                          datetime(1997, 9, 16, 9, 0)])
4677
4678    def testSetExDate(self):
4679        rrset = rruleset()
4680        rrset.rrule(rrule(YEARLY, count=6, byweekday=(TU, TH),
4681                          dtstart=datetime(1997, 9, 2, 9, 0)))
4682        rrset.exdate(datetime(1997, 9, 4, 9))
4683        rrset.exdate(datetime(1997, 9, 11, 9))
4684        rrset.exdate(datetime(1997, 9, 18, 9))
4685        self.assertEqual(list(rrset),
4686                         [datetime(1997, 9, 2, 9, 0),
4687                          datetime(1997, 9, 9, 9, 0),
4688                          datetime(1997, 9, 16, 9, 0)])
4689
4690    def testSetExDateRevOrder(self):
4691        rrset = rruleset()
4692        rrset.rrule(rrule(MONTHLY, count=5, bymonthday=10,
4693                          dtstart=datetime(2004, 1, 1, 9, 0)))
4694        rrset.exdate(datetime(2004, 4, 10, 9, 0))
4695        rrset.exdate(datetime(2004, 2, 10, 9, 0))
4696        self.assertEqual(list(rrset),
4697                         [datetime(2004, 1, 10, 9, 0),
4698                          datetime(2004, 3, 10, 9, 0),
4699                          datetime(2004, 5, 10, 9, 0)])
4700
4701    def testSetDateAndExDate(self):
4702        rrset = rruleset()
4703        rrset.rdate(datetime(1997, 9, 2, 9))
4704        rrset.rdate(datetime(1997, 9, 4, 9))
4705        rrset.rdate(datetime(1997, 9, 9, 9))
4706        rrset.rdate(datetime(1997, 9, 11, 9))
4707        rrset.rdate(datetime(1997, 9, 16, 9))
4708        rrset.rdate(datetime(1997, 9, 18, 9))
4709        rrset.exdate(datetime(1997, 9, 4, 9))
4710        rrset.exdate(datetime(1997, 9, 11, 9))
4711        rrset.exdate(datetime(1997, 9, 18, 9))
4712        self.assertEqual(list(rrset),
4713                         [datetime(1997, 9, 2, 9, 0),
4714                          datetime(1997, 9, 9, 9, 0),
4715                          datetime(1997, 9, 16, 9, 0)])
4716
4717    def testSetDateAndExRule(self):
4718        rrset = rruleset()
4719        rrset.rdate(datetime(1997, 9, 2, 9))
4720        rrset.rdate(datetime(1997, 9, 4, 9))
4721        rrset.rdate(datetime(1997, 9, 9, 9))
4722        rrset.rdate(datetime(1997, 9, 11, 9))
4723        rrset.rdate(datetime(1997, 9, 16, 9))
4724        rrset.rdate(datetime(1997, 9, 18, 9))
4725        rrset.exrule(rrule(YEARLY, count=3, byweekday=TH,
4726                           dtstart=datetime(1997, 9, 2, 9, 0)))
4727        self.assertEqual(list(rrset),
4728                         [datetime(1997, 9, 2, 9, 0),
4729                          datetime(1997, 9, 9, 9, 0),
4730                          datetime(1997, 9, 16, 9, 0)])
4731
4732    def testSetCount(self):
4733        rrset = rruleset()
4734        rrset.rrule(rrule(YEARLY, count=6, byweekday=(TU, TH),
4735                          dtstart=datetime(1997, 9, 2, 9, 0)))
4736        rrset.exrule(rrule(YEARLY, count=3, byweekday=TH,
4737                           dtstart=datetime(1997, 9, 2, 9, 0)))
4738        self.assertEqual(rrset.count(), 3)
4739
4740    def testSetCachePre(self):
4741        rrset = rruleset()
4742        rrset.rrule(rrule(YEARLY, count=2, byweekday=TU,
4743                          dtstart=datetime(1997, 9, 2, 9, 0)))
4744        rrset.rrule(rrule(YEARLY, count=1, byweekday=TH,
4745                          dtstart=datetime(1997, 9, 2, 9, 0)))
4746        self.assertEqual(list(rrset),
4747                         [datetime(1997, 9, 2, 9, 0),
4748                          datetime(1997, 9, 4, 9, 0),
4749                          datetime(1997, 9, 9, 9, 0)])
4750
4751    def testSetCachePost(self):
4752        rrset = rruleset(cache=True)
4753        rrset.rrule(rrule(YEARLY, count=2, byweekday=TU,
4754                          dtstart=datetime(1997, 9, 2, 9, 0)))
4755        rrset.rrule(rrule(YEARLY, count=1, byweekday=TH,
4756                          dtstart=datetime(1997, 9, 2, 9, 0)))
4757        for x in rrset: pass
4758        self.assertEqual(list(rrset),
4759                         [datetime(1997, 9, 2, 9, 0),
4760                          datetime(1997, 9, 4, 9, 0),
4761                          datetime(1997, 9, 9, 9, 0)])
4762
4763    def testSetCachePostInternal(self):
4764        rrset = rruleset(cache=True)
4765        rrset.rrule(rrule(YEARLY, count=2, byweekday=TU,
4766                          dtstart=datetime(1997, 9, 2, 9, 0)))
4767        rrset.rrule(rrule(YEARLY, count=1, byweekday=TH,
4768                          dtstart=datetime(1997, 9, 2, 9, 0)))
4769        for x in rrset: pass
4770        self.assertEqual(list(rrset._cache),
4771                         [datetime(1997, 9, 2, 9, 0),
4772                          datetime(1997, 9, 4, 9, 0),
4773                          datetime(1997, 9, 9, 9, 0)])
4774
4775    def testSetRRuleCount(self):
4776        # Test that the count is updated when an rrule is added
4777        rrset = rruleset(cache=False)
4778        for cache in (True, False):
4779            rrset = rruleset(cache=cache)
4780            rrset.rrule(rrule(YEARLY, count=2, byweekday=TH,
4781                              dtstart=datetime(1983, 4, 1)))
4782            rrset.rrule(rrule(WEEKLY, count=4, byweekday=FR,
4783                              dtstart=datetime(1991, 6, 3)))
4784
4785            # Check the length twice - first one sets a cache, second reads it
4786            self.assertEqual(rrset.count(), 6)
4787            self.assertEqual(rrset.count(), 6)
4788
4789            # This should invalidate the cache and force an update
4790            rrset.rrule(rrule(MONTHLY, count=3, dtstart=datetime(1994, 1, 3)))
4791
4792            self.assertEqual(rrset.count(), 9)
4793            self.assertEqual(rrset.count(), 9)
4794
4795    def testSetRDateCount(self):
4796        # Test that the count is updated when an rdate is added
4797        rrset = rruleset(cache=False)
4798        for cache in (True, False):
4799            rrset = rruleset(cache=cache)
4800            rrset.rrule(rrule(YEARLY, count=2, byweekday=TH,
4801                              dtstart=datetime(1983, 4, 1)))
4802            rrset.rrule(rrule(WEEKLY, count=4, byweekday=FR,
4803                              dtstart=datetime(1991, 6, 3)))
4804
4805            # Check the length twice - first one sets a cache, second reads it
4806            self.assertEqual(rrset.count(), 6)
4807            self.assertEqual(rrset.count(), 6)
4808
4809            # This should invalidate the cache and force an update
4810            rrset.rdate(datetime(1993, 2, 14))
4811
4812            self.assertEqual(rrset.count(), 7)
4813            self.assertEqual(rrset.count(), 7)
4814
4815    def testSetExRuleCount(self):
4816        # Test that the count is updated when an exrule is added
4817        rrset = rruleset(cache=False)
4818        for cache in (True, False):
4819            rrset = rruleset(cache=cache)
4820            rrset.rrule(rrule(YEARLY, count=2, byweekday=TH,
4821                              dtstart=datetime(1983, 4, 1)))
4822            rrset.rrule(rrule(WEEKLY, count=4, byweekday=FR,
4823                              dtstart=datetime(1991, 6, 3)))
4824
4825            # Check the length twice - first one sets a cache, second reads it
4826            self.assertEqual(rrset.count(), 6)
4827            self.assertEqual(rrset.count(), 6)
4828
4829            # This should invalidate the cache and force an update
4830            rrset.exrule(rrule(WEEKLY, count=2, interval=2,
4831                               dtstart=datetime(1991, 6, 14)))
4832
4833            self.assertEqual(rrset.count(), 4)
4834            self.assertEqual(rrset.count(), 4)
4835
4836    def testSetExDateCount(self):
4837        # Test that the count is updated when an rdate is added
4838        for cache in (True, False):
4839            rrset = rruleset(cache=cache)
4840            rrset.rrule(rrule(YEARLY, count=2, byweekday=TH,
4841                              dtstart=datetime(1983, 4, 1)))
4842            rrset.rrule(rrule(WEEKLY, count=4, byweekday=FR,
4843                              dtstart=datetime(1991, 6, 3)))
4844
4845            # Check the length twice - first one sets a cache, second reads it
4846            self.assertEqual(rrset.count(), 6)
4847            self.assertEqual(rrset.count(), 6)
4848
4849            # This should invalidate the cache and force an update
4850            rrset.exdate(datetime(1991, 6, 28))
4851
4852            self.assertEqual(rrset.count(), 5)
4853            self.assertEqual(rrset.count(), 5)
4854
4855
4856class WeekdayTest(unittest.TestCase):
4857    def testInvalidNthWeekday(self):
4858        with self.assertRaises(ValueError):
4859            FR(0)
4860
4861    def testWeekdayCallable(self):
4862        # Calling a weekday instance generates a new weekday instance with the
4863        # value of n changed.
4864        from dateutil.rrule import weekday
4865        self.assertEqual(MO(1), weekday(0, 1))
4866
4867        # Calling a weekday instance with the identical n returns the original
4868        # object
4869        FR_3 = weekday(4, 3)
4870        self.assertIs(FR_3(3), FR_3)
4871
4872    def testWeekdayEquality(self):
4873        # Two weekday objects are not equal if they have different values for n
4874        self.assertNotEqual(TH, TH(-1))
4875        self.assertNotEqual(SA(3), SA(2))
4876
4877    def testWeekdayEqualitySubclass(self):
4878        # Two weekday objects equal if their "weekday" and "n" attributes are
4879        # available and the same
4880        class BasicWeekday(object):
4881            def __init__(self, weekday):
4882                self.weekday = weekday
4883
4884        class BasicNWeekday(BasicWeekday):
4885            def __init__(self, weekday, n=None):
4886                super(BasicNWeekday, self).__init__(weekday)
4887                self.n = n
4888
4889        MO_Basic = BasicWeekday(0)
4890
4891        self.assertNotEqual(MO, MO_Basic)
4892        self.assertNotEqual(MO(1), MO_Basic)
4893
4894        TU_BasicN = BasicNWeekday(1)
4895
4896        self.assertEqual(TU, TU_BasicN)
4897        self.assertNotEqual(TU(3), TU_BasicN)
4898
4899        WE_Basic3 = BasicNWeekday(2, 3)
4900        self.assertEqual(WE(3), WE_Basic3)
4901        self.assertNotEqual(WE(2), WE_Basic3)
4902
4903    def testWeekdayReprNoN(self):
4904        no_n_reprs = ('MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU')
4905        no_n_wdays = (MO, TU, WE, TH, FR, SA, SU)
4906
4907        for repstr, wday in zip(no_n_reprs, no_n_wdays):
4908            self.assertEqual(repr(wday), repstr)
4909
4910    def testWeekdayReprWithN(self):
4911        with_n_reprs = ('WE(+1)', 'TH(-2)', 'SU(+3)')
4912        with_n_wdays = (WE(1), TH(-2), SU(+3))
4913
4914        for repstr, wday in zip(with_n_reprs, with_n_wdays):
4915            self.assertEqual(repr(wday), repstr)
4916