package net.time4j.range;
import net.time4j.CalendarUnit;
import net.time4j.ClockUnit;
import net.time4j.Duration;
import net.time4j.PlainDate;
import net.time4j.PlainTimestamp;
import net.time4j.tz.OffsetSign;
import net.time4j.tz.ZonalOffset;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
@RunWith(JUnit4.class)
public class IsoRecurrenceTest {
@Test
public void dateIntervalsWithStartDuration() {
IsoRecurrence<DateInterval> recurrence =
IsoRecurrence.of(4, PlainDate.of(2016, 7, 1), Duration.of(1, CalendarUnit.MONTHS));
assertThat(recurrence.isBackwards(), is(false));
assertThat(recurrence.isEmpty(), is(false));
assertThat(recurrence.isInfinite(), is(false));
assertThat(recurrence.getCount(), is(4));
assertThat(recurrence.toString(), is("R4/2016-07-01/P1M"));
List<DateInterval> intervals = new ArrayList<>();
for (DateInterval interval : recurrence) {
intervals.add(interval);
}
assertThat(intervals.size(), is(4));
assertThat(intervals.get(0), is(DateInterval.between(PlainDate.of(2016, 7, 1), PlainDate.of(2016, 7, 31))));
assertThat(intervals.get(1), is(DateInterval.between(PlainDate.of(2016, 8, 1), PlainDate.of(2016, 8, 31))));
assertThat(intervals.get(2), is(DateInterval.between(PlainDate.of(2016, 9, 1), PlainDate.of(2016, 9, 30))));
assertThat(intervals.get(3), is(DateInterval.between(PlainDate.of(2016, 10, 1), PlainDate.of(2016, 10, 31))));
}
@Test(expected=IllegalArgumentException.class)
public void dateIntervalsWithNegativeDuration() {
IsoRecurrence.of(4, PlainDate.of(2016, 7, 1), Duration.of(1, CalendarUnit.MONTHS).inverse());
}
@Test(expected=IllegalArgumentException.class)
public void dateIntervalsWithEmptyDuration() {
IsoRecurrence.of(4, PlainDate.of(2016, 7, 1), Duration.of(0, CalendarUnit.MONTHS));
}
@Test
public void dateIntervalsWithDurationEnd() {
IsoRecurrence<DateInterval> recurrence =
IsoRecurrence.of(
4,
Duration.of(1, CalendarUnit.MONTHS.keepingEndOfMonth()),
PlainDate.of(2016, 4, 1).with(PlainDate.DAY_OF_MONTH.maximized()));
assertThat(recurrence.isBackwards(), is(true));
assertThat(recurrence.isEmpty(), is(false));
assertThat(recurrence.isInfinite(), is(false));
assertThat(recurrence.getCount(), is(4));
assertThat(recurrence.toString(), is("R4/P1{M-KEEPING_LAST_DATE}/2016-04-30"));
List<DateInterval> intervals = new ArrayList<>();
for (DateInterval interval : recurrence) {
intervals.add(interval);
}
assertThat(intervals.size(), is(4));
assertThat(intervals.get(0), is(DateInterval.between(PlainDate.of(2016, 4, 1), PlainDate.of(2016, 4, 30))));
assertThat(intervals.get(1), is(DateInterval.between(PlainDate.of(2016, 3, 1), PlainDate.of(2016, 3, 31))));
assertThat(intervals.get(2), is(DateInterval.between(PlainDate.of(2016, 2, 1), PlainDate.of(2016, 2, 29))));
assertThat(intervals.get(3), is(DateInterval.between(PlainDate.of(2016, 1, 1), PlainDate.of(2016, 1, 31))));
}
@Test
public void dateIntervalsWithStartEnd() {
IsoRecurrence<DateInterval> recurrence =
IsoRecurrence.of(4, PlainDate.of(2016, 12, 1), PlainDate.of(2016, 12, 31));
assertThat(recurrence.isBackwards(), is(false));
assertThat(recurrence.isEmpty(), is(false));
assertThat(recurrence.isInfinite(), is(false));
assertThat(recurrence.getCount(), is(4));
assertThat(recurrence.toString(), is("R4/2016-12-01/2016-12-31"));
List<DateInterval> intervals = new ArrayList<>();
for (DateInterval interval : recurrence) {
intervals.add(interval);
}
assertThat(intervals.size(), is(4));
assertThat(intervals.get(0), is(DateInterval.between(PlainDate.of(2016, 12, 1), PlainDate.of(2016, 12, 31))));
assertThat(intervals.get(1), is(DateInterval.between(PlainDate.of(2017, 1, 1), PlainDate.of(2017, 1, 31))));
assertThat(intervals.get(2), is(DateInterval.between(PlainDate.of(2017, 2, 1), PlainDate.of(2017, 2, 28))));
assertThat(intervals.get(3), is(DateInterval.between(PlainDate.of(2017, 3, 1), PlainDate.of(2017, 3, 31))));
}
@Test
public void empty() {
IsoRecurrence<DateInterval> recurrence =
IsoRecurrence.of(0, PlainDate.of(2016, 12, 1), PlainDate.of(2016, 12, 31));
assertThat(recurrence.isEmpty(), is(true));
assertThat(recurrence.getCount(), is(0));
for (DateInterval interval : recurrence) {
fail("Empty recurrence with interval: " + interval);
}
}
@Test
public void testEquality() {
IsoRecurrence<DateInterval> recurrence1 =
IsoRecurrence.of(4, PlainDate.of(2016, 12, 1), PlainDate.of(2016, 12, 31));
IsoRecurrence<DateInterval> recurrence2 =
IsoRecurrence.of(4, PlainDate.of(2016, 12, 1), Duration.of(1, CalendarUnit.MONTHS));
IsoRecurrence<DateInterval> recurrence3 =
IsoRecurrence.of(4, PlainDate.of(2016, 7, 1), Duration.of(1, CalendarUnit.MONTHS));
IsoRecurrence<DateInterval> recurrence4 =
IsoRecurrence.of(4, PlainDate.of(2016, 7, 1), Duration.of(1, CalendarUnit.MONTHS));
assertThat(recurrence1.equals(recurrence1), is(true));
assertThat(recurrence1.equals(null), is(false));
assertThat(recurrence1.equals(recurrence2), is(false));
assertThat(recurrence2.equals(recurrence3), is(false));
assertThat(recurrence4.equals(recurrence3), is(true));
}
@Test
public void withCount() {
IsoRecurrence<DateInterval> recurrence =
IsoRecurrence.of(4, PlainDate.of(2016, 12, 1), PlainDate.of(2016, 12, 31));
IsoRecurrence<DateInterval> expected =
IsoRecurrence.of(12, PlainDate.of(2016, 12, 1), PlainDate.of(2016, 12, 31));
assertThat(recurrence.withCount(4) == recurrence, is(true));
assertThat(recurrence.withCount(12), is(expected));
}
@Test(expected=IllegalArgumentException.class)
public void withInvalidCount() {
IsoRecurrence<DateInterval> recurrence =
IsoRecurrence.of(4, PlainDate.of(2016, 12, 1), PlainDate.of(2016, 12, 31));
recurrence.withCount(-1);
}
@Test
public void withInfiniteCount() {
IsoRecurrence<DateInterval> recurrence =
IsoRecurrence.of(4, PlainDate.of(2016, 12, 1), PlainDate.of(2016, 12, 31)).withInfiniteCount();
assertThat(recurrence.isInfinite(), is(true));
assertThat(recurrence.getCount(), is(-1));
int index = 0;
for (DateInterval ignored : recurrence) {
index++;
if (index > 5) { // arbitrary choice
break; // prevents infinite loop
}
}
assertThat(index, is(6));
}
@Test(expected=ParseException.class)
public void parseInvalidSyntax1() throws ParseException {
IsoRecurrence.parseDateIntervals("2016-12-01/2016-12-31");
}
@Test(expected=ParseException.class)
public void parseInvalidSyntax2() throws ParseException {
IsoRecurrence.parseDateIntervals("/2016-12-01/2016-12-31");
}
@Test(expected=ParseException.class)
public void parseInvalidSyntax3() throws ParseException {
IsoRecurrence.parseDateIntervals("S/2016-12-01/2016-12-31");
}
@Test(expected=ParseException.class)
public void parseInvalidSyntax4() throws ParseException {
IsoRecurrence.parseDateIntervals("RR/2016-12-01/2016-12-31");
}
@Test
public void parseInfiniteDateIntervals() throws ParseException {
IsoRecurrence<DateInterval> expected =
IsoRecurrence.of(4, PlainDate.of(2016, 12, 1), PlainDate.of(2016, 12, 31)).withInfiniteCount();
assertThat(IsoRecurrence.parseDateIntervals("R/2016-12-01/2016-12-31"), is(expected));
}
@Test
public void parseDateIntervalsStartDuration() throws ParseException {
IsoRecurrence<DateInterval> expected =
IsoRecurrence.of(4, PlainDate.of(2016, 12, 1), Duration.of(1, CalendarUnit.MONTHS));
assertThat(IsoRecurrence.parseDateIntervals("R4/20161201/P1M"), is(expected));
assertThat(IsoRecurrence.parseDateIntervals("R4/2016-12-01/P1M"), is(expected));
}
@Test
public void parseDateIntervalsDurationEnd() throws ParseException {
IsoRecurrence<DateInterval> expected =
IsoRecurrence.of(0, Duration.of(2, CalendarUnit.WEEKS), PlainDate.of(2016, 1, 31));
assertThat(IsoRecurrence.parseDateIntervals("R0/P2W/2016W047"), is(expected));
assertThat(IsoRecurrence.parseDateIntervals("R0/P2W/2016-W04-7"), is(expected));
}
@Test
public void parseDateIntervalsStartEnd() throws ParseException {
IsoRecurrence<DateInterval> expected =
IsoRecurrence.of(87, PlainDate.of(2016, 12, 1), PlainDate.of(2016, 12, 31));
assertThat(IsoRecurrence.parseDateIntervals("R87/2016336/2016366"), is(expected));
assertThat(IsoRecurrence.parseDateIntervals("R87/2016336/366"), is(expected));
assertThat(IsoRecurrence.parseDateIntervals("R87/2016-336/2016-366"), is(expected));
assertThat(IsoRecurrence.parseDateIntervals("R87/2016-336/366"), is(expected));
assertThat(IsoRecurrence.parseDateIntervals("R87/20161201/20161231"), is(expected));
assertThat(IsoRecurrence.parseDateIntervals("R87/20161201/1231"), is(expected));
assertThat(IsoRecurrence.parseDateIntervals("R87/2016-12-01/2016-12-31"), is(expected));
assertThat(IsoRecurrence.parseDateIntervals("R87/2016-12-01/12-31"), is(expected));
assertThat(IsoRecurrence.parseDateIntervals("R87/2016-12-01/31"), is(expected));
assertThat(IsoRecurrence.parseDateIntervals("R87/2016W484/2016W526"), is(expected));
assertThat(IsoRecurrence.parseDateIntervals("R87/2016W484/W526"), is(expected));
assertThat(IsoRecurrence.parseDateIntervals("R87/2016-W48-4/2016-W52-6"), is(expected));
assertThat(IsoRecurrence.parseDateIntervals("R87/2016-W48-4/W52-6"), is(expected));
}
@Test(expected=ParseException.class)
public void parseDateIntervalsWithDifferentPatterns() throws ParseException {
IsoRecurrence.parseDateIntervals("R87/20161201/2016-12-31");
}
@Test
public void timestampIntervalsWithStartDuration() {
IsoRecurrence<TimestampInterval> recurrence =
IsoRecurrence.of(
4,
PlainTimestamp.of(2016, 7, 1, 10, 0),
Duration.ofPositive().days(1).hours(6).build());
assertThat(recurrence.isBackwards(), is(false));
assertThat(recurrence.isEmpty(), is(false));
assertThat(recurrence.isInfinite(), is(false));
assertThat(recurrence.getCount(), is(4));
assertThat(recurrence.toString(), is("R4/2016-07-01T10/P1DT6H"));
List<TimestampInterval> intervals = new ArrayList<>();
for (TimestampInterval interval : recurrence) {
intervals.add(interval);
}
assertThat(intervals.size(), is(4));
assertThat(
intervals.get(0),
is(TimestampInterval.between(PlainTimestamp.of(2016, 7, 1, 10, 0), PlainTimestamp.of(2016, 7, 2, 16, 0))));
assertThat(
intervals.get(1),
is(TimestampInterval.between(PlainTimestamp.of(2016, 7, 2, 16, 0), PlainTimestamp.of(2016, 7, 3, 22, 0))));
assertThat(
intervals.get(2),
is(TimestampInterval.between(PlainTimestamp.of(2016, 7, 3, 22, 0), PlainTimestamp.of(2016, 7, 5, 4, 0))));
assertThat(
intervals.get(3),
is(TimestampInterval.between(PlainTimestamp.of(2016, 7, 5, 4, 0), PlainTimestamp.of(2016, 7, 6, 10, 0))));
}
@Test
public void timestampIntervalsWithDurationEnd() {
IsoRecurrence<TimestampInterval> recurrence =
IsoRecurrence.of(
4,
Duration.ofPositive().days(1).hours(6).build(),
PlainTimestamp.of(2016, 7, 6, 10, 0));
assertThat(recurrence.isBackwards(), is(true));
assertThat(recurrence.isEmpty(), is(false));
assertThat(recurrence.isInfinite(), is(false));
assertThat(recurrence.getCount(), is(4));
assertThat(recurrence.toString(), is("R4/P1DT6H/2016-07-06T10"));
List<TimestampInterval> intervals = new ArrayList<>();
for (TimestampInterval interval : recurrence) {
intervals.add(interval);
}
assertThat(intervals.size(), is(4));
assertThat(
intervals.get(3),
is(TimestampInterval.between(PlainTimestamp.of(2016, 7, 1, 10, 0), PlainTimestamp.of(2016, 7, 2, 16, 0))));
assertThat(
intervals.get(2),
is(TimestampInterval.between(PlainTimestamp.of(2016, 7, 2, 16, 0), PlainTimestamp.of(2016, 7, 3, 22, 0))));
assertThat(
intervals.get(1),
is(TimestampInterval.between(PlainTimestamp.of(2016, 7, 3, 22, 0), PlainTimestamp.of(2016, 7, 5, 4, 0))));
assertThat(
intervals.get(0),
is(TimestampInterval.between(PlainTimestamp.of(2016, 7, 5, 4, 0), PlainTimestamp.of(2016, 7, 6, 10, 0))));
}
@Test
public void timestampIntervalsWithStartEnd() {
IsoRecurrence<TimestampInterval> recurrence =
IsoRecurrence.of(
4,
PlainTimestamp.of(2016, 7, 1, 10, 0),
PlainTimestamp.of(2016, 7, 2, 16, 0));
assertThat(recurrence.isBackwards(), is(false));
assertThat(recurrence.isEmpty(), is(false));
assertThat(recurrence.isInfinite(), is(false));
assertThat(recurrence.getCount(), is(4));
assertThat(recurrence.toString(), is("R4/2016-07-01T10/2016-07-02T16"));
List<TimestampInterval> intervals = new ArrayList<>();
for (TimestampInterval interval : recurrence) {
intervals.add(interval);
}
assertThat(intervals.size(), is(4));
assertThat(
intervals.get(0),
is(TimestampInterval.between(PlainTimestamp.of(2016, 7, 1, 10, 0), PlainTimestamp.of(2016, 7, 2, 16, 0))));
assertThat(
intervals.get(1),
is(TimestampInterval.between(PlainTimestamp.of(2016, 7, 2, 16, 0), PlainTimestamp.of(2016, 7, 3, 22, 0))));
assertThat(
intervals.get(2),
is(TimestampInterval.between(PlainTimestamp.of(2016, 7, 3, 22, 0), PlainTimestamp.of(2016, 7, 5, 4, 0))));
assertThat(
intervals.get(3),
is(TimestampInterval.between(PlainTimestamp.of(2016, 7, 5, 4, 0), PlainTimestamp.of(2016, 7, 6, 10, 0))));
}
@Test
public void parseTimestampIntervals() throws ParseException {
IsoRecurrence<TimestampInterval> expected =
IsoRecurrence.of(
87,
PlainTimestamp.of(2016, 7, 1, 10, 15, 59),
PlainTimestamp.of(2016, 7, 2, 16, 45, 0).plus(123, ClockUnit.MILLIS));
assertThat(IsoRecurrence.parseTimestampIntervals("R87/20160701T101559/20160702T164500.123"), is(expected));
assertThat(IsoRecurrence.parseTimestampIntervals("R87/2016-07-01T10:15:59/2016-07-02T16:45:00.123"), is(expected));
assertThat(IsoRecurrence.parseTimestampIntervals("R87/2016-07-01T10:15:59/02T16:45:00.123"), is(expected));
expected =
IsoRecurrence.of(
2,
PlainTimestamp.of(2016, 7, 1, 10, 15, 59),
PlainTimestamp.of(2016, 7, 1, 16, 45, 0).plus(123, ClockUnit.MILLIS));
assertThat(IsoRecurrence.parseTimestampIntervals("R2/2016-07-01T10:15:59/T16:45:00.123"), is(expected));
assertThat(IsoRecurrence.parseTimestampIntervals("R2/2016-07-01T10:15:59/16:45:00.123"), is(expected));
}
@Test
public void parseMomentIntervals() throws ParseException {
IsoRecurrence<MomentInterval> expected =
IsoRecurrence.of(
87,
PlainTimestamp.of(2016, 7, 1, 10, 15, 59).atUTC(),
PlainTimestamp.of(2016, 7, 2, 16, 45, 0).plus(123, ClockUnit.MILLIS).atUTC(),
ZonalOffset.ofHours(OffsetSign.AHEAD_OF_UTC, 2));
assertThat(
IsoRecurrence.parseMomentIntervals("R87/20160701T121559+0200/20160702T184500.123"), is(expected));
assertThat(
IsoRecurrence.parseMomentIntervals("R87/2016-07-01T12:15:59+02:00/2016-07-02T16:45:00.123Z"), is(expected));
expected =
IsoRecurrence.of(
87,
PlainTimestamp.of(2016, 7, 1, 10, 15, 59).atUTC(),
Duration.ofPositive().days(1).hours(6).minutes(29).seconds(59).millis(123).build(),
ZonalOffset.ofHours(OffsetSign.AHEAD_OF_UTC, 2));
assertThat(
IsoRecurrence.parseMomentIntervals("R87/2016-07-01T12:15:59+02:00/P1DT6H29M59,123000000S"), is(expected));
expected =
IsoRecurrence.of(
2,
PlainTimestamp.of(2016, 7, 1, 10, 15, 59).atUTC(),
PlainTimestamp.of(2016, 7, 1, 16, 45, 0).plus(123, ClockUnit.MILLIS).atUTC(),
ZonalOffset.UTC);
assertThat(IsoRecurrence.parseMomentIntervals("R2/2016-07-01T10:15:59Z/T16:45:00.123"), is(expected));
assertThat(IsoRecurrence.parseMomentIntervals("R2/2016-07-01T10:15:59Z/16:45:00.123"), is(expected));
}
@Test
public void testToString() {
IsoRecurrence<DateInterval> dateIntervalIsoRecurrence =
IsoRecurrence.of(0, Duration.of(2, CalendarUnit.WEEKS), PlainDate.of(2016, 1, 31)).withInfiniteCount();
assertThat(
dateIntervalIsoRecurrence.toString(),
is("R/P2W/2016-01-31"));
IsoRecurrence<TimestampInterval> timestampIntervalIsoRecurrence =
IsoRecurrence.of(
6,
PlainTimestamp.of(2016, 7, 1, 10, 15, 59),
Duration.ofPositive().months(2).days(4).hours(12).build());
assertThat(
timestampIntervalIsoRecurrence.toString(),
is("R6/2016-07-01T10:15:59/P2M4DT12H"));
IsoRecurrence<MomentInterval> momentIntervalIsoRecurrence =
IsoRecurrence.of(
87,
PlainTimestamp.of(2016, 7, 1, 10, 15, 59).atUTC(),
PlainTimestamp.of(2016, 7, 2, 16, 45, 0).plus(123, ClockUnit.MILLIS).atUTC(),
ZonalOffset.ofHours(OffsetSign.AHEAD_OF_UTC, 2));
assertThat(
momentIntervalIsoRecurrence.toString(),
is("R87/2016-07-01T12:15:59+02:00/2016-07-02T18:45:00,123+02:00"));
}
@Test
public void intervalStream() {
IsoRecurrence<DateInterval> recurrence =
IsoRecurrence.of(4, PlainDate.of(2016, 7, 1), Duration.of(1, CalendarUnit.MONTHS));
List<DateInterval> expected = new ArrayList<>();
for (DateInterval interval : recurrence) {
expected.add(interval);
}
assertThat(recurrence.intervalStream().collect(Collectors.toList()), is(expected));
assertThat(recurrence.intervalStream().parallel().collect(Collectors.toList()), is(expected));
}
}