Add Lottie-based global loading overlay across key flows.
Introduce GlobalLoadingCenter with reference counting, wire it through RootView and major auth/order/profile screens, and add the loading animation asset plus unit tests. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
113
suixinkanTests/GlobalLoadingCenterTests.swift
Normal file
113
suixinkanTests/GlobalLoadingCenterTests.swift
Normal file
@ -0,0 +1,113 @@
|
||||
//
|
||||
// GlobalLoadingCenterTests.swift
|
||||
// suixinkanTests
|
||||
//
|
||||
// Created by Codex on 2026/6/23.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
@testable import suixinkan
|
||||
|
||||
@MainActor
|
||||
/// 全局 Loading 命令中心测试,验证展示状态不会泄漏给业务页面使用。
|
||||
final class GlobalLoadingCenterTests: XCTestCase {
|
||||
/// 测试多次 show/hide 会按引用计数控制最终显隐。
|
||||
func testShowHideUsesReferenceCount() {
|
||||
let center = GlobalLoadingCenter()
|
||||
|
||||
center.show(message: "加载账号")
|
||||
center.show(message: "加载权限")
|
||||
|
||||
XCTAssertEqual(center.snapshotForTests, GlobalLoadingSnapshot(isVisible: true, message: "加载权限", activeCount: 2))
|
||||
|
||||
center.hide()
|
||||
XCTAssertEqual(center.snapshotForTests, GlobalLoadingSnapshot(isVisible: true, message: "加载权限", activeCount: 1))
|
||||
|
||||
center.hide()
|
||||
XCTAssertEqual(center.snapshotForTests, GlobalLoadingSnapshot(isVisible: false, message: "", activeCount: 0))
|
||||
}
|
||||
|
||||
/// 测试 hide 调用次数超过 show 时不会产生负数计数。
|
||||
func testHideNeverDropsReferenceCountBelowZero() {
|
||||
let center = GlobalLoadingCenter()
|
||||
|
||||
center.hide()
|
||||
|
||||
XCTAssertEqual(center.snapshotForTests, GlobalLoadingSnapshot(isVisible: false, message: "", activeCount: 0))
|
||||
}
|
||||
|
||||
/// 测试更新文案只影响当前展示内容,不改变引用计数。
|
||||
func testUpdateMessageOnlyChangesVisibleMessage() {
|
||||
let center = GlobalLoadingCenter()
|
||||
|
||||
center.updateMessage("不会展示")
|
||||
XCTAssertEqual(center.snapshotForTests, GlobalLoadingSnapshot(isVisible: false, message: "", activeCount: 0))
|
||||
|
||||
center.show(message: "加载中")
|
||||
center.updateMessage("即将完成")
|
||||
|
||||
XCTAssertEqual(center.snapshotForTests, GlobalLoadingSnapshot(isVisible: true, message: "即将完成", activeCount: 1))
|
||||
}
|
||||
|
||||
/// 测试 withLoading 成功完成后自动隐藏 Loading。
|
||||
func testWithLoadingHidesAfterSuccess() async throws {
|
||||
let center = GlobalLoadingCenter()
|
||||
|
||||
let value = try await center.withLoading(message: "提交中") {
|
||||
XCTAssertEqual(center.snapshotForTests, GlobalLoadingSnapshot(isVisible: true, message: "提交中", activeCount: 1))
|
||||
return 42
|
||||
}
|
||||
|
||||
XCTAssertEqual(value, 42)
|
||||
XCTAssertEqual(center.snapshotForTests, GlobalLoadingSnapshot(isVisible: false, message: "", activeCount: 0))
|
||||
}
|
||||
|
||||
/// 测试 withLoading 抛错时也会自动隐藏 Loading。
|
||||
func testWithLoadingHidesAfterFailure() async {
|
||||
let center = GlobalLoadingCenter()
|
||||
|
||||
do {
|
||||
_ = try await center.withLoading(message: "提交中") {
|
||||
throw TestFailure.expected
|
||||
} as Int
|
||||
XCTFail("withLoading 应该向外抛出业务错误")
|
||||
} catch {
|
||||
XCTAssertEqual(error as? TestFailure, .expected)
|
||||
}
|
||||
|
||||
XCTAssertEqual(center.snapshotForTests, GlobalLoadingSnapshot(isVisible: false, message: "", activeCount: 0))
|
||||
}
|
||||
|
||||
/// 测试 withOptionalLoading 关闭时不会改变展示状态。
|
||||
func testWithOptionalLoadingDisabledDoesNotChangeState() async throws {
|
||||
let center = GlobalLoadingCenter()
|
||||
|
||||
let value = try await center.withOptionalLoading(false, message: "不展示") {
|
||||
XCTAssertEqual(center.snapshotForTests, GlobalLoadingSnapshot(isVisible: false, message: "", activeCount: 0))
|
||||
return "done"
|
||||
}
|
||||
|
||||
XCTAssertEqual(value, "done")
|
||||
XCTAssertEqual(center.snapshotForTests, GlobalLoadingSnapshot(isVisible: false, message: "", activeCount: 0))
|
||||
}
|
||||
|
||||
/// 测试使用 Loading 不需要读取可观察展示状态,业务侧只能拿到命令中心类型。
|
||||
func testBusinessCodeOnlyDependsOnCommandCenter() {
|
||||
let center = GlobalLoadingCenter()
|
||||
|
||||
issueLoadingCommand(center)
|
||||
|
||||
XCTAssertEqual(center.snapshotForTests, GlobalLoadingSnapshot(isVisible: true, message: "加载中", activeCount: 1))
|
||||
center.hide()
|
||||
}
|
||||
|
||||
/// 模拟业务代码只接收命令中心并发出展示指令。
|
||||
private func issueLoadingCommand(_ center: GlobalLoadingCenter) {
|
||||
center.show(message: "加载中")
|
||||
}
|
||||
|
||||
/// 测试用错误类型。
|
||||
private enum TestFailure: Error, Equatable {
|
||||
case expected
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user