Files
sst/Tests/SstCoreTests/DictationControllerTests.swift
2026-10-01 09:58:09 +02:00

139 lines
4.3 KiB
Swift

import Testing
@testable import SstCore
@MainActor
struct DictationControllerTests {
let recorder = FakeRecorder()
let transcriber = FakeTranscriber()
let cleaner = FakeCleaner()
let inserter = FakeInserter()
static let oneSecond = [Float](repeating: 0.1, count: 16_000)
func makeController() -> DictationController {
DictationController(
recorder: recorder,
transcriber: transcriber,
cleaner: cleaner,
inserter: inserter
)
}
@Test func pressAndReleaseTranscribesCleansAndInserts() async {
recorder.samples = Self.oneSecond
let controller = makeController()
var states: [DictationState] = []
controller.onStateChange = { states.append($0) }
await controller.handle(.pressed)
await controller.handle(.released)
#expect(states == [.recording, .transcribing, .inserting, .idle])
#expect(inserter.inserted == ["[hallo wereld]"])
}
@Test func shortRecordingIsDiscarded() async {
recorder.samples = [Float](repeating: 0.1, count: 1_000)
let controller = makeController()
var states: [DictationState] = []
controller.onStateChange = { states.append($0) }
await controller.handle(.pressed)
await controller.handle(.released)
#expect(states == [.recording, .idle])
#expect(transcriber.callCount == 0)
#expect(inserter.inserted.isEmpty)
}
@Test func silentRecordingIsDiscarded() async {
recorder.samples = [Float](repeating: 0, count: 16_000)
let controller = makeController()
var states: [DictationState] = []
var errors: [String] = []
controller.onStateChange = { states.append($0) }
controller.onError = { errors.append($0) }
await controller.handle(.pressed)
await controller.handle(.released)
#expect(states == [.recording, .idle])
#expect(transcriber.callCount == 0)
#expect(inserter.inserted.isEmpty)
#expect(errors.isEmpty)
}
@Test func emptyTranscriptionIsNotInserted() async {
recorder.samples = Self.oneSecond
transcriber.result = .success(" \n")
let controller = makeController()
var errors: [String] = []
controller.onError = { errors.append($0) }
await controller.handle(.pressed)
await controller.handle(.released)
#expect(inserter.inserted.isEmpty)
#expect(errors.isEmpty)
#expect(controller.state == .idle)
}
@Test func transcriberErrorReportsAndReturnsToIdle() async {
recorder.samples = Self.oneSecond
transcriber.result = .failure(TestError())
let controller = makeController()
var errors: [String] = []
controller.onError = { errors.append($0) }
await controller.handle(.pressed)
await controller.handle(.released)
#expect(errors.count == 1)
#expect(inserter.inserted.isEmpty)
#expect(controller.state == .idle)
}
@Test func inserterErrorReportsAndReturnsToIdle() async {
recorder.samples = Self.oneSecond
inserter.error = TestError()
let controller = makeController()
var errors: [String] = []
controller.onError = { errors.append($0) }
await controller.handle(.pressed)
await controller.handle(.released)
#expect(errors.count == 1)
#expect(controller.state == .idle)
}
@Test func recorderStartFailureStaysIdle() async {
recorder.startError = TestError()
let controller = makeController()
var errors: [String] = []
controller.onError = { errors.append($0) }
await controller.handle(.pressed)
#expect(errors.count == 1)
#expect(controller.state == .idle)
}
@Test func secondPressWhileRecordingIsIgnored() async {
let controller = makeController()
await controller.handle(.pressed)
await controller.handle(.pressed)
#expect(recorder.startCount == 1)
}
@Test func releaseWithoutPressIsIgnored() async {
let controller = makeController()
var states: [DictationState] = []
controller.onStateChange = { states.append($0) }
await controller.handle(.released)
#expect(states.isEmpty)
#expect(transcriber.callCount == 0)
}
}