fix: keyboard stability, host-only analytics, and auto-reply dedupe
- record analytics/usage only in the host app; the extension no longer opens the SQLite queues, so hiding the keyboard cannot hold WAL locks (0xdead10cc) - sync clipboard history writes across processes so deletes made on one side are not reverted by the other - guard memory-relief reentrancy on controller and telemetry sides to break the recursive crash loop - resolve credentials off the main thread and migrate legacy keys once per install, so Keychain reads cannot be caught in the suspend window - gate Volcengine ASR ping completion to once (SIGTRAP on double resume) - treat same-text captures as the same logical copy and dedupe auto actions by content fingerprint within 30s, stopping Universal Clipboard storms - realign version line to 2.1.0 (build 110)
This commit is contained in:
@@ -188,6 +188,47 @@ final class ClipboardSuggestionLifecycleTests: XCTestCase {
|
||||
XCTAssertNil(state.clipboardSuggestionText)
|
||||
}
|
||||
|
||||
func testSameTextUnderNewChangeCountIsSwallowedAsSameLogicalCopy() {
|
||||
copy("meeting at 3pm")
|
||||
coordinator.captureIfNeeded()
|
||||
let firstEntry = history.newestEntry
|
||||
|
||||
// Universal Clipboard re-announce: same text, new changeCount.
|
||||
pasteboard.setText("meeting at 3pm", changeCount: 12)
|
||||
coordinator.captureIfNeeded()
|
||||
|
||||
XCTAssertEqual(history.entries.count, 1)
|
||||
XCTAssertEqual(history.newestEntry?.id, firstEntry?.id)
|
||||
XCTAssertEqual(history.newestEntry?.createdAt, firstEntry?.createdAt)
|
||||
XCTAssertEqual(history.lastObservedChangeCount, 12)
|
||||
XCTAssertEqual(state.clipboardSuggestionText, "meeting at 3pm")
|
||||
}
|
||||
|
||||
func testRecopyAfterDifferentContentCreatesNewGeneration() {
|
||||
copy("first message")
|
||||
coordinator.captureIfNeeded()
|
||||
copy("second message")
|
||||
coordinator.captureIfNeeded()
|
||||
|
||||
copy("first message")
|
||||
coordinator.captureIfNeeded()
|
||||
|
||||
XCTAssertEqual(history.entries.map(\.text), ["first message", "second message"])
|
||||
XCTAssertEqual(state.clipboardSuggestionText, "first message")
|
||||
}
|
||||
|
||||
func testDismissedSuggestionStaysHiddenAcrossUniversalClipboardResync() {
|
||||
copy("dismiss me")
|
||||
coordinator.captureIfNeeded()
|
||||
coordinator.dismissSuggestion()
|
||||
|
||||
pasteboard.setText("dismiss me", changeCount: 12)
|
||||
coordinator.captureIfNeeded()
|
||||
|
||||
XCTAssertNil(state.clipboardSuggestionText)
|
||||
XCTAssertEqual(history.entries.count, 1)
|
||||
}
|
||||
|
||||
private func copy(_ text: String) {
|
||||
pasteboard.setText(text, changeCount: pasteboard.changeCount + 1)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user