Clean up recurrence jvm tests

pull/1348/head
Alex Baker 3 years ago
parent 5e128fd6de
commit c3080e6559

@ -4,9 +4,9 @@ import org.tasks.time.DateTime
import org.tasks.time.DateTimeUtils
class Freeze {
fun thawAfter(run: () -> Unit) {
fun <T> thawAfter(run: () -> T): T {
try {
run()
return run()
} finally {
thaw()
}
@ -14,16 +14,16 @@ class Freeze {
companion object {
fun freezeClock(run: () -> Unit) {
freezeAt(DateTimeUtils.currentTimeMillis()).thawAfter(run)
fun freezeClock(run: () -> Unit): Any {
return freezeAt(DateTimeUtils.currentTimeMillis()).thawAfter(run)
}
fun freezeAt(dateTime: DateTime, run: () -> Unit) {
freezeAt(dateTime.millis, run)
fun <T> freezeAt(dateTime: DateTime, run: () -> T): T {
return freezeAt(dateTime.millis, run)
}
fun freezeAt(timestamp: Long, run: () -> Unit) {
freezeAt(timestamp).thawAfter(run)
fun <T> freezeAt(timestamp: Long, run: () -> T): T {
return freezeAt(timestamp).thawAfter(run)
}
fun freezeAt(dateTime: DateTime): Freeze {

@ -1,241 +0,0 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.repeats
import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.astrid.data.Task
import net.fortuna.ical4j.model.Recur
import net.fortuna.ical4j.model.Recur.Frequency
import net.fortuna.ical4j.model.WeekDay
import net.fortuna.ical4j.model.WeekDay.*
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.tasks.date.DateTimeUtils
import org.tasks.repeats.RecurrenceUtils.newRecur
import org.tasks.time.DateTime
import org.tasks.time.DateTimeUtils.printTimestamp
import java.text.ParseException
import java.util.*
import kotlin.math.abs
import kotlin.math.min
class AdvancedRepeatTest {
private var task: Task? = null
private var nextDueDate: Long = 0
private var recur: Recur? = null
// --- date with time tests
@Before
fun setUp() {
task = Task()
task!!.completionDate = DateUtilities.now()
recur = newRecur()
}
@Test
@Throws(ParseException::class)
fun testDueDateSpecificTime() {
buildRecur(1, Frequency.DAILY)
// test specific day & time
val dayWithTime = Task.createDueDate(
Task.URGENCY_SPECIFIC_DAY_TIME, DateTime(2010, 8, 1, 10, 4, 0).millis)
task!!.dueDate = dayWithTime
val nextDayWithTime = dayWithTime + DateUtilities.ONE_DAY
nextDueDate = RepeatTaskHelper.computeNextDueDate(task!!, recur!!.toString(), false)
assertDateTimeEquals(nextDayWithTime, nextDueDate)
}
// --- due date tests
@Test
@Throws(ParseException::class)
fun testCompletionDateSpecificTime() {
buildRecur(1, Frequency.DAILY)
// test specific day & time
val dayWithTime = Task.createDueDate(
Task.URGENCY_SPECIFIC_DAY_TIME, DateTime(2010, 8, 1, 10, 4, 0).millis)
task!!.dueDate = dayWithTime
val todayWithTime = DateTimeUtils.newDateTime().withHourOfDay(10).withMinuteOfHour(4).withSecondOfMinute(1)
var nextDayWithTimeLong = todayWithTime.millis
nextDayWithTimeLong += DateUtilities.ONE_DAY
nextDayWithTimeLong = nextDayWithTimeLong / 1000L * 1000
nextDueDate = RepeatTaskHelper.computeNextDueDate(task!!, recur!!.toString(), true)
assertDateTimeEquals(nextDayWithTimeLong, nextDueDate)
}
/** test multiple days per week - DUE DATE */
@Test
@Throws(Exception::class)
fun testDueDateInPastSingleWeekMultiDay() {
buildRecur(1, Frequency.WEEKLY, MO, WE, FR)
setTaskDueDate(THIS, Calendar.SUNDAY)
computeNextDueDate(false)
assertDueDate(nextDueDate, THIS, Calendar.MONDAY)
setTaskDueDate(THIS, Calendar.MONDAY)
computeNextDueDate(false)
assertDueDate(nextDueDate, THIS, Calendar.WEDNESDAY)
setTaskDueDate(THIS, Calendar.FRIDAY)
computeNextDueDate(false)
assertDueDate(nextDueDate, THIS, Calendar.MONDAY)
}
/** test single day repeats - DUE DATE */
@Test
@Throws(Exception::class)
fun testDueDateSingleDay() {
buildRecur(1, Frequency.WEEKLY, MO)
setTaskDueDate(PREV_PREV, Calendar.MONDAY)
computeNextDueDate(false)
assertDueDate(nextDueDate, NEXT, Calendar.MONDAY)
setTaskDueDate(PREV_PREV, Calendar.FRIDAY)
computeNextDueDate(false)
assertDueDate(nextDueDate, THIS, Calendar.MONDAY)
setTaskDueDate(PREV, Calendar.MONDAY)
computeNextDueDate(false)
assertDueDate(nextDueDate, NEXT, Calendar.MONDAY)
setTaskDueDate(PREV, Calendar.FRIDAY)
computeNextDueDate(false)
assertDueDate(nextDueDate, THIS, Calendar.MONDAY)
setTaskDueDate(THIS, Calendar.SUNDAY)
computeNextDueDate(false)
assertDueDate(nextDueDate, THIS, Calendar.MONDAY)
setTaskDueDate(THIS, Calendar.MONDAY)
computeNextDueDate(false)
assertDueDate(nextDueDate, NEXT, Calendar.MONDAY)
}
/** test multiple days per week - DUE DATE */
@Test
@Throws(Exception::class)
fun testDueDateSingleWeekMultiDay() {
buildRecur(1, Frequency.WEEKLY, MO, WE, FR)
setTaskDueDate(THIS, Calendar.SUNDAY)
computeNextDueDate(false)
assertDueDate(nextDueDate, THIS, Calendar.MONDAY)
setTaskDueDate(THIS, Calendar.MONDAY)
computeNextDueDate(false)
assertDueDate(nextDueDate, THIS, Calendar.WEDNESDAY)
setTaskDueDate(THIS, Calendar.FRIDAY)
computeNextDueDate(false)
assertDueDate(nextDueDate, THIS, Calendar.MONDAY)
}
// --- completion tests
/** test multiple days per week, multiple intervals - DUE DATE */
@Test
@Throws(Exception::class)
fun testDueDateMultiWeekMultiDay() {
buildRecur(2, Frequency.WEEKLY, MO, WE, FR)
setTaskDueDate(THIS, Calendar.SUNDAY)
computeNextDueDate(false)
assertDueDate(nextDueDate, NEXT, Calendar.MONDAY)
setTaskDueDate(THIS, Calendar.MONDAY)
computeNextDueDate(false)
assertDueDate(nextDueDate, THIS, Calendar.WEDNESDAY)
setTaskDueDate(THIS, Calendar.FRIDAY)
computeNextDueDate(false)
assertDueDate(nextDueDate, NEXT, Calendar.MONDAY)
}
/** test multiple days per week - COMPLETE DATE */
@Test
@Throws(Exception::class)
fun testCompleteDateSingleWeek() {
for (wday in weekdays) {
buildRecur(1, Frequency.WEEKLY, wday)
computeNextDueDate(true)
val expected = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, THIS, getCalendarDay(wday))
nextDueDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, nextDueDate)
assertEquals(expected, nextDueDate)
}
for (wday1 in weekdays) {
for (wday2 in weekdays) {
if (wday1 == wday2) {
continue
}
buildRecur(1, Frequency.WEEKLY, wday1, wday2)
val nextOne = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, THIS, getCalendarDay(wday1))
val nextTwo = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, THIS, getCalendarDay(wday2))
computeNextDueDate(true)
nextDueDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, nextDueDate)
assertEquals(min(nextOne, nextTwo), nextDueDate)
}
}
}
// --- helpers
/** test multiple days per week, multiple intervals - COMPLETE DATE */
@Test
@Throws(Exception::class)
fun testCompleteDateMultiWeek() {
for (wday in weekdays) {
buildRecur(2, Frequency.WEEKLY, wday)
computeNextDueDate(true)
val expected = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, NEXT, getCalendarDay(wday))
nextDueDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, nextDueDate)
assertEquals(expected, nextDueDate)
}
for (wday1 in weekdays) {
for (wday2 in weekdays) {
if (wday1 == wday2) {
continue
}
buildRecur(2, Frequency.WEEKLY, wday1, wday2)
val nextOne = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, NEXT, getCalendarDay(wday1))
val nextTwo = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, NEXT, getCalendarDay(wday2))
computeNextDueDate(true)
nextDueDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, nextDueDate)
assertEquals(min(nextOne, nextTwo), nextDueDate)
}
}
}
@Throws(ParseException::class)
private fun computeNextDueDate(fromComplete: Boolean) {
nextDueDate = RepeatTaskHelper.computeNextDueDate(task!!, recur!!.toString(), fromComplete)
}
private fun buildRecur(interval: Int, freq: Frequency, vararg weekdays: WeekDay) {
recur!!.interval = interval
recur!!.setFrequency(freq.name)
recur!!.dayList.clear()
recur!!.dayList.addAll(weekdays)
}
private fun assertDueDate(actual: Long, expectedWhich: Int, expectedDayOfWeek: Int) {
val expected = getDate(task!!.dueDate, expectedWhich, expectedDayOfWeek)
assertEquals(expected, actual)
}
private fun setTaskDueDate(which: Int, day: Int) {
val time = getDate(DateUtilities.now(), which, day)
task!!.dueDate = time
}
private fun getDate(start: Long, which: Int, dayOfWeek: Int): Long {
val c = Calendar.getInstance()
c.timeInMillis = start
val direction = if (which > 0) 1 else -1
while (c[Calendar.DAY_OF_WEEK] != dayOfWeek) {
c.add(Calendar.DAY_OF_MONTH, direction)
}
c.add(Calendar.DAY_OF_MONTH, (abs(which) - 1) * direction * 7)
return Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, c.timeInMillis)
}
companion object {
private const val PREV_PREV = -2
private const val PREV = -1
private const val THIS = 1
private const val NEXT = 2
private val weekdays = listOf(SU, MO, TU, WE, TH, FR, SA)
fun assertDateTimeEquals(date: Long, other: Long) {
assertEquals("Expected: ${printTimestamp(date)}, Actual: ${printTimestamp(other)}", date, other)
}
}
}

