summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/test-video-audio-recording-command-structure.el311
1 files changed, 311 insertions, 0 deletions
diff --git a/tests/test-video-audio-recording-command-structure.el b/tests/test-video-audio-recording-command-structure.el
new file mode 100644
index 00000000..c964b246
--- /dev/null
+++ b/tests/test-video-audio-recording-command-structure.el
@@ -0,0 +1,311 @@
+;;; test-video-audio-recording-command-structure.el --- Tests for recording command string structure -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; Tests that validate the structure and syntax of shell commands generated
+;; for video and audio recording. These tests catch issues like invalid flags,
+;; wrong encoder names, and incorrect output syntax that behavioral tests miss.
+
+;;; Code:
+
+(require 'ert)
+
+;; Stub dependencies before loading the module
+(defvar cj/custom-keymap (make-sparse-keymap)
+ "Stub keymap for testing.")
+
+(defvar video-recordings-dir "/tmp/video-recordings/")
+(defvar audio-recordings-dir "/tmp/audio-recordings/")
+
+;; Now load the actual production module
+(require 'video-audio-recording)
+
+;;; Setup and Teardown
+
+(defun test-command-structure-setup ()
+ "Reset all variables before each test."
+ (setq cj/video-recording-ffmpeg-process nil)
+ (setq cj/audio-recording-ffmpeg-process nil)
+ (setq cj/recording-mic-device "test-mic-device")
+ (setq cj/recording-system-device "test-monitor-device")
+ (setq cj/recording-mic-boost 2.0)
+ (setq cj/recording-system-volume 1.0))
+
+(defun test-command-structure-teardown ()
+ "Clean up after each test."
+ (when cj/video-recording-ffmpeg-process
+ (ignore-errors (delete-process cj/video-recording-ffmpeg-process)))
+ (when cj/audio-recording-ffmpeg-process
+ (ignore-errors (delete-process cj/audio-recording-ffmpeg-process)))
+ (setq cj/video-recording-ffmpeg-process nil)
+ (setq cj/audio-recording-ffmpeg-process nil)
+ (setq cj/recording-mic-device nil)
+ (setq cj/recording-system-device nil))
+
+;;; Wayland Video Recording - Command Structure
+
+(ert-deftest test-video-recording-wayland-command-contains-wf-recorder ()
+ "Test that Wayland video recording uses wf-recorder."
+ (test-command-structure-setup)
+ (unwind-protect
+ (let ((command nil))
+ (cl-letf (((symbol-function 'cj/recording--wayland-p) (lambda () t))
+ ((symbol-function 'start-process-shell-command)
+ (lambda (_name _buffer cmd)
+ (setq command cmd)
+ (make-process :name "fake-video" :command '("sleep" "1000")))))
+ (cj/ffmpeg-record-video video-recordings-dir)
+ (should (string-match-p "wf-recorder" command))))
+ (test-command-structure-teardown)))
+
+(ert-deftest test-video-recording-wayland-command-has-auto-confirm-flag ()
+ "Test that wf-recorder command includes -y flag to auto-confirm overwrite."
+ (test-command-structure-setup)
+ (unwind-protect
+ (let ((command nil))
+ (cl-letf (((symbol-function 'cj/recording--wayland-p) (lambda () t))
+ ((symbol-function 'start-process-shell-command)
+ (lambda (_name _buffer cmd)
+ (setq command cmd)
+ (make-process :name "fake-video" :command '("sleep" "1000")))))
+ (cj/ffmpeg-record-video video-recordings-dir)
+ (should (string-match-p "wf-recorder -y" command))))
+ (test-command-structure-teardown)))
+
+(ert-deftest test-video-recording-wayland-command-has-correct-encoder ()
+ "Test that wf-recorder uses libx264 encoder (not h264)."
+ (test-command-structure-setup)
+ (unwind-protect
+ (let ((command nil))
+ (cl-letf (((symbol-function 'cj/recording--wayland-p) (lambda () t))
+ ((symbol-function 'start-process-shell-command)
+ (lambda (_name _buffer cmd)
+ (setq command cmd)
+ (make-process :name "fake-video" :command '("sleep" "1000")))))
+ (cj/ffmpeg-record-video video-recordings-dir)
+ ;; Should use libx264, not h264
+ (should (string-match-p "-c libx264" command))
+ (should-not (string-match-p "-c h264[^a-z]" command))))
+ (test-command-structure-teardown)))
+
+(ert-deftest test-video-recording-wayland-command-has-muxer-format ()
+ "Test that wf-recorder specifies matroska muxer with -m flag."
+ (test-command-structure-setup)
+ (unwind-protect
+ (let ((command nil))
+ (cl-letf (((symbol-function 'cj/recording--wayland-p) (lambda () t))
+ ((symbol-function 'start-process-shell-command)
+ (lambda (_name _buffer cmd)
+ (setq command cmd)
+ (make-process :name "fake-video" :command '("sleep" "1000")))))
+ (cj/ffmpeg-record-video video-recordings-dir)
+ (should (string-match-p "-m matroska" command))))
+ (test-command-structure-teardown)))
+
+(ert-deftest test-video-recording-wayland-command-outputs-to-stdout ()
+ "Test that wf-recorder outputs to stdout using -f /dev/stdout."
+ (test-command-structure-setup)
+ (unwind-protect
+ (let ((command nil))
+ (cl-letf (((symbol-function 'cj/recording--wayland-p) (lambda () t))
+ ((symbol-function 'start-process-shell-command)
+ (lambda (_name _buffer cmd)
+ (setq command cmd)
+ (make-process :name "fake-video" :command '("sleep" "1000")))))
+ (cj/ffmpeg-record-video video-recordings-dir)
+ ;; Should use -f /dev/stdout, not -o -
+ (should (string-match-p "-f /dev/stdout" command))
+ (should-not (string-match-p " -o -" command))))
+ (test-command-structure-teardown)))
+
+(ert-deftest test-video-recording-wayland-command-no-invalid-flags ()
+ "Test that wf-recorder command doesn't contain invalid flags."
+ (test-command-structure-setup)
+ (unwind-protect
+ (let ((command nil))
+ (cl-letf (((symbol-function 'cj/recording--wayland-p) (lambda () t))
+ ((symbol-function 'start-process-shell-command)
+ (lambda (_name _buffer cmd)
+ (setq command cmd)
+ (make-process :name "fake-video" :command '("sleep" "1000")))))
+ (cj/ffmpeg-record-video video-recordings-dir)
+ ;; These flags don't exist in wf-recorder
+ (should-not (string-match-p "--no-audio" command))
+ (should-not (string-match-p "--noaudio" command))))
+ (test-command-structure-teardown)))
+
+(ert-deftest test-video-recording-wayland-command-pipes-to-ffmpeg ()
+ "Test that wf-recorder output is piped to ffmpeg."
+ (test-command-structure-setup)
+ (unwind-protect
+ (let ((command nil))
+ (cl-letf (((symbol-function 'cj/recording--wayland-p) (lambda () t))
+ ((symbol-function 'start-process-shell-command)
+ (lambda (_name _buffer cmd)
+ (setq command cmd)
+ (make-process :name "fake-video" :command '("sleep" "1000")))))
+ (cj/ffmpeg-record-video video-recordings-dir)
+ ;; Should pipe wf-recorder to ffmpeg
+ (should (string-match-p "wf-recorder.*|.*ffmpeg" command))))
+ (test-command-structure-teardown)))
+
+(ert-deftest test-video-recording-wayland-ffmpeg-reads-from-pipe ()
+ "Test that ffmpeg reads from pipe input."
+ (test-command-structure-setup)
+ (unwind-protect
+ (let ((command nil))
+ (cl-letf (((symbol-function 'cj/recording--wayland-p) (lambda () t))
+ ((symbol-function 'start-process-shell-command)
+ (lambda (_name _buffer cmd)
+ (setq command cmd)
+ (make-process :name "fake-video" :command '("sleep" "1000")))))
+ (cj/ffmpeg-record-video video-recordings-dir)
+ (should (string-match-p "ffmpeg -i pipe:0" command))))
+ (test-command-structure-teardown)))
+
+;;; X11 Video Recording - Command Structure
+
+(ert-deftest test-video-recording-x11-command-uses-x11grab ()
+ "Test that X11 video recording uses ffmpeg x11grab."
+ (test-command-structure-setup)
+ (unwind-protect
+ (let ((command nil))
+ (cl-letf (((symbol-function 'cj/recording--wayland-p) (lambda () nil))
+ ((symbol-function 'start-process-shell-command)
+ (lambda (_name _buffer cmd)
+ (setq command cmd)
+ (make-process :name "fake-video" :command '("sleep" "1000")))))
+ (cj/ffmpeg-record-video video-recordings-dir)
+ (should (string-match-p "x11grab" command))))
+ (test-command-structure-teardown)))
+
+(ert-deftest test-video-recording-x11-command-no-wf-recorder ()
+ "Test that X11 video recording doesn't use wf-recorder."
+ (test-command-structure-setup)
+ (unwind-protect
+ (let ((command nil))
+ (cl-letf (((symbol-function 'cj/recording--wayland-p) (lambda () nil))
+ ((symbol-function 'start-process-shell-command)
+ (lambda (_name _buffer cmd)
+ (setq command cmd)
+ (make-process :name "fake-video" :command '("sleep" "1000")))))
+ (cj/ffmpeg-record-video video-recordings-dir)
+ (should-not (string-match-p "wf-recorder" command))))
+ (test-command-structure-teardown)))
+
+(ert-deftest test-video-recording-x11-command-captures-display ()
+ "Test that X11 video recording captures from display :0."
+ (test-command-structure-setup)
+ (unwind-protect
+ (let ((command nil))
+ (cl-letf (((symbol-function 'cj/recording--wayland-p) (lambda () nil))
+ ((symbol-function 'start-process-shell-command)
+ (lambda (_name _buffer cmd)
+ (setq command cmd)
+ (make-process :name "fake-video" :command '("sleep" "1000")))))
+ (cj/ffmpeg-record-video video-recordings-dir)
+ (should (string-match-p "-i :0" command))))
+ (test-command-structure-teardown)))
+
+;;; Audio Recording - Command Structure
+
+(ert-deftest test-audio-recording-command-uses-ffmpeg ()
+ "Test that audio recording uses ffmpeg directly."
+ (test-command-structure-setup)
+ (unwind-protect
+ (let ((command nil))
+ (cl-letf (((symbol-function 'start-process-shell-command)
+ (lambda (_name _buffer cmd)
+ (setq command cmd)
+ (make-process :name "fake-audio" :command '("sleep" "1000")))))
+ (cj/ffmpeg-record-audio audio-recordings-dir)
+ (should (string-match-p "^ffmpeg " command))))
+ (test-command-structure-teardown)))
+
+(ert-deftest test-audio-recording-command-uses-pulse-input ()
+ "Test that audio recording uses pulse audio input."
+ (test-command-structure-setup)
+ (unwind-protect
+ (let ((command nil))
+ (cl-letf (((symbol-function 'start-process-shell-command)
+ (lambda (_name _buffer cmd)
+ (setq command cmd)
+ (make-process :name "fake-audio" :command '("sleep" "1000")))))
+ (cj/ffmpeg-record-audio audio-recordings-dir)
+ (should (string-match-p "-f pulse" command))))
+ (test-command-structure-teardown)))
+
+(ert-deftest test-audio-recording-command-outputs-m4a ()
+ "Test that audio recording outputs to .m4a file."
+ (test-command-structure-setup)
+ (unwind-protect
+ (let ((command nil))
+ (cl-letf (((symbol-function 'start-process-shell-command)
+ (lambda (_name _buffer cmd)
+ (setq command cmd)
+ (make-process :name "fake-audio" :command '("sleep" "1000")))))
+ (cj/ffmpeg-record-audio audio-recordings-dir)
+ (should (string-match-p "\\.m4a" command))))
+ (test-command-structure-teardown)))
+
+;;; Common Command Structure (Both Video and Audio)
+
+(ert-deftest test-video-recording-command-has-audio-filter-complex ()
+ "Test that video recording includes audio filter for mixing mic and system."
+ (test-command-structure-setup)
+ (unwind-protect
+ (let ((command nil))
+ (cl-letf (((symbol-function 'cj/recording--wayland-p) (lambda () t))
+ ((symbol-function 'start-process-shell-command)
+ (lambda (_name _buffer cmd)
+ (setq command cmd)
+ (make-process :name "fake-video" :command '("sleep" "1000")))))
+ (cj/ffmpeg-record-video video-recordings-dir)
+ (should (string-match-p "-filter_complex" command))
+ (should (string-match-p "amerge" command))))
+ (test-command-structure-teardown)))
+
+(ert-deftest test-video-recording-command-maps-video-and-audio ()
+ "Test that video recording maps both video and audio streams."
+ (test-command-structure-setup)
+ (unwind-protect
+ (let ((command nil))
+ (cl-letf (((symbol-function 'cj/recording--wayland-p) (lambda () t))
+ ((symbol-function 'start-process-shell-command)
+ (lambda (_name _buffer cmd)
+ (setq command cmd)
+ (make-process :name "fake-video" :command '("sleep" "1000")))))
+ (cj/ffmpeg-record-video video-recordings-dir)
+ (should (string-match-p "-map 0:v" command))
+ (should (string-match-p "-map.*\\[out\\]" command))))
+ (test-command-structure-teardown)))
+
+(ert-deftest test-video-recording-command-copies-video-codec ()
+ "Test that video recording copies video codec (no re-encoding)."
+ (test-command-structure-setup)
+ (unwind-protect
+ (let ((command nil))
+ (cl-letf (((symbol-function 'cj/recording--wayland-p) (lambda () t))
+ ((symbol-function 'start-process-shell-command)
+ (lambda (_name _buffer cmd)
+ (setq command cmd)
+ (make-process :name "fake-video" :command '("sleep" "1000")))))
+ (cj/ffmpeg-record-video video-recordings-dir)
+ (should (string-match-p "-c:v copy" command))))
+ (test-command-structure-teardown)))
+
+(ert-deftest test-video-recording-command-outputs-mkv ()
+ "Test that video recording outputs to .mkv file."
+ (test-command-structure-setup)
+ (unwind-protect
+ (let ((command nil))
+ (cl-letf (((symbol-function 'cj/recording--wayland-p) (lambda () t))
+ ((symbol-function 'start-process-shell-command)
+ (lambda (_name _buffer cmd)
+ (setq command cmd)
+ (make-process :name "fake-video" :command '("sleep" "1000")))))
+ (cj/ffmpeg-record-video video-recordings-dir)
+ (should (string-match-p "\\.mkv" command))))
+ (test-command-structure-teardown)))
+
+(provide 'test-video-audio-recording-command-structure)
+;;; test-video-audio-recording-command-structure.el ends here