feat: magnifier view setup + unit тесты для TextSelectionHelper
- setMagnifierView(view) в ChatDetailScreen через LaunchedEffect - 9 unit тестов: initial state, clear, getSelectedText, boundary checks Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -396,6 +396,7 @@ fun ChatDetailScreen(
|
|||||||
|
|
||||||
// 🔤 TEXT SELECTION - Telegram-style character-level selection
|
// 🔤 TEXT SELECTION - Telegram-style character-level selection
|
||||||
val textSelectionHelper = remember { com.rosetta.messenger.ui.chats.components.TextSelectionHelper() }
|
val textSelectionHelper = remember { com.rosetta.messenger.ui.chats.components.TextSelectionHelper() }
|
||||||
|
LaunchedEffect(Unit) { textSelectionHelper.setMagnifierView(view) }
|
||||||
|
|
||||||
// 💬 MESSAGE CONTEXT MENU STATE
|
// 💬 MESSAGE CONTEXT MENU STATE
|
||||||
var contextMenuMessage by remember { mutableStateOf<ChatMessage?>(null) }
|
var contextMenuMessage by remember { mutableStateOf<ChatMessage?>(null) }
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
package com.rosetta.messenger.ui.chats.components
|
||||||
|
|
||||||
|
import org.junit.Assert.*
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class TextSelectionHelperTest {
|
||||||
|
|
||||||
|
private lateinit var helper: TextSelectionHelper
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setup() {
|
||||||
|
helper = TextSelectionHelper()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `initial state is not active`() {
|
||||||
|
assertFalse(helper.isActive)
|
||||||
|
assertFalse(helper.isInSelectionMode)
|
||||||
|
assertEquals(-1, helper.selectionStart)
|
||||||
|
assertEquals(-1, helper.selectionEnd)
|
||||||
|
assertNull(helper.selectedMessageId)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `clear resets all state`() {
|
||||||
|
helper.clear()
|
||||||
|
assertFalse(helper.isActive)
|
||||||
|
assertEquals(-1, helper.selectionStart)
|
||||||
|
assertEquals(-1, helper.selectionEnd)
|
||||||
|
assertNull(helper.selectedMessageId)
|
||||||
|
assertNull(helper.layoutInfo)
|
||||||
|
assertFalse(helper.showToolbar)
|
||||||
|
assertFalse(helper.movingHandle)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `getSelectedText returns null when not active`() {
|
||||||
|
assertNull(helper.getSelectedText())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `updateSelectionEnd does not change when not active`() {
|
||||||
|
helper.updateSelectionEnd(5)
|
||||||
|
assertEquals(-1, helper.selectionEnd)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `updateSelectionStart does not change when not active`() {
|
||||||
|
helper.updateSelectionStart(0)
|
||||||
|
assertEquals(-1, helper.selectionStart)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `getCharOffsetFromCoords returns -1 when no layout`() {
|
||||||
|
assertEquals(-1, helper.getCharOffsetFromCoords(100, 100))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `selectAll does nothing when no layout`() {
|
||||||
|
helper.selectAll()
|
||||||
|
assertEquals(-1, helper.selectionStart)
|
||||||
|
assertEquals(-1, helper.selectionEnd)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `moveHandle does nothing when not moving`() {
|
||||||
|
helper.moveHandle(100f, 100f)
|
||||||
|
assertFalse(helper.movingHandle)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `endHandleDrag sets movingHandle to false`() {
|
||||||
|
helper.endHandleDrag()
|
||||||
|
assertFalse(helper.movingHandle)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user