From 0febc3bb65462fd95a75387c2ec97ffa374efc00 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Fri, 14 Nov 2025 02:35:00 -0600 Subject: Revert "checking in modified/removed tests and other misc changes" This reverts commit 9d55ed149e100b4fb3ef6f5a79d263dcb26ce835. --- .../test-video-audio-recording-process-sentinel.el | 190 +++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 tests/test-video-audio-recording-process-sentinel.el (limited to 'tests/test-video-audio-recording-process-sentinel.el') diff --git a/tests/test-video-audio-recording-process-sentinel.el b/tests/test-video-audio-recording-process-sentinel.el new file mode 100644 index 00000000..37a7f94d --- /dev/null +++ b/tests/test-video-audio-recording-process-sentinel.el @@ -0,0 +1,190 @@ +;;; test-video-audio-recording-process-sentinel.el --- Tests for cj/recording-process-sentinel -*- lexical-binding: t; -*- + +;;; Commentary: +;; Unit tests for cj/recording-process-sentinel function. +;; Tests process cleanup and modeline update when recording processes exit. + +;;; Code: + +(require 'ert) + +;; Stub dependencies before loading the module +(defvar cj/custom-keymap (make-sparse-keymap) + "Stub keymap for testing.") + +;; Now load the actual production module +(require 'video-audio-recording) + +;;; Setup and Teardown + +(defun test-sentinel-setup () + "Reset process variables before each test." + (setq cj/audio-recording-ffmpeg-process nil) + (setq cj/video-recording-ffmpeg-process nil)) + +(defun test-sentinel-teardown () + "Clean up process variables after each test." + (setq cj/audio-recording-ffmpeg-process nil) + (setq cj/video-recording-ffmpeg-process nil)) + +;;; Normal Cases + +(ert-deftest test-video-audio-recording-process-sentinel-normal-audio-exit-clears-variable () + "Test that sentinel clears audio process variable when process exits." + (test-sentinel-setup) + (unwind-protect + (let ((fake-process (make-process :name "test-audio" :command '("sh" "-c" "exit 0")))) + (setq cj/audio-recording-ffmpeg-process fake-process) + ;; Mock process-status to return 'exit + (cl-letf (((symbol-function 'process-status) + (lambda (_proc) 'exit))) + ;; Call sentinel with exit status + (cj/recording-process-sentinel fake-process "finished\n") + ;; Variable should be cleared + (should (null cj/audio-recording-ffmpeg-process)))) + (test-sentinel-teardown))) + +(ert-deftest test-video-audio-recording-process-sentinel-normal-video-exit-clears-variable () + "Test that sentinel clears video process variable when process exits." + (test-sentinel-setup) + (unwind-protect + (let ((fake-process (make-process :name "test-video" :command '("sh" "-c" "exit 0")))) + (setq cj/video-recording-ffmpeg-process fake-process) + ;; Mock process-status to return 'exit + (cl-letf (((symbol-function 'process-status) + (lambda (_proc) 'exit))) + ;; Call sentinel with exit status + (cj/recording-process-sentinel fake-process "finished\n") + ;; Variable should be cleared + (should (null cj/video-recording-ffmpeg-process)))) + (test-sentinel-teardown))) + +(ert-deftest test-video-audio-recording-process-sentinel-normal-signal-status-clears-variable () + "Test that sentinel clears variable on signal status (killed)." + (test-sentinel-setup) + (unwind-protect + (let ((fake-process (make-process :name "test-audio" :command '("sleep" "1000")))) + (setq cj/audio-recording-ffmpeg-process fake-process) + (delete-process fake-process) + ;; Call sentinel with signal status + (cj/recording-process-sentinel fake-process "killed\n") + ;; Variable should be cleared + (should (null cj/audio-recording-ffmpeg-process))) + (test-sentinel-teardown))) + +(ert-deftest test-video-audio-recording-process-sentinel-normal-modeline-update-called () + "Test that sentinel triggers modeline update." + (test-sentinel-setup) + (unwind-protect + (let ((fake-process (make-process :name "test-audio" :command '("sh" "-c" "exit 0"))) + (update-called nil)) + (setq cj/audio-recording-ffmpeg-process fake-process) + ;; Mock force-mode-line-update to track if it's called + (cl-letf (((symbol-function 'force-mode-line-update) + (lambda (&optional _all) (setq update-called t)))) + (cj/recording-process-sentinel fake-process "finished\n") + (should update-called))) + (test-sentinel-teardown))) + +;;; Boundary Cases + +(ert-deftest test-video-audio-recording-process-sentinel-boundary-run-status-ignored () + "Test that sentinel ignores processes in 'run status (still running)." + (test-sentinel-setup) + (unwind-protect + (let ((fake-process (make-process :name "test-audio" :command '("sleep" "1000")))) + (setq cj/audio-recording-ffmpeg-process fake-process) + ;; Mock process-status to return 'run + (cl-letf (((symbol-function 'process-status) + (lambda (_proc) 'run))) + (cj/recording-process-sentinel fake-process "run") + ;; Variable should NOT be cleared + (should (eq fake-process cj/audio-recording-ffmpeg-process))) + (delete-process fake-process)) + (test-sentinel-teardown))) + +(ert-deftest test-video-audio-recording-process-sentinel-boundary-open-status-ignored () + "Test that sentinel ignores processes in 'open status." + (test-sentinel-setup) + (unwind-protect + (let ((fake-process (make-process :name "test-audio" :command '("sleep" "1000")))) + (setq cj/audio-recording-ffmpeg-process fake-process) + (cl-letf (((symbol-function 'process-status) + (lambda (_proc) 'open))) + (cj/recording-process-sentinel fake-process "open") + ;; Variable should NOT be cleared + (should (eq fake-process cj/audio-recording-ffmpeg-process))) + (delete-process fake-process)) + (test-sentinel-teardown))) + +(ert-deftest test-video-audio-recording-process-sentinel-boundary-event-trimmed () + "Test that event string is trimmed in message." + (test-sentinel-setup) + (unwind-protect + (let ((fake-process (make-process :name "test-audio" :command '("sh" "-c" "exit 0"))) + (message-text nil)) + (setq cj/audio-recording-ffmpeg-process fake-process) + ;; Mock message to capture output + (cl-letf (((symbol-function 'message) + (lambda (fmt &rest args) (setq message-text (apply #'format fmt args))))) + (cj/recording-process-sentinel fake-process " finished \n") + ;; Message should contain trimmed event + (should (string-match-p "finished" message-text)) + ;; Should not have extra whitespace + (should-not (string-match-p " finished " message-text)))) + (test-sentinel-teardown))) + +;;; Error Cases + +(ert-deftest test-video-audio-recording-process-sentinel-error-unknown-process-ignored () + "Test that sentinel handles unknown process (not audio or video) gracefully." + (test-sentinel-setup) + (unwind-protect + (let ((fake-process (make-process :name "test-unknown" :command '("sh" "-c" "exit 0"))) + (audio-proc (make-process :name "test-audio" :command '("sleep" "1000"))) + (video-proc (make-process :name "test-video" :command '("sleep" "1000")))) + (setq cj/audio-recording-ffmpeg-process audio-proc) + (setq cj/video-recording-ffmpeg-process video-proc) + ;; Call sentinel with unknown process + (cj/recording-process-sentinel fake-process "finished\n") + ;; Audio and video variables should NOT be cleared + (should (eq audio-proc cj/audio-recording-ffmpeg-process)) + (should (eq video-proc cj/video-recording-ffmpeg-process)) + (delete-process audio-proc) + (delete-process video-proc)) + (test-sentinel-teardown))) + +(ert-deftest test-video-audio-recording-process-sentinel-error-nil-event-handled () + "Test that sentinel handles nil event string gracefully." + (test-sentinel-setup) + (unwind-protect + (let ((fake-process (make-process :name "test-audio" :command '("sh" "-c" "exit 0")))) + (setq cj/audio-recording-ffmpeg-process fake-process) + ;; Mock process-status to return 'exit + (cl-letf (((symbol-function 'process-status) + (lambda (_proc) 'exit))) + ;; Should not crash with nil event (string-trim will error, but that's caught) + ;; The function uses string-trim without protection, so this will error + ;; Testing that it doesn't crash means we expect an error + (should-error + (cj/recording-process-sentinel fake-process nil)))) + (test-sentinel-teardown))) + +(ert-deftest test-video-audio-recording-process-sentinel-error-empty-event-handled () + "Test that sentinel handles empty event string gracefully." + (test-sentinel-setup) + (unwind-protect + (let ((fake-process (make-process :name "test-audio" :command '("sh" "-c" "exit 0")))) + (setq cj/audio-recording-ffmpeg-process fake-process) + ;; Mock process-status to return 'exit + (cl-letf (((symbol-function 'process-status) + (lambda (_proc) 'exit))) + ;; Empty string is fine - string-trim handles it + ;; No error should be raised + (cj/recording-process-sentinel fake-process "") + ;; Variable should be cleared + (should (null cj/audio-recording-ffmpeg-process)))) + (test-sentinel-teardown))) + +(provide 'test-video-audio-recording-process-sentinel) +;;; test-video-audio-recording-process-sentinel.el ends here -- cgit v1.2.3