diff --git a/app/src/androidTest/java/com/todoroo/astrid/adapter/OfflineSubtaskTest.kt b/app/src/androidTest/java/com/todoroo/astrid/adapter/OfflineSubtaskTest.kt index 1a516bfaa..945c358b1 100644 --- a/app/src/androidTest/java/com/todoroo/astrid/adapter/OfflineSubtaskTest.kt +++ b/app/src/androidTest/java/com/todoroo/astrid/adapter/OfflineSubtaskTest.kt @@ -3,17 +3,13 @@ package com.todoroo.astrid.adapter import com.natpryce.makeiteasy.MakeItEasy.with import com.natpryce.makeiteasy.PropertyValue import com.todoroo.astrid.dao.TaskDao -import com.todoroo.astrid.service.TaskMover import dagger.hilt.android.testing.HiltAndroidTest import kotlinx.coroutines.runBlocking import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Test -import org.tasks.LocalBroadcastManager import org.tasks.data.TaskContainer import org.tasks.data.TaskListQuery.getQuery -import org.tasks.data.dao.CaldavDao -import org.tasks.data.dao.GoogleTaskDao import org.tasks.data.entity.Task import org.tasks.filters.MyTasksFilter import org.tasks.injection.InjectingTestCase @@ -24,29 +20,15 @@ import javax.inject.Inject @HiltAndroidTest class OfflineSubtaskTest : InjectingTestCase() { - @Inject lateinit var googleTaskDao: GoogleTaskDao - @Inject lateinit var caldavDao: CaldavDao @Inject lateinit var taskDao: TaskDao @Inject lateinit var preferences: Preferences - @Inject lateinit var localBroadcastManager: LocalBroadcastManager - @Inject lateinit var taskMover: TaskMover - private lateinit var adapter: TaskAdapter - private val tasks = ArrayList() private val filter = runBlocking { MyTasksFilter.create() } - private val dataSource = object : TaskAdapterDataSource { - override fun getItem(position: Int) = tasks[position] - - override fun getTaskCount() = tasks.size - } @Before override fun setUp() { super.setUp() preferences.clear() - tasks.clear() - adapter = TaskAdapter(false, googleTaskDao, caldavDao, taskDao, localBroadcastManager, taskMover) - adapter.setDataSource(dataSource) } @Test @@ -54,7 +36,7 @@ class OfflineSubtaskTest : InjectingTestCase() { val parent = addTask() val child = addTask(with(PARENT, parent)) - query() + val tasks = query() assertEquals(child, tasks[1].id) assertEquals(parent, tasks[1].parent) @@ -67,20 +49,81 @@ class OfflineSubtaskTest : InjectingTestCase() { val parent = addTask(with(PARENT, grandparent)) val child = addTask(with(PARENT, parent)) - query() + val tasks = query() assertEquals(child, tasks[2].id) assertEquals(parent, tasks[2].parent) assertEquals(2, tasks[2].indent) } + @Test + fun parentWithOneChildHasChildrenCountOne() { + val parent = addTask() + addTask(with(PARENT, parent)) + + val tasks = query() + + val parentTask = tasks.find { it.id == parent }!! + assertEquals(1, parentTask.children) + } + + @Test + fun parentWithMultipleChildrenHasCorrectCount() { + val parent = addTask() + addTask(with(PARENT, parent)) + addTask(with(PARENT, parent)) + addTask(with(PARENT, parent)) + + val tasks = query() + + val parentTask = tasks.find { it.id == parent }!! + assertEquals(3, parentTask.children) + } + + @Test + fun grandparentCountsAllDescendants() { + val grandparent = addTask() + val parent = addTask(with(PARENT, grandparent)) + addTask(with(PARENT, parent)) + + val tasks = query() + + val grandparentTask = tasks.find { it.id == grandparent }!! + assertEquals(2, grandparentTask.children) + } + + @Test + fun leafTaskHasNoChildren() { + val parent = addTask() + val child = addTask(with(PARENT, parent)) + + val tasks = query() + + val childTask = tasks.find { it.id == child }!! + assertEquals(0, childTask.children) + } + + @Test + fun deepHierarchyCountsAllDescendants() { + val root = addTask() + val level1 = addTask(with(PARENT, root)) + val level2 = addTask(with(PARENT, level1)) + val level3 = addTask(with(PARENT, level2)) + addTask(with(PARENT, level3)) + + val tasks = query() + + val rootTask = tasks.find { it.id == root }!! + assertEquals(4, rootTask.children) + } + private fun addTask(vararg properties: PropertyValue): Long = runBlocking { val task = newTask(*properties) taskDao.createNew(task) task.id } - private fun query() = runBlocking { - tasks.addAll(taskDao.fetchTasks(getQuery(preferences, filter))) + private fun query(): List = runBlocking { + taskDao.fetchTasks(getQuery(preferences, filter)) } -} \ No newline at end of file +} diff --git a/app/src/androidTest/java/com/todoroo/astrid/adapter/RecursiveLoopTest.kt b/app/src/androidTest/java/com/todoroo/astrid/adapter/RecursiveLoopTest.kt index 6c4bb862a..c8052b707 100644 --- a/app/src/androidTest/java/com/todoroo/astrid/adapter/RecursiveLoopTest.kt +++ b/app/src/androidTest/java/com/todoroo/astrid/adapter/RecursiveLoopTest.kt @@ -68,6 +68,17 @@ class RecursiveLoopTest : InjectingTestCase() { assertEquals(grandchild, tasks[2].id) } + @Test + fun descendantsRecursiveLoopBothMatchFilter() = runBlocking { + val parent = addTask(with(DUE_DATE, newDateTime())) + val child = addTask(with(DUE_DATE, newDateTime()), with(PARENT, parent)) + + taskDao.setParent(child, listOf(parent)) + + val tasks = getTasks() + assertEquals(2, tasks.size) + } + private suspend fun getTasks() = taskDao.fetchTasks( getQuery(preferences, TodayFilter.create()) ) diff --git a/kmp/src/commonMain/kotlin/org/tasks/data/TaskListQueryRecursive.kt b/kmp/src/commonMain/kotlin/org/tasks/data/TaskListQueryRecursive.kt index 7bf20f3ef..105bb34b7 100644 --- a/kmp/src/commonMain/kotlin/org/tasks/data/TaskListQueryRecursive.kt +++ b/kmp/src/commonMain/kotlin/org/tasks/data/TaskListQueryRecursive.kt @@ -127,7 +127,7 @@ internal object TaskListQueryRecursive { parent_complete as completed FROM recursive_tasks WHERE parent > 0 - UNION ALL + UNION SELECT d.parent, r.task as descendant,