test: make viewmodel and notification receiver tests deterministic (#1207)
This commit is contained in:
9 files changed
+52
-66
No files matched your search
@@ -70,19 +70,12 @@ class CronJobsViewModelTest {
|
||||
|
||||
private fun createViewModel(): CronJobsViewModel {
|
||||
val vm = CronJobsViewModel()
|
||||
vm.ioDispatcher = testDispatcher
|
||||
testDispatcher.scheduler.advanceUntilIdle()
|
||||
return vm
|
||||
}
|
||||
|
||||
/**
|
||||
* Pump the test scheduler while letting the real Dispatchers.IO hops
|
||||
* (safeLaunchLoad / withContext(IO)) land their resumptions.
|
||||
*/
|
||||
private fun settle() {
|
||||
repeat(20) {
|
||||
testDispatcher.scheduler.advanceUntilIdle()
|
||||
Thread.sleep(10)
|
||||
}
|
||||
testDispatcher.scheduler.advanceUntilIdle()
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ import com.m57.hermescontrol.data.model.KanbanTask
|
||||
import com.m57.hermescontrol.data.model.UpdateTaskResponse
|
||||
import com.m57.hermescontrol.data.remote.ApiClient
|
||||
import com.m57.hermescontrol.data.remote.KanbanApiService
|
||||
import com.m57.hermescontrol.data.repository.KanbanDispatcherNudger
|
||||
import com.m57.hermescontrol.data.repository.KanbanRepositoryImpl
|
||||
import com.m57.hermescontrol.data.ws.KanbanEvent
|
||||
import com.m57.hermescontrol.data.ws.KanbanEventsClient
|
||||
import com.m57.hermescontrol.data.ws.KanbanEventsEnvelope
|
||||
@@ -42,20 +44,24 @@ class KanbanViewModelTest {
|
||||
private val mockEventsClient = mockk<KanbanEventsClient>(relaxed = true)
|
||||
|
||||
private fun createViewModel(): KanbanViewModel {
|
||||
val vm = KanbanViewModel(eventsClientProvider = { mockEventsClient })
|
||||
val mockNudger = mockk<KanbanDispatcherNudger>(relaxed = true)
|
||||
val repo =
|
||||
KanbanRepositoryImpl(
|
||||
apiProvider = { mockApi },
|
||||
ioDispatcher = testDispatcher,
|
||||
nudger = mockNudger,
|
||||
)
|
||||
val vm =
|
||||
KanbanViewModel(
|
||||
repository = repo,
|
||||
eventsClientProvider = { mockEventsClient },
|
||||
)
|
||||
vm.ioDispatcher = testDispatcher
|
||||
testDispatcher.scheduler.advanceUntilIdle()
|
||||
return vm
|
||||
}
|
||||
|
||||
/**
|
||||
* Pump the test scheduler while letting the real Dispatchers.IO hops
|
||||
* (safeLaunchLoad / withContext(IO)) land their resumptions.
|
||||
*/
|
||||
private fun settle() {
|
||||
repeat(20) {
|
||||
testDispatcher.scheduler.advanceUntilIdle()
|
||||
Thread.sleep(10)
|
||||
}
|
||||
testDispatcher.scheduler.advanceUntilIdle()
|
||||
}
|
||||
|
||||
|
||||
@@ -26,15 +26,7 @@ class LogsViewModelTest {
|
||||
private val testDispatcher = StandardTestDispatcher()
|
||||
private val mockApi = mockk<HermesApiService>(relaxed = true)
|
||||
|
||||
/**
|
||||
* Pump the test scheduler while letting the real Dispatchers.IO hops
|
||||
* (safeLaunchLoad / withContext(IO)) land their resumptions.
|
||||
*/
|
||||
private fun settle() {
|
||||
repeat(20) {
|
||||
testDispatcher.scheduler.advanceUntilIdle()
|
||||
Thread.sleep(10)
|
||||
}
|
||||
testDispatcher.scheduler.advanceUntilIdle()
|
||||
}
|
||||
|
||||
|
||||
@@ -36,19 +36,12 @@ class PairingViewModelTest {
|
||||
|
||||
private fun createViewModel(): PairingViewModel {
|
||||
val vm = PairingViewModel()
|
||||
vm.ioDispatcher = testDispatcher
|
||||
testDispatcher.scheduler.advanceUntilIdle()
|
||||
return vm
|
||||
}
|
||||
|
||||
/**
|
||||
* Pump the test scheduler while letting the real Dispatchers.IO hops
|
||||
* (safeLaunchLoad / withContext(IO)) land their resumptions.
|
||||
*/
|
||||
private fun settle() {
|
||||
repeat(20) {
|
||||
testDispatcher.scheduler.advanceUntilIdle()
|
||||
Thread.sleep(10)
|
||||
}
|
||||
testDispatcher.scheduler.advanceUntilIdle()
|
||||
}
|
||||
|
||||
|
||||
@@ -35,15 +35,9 @@ class SkillsViewModelTest {
|
||||
private val mockApi = mockk<HermesApiService>(relaxed = true)
|
||||
private val app = mockk<Application>(relaxed = true)
|
||||
|
||||
/**
|
||||
* Pump the test scheduler while letting the real Dispatchers.IO hops
|
||||
* (safeLaunchLoad / withContext(IO)) land their resumptions.
|
||||
*/
|
||||
private fun createViewModel(): SkillsViewModel = SkillsViewModel(app).also { it.ioDispatcher = testDispatcher }
|
||||
|
||||
private fun settle() {
|
||||
repeat(20) {
|
||||
testDispatcher.scheduler.advanceUntilIdle()
|
||||
Thread.sleep(10)
|
||||
}
|
||||
testDispatcher.scheduler.advanceUntilIdle()
|
||||
}
|
||||
|
||||
@@ -105,7 +99,7 @@ class SkillsViewModelTest {
|
||||
@Test
|
||||
fun `loadHubSources stores sources and featured skills`() {
|
||||
coEvery { mockApi.getSkillHubSources() } returns Response.success(sourcesResponse)
|
||||
val vm = SkillsViewModel(app)
|
||||
val vm = createViewModel()
|
||||
vm.loadHubSources()
|
||||
settle()
|
||||
|
||||
@@ -122,7 +116,7 @@ class SkillsViewModelTest {
|
||||
404,
|
||||
"""{"detail":"Hub sources unavailable"}""".toResponseBody("application/json".toMediaTypeOrNull()),
|
||||
)
|
||||
val vm = SkillsViewModel(app)
|
||||
val vm = createViewModel()
|
||||
vm.loadHubSources()
|
||||
settle()
|
||||
|
||||
@@ -137,7 +131,7 @@ class SkillsViewModelTest {
|
||||
@Test
|
||||
fun `setViewMode HUB triggers sources load when landing is empty`() {
|
||||
coEvery { mockApi.getSkillHubSources() } returns Response.success(sourcesResponse)
|
||||
val vm = SkillsViewModel(app)
|
||||
val vm = createViewModel()
|
||||
vm.setViewMode(SkillsViewMode.HUB)
|
||||
settle()
|
||||
|
||||
@@ -149,7 +143,7 @@ class SkillsViewModelTest {
|
||||
fun `scanHubSkill stores the scan result for the identifier`() {
|
||||
coEvery { mockApi.scanHubSkill(identifier = "hermes-index:web-research") } returns
|
||||
Response.success(scanResponse)
|
||||
val vm = SkillsViewModel(app)
|
||||
val vm = createViewModel()
|
||||
vm.scanHubSkill("hermes-index:web-research")
|
||||
settle()
|
||||
|
||||
@@ -166,7 +160,7 @@ class SkillsViewModelTest {
|
||||
404,
|
||||
"""{"detail":"Skill not found"}""".toResponseBody("application/json".toMediaTypeOrNull()),
|
||||
)
|
||||
val vm = SkillsViewModel(app)
|
||||
val vm = createViewModel()
|
||||
vm.scanHubSkill("broken:skill")
|
||||
settle()
|
||||
|
||||
@@ -178,7 +172,7 @@ class SkillsViewModelTest {
|
||||
|
||||
@Test
|
||||
fun `scanHubSkill ignores blank identifiers`() {
|
||||
val vm = SkillsViewModel(app)
|
||||
val vm = createViewModel()
|
||||
vm.scanHubSkill(" ")
|
||||
settle()
|
||||
|
||||
@@ -190,7 +184,7 @@ class SkillsViewModelTest {
|
||||
fun `clearHubScan resets scan state`() {
|
||||
coEvery { mockApi.scanHubSkill(identifier = "hermes-index:web-research") } returns
|
||||
Response.success(scanResponse)
|
||||
val vm = SkillsViewModel(app)
|
||||
val vm = createViewModel()
|
||||
vm.scanHubSkill("hermes-index:web-research")
|
||||
settle()
|
||||
vm.clearHubScan()
|
||||
|
||||
Reference in new issue
Block a user