mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-10 23:06:05 +00:00
97 lines
3.7 KiB
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)
|
|
}
|
|
}
|