diff options
| author | Craig Jennings <c@cjennings.net> | 2026-02-26 22:41:46 -0600 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-02-26 22:41:46 -0600 |
| commit | a46f8af939b112b603a2c95b2e83a1932b208e20 (patch) | |
| tree | c976afe867bfe7e57a3f425b911e2f654d913168 /tests/test-video-audio-recording--label-sinks.el | |
| parent | 8de47fd766fe57c7f89960ee110b209a946024cb (diff) | |
test(recording): add tests for label-devices, label-sinks, get-sink-apps
Fill test gaps from quality-engineer review: 3 new test files (28 tests)
and error cases for get-available-mics and get-available-sinks (+4 tests).
Diffstat (limited to 'tests/test-video-audio-recording--label-sinks.el')
| -rw-r--r-- | tests/test-video-audio-recording--label-sinks.el | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/tests/test-video-audio-recording--label-sinks.el b/tests/test-video-audio-recording--label-sinks.el new file mode 100644 index 00000000..6bec9349 --- /dev/null +++ b/tests/test-video-audio-recording--label-sinks.el @@ -0,0 +1,111 @@ +;;; test-video-audio-recording--label-sinks.el --- Tests for sink labeling -*- lexical-binding: t; -*- + +;;; Commentary: +;; Unit tests for cj/recording--label-sinks. +;; Verifies that sink labels include app names for active sinks, +;; e.g. "JDS Labs [in use] (Firefox)" and sort correctly. + +;;; Code: + +(require 'ert) + +;; Stub dependencies before loading the module +(defvar cj/custom-keymap (make-sparse-keymap) + "Stub keymap for testing.") + +(require 'video-audio-recording) + +;;; Helpers + +(defun test-label-sinks--stub (sink-apps-alist sinks-short-output) + "Return a cl-letf binding list that stubs get-sink-apps and sinks short. +SINK-APPS-ALIST is the return value for `cj/recording--get-sink-apps'. +SINKS-SHORT-OUTPUT is the raw pactl list sinks short output." + ;; We use cl-letf in each test to stub both get-sink-apps and + ;; shell-command-to-string (for the sinks short call inside label-sinks). + `(((symbol-function 'cj/recording--get-sink-apps) + (lambda () ',sink-apps-alist)) + ((symbol-function 'shell-command-to-string) + (lambda (_cmd) ,sinks-short-output)))) + +;;; Normal Cases + +(ert-deftest test-video-audio-recording--label-sinks-normal-appends-app-names () + "Test that active sinks show app names in parentheses." + (cl-letf (((symbol-function 'cj/recording--get-sink-apps) + (lambda () '(("65" "Firefox")))) + ((symbol-function 'shell-command-to-string) + (lambda (_cmd) "65\tjds-labs\tmodule\ts16le\tRUNNING\n"))) + (let ((result (cj/recording--label-sinks + '(("jds-labs" "JDS Labs" "RUNNING" "no"))))) + (should (= 1 (length result))) + (should (string-match-p "JDS Labs \\[in use\\] (Firefox)" (caar result)))))) + +(ert-deftest test-video-audio-recording--label-sinks-normal-multiple-apps () + "Test that multiple apps are comma-separated." + (cl-letf (((symbol-function 'cj/recording--get-sink-apps) + (lambda () '(("65" "Firefox" "Spotify")))) + ((symbol-function 'shell-command-to-string) + (lambda (_cmd) "65\tjds-labs\tmodule\ts16le\tRUNNING\n"))) + (let ((result (cj/recording--label-sinks + '(("jds-labs" "JDS Labs" "RUNNING" "no"))))) + (should (string-match-p "(Firefox, Spotify)" (caar result)))))) + +(ert-deftest test-video-audio-recording--label-sinks-normal-no-apps () + "Test that sinks without apps have no parenthesized suffix." + (cl-letf (((symbol-function 'cj/recording--get-sink-apps) + (lambda () nil)) + ((symbol-function 'shell-command-to-string) + (lambda (_cmd) "65\tjds-labs\tmodule\ts16le\tSUSPENDED\n"))) + (let ((result (cj/recording--label-sinks + '(("jds-labs" "JDS Labs" "SUSPENDED" "no"))))) + (should (string-match-p "JDS Labs \\[available\\]$" (caar result)))))) + +(ert-deftest test-video-audio-recording--label-sinks-normal-sort-order () + "Test that sinks sort: in use → ready → available → muted." + (cl-letf (((symbol-function 'cj/recording--get-sink-apps) + (lambda () '(("65" "Firefox")))) + ((symbol-function 'shell-command-to-string) + (lambda (_cmd) + "65\tsink-run\tmodule\ts16le\tRUNNING\n73\tsink-idle\tmodule\ts16le\tIDLE\n80\tsink-sus\tmodule\ts16le\tSUSPENDED\n"))) + (let ((result (cj/recording--label-sinks + '(("sink-sus" "Suspended" "SUSPENDED" "no") + ("sink-run" "Running" "RUNNING" "no") + ("sink-idle" "Idle" "IDLE" "no"))))) + (should (equal '("sink-run" "sink-idle" "sink-sus") + (mapcar #'cdr result)))))) + +(ert-deftest test-video-audio-recording--label-sinks-normal-muted-sink () + "Test that muted sinks get [muted] label and no apps shown." + (cl-letf (((symbol-function 'cj/recording--get-sink-apps) + (lambda () nil)) + ((symbol-function 'shell-command-to-string) + (lambda (_cmd) "65\tmuted-sink\tmodule\ts16le\tSUSPENDED\n"))) + (let ((result (cj/recording--label-sinks + '(("muted-sink" "Muted Sink" "SUSPENDED" "yes"))))) + (should (string-match-p "\\[muted\\]" (caar result)))))) + +;;; Boundary Cases + +(ert-deftest test-video-audio-recording--label-sinks-boundary-empty () + "Test that empty sink list returns empty alist." + (cl-letf (((symbol-function 'cj/recording--get-sink-apps) + (lambda () nil)) + ((symbol-function 'shell-command-to-string) + (lambda (_cmd) ""))) + (should (null (cj/recording--label-sinks nil))))) + +(ert-deftest test-video-audio-recording--label-sinks-boundary-sink-not-in-short () + "Test that sink not found in sinks short still gets label (no apps)." + (cl-letf (((symbol-function 'cj/recording--get-sink-apps) + (lambda () '(("65" "Firefox")))) + ((symbol-function 'shell-command-to-string) + (lambda (_cmd) ""))) + (let ((result (cj/recording--label-sinks + '(("unknown-sink" "Unknown" "IDLE" "no"))))) + (should (= 1 (length result))) + ;; No app suffix since index lookup returned nil + (should (string-match-p "Unknown \\[ready\\]$" (caar result)))))) + +(provide 'test-video-audio-recording--label-sinks) +;;; test-video-audio-recording--label-sinks.el ends here |
