From a8a07d9c8ab49149810d8f59005794c0de78dbb2 Mon Sep 17 00:00:00 2001 From: Christian Basler Date: Mon, 12 Jan 2026 06:00:57 +0100 Subject: [PATCH] Add tests --- .../common/focus/CluesSelectionManagerTest.kt | 96 +++++++++++++++++++ .../common/focus/GridSelectionManagerTest.kt | 80 ++++++++++++++++ .../focus/LinearSelectionManagerTest.kt | 73 ++++++++++++++ .../ui/common/focus/SelectionManagerTest.kt | 21 ++++ 4 files changed, 270 insertions(+) create mode 100644 commonUI/src/commonTest/kotlin/ch/dissem/yaep/ui/common/focus/CluesSelectionManagerTest.kt create mode 100644 commonUI/src/commonTest/kotlin/ch/dissem/yaep/ui/common/focus/GridSelectionManagerTest.kt create mode 100644 commonUI/src/commonTest/kotlin/ch/dissem/yaep/ui/common/focus/LinearSelectionManagerTest.kt create mode 100644 commonUI/src/commonTest/kotlin/ch/dissem/yaep/ui/common/focus/SelectionManagerTest.kt diff --git a/commonUI/src/commonTest/kotlin/ch/dissem/yaep/ui/common/focus/CluesSelectionManagerTest.kt b/commonUI/src/commonTest/kotlin/ch/dissem/yaep/ui/common/focus/CluesSelectionManagerTest.kt new file mode 100644 index 0000000..9d11270 --- /dev/null +++ b/commonUI/src/commonTest/kotlin/ch/dissem/yaep/ui/common/focus/CluesSelectionManagerTest.kt @@ -0,0 +1,96 @@ +package ch.dissem.yaep.ui.common.focus + +import androidx.compose.ui.input.key.Key +import ch.tutteli.atrium.api.fluent.en_GB.toEqual +import ch.tutteli.atrium.api.verbs.expect +import kotlin.test.Test + +class CluesSelectionManagerTest : SelectionManagerTest() { + + var primaryActionCalled: Int? = null + var secondaryActionCalled: Int? = null + + lateinit var focusables: MutableList + + override fun setUp() { + manager = CluesSelectionManager() + + primaryActionCalled = null + secondaryActionCalled = null + focusables = mutableListOf() + for (i in 0..10) { + focusables.add( + manager.add( + primaryAction = { + primaryActionCalled = i + }, + secondaryAction = { + secondaryActionCalled = i + } + ) + ) + } + manager.columns = 3 + } + + @Test + fun ensure_navigation_right_cycles() { + manager.onKeyEvent(keyEvent(Key.DirectionRight)) + expect(manager.focused).toEqual(focusables[1]) + + manager.onKeyEvent(keyEvent(Key.DirectionRight)) + expect(manager.focused).toEqual(focusables[2]) + + manager.onKeyEvent(keyEvent(Key.DirectionRight)) + expect(manager.focused).toEqual(focusables[0]) + } + + @Test + fun ensure_navigation_left_cycles() { + manager.onKeyEvent(keyEvent(Key.DirectionLeft)) + expect(manager.focused).toEqual(focusables[2]) + + manager.onKeyEvent(keyEvent(Key.DirectionLeft)) + expect(manager.focused).toEqual(focusables[1]) + + manager.onKeyEvent(keyEvent(Key.DirectionLeft)) + expect(manager.focused).toEqual(focusables[0]) + + manager.onKeyEvent(keyEvent(Key.DirectionLeft)) + expect(manager.focused).toEqual(focusables[2]) + } + + @Test + fun ensure_navigation_down_cycles() { + manager.onKeyEvent(keyEvent(Key.DirectionDown)) + expect(manager.focused).toEqual(focusables[3]) + + manager.onKeyEvent(keyEvent(Key.DirectionDown)) + expect(manager.focused).toEqual(focusables[6]) + + manager.onKeyEvent(keyEvent(Key.DirectionDown)) + expect(manager.focused).toEqual(focusables[9]) + + manager.onKeyEvent(keyEvent(Key.DirectionDown)) + expect(manager.focused).toEqual(focusables[0]) + } + + @Test + fun ensure_navigation_up_cycles() { + manager.onKeyEvent(keyEvent(Key.DirectionUp)) + expect(manager.focused).toEqual(focusables[9]) + + manager.onKeyEvent(keyEvent(Key.DirectionUp)) + expect(manager.focused).toEqual(focusables[6]) + + manager.onKeyEvent(keyEvent(Key.DirectionUp)) + expect(manager.focused).toEqual(focusables[3]) + + manager.onKeyEvent(keyEvent(Key.DirectionUp)) + expect(manager.focused).toEqual(focusables[0]) + + manager.onKeyEvent(keyEvent(Key.DirectionUp)) + expect(manager.focused).toEqual(focusables[9]) + } + +} \ No newline at end of file diff --git a/commonUI/src/commonTest/kotlin/ch/dissem/yaep/ui/common/focus/GridSelectionManagerTest.kt b/commonUI/src/commonTest/kotlin/ch/dissem/yaep/ui/common/focus/GridSelectionManagerTest.kt new file mode 100644 index 0000000..25caf6f --- /dev/null +++ b/commonUI/src/commonTest/kotlin/ch/dissem/yaep/ui/common/focus/GridSelectionManagerTest.kt @@ -0,0 +1,80 @@ +package ch.dissem.yaep.ui.common.focus + +import androidx.compose.ui.input.key.Key +import ch.tutteli.atrium.api.fluent.en_GB.toEqual +import ch.tutteli.atrium.api.verbs.expect +import kotlin.test.Test + +class GridSelectionManagerTest : SelectionManagerTest() { + + lateinit var focusables: MutableList + + override fun setUp() { + manager = GridSelectionManager() + + focusables = mutableListOf() + repeat(3) { + manager.addRow() + repeat(3) { + focusables.add( + manager.add() + ) + } + } + } + + @Test + fun ensure_navigation_right_cycles() { + manager.onKeyEvent(keyEvent(Key.DirectionRight)) + expect(manager.focused).toEqual(focusables[1]) + + manager.onKeyEvent(keyEvent(Key.DirectionRight)) + expect(manager.focused).toEqual(focusables[2]) + + manager.onKeyEvent(keyEvent(Key.DirectionRight)) + expect(manager.focused).toEqual(focusables[0]) + } + + @Test + fun ensure_navigation_left_cycles() { + manager.onKeyEvent(keyEvent(Key.DirectionLeft)) + expect(manager.focused).toEqual(focusables[2]) + + manager.onKeyEvent(keyEvent(Key.DirectionLeft)) + expect(manager.focused).toEqual(focusables[1]) + + manager.onKeyEvent(keyEvent(Key.DirectionLeft)) + expect(manager.focused).toEqual(focusables[0]) + + manager.onKeyEvent(keyEvent(Key.DirectionLeft)) + expect(manager.focused).toEqual(focusables[2]) + } + + @Test + fun ensure_navigation_down_cycles() { + manager.onKeyEvent(keyEvent(Key.DirectionDown)) + expect(manager.focused).toEqual(focusables[3]) + + manager.onKeyEvent(keyEvent(Key.DirectionDown)) + expect(manager.focused).toEqual(focusables[6]) + + manager.onKeyEvent(keyEvent(Key.DirectionDown)) + expect(manager.focused).toEqual(focusables[0]) + } + + @Test + fun ensure_navigation_up_cycles() { + manager.onKeyEvent(keyEvent(Key.DirectionUp)) + expect(manager.focused).toEqual(focusables[6]) + + manager.onKeyEvent(keyEvent(Key.DirectionUp)) + expect(manager.focused).toEqual(focusables[3]) + + manager.onKeyEvent(keyEvent(Key.DirectionUp)) + expect(manager.focused).toEqual(focusables[0]) + + manager.onKeyEvent(keyEvent(Key.DirectionUp)) + expect(manager.focused).toEqual(focusables[6]) + } + +} \ No newline at end of file diff --git a/commonUI/src/commonTest/kotlin/ch/dissem/yaep/ui/common/focus/LinearSelectionManagerTest.kt b/commonUI/src/commonTest/kotlin/ch/dissem/yaep/ui/common/focus/LinearSelectionManagerTest.kt new file mode 100644 index 0000000..275a87e --- /dev/null +++ b/commonUI/src/commonTest/kotlin/ch/dissem/yaep/ui/common/focus/LinearSelectionManagerTest.kt @@ -0,0 +1,73 @@ +package ch.dissem.yaep.ui.common.focus + +import androidx.compose.ui.input.key.Key +import ch.tutteli.atrium.api.fluent.en_GB.toEqual +import ch.tutteli.atrium.api.verbs.expect +import kotlin.test.Test + +class LinearSelectionManagerTest : SelectionManagerTest() { + + override fun setUp() { + manager = LinearSelectionManager( + keyNext = Key.A, + keyPrevious = Key.B + ) + } + + @Test + fun ensure_manager_with_focusables_has_focus_on_first_item() { + val focusables = arrayOf( + manager.add(), + manager.add() + ) + + expect(manager.focused).toEqual(focusables[0]) + } + + @Test + fun ensure_keyEvent_A_selects_next() { + val focusables = arrayOf( + manager.add(), + manager.add(), + manager.add() + ) + + manager.onKeyEvent(keyEvent(Key.A)) + expect(manager.focused).toEqual(focusables[1]) + + manager.onKeyEvent(keyEvent(Key.A)) + expect(manager.focused).toEqual(focusables[2]) + } + + @Test + fun ensure_keyEvent_B_selects_previous() { + val focusables = arrayOf( + manager.add(), + manager.add(), + manager.add() + ) + manager.focused = focusables[2] + + manager.onKeyEvent(keyEvent(Key.B)) + expect(manager.focused).toEqual(focusables[1]) + + manager.onKeyEvent(keyEvent(Key.B)) + expect(manager.focused).toEqual(focusables[0]) + } + + @Test + fun ensure_ring_behaviour() { + val focusables = arrayOf( + manager.add(), + manager.add(), + manager.add() + ) + + manager.onKeyEvent(keyEvent(Key.B)) + expect(manager.focused).toEqual(focusables[2]) + + manager.onKeyEvent(keyEvent(Key.A)) + expect(manager.focused).toEqual(focusables[0]) + } + +} \ No newline at end of file diff --git a/commonUI/src/commonTest/kotlin/ch/dissem/yaep/ui/common/focus/SelectionManagerTest.kt b/commonUI/src/commonTest/kotlin/ch/dissem/yaep/ui/common/focus/SelectionManagerTest.kt new file mode 100644 index 0000000..45c497e --- /dev/null +++ b/commonUI/src/commonTest/kotlin/ch/dissem/yaep/ui/common/focus/SelectionManagerTest.kt @@ -0,0 +1,21 @@ +package ch.dissem.yaep.ui.common.focus + +import androidx.compose.ui.InternalComposeUiApi +import androidx.compose.ui.input.key.Key +import androidx.compose.ui.input.key.KeyEvent +import androidx.compose.ui.input.key.KeyEventType +import kotlin.test.BeforeTest + +abstract class SelectionManagerTest> { + lateinit var manager: M + + @BeforeTest + abstract fun setUp() + + @OptIn(InternalComposeUiApi::class) + fun keyEvent(key: Key, type: KeyEventType = KeyEventType.KeyUp) = KeyEvent( + key = key, + type = type + ) + +} \ No newline at end of file