Files
OSGKeyboard/OSGKeyboardTests/FlowCaptureTailDrainTests.swift
T
Cursor Agent 8b105430e3 fix(flow): drain trailing audio and harden chunked ASR pipeline
- P0/P1: tail-drain state machine in FlowContinuousCapture with converter
  flush; FlowSessionManager awaits drain before finalize
- P2: FlowCaptureTailDrain policy/tracker, pipeline diagnostics, unit tests
- P3: short final chunk merged re-transcription in ChunkedUtterancePipeline
- P4: UtteranceTranscriptStitcher composedSafely fallback; preview path parity
  in LiveDictationController

Co-authored-by: Rocky <hkgood@users.noreply.github.com>
2026-07-06 05:13:58 +00:00

52 lines
1.7 KiB
Swift

// FlowCaptureTailDrainTests.swift
// OSGKeyboardTests
import XCTest
@testable import OSGKeyboardShared
final class FlowCaptureTailDrainTests: XCTestCase {
private let policy = FlowCaptureTailDrainPolicy(
silenceRMSThreshold: 0.02,
silenceDurationSeconds: 0.2,
maxDrainSeconds: 1.0
)
func testDrainFinishesAfterContinuousSilence() {
let tracker = FlowCaptureDrainTracker()
let start = Date().timeIntervalSince1970
tracker.beginDrain(now: start)
tracker.noteAudio(samples: [0.001, 0.001], policy: policy, now: start + 0.05)
let silentAt = start + 0.1
let decision = tracker.shouldFinish(policy: policy, now: silentAt + policy.silenceDurationSeconds)
XCTAssertTrue(decision.finished)
XCTAssertTrue(decision.endedBySilence)
}
func testDrainFinishesAtMaxDurationEvenWithoutSilence() {
let tracker = FlowCaptureDrainTracker()
let start = Date().timeIntervalSince1970
tracker.beginDrain(now: start)
tracker.noteAudio(samples: [0.5, 0.4], policy: policy, now: start + 0.05)
tracker.noteAudio(samples: [0.45, 0.42], policy: policy, now: start + 0.4)
let decision = tracker.shouldFinish(policy: policy, now: start + policy.maxDrainSeconds)
XCTAssertTrue(decision.finished)
XCTAssertFalse(decision.endedBySilence)
}
func testRMSDetectsAudibleSamples() {
XCTAssertGreaterThan(
FlowCaptureDrainTracker.rms(of: [0.2, 0.18, 0.15]),
policy.silenceRMSThreshold
)
XCTAssertLessThan(
FlowCaptureDrainTracker.rms(of: [0.001, 0.0005]),
policy.silenceRMSThreshold
)
}
}