Merge pull request #1108 from sgallese/feature/midnight-timer-remove-jvm

Place MidnightTimer under test
pull/1139/head
Alinson S. Xavier 4 years ago committed by GitHub
commit 87f071b5b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -36,10 +36,15 @@ abstract class DateUtils {
private var startDayHourOffset: Int = 0
private var startDayMinuteOffset: Int = 0
/**
* Number of milliseconds in one second.
*/
const val SECOND_LENGTH: Long = 1000
/**
* Number of milliseconds in one minute.
*/
const val MINUTE_LENGTH: Long = 60 * 1000
const val MINUTE_LENGTH: Long = 60 * SECOND_LENGTH
/**
* Number of milliseconds in one hour.

@ -33,31 +33,39 @@ open class MidnightTimer @Inject constructor() {
private val listeners: MutableList<MidnightListener> = LinkedList()
private lateinit var executor: ScheduledExecutorService
@Synchronized fun addListener(listener: MidnightListener) {
@Synchronized
fun addListener(listener: MidnightListener) {
this.listeners.add(listener)
}
@Synchronized fun onPause(): MutableList<Runnable>? = executor.shutdownNow()
@Synchronized
fun onPause(): MutableList<Runnable>? = executor.shutdownNow()
@Synchronized fun onResume() {
executor = Executors.newSingleThreadScheduledExecutor()
@Synchronized
fun onResume(
delayOffsetInMillis: Long = DateUtils.SECOND_LENGTH,
testExecutor: ScheduledExecutorService? = null
) {
executor = testExecutor ?: Executors.newSingleThreadScheduledExecutor()
executor.scheduleAtFixedRate(
{ notifyListeners() },
DateUtils.millisecondsUntilTomorrowWithOffset() + 1000,
DateUtils.millisecondsUntilTomorrowWithOffset() + delayOffsetInMillis,
DateUtils.DAY_LENGTH,
TimeUnit.MILLISECONDS
)
}
@Synchronized fun removeListener(listener: MidnightListener) = this.listeners.remove(listener)
@Synchronized
fun removeListener(listener: MidnightListener) = this.listeners.remove(listener)
@Synchronized private fun notifyListeners() {
@Synchronized
private fun notifyListeners() {
for (l in listeners) {
l.atMidnight()
}
}
interface MidnightListener {
fun interface MidnightListener {
fun atMidnight()
}
}

@ -95,15 +95,13 @@ open class BaseUnitTest {
}
fun unixTime(year: Int, month: Int, day: Int): Long {
val cal = getStartOfTodayCalendar()
cal.set(year, month, day, 0, 0, 0)
return cal.timeInMillis
return unixTime(year, month, day, 0, 0)
}
open fun unixTime(year: Int, month: Int, day: Int, hour: Int, minute: Int): Long {
open fun unixTime(year: Int, month: Int, day: Int, hour: Int, minute: Int, milliseconds: Long = 0): Long {
val cal = getStartOfTodayCalendar()
cal.set(year, month, day, hour, minute)
return cal.timeInMillis
return cal.timeInMillis + milliseconds
}
fun timestamp(year: Int, month: Int, day: Int): Timestamp {

@ -138,7 +138,7 @@ class ReminderSchedulerTest : BaseUnitTest() {
reminderScheduler.schedule(habit)
}
override fun unixTime(year: Int, month: Int, day: Int, hour: Int, minute: Int): Long {
override fun unixTime(year: Int, month: Int, day: Int, hour: Int, minute: Int, milliseconds: Long): Long {
val cal: Calendar = getStartOfTodayCalendar()
cal[year, month, day, hour] = minute
return cal.timeInMillis

@ -0,0 +1,48 @@
package org.isoron.uhabits.core.utils
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import org.isoron.uhabits.core.BaseUnitTest
import org.junit.Test
import java.util.Calendar
import java.util.TimeZone
import java.util.concurrent.Executors
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
import kotlin.test.assertEquals
class MidnightTimerTest : BaseUnitTest() {
@Test
fun testMidnightTimer_notifyListener_atMidnight() = runBlocking {
// Given
val executor = Executors.newSingleThreadScheduledExecutor()
val dispatcher = executor.asCoroutineDispatcher()
withContext(dispatcher) {
DateUtils.setFixedTimeZone(TimeZone.getTimeZone("GMT"))
DateUtils.setFixedLocalTime(
unixTime(
2017,
Calendar.JANUARY,
1,
23,
59,
DateUtils.MINUTE_LENGTH - 1
)
)
val suspendedListener = suspendCoroutine<Boolean> { continuation ->
MidnightTimer().apply {
addListener { continuation.resume(true) }
// When
onResume(1, executor)
}
}
// Then
assertEquals(true, suspendedListener)
}
}
}
Loading…
Cancel
Save