Make runBlocking crash when used on main thread

pull/1051/head
Alex Baker 4 years ago
parent e4b2dc932e
commit a2776b960e

@ -10,6 +10,8 @@ import com.todoroo.astrid.service.TaskDeleter
import com.todoroo.astrid.service.TaskMover import com.todoroo.astrid.service.TaskMover
import com.todoroo.astrid.timers.TimerPlugin import com.todoroo.astrid.timers.TimerPlugin
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import org.junit.Before import org.junit.Before
import org.tasks.calendars.CalendarEventProvider import org.tasks.calendars.CalendarEventProvider
import org.tasks.injection.InjectingTestCase import org.tasks.injection.InjectingTestCase
@ -61,4 +63,8 @@ open class BaseTaskEditViewModelTest : InjectingTestCase() {
db.alarmDao, db.alarmDao,
alarmService) alarmService)
} }
protected fun save(): Boolean = runBlocking(Dispatchers.Main) {
viewModel.save()
}
} }

@ -1,11 +1,9 @@
package org.tasks.ui.editviewmodel package org.tasks.ui.editviewmodel
import androidx.test.annotation.UiThreadTest
import com.natpryce.makeiteasy.MakeItEasy import com.natpryce.makeiteasy.MakeItEasy
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.HiltAndroidTest
import dagger.hilt.android.testing.UninstallModules import dagger.hilt.android.testing.UninstallModules
import kotlinx.coroutines.runBlocking
import org.junit.Assert import org.junit.Assert
import org.junit.Test import org.junit.Test
import org.tasks.injection.ProductionModule import org.tasks.injection.ProductionModule
@ -24,13 +22,12 @@ class PriorityTests : BaseTaskEditViewModelTest() {
} }
@Test @Test
@UiThreadTest fun applyPriorityChange() {
fun applyPriorityChange() = runBlocking {
val task = TaskMaker.newTask(MakeItEasy.with(TaskMaker.PRIORITY, Task.Priority.HIGH)) val task = TaskMaker.newTask(MakeItEasy.with(TaskMaker.PRIORITY, Task.Priority.HIGH))
viewModel.setup(task) viewModel.setup(task)
viewModel.priority = Task.Priority.MEDIUM viewModel.priority = Task.Priority.MEDIUM
viewModel.save() save()
Assert.assertEquals(Task.Priority.MEDIUM, task.priority) Assert.assertEquals(Task.Priority.MEDIUM, task.priority)
} }

