Emacs library to communicate with Music Player Daemon (MPD, https://www.musicpd.org/), a flexible, powerful, server-side application for playing music.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

377 lignes
16KB

  1. ;;; libmpdel-test.el --- Tests for libmpdel.el -*- lexical-binding: t; -*-
  2. ;; Copyright (C) 2017 Damien Cassou
  3. ;; Author: Damien Cassou <damien@cassou.me>
  4. ;; Url: https://gitlab.petton.fr/mpdel/mpdel
  5. ;; Package-requires: ((emacs "25.1"))
  6. ;; Version: 1.2.0
  7. ;; This program is free software; you can redistribute it and/or modify
  8. ;; it under the terms of the GNU General Public License as published by
  9. ;; the Free Software Foundation, either version 3 of the License, or
  10. ;; (at your option) any later version.
  11. ;; This program is distributed in the hope that it will be useful,
  12. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. ;; GNU General Public License for more details.
  15. ;; You should have received a copy of the GNU General Public License
  16. ;; along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. ;;; Commentary:
  18. ;; Tests for libmpdel.el.
  19. ;;; Code:
  20. (require 'ert)
  21. (require 'ert-x)
  22. (require 'cl-lib)
  23. (require 'libmpdel)
  24. ;;; Global private variables
  25. (ert-deftest libmpdel-test--response-regexp ()
  26. (should (string-match-p libmpdel--response-regexp "OK\n"))
  27. (should (string-match-p libmpdel--response-regexp "OK MPD 0.20.0\n"))
  28. (should (string-match-p libmpdel--response-regexp "ACK [51@10] {} unknown command \"foobar\"\n"))
  29. (should (string-match-p libmpdel--response-regexp "Artist: A-ha\nOK\n")))
  30. (ert-deftest libmpdel-test-msgfield-regexp ()
  31. (save-match-data
  32. (let ((line "key: value\n"))
  33. (should (string-match libmpdel--msgfield-regexp line))
  34. (should (equal "key" (match-string 1 line)))
  35. (should (equal "value" (match-string 2 line))))))
  36. ;;; Data structures
  37. (ert-deftest libmpdel-test-artist ()
  38. (let* ((artist (libmpdel--artist-create :name "The Artist"))
  39. (album (libmpdel--album-create :name "The Album" :artist artist))
  40. (song (libmpdel--song-create :name "The song" :album album)))
  41. (should (equal artist (libmpdel-artist artist)))
  42. (should (equal artist (libmpdel-artist album)))
  43. (should (equal artist (libmpdel-artist song)))))
  44. (ert-deftest libmpdel-test-artist-name ()
  45. (let* ((artist (libmpdel--artist-create :name "The Artist"))
  46. (album (libmpdel--album-create :name "The Album" :artist artist))
  47. (song (libmpdel--song-create :name "The song" :album album)))
  48. (should (equal "The Artist" (libmpdel-artist-name artist)))
  49. (should (equal "The Artist" (libmpdel-artist-name album)))
  50. (should (equal "The Artist" (libmpdel-artist-name song)))))
  51. (ert-deftest libmpdel-test-album-name ()
  52. (let* ((artist (libmpdel--artist-create :name "The Artist"))
  53. (album (libmpdel--album-create :name "The Album" :artist artist))
  54. (song (libmpdel--song-create :name "The song" :album album)))
  55. (should-error (libmpdel-album-name artist))
  56. (should (equal "The Album" (libmpdel-album-name album)))
  57. (should (equal "The Album" (libmpdel-album-name song)))))
  58. (ert-deftest libmpdel-test-album ()
  59. (let* ((artist (libmpdel--artist-create :name "The Artist"))
  60. (album (libmpdel--album-create :name "The Album" :artist artist))
  61. (song (libmpdel--song-create :name "The song" :album album)))
  62. (should-error (libmpdel-album artist))
  63. (should (equal album (libmpdel-album album)))
  64. (should (equal album (libmpdel-album song)))))
  65. (ert-deftest libmpdel-test-entity-name ()
  66. (let* ((artist (libmpdel--artist-create :name "The Artist"))
  67. (album (libmpdel--album-create :name "The Album" :artist artist))
  68. (song (libmpdel--song-create :name "The song" :album album))
  69. (stored-playlist (libmpdel--stored-playlist-create :name "The playlist")))
  70. (should (equal "The Artist" (libmpdel-entity-name artist)))
  71. (should (equal "The Album" (libmpdel-entity-name album)))
  72. (should (equal "The song" (libmpdel-entity-name song)))
  73. (should (equal "The playlist" (libmpdel-entity-name stored-playlist)))))
  74. (ert-deftest libmpdel-test-entity-parent ()
  75. (let* ((artist (libmpdel--artist-create :name "The Artist"))
  76. (album (libmpdel--album-create :name "The Album" :artist artist))
  77. (song (libmpdel--song-create :name "The song" :album album))
  78. (stored-playlist (libmpdel--stored-playlist-create :name "The playlist")))
  79. (should (equal 'artists (libmpdel-entity-parent artist)))
  80. (should (equal artist (libmpdel-entity-parent album)))
  81. (should (equal album (libmpdel-entity-parent song)))
  82. (should (equal 'stored-playlists (libmpdel-entity-parent stored-playlist)))
  83. (should-not (libmpdel-entity-parent 'stored-playlists))
  84. (should-not (libmpdel-entity-parent 'artists))
  85. (should-not (libmpdel-entity-parent 'current-playlist))))
  86. (ert-deftest libmpdel-test-create-song-from-data ()
  87. (let ((song (libmpdel--create-song-from-data
  88. '((Title . "The song")
  89. (file . "foo/song.ogg")
  90. (Album . "The Album")
  91. (Artist . "The Artist")))))
  92. (should (equal "The song" (libmpdel-entity-name song)))
  93. (should (equal "foo/song.ogg" (libmpdel-song-file song)))
  94. (should (equal "The Album" (libmpdel-entity-name (libmpdel-album song))))
  95. (should (equal "The Artist" (libmpdel-entity-name (libmpdel-artist (libmpdel-album song)))))))
  96. (ert-deftest libmpdel-test-current-playlist-p ()
  97. (should (libmpdel-current-playlist-p 'current-playlist))
  98. (should-not (libmpdel-current-playlist-p (libmpdel--stored-playlist-create :name "The Playlist")))
  99. (should-not (libmpdel-current-playlist-p (libmpdel--artist-create :name "The Artist"))))
  100. ;;; Helper functions
  101. (defmacro libmpdel-test--with-connection (&rest body)
  102. "Execute BODY within a new fake MPD connection."
  103. `(let ((libmpdel--msghandlers (list))
  104. (commands (list))
  105. (log (list)))
  106. (cl-letf (((symbol-function 'libmpdel--log)
  107. (lambda (string type-string) (setq log (append log (list (cons string type-string))))))
  108. ((symbol-function 'libmpdel--raw-send-command)
  109. (lambda (command) (setq commands (append commands (list command)))))
  110. ((symbol-function 'libmpdel-connected-p)
  111. (lambda () t)))
  112. ,@body)))
  113. (ert-deftest libmpdel-test--raw-send-command-with-handler-with-a-string ()
  114. (libmpdel-test--with-connection
  115. (libmpdel--raw-send-command-with-handler "command")
  116. (should (equal "command" (car commands)))))
  117. (ert-deftest libmpdel-test--raw-send-command-with-handler-with-a-list ()
  118. (libmpdel-test--with-connection
  119. (libmpdel--raw-send-command-with-handler '("%s foo %S" "a" "b"))
  120. (should (equal "a foo \"b\"" (car commands)))))
  121. (ert-deftest libmpdel-test--raw-send-command-with-handler-update-handlers ()
  122. (libmpdel-test--with-connection
  123. (ert-with-test-buffer ()
  124. (libmpdel--raw-send-command-with-handler "command" 'foo)
  125. (let ((handler (car libmpdel--msghandlers)))
  126. (should (equal (cl-first handler) "command"))
  127. (should (eql 'foo (cl-second handler)))
  128. (should (eql (current-buffer) (cl-third handler)))))))
  129. (ert-deftest libmpdel-test--raw-send-command-with-handler-add-ignore-handler ()
  130. (libmpdel-test--with-connection
  131. (libmpdel--raw-send-command-with-handler "command")
  132. (let ((handler (car libmpdel--msghandlers)))
  133. (should (eql #'libmpdel--msghandler-ignore (cl-second handler))))))
  134. (ert-deftest libmpdel-test--message-filter-activates-saved-buffer ()
  135. (let* ((expected-buffer nil)
  136. (actual-buffer nil)
  137. (handler (lambda (_) (setq actual-buffer (current-buffer)))))
  138. (libmpdel-test--with-connection
  139. (ert-with-test-buffer ()
  140. (setq expected-buffer (current-buffer))
  141. (libmpdel--raw-send-command-with-handler "foo" handler)
  142. (ert-with-test-buffer ()
  143. (libmpdel--message-filter nil "OK\n")
  144. (should (bufferp actual-buffer))
  145. (should (equal expected-buffer actual-buffer)))))))
  146. (ert-deftest libmpdel-test--message-filter-keeps-current-buffer-if-saved-one-died ()
  147. (let* ((dead-buffer nil)
  148. (actual-buffer nil)
  149. (handler (lambda (_) (setq actual-buffer (current-buffer)))))
  150. (libmpdel-test--with-connection
  151. (ert-with-test-buffer ()
  152. (setq dead-buffer (current-buffer))
  153. (libmpdel--raw-send-command-with-handler "foo" handler))
  154. (ert-with-test-buffer ()
  155. (libmpdel--message-filter nil "OK\n")
  156. (should (bufferp actual-buffer))
  157. (should-not (equal dead-buffer actual-buffer))
  158. (should (equal (current-buffer) actual-buffer))))))
  159. (ert-deftest libmpdel-test--msghandler-status-updates-volume ()
  160. (libmpdel-test--with-connection
  161. (libmpdel--msghandler-status '((volume . "42")))
  162. (should (equal (libmpdel-volume) "42"))))
  163. (ert-deftest libmpdel-test-extract-data ()
  164. (should (equal '()
  165. (libmpdel--extract-data "OK\n")))
  166. (should (equal '((changed . "playlist"))
  167. (libmpdel--extract-data "changed: playlist\nOK\n")))
  168. (should (equal '((changed . "player") (changed . "mixer"))
  169. (libmpdel--extract-data "changed: player\nchanged: mixer\nOK\n")))
  170. (should (equal '((volume . "100") (repeat . "0"))
  171. (libmpdel--extract-data "volume: 100\nrepeat: 0\nOK\n"))))
  172. (ert-deftest libmpdel-test-string<-ignore-case ()
  173. (should (libmpdel--string<-ignore-case "a" "b"))
  174. (should (libmpdel--string<-ignore-case "a" "B"))
  175. (should (libmpdel--string<-ignore-case "A" "b"))
  176. (should-not (libmpdel--string<-ignore-case "b" "a"))
  177. (should-not (libmpdel--string<-ignore-case "B" "a"))
  178. (should-not (libmpdel--string<-ignore-case "b" "A")))
  179. (ert-deftest libmpdel-test-time-to-string ()
  180. (should (string= (libmpdel-time-to-string nil) "0"))
  181. (should (string= (libmpdel-time-to-string "2.230") "00:02"))
  182. (should (string= (libmpdel-time-to-string "84.450") "01:24"))
  183. (should (string= (libmpdel-time-to-string "3623.23") "60:23")))
  184. (ert-deftest libmpdel-test-getting-and-setting-play-state ()
  185. (libmpdel--set-play-state "play")
  186. (should (equal (libmpdel-play-state) 'play)))
  187. (ert-deftest libmpdel-test-setting-play-state-run-hook ()
  188. (let* ((fn-executed 0)
  189. (fn (lambda () (cl-incf fn-executed))))
  190. (add-hook 'libmpdel-player-changed-hook fn)
  191. (setq libmpdel--play-state nil)
  192. (libmpdel--set-play-state "play")
  193. (libmpdel--set-play-state "pause")
  194. (should (equal fn-executed 2))))
  195. (ert-deftest libmpdel-test-setting-play-state-run-hook-only-once ()
  196. (let* ((fn-executed 0)
  197. (fn (lambda () (cl-incf fn-executed))))
  198. (setq libmpdel-player-changed-hook nil)
  199. (add-hook 'libmpdel-player-changed-hook fn)
  200. (setq libmpdel--play-state nil)
  201. (libmpdel--set-play-state "play")
  202. (libmpdel--set-play-state "play")
  203. (should (equal fn-executed 1))))
  204. (ert-deftest libmpdel-test-getting-and-setting-volume ()
  205. (libmpdel--set-volume "50")
  206. (should (string= (libmpdel-volume) "50")))
  207. (ert-deftest libmpdel-test-playlist-add-sends-addid ()
  208. (let ((gmusic-album
  209. (libmpdel--create-song-from-data
  210. '((Title . "Album: The Belly Of An Architect (Edicion 2007)")
  211. (file . "gmusic:album:Bbtjr2k5632pgyabagduxcg3p4q")
  212. (Album . "The Belly Of An Architect (Edicion 2007)")
  213. (AlbumArtist . "Wim Mertens")
  214. (Artist . "Wim Mertens")
  215. (Date . "1983")
  216. (X-AlbumUri "gmusic:album:Bbtjr2k5632pgyabagduxcg3p4q")))))
  217. (libmpdel-test--with-connection
  218. (libmpdel-playlist-add gmusic-album 'current-playlist)
  219. (should (equal '("addid \"gmusic:album:Bbtjr2k5632pgyabagduxcg3p4q\"")
  220. (last commands))))))
  221. (ert-deftest libmpdel-test-playlist-add-no-string-id-sends-findadd ()
  222. (let* ((artist (libmpdel--artist-create :name "The Artist"))
  223. (album (libmpdel--album-create :name "The Album" :artist artist)))
  224. (libmpdel-test--with-connection
  225. (libmpdel-playlist-add album 'current-playlist)
  226. (should (equal '("findadd artist \"The Artist\" album \"The Album\"")
  227. (last commands))))))
  228. (ert-deftest libmpdel-test-playlist-add-sends-findadd ()
  229. (let ((song (libmpdel--create-song-from-data
  230. '((Title . "S")
  231. (Album . "A")
  232. (Artist . "Art")))))
  233. (libmpdel-test--with-connection
  234. (libmpdel-playlist-add song 'current-playlist)
  235. (should (equal '("findadd artist \"Art\" album \"A\" title \"S\"")
  236. (last commands))))))
  237. ;;; Public functions
  238. (ert-deftest libmpdel-test-entries ()
  239. (should (equal '("A" "B")
  240. (libmpdel-entries '((Album . "A") (Album . "B")) 'Album)))
  241. (should (equal '("B" "A")
  242. (libmpdel-entries '((Album . "B") (Album . "A")) 'Album)))
  243. (should (equal '("A" "B")
  244. (libmpdel-entries '((Album . "A") (Foo . "Bar") (Album . "B")) 'Album)))
  245. (should (equal '("Bar")
  246. (libmpdel-entries '((Album . "A") (Foo . "Bar") (Album . "B")) 'Foo))))
  247. (ert-deftest libmpdel-test-sorted-entries ()
  248. (should (equal '("A" "B")
  249. (libmpdel-sorted-entries '((Album . "A") (Album . "B")) 'Album)))
  250. (should (equal '("A" "B")
  251. (libmpdel-sorted-entries '((Album . "B") (Album . "A")) 'Album)))
  252. (should (equal '("A" "B")
  253. (libmpdel-sorted-entries '((Album . "A") (Foo . "Bar") (Album . "B")) 'Album)))
  254. (should (equal '("Bar")
  255. (libmpdel-sorted-entries '((Album . "A") (Foo . "Bar") (Album . "B")) 'Foo))))
  256. (ert-deftest libmpdel-test-group-data ()
  257. (should (equal '(((Album . "1 Album") (Title . "1 Title"))
  258. ((Album . "2 Album") (Title . "2 Title")))
  259. (libmpdel-group-data '((Album . "1 Album")
  260. (Title . "1 Title")
  261. (Album . "2 Album")
  262. (Title . "2 Title"))))))
  263. (ert-deftest libmpdel-test-group-data-of-nil-is-nil ()
  264. (should (null (libmpdel-group-data nil))))
  265. (ert-deftest libmpdel-test-equal ()
  266. (let* ((artist1 (libmpdel--artist-create :name "artist1"))
  267. (artist1-bis (libmpdel--artist-create :name "artist1"))
  268. (artist2 (libmpdel--artist-create :name "artist2"))
  269. (album1 (libmpdel--album-create :name "album1" :artist artist1))
  270. (album1-bis (libmpdel--album-create :name "album1" :artist artist1))
  271. (album2 (libmpdel--album-create :name "album2" :artist artist1))
  272. (song1 (libmpdel--song-create
  273. :name "name"
  274. :file "file"
  275. :track "3"
  276. :album album1
  277. :id "1"
  278. :pos "1"))
  279. (song1-bis (libmpdel--song-create
  280. :name "name"
  281. :file "file"
  282. :track "3"
  283. :album album1-bis
  284. :id "2" ;; change id and pos
  285. :pos "2"))
  286. (song2 (libmpdel--song-create
  287. :name "name2"
  288. :file "file2"
  289. :track "3"
  290. :album album2
  291. :id "3"
  292. :pos "3")))
  293. (should (libmpdel-equal artist1 artist1))
  294. (should (libmpdel-equal artist1 artist1-bis))
  295. (should (libmpdel-equal artist1-bis artist1))
  296. (should (not (libmpdel-equal artist1 artist2)))
  297. (should (not (libmpdel-equal artist2 artist1)))
  298. (should (libmpdel-equal album1 album1))
  299. (should (libmpdel-equal album1 album1-bis))
  300. (should (libmpdel-equal album1-bis album1))
  301. (should (not (libmpdel-equal album1 album2)))
  302. (should (not (libmpdel-equal album2 album1)))
  303. (should (libmpdel-equal song1 song1))
  304. (should (libmpdel-equal song1 song1-bis))
  305. (should (libmpdel-equal song1-bis song1))
  306. (should (not (libmpdel-equal song1 song2)))
  307. (should (not (libmpdel-equal song2 song1)))))
  308. (ert-deftest libmpdel-test-playlist-add-artist-to-stored-playlist ()
  309. (libmpdel-test--with-connection
  310. (let ((artist (libmpdel--artist-create :name "The Artist"))
  311. (playlist (libmpdel--stored-playlist-create :name "the playlist")))
  312. (libmpdel-playlist-add artist playlist)
  313. (should (equal (car (last commands))
  314. "searchaddpl \"the playlist\" artist \"The Artist\"")))))
  315. (provide 'libmpdel-test)
  316. ;;; libmpdel-test.el ends here
  317. ;; Local Variables:
  318. ;; nameless-current-name: "libmpdel-test"
  319. ;; End: