import Foundation import Testing @testable import SstCore @MainActor struct DictationControllerHooksTests { let recorder = FakeRecorder() let transcriber = FakeVocabularyTranscriber() let inserter = FakeInserter() static let loud = [Float](repeating: 0.1, count: 16_000) static let quiet = [Float](repeating: 0.01, count: 16_000) func makeController( cleaner: Cleaner = FakeCleaner(), corrector: TextCorrecting? = nil, vocabulary: [String] = [] ) -> DictationController { DictationController( recorder: recorder, transcriber: transcriber, cleaner: cleaner, inserter: inserter, corrector: corrector, vocabularyProvider: { vocabulary } ) } func dictate(_ controller: DictationController) async { await controller.handle(.pressed) await controller.handle(.released) } @Test func loudRecordingPassesVocabularyToTranscriber() async { recorder.samples = Self.loud await dictate(makeController(vocabulary: ["Anthropic", "Vercel"])) #expect(transcriber.vocabularies == [["Anthropic", "Vercel"]]) } @Test func quietRecordingSkipsVocabularyButStillTranscribes() async { recorder.samples = Self.quiet // RMS 0.01: above silence (0.005), below bias minimum (0.015) await dictate(makeController(vocabulary: ["Anthropic", "Vercel"])) #expect(transcriber.vocabularies == [[]]) #expect(inserter.inserted == ["[hallo wereld]"]) } @Test func promptEchoIsDiscarded() async { recorder.samples = Self.loud transcriber.result = "Anthropic, Vercel." let controller = makeController(vocabulary: ["Anthropic", "Vercel", "Supabase"]) var results: [DictationResult] = [] controller.onResult = { results.append($0) } await dictate(controller) #expect(inserter.inserted.isEmpty) #expect(results.isEmpty) #expect(controller.state == .idle) } @Test func singleVocabularyTermIsKept() async { recorder.samples = Self.loud transcriber.result = "Anthropic" await dictate(makeController(vocabulary: ["Anthropic", "Vercel", "Supabase"])) #expect(inserter.inserted == ["[Anthropic]"]) } @Test func correctorRunsBeforeCleanerAndCorrectionsSurviveAPassthroughCleaner() async { recorder.samples = Self.loud transcriber.result = "hallo" let controller = makeController(cleaner: PassthroughCleaner(), corrector: UppercaseCorrector()) var results: [DictationResult] = [] controller.onResult = { results.append($0) } await dictate(controller) #expect(inserter.inserted == ["HALLO"]) #expect(results.count == 1) #expect(results[0].rawText == "hallo") #expect(results[0].finalText == "HALLO") #expect(results[0].corrections.count == 1) } @Test func correctionsAreDroppedWhenTheCleanerChangesTheText() async { recorder.samples = Self.loud transcriber.result = "hallo" let controller = makeController(cleaner: FakeCleaner(), corrector: UppercaseCorrector()) var results: [DictationResult] = [] controller.onResult = { results.append($0) } await dictate(controller) #expect(results[0].finalText == "[HALLO]") #expect(results[0].corrections.isEmpty) } @Test func resultIsReportedEvenWhenInsertionFails() async { recorder.samples = Self.loud inserter.error = TestError() let controller = makeController() var results: [DictationResult] = [] var errors: [String] = [] controller.onResult = { results.append($0) } controller.onError = { errors.append($0) } await dictate(controller) #expect(results.count == 1) #expect(errors.count == 1) } @Test func resultCarriesDurationAndDate() async { recorder.samples = Self.loud // 16 000 samples = 1 s let controller = makeController() var results: [DictationResult] = [] controller.onResult = { results.append($0) } let before = Date() await dictate(controller) #expect(results[0].duration == 1.0) #expect(results[0].date >= before) #expect(results[0].corrections.isEmpty) } }