package ru.orangesoftware.financisto2.test.recur;
import android.test.AndroidTestCase;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import ru.orangesoftware.financisto2.recur.DateRecurrenceIterator;
import ru.orangesoftware.financisto2.recur.Recurrence;
import ru.orangesoftware.financisto2.test.builders.DateTime;
import static ru.orangesoftware.financisto2.test.builders.DateTime.date;
/**
* Created by IntelliJ IDEA.
* User: Denis Solonenko
* Date: 2/18/11 7:15 PM
*/
public class RecurrenceTest extends AndroidTestCase {
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public void test_should_schedule_correctly_monthly_last_working_day() throws ParseException {
assertDates(
"2010-06-30T15:20:00~MONTHLY:count@1#interval@1#monthly_pattern_params_0@LAST-WEEKDAY#monthly_pattern_0@SPECIFIC_DAY#~INDEFINETELY:null",
date(2011, 2, 18).atMidnight(),
"2011-02-28 15:20:00,2011-03-31 15:20:00,2011-04-29 15:20:00,...");
}
public void test_should_schedule_correctly_on_the_same_day_if_the_schedule_time_is_after_the_current_time() throws Exception {
assertDates(
"2011-02-27T19:30:00~DAILY:interval@1#~INDEFINETELY:null",
date(2011, 2, 27).at(12, 0, 0, 0),
"2011-02-27 19:30:00,2011-02-28 19:30:00,...");
}
public void test_should_schedule_correctly_on_the_next_day_if_the_scheduled_time_is_before_the_current_time() throws Exception {
assertDates(
"2011-02-27T19:30:00~DAILY:interval@1#~INDEFINETELY:null",
date(2011, 2, 27).at(20, 0, 0, 0),
"2011-02-28 19:30:00,2011-03-01 19:30:00,...");
}
public void test_should_generate_scheduled_times_for_specific_period() throws Exception {
assertDates(generateDates("2011-08-02T21:40:00~DAILY:interval@1#~INDEFINETELY:null", date(2011, 8, 1).atMidnight(), date(2011, 8, 5).atDayEnd()),
"2011-08-02 21:40:00,2011-08-03 21:40:00,2011-08-04 21:40:00,2011-08-05 21:40:00");
assertDates(generateDates("2011-08-02T21:40:00~DAILY:interval@2#~INDEFINETELY:null", date(2011, 8, 8).at(23, 20, 0, 0), date(2011, 8, 16).atDayEnd()),
"2011-08-10 21:40:00,2011-08-12 21:40:00,2011-08-14 21:40:00,2011-08-16 21:40:00");
assertDates(generateDates("2011-08-02T23:00:00~WEEKLY:days@TUE#interval@1#~INDEFINETELY:null", date(2011, 8, 8).at(23, 20, 0, 0), date(2011, 8, 16).atDayEnd()),
"2011-08-09 23:00:00,2011-08-16 23:00:00");
assertDates(generateDates("2011-08-02T21:20:00~WEEKLY:days@FRI#interval@1#~INDEFINETELY:null", date(2011, 8, 8).at(23, 20, 0, 0), date(2011, 8, 16).atDayEnd()),
"2011-08-12 21:20:00");
assertTrue(generateDates("2011-09-02T21:20:00~WEEKLY:days@FRI#interval@1#~INDEFINETELY:null", date(2011, 8, 8).at(23, 20, 0, 0), date(2011, 8, 16).atDayEnd()).isEmpty());
}
private List<Date> generateDates(String pattern, DateTime start, DateTime end) {
Recurrence r = Recurrence.parse(pattern);
return r.generateDates(start.asDate(), end.asDate());
}
private void assertDates(List<Date> dates, String datesAsString) throws ParseException {
String[] expectedDates = datesAsString.split(",");
int count = expectedDates.length;
if (count < dates.size()) {
fail("Too many dates generated: Expected "+count+", Got "+dates.size());
}
if (count > dates.size()) {
fail("Too few dates generated: Expected "+count+", Got "+dates.size());
}
for (int i=0; i<count; i++) {
String expectedDate = expectedDates[i];
String actualDate = formatDateTime(dates.get(i));
assertEquals(i+" -> Expected: "+expectedDate+" Got: "+actualDate, expectedDate, actualDate);
}
}
private void assertDates(String pattern, DateTime startDateTime, String datesAsString) throws ParseException {
Recurrence r = Recurrence.parse(pattern);
DateRecurrenceIterator ri = r.createIterator(startDateTime.asDate());
assertTrue(ri.hasNext());
String[] expectedDates = datesAsString.split(",");
for (String expectedDate : expectedDates) {
if ("...".equals(expectedDate)) {
assertTrue(ri.hasNext());
return;
}
assertEquals(expectedDate, formatDateTime(ri.next()));
}
}
private String formatDateTime(Date d) throws ParseException {
return sdf.format(d);
}
}