aboutsummaryrefslogtreecommitdiff
path: root/tests/test-music-config-create-radio-station.el
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test-music-config-create-radio-station.el')
-rw-r--r--tests/test-music-config-create-radio-station.el220
1 files changed, 99 insertions, 121 deletions
diff --git a/tests/test-music-config-create-radio-station.el b/tests/test-music-config-create-radio-station.el
index 1f4365a4..4f49f49b 100644
--- a/tests/test-music-config-create-radio-station.el
+++ b/tests/test-music-config-create-radio-station.el
@@ -1,153 +1,131 @@
-;;; test-music-config-create-radio-station.el --- Tests for radio station creation -*- coding: utf-8; lexical-binding: t; -*-
+;;; test-music-config-create-radio-station.el --- Tests for manual radio-station entry -*- coding: utf-8; lexical-binding: t; -*-
;;
;; Author: Craig Jennings <c@cjennings.net>
;;
;;; Commentary:
-;; Unit tests for cj/music-create-radio-station function.
-;; Tests M3U file creation for radio stations with stream URLs.
+;; Unit tests for cj/music-create-radio-station under the queue-first model:
+;; a hand-entered name + URL becomes a url track in the playlist queue (with
+;; the name as its title property) and playback starts. Nothing is written
+;; to disk — saving is the normal playlist-save flow.
;;
;; Test organization:
-;; - Normal Cases: Standard creation, EXTM3U format, safe filename
-;; - Boundary Cases: Unicode name, complex URL, overwrite confirmed
-;; - Error Cases: Empty name, empty URL, overwrite declined
-;;
+;; - Normal Cases: track queued with title, playback started, no file written
+;; - Boundary Cases: unicode name preserved verbatim
+;; - Error Cases: empty name, empty URL
+
;;; Code:
(require 'ert)
-(require 'testutil-general)
+(require 'cl-lib)
;; Stub missing dependencies before loading music-config
(defvar-keymap cj/custom-keymap
:doc "Stub keymap for testing")
-;; Load production code
-(require 'music-config)
-
-;;; Setup & Teardown
+(let ((emms-dir (car (file-expand-wildcards
+ (expand-file-name "elpa/emms-*" user-emacs-directory)))))
+ (when emms-dir (add-to-list 'load-path emms-dir)))
-(defun test-music-config-create-radio-station-setup ()
- "Setup test environment with temp directory for M3U output."
- (cj/create-test-base-dir)
- (cj/create-test-subdirectory "radio-playlists"))
+(require 'emms)
+(require 'music-config)
-(defun test-music-config-create-radio-station-teardown ()
- "Clean up test environment."
- (cj/delete-test-base-dir))
+(defmacro test-music-create-radio--with-env (&rest body)
+ "Run BODY with a fresh playlist buffer, playback mocked, messages captured."
+ `(let* ((cj/music-playlist-buffer-name
+ (generate-new-buffer-name "*test-create-radio*"))
+ (emms-player-playing-p nil)
+ (started 0) (msg nil))
+ (ignore started msg)
+ (unwind-protect
+ (cl-letf (((symbol-function 'emms-start)
+ (lambda () (setq started (1+ started))))
+ ((symbol-function 'emms-stop) #'ignore)
+ ((symbol-function 'message)
+ (lambda (fmt &rest args)
+ (when fmt (setq msg (apply #'format fmt args))))))
+ ,@body)
+ (when (get-buffer cj/music-playlist-buffer-name)
+ (kill-buffer cj/music-playlist-buffer-name)))))
+
+(defun test-music-create-radio--queued-tracks ()
+ "Track objects currently in the test playlist buffer."
+ (let ((tracks '()))
+ (with-current-buffer cj/music-playlist-buffer-name
+ (save-excursion
+ (goto-char (point-min))
+ (while (not (eobp))
+ (when-let ((tr (emms-playlist-track-at (point))))
+ (push tr tracks))
+ (forward-line 1))))
+ (nreverse tracks)))
;;; Normal Cases
-(ert-deftest test-music-config-create-radio-station-normal-creates-m3u-file ()
- "Creating a radio station produces an M3U file in the music root."
- (let ((test-dir (test-music-config-create-radio-station-setup)))
- (unwind-protect
- (let ((cj/music-m3u-root test-dir))
- (cj/music-create-radio-station "Jazz FM" "http://stream.jazzfm.com/radio")
- (let ((expected-file (expand-file-name "Jazz_FM_Radio.m3u" test-dir)))
- (should (file-exists-p expected-file))))
- (test-music-config-create-radio-station-teardown))))
-
-(ert-deftest test-music-config-create-radio-station-normal-extm3u-format ()
- "Created file contains EXTM3U header, EXTINF with station name, and URL."
- (let ((test-dir (test-music-config-create-radio-station-setup)))
+(ert-deftest test-music-config-create-radio-station-normal-queues-track ()
+ "Normal: name+url queues a url track carrying the name, and playback starts."
+ (test-music-create-radio--with-env
+ (cj/music-create-radio-station "Jazz FM" "http://stream.jazzfm.com/radio")
+ (let ((tracks (test-music-create-radio--queued-tracks)))
+ (should (= (length tracks) 1))
+ (should (eq (emms-track-type (car tracks)) 'url))
+ (should (equal (emms-track-name (car tracks)) "http://stream.jazzfm.com/radio"))
+ (should (equal (emms-track-get (car tracks) 'info-title) "Jazz FM")))
+ (should (= started 1))
+ (should (string-match-p "Jazz FM" msg))))
+
+(ert-deftest test-music-config-create-radio-station-normal-writes-no-file ()
+ "Normal: nothing lands on disk — saving is the playlist-save flow's job."
+ (let ((tmp (file-name-as-directory (make-temp-file "cj-radio-nofile-" t))))
(unwind-protect
- (let ((cj/music-m3u-root test-dir))
- (cj/music-create-radio-station "Jazz FM" "http://stream.jazzfm.com/radio")
- (let ((content (with-temp-buffer
- (insert-file-contents
- (expand-file-name "Jazz_FM_Radio.m3u" test-dir))
- (buffer-string))))
- (should (string-match-p "^#EXTM3U" content))
- (should (string-match-p "#EXTINF:-1,Jazz FM" content))
- (should (string-match-p "http://stream.jazzfm.com/radio" content))))
- (test-music-config-create-radio-station-teardown))))
-
-(ert-deftest test-music-config-create-radio-station-normal-safe-filename ()
- "Station name with special characters produces filesystem-safe filename."
- (let ((test-dir (test-music-config-create-radio-station-setup)))
- (unwind-protect
- (let ((cj/music-m3u-root test-dir))
- (cj/music-create-radio-station "Rock & Roll 101.5" "http://example.com/stream")
- ;; Spaces and special chars replaced with underscores
- (let ((expected-file (expand-file-name "Rock___Roll_101_5_Radio.m3u" test-dir)))
- (should (file-exists-p expected-file))))
- (test-music-config-create-radio-station-teardown))))
+ (test-music-create-radio--with-env
+ (let ((cj/music-m3u-root tmp)
+ (cj/music-radio-save-dir tmp))
+ (cj/music-create-radio-station "NPR" "https://example.test/stream")
+ (should-not (directory-files tmp nil "\\.m3u\\'"))))
+ (delete-directory tmp t))))
;;; Boundary Cases
-(ert-deftest test-music-config-create-radio-station-boundary-unicode-name-safe-filename ()
- "Unicode station name produces safe filename while preserving name in EXTINF."
- (let ((test-dir (test-music-config-create-radio-station-setup)))
- (unwind-protect
- (let ((cj/music-m3u-root test-dir))
- (cj/music-create-radio-station "Klassik Radio" "http://example.com/stream")
- ;; Name is all ASCII-safe, so filename uses it directly
- (should (file-exists-p (expand-file-name "Klassik_Radio_Radio.m3u" test-dir)))
- ;; Original name preserved in EXTINF inside the file
- (let ((content (with-temp-buffer
- (insert-file-contents
- (expand-file-name "Klassik_Radio_Radio.m3u" test-dir))
- (buffer-string))))
- (should (string-match-p "Klassik Radio" content))))
- (test-music-config-create-radio-station-teardown))))
-
-(ert-deftest test-music-config-create-radio-station-boundary-url-with-query-params ()
- "Complex URL with query parameters preserved in file content."
- (let ((test-dir (test-music-config-create-radio-station-setup)))
- (unwind-protect
- (let ((cj/music-m3u-root test-dir)
- (url "https://stream.example.com/radio?format=mp3&quality=320&token=abc123"))
- (cj/music-create-radio-station "Test Radio" url)
- (let ((content (with-temp-buffer
- (insert-file-contents
- (expand-file-name "Test_Radio_Radio.m3u" test-dir))
- (buffer-string))))
- (should (string-match-p (regexp-quote url) content))))
- (test-music-config-create-radio-station-teardown))))
-
-(ert-deftest test-music-config-create-radio-station-boundary-overwrite-confirmed ()
- "Overwriting existing file when user confirms succeeds."
- (let ((test-dir (test-music-config-create-radio-station-setup)))
- (unwind-protect
- (let ((cj/music-m3u-root test-dir))
- ;; Create initial file
- (cj/music-create-radio-station "MyRadio" "http://old.url/stream")
- (let ((file (expand-file-name "MyRadio_Radio.m3u" test-dir)))
- (should (file-exists-p file))
- ;; Overwrite with user confirming
- (cl-letf (((symbol-function 'yes-or-no-p) (lambda (_prompt) t)))
- (cj/music-create-radio-station "MyRadio" "http://new.url/stream"))
- ;; File should now contain new URL
- (let ((content (with-temp-buffer
- (insert-file-contents file)
- (buffer-string))))
- (should (string-match-p "http://new.url/stream" content))
- (should-not (string-match-p "http://old.url/stream" content)))))
- (test-music-config-create-radio-station-teardown))))
+(ert-deftest test-music-config-create-radio-station-boundary-unicode-name ()
+ "Boundary: a unicode name is kept verbatim on the track (no filename munging)."
+ (test-music-create-radio--with-env
+ (cj/music-create-radio-station "Café Del Mar ☕" "https://cafe.example/stream")
+ (should (equal (emms-track-get (car (test-music-create-radio--queued-tracks))
+ 'info-title)
+ "Café Del Mar ☕"))))
+
+;;; Keymap
+
+(ert-deftest test-music-config-radio-map-prefix-mirrors-playlist-keys ()
+ "Normal: C-; m r is a radio prefix whose n/t/m mirror the playlist buffer."
+ (let ((map (lookup-key cj/music-map "r")))
+ (should (keymapp map))
+ (should (eq (lookup-key map "n") 'cj/music-radio-search-by-name))
+ (should (eq (lookup-key map "t") 'cj/music-radio-search-by-tag))
+ (should (eq (lookup-key map "m") 'cj/music-create-radio-station))))
+
+(ert-deftest test-music-config-menu-map-lowercase-keys ()
+ "Normal: the menu's former uppercase keys live on lowercase homes, and the
+playlist buffer saves on s (single on 1, old save key v unbound)."
+ (should (eq (lookup-key cj/music-map "v") 'cj/music-playlist-show))
+ (should (eq (lookup-key cj/music-map "u") 'emms-shuffle))
+ (should (eq (lookup-key cj/music-map "l") 'emms-toggle-repeat-playlist))
+ (should-not (lookup-key cj/music-map "R"))
+ (should-not (lookup-key cj/music-map "M"))
+ (should-not (lookup-key cj/music-map "Z"))
+ (should (eq (lookup-key emms-playlist-mode-map "s") 'cj/music-playlist-save))
+ (should (eq (lookup-key emms-playlist-mode-map "1") 'emms-toggle-repeat-track))
+ (should-not (lookup-key emms-playlist-mode-map "v")))
;;; Error Cases
(ert-deftest test-music-config-create-radio-station-error-empty-name-signals-user-error ()
- "Empty station name signals user-error."
- (should-error (cj/music-create-radio-station "" "http://example.com/stream")
- :type 'user-error))
+ "Error: empty name signals user-error."
+ (should-error (cj/music-create-radio-station "" "https://x") :type 'user-error))
(ert-deftest test-music-config-create-radio-station-error-empty-url-signals-user-error ()
- "Empty URL signals user-error."
- (should-error (cj/music-create-radio-station "Test Radio" "")
- :type 'user-error))
-
-(ert-deftest test-music-config-create-radio-station-error-overwrite-declined-signals-user-error ()
- "Declining overwrite signals user-error."
- (let ((test-dir (test-music-config-create-radio-station-setup)))
- (unwind-protect
- (let ((cj/music-m3u-root test-dir))
- ;; Create initial file
- (cj/music-create-radio-station "MyRadio" "http://old.url/stream")
- ;; Decline overwrite
- (cl-letf (((symbol-function 'yes-or-no-p) (lambda (_prompt) nil)))
- (should-error (cj/music-create-radio-station "MyRadio" "http://new.url/stream")
- :type 'user-error)))
- (test-music-config-create-radio-station-teardown))))
+ "Error: empty URL signals user-error."
+ (should-error (cj/music-create-radio-station "NPR" "") :type 'user-error))
(provide 'test-music-config-create-radio-station)
;;; test-music-config-create-radio-station.el ends here