package ch.dissem.yaep.ui.common.focus

import androidx.compose.ui.input.key.Key
import androidx.compose.ui.input.key.KeyEventType
import ch.tutteli.atrium.api.fluent.en_GB.toEqual
import ch.tutteli.atrium.api.verbs.expect
import kotlin.test.BeforeTest
import kotlin.test.Test
import kotlin.test.fail

abstract class SelectionManagerTest<F : Focusable<F>, M : SelectionManager<F>> {
    lateinit var manager: M

    @BeforeTest
    abstract fun setUp()

    @Test
    fun ensure_key_event_is_ignored_if_not_keyup() {
        for (t in arrayOf(KeyEventType.KeyDown, KeyEventType.Unknown)) {
            manager.focused = manager.add {
                fail("Action must not be called, event type $t should be ignored")
            }
            manager.onKeyEvent(keyEvent(Key.Enter, t))
        }
    }

    @Test
    fun ensure_primary_action_is_called() {
        for (k in arrayOf(Key.Enter, Key.Spacebar)) {
            var primary = false
            var secondary = false

            manager.focused = manager.add(
                primaryAction = { primary = true },
                secondaryAction = { secondary = true }
            )
            manager.onKeyEvent(keyEvent(k))
            expect(primary).toEqual(true)
            expect(secondary).toEqual(false)
        }
    }

    @Test
    fun ensure_secondary_action_is_called() {
        for (k in arrayOf(Key.Backspace, Key.Delete)) {
            var primary = false
            var secondary = false

            manager.focused = manager.add(
                primaryAction = { primary = true },
                secondaryAction = { secondary = true }
            )
            manager.onKeyEvent(keyEvent(k))
            expect(primary).toEqual(false)
            expect(secondary).toEqual(true)
        }
    }

}