Random reminder fixes

- Make random reminder calculation deterministic
- Don't fire reminders immediately on recurring tasks
pull/3995/head
Alex Baker 3 weeks ago
parent 40961dad87
commit 9190930745

@ -75,10 +75,16 @@ class AlarmCalculator(
*/ */
private fun calculateNextRandomReminder(random: Random, task: Task, reminderPeriod: Long) = private fun calculateNextRandomReminder(random: Random, task: Task, reminderPeriod: Long) =
if (reminderPeriod > 0) { if (reminderPeriod > 0) {
val baseline = when {
task.reminderLast > 0 -> task.reminderLast
task.isRecurring -> task.modificationDate
else -> task.creationDate
}
val multiplier = 0.85f + 0.3f * random.nextFloat(task.id + baseline)
maxOf( maxOf(
task.reminderLast baseline.plus((reminderPeriod * multiplier).toLong()),
.coerceAtLeast(task.creationDate)
.plus((reminderPeriod * (0.85f + 0.3f * random.nextFloat())).toLong()),
task.hideUntil task.hideUntil
) )
} else { } else {

@ -1,10 +0,0 @@
package org.tasks.reminders;
public class Random {
private static final java.util.Random random = new java.util.Random();
public float nextFloat() {
return random.nextFloat();
}
}

@ -0,0 +1,14 @@
package org.tasks.reminders
import java.util.Random
open class Random {
open fun nextFloat(seed: Long): Float {
random.setSeed(seed)
return random.nextFloat()
}
companion object {
private val random = Random()
}
}

@ -295,7 +295,7 @@ class AlarmCalculatorTest {
@Test @Test
fun scheduleOverdueRandomReminder() { fun scheduleOverdueRandomReminder() {
random.seed = 0.3865f random.stub = 0.3865f
freezeAt(now) { freezeAt(now) {
val alarm = alarmCalculator.toAlarmEntry( val alarm = alarmCalculator.toAlarmEntry(
newTask( newTask(
@ -316,7 +316,7 @@ class AlarmCalculatorTest {
@Test @Test
fun scheduleOverdueRandomReminderForHiddenTask() { fun scheduleOverdueRandomReminderForHiddenTask() {
random.seed = 0.3865f random.stub = 0.3865f
freezeAt(now) { freezeAt(now) {
val task = newTask( val task = newTask(
with(REMINDER_LAST, now.minusDays(14)), with(REMINDER_LAST, now.minusDays(14)),
@ -335,7 +335,7 @@ class AlarmCalculatorTest {
@Test @Test
fun scheduleInitialRandomReminder() { fun scheduleInitialRandomReminder() {
random.seed = 0.3865f random.stub = 0.3865f
freezeAt(now) { freezeAt(now) {
val alarm = alarmCalculator.toAlarmEntry( val alarm = alarmCalculator.toAlarmEntry(
@ -358,7 +358,7 @@ class AlarmCalculatorTest {
@Test @Test
fun scheduleNextRandomReminder() { fun scheduleNextRandomReminder() {
random.seed = 0.3865f random.stub = 0.3865f
freezeAt(now) { freezeAt(now) {
val alarm = alarmCalculator.toAlarmEntry( val alarm = alarmCalculator.toAlarmEntry(
@ -379,9 +379,28 @@ class AlarmCalculatorTest {
} }
} }
@Test
fun randomReminderIsDeterministic() {
val calculator = AlarmCalculator(
isDefaultDueTimeEnabled = true,
random = Random(),
defaultDueTime = TimeUnit.HOURS.toMillis(13).toInt(),
)
freezeAt(now) {
val task = newTask(with(CREATION_TIME, now.minusDays(1)))
val alarm = Alarm(time = ONE_WEEK, type = TYPE_RANDOM)
val first = calculator.toAlarmEntry(task, alarm)
val second = calculator.toAlarmEntry(task, alarm)
assertEquals(first, second)
}
}
internal class RandomStub : Random() { internal class RandomStub : Random() {
var seed = 1.0f var stub = 1.0f
override fun nextFloat() = seed override fun nextFloat(seed: Long) = this.stub
} }
} }
Loading…
Cancel
Save