feat(keyboard): improve typing, voice flow, and polish reliability

Reduce extension memory pressure and delivery races while adding richer candidates, tactile feedback, and safer two-level creative polishing.
This commit is contained in:
Rocky
2026-08-05 21:39:31 +08:00
parent 38e5ad570d
commit 31f5937a7f
177 changed files with 8343 additions and 3904 deletions
@@ -2,7 +2,7 @@ import XCTest
@testable import OSGKeyboardShared
final class PolishOutputValidatorTests: XCTestCase {
func testMissingDictionaryCanonicalTermIsHardViolation() {
func testMissingDictionaryCanonicalTermIsViolation() {
let dictionary = PersonalDictionary(entries: [
.init(
term: "Kubernetes",
@@ -14,19 +14,16 @@ final class PolishOutputValidatorTests: XCTestCase {
let violations = PolishOutputValidator.validate(
input: "部署 k8s 集群",
output: "部署容器集群",
dictionary: dictionary,
lengthRatio: 0.5...2
dictionary: dictionary
)
XCTAssertTrue(violations.contains(.missingDictionaryTerms(["Kubernetes"])))
XCTAssertTrue(violations.contains(where: \.isHard))
}
func testIdentifiersArePreservedExactly() {
let violations = PolishOutputValidator.validate(
input: "send https://example.com/a to dev@example.com using user_id",
output: "send it to the team",
dictionary: .empty,
lengthRatio: 0.5...2
dictionary: .empty
)
XCTAssertTrue(violations.contains { violation in
if case .missingIdentifiers(let values) = violation {
@@ -50,8 +47,7 @@ final class PolishOutputValidatorTests: XCTestCase {
let violations = PolishOutputValidator.validate(
input: input,
output: output,
dictionary: .empty,
lengthRatio: 0.2...3
dictionary: .empty
)
XCTAssertFalse(
violations.contains {
@@ -74,8 +70,7 @@ final class PolishOutputValidatorTests: XCTestCase {
let violations = PolishOutputValidator.validate(
input: "打开 \(input)",
output: "打开对应文件",
dictionary: .empty,
lengthRatio: 0.2...3
dictionary: .empty
)
XCTAssertTrue(
violations.contains {
@@ -89,42 +84,4 @@ final class PolishOutputValidatorTests: XCTestCase {
}
}
func testOrdinalASRRepairDoesNotReportMissingZeroes() {
let violations = PolishOutputValidator.validate(
input: "第一点是A第2:00是B",
output: "第一点是 A\n2. B",
dictionary: .empty,
lengthRatio: 0.2...3
)
XCTAssertFalse(violations.contains {
if case .missingNumbers = $0 { return true }
return false
})
}
func testRealTimeStillReportsMissingZeroes() {
let violations = PolishOutputValidator.validate(
input: "第一点是坐第2:00班车",
output: "第一点是坐第二班车",
dictionary: .empty,
lengthRatio: 0.2...3
)
XCTAssertTrue(violations.contains {
if case .missingNumbers(let values) = $0 {
return values.contains("00")
}
return false
})
}
func testNumbersLengthAndLanguageAreObservationOnly() {
let violations = PolishOutputValidator.validate(
input: "项目 123 明天下午交付并通知全部相关成员",
output: "Ship tomorrow.",
dictionary: .empty,
lengthRatio: 0.9...1.1
)
XCTAssertFalse(violations.isEmpty)
XCTAssertTrue(violations.filter(\.isHard).isEmpty)
}
}