diff options
| author | Craig Jennings <c@cjennings.net> | 2026-04-19 07:10:17 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-04-19 07:10:17 -0500 |
| commit | e18d90875c221b489a568421e8356c1ec8fdfe85 (patch) | |
| tree | b5c606fd25011023a19fbb9648e697bcd7fddf77 | |
| parent | 13c057a75ce6d92f9de7e1d53d0ae2554261cb2e (diff) | |
| download | dotemacs-e18d90875c221b489a568421e8356c1ec8fdfe85.tar.gz dotemacs-e18d90875c221b489a568421e8356c1ec8fdfe85.zip | |
refactor(transcription): extract init-log-file and track-transcription
Pull two more helpers out of cj/--start-transcription-process:
- cj/--init-log-file: writes the initial log header with timestamp,
backend, audio file, script path
- cj/--track-transcription: pushes a running-status entry and refreshes
the modeline
Start-process shrinks from 58 lines with 4 levels of nesting to ~25 lines
mostly at depth 1-2. 10 tests cover the extracted helpers.
| -rw-r--r-- | modules/transcription-config.el | 30 | ||||
| -rw-r--r-- | tests/test-transcription-start-helpers.el | 116 |
2 files changed, 132 insertions, 14 deletions
diff --git a/modules/transcription-config.el b/modules/transcription-config.el index 69111a11..e8fe1159 100644 --- a/modules/transcription-config.el +++ b/modules/transcription-config.el @@ -132,6 +132,20 @@ a key but none is found in authinfo.gpg." (user-error "API key not found in authinfo.gpg for host %s" auth-host)) process-environment))) +(defun cj/--init-log-file (log-file audio-file script) + "Create LOG-FILE with a header recording the start of transcription. +Records the current time, active backend, AUDIO-FILE, and SCRIPT path." + (with-temp-file log-file + (insert (format "Transcription started: %s\n" (current-time-string)) + (format "Backend: %s\n" cj/transcribe-backend) + (format "Audio file: %s\n" audio-file) + (format "Script: %s\n\n" script)))) + +(defun cj/--track-transcription (process audio-file) + "Push a running-status entry for PROCESS and AUDIO-FILE, refresh modeline." + (push (list process audio-file (current-time) 'running) cj/transcriptions-list) + (force-mode-line-update t)) + ;; ---------------------------- Process Management ----------------------------- (defun cj/--notify (title message &optional urgency) @@ -164,14 +178,8 @@ Returns the process object." (unless (file-executable-p script) (user-error "Transcription script not found or not executable: %s" script)) - ;; Create log file - (with-temp-file log-file - (insert (format "Transcription started: %s\n" (current-time-string)) - (format "Backend: %s\n" cj/transcribe-backend) - (format "Audio file: %s\n" audio-file) - (format "Script: %s\n\n" script))) + (cj/--init-log-file log-file audio-file script) - ;; Start process with environment (let* ((process-environment (cj/--build-process-environment cj/transcribe-backend)) (process (make-process :name process-name @@ -180,15 +188,9 @@ Returns the process object." :sentinel (lambda (proc event) (cj/--transcription-sentinel proc event audio-file txt-file log-file)) :stderr log-file))) - - ;; Track transcription - (push (list process audio-file (current-time) 'running) cj/transcriptions-list) - (force-mode-line-update t) - - ;; Notify user + (cj/--track-transcription process audio-file) (cj/--notify "Transcription" (format "Started on %s" (file-name-nondirectory audio-file))) - process))) (defun cj/--transcription-sentinel (process event audio-file txt-file log-file) diff --git a/tests/test-transcription-start-helpers.el b/tests/test-transcription-start-helpers.el new file mode 100644 index 00000000..f52d2066 --- /dev/null +++ b/tests/test-transcription-start-helpers.el @@ -0,0 +1,116 @@ +;;; test-transcription-start-helpers.el --- Tests for process-start helpers -*- lexical-binding: t; -*- + +;;; Commentary: +;; Tests for the two helpers extracted from `cj/--start-transcription-process': +;; - `cj/--init-log-file' (writes the initial log header) +;; - `cj/--track-transcription' (pushes an entry onto the active list) + +;;; Code: + +(require 'ert) +(require 'cl-lib) + +(defvar cj/custom-keymap (make-sparse-keymap)) + +(unless (fboundp 'notifications-notify) + (defun notifications-notify (&rest _args) nil)) + +(require 'transcription-config) + +(defmacro test-start-helpers-with-temp-log (var &rest body) + "Bind VAR to a fresh temp log-file path and run BODY, cleaning up after." + (declare (indent 1)) + `(let ((,var (make-temp-file "transcription-log-" nil ".log"))) + (unwind-protect + (progn ,@body) + (when (file-exists-p ,var) (delete-file ,var))))) + +(defun test-start-helpers-file-contents (path) + "Return contents of PATH as a string." + (with-temp-buffer + (insert-file-contents path) + (buffer-string))) + +;;; cj/--init-log-file — Normal Cases + +(ert-deftest test-init-log-file-normal-creates-file () + "The log file exists after `cj/--init-log-file' runs." + (test-start-helpers-with-temp-log log-file + (delete-file log-file) ; start from a clean slate + (cj/--init-log-file log-file "/tmp/foo.m4a" "/tmp/script") + (should (file-exists-p log-file)))) + +(ert-deftest test-init-log-file-normal-records-audio-path () + "Log header includes the full AUDIO-FILE path." + (test-start-helpers-with-temp-log log-file + (cj/--init-log-file log-file "/tmp/foo.m4a" "/tmp/script") + (should (string-match-p "Audio file: /tmp/foo\\.m4a" + (test-start-helpers-file-contents log-file))))) + +(ert-deftest test-init-log-file-normal-records-script-path () + "Log header includes the SCRIPT path." + (test-start-helpers-with-temp-log log-file + (cj/--init-log-file log-file "/tmp/foo.m4a" "/usr/local/bin/whisper") + (should (string-match-p "Script: /usr/local/bin/whisper" + (test-start-helpers-file-contents log-file))))) + +(ert-deftest test-init-log-file-normal-records-backend () + "Log header includes the current `cj/transcribe-backend' value." + (test-start-helpers-with-temp-log log-file + (let ((cj/transcribe-backend 'local-whisper)) + (cj/--init-log-file log-file "/tmp/foo.m4a" "/tmp/script")) + (should (string-match-p "Backend: local-whisper" + (test-start-helpers-file-contents log-file))))) + +(ert-deftest test-init-log-file-normal-records-start-timestamp () + "Log header begins with a `Transcription started:' line." + (test-start-helpers-with-temp-log log-file + (cj/--init-log-file log-file "/tmp/foo.m4a" "/tmp/script") + (should (string-match-p "Transcription started:" + (test-start-helpers-file-contents log-file))))) + +;;; cj/--init-log-file — Boundary Cases + +(ert-deftest test-init-log-file-boundary-overwrites-existing () + "An existing log file is overwritten (not appended to)." + (test-start-helpers-with-temp-log log-file + (with-temp-file log-file (insert "STALE CONTENT\n")) + (cj/--init-log-file log-file "/tmp/foo.m4a" "/tmp/script") + (should-not (string-match-p "STALE CONTENT" + (test-start-helpers-file-contents log-file))))) + +;;; cj/--track-transcription — Normal Cases + +(ert-deftest test-track-transcription-normal-adds-entry-to-list () + "A call to `cj/--track-transcription' pushes one entry." + (let ((cj/transcriptions-list '())) + (cj/--track-transcription 'proc1 "/tmp/foo.m4a") + (should (= 1 (length cj/transcriptions-list))))) + +(ert-deftest test-track-transcription-normal-entry-shape () + "Pushed entry is (PROC AUDIO-FILE TIME running)." + (let ((cj/transcriptions-list '())) + (cj/--track-transcription 'proc1 "/tmp/foo.m4a") + (let ((entry (car cj/transcriptions-list))) + (should (eq 'proc1 (nth 0 entry))) + (should (equal "/tmp/foo.m4a" (nth 1 entry))) + (should (nth 2 entry)) ; start-time is non-nil + (should (eq 'running (nth 3 entry)))))) + +(ert-deftest test-track-transcription-normal-multiple-entries-accumulate () + "Multiple calls accumulate onto the list." + (let ((cj/transcriptions-list '())) + (cj/--track-transcription 'p1 "/a.m4a") + (cj/--track-transcription 'p2 "/b.m4a") + (cj/--track-transcription 'p3 "/c.m4a") + (should (= 3 (length cj/transcriptions-list))))) + +(ert-deftest test-track-transcription-normal-preserves-existing-entries () + "Pre-existing entries in the list are not disturbed." + (let ((cj/transcriptions-list '((old-proc "/old.m4a" nil complete)))) + (cj/--track-transcription 'new-proc "/new.m4a") + (should (= 2 (length cj/transcriptions-list))) + (should (member '(old-proc "/old.m4a" nil complete) cj/transcriptions-list)))) + +(provide 'test-transcription-start-helpers) +;;; test-transcription-start-helpers.el ends here |
