This commit was merged in pull request #48.
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
package org.shahondin1624
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.geometry.Rect
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.getBoundsInRoot
|
||||
import androidx.compose.ui.test.onAllNodesWithTag
|
||||
import androidx.compose.ui.test.runComposeUiTest
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.shahondin1624.lib.components.TestTags
|
||||
import org.shahondin1624.lib.components.charactermodel.attributespage.AttributesPage
|
||||
import org.shahondin1624.model.EXAMPLE_CHARACTER
|
||||
import org.shahondin1624.model.attributes.AttributeType
|
||||
import org.shahondin1624.theme.LocalWindowSizeClass
|
||||
import org.shahondin1624.theme.WindowSizeClass
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertFalse
|
||||
|
||||
/**
|
||||
* Verifies that attribute and talent cards never overlap at any screen width.
|
||||
* Tests at 360dp (compact/phone), 768dp (medium/tablet), and 1280dp (expanded/desktop).
|
||||
*/
|
||||
@OptIn(ExperimentalTestApi::class)
|
||||
class NoOverlappingCardsTest {
|
||||
|
||||
private val allAttributeTags = AttributeType.entries.map { TestTags.attributeCard(it.name) }
|
||||
private val character = EXAMPLE_CHARACTER
|
||||
|
||||
/**
|
||||
* Collects the bounding rectangles for all attribute and talent cards,
|
||||
* then asserts no two rectangles intersect.
|
||||
*/
|
||||
private fun assertNoOverlap(tag: String, bounds: List<Pair<String, Rect>>) {
|
||||
for (i in bounds.indices) {
|
||||
for (j in i + 1 until bounds.size) {
|
||||
val (tagA, rectA) = bounds[i]
|
||||
val (tagB, rectB) = bounds[j]
|
||||
val overlaps = rectA.overlaps(rectB) &&
|
||||
rectA.width > 0 && rectA.height > 0 &&
|
||||
rectB.width > 0 && rectB.height > 0
|
||||
assertFalse(
|
||||
overlaps,
|
||||
"Cards overlap at $tag width: '$tagA' $rectA intersects '$tagB' $rectB"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun runOverlapTestAtWidth(widthDp: Int) = runComposeUiTest {
|
||||
val sizeClass = WindowSizeClass.fromWidth(widthDp.dp)
|
||||
|
||||
setContent {
|
||||
CompositionLocalProvider(LocalWindowSizeClass provides sizeClass) {
|
||||
Column(modifier = Modifier.width(widthDp.dp).fillMaxSize()) {
|
||||
AttributesPage(character)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
waitForIdle()
|
||||
|
||||
val bounds = mutableListOf<Pair<String, Rect>>()
|
||||
|
||||
// Collect attribute card bounds
|
||||
for (tag in allAttributeTags) {
|
||||
val nodes = onAllNodesWithTag(tag)
|
||||
val count = nodes.fetchSemanticsNodes().size
|
||||
for (i in 0 until count) {
|
||||
val rect = nodes[i].getBoundsInRoot()
|
||||
bounds.add(tag to Rect(
|
||||
left = rect.left.value,
|
||||
top = rect.top.value,
|
||||
right = rect.right.value,
|
||||
bottom = rect.bottom.value
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
// Collect talent card bounds (sample first few visible)
|
||||
val talentTags = character.talents.talents.take(10).map { TestTags.talentCard(it.name) }
|
||||
for (tag in talentTags) {
|
||||
val nodes = onAllNodesWithTag(tag)
|
||||
val count = nodes.fetchSemanticsNodes().size
|
||||
for (i in 0 until count) {
|
||||
val rect = nodes[i].getBoundsInRoot()
|
||||
bounds.add(tag to Rect(
|
||||
left = rect.left.value,
|
||||
top = rect.top.value,
|
||||
right = rect.right.value,
|
||||
bottom = rect.bottom.value
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
assertNoOverlap("${widthDp}dp", bounds)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun noOverlapAtCompactWidth() = runOverlapTestAtWidth(360)
|
||||
|
||||
@Test
|
||||
fun noOverlapAtMediumWidth() = runOverlapTestAtWidth(768)
|
||||
|
||||
@Test
|
||||
fun noOverlapAtExpandedWidth() = runOverlapTestAtWidth(1280)
|
||||
}
|
||||
Reference in New Issue
Block a user