Add unit test on MatrixTimelineDiffProcessor
This commit is contained in:
committed by
Benoit Marty
parent
98abb7827e
commit
f91d0688d8
@@ -15,7 +15,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import org.matrix.rustcomponents.sdk.TimelineChange
|
||||
import org.matrix.rustcomponents.sdk.TimelineDiff
|
||||
import org.matrix.rustcomponents.sdk.TimelineDiffInterface
|
||||
import org.matrix.rustcomponents.sdk.TimelineItem
|
||||
import timber.log.Timber
|
||||
|
||||
@@ -36,7 +36,7 @@ internal class MatrixTimelineDiffProcessor(
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun postDiffs(diffs: List<TimelineDiff>) {
|
||||
suspend fun postDiffs(diffs: List<TimelineDiffInterface>) {
|
||||
updateTimelineItems {
|
||||
Timber.v("Update timeline items from postDiffs (with ${diffs.size} items) on ${Thread.currentThread()}")
|
||||
diffs.forEach { diff ->
|
||||
@@ -52,7 +52,7 @@ internal class MatrixTimelineDiffProcessor(
|
||||
timelineItems.value = mutableTimelineItems
|
||||
}
|
||||
|
||||
private fun MutableList<MatrixTimelineItem>.applyDiff(diff: TimelineDiff) {
|
||||
private fun MutableList<MatrixTimelineItem>.applyDiff(diff: TimelineDiffInterface) {
|
||||
when (diff.change()) {
|
||||
TimelineChange.APPEND -> {
|
||||
val items = diff.append()?.map { it.asMatrixTimelineItem() } ?: return
|
||||
@@ -100,7 +100,8 @@ internal class MatrixTimelineDiffProcessor(
|
||||
clear()
|
||||
}
|
||||
TimelineChange.TRUNCATE -> {
|
||||
// Not supported
|
||||
val index = diff.truncate() ?: return
|
||||
subList(index.toInt(), size).clear()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* Copyright 2024 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* Please see LICENSE in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.matrix.impl.timeline
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
|
||||
import io.element.android.libraries.matrix.impl.timeline.item.event.EventTimelineItemMapper
|
||||
import io.element.android.libraries.matrix.impl.timeline.item.event.TimelineEventContentMapper
|
||||
import io.element.android.libraries.matrix.impl.timeline.item.virtual.VirtualTimelineItemMapper
|
||||
import io.element.android.libraries.matrix.test.A_UNIQUE_ID
|
||||
import io.element.android.libraries.matrix.test.A_UNIQUE_ID_2
|
||||
import io.element.android.libraries.matrix.test.timeline.anEventTimelineItem
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
import org.matrix.rustcomponents.sdk.EventTimelineItem
|
||||
import org.matrix.rustcomponents.sdk.InsertData
|
||||
import org.matrix.rustcomponents.sdk.NoPointer
|
||||
import org.matrix.rustcomponents.sdk.SetData
|
||||
import org.matrix.rustcomponents.sdk.TimelineChange
|
||||
import org.matrix.rustcomponents.sdk.TimelineDiffInterface
|
||||
import org.matrix.rustcomponents.sdk.TimelineItem
|
||||
import org.matrix.rustcomponents.sdk.VirtualTimelineItem
|
||||
|
||||
open class FakeTimelineDiff(
|
||||
private val change: TimelineChange,
|
||||
private val item: TimelineItem? = FakeTimelineItem()
|
||||
) : TimelineDiffInterface {
|
||||
override fun change() = change
|
||||
override fun append(): List<TimelineItem>? = item?.let { listOf(it) }
|
||||
override fun insert(): InsertData? = item?.let { InsertData(1u, it) }
|
||||
override fun pushBack(): TimelineItem? = item
|
||||
override fun pushFront(): TimelineItem? = item
|
||||
override fun remove(): UInt? = 1u
|
||||
override fun reset(): List<TimelineItem>? = item?.let { listOf(it) }
|
||||
override fun set(): SetData? = item?.let { SetData(1u, it) }
|
||||
override fun truncate(): UInt? = 1u
|
||||
}
|
||||
|
||||
class MatrixTimelineDiffProcessorTest {
|
||||
private val timelineItems = MutableStateFlow<List<MatrixTimelineItem>>(emptyList())
|
||||
|
||||
private val anEvent = MatrixTimelineItem.Event(A_UNIQUE_ID, anEventTimelineItem())
|
||||
private val anEvent2 = MatrixTimelineItem.Event(A_UNIQUE_ID_2, anEventTimelineItem())
|
||||
|
||||
@Test
|
||||
fun `Append adds new entries at the end of the list`() = runTest {
|
||||
timelineItems.value = listOf(anEvent)
|
||||
val processor = createProcessor()
|
||||
processor.postDiffs(listOf(FakeTimelineDiff(change = TimelineChange.APPEND)))
|
||||
assertThat(timelineItems.value.count()).isEqualTo(2)
|
||||
assertThat(timelineItems.value).containsExactly(
|
||||
anEvent,
|
||||
MatrixTimelineItem.Other,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `PushBack adds a new entry at the end of the list`() = runTest {
|
||||
timelineItems.value = listOf(anEvent)
|
||||
val processor = createProcessor()
|
||||
processor.postDiffs(listOf(FakeTimelineDiff(change = TimelineChange.PUSH_BACK)))
|
||||
assertThat(timelineItems.value.count()).isEqualTo(2)
|
||||
assertThat(timelineItems.value).containsExactly(
|
||||
anEvent,
|
||||
MatrixTimelineItem.Other,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `PushFront inserts a new entry at the start of the list`() = runTest {
|
||||
timelineItems.value = listOf(anEvent)
|
||||
val processor = createProcessor()
|
||||
processor.postDiffs(listOf(FakeTimelineDiff(change = TimelineChange.PUSH_FRONT)))
|
||||
assertThat(timelineItems.value.count()).isEqualTo(2)
|
||||
assertThat(timelineItems.value).containsExactly(
|
||||
MatrixTimelineItem.Other,
|
||||
anEvent,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Set replaces an entry at some index`() = runTest {
|
||||
timelineItems.value = listOf(anEvent, anEvent2)
|
||||
val processor = createProcessor()
|
||||
processor.postDiffs(listOf(FakeTimelineDiff(change = TimelineChange.SET)))
|
||||
assertThat(timelineItems.value.count()).isEqualTo(2)
|
||||
assertThat(timelineItems.value).containsExactly(
|
||||
anEvent,
|
||||
MatrixTimelineItem.Other
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Insert inserts a new entry at the provided index`() = runTest {
|
||||
timelineItems.value = listOf(anEvent, anEvent2)
|
||||
val processor = createProcessor()
|
||||
processor.postDiffs(listOf(FakeTimelineDiff(change = TimelineChange.INSERT)))
|
||||
assertThat(timelineItems.value.count()).isEqualTo(3)
|
||||
assertThat(timelineItems.value).containsExactly(
|
||||
anEvent,
|
||||
MatrixTimelineItem.Other,
|
||||
anEvent2,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Remove removes an entry at some index`() = runTest {
|
||||
timelineItems.value = listOf(anEvent, MatrixTimelineItem.Other, anEvent2)
|
||||
val processor = createProcessor()
|
||||
processor.postDiffs(listOf(FakeTimelineDiff(change = TimelineChange.REMOVE)))
|
||||
assertThat(timelineItems.value.count()).isEqualTo(2)
|
||||
assertThat(timelineItems.value).containsExactly(
|
||||
anEvent,
|
||||
anEvent2,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `PopBack removes an entry at the end of the list`() = runTest {
|
||||
timelineItems.value = listOf(anEvent, anEvent2)
|
||||
val processor = createProcessor()
|
||||
processor.postDiffs(listOf(FakeTimelineDiff(change = TimelineChange.POP_BACK)))
|
||||
assertThat(timelineItems.value.count()).isEqualTo(1)
|
||||
assertThat(timelineItems.value).containsExactly(
|
||||
anEvent,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `PopFront removes an entry at the start of the list`() = runTest {
|
||||
timelineItems.value = listOf(anEvent, anEvent2)
|
||||
val processor = createProcessor()
|
||||
processor.postDiffs(listOf(FakeTimelineDiff(change = TimelineChange.POP_FRONT)))
|
||||
assertThat(timelineItems.value.count()).isEqualTo(1)
|
||||
assertThat(timelineItems.value).containsExactly(
|
||||
anEvent2,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Clear removes all the entries`() = runTest {
|
||||
timelineItems.value = listOf(anEvent, anEvent2)
|
||||
val processor = createProcessor()
|
||||
processor.postDiffs(listOf(FakeTimelineDiff(change = TimelineChange.CLEAR)))
|
||||
assertThat(timelineItems.value).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Truncate removes all entries after the provided length`() = runTest {
|
||||
timelineItems.value = listOf(anEvent, MatrixTimelineItem.Other, anEvent2)
|
||||
val processor = createProcessor()
|
||||
processor.postDiffs(listOf(FakeTimelineDiff(change = TimelineChange.TRUNCATE)))
|
||||
assertThat(timelineItems.value.count()).isEqualTo(1)
|
||||
assertThat(timelineItems.value).containsExactly(
|
||||
anEvent,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Reset removes all entries and add the provided ones`() = runTest {
|
||||
timelineItems.value = listOf(anEvent, MatrixTimelineItem.Other, anEvent2)
|
||||
val processor = createProcessor()
|
||||
processor.postDiffs(listOf(FakeTimelineDiff(change = TimelineChange.RESET)))
|
||||
assertThat(timelineItems.value.count()).isEqualTo(1)
|
||||
assertThat(timelineItems.value).containsExactly(
|
||||
MatrixTimelineItem.Other,
|
||||
)
|
||||
}
|
||||
|
||||
private fun TestScope.createProcessor(): MatrixTimelineDiffProcessor {
|
||||
val timelineEventContentMapper = TimelineEventContentMapper()
|
||||
val timelineItemMapper = MatrixTimelineItemMapper(
|
||||
fetchDetailsForEvent = { _ -> Result.success(Unit) },
|
||||
coroutineScope = this,
|
||||
virtualTimelineItemMapper = VirtualTimelineItemMapper(),
|
||||
eventTimelineItemMapper = EventTimelineItemMapper(
|
||||
contentMapper = timelineEventContentMapper
|
||||
)
|
||||
)
|
||||
return MatrixTimelineDiffProcessor(
|
||||
timelineItems,
|
||||
timelineItemFactory = timelineItemMapper,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class FakeTimelineItem : TimelineItem(NoPointer) {
|
||||
override fun asEvent(): EventTimelineItem? = null
|
||||
override fun asVirtual(): VirtualTimelineItem? = null
|
||||
override fun fmtDebug(): String = "fmtDebug"
|
||||
override fun uniqueId(): String = "uniqueId"
|
||||
}
|
||||
Reference in New Issue
Block a user