diff --git a/app/src/test/java/eu/darken/capod/common/upgrade/ui/BrandTitleTest.kt b/app/src/test/java/eu/darken/capod/common/upgrade/ui/BrandTitleTest.kt index ed8579a7..a2bfe594 100644 --- a/app/src/test/java/eu/darken/capod/common/upgrade/ui/BrandTitleTest.kt +++ b/app/src/test/java/eu/darken/capod/common/upgrade/ui/BrandTitleTest.kt @@ -2,6 +2,7 @@ package eu.darken.capod.common.upgrade.ui import android.content.Context import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.AnnotatedString import androidx.test.core.app.ApplicationProvider import eu.darken.capod.R @@ -74,6 +75,31 @@ class BrandTitleTest : BaseComposeRobolectricTest() { result.text.substring(span.start, span.end) shouldBe qualifier } + @Test + fun `the highlight defaults to the upgraded brand color`() { + val result = capture { brandTitle(includeQualifier = true, highlightQualifier = true) } + + result.spanStyles.single().item.color shouldBe Color(context.getColor(R.color.brand_tertiary)) + } + + // The toolbar tints by flavor — FOSS on brand_secondary, Pro on brand_tertiary — so the color + // is a parameter rather than a constant. Without this, hardcoding the default back into + // brandTitle would keep every other assertion green while the FOSS toolbar lost its tint. + @Test + fun `a caller-supplied highlight color is the one applied`() { + val custom = Color(context.getColor(R.color.brand_secondary)) + + val result = capture { + brandTitle(includeQualifier = true, highlightQualifier = true, highlightColor = custom) + } + + result.spanStyles.single().item.color shouldBe custom + result.text.substring( + result.spanStyles.single().start, + result.spanStyles.single().end, + ) shouldBe qualifier + } + // The markers are injected as format arguments, so a template or formatter that mangled them // would leak U+FFFC / U+FFF9 into the toolbar. @Test diff --git a/app/src/testGplay/java/eu/darken/capod/common/upgrade/ui/BrandTitleTemplateLocalesTest.kt b/app/src/testGplay/java/eu/darken/capod/common/upgrade/ui/BrandTitleTemplateLocalesTest.kt index 2e5f9be8..01eecde0 100644 --- a/app/src/testGplay/java/eu/darken/capod/common/upgrade/ui/BrandTitleTemplateLocalesTest.kt +++ b/app/src/testGplay/java/eu/darken/capod/common/upgrade/ui/BrandTitleTemplateLocalesTest.kt @@ -63,16 +63,26 @@ class BrandTitleTemplateLocalesTest { locales shouldHaveAtLeastSize 60 } + // Asserted against the FORMATTER'S OUTPUT rather than against the template text, because the + // format grammar is bigger than it looks: `%1$s %2$s % - val template = localized(tag).getString(R.string.app_name_upgraded_template) - val specifiers = FORMAT_SPECIFIER - .findAll(template.replace("%%", "")) - .map { it.value } - .sorted() - .toList() - if (specifiers == listOf("%1\$s", "%2\$s")) null else "$tag -> $template" + val formatted = localized(tag).getString( + R.string.app_name_upgraded_template, + BRAND_TITLE_MARKER, + BRAND_QUALIFIER_MARKER, + ) + val names = formatted.split(BRAND_TITLE_MARKER).size - 1 + val qualifiers = formatted.split(BRAND_QUALIFIER_MARKER).size - 1 + if (names == 1 && qualifiers == 1) { + null + } else { + "$tag -> name x$names, qualifier x$qualifiers in '$formatted'" + } } offenders shouldBe emptyList() @@ -89,11 +99,17 @@ class BrandTitleTemplateLocalesTest { val result = compose(ctx) val span = result.spanStyles.singleOrNull() + // What Android itself produces for this template. Comparing against it is what proves + // the splice REPRODUCED the translator's arrangement rather than quietly discarding a + // damaged template and rebuilding the default — a fallback renders a plausible title + // with exactly one correctly-styled qualifier, so every other assertion here passes + // straight through it. + val expected = ctx.getString(R.string.app_name_upgraded_template, name, qualifier) when { name.isBlank() || qualifier.isBlank() -> "$tag -> blank part" result.text.contains(BRAND_TITLE_MARKER) -> "$tag -> name marker leaked" result.text.contains(BRAND_QUALIFIER_MARKER) -> "$tag -> qualifier marker leaked" - !result.text.contains(name) -> "$tag -> name missing from '${result.text}'" + result.text != expected -> "$tag -> rendered '${result.text}', formatter says '$expected'" span == null -> "$tag -> expected one span, got ${result.spanStyles.size}" result.text.substring(span.start, span.end) != qualifier -> "$tag -> span covers '${result.text.substring(span.start, span.end)}', want '$qualifier'" @@ -104,8 +120,4 @@ class BrandTitleTemplateLocalesTest { offenders shouldBe emptyList() } - - companion object { - private val FORMAT_SPECIFIER = Regex("""%(\d+\$)?[a-zA-Z]""") - } }