mirror of
https://github.com/d4rken-org/capod.git
synced 2026-09-15 10:46:12 -04:00
Refactor time access behind TimeSource
This commit is contained in:
@@ -1,41 +1,35 @@
|
||||
package eu.darken.capod.common
|
||||
|
||||
import android.media.AudioManager
|
||||
import android.os.SystemClock
|
||||
import io.mockk.Runs
|
||||
import io.mockk.clearMocks
|
||||
import io.mockk.every
|
||||
import io.mockk.just
|
||||
import io.mockk.mockk
|
||||
import io.mockk.mockkStatic
|
||||
import io.mockk.unmockkStatic
|
||||
import io.mockk.verify
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.Assertions.assertFalse
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import testhelpers.BaseTest
|
||||
import testhelpers.TestTimeSource
|
||||
|
||||
class MediaControlTest : BaseTest() {
|
||||
|
||||
private lateinit var audioManager: AudioManager
|
||||
private lateinit var mediaControl: MediaControl
|
||||
private lateinit var timeSource: TestTimeSource
|
||||
|
||||
@BeforeEach
|
||||
fun setup() {
|
||||
mockkStatic(SystemClock::class)
|
||||
every { SystemClock.elapsedRealtime() } returns 1_000L
|
||||
every { SystemClock.uptimeMillis() } returns 1_000L
|
||||
timeSource = TestTimeSource(
|
||||
elapsedRealtimeMs = 1_000L,
|
||||
uptimeMillisValue = 1_000L,
|
||||
)
|
||||
audioManager = mockk(relaxed = true)
|
||||
every { audioManager.dispatchMediaKeyEvent(any()) } just Runs
|
||||
mediaControl = MediaControl(audioManager)
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
fun teardown() {
|
||||
unmockkStatic(SystemClock::class)
|
||||
mediaControl = MediaControl(audioManager, timeSource)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+4
@@ -1,5 +1,6 @@
|
||||
package eu.darken.capod.main.ui.devicesettings
|
||||
|
||||
import eu.darken.capod.common.TimeSource
|
||||
import eu.darken.capod.common.bluetooth.BluetoothAddress
|
||||
import eu.darken.capod.common.bluetooth.BluetoothDevice2
|
||||
import eu.darken.capod.common.bluetooth.BluetoothManager2
|
||||
@@ -36,6 +37,7 @@ import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.extension.ExtendWith
|
||||
import testhelpers.BaseTest
|
||||
import testhelpers.TestTimeSource
|
||||
import testhelpers.coroutine.TestDispatcherProvider
|
||||
import testhelpers.livedata.InstantExecutorExtension
|
||||
|
||||
@@ -53,6 +55,7 @@ class DeviceSettingsViewModelTest : BaseTest() {
|
||||
private lateinit var bluetoothManager: BluetoothManager2
|
||||
private lateinit var profilesRepo: DeviceProfilesRepo
|
||||
private lateinit var generalSettings: GeneralSettings
|
||||
private val timeSource: TimeSource = TestTimeSource()
|
||||
|
||||
private lateinit var devicesFlow: MutableStateFlow<List<PodDevice>>
|
||||
private lateinit var upgradeInfoFlow: MutableStateFlow<UpgradeRepo.Info>
|
||||
@@ -107,6 +110,7 @@ class DeviceSettingsViewModelTest : BaseTest() {
|
||||
bluetoothManager = bluetoothManager,
|
||||
profilesRepo = profilesRepo,
|
||||
generalSettings = generalSettings,
|
||||
timeSource = timeSource,
|
||||
)
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package eu.darken.capod.main.ui.overview
|
||||
|
||||
import eu.darken.capod.common.TimeSource
|
||||
import eu.darken.capod.common.bluetooth.BluetoothDevice2
|
||||
import eu.darken.capod.common.bluetooth.BluetoothManager2
|
||||
import eu.darken.capod.common.debug.DebugSettings
|
||||
@@ -34,6 +35,7 @@ import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.extension.ExtendWith
|
||||
import testhelpers.BaseTest
|
||||
import testhelpers.TestTimeSource
|
||||
import testhelpers.coroutine.TestDispatcherProvider
|
||||
import testhelpers.datastore.FakeDataStoreValue
|
||||
import testhelpers.livedata.InstantExecutorExtension
|
||||
@@ -52,6 +54,7 @@ class OverviewViewModelTest : BaseTest() {
|
||||
private lateinit var upgradeRepo: UpgradeRepo
|
||||
private lateinit var bluetoothManager: BluetoothManager2
|
||||
private lateinit var profilesRepo: DeviceProfilesRepo
|
||||
private val timeSource: TimeSource = TestTimeSource()
|
||||
|
||||
private lateinit var missingPermissionsFlow: MutableStateFlow<Set<Permission>>
|
||||
private lateinit var devicesFlow: MutableStateFlow<List<PodDevice>>
|
||||
@@ -126,6 +129,7 @@ class OverviewViewModelTest : BaseTest() {
|
||||
bluetoothManager = bluetoothManager,
|
||||
profilesRepo = profilesRepo,
|
||||
aapManager = mockk(relaxed = true),
|
||||
timeSource = timeSource,
|
||||
)
|
||||
|
||||
@Nested
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package eu.darken.capod.monitor.core
|
||||
|
||||
import eu.darken.capod.common.TimeSource
|
||||
import eu.darken.capod.common.bluetooth.BluetoothAddress
|
||||
import eu.darken.capod.monitor.core.aap.AapLifecycleManager
|
||||
import eu.darken.capod.monitor.core.ble.BlePodMonitor
|
||||
@@ -26,12 +27,14 @@ import kotlinx.coroutines.test.UnconfinedTestDispatcher
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.Test
|
||||
import testhelpers.BaseTest
|
||||
import testhelpers.TestTimeSource
|
||||
import java.time.Instant
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class DeviceMonitorTest : BaseTest() {
|
||||
|
||||
private val testDispatcher = UnconfinedTestDispatcher()
|
||||
private val timeSource: TimeSource = TestTimeSource(wallNow = Instant.parse("2026-04-05T18:00:00Z"))
|
||||
|
||||
private val testAddress: BluetoothAddress = "AA:BB:CC:DD:EE:FF"
|
||||
private val testProfile = AppleDeviceProfile(
|
||||
@@ -135,6 +138,7 @@ class DeviceMonitorTest : BaseTest() {
|
||||
deviceStateCache = deviceStateCache,
|
||||
profilesRepo = profilesRepo,
|
||||
aapLifecycleManager = aapLifecycleManager,
|
||||
timeSource = timeSource,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package eu.darken.capod.pods.core.apple.aap
|
||||
|
||||
import android.bluetooth.BluetoothDevice
|
||||
import android.bluetooth.BluetoothSocket
|
||||
import eu.darken.capod.common.TimeSource
|
||||
import eu.darken.capod.common.bluetooth.l2cap.L2capSocketFactory
|
||||
import eu.darken.capod.pods.core.apple.PodModel
|
||||
import eu.darken.capod.pods.core.apple.aap.protocol.AapCommand
|
||||
@@ -20,6 +21,7 @@ import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.Test
|
||||
import testhelpers.BaseTest
|
||||
import testhelpers.TestTimeSource
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.IOException
|
||||
@@ -32,6 +34,7 @@ class AapConnectionManagerTest : BaseTest() {
|
||||
|
||||
private lateinit var socketFactory: L2capSocketFactory
|
||||
private lateinit var manager: AapConnectionManager
|
||||
private val timeSource: TimeSource = TestTimeSource()
|
||||
|
||||
private val testAddress = "AA:BB:CC:DD:EE:FF"
|
||||
private val testDevice: BluetoothDevice = mockk(relaxed = true) {
|
||||
@@ -44,6 +47,7 @@ class AapConnectionManagerTest : BaseTest() {
|
||||
manager = AapConnectionManager(
|
||||
socketFactory = socketFactory,
|
||||
scope = testScope,
|
||||
timeSource = timeSource,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package eu.darken.capod.pods.core.apple.ble.devices
|
||||
|
||||
import dagger.BindsInstance
|
||||
import dagger.Component
|
||||
import eu.darken.capod.common.SystemClockWrap
|
||||
import eu.darken.capod.common.bluetooth.BleScanResult
|
||||
import eu.darken.capod.common.fromHex
|
||||
import eu.darken.capod.common.serialization.SerializationModule
|
||||
@@ -15,9 +14,6 @@ import eu.darken.capod.profiles.core.DeviceProfilesRepo
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.mockkObject
|
||||
import io.mockk.unmockkObject
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import testhelpers.BaseTest
|
||||
@@ -59,14 +55,6 @@ abstract class BaseBlePodsTest : BaseTest() {
|
||||
@BeforeEach
|
||||
fun setup() {
|
||||
MockKAnnotations.init(this)
|
||||
|
||||
mockkObject(SystemClockWrap)
|
||||
every { SystemClockWrap.elapsedRealtimeNanos } returns 1000L
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
fun teardown() {
|
||||
unmockkObject(SystemClockWrap)
|
||||
}
|
||||
|
||||
internal suspend inline fun <reified T : BlePodSnapshot?> create(
|
||||
@@ -75,7 +63,7 @@ abstract class BaseBlePodsTest : BaseTest() {
|
||||
block: T.() -> Unit
|
||||
) {
|
||||
val result = BleScanResult(
|
||||
receivedAt = Instant.now(),
|
||||
receivedAt = Instant.parse("2026-01-01T00:00:00Z"),
|
||||
address = address,
|
||||
rssi = -66,
|
||||
generatedAtNanos = 136136027721826,
|
||||
|
||||
@@ -7,6 +7,7 @@ import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.Test
|
||||
import testhelpers.BaseTest
|
||||
import testhelpers.TestTimeSource
|
||||
import java.time.Duration
|
||||
import java.time.Instant
|
||||
|
||||
@@ -19,6 +20,7 @@ class PopUpReactionLogicTest : BaseTest() {
|
||||
popUpReaction = PopUpReaction(
|
||||
deviceMonitor = mockk(relaxed = true),
|
||||
bluetoothManager = mockk(relaxed = true),
|
||||
timeSource = TestTimeSource(),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package testhelpers
|
||||
|
||||
import eu.darken.capod.common.TimeSource
|
||||
import java.time.Duration
|
||||
import java.time.Instant
|
||||
|
||||
class TestTimeSource(
|
||||
var wallNow: Instant = Instant.parse("2026-01-01T00:00:00Z"),
|
||||
var elapsedRealtimeMs: Long = 0L,
|
||||
var elapsedRealtimeNanosValue: Long = 0L,
|
||||
var uptimeMillisValue: Long = 0L,
|
||||
) : TimeSource {
|
||||
|
||||
override fun now(): Instant = wallNow
|
||||
|
||||
override fun currentTimeMillis(): Long = wallNow.toEpochMilli()
|
||||
|
||||
override fun elapsedRealtime(): Long = elapsedRealtimeMs
|
||||
|
||||
override fun elapsedRealtimeNanos(): Long = elapsedRealtimeNanosValue
|
||||
|
||||
override fun uptimeMillis(): Long = uptimeMillisValue
|
||||
|
||||
fun advanceBy(duration: Duration) {
|
||||
wallNow = wallNow.plus(duration)
|
||||
elapsedRealtimeMs += duration.toMillis()
|
||||
elapsedRealtimeNanosValue += duration.toNanos()
|
||||
uptimeMillisValue += duration.toMillis()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user