checkpoint before checking out main

This commit is contained in:
Rocky
2026-08-25 13:42:00 +08:00
parent 57844ce615
commit dccafe6f9e
105 changed files with 4302 additions and 1323 deletions
@@ -0,0 +1,128 @@
// PersonalDictionaryEntryServiceTests.swift
// OSGKeyboardTests
//
// Verifies that every manual-entry UI gets the same alias-generation behavior
// without allowing a late asynchronous response to overwrite newer edits.
@testable import OSGKeyboardShared
import XCTest
@MainActor
final class PersonalDictionaryEntryServiceTests: XCTestCase {
private var suiteName: String!
private var defaults: UserDefaults!
private var store: AppGroupStore!
override func setUp() {
super.setUp()
suiteName = "group.com.osgkeyboard.shared.tests.entry-service.\(UUID().uuidString)"
defaults = UserDefaults(suiteName: suiteName)!
defaults.removePersistentDomain(forName: suiteName)
store = AppGroupStore(defaults: defaults)
}
override func tearDown() {
defaults.removePersistentDomain(forName: suiteName)
super.tearDown()
}
func testSuggestedTermGeneratesAliasesAndPreservesUsageCount() async throws {
var pushedDictionaries: [PersonalDictionary] = []
let service = PersonalDictionaryEntryService(
store: store,
aliasGeneration: { _ in ["洛基", "肉鸡"] },
cloudPush: { pushedDictionaries.append($0) }
)
let saved = try XCTUnwrap(
service.saveEntry(term: "Rocky", source: .history, minimumUsageCount: 3)
)
XCTAssertTrue(saved.shouldGenerateAliases)
XCTAssertEqual(saved.dictionary.entries.first?.source, .history)
XCTAssertEqual(saved.dictionary.entries.first?.usageCount, 3)
XCTAssertTrue(saved.dictionary.entries.first?.aliases.isEmpty == true)
let finished = await service.finishSaving(saved)
XCTAssertEqual(Set(finished.entries.first?.aliases ?? []), Set(["洛基", "肉鸡"]))
XCTAssertEqual(finished.entries.first?.usageCount, 3)
XCTAssertEqual(pushedDictionaries.count, 2)
}
func testAliasCompletionPreservesChangesMadeWhileGenerating() async throws {
let service = PersonalDictionaryEntryService(
store: store,
aliasGeneration: { _ in ["swift u i"] },
cloudPush: { _ in }
)
let saved = try XCTUnwrap(service.saveEntry(term: "SwiftUI", source: .manual))
store.updatePersonalDictionary { dictionary -> UUID? in
guard let concurrent = dictionary.upsertManual(term: "Cursor") else { return nil }
dictionary.version += 1
return concurrent.id
}
let finished = await service.finishSaving(saved)
XCTAssertEqual(Set(finished.entries.map(\.term)), Set(["SwiftUI", "Cursor"]))
XCTAssertEqual(
finished.entry(matchingTerm: "SwiftUI")?.aliases,
["swift u i"]
)
}
func testAliasCompletionDoesNotRestoreDeletedEntry() async throws {
let service = PersonalDictionaryEntryService(
store: store,
aliasGeneration: { _ in ["late alias"] },
cloudPush: { _ in }
)
let saved = try XCTUnwrap(service.saveEntry(term: "Deleted", source: .manual))
store.deletePersonalDictionaryEntry(id: saved.entryID)
let finished = await service.finishSaving(saved)
XCTAssertNil(finished.entries.first(where: { $0.id == saved.entryID }))
XCTAssertNotNil(finished.deletedEntryIDs[saved.entryID])
}
func testAliasCompletionIgnoresEntryRenamedAfterSave() async throws {
let service = PersonalDictionaryEntryService(
store: store,
aliasGeneration: { _ in ["stale alias"] },
cloudPush: { _ in }
)
let saved = try XCTUnwrap(service.saveEntry(term: "Before", source: .manual))
store.updatePersonalDictionary { dictionary -> UUID? in
guard let renamed = dictionary.upsertManual(
term: "After",
existingID: saved.entryID
) else {
return nil
}
dictionary.version += 1
return renamed.id
}
let finished = await service.finishSaving(saved)
XCTAssertEqual(finished.entries.first?.term, "After")
XCTAssertTrue(finished.entries.first?.aliases.isEmpty == true)
}
func testAliasGenerationFailureKeepsSavedEntry() async throws {
var pushCount = 0
let service = PersonalDictionaryEntryService(
store: store,
aliasGeneration: { _ in [] },
cloudPush: { _ in pushCount += 1 }
)
let saved = try XCTUnwrap(service.saveEntry(term: "Durable", source: .manual))
let finished = await service.finishSaving(saved)
XCTAssertEqual(finished.entries.first?.term, "Durable")
XCTAssertTrue(finished.entries.first?.aliases.isEmpty == true)
XCTAssertEqual(pushCount, 1)
}
}