P1 Stream B: port iOS brand assets to Android

- outline, tab_view, app_icon_mark, widget_icon: rasterized from iOS
  PDF/PNG sources at 1024px (gradients/shadows would flatten via SVG trace)
- honeycomb_texture: hand-authored VectorDrawable, seamless hex tiling
  verified at 4x4 render
- widget_icon: adaptive icon (mipmap-anydpi-v26) + density-specific
  mipmap + foreground bitmaps (mdpi..xxxhdpi)
- Source PDFs preserved in docs/ios-parity/source-assets/ for future
  re-rasterization

AssetInventoryTest asserts all 5 Res.drawable entries resolve.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Trey T
2026-04-18 12:35:31 -05:00
parent db181c0d6a
commit 7aab8b0f29
22 changed files with 135 additions and 0 deletions
@@ -0,0 +1,53 @@
package com.tt.honeyDue.resources
import honeydue.composeapp.generated.resources.Res
import honeydue.composeapp.generated.resources.app_icon_mark
import honeydue.composeapp.generated.resources.honeycomb_texture
import honeydue.composeapp.generated.resources.outline
import honeydue.composeapp.generated.resources.tab_view
import honeydue.composeapp.generated.resources.widget_icon
import org.jetbrains.compose.resources.ExperimentalResourceApi
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
/**
* P1 Stream B — Asset port inventory.
*
* Guards iOS → Android brand-asset parity. Each referenced drawable must
* exist in composeResources so the generated `Res.drawable.<name>` accessor
* compiles. Any removal will fail at compile time, not silently at runtime.
*
* Sources documented in docs/ios-parity/source-assets/ (commit-tracked).
*/
@OptIn(ExperimentalResourceApi::class)
class AssetInventoryTest {
@Test
fun all_ported_assets_exist() {
// Fails to compile if any of these generated symbols don't exist.
val assets = listOf(
Res.drawable.outline,
Res.drawable.tab_view,
Res.drawable.app_icon_mark,
Res.drawable.honeycomb_texture,
Res.drawable.widget_icon
)
assertEquals(5, assets.size, "Expected 5 ported brand assets")
assets.forEach { assertNotNull(it) }
}
@Test
fun assets_are_distinct_resources() {
// Ensures no accidental alias/duplicate definitions.
val assets = setOf(
Res.drawable.outline,
Res.drawable.tab_view,
Res.drawable.app_icon_mark,
Res.drawable.honeycomb_texture,
Res.drawable.widget_icon
)
assertEquals(5, assets.size, "All ported assets must be distinct DrawableResource instances")
}
}