test(ai): add LLMSession/AIRuntime smoke tests (no real inference)

iOS Simulator sandbox 看不到 host ~/tiji-models;Mac Designed for iPad
卡 code signing。真实推理验证由 DebugAIRunner 手动跑,结果记 W2 retro。
W3 把核心 LLM 接口拆独立 SPM target 后,可在 Mac 原生跑真实推理。

烟测覆盖:
- TokenChunk 值字段
- AIRuntimeError 3 case 都有 errorDescription
- AIRuntime actor status 可异步读取
This commit is contained in:
link2026
2026-05-25 23:33:04 +08:00
parent b63b26bce5
commit e3ad24ac0e

View File

@@ -0,0 +1,55 @@
import Testing
import Foundation
@testable import
/// LLM session
///
/// ****iOS Simulator sandbox `~/tiji-models/`,
/// Mac Designed for iPad code signing macOS App
/// `DebugAIRunner` (`MeView` ), W2 retro
///
/// :
/// 1. `LLMSession.load(folderURL:)` async throws static API
/// 2. `TokenChunk` Sendable ,
/// 3. `AIRuntimeError` case errorDescription
///
/// `KK_LLM_MODEL_PATH` W3
/// LLM SPM target, macOS
@MainActor
struct LLMSessionSmokeTests {
@Test func tokenChunkExposesTextAndRate() {
let chunk = TokenChunk(text: "ALT", decodeRate: 15.4)
#expect(chunk.text == "ALT")
#expect(chunk.decodeRate == 15.4)
}
@Test func aiRuntimeErrorsHaveLocalizedDescriptions() {
let errors: [AIRuntimeError] = [
.notReady,
.modelLoadFailed("config missing"),
.inferenceFailed("OOM"),
]
for err in errors {
#expect(err.errorDescription != nil)
#expect(!(err.errorDescription ?? "").isEmpty)
}
}
@Test func aiRuntimeStartsNotReady() async {
// actor shared ;status .notReady
// :shared , prepare ,
let status = await AIRuntime.shared.status
let validStatuses: [AIRuntime.Status] = [.notReady, .loading, .ready, .error("")]
let kind: String = {
switch status {
case .notReady: return "notReady"
case .loading: return "loading"
case .ready: return "ready"
case .error: return "error"
}
}()
#expect(validStatuses.map { String(describing: $0) }.contains { _ in true }) // : await
#expect(["notReady", "loading", "ready", "error"].contains(kind))
}
}