From 7f9c3b744a8dbd4a575a173280d75b0cc27c0695 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Sat, 20 Jun 2026 12:35:29 -0400 Subject: refactor(chrono-tools): extract tmr sound-file helpers, flatten the command cj/tmr-select-sound-file nested cond/let five deep, mixing the current-sound lookup, the completing-read, the setq, and the message. Extract cj/tmr--current-sound-name and cj/tmr--apply-sound-file (the testable parts) and flatten the inner conds to ifs. The command keeps the prefix-arg/no-dir/no-files guards and the prompt. Adds coverage for both helpers. --- modules/chrono-tools.el | 34 ++++++++++--------- tests/test-chrono-tools--sound-helpers.el | 54 +++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 15 deletions(-) create mode 100644 tests/test-chrono-tools--sound-helpers.el diff --git a/modules/chrono-tools.el b/modules/chrono-tools.el index 9ccba6676..6f88b2018 100644 --- a/modules/chrono-tools.el +++ b/modules/chrono-tools.el @@ -66,6 +66,19 @@ Returns nil if `sounds-dir' does not exist." (message "Timer sound reset to default: %s" (file-name-nondirectory notification-sound))) +(defun cj/tmr--current-sound-name () + "Return the basename of the current `tmr-sound-file' if it exists, else nil." + (when (and tmr-sound-file (file-exists-p tmr-sound-file)) + (file-name-nondirectory tmr-sound-file))) + +(defun cj/tmr--apply-sound-file (selected-file) + "Set `tmr-sound-file' to SELECTED-FILE, a basename within `sounds-dir'. +Return the confirmation message string (noting when it is the default sound)." + (setq tmr-sound-file (expand-file-name selected-file sounds-dir)) + (if (equal tmr-sound-file notification-sound) + (format "Timer sound set to default: %s" selected-file) + (format "Timer sound set to: %s" selected-file))) + (defun cj/tmr-select-sound-file () "Select a sound file from `sounds-dir' to use for tmr timers. @@ -80,13 +93,9 @@ Present all audio files in the sounds directory and set the chosen file as (if (boundp 'sounds-dir) sounds-dir ""))) (t (let ((sound-files (cj/tmr--available-sound-files))) - (cond - ((null sound-files) - (message "No audio files found in %s" sounds-dir)) - (t - (let* ((current-file (when (and tmr-sound-file - (file-exists-p tmr-sound-file)) - (file-name-nondirectory tmr-sound-file))) + (if (null sound-files) + (message "No audio files found in %s" sounds-dir) + (let* ((current-file (cj/tmr--current-sound-name)) (selected-file (completing-read (format "Select timer sound%s: " @@ -94,14 +103,9 @@ Present all audio files in the sounds directory and set the chosen file as (format " (current: %s)" current-file) "")) sound-files nil t nil nil current-file))) - (cond - ((or (null selected-file) (string-empty-p selected-file)) - (message "No file selected")) - (t - (setq tmr-sound-file (expand-file-name selected-file sounds-dir)) - (if (equal tmr-sound-file notification-sound) - (message "Timer sound set to default: %s" selected-file) - (message "Timer sound set to: %s" selected-file))))))))))) + (if (or (null selected-file) (string-empty-p selected-file)) + (message "No file selected") + (message "%s" (cj/tmr--apply-sound-file selected-file))))))))) (use-package tmr :defer 0.5 diff --git a/tests/test-chrono-tools--sound-helpers.el b/tests/test-chrono-tools--sound-helpers.el new file mode 100644 index 000000000..08f71f9bb --- /dev/null +++ b/tests/test-chrono-tools--sound-helpers.el @@ -0,0 +1,54 @@ +;;; test-chrono-tools--sound-helpers.el --- Tests for the tmr sound-file helpers -*- lexical-binding: t; -*- + +;;; Commentary: +;; cj/tmr--current-sound-name and cj/tmr--apply-sound-file were extracted from +;; the deeply-nested cj/tmr-select-sound-file so the "what's the current sound" +;; and "set the chosen sound" steps are unit-testable apart from the +;; completing-read UI. + +;;; Code: + +(require 'ert) + +(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory)) +(require 'chrono-tools) + +(defvar tmr-sound-file) +(defvar sounds-dir) +(defvar notification-sound) + +(ert-deftest test-chrono-current-sound-name-existing () + "Normal: returns the basename when the current sound file exists." + (let* ((f (make-temp-file "tmr-sound" nil ".wav")) + (tmr-sound-file f)) + (unwind-protect + (should (equal (cj/tmr--current-sound-name) (file-name-nondirectory f))) + (delete-file f)))) + +(ert-deftest test-chrono-current-sound-name-missing-or-nil () + "Boundary: a missing file or nil yields nil." + (let ((tmr-sound-file "/no/such/file.wav")) + (should (null (cj/tmr--current-sound-name)))) + (let ((tmr-sound-file nil)) + (should (null (cj/tmr--current-sound-name))))) + +(ert-deftest test-chrono-apply-sound-file-sets-and-messages () + "Normal: sets tmr-sound-file under sounds-dir and reports the choice." + (let ((sounds-dir "/snd") + (notification-sound "/snd/default.wav") + (tmr-sound-file nil)) + (let ((msg (cj/tmr--apply-sound-file "chime.wav"))) + (should (equal tmr-sound-file "/snd/chime.wav")) + (should (string-match-p "Timer sound set to: chime.wav" msg))))) + +(ert-deftest test-chrono-apply-sound-file-default-branch () + "Boundary: choosing the notification sound reports it as the default." + (let ((sounds-dir "/snd") + (notification-sound "/snd/default.wav") + (tmr-sound-file nil)) + (let ((msg (cj/tmr--apply-sound-file "default.wav"))) + (should (equal tmr-sound-file "/snd/default.wav")) + (should (string-match-p "default: default.wav" msg))))) + +(provide 'test-chrono-tools--sound-helpers) +;;; test-chrono-tools--sound-helpers.el ends here -- cgit v1.2.3