Files
OSGKeyboard/OSGKeyboardTests/FrequentTermStoreTests.swift
T
2026-08-25 13:42:00 +08:00

132 lines
4.4 KiB
Swift

// FrequentTermStoreTests.swift
// OSGKeyboardTests
@testable import OSGKeyboardShared
import XCTest
final class FrequentTermStoreTests: XCTestCase {
private var defaults: UserDefaults!
private var suiteName: String!
override func setUpWithError() throws {
suiteName = "FrequentTermStoreTests.\(UUID().uuidString)"
defaults = try XCTUnwrap(UserDefaults(suiteName: suiteName))
}
override func tearDownWithError() throws {
defaults.removePersistentDomain(forName: suiteName)
defaults = nil
suiteName = nil
}
func testRepeatedCommitBecomesSuggestion() {
let store = FrequentTermStore(defaults: defaults)
store.recordCommittedText("少数派")
XCTAssertTrue(store.suggestions(excludingPersonalTerms: []).isEmpty)
store.recordCommittedText("少数派")
let suggestion = store.suggestions(excludingPersonalTerms: []).first
XCTAssertEqual(suggestion?.term, "少数派")
XCTAssertEqual(suggestion?.commitCount, 2)
}
func testSuggestionsExcludeExistingDictionaryTermsAndCommonWords() {
let store = FrequentTermStore(defaults: defaults)
for _ in 0..<4 {
store.recordCommittedText("我们")
store.recordCommittedText("飞书文档")
store.recordCommittedText("微信读书")
}
let suggestions = store.suggestions(
excludingPersonalTerms: ["飞书文档"]
)
XCTAssertEqual(suggestions.map(\.term), ["微信读书"])
}
func testSuggestionsRankFrequencyBeforeRecency() {
let store = FrequentTermStore(defaults: defaults)
let earlier = Date(timeIntervalSince1970: 100)
let later = Date(timeIntervalSince1970: 200)
for _ in 0..<3 {
store.recordCommittedText("光锥之内", at: earlier)
}
for _ in 0..<2 {
store.recordCommittedText("即刻笔记", at: later)
}
XCTAssertEqual(
store.suggestions(excludingPersonalTerms: []).map(\.term),
["光锥之内", "即刻笔记"]
)
}
func testPunctuationAndSingleCharactersAreIgnored() {
let store = FrequentTermStore(defaults: defaults)
for _ in 0..<3 {
store.recordCommittedText("我")
store.recordCommittedText("你好!")
store.recordCommittedText("\n")
}
XCTAssertTrue(store.suggestions(excludingPersonalTerms: []).isEmpty)
}
func testClearRemovesLearnedSuggestions() {
let store = FrequentTermStore(defaults: defaults)
store.recordCommittedText("少数派")
store.recordCommittedText("少数派")
XCTAssertFalse(store.suggestions(excludingPersonalTerms: []).isEmpty)
store.clear()
XCTAssertTrue(store.suggestions(excludingPersonalTerms: []).isEmpty)
}
func testEnglishTermsAreCaseInsensitiveAndCommonWordsAreIgnored() {
let store = FrequentTermStore(defaults: defaults)
for term in ["OpenAI", "openAI", "the", "the"] {
store.recordCommittedText(term)
}
let suggestion = store.suggestions(excludingPersonalTerms: []).first
XCTAssertEqual(suggestion?.term, "openAI")
XCTAssertEqual(suggestion?.commitCount, 2)
}
func testEnglishNamesAndProductSeparatorsAreAccepted() {
let store = FrequentTermStore(defaults: defaults)
for term in ["O'Connor", "O'Connor", "GPT-5", "GPT-5"] {
store.recordCommittedText(term)
}
XCTAssertEqual(
Set(store.suggestions(excludingPersonalTerms: []).map(\.term)),
["O'Connor", "GPT-5"]
)
}
func testLegacyRimeTermsMigrateWithoutLosingHistory() throws {
let legacyTerm = FrequentTerm(
term: "少数派",
commitCount: 3,
firstSeenAt: Date(timeIntervalSince1970: 100),
lastSeenAt: Date(timeIntervalSince1970: 200)
)
defaults.set(
try JSONEncoder().encode([legacyTerm]),
forKey: FrequentTermStore.legacyRimeDefaultsKey
)
let store = FrequentTermStore(defaults: defaults)
let suggestions = store.suggestions(excludingPersonalTerms: [])
XCTAssertEqual(suggestions.first, legacyTerm)
XCTAssertNotNil(defaults.data(forKey: FrequentTermStore.defaultsKey))
XCTAssertNil(defaults.data(forKey: FrequentTermStore.legacyRimeDefaultsKey))
}
}