fix(chat): 分享确认面板一打开就崩 —— 正文那一层绝不能再拿到 Dp.Infinity
真机崩溃栈:heightIn(max = Dp.Infinity) 等于不施加约束,verticalScroll 在无界高度下被测量时 checkScrollableContainerConstraints 直接抛 IllegalStateException(ScrollNode.measure ← SizeNode.measure ← DialogLayout.internalOnMeasure),分享进来、面板刚打开就闪退。 改法:这一层的高度上限只经纯函数 shareConfirmWindowCap() 一个出口 —— 首帧用 SHARE_PREVIEW_MAX_HEIGHT(150dp) 兜底(有限值),展开态这一层不设上限(外层 240dp 仍是有限约束), 并且不再用 Dp.Infinity 当「还没量到」的哨兵值(改用 null)。新增 4 条单测钉住 「任何输入组合都不会产出非有限上限」。
This commit is contained in:
1 parent
af9c63d267
commit
6d4f2cdbae
2 files changed
+91
-17
No files matched your search
@@ -317,3 +317,53 @@ class ShareConfirmTest {
|
||||
assertTrue(SHARE_PREVIEW_COLLAPSE_LABEL.isNotBlank())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* W58:正文那一窗的高度上限**永远不许是 [androidx.compose.ui.unit.Dp.Infinity]**。
|
||||
*
|
||||
* 背景是真机上的一次崩溃:`heightIn(max = Dp.Infinity)` 等于**不施加约束**,而 `verticalScroll`
|
||||
* 一旦在无界高度下被测量,Compose 的 `checkScrollableContainerConstraints` 会直接抛
|
||||
* `IllegalStateException` 把 App 打崩(分享面板一打开就闪退,栈是 `ScrollNode.measure` ←
|
||||
* `SizeNode.measure` ← `DialogLayout.internalOnMeasure`)。
|
||||
*
|
||||
* 这条不变量只能靠纯函数钉住:本模块的 `testImplementation` 只有 junit,没有 Compose UI 测试依赖,
|
||||
* 渲染层的崩溃单测抓不到。
|
||||
*/
|
||||
class ShareConfirmWindowCapTest {
|
||||
|
||||
@Test
|
||||
fun `the fallback cap is finite and never infinity`() {
|
||||
val fallback = shareConfirmWindowCap(measured = null, expanded = false)
|
||||
org.junit.Assert.assertNotNull("首帧必须给出一个上限,不能是 null", fallback)
|
||||
assertTrue("首帧的兜底上限必须是有限值", fallback!!.value.isFinite())
|
||||
assertEquals(SHARE_PREVIEW_MAX_HEIGHT, fallback)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `the expanded state leaves this layer unbounded instead of passing infinity`() {
|
||||
// 展开态是「这一层不设上限」(null),**不是**「给一个无穷大的上限」——后者正是崩溃的成因。
|
||||
org.junit.Assert.assertNull(shareConfirmWindowCap(measured = null, expanded = true))
|
||||
org.junit.Assert.assertNull(shareConfirmWindowCap(measured = 42.dp, expanded = true))
|
||||
// 而且外层仍然是一层**有限**约束在管事。
|
||||
assertTrue(sharePreviewMaxHeight(expanded = true).value.isFinite())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `a measured cap is passed through`() {
|
||||
assertEquals(42.dp, shareConfirmWindowCap(measured = 42.dp, expanded = false))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `no input combination can produce a non finite cap`() {
|
||||
val measured = listOf(null, 0.dp, 1.dp, 150.dp, 10_000.dp)
|
||||
for (m in measured) {
|
||||
for (expanded in listOf(false, true)) {
|
||||
val cap = shareConfirmWindowCap(m, expanded)
|
||||
assertTrue(
|
||||
"m=$m expanded=$expanded 给出了非有限的上限:$cap",
|
||||
cap == null || cap.value.isFinite(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user