Ariver
2026-06-12 9c898b0ca61c090e5e327f750f6c73e28475e10b
C1.source/Tests/AlignerCoreTests/AlignerCoreTests.swift
@@ -873,6 +873,7 @@
                "schemaVersion",
                "quickSwitch.showMinimizedWindows",
                "quickSwitch.showFullscreenWindows",
                "quickSwitch.waterfallViewMode",
                "appearance.theme",
                "appearance.language",
                "spaces.displayStrategy"
@@ -885,9 +886,10 @@
    }
    func testDefaultPreferencesMatchRound0Decisions() {
        XCTAssertEqual(PreferenceSchema.version, 1)
        XCTAssertEqual(PreferenceSchema.version, 2)
        XCTAssertEqual(PreferenceSchema.defaults.showMinimizedWindows, true)
        XCTAssertEqual(PreferenceSchema.defaults.showFullscreenWindows, true)
        XCTAssertEqual(PreferenceSchema.defaults.quickSwitchWaterfallViewMode, .verticalColumns)
        XCTAssertEqual(PreferenceSchema.defaults.theme, .system)
        XCTAssertEqual(PreferenceSchema.defaults.language, .system)
        XCTAssertEqual(PreferenceSchema.defaults.spaceDisplayStrategy, .includeVisibleAndFullscreen)
@@ -908,6 +910,7 @@
        let preferences = AlignerPreferences(
            showMinimizedWindows: false,
            showFullscreenWindows: false,
            quickSwitchWaterfallViewMode: .horizontalMasonry,
            theme: .dark,
            language: .simplifiedChinese,
            spaceDisplayStrategy: .currentSpaceOnly
@@ -945,12 +948,14 @@
        userDefaults.set("not-a-theme", forKey: PreferenceKey.theme.storageKey)
        userDefaults.set("not-a-language", forKey: PreferenceKey.language.storageKey)
        userDefaults.set("not-a-space-strategy", forKey: PreferenceKey.spaceDisplayStrategy.storageKey)
        userDefaults.set("not-a-waterfall-mode", forKey: PreferenceKey.quickSwitchWaterfallViewMode.storageKey)
        let preferences = UserDefaultsPreferenceStore(userDefaults: userDefaults).read()
        XCTAssertEqual(preferences.theme, PreferenceSchema.defaults.theme)
        XCTAssertEqual(preferences.language, PreferenceSchema.defaults.language)
        XCTAssertEqual(preferences.spaceDisplayStrategy, PreferenceSchema.defaults.spaceDisplayStrategy)
        XCTAssertEqual(preferences.quickSwitchWaterfallViewMode, PreferenceSchema.defaults.quickSwitchWaterfallViewMode)
    }
    @MainActor
@@ -1279,6 +1284,163 @@
        XCTAssertEqual(viewModel.waterfallColumns.flatMap { $0.windows.map(\.primarySpaceLabel) }, ["01", "02"])
    }
    func testQuickSwitchSpaceFilterProjectsAppShelfAndWaterfallWithoutChangingSpaceLane() {
        let alpha = AlignerApp(bundleIdentifier: "com.example.Alpha", name: "Alpha", category: .generic)
        let beta = AlignerApp(bundleIdentifier: "com.example.Beta", name: "Beta", category: .generic)
        let snapshot = QuickSwitchSnapshotBuilder.snapshot(
            displays: [makeDisplay(spaceIDs: [10, 11])],
            windows: [
                AlignerWindow(id: 1, app: alpha, title: "A1", spaceIDs: [10]),
                AlignerWindow(id: 2, app: alpha, title: "A2", spaceIDs: [11]),
                AlignerWindow(id: 3, app: beta, title: "B1", spaceIDs: [11]),
                AlignerWindow(id: 4, app: beta, title: "No Space")
            ]
        )
        let viewModel = QuickSwitchViewModelBuilder.viewModel(from: snapshot)
        let filtered = QuickSwitchSpaceFilterPolicy.projectedViewModel(
            from: viewModel,
            lockedSpaceID: 11
        )
        XCTAssertEqual(filtered.lockedSpaceID, 11)
        XCTAssertEqual(filtered.displays.flatMap { $0.spaces.map(\.id) }, [10, 11])
        XCTAssertEqual(filtered.displays.flatMap { $0.spaces.map(\.windowCount) }, [1, 2])
        XCTAssertEqual(filtered.appShelf.map(\.app.name), ["Alpha", "Beta"])
        XCTAssertEqual(filtered.appShelf.map(\.windowCount), [1, 1])
        XCTAssertEqual(filtered.appShelf.flatMap(\.primarySpaceIDs), [11, 11])
        XCTAssertEqual(filtered.waterfallColumns.flatMap { $0.windows.map(\.window.id) }, [2, 3])
        XCTAssertEqual(filtered.waterfallColumns.flatMap { $0.windows.map(\.windowIndex) }, [0, 0])
        XCTAssertEqual(filtered.waterfallColumns.flatMap { $0.windows.map(\.globalIndex) }, [0, 1])
        XCTAssertEqual(filtered.initialSelection, QuickSwitchSelection(appGroupIndex: 0, windowIndex: 0, windowID: 2))
    }
    func testQuickSwitchSpaceFilterKeyboardNavigationStaysInsideFilteredCollection() {
        let alpha = AlignerApp(bundleIdentifier: "com.example.Alpha", name: "Alpha", category: .generic)
        let beta = AlignerApp(bundleIdentifier: "com.example.Beta", name: "Beta", category: .generic)
        let snapshot = QuickSwitchSnapshotBuilder.snapshot(
            displays: [makeDisplay(spaceIDs: [10, 11])],
            windows: [
                AlignerWindow(id: 1, app: alpha, title: "Alpha A1", spaceIDs: [10]),
                AlignerWindow(id: 2, app: alpha, title: "Alpha A2", spaceIDs: [11]),
                AlignerWindow(id: 3, app: beta, title: "Beta A2", spaceIDs: [11]),
                AlignerWindow(id: 4, app: beta, title: "Beta No Space")
            ]
        )
        let viewModel = QuickSwitchViewModelBuilder.viewModel(from: snapshot)
        let filtered = QuickSwitchSpaceFilterPolicy.projectedViewModel(
            from: viewModel,
            lockedSpaceID: 11
        )
        let filteredSnapshot = QuickSwitchSnapshot(
            displays: snapshot.displays,
            appGroups: filtered.waterfallColumns.map { column in
                QuickSwitchAppGroup(
                    app: column.app,
                    windows: column.windows.map {
                        QuickSwitchWindowItem(window: $0.window, primarySpaceID: $0.primarySpaceID)
                    }
                )
            }
        )
        XCTAssertEqual(filtered.initialSelection, QuickSwitchSelection(appGroupIndex: 0, windowIndex: 0, windowID: 2))
        XCTAssertEqual(
            QuickSwitchFocusPolicy.nextSelection(
                from: filtered.initialSelection!,
                in: filteredSnapshot,
                direction: .right
            ),
            QuickSwitchSelection(appGroupIndex: 1, windowIndex: 0, windowID: 3)
        )
        XCTAssertEqual(
            QuickSwitchFocusPolicy.nextSelection(
                from: QuickSwitchSelection(appGroupIndex: 1, windowIndex: 0, windowID: 3),
                in: filteredSnapshot,
                direction: .right
            ),
            QuickSwitchSelection(appGroupIndex: 1, windowIndex: 0, windowID: 3)
        )
        XCTAssertFalse(filteredSnapshot.appGroups.flatMap(\.windows).contains { $0.window.id == 1 || $0.window.id == 4 })
    }
    func testQuickSwitchSpaceFilterCanLockEmptySpaceWithoutChangingSpaceLane() {
        let app = AlignerApp(bundleIdentifier: "com.example.Alpha", name: "Alpha", category: .generic)
        let snapshot = QuickSwitchSnapshotBuilder.snapshot(
            displays: [makeDisplay(spaceIDs: [10, 11])],
            windows: [
                AlignerWindow(id: 1, app: app, title: "A1", spaceIDs: [10])
            ]
        )
        let viewModel = QuickSwitchViewModelBuilder.viewModel(from: snapshot)
        let filtered = QuickSwitchSpaceFilterPolicy.projectedViewModel(
            from: viewModel,
            lockedSpaceID: 11
        )
        XCTAssertEqual(filtered.lockedSpaceID, 11)
        XCTAssertEqual(filtered.displays.flatMap { $0.spaces.map(\.id) }, [10, 11])
        XCTAssertTrue(filtered.appShelf.isEmpty)
        XCTAssertTrue(filtered.waterfallColumns.isEmpty)
        XCTAssertNil(filtered.initialSelection)
    }
    func testQuickSwitchSpaceFilterRestoresPreferredSelectionWhenUnlocking() {
        let app = AlignerApp(bundleIdentifier: "com.example.Alpha", name: "Alpha", category: .generic)
        let snapshot = QuickSwitchSnapshotBuilder.snapshot(
            displays: [makeDisplay(spaceIDs: [10, 11])],
            windows: [
                AlignerWindow(id: 1, app: app, title: "A1", spaceIDs: [10]),
                AlignerWindow(id: 2, app: app, title: "A2", spaceIDs: [11])
            ]
        )
        let viewModel = QuickSwitchViewModelBuilder.viewModel(from: snapshot)
        let preferred = QuickSwitchSelection(appGroupIndex: 0, windowIndex: 1, windowID: 2)
        let unlocked = QuickSwitchSpaceFilterPolicy.projectedViewModel(
            from: viewModel,
            lockedSpaceID: nil,
            preferredSelection: preferred
        )
        XCTAssertNil(unlocked.lockedSpaceID)
        XCTAssertEqual(unlocked.initialSelection, preferred)
    }
    func testQuickSwitchSpaceFilterDetectsOnlySingleFullscreenWindowSpacesAsDirectActivation() {
        let alpha = AlignerApp(bundleIdentifier: "com.example.Alpha", name: "Alpha", category: .generic)
        let beta = AlignerApp(bundleIdentifier: "com.example.Beta", name: "Beta", category: .generic)
        let displayUUID = "display-a"
        let snapshot = QuickSwitchSnapshotBuilder.snapshot(
            displays: [
                AlignerDisplay(
                    uuid: displayUUID,
                    physical: true,
                    spaces: [
                        AlignerSpace(id: 10, type: .user, displayUUID: displayUUID, index: 1),
                        AlignerSpace(id: 11, type: .fullscreen, displayUUID: displayUUID, index: 2),
                        AlignerSpace(id: 12, type: .fullscreen, displayUUID: displayUUID, index: 3)
                    ]
                )
            ],
            windows: [
                AlignerWindow(id: 1, app: alpha, title: "Normal", spaceIDs: [10]),
                AlignerWindow(id: 2, app: alpha, title: "Fullscreen", isFullscreen: true, spaceIDs: [11]),
                AlignerWindow(id: 3, app: beta, title: "Split A", isFullscreen: true, spaceIDs: [12]),
                AlignerWindow(id: 4, app: beta, title: "Split B", isFullscreen: true, spaceIDs: [12])
            ]
        )
        let viewModel = QuickSwitchViewModelBuilder.viewModel(from: snapshot)
        XCTAssertEqual(
            QuickSwitchSpaceFilterPolicy.singleFullscreenSelection(inSpaceID: 11, viewModel: viewModel),
            QuickSwitchSelection(appGroupIndex: 0, windowIndex: 1, windowID: 2)
        )
        XCTAssertNil(QuickSwitchSpaceFilterPolicy.singleFullscreenSelection(inSpaceID: 10, viewModel: viewModel))
        XCTAssertNil(QuickSwitchSpaceFilterPolicy.singleFullscreenSelection(inSpaceID: 12, viewModel: viewModel))
    }
    func testQuickSwitchFocusPolicySelectsFirstStableWindowInitially() {
        let app = makeApp()
        let snapshot = QuickSwitchSnapshotBuilder.snapshot(