Files
openclaw/apps/shared/OpenClawKit/Tests/OpenClawKitTests/ChatModelPickerStoreTests.swift

97 lines
3.7 KiB
Swift

import Foundation
import Testing
@testable import OpenClawChatUI
private func pickerModel(_ selectionID: String) -> OpenClawChatModelChoice {
let parts = selectionID.split(separator: "/", maxSplits: 1).map(String.init)
return OpenClawChatModelChoice(
modelID: parts.count == 2 ? parts[1] : selectionID,
name: selectionID,
provider: parts.count == 2 ? parts[0] : "test",
contextWindow: nil)
}
@MainActor
private func withPickerStore(_ body: (ChatModelPickerStore, UserDefaults) throws -> Void) throws {
let suiteName = "ChatModelPickerStoreTests.\(UUID().uuidString)"
let defaults = try #require(UserDefaults(suiteName: suiteName))
defer { defaults.removePersistentDomain(forName: suiteName) }
try body(ChatModelPickerStore(defaults: defaults), defaults)
}
@MainActor
@Suite struct ChatModelPickerStoreTests {
@Test func `favorites and recents round trip through defaults`() throws {
try withPickerStore { store, defaults in
store.toggleFavorite("anthropic/opus")
store.recordRecent("openai/gpt")
let reloaded = ChatModelPickerStore(defaults: defaults)
#expect(reloaded.favorites == ["anthropic/opus"])
#expect(reloaded.recents == ["openai/gpt"])
}
}
@Test func `recents dedupe move to front cap and skip invalid ids`() throws {
try withPickerStore { store, _ in
store.recordRecent("")
store.recordRecent(OpenClawChatViewModel.defaultModelSelectionID)
for id in ["one", "two", "three", "four", "five", "six"] {
store.recordRecent(id)
}
#expect(store.recents == ["six", "five", "four", "three", "two"])
store.recordRecent("four")
#expect(store.recents == ["four", "six", "five", "three", "two"])
}
}
@Test func `favorites preserve pin order and remove unpinned ids`() throws {
try withPickerStore { store, _ in
store.toggleFavorite("one")
store.toggleFavorite("two")
store.toggleFavorite("three")
#expect(store.favorites == ["one", "two", "three"])
store.toggleFavorite("two")
#expect(store.favorites == ["one", "three"])
store.toggleFavorite("two")
#expect(store.favorites == ["one", "three", "two"])
}
}
@Test func `separate stores preserve each others updates`() throws {
try withPickerStore { first, defaults in
let second = ChatModelPickerStore(defaults: defaults)
first.toggleFavorite("one")
second.toggleFavorite("two")
#expect(second.favorites == ["one", "two"])
first.recordRecent("one")
second.recordRecent("two")
#expect(second.recents == ["two", "one"])
}
}
@Test func `ordering preserves sections and skips missing models`() {
let choices = [pickerModel("a/one"), pickerModel("b/two"), pickerModel("c/three"), pickerModel("d/four")]
let sections = ChatModelPickerStore.sections(
choices: choices,
favorites: ["c/three", "missing/model", "a/one"],
recents: ["a/one", "d/four", "missing/recent"])
#expect(sections.pinned.map(\.selectionID) == ["c/three", "a/one"])
#expect(sections.recent.map(\.selectionID) == ["d/four"])
#expect(sections.remaining.map(\.selectionID) == ["b/two"])
}
@Test func `ordering handles empty inputs`() {
let sections = ChatModelPickerStore.sections(choices: [], favorites: [], recents: [])
#expect(sections.pinned.isEmpty)
#expect(sections.recent.isEmpty)
#expect(sections.remaining.isEmpty)
}
}