aboutsummaryrefslogtreecommitdiff
path: root/tests/test-music-config-commands.el
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-14 04:18:33 -0500
committerCraig Jennings <c@cjennings.net>2026-05-14 04:18:33 -0500
commit9d9afb4e971c795529046bb7a5dd60b340e1096c (patch)
treee93c06c27d437a0a5e75afded21bf93b05331df2 /tests/test-music-config-commands.el
parent7994ee3d0f68d1cda261b4b6ed2a82671d9095eb (diff)
downloaddotemacs-9d9afb4e971c795529046bb7a5dd60b340e1096c.tar.gz
dotemacs-9d9afb4e971c795529046bb7a5dd60b340e1096c.zip
test(music-config): cover add-directory, fuzzy-select, playlist-clear, next/previous, consume-toggle
Diffstat (limited to 'tests/test-music-config-commands.el')
-rw-r--r--tests/test-music-config-commands.el191
1 files changed, 191 insertions, 0 deletions
diff --git a/tests/test-music-config-commands.el b/tests/test-music-config-commands.el
new file mode 100644
index 00000000..d57e339c
--- /dev/null
+++ b/tests/test-music-config-commands.el
@@ -0,0 +1,191 @@
+;;; test-music-config-commands.el --- Tests for music-config interactive commands -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; Sibling tests cover the pure helpers (valid-file-p, valid-directory-p,
+;; collect-entries-recursive, completion-table, safe-filename, etc).
+;; This file covers the user-facing wrappers that route through them:
+;;
+;; cj/music-add-directory-recursive
+;; cj/music-fuzzy-select-and-add
+;; cj/music-playlist-clear
+;; cj/music-next
+;; cj/music-previous
+;; cj/music-toggle-consume
+
+;;; Code:
+
+(require 'ert)
+(require 'cl-lib)
+
+(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
+(require 'music-config)
+
+;; Top-level defvars so let-binds reach the dynamic binding under
+;; lexical scope.
+(defvar emms-random-playlist nil)
+(defvar cj/music--random-history nil)
+(defvar cj/music-consume-mode nil)
+(defvar cj/music-playlist-file nil)
+
+;;; cj/music-add-directory-recursive
+
+(ert-deftest test-music-add-directory-recursive-passes-dir-to-emms ()
+ "Normal: add-directory-recursive routes through emms-add-directory-tree."
+ (let* ((tmp (file-name-as-directory (make-temp-file "cj-music-add-" t)))
+ called)
+ (unwind-protect
+ (cl-letf (((symbol-function 'cj/music--ensure-playlist-buffer) #'ignore)
+ ((symbol-function 'emms-add-directory-tree)
+ (lambda (dir) (setq called dir)))
+ ((symbol-function 'message) #'ignore))
+ (cj/music-add-directory-recursive tmp))
+ (delete-directory tmp t))
+ (should (equal called tmp))))
+
+(ert-deftest test-music-add-directory-recursive-errors-on-non-directory ()
+ "Error: passing a regular file (not a directory) signals user-error."
+ (let ((tmp (make-temp-file "cj-music-not-dir-")))
+ (unwind-protect
+ (should-error (cj/music-add-directory-recursive tmp)
+ :type 'user-error)
+ (delete-file tmp))))
+
+;;; cj/music-fuzzy-select-and-add
+
+(ert-deftest test-music-fuzzy-select-adds-file-when-not-trailing-slash ()
+ "Normal: a non-directory pick routes through emms-add-file."
+ (let ((cj/music-root (file-name-as-directory (make-temp-file "cj-music-root-" t)))
+ added)
+ (unwind-protect
+ (progn
+ (with-temp-file (expand-file-name "song.mp3" cj/music-root))
+ (cl-letf (((symbol-function 'cj/music--collect-entries-recursive)
+ (lambda (_) '("song.mp3")))
+ ((symbol-function 'cj/music--completion-table)
+ (lambda (xs) xs))
+ ((symbol-function 'cj/music--ensure-playlist-buffer) #'ignore)
+ ((symbol-function 'completing-read)
+ (lambda (&rest _) "song.mp3"))
+ ((symbol-function 'emms-add-file)
+ (lambda (f) (setq added f)))
+ ((symbol-function 'message) #'ignore))
+ (cj/music-fuzzy-select-and-add)))
+ (delete-directory cj/music-root t))
+ (should (equal added (expand-file-name "song.mp3" cj/music-root)))))
+
+(ert-deftest test-music-fuzzy-select-adds-directory-when-trailing-slash ()
+ "Normal: a pick ending in / routes through add-directory-recursive."
+ (let ((cj/music-root (file-name-as-directory (make-temp-file "cj-music-root-" t)))
+ added-dir)
+ (unwind-protect
+ (progn
+ (make-directory (expand-file-name "albums/jazz" cj/music-root) t)
+ (cl-letf (((symbol-function 'cj/music--collect-entries-recursive)
+ (lambda (_) '("albums/jazz/")))
+ ((symbol-function 'cj/music--completion-table)
+ (lambda (xs) xs))
+ ((symbol-function 'cj/music--ensure-playlist-buffer) #'ignore)
+ ((symbol-function 'completing-read)
+ (lambda (&rest _) "albums/jazz/"))
+ ((symbol-function 'cj/music-add-directory-recursive)
+ (lambda (d) (setq added-dir d)))
+ ((symbol-function 'message) #'ignore))
+ (cj/music-fuzzy-select-and-add)))
+ (delete-directory cj/music-root t))
+ (should (equal (file-name-as-directory added-dir)
+ (file-name-as-directory
+ (expand-file-name "albums/jazz" cj/music-root))))))
+
+;;; cj/music-playlist-clear
+
+(ert-deftest test-music-playlist-clear-calls-emms-stop-and-clear ()
+ "Normal: playlist-clear calls emms-stop, emms-playlist-clear, and
+nils the active-playlist-file."
+ (let ((cj/music-playlist-file "/tmp/old.m3u")
+ stopped cleared msg)
+ (cl-letf (((symbol-function 'emms-stop)
+ (lambda () (setq stopped t)))
+ ((symbol-function 'emms-playlist-clear)
+ (lambda () (setq cleared t)))
+ ((symbol-function 'cj/music--ensure-playlist-buffer)
+ (lambda () (current-buffer)))
+ ((symbol-function 'message)
+ (lambda (fmt &rest args) (setq msg (apply #'format fmt args)))))
+ (cj/music-playlist-clear))
+ (should stopped)
+ (should cleared)
+ (should (string-match-p "Playlist cleared" msg))))
+
+;;; cj/music-next
+
+(ert-deftest test-music-next-uses-random-when-active ()
+ "Normal: with random mode active, next calls emms-random."
+ (let (called)
+ (cl-letf (((symbol-function 'emms-random)
+ (lambda () (setq called 'random)))
+ ((symbol-function 'emms-next)
+ (lambda () (setq called 'next))))
+ (let ((emms-random-playlist t))
+ (cj/music-next)))
+ (should (eq called 'random))))
+
+(ert-deftest test-music-next-uses-emms-next-when-sequential ()
+ "Normal: without random mode, next calls emms-next."
+ (let (called)
+ (cl-letf (((symbol-function 'emms-random)
+ (lambda () (setq called 'random)))
+ ((symbol-function 'emms-next)
+ (lambda () (setq called 'next))))
+ (let ((emms-random-playlist nil))
+ (cj/music-next)))
+ (should (eq called 'next))))
+
+;;; cj/music-previous
+
+(ert-deftest test-music-previous-replays-from-random-history ()
+ "Normal: with history present in random mode, previous reselects the
+last-played track and starts it."
+ (let ((emms-random-playlist t)
+ (cj/music--random-history '("/songs/last.mp3" "/songs/older.mp3"))
+ started)
+ (cl-letf (((symbol-function 'cj/music--find-track-in-playlist)
+ (lambda (_) 42))
+ ((symbol-function 'emms-playlist-select) #'ignore)
+ ((symbol-function 'emms-start)
+ (lambda () (setq started t)))
+ ((symbol-function 'emms-previous)
+ (lambda () (setq started 'previous))))
+ (cj/music-previous))
+ (should (eq started t))))
+
+(ert-deftest test-music-previous-falls-through-to-emms-previous ()
+ "Normal: with no history (random off), previous calls emms-previous."
+ (let ((emms-random-playlist nil)
+ (cj/music--random-history nil)
+ called)
+ (cl-letf (((symbol-function 'emms-previous)
+ (lambda () (setq called t))))
+ (cj/music-previous))
+ (should called)))
+
+;;; cj/music-toggle-consume
+
+(ert-deftest test-music-toggle-consume-flips-flag-and-hook ()
+ "Normal: toggle-consume flips the flag, then toggles back."
+ (let ((cj/music-consume-mode nil)
+ (added-hooks nil)
+ (removed-hooks nil))
+ (cl-letf (((symbol-function 'add-hook)
+ (lambda (hook _fn) (push hook added-hooks)))
+ ((symbol-function 'remove-hook)
+ (lambda (hook _fn) (push hook removed-hooks)))
+ ((symbol-function 'message) #'ignore))
+ (cj/music-toggle-consume)
+ (should cj/music-consume-mode)
+ (should (member 'emms-player-finished-hook added-hooks))
+ (cj/music-toggle-consume)
+ (should-not cj/music-consume-mode)
+ (should (member 'emms-player-finished-hook removed-hooks)))))
+
+(provide 'test-music-config-commands)
+;;; test-music-config-commands.el ends here