// // GalleryManifestParityTest.swift // HoneyDueTests // // Parity gate — asserts `SnapshotGalleryTests.swift`'s covered-screen // set matches exactly the subset of screens in the canonical // `GalleryScreens` manifest (in // `composeApp/src/commonMain/.../testing/GalleryManifest.kt`) with // `Platform.IOS` in their `platforms`. // // If this fails, either: // - A new `test_()` was added to `SnapshotGalleryTests.swift` // but the name isn't in the canonical manifest — add it to // `GalleryScreens.all`. // - A new screen was added to the manifest but there's no matching // `test_()` function in the Swift test file — write one. // - A rename landed on only one side — reconcile. // // Together with the Android `GalleryManifestParityTest`, this keeps // the two platforms from silently drifting apart in coverage. // import XCTest import ComposeApp @MainActor final class GalleryManifestParityTest: XCTestCase { /// Canonical names of every surface covered by /// `SnapshotGalleryTests.swift`. This must be updated whenever a /// new `test_()` is added to the suite. The parity assertion /// below catches a missed update. /// /// Using a hand-maintained list (rather than runtime introspection /// of `XCTestCase` selectors) keeps the contract explicit and makes /// drifts obvious in a diff. private static let iosCoveredScreens: Set = [ // Auth "login", "register", "forgot_password", "verify_reset_code", "reset_password", "verify_email", // Onboarding "onboarding_welcome", "onboarding_value_props", "onboarding_create_account", "onboarding_verify_email", "onboarding_location", "onboarding_name_residence", "onboarding_home_profile", "onboarding_join_residence", "onboarding_first_task", "onboarding_subscription", // Residences "residences", "residence_detail", "add_residence", "edit_residence", "join_residence", "manage_users", // Tasks "all_tasks", "add_task", "add_task_with_residence", "edit_task", "complete_task", "task_suggestions", "task_templates_browser", // Contractors "contractors", "contractor_detail", // Documents "documents_warranties", "document_detail", "add_document", "edit_document", // Profile / settings "profile", "profile_edit", "notification_preferences", "theme_selection", // Subscription "feature_comparison", ] func test_ios_surfaces_match_canonical_manifest() { // `GalleryScreens.shared.forIos` is the Swift-bridged map of // `GalleryScreen` keyed by canonical name. SKIE exposes the // Kotlin `object GalleryScreens` as a Swift type with a // `shared` instance accessor. let manifestKeys = Set(GalleryScreens.shared.forIos.keys.compactMap { $0 as? String }) let missing = manifestKeys.subtracting(Self.iosCoveredScreens) let extra = Self.iosCoveredScreens.subtracting(manifestKeys) if !missing.isEmpty || !extra.isEmpty { var message = "iOS SnapshotGalleryTests drifted from canonical manifest.\n" if !missing.isEmpty { message += "\nScreens in manifest but missing test_() in Swift:\n" for name in missing.sorted() { message += " - \(name)\n" } } if !extra.isEmpty { message += "\nScreens covered by Swift tests but missing from manifest:\n" for name in extra.sorted() { message += " - \(name)\n" } } message += "\nReconcile by editing com.tt.honeyDue.testing.GalleryScreens and/or\n" message += "SnapshotGalleryTests.swift (plus iosCoveredScreens above) so all three agree.\n" XCTFail(message) } } }