Parity gallery: honest populated-state coverage (10/34 surfaces differ)
Fixed & documented, not-just-marketed: - HomeScreen now derives summary card from LocalDataManager.myResidences with VM fallback — populated PNG genuinely differs from empty. - DocumentsScreen added same LocalDataManager fallback pattern + ambient subscription check (bypass SubscriptionHelper's singleton gate). - ScreenshotTests.setUp seeds the global DataManager singleton from the fixture per variant (subscription/user/residences/tasks/docs/contractors/ lookups). Unblocks screens that bypass LocalDataManager. Honest coverage after all fixes: 10/34 surface-pairs genuinely differ (home, profile, residences, contractors, all_tasks, task_templates_browser in dark mode, etc.). The other 24 remain identical because their VMs independently track state via APILayer.getXxx() calls that fail in Robolectric — VM state stays Idle/Error, so gated "populated" branches never render. Root architectural fix needed (not landed here): every VM's xxxState should mirror DataManager.xxx reactively instead of tracking API results independently. That's a ~20-VM refactor tracked as follow-up in docs/parity-gallery.md "Known limitations". Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -97,12 +97,34 @@ class ScreenshotTests(
|
||||
fun captureAllVariants() {
|
||||
Variant.all().forEach { variant ->
|
||||
val fileName = "${surface.name}_${variant.state}_${variant.mode}.png"
|
||||
val fixture = variant.dataManager()
|
||||
// Seed the global DataManager singleton from the fixture. Many
|
||||
// helpers (SubscriptionHelper, screen ViewModels that read
|
||||
// DataManager directly, plus the screens' APILayer-triggered
|
||||
// fallbacks) bypass LocalDataManager and read the singleton. By
|
||||
// seeding here, all three data paths converge on the fixture
|
||||
// data so empty/populated tests produce genuinely different
|
||||
// renders — not just the ones that happen to use LocalDataManager.
|
||||
val dm = com.tt.honeyDue.data.DataManager
|
||||
dm.setSubscription(fixture.subscription.value)
|
||||
dm.setCurrentUser(fixture.currentUser.value)
|
||||
fixture.myResidences.value?.let { dm.setMyResidences(it) }
|
||||
dm.setResidences(fixture.residences.value)
|
||||
fixture.totalSummary.value?.let { dm.setTotalSummary(it) }
|
||||
fixture.allTasks.value?.let { dm.setAllTasks(it) }
|
||||
dm.setDocuments(fixture.documents.value)
|
||||
dm.setContractors(fixture.contractors.value)
|
||||
dm.setFeatureBenefits(fixture.featureBenefits.value)
|
||||
dm.setUpgradeTriggers(fixture.upgradeTriggers.value)
|
||||
dm.setTaskCategories(fixture.taskCategories.value)
|
||||
dm.setTaskPriorities(fixture.taskPriorities.value)
|
||||
dm.setTaskFrequencies(fixture.taskFrequencies.value)
|
||||
captureRoboImage(filePath = "src/androidUnitTest/roborazzi/$fileName") {
|
||||
HoneyDueTheme(
|
||||
themeColors = AppThemes.Default,
|
||||
darkTheme = variant.darkTheme,
|
||||
) {
|
||||
CompositionLocalProvider(LocalDataManager provides variant.dataManager()) {
|
||||
CompositionLocalProvider(LocalDataManager provides fixture) {
|
||||
Box(Modifier.fillMaxSize()) {
|
||||
surface.content()
|
||||
}
|
||||
@@ -110,6 +132,8 @@ class ScreenshotTests(
|
||||
}
|
||||
}
|
||||
}
|
||||
// Reset after suite so other tests don't inherit state.
|
||||
com.tt.honeyDue.data.DataManager.setSubscription(null)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
Reference in New Issue
Block a user