blob: 8abe17044a2c4925ed4e4a95396754d6a6f5aed7 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
;;; test-music-config--renumber-rows.el --- Tests for playlist row numbering -*- coding: utf-8; lexical-binding: t; -*-
;;
;; Author: Craig Jennings <c@cjennings.net>
;;
;;; Commentary:
;; Playlist rows carry a numeric overlay prefix so the cursor stays visible
;; when it sits on a cover-art thumbnail and each row's position in the list
;; is readable. The renumber walks the buffer and rebuilds the overlays; a
;; buffer-local after-change hook debounces it behind an idle timer. Overlays
;; leave the buffer text untouched (EMMS owns it), so these tests drive plain
;; temp buffers.
;;; Code:
(require 'ert)
(require 'cl-lib)
(defvar cj/custom-keymap (make-sparse-keymap)
"Stub keymap for testing.")
(require 'music-config)
(defun test-music-renumber--numbers (buffer)
"Return the overlay number strings in BUFFER, in position order."
(with-current-buffer buffer
(mapcar (lambda (ov) (overlay-get ov 'before-string))
(sort (seq-filter (lambda (ov) (overlay-get ov 'cj-music-row-number))
(overlays-in (point-min) (point-max)))
(lambda (a b) (< (overlay-start a) (overlay-start b)))))))
;;; Normal Cases
(ert-deftest test-music-renumber-rows-numbers-each-line ()
"Normal: every non-blank line gets a sequential number overlay."
(with-temp-buffer
(insert "track one\ntrack two\ntrack three\n")
(cj/music--renumber-rows (current-buffer))
(should (equal (mapcar #'substring-no-properties
(test-music-renumber--numbers (current-buffer)))
'(" 1 " " 2 " " 3 ")))))
(ert-deftest test-music-renumber-rows-idempotent ()
"Normal: renumbering twice leaves one overlay per line, not two."
(with-temp-buffer
(insert "track one\ntrack two\n")
(cj/music--renumber-rows (current-buffer))
(cj/music--renumber-rows (current-buffer))
(should (= 2 (length (test-music-renumber--numbers (current-buffer)))))))
;;; Boundary Cases
(ert-deftest test-music-renumber-rows-skips-blank-lines ()
"Boundary: blank lines are not numbered and don't advance the count."
(with-temp-buffer
(insert "track one\n\ntrack two\n")
(cj/music--renumber-rows (current-buffer))
(should (equal (mapcar #'substring-no-properties
(test-music-renumber--numbers (current-buffer)))
'(" 1 " " 2 ")))))
(ert-deftest test-music-renumber-rows-empty-buffer-no-overlays ()
"Boundary: an empty buffer gets no overlays and no error."
(with-temp-buffer
(cj/music--renumber-rows (current-buffer))
(should-not (test-music-renumber--numbers (current-buffer)))))
;;; Error Cases
(ert-deftest test-music-renumber-rows-dead-buffer-noop ()
"Error: renumbering a killed buffer is a silent no-op (the debounce timer
can fire after the playlist buffer is gone)."
(let ((buf (generate-new-buffer " *test-renumber-dead*")))
(kill-buffer buf)
(should-not (cj/music--renumber-rows buf))))
;;; Hook wiring
(ert-deftest test-music-renumber-ensure-playlist-buffer-wires-hook ()
"Normal: the playlist buffer gets the debounced renumber on after-change."
(let (created)
(cl-letf (((symbol-function 'emms-playlist-mode) #'ignore))
(unwind-protect
(progn
(setq created (cj/music--ensure-playlist-buffer))
(with-current-buffer created
(should (member #'cj/music--schedule-renumber after-change-functions))))
(when (buffer-live-p created) (kill-buffer created))))))
(provide 'test-music-config--renumber-rows)
;;; test-music-config--renumber-rows.el ends here
|