Files
OSGKeyboard/OSGKeyboardTests/AIHistoryAndUsageTests.swift
T
Rocky 3de665d254 feat(keyboard): ship AI mode surface with streaming search answers
Add the AI keyboard tab, Agent settings, and user-owned LLM key path for 1.7.0, including streaming answers and web-search transports without the built-in DeepSeek fallback.
2026-08-11 01:06:27 +08:00

60 lines
2.0 KiB
Swift

import XCTest
@testable import OSGKeyboardShared
final class AIHistoryAndUsageTests: XCTestCase {
@MainActor
func testAIHistoryMutationPreservesSource() throws {
let defaults = try makeDefaults()
let store = SpeechHistoryStore(defaults: defaults)
let mutation = HistoryMutation(
action: .append,
entryID: UUID(),
text: "AI 答案",
engineMode: "local",
source: .ai,
usageCategory: .ai
)
let entry = try XCTUnwrap(store.applyHistoryMutation(mutation))
XCTAssertEqual(entry.text, "AI 答案")
XCTAssertEqual(entry.source, .ai)
}
@MainActor
func testAICharacterCommitIsIdempotent() throws {
let defaults = try makeDefaults()
let store = UsageStatisticsStore(defaults: defaults)
let commitID = UUID()
store.recordAIInsertion(text: "四个字符", commitID: commitID)
store.recordAIInsertion(text: "四个字符", commitID: commitID)
XCTAssertEqual(store.aiCharacterCount, 4)
XCTAssertEqual(store.totalInputCharacterCount, 4)
}
func testLegacyHistoryEntryDefaultsToDictationSource() throws {
let payload: [String: Any] = [
"id": UUID().uuidString,
"text": "旧记录",
"createdAt": Date().timeIntervalSinceReferenceDate,
"modifiedAt": Date().timeIntervalSinceReferenceDate,
"revision": 0,
]
let data = try JSONSerialization.data(withJSONObject: payload)
let decoder = JSONDecoder()
let entry = try decoder.decode(SpeechHistoryEntry.self, from: data)
XCTAssertEqual(entry.source, .dictation)
}
private func makeDefaults() throws -> UserDefaults {
let name = "AIHistoryAndUsageTests.\(UUID().uuidString)"
let defaults = try XCTUnwrap(UserDefaults(suiteName: name))
defaults.removePersistentDomain(forName: name)
return defaults
}
}