fix(ipad): ship iPad P0 layout/globe fixes, edit-last-input, drop clipboard commands

Adapt typing/voice surfaces for iPad width and height, add the system globe
key and last-input editing flow, harden host-only Rime deployment, and remove
clipboard voice commands. Bump build to 61.
This commit is contained in:
Rocky
2026-08-10 13:50:50 +08:00
parent 53abad2050
commit 2bc8c1b87d
85 changed files with 5703 additions and 3997 deletions
@@ -0,0 +1,78 @@
import XCTest
@testable import OSGKeyboardShared
final class FlowStartTransactionPolicyTests: XCTestCase {
func testSameUtteranceIsIdempotentAcrossStartingRecordingAndProcessing() {
let id = UUID()
for state in [
FlowHostUtteranceState.starting(id),
.recording(id),
.processing(id)
] {
XCTAssertEqual(
FlowStartTransactionPolicy.decide(
incomingUtteranceID: id,
deadlineAt: 200,
now: 100,
hostState: state
),
.idempotent
)
}
}
func testDifferentUtteranceIsRejectedWhileBusy() {
XCTAssertEqual(
FlowStartTransactionPolicy.decide(
incomingUtteranceID: UUID(),
deadlineAt: 200,
now: 100,
hostState: .starting(UUID())
),
.rejectBusy
)
}
func testExpiredStartIsRejectedBeforeCapture() {
XCTAssertEqual(
FlowStartTransactionPolicy.decide(
incomingUtteranceID: UUID(),
deadlineAt: 100,
now: 100,
hostState: .idle
),
.rejectExpired
)
}
func testIdleStartWithinBudgetIsAccepted() {
XCTAssertEqual(
FlowStartTransactionPolicy.decide(
incomingUtteranceID: UUID(),
deadlineAt: 101,
now: 100,
hostState: .idle
),
.accept
)
}
func testEditAndDictationShareOneRequestContract() {
let reference = EditableInputReference(
historyEntryID: UUID(),
historyEntryRevision: 3,
displayText: "原文",
insertedText: "原文",
postInsertionFingerprint: "field",
extensionInstanceID: UUID()
)
let edit = FlowUtteranceRequest.editLastInput(reference)
XCTAssertEqual(edit.mode, .editLastInput)
XCTAssertEqual(edit.editSourceText, "原文")
XCTAssertEqual(edit.sourceHistoryEntryID, reference.historyEntryID)
XCTAssertEqual(edit.sourceHistoryEntryRevision, 3)
XCTAssertEqual(FlowUtteranceRequest.dictation.mode, .dictation)
XCTAssertNil(FlowUtteranceRequest.dictation.editSourceText)
}
}