Files
sst/Tests/SstCoreTests/DictationControllerHooksTests.swift
T

125 lines
4.3 KiB
Swift

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