summaryrefslogtreecommitdiff
path: root/tests/test_controller.py
blob: 61c291e2b3a3326e9905c16fb1cd41524dda5ccc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
from pathlib import Path
import tempfile
import threading
import unittest

from parley.config import Config
from parley.controller import Controller
from parley.state import State


class FakeRecorder:
    def __init__(self) -> None:
        self.path = None
        self.cancelled = False

    def start(self, path: Path) -> None:
        self.path = path
        path.write_bytes(b"RIFF")

    def stop(self) -> Path:
        return self.path

    def cancel(self) -> None:
        self.cancelled = True
        if self.path:
            self.path.unlink(missing_ok=True)


class FakeTranscriber:
    def transcribe(self, wav_path: Path, workspace: Path) -> str:
        return "hello from controller"

    def cancel(self) -> None:
        pass


class ControllerTests(unittest.TestCase):
    def setUp(self) -> None:
        self.temporary = tempfile.TemporaryDirectory()
        root = Path(self.temporary.name)
        ffmpeg = root / "ffmpeg"
        runtime = root / "transcribe-cli"
        model = root / "model.gguf"
        for path in (ffmpeg, runtime):
            path.write_text("#!/bin/sh\n")
            path.chmod(0o755)
        model.touch()
        self.config = Config(ffmpeg, runtime, model, root / "transcripts")

    def tearDown(self) -> None:
        self.temporary.cleanup()

    def test_successful_operation_persists_before_callback(self) -> None:
        ready = threading.Event()
        received = []
        controller = Controller(
            self.config,
            on_transcript=lambda text, path: (received.append((text, path)), ready.set()),
        )
        controller.recorder = FakeRecorder()
        controller.transcriber = FakeTranscriber()
        try:
            controller.start()
            self.assertEqual(controller.state, State.RECORDING)
            controller.stop_and_transcribe()
            self.assertTrue(ready.wait(2), "transcription callback was not delivered")
            self.assertEqual(controller.state, State.IDLE)
            text, path = received[0]
            self.assertEqual(text, "hello from controller")
            self.assertEqual(path.read_text(), "hello from controller\n")
        finally:
            controller.close()

    def test_cancel_recording_discards_operation(self) -> None:
        controller = Controller(self.config)
        recorder = FakeRecorder()
        controller.recorder = recorder
        try:
            controller.start()
            controller.cancel()
            self.assertEqual(controller.state, State.IDLE)
            self.assertTrue(recorder.cancelled)
        finally:
            controller.close()


if __name__ == "__main__":
    unittest.main()