@ -1,6 +1,5 @@
package org.tasks.ui.editviewmodel package org.tasks.ui.editviewmodel
import androidx.test.annotation.UiThreadTest
import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.HiltAndroidTest
import dagger.hilt.android.testing.UninstallModules import dagger.hilt.android.testing.UninstallModules
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
@ -14,76 +13,76 @@ import org.tasks.makers.TaskMaker.newTask
@HiltAndroidTest @HiltAndroidTest
class ReminderTests : BaseTaskEditViewModelTest() { class ReminderTests : BaseTaskEditViewModelTest() {
@Test @Test
@UiThreadTest
fun whenDueReminder() = runBlocking { fun whenDueReminder() = runBlocking {
val task = newTask() val task = newTask()
viewModel.setup(task) viewModel.setup(task)
viewModel.whenDue = true viewModel.whenDue = true
viewModel.save()
save()
assertTrue(taskDao.fetch(task.id)!!.isNotifyAtDeadline) assertTrue(taskDao.fetch(task.id)!!.isNotifyAtDeadline)
} }
@Test @Test
@UiThreadTest
fun whenOverDueReminder() = runBlocking { fun whenOverDueReminder() = runBlocking {
val task = newTask() val task = newTask()
viewModel.setup(task) viewModel.setup(task)
viewModel.whenOverdue = true viewModel.whenOverdue = true
viewModel.save()
save()
assertTrue(taskDao.fetch(task.id)!!.isNotifyAfterDeadline) assertTrue(taskDao.fetch(task.id)!!.isNotifyAfterDeadline)
} }
@Test @Test
@UiThreadTest
fun ringFiveTimes() = runBlocking { fun ringFiveTimes() = runBlocking {
val task = newTask() val task = newTask()
viewModel.setup(task) viewModel.setup(task)
viewModel.ringFiveTimes = true viewModel.ringFiveTimes = true
viewModel.save()
save()
assertTrue(taskDao.fetch(task.id)!!.isNotifyModeFive) assertTrue(taskDao.fetch(task.id)!!.isNotifyModeFive)
} }
@Test @Test
@UiThreadTest
fun ringNonstop() = runBlocking { fun ringNonstop() = runBlocking {
val task = newTask() val task = newTask()
viewModel.setup(task) viewModel.setup(task)
viewModel.ringNonstop = true viewModel.ringNonstop = true
viewModel.save()
save()
assertTrue(taskDao.fetch(task.id)!!.isNotifyModeNonstop) assertTrue(taskDao.fetch(task.id)!!.isNotifyModeNonstop)
} }
@Test @Test
@UiThreadTest
fun ringFiveTimesCantRingNonstop() = runBlocking { fun ringFiveTimesCantRingNonstop() = runBlocking {
val task = newTask() val task = newTask()
viewModel.setup(task) viewModel.setup(task)
viewModel.ringNonstop = true viewModel.ringNonstop = true
viewModel.ringFiveTimes = true viewModel.ringFiveTimes = true
viewModel.save()
save()
assertFalse(taskDao.fetch(task.id)!!.isNotifyModeNonstop) assertFalse(taskDao.fetch(task.id)!!.isNotifyModeNonstop)
assertTrue(taskDao.fetch(task.id)!!.isNotifyModeFive) assertTrue(taskDao.fetch(task.id)!!.isNotifyModeFive)
} }
@Test @Test
@UiThreadTest
fun ringNonStopCantRingFiveTimes() = runBlocking { fun ringNonStopCantRingFiveTimes() = runBlocking {
val task = newTask() val task = newTask()
viewModel.setup(task) viewModel.setup(task)
viewModel.ringFiveTimes = true viewModel.ringFiveTimes = true
viewModel.ringNonstop = true viewModel.ringNonstop = true
viewModel.save()
save()
assertFalse(taskDao.fetch(task.id)!!.isNotifyModeFive) assertFalse(taskDao.fetch(task.id)!!.isNotifyModeFive)
assertTrue(taskDao.fetch(task.id)!!.isNotifyModeNonstop) assertTrue(taskDao.fetch(task.id)!!.isNotifyModeNonstop)

@ -1,6 +1,5 @@
package org.tasks.ui.editviewmodel package org.tasks.ui.editviewmodel
import androidx.test.annotation.UiThreadTest
import com.google.ical.values.RRule import com.google.ical.values.RRule
import com.natpryce.makeiteasy.MakeItEasy.with import com.natpryce.makeiteasy.MakeItEasy.with
import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.HiltAndroidTest
@ -16,14 +15,13 @@ import org.tasks.makers.TaskMaker.newTask
@HiltAndroidTest @HiltAndroidTest
class RepeatTests : BaseTaskEditViewModelTest() { class RepeatTests : BaseTaskEditViewModelTest() {
@Test @Test
@UiThreadTest
fun changeRepeatAfterCompletion() = runBlocking { fun changeRepeatAfterCompletion() = runBlocking {
val task = newTask(with(TaskMaker.RRULE, RRule("RRULE:FREQ=DAILY;INTERVAL=1"))) val task = newTask(with(TaskMaker.RRULE, RRule("RRULE:FREQ=DAILY;INTERVAL=1")))
viewModel.setup(task) viewModel.setup(task)
viewModel.repeatAfterCompletion = true viewModel.repeatAfterCompletion = true
viewModel.save() save()
assertEquals( assertEquals(
"RRULE:FREQ=DAILY;INTERVAL=1;FROM=COMPLETION", "RRULE:FREQ=DAILY;INTERVAL=1;FROM=COMPLETION",
@ -31,7 +29,6 @@ class RepeatTests : BaseTaskEditViewModelTest() {
} }
@Test @Test
@UiThreadTest
fun removeRepeatAfterCompletion() = runBlocking { fun removeRepeatAfterCompletion() = runBlocking {
val task = newTask() val task = newTask()
task.recurrence = "RRULE:FREQ=DAILY;INTERVAL=1;FROM=COMPLETION" task.recurrence = "RRULE:FREQ=DAILY;INTERVAL=1;FROM=COMPLETION"
@ -39,7 +36,7 @@ class RepeatTests : BaseTaskEditViewModelTest() {
viewModel.repeatAfterCompletion = false viewModel.repeatAfterCompletion = false
viewModel.save() save()
assertEquals( assertEquals(
"RRULE:FREQ=DAILY;INTERVAL=1", "RRULE:FREQ=DAILY;INTERVAL=1",

@ -1,6 +1,5 @@
package org.tasks.ui.editviewmodel package org.tasks.ui.editviewmodel
import androidx.test.annotation.UiThreadTest
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.HiltAndroidTest
import dagger.hilt.android.testing.UninstallModules import dagger.hilt.android.testing.UninstallModules
@ -22,23 +21,21 @@ class TaskEditViewModelTest : BaseTaskEditViewModelTest() {
} }
@Test @Test
@UiThreadTest
fun dontSaveTaskWithoutChanges() = runBlocking { fun dontSaveTaskWithoutChanges() = runBlocking {
viewModel.setup(newTask()) viewModel.setup(newTask())
assertFalse(viewModel.save()) assertFalse(save())
assertTrue(taskDao.getAll().isEmpty()) assertTrue(taskDao.getAll().isEmpty())
} }
@Test @Test
@UiThreadTest
fun dontSaveTaskTwice() = runBlocking { fun dontSaveTaskTwice() = runBlocking {
viewModel.setup(newTask()) viewModel.setup(newTask())
viewModel.priority = Task.Priority.HIGH viewModel.priority = Task.Priority.HIGH
assertTrue(viewModel.save()) assertTrue(save())
assertFalse(viewModel.save()) assertFalse(viewModel.save())
} }

@ -1,6 +1,5 @@
package org.tasks.ui.editviewmodel package org.tasks.ui.editviewmodel
import androidx.test.annotation.UiThreadTest
import com.natpryce.makeiteasy.MakeItEasy.with import com.natpryce.makeiteasy.MakeItEasy.with
import com.todoroo.astrid.data.Task.Priority.Companion.HIGH import com.todoroo.astrid.data.Task.Priority.Companion.HIGH
import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.HiltAndroidTest
@ -26,20 +25,18 @@ class TitleTests : BaseTaskEditViewModelTest() {
} }
@Test @Test
@UiThreadTest
fun saveWithEmptyTitle() = runBlocking { fun saveWithEmptyTitle() = runBlocking {
val task = newTask() val task = newTask()
viewModel.setup(task) viewModel.setup(task)
viewModel.priority = HIGH viewModel.priority = HIGH
viewModel.save() save()
assertEquals("(No title)", taskDao.fetch(task.id)!!.title) assertEquals("(No title)", taskDao.fetch(task.id)!!.title)
} }
@Test @Test
@UiThreadTest
fun newTaskPrepopulatedWithTitleHasChanges() { fun newTaskPrepopulatedWithTitleHasChanges() {
viewModel.setup(newTask(with(TaskMaker.TITLE, "some title"))) viewModel.setup(newTask(with(TaskMaker.TITLE, "some title")))

@ -5,9 +5,9 @@
*/ */
package com.todoroo.astrid.alarms package com.todoroo.astrid.alarms
import kotlinx.coroutines.runBlocking
import org.tasks.data.Alarm import org.tasks.data.Alarm
import org.tasks.data.AlarmDao import org.tasks.data.AlarmDao
import org.tasks.data.runBlocking
import org.tasks.jobs.AlarmEntry import org.tasks.jobs.AlarmEntry
import org.tasks.jobs.NotificationQueue import org.tasks.jobs.NotificationQueue
import java.util.* import java.util.*

@ -9,9 +9,9 @@ import androidx.paging.DataSource
import androidx.sqlite.db.SimpleSQLiteQuery import androidx.sqlite.db.SimpleSQLiteQuery
import com.todoroo.astrid.api.Filter import com.todoroo.astrid.api.Filter
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
import kotlinx.coroutines.runBlocking
import org.tasks.data.SubtaskInfo import org.tasks.data.SubtaskInfo
import org.tasks.data.TaskContainer import org.tasks.data.TaskContainer
import org.tasks.data.runBlocking
import org.tasks.preferences.Preferences import org.tasks.preferences.Preferences
import javax.inject.Inject import javax.inject.Inject

@ -3,8 +3,8 @@ package com.todoroo.astrid.service
import com.todoroo.andlib.utility.DateUtilities import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.astrid.dao.TaskDao import com.todoroo.astrid.dao.TaskDao
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
import kotlinx.coroutines.runBlocking
import org.tasks.data.GoogleTaskDao import org.tasks.data.GoogleTaskDao
import org.tasks.data.runBlocking
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject

@ -8,7 +8,6 @@ import com.todoroo.astrid.api.GtasksFilter
import com.todoroo.astrid.dao.TaskDao import com.todoroo.astrid.dao.TaskDao
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.runBlocking
import org.tasks.BuildConfig import org.tasks.BuildConfig
import org.tasks.LocalBroadcastManager import org.tasks.LocalBroadcastManager
import org.tasks.data.* import org.tasks.data.*
@ -58,7 +57,6 @@ class TaskMover @Inject constructor(
localBroadcastManager.broadcastRefresh() localBroadcastManager.broadcastRefresh()
} }
// TODO: remove runBlocking
fun migrateLocalTasks() = runBlocking { fun migrateLocalTasks() = runBlocking {
val list = caldavDao.getLocalList(context) val list = caldavDao.getLocalList(context)
move(taskDao.getLocalTasks(), CaldavFilter(list)) move(taskDao.getLocalTasks(), CaldavFilter(list))

@ -1,6 +1,5 @@
package org.tasks.data package org.tasks.data
import kotlinx.coroutines.runBlocking
import javax.inject.Inject import javax.inject.Inject
@Deprecated("use coroutines") @Deprecated("use coroutines")

@ -3,7 +3,6 @@ package org.tasks.data
import android.content.Context import android.content.Context
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
import kotlinx.coroutines.runBlocking
import org.tasks.filters.CaldavFilters import org.tasks.filters.CaldavFilters
import org.tasks.time.DateTimeUtils.currentTimeMillis import org.tasks.time.DateTimeUtils.currentTimeMillis
import javax.inject.Inject import javax.inject.Inject

@ -3,7 +3,6 @@ package org.tasks.data
import android.database.Cursor import android.database.Cursor
import androidx.sqlite.db.SupportSQLiteQuery import androidx.sqlite.db.SupportSQLiteQuery
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
import kotlinx.coroutines.runBlocking
import javax.inject.Inject import javax.inject.Inject
@Deprecated("use coroutines") @Deprecated("use coroutines")

@ -1,6 +1,5 @@
package org.tasks.data package org.tasks.data
import kotlinx.coroutines.runBlocking
import javax.inject.Inject import javax.inject.Inject
@Deprecated("use coroutines") @Deprecated("use coroutines")

@ -1,6 +1,5 @@
package org.tasks.data package org.tasks.data
import kotlinx.coroutines.runBlocking
import javax.inject.Inject import javax.inject.Inject
@Deprecated("use coroutines") @Deprecated("use coroutines")

@ -1,7 +1,6 @@
package org.tasks.data package org.tasks.data
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
import kotlinx.coroutines.runBlocking
import org.tasks.time.DateTimeUtils.currentTimeMillis import org.tasks.time.DateTimeUtils.currentTimeMillis
import javax.inject.Inject import javax.inject.Inject

@ -1,7 +1,6 @@
package org.tasks.data package org.tasks.data
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import kotlinx.coroutines.runBlocking
import org.tasks.filters.GoogleTaskFilters import org.tasks.filters.GoogleTaskFilters
import org.tasks.time.DateTimeUtils.currentTimeMillis import org.tasks.time.DateTimeUtils.currentTimeMillis
import javax.inject.Inject import javax.inject.Inject

@ -1,7 +1,6 @@
package org.tasks.data package org.tasks.data
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import kotlinx.coroutines.runBlocking
import org.tasks.filters.LocationFilters import org.tasks.filters.LocationFilters
import org.tasks.time.DateTimeUtils.currentTimeMillis import org.tasks.time.DateTimeUtils.currentTimeMillis
import javax.inject.Inject import javax.inject.Inject

@ -0,0 +1,14 @@
package org.tasks.data
import com.todoroo.andlib.utility.AndroidUtilities.assertNotMainThread
import kotlinx.coroutines.CoroutineScope
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
@Throws(InterruptedException::class)
fun <T> runBlocking(context: CoroutineContext = EmptyCoroutineContext, block: suspend CoroutineScope.() -> T): T {
assertNotMainThread()
return kotlinx.coroutines.runBlocking(context, block)
}

@ -1,7 +1,6 @@
package org.tasks.data package org.tasks.data
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
import kotlinx.coroutines.runBlocking
import javax.inject.Inject import javax.inject.Inject
@Deprecated("use coroutines") @Deprecated("use coroutines")

@ -3,7 +3,6 @@ package org.tasks.data
import androidx.core.util.Pair import androidx.core.util.Pair
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
import kotlinx.coroutines.runBlocking
import org.tasks.filters.TagFilters import org.tasks.filters.TagFilters
import org.tasks.time.DateTimeUtils.currentTimeMillis import org.tasks.time.DateTimeUtils.currentTimeMillis
import javax.inject.Inject import javax.inject.Inject

@ -1,6 +1,5 @@
package org.tasks.data package org.tasks.data
import kotlinx.coroutines.runBlocking
import javax.inject.Inject import javax.inject.Inject
@Deprecated("use coroutines") @Deprecated("use coroutines")

@ -1,6 +1,5 @@
package org.tasks.data package org.tasks.data
import kotlinx.coroutines.runBlocking
import javax.inject.Inject import javax.inject.Inject
@Deprecated("use coroutines") @Deprecated("use coroutines")

@ -1,6 +1,5 @@
package org.tasks.data package org.tasks.data
import kotlinx.coroutines.runBlocking
import javax.inject.Inject import javax.inject.Inject
@Deprecated("use coroutines") @Deprecated("use coroutines")

@ -7,12 +7,8 @@ import androidx.work.WorkerParameters
import com.todoroo.astrid.alarms.AlarmService import com.todoroo.astrid.alarms.AlarmService
import com.todoroo.astrid.reminders.ReminderService import com.todoroo.astrid.reminders.ReminderService
import com.todoroo.astrid.timers.TimerPlugin import com.todoroo.astrid.timers.TimerPlugin
import kotlinx.coroutines.runBlocking
import org.tasks.analytics.Firebase import org.tasks.analytics.Firebase
import org.tasks.data.DeletionDaoBlocking import org.tasks.data.*
import org.tasks.data.LocationDaoBlocking
import org.tasks.data.TaskAttachmentDaoBlocking
import org.tasks.data.UserActivityDaoBlocking
import org.tasks.files.FileHelper import org.tasks.files.FileHelper
import org.tasks.injection.InjectingWorker import org.tasks.injection.InjectingWorker
import org.tasks.location.GeofenceApi import org.tasks.location.GeofenceApi

@ -10,12 +10,12 @@ import androidx.work.*
import com.todoroo.andlib.utility.AndroidUtilities import com.todoroo.andlib.utility.AndroidUtilities
import com.todoroo.andlib.utility.DateUtilities import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
import kotlinx.coroutines.runBlocking
import org.tasks.BuildConfig import org.tasks.BuildConfig
import org.tasks.R import org.tasks.R
import org.tasks.data.CaldavDao import org.tasks.data.CaldavDao
import org.tasks.data.GoogleTaskListDao import org.tasks.data.GoogleTaskListDao
import org.tasks.data.Place import org.tasks.data.Place
import org.tasks.data.runBlocking
import org.tasks.date.DateTimeUtils.midnight import org.tasks.date.DateTimeUtils.midnight
import org.tasks.date.DateTimeUtils.newDateTime import org.tasks.date.DateTimeUtils.newDateTime
import org.tasks.jobs.WorkManager.Companion.MAX_CLEANUP_LENGTH import org.tasks.jobs.WorkManager.Companion.MAX_CLEANUP_LENGTH

@ -1,6 +1,6 @@
package org.tasks.notifications package org.tasks.notifications
import kotlinx.coroutines.runBlocking import org.tasks.data.runBlocking
import javax.inject.Inject import javax.inject.Inject
@Deprecated("use coroutines") @Deprecated("use coroutines")

@ -7,7 +7,6 @@ import com.todoroo.astrid.core.BuiltInFilterExposer
import com.todoroo.astrid.core.BuiltInFilterExposer.getMyTasksFilter import com.todoroo.astrid.core.BuiltInFilterExposer.getMyTasksFilter
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.runBlocking
import org.tasks.R import org.tasks.R
import org.tasks.Strings.isNullOrEmpty import org.tasks.Strings.isNullOrEmpty
import org.tasks.data.* import org.tasks.data.*

@ -30,7 +30,6 @@ import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toImmutableSet import kotlinx.collections.immutable.toImmutableSet
import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.async import kotlinx.coroutines.async
import kotlinx.coroutines.runBlocking
import org.tasks.Event import org.tasks.Event
import org.tasks.R import org.tasks.R
import org.tasks.Strings import org.tasks.Strings

Loading…
Cancel
Save