@ -1,268 +0,0 @@
package com.todoroo.astrid.repeats
import com.natpryce.makeiteasy.MakeItEasy.with
import com.todoroo.astrid.data.Task
import net.fortuna.ical4j.model.Recur.Frequency
import net.fortuna.ical4j.model.WeekDay
import org.junit.Assert.assertEquals
import org.junit.Test
import org.tasks.makers.TaskMaker.AFTER_COMPLETE
import org.tasks.makers.TaskMaker.COMPLETION_TIME
import org.tasks.makers.TaskMaker.DUE_TIME
import org.tasks.makers.TaskMaker.RECUR
import org.tasks.makers.TaskMaker.newTask
import org.tasks.repeats.RecurrenceUtils.newRecur
import org.tasks.time.DateTime
import java.text.ParseException
class NewRepeatTests {
@Test
@Throws(ParseException::class)
fun testRepeatMinutelyFromDueDate() {
val dueDateTime = newDayTime(2016, 8, 26, 12, 30)
val task = newFromDue(Frequency.MINUTELY, 1, dueDateTime)
assertEquals(newDayTime(2016, 8, 26, 12, 31), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatHourlyFromDueDate() {
val dueDateTime = newDayTime(2016, 8, 26, 12, 30)
val task = newFromDue(Frequency.HOURLY, 1, dueDateTime)
assertEquals(newDayTime(2016, 8, 26, 13, 30), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatDailyFromDueDate() {
val dueDateTime = newDayTime(2016, 8, 26, 12, 30)
val task = newFromDue(Frequency.DAILY, 1, dueDateTime)
assertEquals(newDayTime(2016, 8, 27, 12, 30), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatWeeklyFromDueDate() {
val dueDateTime = newDayTime(2016, 8, 28, 1, 34)
val task = newFromDue(Frequency.WEEKLY, 1, dueDateTime)
assertEquals(newDayTime(2016, 9, 4, 1, 34), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatMonthlyFromDueDate() {
val dueDateTime = newDayTime(2016, 8, 28, 1, 44)
val task = newFromDue(Frequency.MONTHLY, 1, dueDateTime)
assertEquals(newDayTime(2016, 9, 28, 1, 44), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatYearlyFromDueDate() {
val dueDateTime = newDayTime(2016, 8, 28, 1, 44)
val task = newFromDue(Frequency.YEARLY, 1, dueDateTime)
assertEquals(newDayTime(2017, 8, 28, 1, 44), calculateNextDueDate(task))
}
/** Tests for repeating from completionDate */
@Test
@Throws(ParseException::class)
fun testRepeatMinutelyFromCompleteDateCompleteBefore() {
val dueDateTime = newDayTime(2016, 8, 30, 0, 25)
val completionDateTime = newDayTime(2016, 8, 29, 0, 14)
val task = newFromCompleted(Frequency.MINUTELY, 1, dueDateTime, completionDateTime)
assertEquals(newDayTime(2016, 8, 29, 0, 15), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatMinutelyFromCompleteDateCompleteAfter() {
val dueDateTime = newDayTime(2016, 8, 28, 0, 4)
val completionDateTime = newDayTime(2016, 8, 29, 0, 14)
val task = newFromCompleted(Frequency.MINUTELY, 1, dueDateTime, completionDateTime)
assertEquals(newDayTime(2016, 8, 29, 0, 15), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatHourlyFromCompleteDateCompleteBefore() {
val dueDateTime = newDayTime(2016, 8, 30, 0, 25)
val completionDateTime = newDayTime(2016, 8, 29, 0, 14)
val task = newFromCompleted(Frequency.HOURLY, 1, dueDateTime, completionDateTime)
assertEquals(newDayTime(2016, 8, 29, 1, 14), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatHourlyFromCompleteDateCompleteAfter() {
val dueDateTime = newDayTime(2016, 8, 28, 0, 4)
val completionDateTime = newDayTime(2016, 8, 29, 0, 14)
val task = newFromCompleted(Frequency.HOURLY, 1, dueDateTime, completionDateTime)
assertEquals(newDayTime(2016, 8, 29, 1, 14), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatDailyFromCompleteDateCompleteBefore() {
val dueDateTime = newDayTime(2016, 8, 30, 0, 25)
val completionDateTime = newDayTime(2016, 8, 29, 0, 14)
val task = newFromCompleted(Frequency.DAILY, 1, dueDateTime, completionDateTime)
assertEquals(newDayTime(2016, 8, 30, 0, 25), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatDailyFromCompleteDateCompleteAfter() {
val dueDateTime = newDayTime(2016, 8, 28, 0, 4)
val completionDateTime = newDayTime(2016, 8, 29, 0, 14)
val task = newFromCompleted(Frequency.DAILY, 1, dueDateTime, completionDateTime)
assertEquals(newDayTime(2016, 8, 30, 0, 4), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatWeeklyFromCompleteDateCompleteBefore() {
val dueDateTime = newDayTime(2016, 8, 30, 0, 25)
val completionDateTime = newDayTime(2016, 8, 29, 0, 14)
val task = newFromCompleted(Frequency.WEEKLY, 1, dueDateTime, completionDateTime)
assertEquals(newDayTime(2016, 9, 5, 0, 25), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatWeeklyFromCompleteDateCompleteAfter() {
val dueDateTime = newDayTime(2016, 8, 28, 0, 4)
val completionDateTime = newDayTime(2016, 8, 29, 0, 14)
val task = newFromCompleted(Frequency.WEEKLY, 1, dueDateTime, completionDateTime)
assertEquals(newDayTime(2016, 9, 5, 0, 4), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatMonthlyFromCompleteDateCompleteBefore() {
val dueDateTime = newDayTime(2016, 8, 30, 0, 25)
val completionDateTime = newDayTime(2016, 8, 29, 0, 14)
val task = newFromCompleted(Frequency.MONTHLY, 1, dueDateTime, completionDateTime)
assertEquals(newDayTime(2016, 9, 29, 0, 25), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatMonthlyFromCompleteDateCompleteAfter() {
val dueDateTime = newDayTime(2016, 8, 28, 0, 4)
val completionDateTime = newDayTime(2016, 8, 29, 0, 14)
val task = newFromCompleted(Frequency.MONTHLY, 1, dueDateTime, completionDateTime)
assertEquals(newDayTime(2016, 9, 29, 0, 4), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatYearlyFromCompleteDateCompleteBefore() {
val dueDateTime = newDayTime(2016, 8, 30, 0, 25)
val completionDateTime = newDayTime(2016, 8, 29, 0, 14)
val task = newFromCompleted(Frequency.YEARLY, 1, dueDateTime, completionDateTime)
assertEquals(newDayTime(2017, 8, 29, 0, 25), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testRepeatYearlyFromCompleteDateCompleteAfter() {
val dueDateTime = newDayTime(2016, 8, 28, 0, 4)
val completionDateTime = newDayTime(2016, 8, 29, 0, 14)
val task = newFromCompleted(Frequency.YEARLY, 1, dueDateTime, completionDateTime)
assertEquals(newDayTime(2017, 8, 29, 0, 4), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testAdvancedRepeatWeeklyFromDueDate() {
val dueDateTime = newDayTime(2016, 8, 29, 0, 25)
val task = newWeeklyFromDue(
1, dueDateTime, WeekDay(WeekDay.MO, 0), WeekDay(WeekDay.WE, 0))
assertEquals(newDayTime(2016, 8, 31, 0, 25), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testAdvancedRepeatWeeklyFromCompleteDateCompleteBefore() {
val dueDateTime = newDayTime(2016, 8, 29, 0, 25)
val completionDateTime = newDayTime(2016, 8, 28, 1, 9)
val task = newWeeklyFromCompleted(
1,
dueDateTime,
completionDateTime,
WeekDay(WeekDay.MO, 0),
WeekDay(WeekDay.WE, 0))
assertEquals(newDayTime(2016, 8, 29, 0, 25), calculateNextDueDate(task))
}
@Test
@Throws(ParseException::class)
fun testAdvancedRepeatWeeklyFromCompleteDateCompleteAfter() {
val dueDateTime = newDayTime(2016, 8, 29, 0, 25)
val completionDateTime = newDayTime(2016, 9, 1, 1, 9)
val task = newWeeklyFromCompleted(
1,
dueDateTime,
completionDateTime,
WeekDay(WeekDay.MO, 0),
WeekDay(WeekDay.WE, 0))
assertEquals(newDayTime(2016, 9, 5, 0, 25), calculateNextDueDate(task))
}
private fun newDayTime(year: Int, month: Int, day: Int, hour: Int, minute: Int): DateTime {
return DateTime(
Task.createDueDate(
Task.URGENCY_SPECIFIC_DAY_TIME,
DateTime(year, month, day, hour, minute).millis))
}
@Throws(ParseException::class)
private fun calculateNextDueDate(task: Task): DateTime {
return DateTime(
RepeatTaskHelper.computeNextDueDate(task, task.recurrence!!, task.repeatAfterCompletion()))
}
private fun newFromDue(frequency: Frequency, interval: Int, dueDateTime: DateTime): Task {
return newTask(
with(RECUR, getRecurrenceRule(frequency, interval)),
with(AFTER_COMPLETE, false),
with(DUE_TIME, dueDateTime))
}
private fun newWeeklyFromDue(interval: Int, dueDateTime: DateTime, vararg weekdays: WeekDay): Task {
return newTask(
with(RECUR, getRecurrenceRule(Frequency.WEEKLY, interval, *weekdays)),
with(AFTER_COMPLETE, false),
with(DUE_TIME, dueDateTime))
}
private fun newFromCompleted(
frequency: Frequency, interval: Int, dueDateTime: DateTime, completionDate: DateTime): Task {
return newTask(
with(RECUR, getRecurrenceRule(frequency, interval)),
with(AFTER_COMPLETE, true),
with(DUE_TIME, dueDateTime),
with(COMPLETION_TIME, completionDate))
}
private fun newWeeklyFromCompleted(
interval: Int, dueDateTime: DateTime, completionDate: DateTime, vararg weekdays: WeekDay): Task {
return newTask(
with(RECUR, getRecurrenceRule(Frequency.WEEKLY, interval, *weekdays)),
with(AFTER_COMPLETE, true),
with(DUE_TIME, dueDateTime),
with(COMPLETION_TIME, completionDate))
}
private fun getRecurrenceRule(
frequency: Frequency, interval: Int, vararg weekdays: WeekDay): String {
val rrule = newRecur()
rrule.setFrequency(frequency.name)
rrule.interval = interval
if (weekdays.isNotEmpty()) {
rrule.dayList.addAll(weekdays)
}
return rrule.toString()
}
}

@ -0,0 +1,46 @@
package com.todoroo.astrid.repeats
import com.natpryce.makeiteasy.MakeItEasy.with
import org.junit.Assert.assertEquals
import org.junit.Test
import org.tasks.makers.TaskMaker.COMPLETION_TIME
import org.tasks.time.DateTime
class RepeatDailyTests : RepeatTests() {
@Test
fun testRepeatDailyFromDueDate() {
val task = newFromDue("FREQ=DAILY;INTERVAL=3", newDayTime(2016, 8, 26, 12, 30))
val next = calculateNextDueDate(task)
assertEquals(newDayTime(2016, 8, 29, 12, 30), next)
}
@Test
fun testRepeatDailyFromCompleteDateCompleteBefore() {
val task = newFromDue(
"FREQ=DAILY;INTERVAL=1",
newDayTime(2016, 8, 30, 0, 25),
with(COMPLETION_TIME, DateTime(2016, 8, 29, 0, 14, 13, 451)),
afterComplete = true
)
val next = calculateNextDueDate(task)
assertEquals(newDayTime(2016, 8, 30, 0, 25), next)
}
@Test
fun testRepeatDailyFromCompleteDateCompleteAfter() {
val task = newFromDue(
"FREQ=DAILY;INTERVAL=1",
newDayTime(2016, 8, 28, 0, 4),
with(COMPLETION_TIME, DateTime(2016, 8, 29, 0, 14, 13, 451)),
afterComplete = true
)
val next = calculateNextDueDate(task)
assertEquals(newDayTime(2016, 8, 30, 0, 4), next)
}
}

@ -0,0 +1,49 @@
package com.todoroo.astrid.repeats
import com.natpryce.makeiteasy.MakeItEasy.with
import org.junit.Assert.assertEquals
import org.junit.Test
import org.tasks.Freeze.Companion.freezeAt
import org.tasks.makers.TaskMaker.COMPLETION_TIME
import org.tasks.time.DateTime
class RepeatHourlyTests : RepeatTests() {
@Test
fun testRepeatHourlyFromDueDate() {
val task = newFromDue("FREQ=HOURLY;INTERVAL=6", newDayTime(2016, 8, 26, 12, 30))
val next = calculateNextDueDate(task)
assertEquals(newDayTime(2016, 8, 26, 18, 30), next)
}
@Test
fun testRepeatHourlyFromCompleteDateCompleteBefore() {
val task = newFromDue(
"FREQ=HOURLY;INTERVAL=1",
newDayTime(2016, 8, 30, 0, 25),
with(COMPLETION_TIME, DateTime(2016, 8, 29, 0, 14, 13, 451)),
afterComplete = true
)
val next = calculateNextDueDate(task)
assertEquals(newDayTime(2016, 8, 29, 1, 14), next)
}
@Test
fun testRepeatHourlyFromCompleteDateCompleteAfter() {
val task = newFromDue(
"FREQ=HOURLY;INTERVAL=1",
newDayTime(2016, 8, 28, 0, 4),
with(COMPLETION_TIME, DateTime(2016, 8, 29, 0, 14, 13, 451)),
afterComplete = true
)
val next = freezeAt(newDayTime(2016, 8, 29, 0, 14)) {
calculateNextDueDate(task)
}
assertEquals(newDayTime(2016, 8, 29, 1, 14), next)
}
}

@ -0,0 +1,46 @@
package com.todoroo.astrid.repeats
import com.natpryce.makeiteasy.MakeItEasy.with
import org.junit.Assert.assertEquals
import org.junit.Test
import org.tasks.makers.TaskMaker.COMPLETION_TIME
import org.tasks.time.DateTime
class RepeatMinutelyTests : RepeatTests() {
@Test
fun testRepeatMinutelyFromDueDate() {
val task = newFromDue("FREQ=MINUTELY;INTERVAL=30", newDayTime(2016, 8, 26, 12, 30))
val next = calculateNextDueDate(task)
assertEquals(newDayTime(2016, 8, 26, 13, 0), next)
}
@Test
fun testRepeatMinutelyFromCompleteDateCompleteBefore() {
val task = newFromDue(
"FREQ=MINUTELY;INTERVAL=1",
newDayTime(2016, 8, 30, 0, 25),
with(COMPLETION_TIME, DateTime(2016, 8, 29, 0, 14, 13, 451)),
afterComplete = true
)
val next = calculateNextDueDate(task)
assertEquals(newDayTime(2016, 8, 29, 0, 15), next)
}
@Test
fun testRepeatMinutelyFromCompleteDateCompleteAfter() {
val task = newFromDue(
"FREQ=MINUTELY;INTERVAL=1",
newDayTime(2016, 8, 28, 0, 4),
with(COMPLETION_TIME, DateTime(2016, 8, 29, 0, 14, 13, 451)),
afterComplete = true
)
val next = calculateNextDueDate(task)
assertEquals(newDayTime(2016, 8, 29, 0, 15), next)
}
}

@ -0,0 +1,58 @@
package com.todoroo.astrid.repeats
import com.natpryce.makeiteasy.MakeItEasy.with
import org.junit.Assert.assertEquals
import org.junit.Test
import org.tasks.makers.TaskMaker.COMPLETION_TIME
import org.tasks.time.DateTime
class RepeatMonthlyTests : RepeatTests() {
@Test
fun testRepeatMonthlyFromDueDate() {
val task = newFromDue("FREQ=MONTHLY;INTERVAL=3", newDayTime(2016, 8, 28, 1, 44))
val next = calculateNextDueDate(task)
assertEquals(newDayTime(2016, 11, 28, 1, 44), next)
}
@Test
fun testRepeatMonthlyFromCompleteDateCompleteBefore() {
val task = newFromDue(
"FREQ=MONTHLY;INTERVAL=1",
newDayTime(2016, 8, 30, 0, 25),
with(COMPLETION_TIME, DateTime(2016, 8, 29, 0, 14, 13, 451)),
afterComplete = true
)
val next = calculateNextDueDate(task)
assertEquals(newDayTime(2016, 9, 29, 0, 25), next)
}
@Test
fun testRepeatMonthlyFromCompleteDateCompleteAfter() {
val task = newFromDue(
"FREQ=MONTHLY;INTERVAL=1",
newDayTime(2016, 8, 28, 0, 4),
with(COMPLETION_TIME, DateTime(2016, 8, 29, 0, 14, 13, 451)),
afterComplete = true
)
val next = calculateNextDueDate(task)
assertEquals(newDayTime(2016, 9, 29, 0, 4), next)
}
@Test
fun repeatAtEndOfJanuary() {
val task = newFromDue(
"FREQ=MONTHLY;INTERVAL=1",
newDayTime(2017, 1, 31, 13, 30)
)
val next = calculateNextDueDate(task)
assertEquals(newDayTime(2017, 2, 28, 13, 30), next)
}
}

@ -1,211 +0,0 @@
package com.todoroo.astrid.repeats
import android.annotation.SuppressLint
import com.natpryce.makeiteasy.MakeItEasy.with
import com.todoroo.astrid.alarms.AlarmService
import com.todoroo.astrid.dao.TaskDao
import com.todoroo.astrid.data.Task
import com.todoroo.astrid.gcal.GCalHelper
import com.todoroo.astrid.service.TaskCompleter
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runBlockingTest
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.mockito.InOrder
import org.mockito.Mockito
import org.tasks.Freeze.Companion.freezeClock
import org.tasks.LocalBroadcastManager
import org.tasks.makers.TaskMaker.AFTER_COMPLETE
import org.tasks.makers.TaskMaker.COMPLETION_TIME
import org.tasks.makers.TaskMaker.DUE_TIME
import org.tasks.makers.TaskMaker.ID
import org.tasks.makers.TaskMaker.RECUR
import org.tasks.makers.TaskMaker.newTask
import org.tasks.repeats.RecurrenceUtils.newRecur
import org.tasks.time.DateTime
import java.text.ParseException
@ExperimentalCoroutinesApi
@SuppressLint("NewApi")
class RepeatTaskHelperTest {
private lateinit var taskDao: TaskDao
private lateinit var localBroadcastManager: LocalBroadcastManager
private lateinit var alarmService: AlarmService
private lateinit var gCalHelper: GCalHelper
private lateinit var helper: RepeatTaskHelper
private lateinit var mocks: InOrder
private lateinit var taskCompleter: TaskCompleter
@Before
fun setUp() {
taskDao = Mockito.mock(TaskDao::class.java)
alarmService = Mockito.mock(AlarmService::class.java)
gCalHelper = Mockito.mock(GCalHelper::class.java)
localBroadcastManager = Mockito.mock(LocalBroadcastManager::class.java)
taskCompleter = Mockito.mock(TaskCompleter::class.java)
mocks = Mockito.inOrder(alarmService, gCalHelper, localBroadcastManager)
helper = RepeatTaskHelper(gCalHelper, alarmService, taskDao, localBroadcastManager, taskCompleter)
}
@After
fun after() {
Mockito.verifyNoMoreInteractions(localBroadcastManager, gCalHelper, alarmService)
}
@Test
fun noRepeat() = runBlockingTest {
helper.handleRepeat(newTask(with(DUE_TIME, DateTime(2017, 10, 4, 13, 30))))
}
@Test
@Throws(ParseException::class)
fun testMinutelyRepeat() {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTime(2017, 10, 4, 13, 30)),
with(RECUR, "RRULE:FREQ=MINUTELY;INTERVAL=30"))
repeatAndVerify(
task, DateTime(2017, 10, 4, 13, 30, 1), DateTime(2017, 10, 4, 14, 0, 1))
}
@Test
@Throws(ParseException::class)
fun testMinutelyRepeatAfterCompletion() {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTime(2017, 10, 4, 13, 30)),
with(COMPLETION_TIME, DateTime(2017, 10, 4, 13, 17, 45, 340)),
with(RECUR, "RRULE:FREQ=MINUTELY;INTERVAL=30"),
with(AFTER_COMPLETE, true))
repeatAndVerify(
task, DateTime(2017, 10, 4, 13, 30, 1), DateTime(2017, 10, 4, 13, 47, 1))
}
@Test
@Throws(ParseException::class)
fun testMinutelyDecrementCount() {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTime(2017, 10, 4, 13, 30)),
with(RECUR, "RRULE:FREQ=MINUTELY;COUNT=2;INTERVAL=30"))
repeatAndVerify(
task, DateTime(2017, 10, 4, 13, 30, 1), DateTime(2017, 10, 4, 14, 0, 1))
assertEquals(1, newRecur(task.recurrence!!).count)
}
@Test
@Throws(ParseException::class)
fun testMinutelyLastOccurrence() = runBlockingTest {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTime(2017, 10, 4, 13, 30)),
with(RECUR, "RRULE:FREQ=MINUTELY;COUNT=1;INTERVAL=30"))
helper.handleRepeat(task)
}
@Test
@Throws(ParseException::class)
fun testHourlyRepeat() {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTime(2017, 10, 4, 13, 30)),
with(RECUR, "RRULE:FREQ=HOURLY;INTERVAL=6"))
repeatAndVerify(
task, DateTime(2017, 10, 4, 13, 30, 1), DateTime(2017, 10, 4, 19, 30, 1))
}
@Test
@Throws(ParseException::class)
fun testHourlyRepeatAfterCompletion() {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTime(2017, 10, 4, 13, 30)),
with(COMPLETION_TIME, DateTime(2017, 10, 4, 13, 17, 45, 340)),
with(RECUR, "RRULE:FREQ=HOURLY;INTERVAL=6"),
with(AFTER_COMPLETE, true))
repeatAndVerify(
task, DateTime(2017, 10, 4, 13, 30, 1), DateTime(2017, 10, 4, 19, 17, 1))
}
@Test
@Throws(ParseException::class)
fun testDailyRepeat() {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTime(2017, 10, 4, 13, 30)),
with(RECUR, "RRULE:FREQ=DAILY;INTERVAL=6"))
repeatAndVerify(
task, DateTime(2017, 10, 4, 13, 30, 1), DateTime(2017, 10, 10, 13, 30, 1))
}
@Test
@Throws(ParseException::class)
fun testRepeatWeeklyNoDays() {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTime(2017, 10, 4, 13, 30)),
with(RECUR, "RRULE:FREQ=WEEKLY;INTERVAL=2"))
repeatAndVerify(
task, DateTime(2017, 10, 4, 13, 30, 1), DateTime(2017, 10, 18, 13, 30, 1))
}
@Test
@Throws(ParseException::class)
fun testYearly() {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTime(2017, 10, 4, 13, 30)),
with(RECUR, "RRULE:FREQ=YEARLY;INTERVAL=3"))
repeatAndVerify(
task, DateTime(2017, 10, 4, 13, 30, 1), DateTime(2020, 10, 4, 13, 30, 1))
}
@Test
@Throws(ParseException::class)
fun testMonthlyRepeat() {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTime(2017, 10, 4, 13, 30)),
with(RECUR, "RRULE:FREQ=MONTHLY;INTERVAL=3"))
repeatAndVerify(
task, DateTime(2017, 10, 4, 13, 30, 1), DateTime(2018, 1, 4, 13, 30, 1))
}
@Test
@Throws(ParseException::class)
fun testMonthlyRepeatAtEndOfMonth() {
val task = newTask(
with(ID, 1L),
with(DUE_TIME, DateTime(2017, 1, 31, 13, 30)),
with(RECUR, "RRULE:FREQ=MONTHLY;INTERVAL=1"))
repeatAndVerify(
task, DateTime(2017, 1, 31, 13, 30, 1), DateTime(2017, 2, 28, 13, 30, 1))
}
@Test
fun testAlarmShiftWithNoDueDate() {
val task = newTask(
with(ID, 1L),
with(RECUR, "RRULE:FREQ=DAILY")
)
freezeClock {
repeatAndVerify(
task,
Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, DateTime().millis),
Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, DateTime().plusDays(1).millis)
)
}
}
private fun repeatAndVerify(task: Task, oldDueDate: DateTime, newDueDate: DateTime) =
repeatAndVerify(task, oldDueDate.millis, newDueDate.millis)
private fun repeatAndVerify(task: Task, oldDueDate: Long, newDueDate: Long) = runBlockingTest {
helper.handleRepeat(task)
mocks.verify(gCalHelper).rescheduleRepeatingTask(task)
mocks.verify(alarmService).rescheduleAlarms(1, oldDueDate, newDueDate)
mocks.verify(localBroadcastManager).broadcastRepeat(1, oldDueDate, newDueDate)
}
}

@ -0,0 +1,80 @@
package com.todoroo.astrid.repeats
import com.natpryce.makeiteasy.MakeItEasy.with
import org.junit.Assert.*
import org.junit.Test
import org.tasks.Freeze.Companion.freezeAt
import org.tasks.makers.TaskMaker.COMPLETION_TIME
import org.tasks.repeats.RecurrenceUtils.newRecur
import org.tasks.time.DateTime
class RepeatTaskHelperTests : RepeatTests() {
@Test
fun shouldDecrementCount() {
val task = newFromDue(
"RRULE:FREQ=MINUTELY;COUNT=2;INTERVAL=30",
newDayTime(2017, 10, 4, 13, 30)
)
calculateNextDueDate(task)
assertEquals(1, newRecur(task.recurrence!!).count)
}
@Test
fun shouldUncompleteTask() {
val task = newFromDue(
"FREQ=DAILY;INTERVAL=1",
newDayTime(2017, 10, 4, 13, 30),
with(COMPLETION_TIME, DateTime())
)
calculateNextDueDate(task)
assertFalse(task.isCompleted)
}
@Test
fun dontAdjustOnLastInstance() {
val task = newFromDue(
"FREQ=MINUTELY;COUNT=1;INTERVAL=30",
newDayTime(2017, 10, 4, 13, 30),
with(COMPLETION_TIME, DateTime())
)
val next = calculateNextDueDate(task)
assertEquals(1, newRecur(task.recurrence!!).count)
assertEquals(newDayTime(2017, 10, 4, 13, 30), next)
assertTrue(task.isCompleted)
}
@Test
fun useCompletionWhenNoDue() {
val task = newFromDue(
"FREQ=DAILY;INTERVAL=1",
DateTime(0)
)
val next = freezeAt(DateTime(2021, 2, 1, 16, 54, 32, 451)) {
calculateNextDueDate(task)
}
assertEquals(newDay(2021, 2, 2), next)
}
@Test
fun useNowWhenNoCompletion() {
val task = newFromDue(
"FREQ=DAILY;INTERVAL=1",
newDay(2021, 3, 15),
afterComplete = true
)
val next = freezeAt(newDayTime(2021, 3, 29, 14, 32)) {
calculateNextDueDate(task)
}
assertEquals(newDayTime(2021, 3, 30, 12, 0), next)
}
}

@ -0,0 +1,57 @@
package com.todoroo.astrid.repeats
import com.natpryce.makeiteasy.MakeItEasy
import com.natpryce.makeiteasy.PropertyValue
import com.todoroo.astrid.alarms.AlarmService
import com.todoroo.astrid.dao.TaskDao
import com.todoroo.astrid.data.Task
import com.todoroo.astrid.gcal.GCalHelper
import com.todoroo.astrid.service.TaskCompleter
import kotlinx.coroutines.runBlocking
import org.mockito.Mockito
import org.tasks.LocalBroadcastManager
import org.tasks.makers.TaskMaker
import org.tasks.time.DateTime
abstract class RepeatTests {
private val helper = RepeatTaskHelper(
Mockito.mock(GCalHelper::class.java),
Mockito.mock(AlarmService::class.java),
Mockito.mock(TaskDao::class.java),
Mockito.mock(LocalBroadcastManager::class.java),
Mockito.mock(TaskCompleter::class.java)
)
protected fun newDay(year: Int, month: Int, day: Int) =
DateTime(
Task.createDueDate(
Task.URGENCY_SPECIFIC_DAY,
DateTime(year, month, day).millis
)
)
protected fun newDayTime(year: Int, month: Int, day: Int, hour: Int, minute: Int) =
DateTime(
Task.createDueDate(
Task.URGENCY_SPECIFIC_DAY_TIME,
DateTime(year, month, day, hour, minute).millis
)
)
protected fun calculateNextDueDate(task: Task): DateTime = runBlocking {
helper.handleRepeat(task)
DateTime(task.dueDate)
}
protected fun newFromDue(
recur: String,
due: DateTime,
vararg properties: PropertyValue<in Task?, *>,
afterComplete: Boolean = false
) = TaskMaker.newTask(
MakeItEasy.with(TaskMaker.RECUR, recur),
MakeItEasy.with(TaskMaker.AFTER_COMPLETE, afterComplete),
MakeItEasy.with(TaskMaker.DUE_TIME, due),
*properties
)
}

@ -0,0 +1,190 @@
package com.todoroo.astrid.repeats
import com.natpryce.makeiteasy.MakeItEasy.with
import org.junit.Assert.assertEquals
import org.junit.Test
import org.tasks.makers.TaskMaker.COMPLETION_TIME
class RepeatWeeklyTests : RepeatTests() {
@Test
fun testRepeatWeeklyFromDueDate() {
val task = newFromDue("FREQ=WEEKLY;INTERVAL=1", newDayTime(2016, 8, 28, 1, 34))
val next = calculateNextDueDate(task)
assertEquals(newDayTime(2016, 9, 4, 1, 34), next)
}
@Test
fun testRepeatBiWeekly() {
val task = newFromDue("FREQ=WEEKLY;INTERVAL=2", newDayTime(2016, 8, 28, 1, 34))
val next = calculateNextDueDate(task)
assertEquals(newDayTime(2016, 9, 11, 1, 34), next)
}
@Test
fun testRepeatWeeklyFromCompleteDateCompleteBefore() {
val task = newFromDue(
"FREQ=WEEKLY;INTERVAL=1",
newDayTime(2016, 8, 30, 0, 25),
with(COMPLETION_TIME, newDayTime(2016, 8, 29, 0, 14)),
afterComplete = true
)
val next = calculateNextDueDate(task)
assertEquals(newDayTime(2016, 9, 5, 0, 25), next)
}
@Test
fun testRepeatWeeklyFromCompleteDateCompleteAfter() {
val task = newFromDue(
"FREQ=WEEKLY;INTERVAL=1",
newDayTime(2016, 8, 28, 0, 4),
with(COMPLETION_TIME, newDayTime(2016, 8, 29, 0, 14)),
afterComplete = true
)
val next = calculateNextDueDate(task)
assertEquals(newDayTime(2016, 9, 5, 0, 4), next)
}
@Test
fun testWeeklyBySingleDayBefore() {
val task = newFromDue(
"FREQ=WEEKLY;INTERVAL=1;BYDAY=MO",
newDayTime(2016, 8, 28, 0, 25) // Sunday
)
val next = calculateNextDueDate(task)
assertEquals(newDayTime(2016, 8, 29, 0, 25), next)
}
@Test
fun testWeeklyBySingleDayOf() {
val task = newFromDue(
"FREQ=WEEKLY;INTERVAL=1;BYDAY=MO",
newDayTime(2016, 8, 29, 0, 25) // Monday
)
val next = calculateNextDueDate(task)
assertEquals(newDayTime(2016, 9, 5, 0, 25), next)
}
@Test
fun testWeeklyBySingleDayAfter() {
val task = newFromDue(
"FREQ=WEEKLY;INTERVAL=1;BYDAY=MO",
newDayTime(2016, 8, 30, 0, 25) // Sunday
)
val next = calculateNextDueDate(task)
assertEquals(newDayTime(2016, 9, 5, 0, 25), next)
}
@Test
fun testByDayBeforeFirstDate() {
val task = newFromDue(
"FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,WE",
newDayTime(2016, 8, 28, 0, 25) // Sunday
)
val next = calculateNextDueDate(task)
assertEquals(newDayTime(2016, 8, 29, 0, 25), next)
}
@Test
fun testAdvancedRepeatWeeklyOnFirstDate() {
val task = newFromDue(
"FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,WE",
newDayTime(2016, 8, 29, 0, 25) // Monday
)
val next = calculateNextDueDate(task)
assertEquals(newDayTime(2016, 8, 31, 0, 25), next)
}
@Test
fun testAdvancedRepeatWeeklyOnLastDate() {
val task = newFromDue(
"FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,WE",
newDayTime(2016, 8, 31, 0, 25) // Wednesday
)
val next = calculateNextDueDate(task)
assertEquals(newDayTime(2016, 9, 5, 0, 25), next)
}
@Test
fun testAdvancedRepeatWeeklyFromCompleteDateCompleteBefore() {
val task = newFromDue(
"FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,WE",
newDayTime(2016, 8, 29, 0, 25),
with(COMPLETION_TIME, newDayTime(2016, 8, 28, 1, 9)),
afterComplete = true
)
val next = calculateNextDueDate(task)
assertEquals(newDayTime(2016, 8, 29, 0, 25), next)
}
@Test
fun testAdvancedRepeatWeeklyFromCompleteDateCompleteAfter() {
val task = newFromDue(
"FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,WE",
newDayTime(2016, 8, 29, 0, 25),
with(COMPLETION_TIME, newDayTime(2016, 9, 1, 1, 9)),
afterComplete = true
)
val next = calculateNextDueDate(task)
assertEquals(newDayTime(2016, 9, 5, 0, 25), next)
}
@Test
fun biweeklyOnBeforeFirstDay() {
val task = newFromDue(
"FREQ=WEEKLY;INTERVAL=2;BYDAY=MO,WE",
newDayTime(2016, 8, 28, 0, 25), // Sunday
)
val next = calculateNextDueDate(task)
assertEquals(newDayTime(2016, 9, 5, 0, 25), next)
}
@Test
fun biweeklyOnFirstDay() {
val task = newFromDue(
"FREQ=WEEKLY;INTERVAL=2;BYDAY=MO,WE",
newDayTime(2016, 8, 29, 0, 25), // Monday
)
val next = calculateNextDueDate(task)
assertEquals(newDayTime(2016, 8, 31, 0, 25), next)
}
@Test
fun biweeklyOnLastDay() {
val task = newFromDue(
"FREQ=WEEKLY;INTERVAL=2;BYDAY=MO,WE",
newDayTime(2016, 8, 31, 0, 25), // Wednesday
)
val next = calculateNextDueDate(task)
assertEquals(newDayTime(2016, 9, 12, 0, 25), next)
}
}

@ -0,0 +1,45 @@
package com.todoroo.astrid.repeats
import com.natpryce.makeiteasy.MakeItEasy.with
import org.junit.Assert.assertEquals
import org.junit.Test
import org.tasks.makers.TaskMaker.COMPLETION_TIME
class RepeatYearlyTests : RepeatTests() {
@Test
fun testRepeatYearlyFromDueDate() {
val task = newFromDue("FREQ=YEARLY;INTERVAL=2", newDayTime(2016, 8, 28, 1, 44))
val next = calculateNextDueDate(task)
assertEquals(newDayTime(2018, 8, 28, 1, 44), next)
}
@Test
fun testRepeatYearlyFromCompleteDateCompleteBefore() {
val task = newFromDue(
"FREQ=YEARLY;INTERVAL=1",
newDayTime(2016, 8, 30, 0, 25),
with(COMPLETION_TIME, newDayTime(2016, 8, 29, 0, 14)),
afterComplete = true
)
val next = calculateNextDueDate(task)
assertEquals(newDayTime(2017, 8, 29, 0, 25), next)
}
@Test
fun testRepeatYearlyFromCompleteDateCompleteAfter() {
val task = newFromDue(
"FREQ=YEARLY;INTERVAL=1",
newDayTime(2016, 8, 28, 0, 4),
with(COMPLETION_TIME, newDayTime(2016, 8, 29, 0, 14)),
afterComplete = true
)
val next = calculateNextDueDate(task)
assertEquals(newDayTime(2017, 8, 29, 0, 4), next)
}
}
Loading…
Cancel
Save