Improve tests
This commit is contained in:
@@ -120,7 +120,6 @@ fun App(
|
||||
textAlign = TextAlign.End
|
||||
)
|
||||
},
|
||||
spacing = spacing,
|
||||
game, resetCluesBeacon
|
||||
)
|
||||
EndOfGame(isSolved = isSolved, time = time, onRestart = onNewGame)
|
||||
|
||||
@@ -8,7 +8,6 @@ import androidx.compose.ui.layout.Layout
|
||||
import androidx.compose.ui.layout.Placeable
|
||||
import androidx.compose.ui.unit.Constraints
|
||||
import androidx.compose.ui.unit.Constraints.Companion.fixed
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import ch.dissem.yaep.ui.common.focus.CluesSelectionManager
|
||||
import ch.dissem.yaep.ui.common.focus.FocusFollowingFocusable
|
||||
@@ -29,7 +28,6 @@ fun AdaptiveGameLayout(
|
||||
horizontalClues: @Composable (SelectionManager<*>) -> Unit,
|
||||
verticalClues: @Composable (SelectionManager<*>) -> Unit,
|
||||
time: @Composable () -> Unit,
|
||||
spacing: Dp = 8.dp,
|
||||
vararg resetBeacons: Any
|
||||
) {
|
||||
val gridFocusable = remember(*resetBeacons) { selectionManager.add() }
|
||||
@@ -80,7 +78,7 @@ fun AdaptiveGameLayout(
|
||||
val timeMeasurable = measurables[6][0]
|
||||
val dividerMeasurables = measurables[7]
|
||||
|
||||
val spacingPx = spacing.roundToPx()
|
||||
val spacingPx = 8.dp.roundToPx()
|
||||
|
||||
when (aspectRatio) {
|
||||
PORTRAIT -> {
|
||||
|
||||
@@ -1,20 +1,30 @@
|
||||
package ch.dissem.yaep.ui.common
|
||||
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.geometry.Size
|
||||
import androidx.compose.ui.input.key.Key
|
||||
import androidx.compose.ui.input.key.onKeyEvent
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.SkikoComposeUiTest
|
||||
import androidx.compose.ui.test.onNodeWithTag
|
||||
import androidx.compose.ui.test.onRoot
|
||||
import androidx.compose.ui.test.performKeyInput
|
||||
import androidx.compose.ui.test.pressKey
|
||||
import androidx.compose.ui.test.runSkikoComposeUiTest
|
||||
import androidx.compose.ui.test.withKeyDown
|
||||
import androidx.compose.ui.unit.dp
|
||||
import ch.dissem.yaep.domain.Game
|
||||
import ch.dissem.yaep.domain.UnsolvablePuzzleException
|
||||
import ch.dissem.yaep.ui.common.focus.FocusFollowingSelectionManager
|
||||
import ch.dissem.yaep.ui.common.focus.GridSelectionManager
|
||||
import ch.tutteli.atrium.api.fluent.en_GB.notToEqualNull
|
||||
import ch.tutteli.atrium.api.fluent.en_GB.toBeAnInstanceOf
|
||||
import ch.tutteli.atrium.api.fluent.en_GB.toEqual
|
||||
import ch.tutteli.atrium.api.fluent.en_GB.toHaveElementsAndAll
|
||||
import ch.tutteli.atrium.api.fluent.en_GB.toHaveSize
|
||||
import ch.tutteli.atrium.api.verbs.expect
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.fail
|
||||
@@ -25,7 +35,7 @@ class AppTest {
|
||||
var resetCluesBeacon by mutableStateOf(Any())
|
||||
|
||||
@Test
|
||||
fun ensure_app_can_be_rendered_on_1920x1080_and_can_be_solved() = ensure_app_can_be_rendered_on(
|
||||
fun ensure_app_can_be_rendered_on_1920x1080_and_can_be_solved() = showApp(
|
||||
Size(1920f, 1080f)
|
||||
) {
|
||||
val clues = game.clues
|
||||
@@ -49,31 +59,89 @@ class AppTest {
|
||||
} while (removedOptions)
|
||||
|
||||
expect(game.isSolved).toEqual(true)
|
||||
onNodeWithTag("EndOfGame.solved_time").assertExists("End of Game must be shown when puzzle is solved")
|
||||
onNodeWithTag("EndOfGame.solved_time")
|
||||
.assertExists("End of Game must be shown when puzzle is solved")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun ensure_app_can_be_rendered_on_1080x1920() = ensure_app_can_be_rendered_on(
|
||||
fun ensure_app_can_be_rendered_on_1080x1920_and_keyboard_selection_and_deselection_works() = showApp(
|
||||
Size(1080f, 1920f)
|
||||
)
|
||||
) {
|
||||
expect(game.grid[0][1].selection).toEqual(null)
|
||||
expect(FocusFollowingSelectionManager.focused).notToEqualNull()
|
||||
expect(FocusFollowingSelectionManager.focused?.child).toBeAnInstanceOf<GridSelectionManager>()
|
||||
onRoot().performKeyInput {
|
||||
pressKey(Key.DirectionRight)
|
||||
pressKey(Key.One)
|
||||
}
|
||||
expect(game.grid[0][1].selection).notToEqualNull()
|
||||
|
||||
onRoot().performKeyInput {
|
||||
pressKey(Key.Backspace)
|
||||
}
|
||||
expect(game.grid[0][1].selection).toEqual(null)
|
||||
expect(game.grid.map { it.options }).toHaveElementsAndAll {
|
||||
toHaveSize(6)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun ensure_app_can_be_rendered_on_800x600() = ensure_app_can_be_rendered_on(
|
||||
fun ensure_app_can_be_rendered_on_800x600_and_keyboard_option_removal_works() = showApp(
|
||||
Size(800f, 600f)
|
||||
)
|
||||
) {
|
||||
val gridCell = game.grid[0][1]
|
||||
|
||||
expect(gridCell.selection).toEqual(null)
|
||||
onRoot().performKeyInput {
|
||||
pressKey(Key.DirectionRight)
|
||||
withKeyDown(Key.ShiftLeft) {
|
||||
expect(gridCell.options).toHaveSize(6)
|
||||
pressKey(Key.One)
|
||||
expect(gridCell.options).toHaveSize(5)
|
||||
pressKey(Key.Two)
|
||||
expect(gridCell.options).toHaveSize(4)
|
||||
pressKey(Key.Three)
|
||||
expect(gridCell.options).toHaveSize(3)
|
||||
pressKey(Key.Four)
|
||||
expect(gridCell.options).toHaveSize(2)
|
||||
pressKey(Key.Five)
|
||||
expect(gridCell.options).toHaveSize(1)
|
||||
}
|
||||
}
|
||||
expect(gridCell.selection).notToEqualNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun ensure_app_can_be_rendered_on_600x800() = ensure_app_can_be_rendered_on(
|
||||
fun ensure_app_can_be_rendered_on_600x800_and_numpad_option_selection_works() = showApp(
|
||||
Size(600f, 800f)
|
||||
)
|
||||
) {
|
||||
val gridCell = game.grid[0][1]
|
||||
|
||||
fun ensure_app_can_be_rendered_on(
|
||||
onRoot().performKeyInput {
|
||||
pressKey(Key.DirectionRight)
|
||||
withKeyDown(Key.ShiftLeft) {
|
||||
expect(gridCell.options).toHaveSize(6)
|
||||
pressKey(Key.NumPad1)
|
||||
expect(gridCell.options).toHaveSize(5)
|
||||
pressKey(Key.NumPad5)
|
||||
expect(gridCell.options).toHaveSize(4)
|
||||
pressKey(Key.NumPad5)
|
||||
expect(gridCell.options).toHaveSize(5)
|
||||
pressKey(Key.NumPad4)
|
||||
expect(gridCell.options).toHaveSize(4)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun showApp(
|
||||
screenSize: Size,
|
||||
block: suspend SkikoComposeUiTest.() -> Unit = {}
|
||||
) = runSkikoComposeUiTest(size = screenSize) {
|
||||
setContent {
|
||||
App(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
modifier = Modifier.onKeyEvent { event ->
|
||||
FocusFollowingSelectionManager.onKeyEvent(event)
|
||||
},
|
||||
rootSelectionManager = FocusFollowingSelectionManager,
|
||||
spacing = 8.dp,
|
||||
game = game,
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
package ch.dissem.yaep.ui.common
|
||||
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.runComposeUiTest
|
||||
import ch.dissem.yaep.domain.Animal
|
||||
import ch.dissem.yaep.domain.Drink
|
||||
import ch.dissem.yaep.domain.Fruit
|
||||
import ch.dissem.yaep.domain.ItemClass
|
||||
import ch.dissem.yaep.domain.Nationality
|
||||
import ch.dissem.yaep.domain.Profession
|
||||
import ch.dissem.yaep.domain.Transportation
|
||||
import ch.tutteli.atrium.api.fluent.en_GB.notToBeBlank
|
||||
import ch.tutteli.atrium.api.fluent.en_GB.toHaveElementsAndAll
|
||||
import ch.tutteli.atrium.api.verbs.expect
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import kotlin.test.Test
|
||||
|
||||
@OptIn(ExperimentalTestApi::class)
|
||||
class NamesTest {
|
||||
@Test
|
||||
fun ensure_names_are_defined_for_animal() {
|
||||
ensure_names_are_defined_for(Animal.items)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun ensure_names_are_defined_for_nationality() {
|
||||
ensure_names_are_defined_for(Nationality.items)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun ensure_names_are_defined_for_drink() {
|
||||
ensure_names_are_defined_for(Drink.items)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun ensure_names_are_defined_for_profession() {
|
||||
ensure_names_are_defined_for(Profession.items)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun ensure_names_are_defined_for_fruit() {
|
||||
ensure_names_are_defined_for(Fruit.items)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun ensure_names_are_defined_for_dessert() {
|
||||
ensure_names_are_defined_for(Fruit.items)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun ensure_names_are_defined_for_transportation() {
|
||||
ensure_names_are_defined_for(Transportation.items)
|
||||
}
|
||||
|
||||
fun ensure_names_are_defined_for(items: List<ItemClass<*>>) {
|
||||
runComposeUiTest {
|
||||
var strings = listOf<String>()
|
||||
setContent {
|
||||
strings = items.map { stringResource(it.localName) }
|
||||
}
|
||||
expect(strings).toHaveElementsAndAll {
|
||||
notToBeBlank()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
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 ch.tutteli.atrium.api.fluent.en_GB.toEqual
|
||||
import ch.tutteli.atrium.api.verbs.expect
|
||||
@@ -58,10 +56,4 @@ abstract class SelectionManagerTest<F : Focusable<F>, M : SelectionManager<F>> {
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(InternalComposeUiApi::class)
|
||||
fun keyEvent(key: Key, type: KeyEventType = KeyEventType.KeyUp) = KeyEvent(
|
||||
key = key,
|
||||
type = type
|
||||
)
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
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
|
||||
|
||||
@OptIn(InternalComposeUiApi::class)
|
||||
fun keyEvent(key: Key, type: KeyEventType = KeyEventType.KeyUp) = KeyEvent(
|
||||
key = key,
|
||||
type = type
|
||||
)
|
||||
Reference in New Issue
Block a user