Test the rule that chooses the dictionary's container
The guard added in #3 decides whether the dictionary opens beside the poem or as a sheet over it, and until now nothing proved it. I tried four times to verify it by hand and failed every time: reaching it needs a tap landing on the glyphs of one Persian word inside a SelectionContainer, and adb's synthetic taps either became a long press and opened the selection menu, or landed between words and opened the couplet's actions instead. The verses are not exposed to uiautomator either, so there is nothing to aim at. The arithmetic behind the rule can be tested even though the gesture cannot, so it moves into a pure function and gets four cases: a tablet keeps the panel, a foldable open in portrait does not, a phone never gets it however wide the page is measured, and the boundary sits exactly at the panel plus the minimum measure (616dp passes, 615dp does not). No behaviour changes — this is the same expression, named and covered. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
701b984f4b
commit
3486a89b56
@ -111,7 +111,7 @@ fun PoemScreen(
|
|||||||
// foldable held open in portrait the page is already down to ~450dp, and a panel beside it
|
// foldable held open in portrait the page is already down to ~450dp, and a panel beside it
|
||||||
// left the verse a couple of characters a line. Where it does not fit, the sheet is the
|
// left the verse a couple of characters a line. Where it does not fit, the sheet is the
|
||||||
// better answer: it covers the foot of the poem but leaves the lines whole.
|
// better answer: it covers the foot of the poem but leaves the lines whole.
|
||||||
val roomForPanel = wide && maxWidth - DictionaryPanelWidth >= MinPageMeasure
|
val roomForPanel = dictionaryFitsBeside(maxWidth, wide)
|
||||||
|
|
||||||
Load(
|
Load(
|
||||||
key = fullUrl,
|
key = fullUrl,
|
||||||
|
|||||||
@ -39,6 +39,7 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.platform.LocalLayoutDirection
|
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.LayoutDirection
|
import androidx.compose.ui.unit.LayoutDirection
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.ganjoor.android.R
|
import com.ganjoor.android.R
|
||||||
import com.ganjoor.android.data.Definition
|
import com.ganjoor.android.data.Definition
|
||||||
@ -64,6 +65,21 @@ val DictionaryPanelWidth = 216.dp
|
|||||||
*/
|
*/
|
||||||
val MinPageMeasure = 400.dp
|
val MinPageMeasure = 400.dp
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the dictionary earns a column of its own beside a page [pageWidth] wide.
|
||||||
|
*
|
||||||
|
* Not a question about the window but about the page: by the time a poem is open the columns have
|
||||||
|
* already taken their room, and on a book-style foldable held open in portrait what is left is
|
||||||
|
* about 450dp. A panel beside that leaves the verse a couple of characters a line, so below
|
||||||
|
* [MinPageMeasure] the bottom sheet is used instead — it covers the foot of the poem but leaves
|
||||||
|
* every line whole.
|
||||||
|
*
|
||||||
|
* A pure function so the rule can be tested: the gesture that reaches it cannot be driven
|
||||||
|
* reliably, but the arithmetic behind it can.
|
||||||
|
*/
|
||||||
|
internal fun dictionaryFitsBeside(pageWidth: Dp, wide: Boolean): Boolean =
|
||||||
|
wide && pageWidth - DictionaryPanelWidth >= MinPageMeasure
|
||||||
|
|
||||||
/** English prose inside an otherwise right-to-left sheet. */
|
/** English prose inside an otherwise right-to-left sheet. */
|
||||||
@Composable
|
@Composable
|
||||||
private fun LeftToRight(content: @Composable () -> Unit) {
|
private fun LeftToRight(content: @Composable () -> Unit) {
|
||||||
|
|||||||
@ -0,0 +1,41 @@
|
|||||||
|
package com.ganjoor.android
|
||||||
|
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.ganjoor.android.ui.dictionaryFitsBeside
|
||||||
|
import org.junit.Assert.assertFalse
|
||||||
|
import org.junit.Assert.assertTrue
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The rule that decides whether the dictionary opens beside the poem or as a sheet over it.
|
||||||
|
*
|
||||||
|
* Driving the gesture that reaches it — a tap landing on the glyphs of one Persian word — is not
|
||||||
|
* something adb does reliably, so the arithmetic is tested directly instead.
|
||||||
|
*/
|
||||||
|
class DictionaryPanelFitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `a tablet has room beside the poem`() {
|
||||||
|
// 1280dp window, less the poets rail and two list columns, leaves the page about 900dp.
|
||||||
|
assertTrue(dictionaryFitsBeside(900.dp, wide = true))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `a foldable open in portrait does not`() {
|
||||||
|
// 700dp window, less the rail and the newest column, leaves about 450dp — and 450 less
|
||||||
|
// the 216dp panel is 234dp, which is a cramped phone column, not a measure for a verse.
|
||||||
|
assertFalse(dictionaryFitsBeside(450.dp, wide = true))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `a phone never gets the panel, however the page is measured`() {
|
||||||
|
assertFalse(dictionaryFitsBeside(420.dp, wide = false))
|
||||||
|
assertFalse(dictionaryFitsBeside(2000.dp, wide = false))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `the boundary is the panel plus the minimum measure`() {
|
||||||
|
assertTrue(dictionaryFitsBeside(616.dp, wide = true)) // 400 + 216, exactly
|
||||||
|
assertFalse(dictionaryFitsBeside(615.dp, wide = true))
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user