diff --git a/wear/build.gradle b/wear/build.gradle index a4b592cf00..a7638ba42d 100644 --- a/wear/build.gradle +++ b/wear/build.gradle @@ -118,6 +118,7 @@ dependencies { implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-guava:$coroutines_version" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:$coroutines_version" + implementation "org.jetbrains.kotlinx:kotlinx-datetime:$kotlinx_datetime_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" // for old fashioned support-app version @@ -145,4 +146,4 @@ configurations { all { exclude group: 'androidx.lifecycle', module: 'lifecycle-viewmodel-ktx' } -} \ No newline at end of file +} diff --git a/wear/src/main/java/info/nightscout/androidaps/di/WearModule.kt b/wear/src/main/java/info/nightscout/androidaps/di/WearModule.kt index 1875954570..014b247cc8 100644 --- a/wear/src/main/java/info/nightscout/androidaps/di/WearModule.kt +++ b/wear/src/main/java/info/nightscout/androidaps/di/WearModule.kt @@ -3,11 +3,13 @@ package info.nightscout.androidaps.di import android.content.Context import dagger.Binds import dagger.Module +import dagger.Provides import dagger.android.HasAndroidInjector import info.nightscout.androidaps.WearApp import info.nightscout.rx.di.RxModule import info.nightscout.shared.di.SharedModule import info.nightscout.shared.impl.di.SharedImplModule +import kotlinx.datetime.Clock @Suppress("unused") @Module( @@ -27,5 +29,8 @@ open class WearModule { @Binds fun bindContext(aaps: WearApp): Context @Binds fun bindInjector(aaps: WearApp): HasAndroidInjector } + + @Provides + fun providesClock(): Clock = Clock.System } diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/WearUtil.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/WearUtil.kt index 3744ab2868..80885f87bf 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/WearUtil.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/WearUtil.kt @@ -5,9 +5,9 @@ import android.os.PowerManager import info.nightscout.annotations.OpenForTesting import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.LTag - import javax.inject.Inject import javax.inject.Singleton +import kotlinx.datetime.Clock /** * Created by andy on 3/5/19. @@ -16,25 +16,26 @@ import javax.inject.Singleton @Singleton @OpenForTesting open class WearUtil @Inject constructor( - open val context: Context, - open val aapsLogger: AAPSLogger + private val context: Context, + private val aapsLogger: AAPSLogger, + private val clock: Clock, ) { private val debugWakelocks = false - open val rateLimits: MutableMap = HashMap() + private val rateLimits: MutableMap = HashMap() //============================================================================================== // Time related util methods //============================================================================================== open fun timestamp(): Long { - return System.currentTimeMillis() + return clock.now().toEpochMilliseconds() } - fun msSince(`when`: Long): Long { + open fun msSince(`when`: Long): Long { return timestamp() - `when` } - fun msTill(`when`: Long): Long { + open fun msTill(`when`: Long): Long { return `when` - timestamp() } diff --git a/wear/src/test/java/info/nightscout/androidaps/WearTestBase.kt b/wear/src/test/java/info/nightscout/androidaps/WearTestBase.kt index 3b9c6ed7c9..0c04c2a324 100644 --- a/wear/src/test/java/info/nightscout/androidaps/WearTestBase.kt +++ b/wear/src/test/java/info/nightscout/androidaps/WearTestBase.kt @@ -6,44 +6,32 @@ import info.nightscout.androidaps.interaction.utils.Constants import info.nightscout.androidaps.interaction.utils.Persistence import info.nightscout.androidaps.interaction.utils.WearUtil import info.nightscout.androidaps.testing.mocks.SharedPreferencesMock -import info.nightscout.rx.logging.AAPSLogger import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.utils.DateUtil import info.nightscout.sharedtests.TestBase +import kotlinx.datetime.Clock +import kotlinx.datetime.Instant import org.junit.jupiter.api.BeforeEach import org.mockito.ArgumentMatchers import org.mockito.Mock import org.mockito.Mockito -class FakeWearUtil(context: Context, aapsLogger: AAPSLogger) : WearUtil(context, aapsLogger) { - private var clockMsDiff = 0L - - override fun timestamp(): Long = REF_NOW + clockMsDiff - - fun progressClock(byMilliseconds: Long) { - clockMsDiff += byMilliseconds - } - - companion object { - const val REF_NOW = 1572610530000L - } -} - open class WearTestBase : TestBase() { + private var clockNow: Long = REF_NOW @Mock lateinit var context: Context @Mock lateinit var sp: SP @Mock lateinit var dateUtil: DateUtil - lateinit var fakeWearUtil: FakeWearUtil + @Mock lateinit var clock: Clock + lateinit var wearUtil: WearUtil lateinit var persistence: Persistence private val mockedSharedPrefs: HashMap = HashMap() - @BeforeEach fun setup() { - fakeWearUtil = FakeWearUtil(context, aapsLogger) + wearUtil = WearUtil(context, aapsLogger, clock) Mockito.doAnswer { invocation -> val key = invocation.getArgument(0) if (mockedSharedPrefs.containsKey(key)) { @@ -54,12 +42,25 @@ open class WearTestBase : TestBase() { return@doAnswer newPrefs } }.`when`(context).getSharedPreferences(ArgumentMatchers.anyString(), ArgumentMatchers.anyInt()) + setClockNow() persistence = Mockito.spy(Persistence(aapsLogger, dateUtil, sp)) } + fun progressClock(byMilliseconds: Long) { + clockNow += byMilliseconds + setClockNow() + } + + private fun setClockNow() { + Mockito.`when`(clock.now()).thenReturn(Instant.fromEpochMilliseconds(clockNow)) + } + companion object { + + const val REF_NOW = 1572610530000L + fun backInTime(d: Int, h: Int, m: Int, s: Int): Long = - FakeWearUtil.REF_NOW - (Constants.DAY_IN_MS * d + Constants.HOUR_IN_MS * h + Constants.MINUTE_IN_MS * m + Constants.SECOND_IN_MS * s) + REF_NOW - (Constants.DAY_IN_MS * d + Constants.HOUR_IN_MS * h + Constants.MINUTE_IN_MS * m + Constants.SECOND_IN_MS * s) } } diff --git a/wear/src/test/java/info/nightscout/androidaps/interaction/utils/DisplayFormatTest.kt b/wear/src/test/java/info/nightscout/androidaps/interaction/utils/DisplayFormatTest.kt index 6ce2cce75f..e2a0934f21 100644 --- a/wear/src/test/java/info/nightscout/androidaps/interaction/utils/DisplayFormatTest.kt +++ b/wear/src/test/java/info/nightscout/androidaps/interaction/utils/DisplayFormatTest.kt @@ -22,7 +22,7 @@ class DisplayFormatTest : WearTestBase() { fun mock() { rawDataMocker = RawDataMocker() displayFormat = DisplayFormat() - displayFormat.wearUtil = fakeWearUtil + displayFormat.wearUtil = wearUtil displayFormat.sp = sp displayFormat.context = context Mockito.`when`(sp.getBoolean("complication_unicode", true)).thenReturn(true) diff --git a/wear/src/test/java/info/nightscout/androidaps/interaction/utils/WearUtilTest.kt b/wear/src/test/java/info/nightscout/androidaps/interaction/utils/WearUtilTest.kt index 3c88639184..1350669279 100644 --- a/wear/src/test/java/info/nightscout/androidaps/interaction/utils/WearUtilTest.kt +++ b/wear/src/test/java/info/nightscout/androidaps/interaction/utils/WearUtilTest.kt @@ -1,7 +1,6 @@ package info.nightscout.androidaps.interaction.utils import com.google.common.truth.Truth.assertThat -import info.nightscout.androidaps.FakeWearUtil import info.nightscout.androidaps.WearTestBase import org.junit.jupiter.api.Test @@ -14,13 +13,13 @@ class WearUtilTest : WearTestBase() { @Test fun timestampAndTimeDiffsTest() { // smoke for mocks - since we freeze "now" to get stable tests - assertThat(fakeWearUtil.timestamp()).isEqualTo(FakeWearUtil.REF_NOW) - assertThat(fakeWearUtil.msTill(FakeWearUtil.REF_NOW)).isEqualTo(0L) - assertThat(fakeWearUtil.msTill(FakeWearUtil.REF_NOW + 3456L)).isEqualTo(3456L) - assertThat(fakeWearUtil.msTill(FakeWearUtil.REF_NOW - 6294L)).isEqualTo(-6294L) - assertThat(fakeWearUtil.msTill(FakeWearUtil.REF_NOW)).isEqualTo(0L) - assertThat(fakeWearUtil.msSince(FakeWearUtil.REF_NOW + 3456L)).isEqualTo(-3456L) - assertThat(fakeWearUtil.msSince(FakeWearUtil.REF_NOW - 6294L)).isEqualTo(6294L) + assertThat(wearUtil.timestamp()).isEqualTo(REF_NOW) + assertThat(wearUtil.msTill(REF_NOW)).isEqualTo(0L) + assertThat(wearUtil.msTill(REF_NOW + 3456L)).isEqualTo(3456L) + assertThat(wearUtil.msTill(REF_NOW - 6294L)).isEqualTo(-6294L) + assertThat(wearUtil.msTill(REF_NOW)).isEqualTo(0L) + assertThat(wearUtil.msSince(REF_NOW + 3456L)).isEqualTo(-3456L) + assertThat(wearUtil.msSince(REF_NOW - 6294L)).isEqualTo(6294L) } @Test fun joinSetTest() { @@ -99,12 +98,12 @@ class WearUtilTest : WearTestBase() { */ @Test fun rateLimitTest() { // WHEN - val firstCall = fakeWearUtil.isBelowRateLimit("test-limit", 3) - val callAfterward = fakeWearUtil.isBelowRateLimit("test-limit", 3) - fakeWearUtil.progressClock(500L) - val callTooSoon = fakeWearUtil.isBelowRateLimit("test-limit", 3) - fakeWearUtil.progressClock(3100L) - val callAfterRateLimit = fakeWearUtil.isBelowRateLimit("test-limit", 3) + val firstCall = wearUtil.isBelowRateLimit("test-limit", 3) + val callAfterward = wearUtil.isBelowRateLimit("test-limit", 3) + progressClock(500L) + val callTooSoon = wearUtil.isBelowRateLimit("test-limit", 3) + progressClock(3100L) + val callAfterRateLimit = wearUtil.isBelowRateLimit("test-limit", 3) // THEN assertThat(firstCall).isTrue()