17
17
18
18
package org .dmfs .rfc5545 .recurrenceset ;
19
19
20
+ import org .dmfs .iterators .AbstractBaseIterator ;
20
21
import org .dmfs .rfc5545 .DateTime ;
21
22
import org .dmfs .rfc5545 .Duration ;
22
23
import org .dmfs .rfc5545 .recur .InvalidRecurrenceRuleException ;
23
24
import org .dmfs .rfc5545 .recur .RecurrenceRule ;
24
25
import org .junit .Test ;
25
26
27
+ import java .util .NoSuchElementException ;
26
28
import java .util .TimeZone ;
27
29
import java .util .concurrent .TimeUnit ;
28
30
29
31
import static java .util .Arrays .asList ;
30
32
import static org .dmfs .jems .hamcrest .matchers .GeneratableMatcher .startsWith ;
33
+ import static org .dmfs .jems .hamcrest .matchers .iterator .IteratorMatcher .iteratorOf ;
31
34
import static org .hamcrest .Matchers .is ;
32
35
import static org .junit .Assert .assertThat ;
33
36
@@ -48,8 +51,8 @@ public void testExceptionsAllDay()
48
51
TimeZone testZone = TimeZone .getTimeZone ("UTC" );
49
52
DateTime start = DateTime .parse ("20180101" );
50
53
RecurrenceSetIterator recurrenceSetIterator = new RecurrenceSetIterator (
51
- asList (new RecurrenceList ("20180101,20180102,20180103,20180104" , testZone ).getIterator (testZone , start .getTimestamp ())),
52
- asList (new RecurrenceList ("20180102,20180103" , testZone ).getIterator (testZone , start .getTimestamp ())));
54
+ asList (new RecurrenceList ("20180101,20180102,20180103,20180104" , testZone ).getIterator (testZone , start .getTimestamp ())),
55
+ asList (new RecurrenceList ("20180102,20180103" , testZone ).getIterator (testZone , start .getTimestamp ())));
53
56
54
57
// note we call hasNext twice to ensure it's idempotent
55
58
assertThat (recurrenceSetIterator .hasNext (), is (true ));
@@ -72,9 +75,9 @@ public void testMultipleExceptionsAllDay()
72
75
TimeZone testZone = TimeZone .getTimeZone ("UTC" );
73
76
DateTime start = DateTime .parse ("20180101" );
74
77
RecurrenceSetIterator recurrenceSetIterator = new RecurrenceSetIterator (
75
- asList (new RecurrenceList ("20180101,20180102,20180103,20180104" , testZone ).getIterator (testZone , start .getTimestamp ())),
76
- asList (new RecurrenceList ("20180103" , testZone ).getIterator (testZone , start .getTimestamp ()),
77
- new RecurrenceList ("20180102" , testZone ).getIterator (testZone , start .getTimestamp ())));
78
+ asList (new RecurrenceList ("20180101,20180102,20180103,20180104" , testZone ).getIterator (testZone , start .getTimestamp ())),
79
+ asList (new RecurrenceList ("20180103" , testZone ).getIterator (testZone , start .getTimestamp ()),
80
+ new RecurrenceList ("20180102" , testZone ).getIterator (testZone , start .getTimestamp ())));
78
81
79
82
// note we call hasNext twice to ensure it's idempotent
80
83
assertThat (recurrenceSetIterator .hasNext (), is (true ));
@@ -97,9 +100,9 @@ public void testExceptions()
97
100
TimeZone testZone = TimeZone .getTimeZone ("UTC" );
98
101
DateTime start = DateTime .parse ("20180101T120000" );
99
102
RecurrenceSetIterator recurrenceSetIterator = new RecurrenceSetIterator (
100
- asList (new RecurrenceList ("20180101T120000,20180102T120000,20180103T120000,20180104T120000" , testZone ).getIterator (testZone ,
101
- start .getTimestamp ())),
102
- asList (new RecurrenceList ("20180102T120000,20180103T120000" , testZone ).getIterator (testZone , start .getTimestamp ())));
103
+ asList (new RecurrenceList ("20180101T120000,20180102T120000,20180103T120000,20180104T120000" , testZone ).getIterator (testZone ,
104
+ start .getTimestamp ())),
105
+ asList (new RecurrenceList ("20180102T120000,20180103T120000" , testZone ).getIterator (testZone , start .getTimestamp ())));
103
106
104
107
// note we call hasNext twice to ensure it's idempotent
105
108
assertThat (recurrenceSetIterator .hasNext (), is (true ));
@@ -122,10 +125,10 @@ public void testMultipleExceptions()
122
125
TimeZone testZone = TimeZone .getTimeZone ("UTC" );
123
126
DateTime start = DateTime .parse ("20180101T120000" );
124
127
RecurrenceSetIterator recurrenceSetIterator = new RecurrenceSetIterator (
125
- asList (new RecurrenceList ("20180101T120000,20180102T120000,20180103T120000,20180104T120000" , testZone ).getIterator (testZone ,
126
- start .getTimestamp ())),
127
- asList (new RecurrenceList ("20180103T120000" , testZone ).getIterator (testZone , start .getTimestamp ()),
128
- new RecurrenceList ("20180102T120000" , testZone ).getIterator (testZone , start .getTimestamp ())));
128
+ asList (new RecurrenceList ("20180101T120000,20180102T120000,20180103T120000,20180104T120000" , testZone ).getIterator (testZone ,
129
+ start .getTimestamp ())),
130
+ asList (new RecurrenceList ("20180103T120000" , testZone ).getIterator (testZone , start .getTimestamp ()),
131
+ new RecurrenceList ("20180102T120000" , testZone ).getIterator (testZone , start .getTimestamp ())));
129
132
130
133
// note we call hasNext twice to ensure it's idempotent
131
134
assertThat (recurrenceSetIterator .hasNext (), is (true ));
@@ -156,19 +159,19 @@ public void testMultipleRules() throws InvalidRecurrenceRuleException
156
159
RecurrenceSetIterator it = ruleSet .iterator (start .getTimeZone (), start .getTimestamp ());
157
160
158
161
assertThat (() -> it ::next , startsWith (
159
- new DateTime (DateTime .UTC , 2019 , 1 , 1 , 0 , 0 , 0 ).getTimestamp (),
160
- new DateTime (DateTime .UTC , 2019 , 1 , 1 , 5 , 0 , 0 ).getTimestamp (),
161
- new DateTime (DateTime .UTC , 2019 , 1 , 1 , 10 , 0 , 0 ).getTimestamp (),
162
- new DateTime (DateTime .UTC , 2019 , 1 , 1 , 15 , 0 , 0 ).getTimestamp (),
163
- new DateTime (DateTime .UTC , 2019 , 1 , 1 , 20 , 0 , 0 ).getTimestamp (),
164
- new DateTime (DateTime .UTC , 2019 , 1 , 2 , 0 , 0 , 0 ).getTimestamp (),
165
- new DateTime (DateTime .UTC , 2019 , 1 , 2 , 1 , 0 , 0 ).getTimestamp (),
166
- new DateTime (DateTime .UTC , 2019 , 1 , 2 , 6 , 0 , 0 ).getTimestamp (),
167
- new DateTime (DateTime .UTC , 2019 , 1 , 2 , 11 , 0 , 0 ).getTimestamp (),
168
- new DateTime (DateTime .UTC , 2019 , 1 , 2 , 16 , 0 , 0 ).getTimestamp (),
169
- new DateTime (DateTime .UTC , 2019 , 1 , 2 , 21 , 0 , 0 ).getTimestamp (),
170
- new DateTime (DateTime .UTC , 2019 , 1 , 3 , 0 , 0 , 0 ).getTimestamp (),
171
- new DateTime (DateTime .UTC , 2019 , 1 , 3 , 2 , 0 , 0 ).getTimestamp ()
162
+ new DateTime (DateTime .UTC , 2019 , 1 , 1 , 0 , 0 , 0 ).getTimestamp (),
163
+ new DateTime (DateTime .UTC , 2019 , 1 , 1 , 5 , 0 , 0 ).getTimestamp (),
164
+ new DateTime (DateTime .UTC , 2019 , 1 , 1 , 10 , 0 , 0 ).getTimestamp (),
165
+ new DateTime (DateTime .UTC , 2019 , 1 , 1 , 15 , 0 , 0 ).getTimestamp (),
166
+ new DateTime (DateTime .UTC , 2019 , 1 , 1 , 20 , 0 , 0 ).getTimestamp (),
167
+ new DateTime (DateTime .UTC , 2019 , 1 , 2 , 0 , 0 , 0 ).getTimestamp (),
168
+ new DateTime (DateTime .UTC , 2019 , 1 , 2 , 1 , 0 , 0 ).getTimestamp (),
169
+ new DateTime (DateTime .UTC , 2019 , 1 , 2 , 6 , 0 , 0 ).getTimestamp (),
170
+ new DateTime (DateTime .UTC , 2019 , 1 , 2 , 11 , 0 , 0 ).getTimestamp (),
171
+ new DateTime (DateTime .UTC , 2019 , 1 , 2 , 16 , 0 , 0 ).getTimestamp (),
172
+ new DateTime (DateTime .UTC , 2019 , 1 , 2 , 21 , 0 , 0 ).getTimestamp (),
173
+ new DateTime (DateTime .UTC , 2019 , 1 , 3 , 0 , 0 , 0 ).getTimestamp (),
174
+ new DateTime (DateTime .UTC , 2019 , 1 , 3 , 2 , 0 , 0 ).getTimestamp ()
172
175
));
173
176
}
174
177
@@ -191,24 +194,45 @@ public void testMultipleRulesWithSameValues() throws InvalidRecurrenceRuleExcept
191
194
RecurrenceSetIterator it = ruleSet .iterator (start .getTimeZone (), start .getTimestamp ());
192
195
193
196
assertThat (() -> it ::next , startsWith (
194
- new DateTime (2019 , 1 , 2 ).getTimestamp (), // SA
195
- new DateTime (2019 , 1 , 5 ).getTimestamp (), // TU
196
- new DateTime (2019 , 1 , 6 ).getTimestamp (), // WE
197
- new DateTime (2019 , 1 , 9 ).getTimestamp (), // SA
198
- new DateTime (2019 , 1 , 12 ).getTimestamp (), // TU
199
- new DateTime (2019 , 1 , 13 ).getTimestamp (), // WE
200
- new DateTime (2019 , 1 , 16 ).getTimestamp (), // SA
201
- new DateTime (2019 , 1 , 19 ).getTimestamp (), // TU
202
- new DateTime (2019 , 1 , 20 ).getTimestamp (), // WE
203
- new DateTime (2019 , 1 , 23 ).getTimestamp (), // SA
204
- new DateTime (2019 , 1 , 26 ).getTimestamp (), // TU
205
- new DateTime (2019 , 1 , 27 ).getTimestamp (), // WE
206
- new DateTime (2019 , 2 , 2 ).getTimestamp (), // SA
207
- new DateTime (2019 , 2 , 5 ).getTimestamp () // TU
197
+ new DateTime (2019 , 1 , 2 ).getTimestamp (), // SA
198
+ new DateTime (2019 , 1 , 5 ).getTimestamp (), // TU
199
+ new DateTime (2019 , 1 , 6 ).getTimestamp (), // WE
200
+ new DateTime (2019 , 1 , 9 ).getTimestamp (), // SA
201
+ new DateTime (2019 , 1 , 12 ).getTimestamp (), // TU
202
+ new DateTime (2019 , 1 , 13 ).getTimestamp (), // WE
203
+ new DateTime (2019 , 1 , 16 ).getTimestamp (), // SA
204
+ new DateTime (2019 , 1 , 19 ).getTimestamp (), // TU
205
+ new DateTime (2019 , 1 , 20 ).getTimestamp (), // WE
206
+ new DateTime (2019 , 1 , 23 ).getTimestamp (), // SA
207
+ new DateTime (2019 , 1 , 26 ).getTimestamp (), // TU
208
+ new DateTime (2019 , 1 , 27 ).getTimestamp (), // WE
209
+ new DateTime (2019 , 2 , 2 ).getTimestamp (), // SA
210
+ new DateTime (2019 , 2 , 5 ).getTimestamp () // TU
208
211
));
209
212
}
210
213
211
214
215
+ /**
216
+ * See https://github.com/dmfs/lib-recur/issues/93
217
+ */
218
+ @ Test
219
+ public void testGithubIssue93 () throws InvalidRecurrenceRuleException
220
+ {
221
+ DateTime start = DateTime .parse ("20200414T160000Z" );
222
+
223
+ // Combine all Recurrence Rules into a RecurrenceSet
224
+ RecurrenceSet ruleSet = new RecurrenceSet ();
225
+ ruleSet .addInstances (new RecurrenceRuleAdapter (new RecurrenceRule ("FREQ=WEEKLY;UNTIL=20200511T000000Z;BYDAY=TU" )));
226
+ ruleSet .addExceptions (new RecurrenceList ("20200421T160000Z,20200505T160000Z" , DateTime .UTC ));
227
+
228
+ // Create an iterator using the RecurrenceSet
229
+ assertThat (() -> new RecurrenceAdapter (ruleSet .iterator (start .getTimeZone (), start .getTimestamp ())),
230
+ iteratorOf (
231
+ DateTime .parse ("20200414T160000Z" ).getTimestamp (),
232
+ DateTime .parse ("20200428T160000Z" ).getTimestamp ()));
233
+ }
234
+
235
+
212
236
@ Test
213
237
public void testMultipleRulesWithSameValuesAndCount () throws InvalidRecurrenceRuleException
214
238
{
@@ -227,22 +251,22 @@ public void testMultipleRulesWithSameValuesAndCount() throws InvalidRecurrenceRu
227
251
RecurrenceSetIterator it = ruleSet .iterator (start .getTimeZone (), start .getTimestamp ());
228
252
229
253
assertThat (() -> it ::next , startsWith (
230
- new DateTime (2019 , 1 , 2 ).getTimestamp (), // SA
231
- new DateTime (2019 , 1 , 5 ).getTimestamp (), // TU
232
- new DateTime (2019 , 1 , 6 ).getTimestamp (), // WE
233
- new DateTime (2019 , 1 , 9 ).getTimestamp (), // SA
234
- new DateTime (2019 , 1 , 12 ).getTimestamp (), // TU
235
- new DateTime (2019 , 1 , 13 ).getTimestamp (), // WE
236
- //new DateTime(2019, 1, 16).getTimestamp(), // SA
237
- new DateTime (2019 , 1 , 19 ).getTimestamp (), // TU
238
- new DateTime (2019 , 1 , 20 ).getTimestamp (), // WE
239
- //new DateTime(2019, 1, 23).getTimestamp(), // SA
240
- new DateTime (2019 , 1 , 25 ).getTimestamp (), // MO
241
- new DateTime (2019 , 1 , 26 ).getTimestamp (), // TU
242
- new DateTime (2019 , 1 , 27 ).getTimestamp (), // WE
243
- //new DateTime(2019, 2, 2).getTimestamp(), // SA
244
- new DateTime (2019 , 2 , 4 ).getTimestamp (), // MO
245
- new DateTime (2019 , 2 , 5 ).getTimestamp () // TU
254
+ new DateTime (2019 , 1 , 2 ).getTimestamp (), // SA
255
+ new DateTime (2019 , 1 , 5 ).getTimestamp (), // TU
256
+ new DateTime (2019 , 1 , 6 ).getTimestamp (), // WE
257
+ new DateTime (2019 , 1 , 9 ).getTimestamp (), // SA
258
+ new DateTime (2019 , 1 , 12 ).getTimestamp (), // TU
259
+ new DateTime (2019 , 1 , 13 ).getTimestamp (), // WE
260
+ //new DateTime(2019, 1, 16).getTimestamp(), // SA
261
+ new DateTime (2019 , 1 , 19 ).getTimestamp (), // TU
262
+ new DateTime (2019 , 1 , 20 ).getTimestamp (), // WE
263
+ //new DateTime(2019, 1, 23).getTimestamp(), // SA
264
+ new DateTime (2019 , 1 , 25 ).getTimestamp (), // MO
265
+ new DateTime (2019 , 1 , 26 ).getTimestamp (), // TU
266
+ new DateTime (2019 , 1 , 27 ).getTimestamp (), // WE
267
+ //new DateTime(2019, 2, 2).getTimestamp(), // SA
268
+ new DateTime (2019 , 2 , 4 ).getTimestamp (), // MO
269
+ new DateTime (2019 , 2 , 5 ).getTimestamp () // TU
246
270
));
247
271
}
248
272
@@ -267,14 +291,14 @@ public void testMultipleRulesWithFastForward() throws InvalidRecurrenceRuleExcep
267
291
it .fastForward (new DateTime (DateTime .UTC , 2019 , 1 , 1 , 22 , 0 , 0 ).getTimestamp ());
268
292
269
293
assertThat (() -> it ::next , startsWith (
270
- new DateTime (DateTime .UTC , 2019 , 1 , 2 , 0 , 0 , 0 ).getTimestamp (),
271
- new DateTime (DateTime .UTC , 2019 , 1 , 2 , 1 , 0 , 0 ).getTimestamp (),
272
- new DateTime (DateTime .UTC , 2019 , 1 , 2 , 6 , 0 , 0 ).getTimestamp (),
273
- new DateTime (DateTime .UTC , 2019 , 1 , 2 , 11 , 0 , 0 ).getTimestamp (),
274
- new DateTime (DateTime .UTC , 2019 , 1 , 2 , 16 , 0 , 0 ).getTimestamp (),
275
- new DateTime (DateTime .UTC , 2019 , 1 , 2 , 21 , 0 , 0 ).getTimestamp (),
276
- new DateTime (DateTime .UTC , 2019 , 1 , 3 , 0 , 0 , 0 ).getTimestamp (),
277
- new DateTime (DateTime .UTC , 2019 , 1 , 3 , 2 , 0 , 0 ).getTimestamp ()
294
+ new DateTime (DateTime .UTC , 2019 , 1 , 2 , 0 , 0 , 0 ).getTimestamp (),
295
+ new DateTime (DateTime .UTC , 2019 , 1 , 2 , 1 , 0 , 0 ).getTimestamp (),
296
+ new DateTime (DateTime .UTC , 2019 , 1 , 2 , 6 , 0 , 0 ).getTimestamp (),
297
+ new DateTime (DateTime .UTC , 2019 , 1 , 2 , 11 , 0 , 0 ).getTimestamp (),
298
+ new DateTime (DateTime .UTC , 2019 , 1 , 2 , 16 , 0 , 0 ).getTimestamp (),
299
+ new DateTime (DateTime .UTC , 2019 , 1 , 2 , 21 , 0 , 0 ).getTimestamp (),
300
+ new DateTime (DateTime .UTC , 2019 , 1 , 3 , 0 , 0 , 0 ).getTimestamp (),
301
+ new DateTime (DateTime .UTC , 2019 , 1 , 3 , 2 , 0 , 0 ).getTimestamp ()
278
302
));
279
303
}
280
304
@@ -299,11 +323,11 @@ public void testFastForwardToStart() throws InvalidRecurrenceRuleException
299
323
it .fastForward (start .getTimestamp ());
300
324
301
325
assertThat (() -> it ::next , startsWith (
302
- new DateTime (DateTime .UTC , 2019 , 1 , 1 , 0 , 0 , 0 ).getTimestamp (),
303
- new DateTime (DateTime .UTC , 2019 , 1 , 2 , 0 , 0 , 0 ).getTimestamp (),
304
- new DateTime (DateTime .UTC , 2019 , 1 , 3 , 0 , 0 , 0 ).getTimestamp (),
305
- new DateTime (DateTime .UTC , 2019 , 1 , 4 , 0 , 0 , 0 ).getTimestamp (),
306
- new DateTime (DateTime .UTC , 2019 , 1 , 5 , 0 , 0 , 0 ).getTimestamp ()
326
+ new DateTime (DateTime .UTC , 2019 , 1 , 1 , 0 , 0 , 0 ).getTimestamp (),
327
+ new DateTime (DateTime .UTC , 2019 , 1 , 2 , 0 , 0 , 0 ).getTimestamp (),
328
+ new DateTime (DateTime .UTC , 2019 , 1 , 3 , 0 , 0 , 0 ).getTimestamp (),
329
+ new DateTime (DateTime .UTC , 2019 , 1 , 4 , 0 , 0 , 0 ).getTimestamp (),
330
+ new DateTime (DateTime .UTC , 2019 , 1 , 5 , 0 , 0 , 0 ).getTimestamp ()
307
331
));
308
332
}
309
333
@@ -323,11 +347,11 @@ public void testFastForwardToPast() throws InvalidRecurrenceRuleException
323
347
it .fastForward (start .getTimestamp () - TimeUnit .DAYS .toMillis (100 ));
324
348
325
349
assertThat (() -> it ::next , startsWith (
326
- new DateTime (DateTime .UTC , 2019 , 1 , 1 , 0 , 0 , 0 ).getTimestamp (),
327
- new DateTime (DateTime .UTC , 2019 , 1 , 2 , 0 , 0 , 0 ).getTimestamp (),
328
- new DateTime (DateTime .UTC , 2019 , 1 , 3 , 0 , 0 , 0 ).getTimestamp (),
329
- new DateTime (DateTime .UTC , 2019 , 1 , 4 , 0 , 0 , 0 ).getTimestamp (),
330
- new DateTime (DateTime .UTC , 2019 , 1 , 5 , 0 , 0 , 0 ).getTimestamp ()
350
+ new DateTime (DateTime .UTC , 2019 , 1 , 1 , 0 , 0 , 0 ).getTimestamp (),
351
+ new DateTime (DateTime .UTC , 2019 , 1 , 2 , 0 , 0 , 0 ).getTimestamp (),
352
+ new DateTime (DateTime .UTC , 2019 , 1 , 3 , 0 , 0 , 0 ).getTimestamp (),
353
+ new DateTime (DateTime .UTC , 2019 , 1 , 4 , 0 , 0 , 0 ).getTimestamp (),
354
+ new DateTime (DateTime .UTC , 2019 , 1 , 5 , 0 , 0 , 0 ).getTimestamp ()
331
355
));
332
356
}
333
357
@@ -347,12 +371,42 @@ public void testFastForwardToNext() throws InvalidRecurrenceRuleException
347
371
it .fastForward (start .getTimestamp () + 1 );
348
372
349
373
assertThat (() -> it ::next , startsWith (
350
- new DateTime (DateTime .UTC , 2019 , 1 , 2 , 0 , 0 , 0 ).getTimestamp (),
351
- new DateTime (DateTime .UTC , 2019 , 1 , 3 , 0 , 0 , 0 ).getTimestamp (),
352
- new DateTime (DateTime .UTC , 2019 , 1 , 4 , 0 , 0 , 0 ).getTimestamp (),
353
- new DateTime (DateTime .UTC , 2019 , 1 , 5 , 0 , 0 , 0 ).getTimestamp (),
354
- new DateTime (DateTime .UTC , 2019 , 1 , 6 , 0 , 0 , 0 ).getTimestamp ()
374
+ new DateTime (DateTime .UTC , 2019 , 1 , 2 , 0 , 0 , 0 ).getTimestamp (),
375
+ new DateTime (DateTime .UTC , 2019 , 1 , 3 , 0 , 0 , 0 ).getTimestamp (),
376
+ new DateTime (DateTime .UTC , 2019 , 1 , 4 , 0 , 0 , 0 ).getTimestamp (),
377
+ new DateTime (DateTime .UTC , 2019 , 1 , 5 , 0 , 0 , 0 ).getTimestamp (),
378
+ new DateTime (DateTime .UTC , 2019 , 1 , 6 , 0 , 0 , 0 ).getTimestamp ()
355
379
));
356
380
}
357
381
382
+
383
+ private final static class RecurrenceAdapter extends AbstractBaseIterator <Long >
384
+ {
385
+
386
+ private final RecurrenceSetIterator mDelegate ;
387
+
388
+
389
+ private RecurrenceAdapter (RecurrenceSetIterator delegate )
390
+ {
391
+ mDelegate = delegate ;
392
+ }
393
+
394
+
395
+ @ Override
396
+ public boolean hasNext ()
397
+ {
398
+ return mDelegate .hasNext ();
399
+ }
400
+
401
+
402
+ @ Override
403
+ public Long next ()
404
+ {
405
+ if (!hasNext ())
406
+ {
407
+ throw new NoSuchElementException ();
408
+ }
409
+ return mDelegate .next ();
410
+ }
411
+ }
358
412
}
0 commit comments