Files
web-terminal/ios/App/WebTermTests/ProjectsLayoutTests.swift
Yaojia Wang 823432b1c8 feat(ipad): W1-W3 — adaptive split-view layout + finding fixes
T-iPad-2: AdaptiveRootView/LayoutPolicy (sole size-class decision), SplitRootView
(NavigationSplitView sidebar+detail), StackRootView (iPhone path verbatim, zero
regression); privacy shade hoisted to shared ZStack top for both branches
T-iPad-3: KeyBarVisibility predicate (hide when hardware keyboard present),
pointer context menu (copy/new-in-cwd/kill, all via existing channels)
T-iPad-4: Projects multi-column grid on iPad (idiom-gated), adaptive sheet detents
T-iPad-5 findings (4/4 fixed): kill onKillSession thread-through +
AppCoordinator.killCurrentSession; split route-gated to .sessions (iPad first-run
pairing); continue-last banner in split sidebar; iPad XCUITest deferred (covered
by SidebarSelectionTests)
Verified: iPhone 16 277 + iPad Pro 11 278 tests green; packages 261 + integration 10;
zero changes under ios/Packages, src/, public/
2026-07-05 19:58:30 +02:00

76 lines
3.5 KiB
Swift
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import SwiftUI
import Testing
import UIKit
@testable import WebTerm
/// T-iPad-4 · Projects ** idiom + **
/// 仿 `LayoutPolicy` `ProjectsLayout` idiom
/// size classiPad Projects sheet compact iPhone
/// size class iPhone
///
/// iPhone `.phone`
/// 1 Listsheet detents nil =
/// sheet`.pad`
@Suite("ProjectsGridLayout column count (T-iPad-4)")
struct ProjectsGridLayoutTests {
// MARK: - iPhone 1 /
@Test(".phone → 恒 1 列,宽度无关(含横屏宽尺寸,现有单列 List 原样复用)")
func phoneIsAlwaysSingleColumn() {
#expect(ProjectsGridLayout.columnCount(availableWidth: 320, idiom: .phone) == 1)
// iPhone ~852
#expect(ProjectsGridLayout.columnCount(availableWidth: 852, idiom: .phone) == 1)
#expect(ProjectsGridLayout.columnCount(availableWidth: 2000, idiom: .phone) == 1)
}
@Test(".phone 不走网格;.pad 走网格")
func usesGridOnlyOnPad() {
#expect(ProjectsGridLayout.usesGrid(idiom: .phone) == false)
#expect(ProjectsGridLayout.usesGrid(idiom: .pad) == true)
}
// MARK: - iPad 1/2/3
@Test(".pad 且窄于两列阈值 → 1 列(极窄 iPad 多任务,绝不挤压)")
func padNarrowIsSingleColumn() {
#expect(ProjectsGridLayout.columnCount(
availableWidth: ProjectsGridLayout.twoColumnMinWidth - 1, idiom: .pad) == 1)
}
@Test(".pad 且在 [两列阈值, 三列阈值) → 2 列(表单 sheet 内宽即此档)")
func padMediumIsTwoColumns() {
#expect(ProjectsGridLayout.columnCount(
availableWidth: ProjectsGridLayout.twoColumnMinWidth, idiom: .pad) == 2)
#expect(ProjectsGridLayout.columnCount(
availableWidth: ProjectsGridLayout.threeColumnMinWidth - 1, idiom: .pad) == 2)
}
@Test(".pad 且 >= 三列阈值 → 3 列(更宽面板/横屏全宽)")
func padWideIsThreeColumns() {
#expect(ProjectsGridLayout.columnCount(
availableWidth: ProjectsGridLayout.threeColumnMinWidth, idiom: .pad) == 3)
#expect(ProjectsGridLayout.columnCount(availableWidth: 1400, idiom: .pad) == 3)
}
@Test("列数恒 >= 1任何宽度都不返回 0/负,防空网格崩溃)")
func columnCountIsAlwaysPositive() {
for width in stride(from: CGFloat(0), through: 2000, by: 137) {
#expect(ProjectsGridLayout.columnCount(availableWidth: width, idiom: .pad) >= 1)
#expect(ProjectsGridLayout.columnCount(availableWidth: width, idiom: .phone) == 1)
}
}
}
@Suite("ProjectsSheetSizing (T-iPad-4)")
struct ProjectsSheetSizingTests {
@Test(".phone → nil不加 detent 修饰符 = 现有默认全高 sheet字节级不变")
func phoneIsNil() {
#expect(ProjectsSheetSizing.detents(idiom: .phone) == nil)
}
@Test(".pad → [.medium, .large]iPad 卡片式,不铺满大屏;仍可上拉到大)")
func padIsCardDetents() {
#expect(ProjectsSheetSizing.detents(idiom: .pad) == [.medium, .large])
}
}