M2b: Android skeleton, :core:model contract, :domain passing all vectors

Gradle project in android/ with every module of SPEC §6.2 (build-logic convention plugins, version catalog,
architecture check in check), :core:model types and repository interfaces of §14.2.4 and §14.5, :domain
implementing §14.5.2 and §14.5.4 (125 vector cases), scenario-driven fakes with the empty scenario, Room 3
entities and KvittDatabase v1 with exported schema, :app shell with Hilt, en/sv strings with MissingTranslation
as a lint error, Roborazzi goldens of the empty screen in light and dark.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-17 21:23:43 +02:00
parent 76ee957f41
commit c277ee37c2
93 changed files with 4915 additions and 1 deletions
@@ -0,0 +1,38 @@
package se.hagstedt.kvitt
import androidx.compose.ui.test.junit4.v2.createComposeRule
import androidx.compose.ui.test.onRoot
import com.github.takahirom.roborazzi.captureRoboImage
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import org.robolectric.annotation.GraphicsMode
import se.hagstedt.kvitt.design.KvittTheme
/**
* Golden screenshots of the empty screen in light and dark (Roborazzi on Robolectric). `check` verifies them;
* re-record an intended change with `tools/gradle-serial.sh recordRoborazziDebug` and open every changed PNG.
* Viewport: the Galaxy S26 (about 411 x 891 dp, SPEC §13.1).
*/
@RunWith(RobolectricTestRunner::class)
@GraphicsMode(GraphicsMode.Mode.NATIVE)
@Config(sdk = [36], qualifiers = "w411dp-h891dp-xxhdpi")
class KvittEmptyScreenScreenshotTest {
@get:Rule
val compose = createComposeRule()
@Test
fun emptyScreenLight() = capture(darkTheme = false, name = "empty_screen_light")
@Test
fun emptyScreenDark() = capture(darkTheme = true, name = "empty_screen_dark")
private fun capture(darkTheme: Boolean, name: String) {
compose.setContent {
KvittTheme(darkTheme = darkTheme) { KvittEmptyScreen() }
}
compose.onRoot().captureRoboImage("src/test/screenshots/$name.png")
}
}