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 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) } }