1
0
Fork 0
mirror of https://github.com/heyarne/airsonic-ui.git synced 2026-05-07 10:43:39 +02:00

Implement all the playlist skipping functionality

This commit is contained in:
Arne Schlüter 2018-08-20 10:50:03 +02:00
commit 27ac6f9478
4 changed files with 185 additions and 65 deletions

View file

@ -1,26 +1,27 @@
(ns airsonic-ui.audio.playlist-test
(:require [cljs.test :refer [deftest testing is]]
[airsonic-ui.audio.playlist :as playlist]
[airsonic-ui.utils.helpers :refer [find-where]]
[airsonic-ui.fixtures :as fixtures]
[airsonic-ui.test-helpers :as helpers]
[debux.cs.core :refer-macros [dbg]]))
(enable-console-print!)
(defn- playing-queue
(defn- song-queue
"Generates a seq of n different songs"
[n]
(repeatedly n #(hash-map :id (rand-int 9999)
:coverArt (rand-int 9999)
:year (+ 1900 (rand-int 118))
:artist (helpers/rand-str)
:aristId (rand-int 100000)
:artistId (rand-int 100000)
:title (helpers/rand-str)
:album (helpers/rand-str))))
(def fixture
{:audio {:current-song fixtures/song
:playlist (playing-queue 20)
:playlist (song-queue 20)
:playback-status fixtures/playback-status}})
(defn- same-song? [a b] (= (:id a) (:id b)))
@ -28,7 +29,7 @@
(deftest playlist-creation
(testing "Playlist creation"
(testing "should give us the correct current song"
(let [queue (playing-queue 10)
(let [queue (song-queue 10)
start-idx (rand-int 10)]
(doseq [playback-mode [:playback-mode/linear, :playback-mode/shuffled]
repeat-mode [:repeat-mode/none, :repeat-mode/single, :repeat-mode/all]]
@ -37,7 +38,7 @@
(playlist/peek)))
(str playback-mode ", " repeat-mode)))))
(testing "should give us a playlist with the correct number of tracks"
(let [queue (playing-queue 100)
(let [queue (song-queue 100)
start-idx (rand-int 100)]
(doseq [playback-mode [:playback-mode/linear, :playback-mode/shuffled]
repeat-mode [:repeat-mode/none, :repeat-mode/single, :repeat-mode/all]]
@ -48,7 +49,7 @@
(deftest changing-playback-mode
(testing "Changing playback mode"
(testing "from linear to shuffled"
(let [queue (playing-queue 10)
(let [queue (song-queue 10)
start-idx (rand-int 10)
linear (playlist/->playlist queue start-idx :playback-mode/linear :repeat-mode/node)
shuffled (playlist/set-playback-mode linear :playback-mode/shuffled)]
@ -59,7 +60,7 @@
(testing "should not change the repeat mode"
(is (= (:repeat-mode shuffled) (:repeat-mode linear)))))
(testing "from shuffled to linear"
(let [queue (playing-queue 10)
(let [queue (song-queue 10)
start-idx (rand-int 10)
shuffled (playlist/->playlist queue start-idx
:playback-mode/shuffled :repeat-mode/none)
@ -85,7 +86,7 @@
(doseq [playback-mode [:playback-mode/linear, :playback-mode/shuffled]
repeat-mode [:repeat-mode/none, :repeat-mode/single, :repeat-mode/all]
next-repeat-mode [:repeat-mode/none, :repeat-mode/single, :repeat-mode/all]]
(let [playlist (-> (playlist/->playlist (playing-queue 1) 0
(let [playlist (-> (playlist/->playlist (song-queue 1) 0
playback-mode repeat-mode)
(playlist/set-repeat-mode next-repeat-mode))]
(is (= playback-mode (:playback-mode playlist)))
@ -95,7 +96,7 @@
(deftest linear-next-song
(testing "Should follow the same order as the queue used for creation"
(doseq [repeat-mode [:repeat-mode/none :repeat-mode/all]]
(let [queue (playing-queue 5)
(let [queue (song-queue 5)
playlist (playlist/->playlist queue 0 :playback-mode/linear repeat-mode)]
(is (same-song? (nth queue 1) (-> (playlist/next-song playlist)
(playlist/peek)))
@ -106,7 +107,7 @@
(str repeat-mode ", skipped twice")))))
(testing "Should go back to the first song when repeat-mode is all and we played the last song")
(testing "Should always give the same track when repeat-mode is single"
(let [queue (playing-queue 3)
(let [queue (song-queue 3)
playing-idx (rand-int 3)
playlist (playlist/->playlist queue playing-idx
:playback-mode/linear :repeat-mode/single)
@ -116,30 +117,31 @@
(is (same-song? (nth queue playing-idx) (nth played-back 2)))
(is (same-song? (nth queue playing-idx) (nth played-back 3)) "wrapping around")))
(testing "Should stop playing at the end of the queue when repeat-mode is none"
(is (nil? (-> (playing-queue 1)
(is (nil? (-> (song-queue 1)
(playlist/->playlist 0 :playback-mode/linear :repeat-mode/none)
(playlist/next-song)
(playlist/peek))))))
(deftest shuffled-next-song
(testing "Should play every track once when called for the entire queue"
(doseq [repeat-mode '(:repeat-mode/none :repeat-mode/all)]
(let [length 10
playlist (playlist/->playlist (playing-queue length) 0
:playback-mode/shuffled repeat-mode)
played-tracks (->> (iterate playlist/next-song playlist)
(map playlist/peek)
(take length))]
(is (= (count played-tracks) (count (set played-tracks)))
(str repeat-mode)))))
(with-redefs [shuffle reverse]
(doseq [repeat-mode '(:repeat-mode/none :repeat-mode/all)]
(let [length 10
playlist (playlist/->playlist (song-queue length) 9
:playback-mode/shuffled repeat-mode)
played-tracks (->> (iterate playlist/next-song playlist)
(map playlist/peek)
(take length))]
(is (= (count played-tracks) (count (set played-tracks)))
(str repeat-mode))))))
(testing "Should re-shuffle the playlist when wrapping around and repeat-mode is all"
(let [length 100
playlist (playlist/->playlist (playing-queue length) (dec length)
:playback-mode/shuffled :repeat-mode/all)]
(let [playlist (playlist/->playlist (song-queue 100) 0 :playback-mode/shuffled :repeat-mode/all)
[last-idx _] (find-where #(= (:order %) 99) (:queue playlist))]
(is (not= (map :order (:queue playlist))
(map :order (:queue (playlist/next-song playlist)))))))
(map :order (:queue (-> (playlist/set-current-song playlist last-idx)
(playlist/next-song))))))))
(testing "Should always give the same track when repeat-mode is single"
(let [queue (playing-queue 3)
(let [queue (song-queue 3)
playing-idx (rand-int 3)
playlist (playlist/->playlist queue playing-idx
:playback-mode/shuffled :repeat-mode/single)
@ -149,10 +151,85 @@
(is (same-song? (nth queue playing-idx) (nth played-back 2)))
(is (same-song? (nth queue playing-idx) (nth played-back 3)) "wrapping around")))
(testing "Should stop playing at the end of the queue when repeat-mode is none"
(is (nil? (-> (playing-queue 1)
(is (nil? (-> (song-queue 1)
(playlist/->playlist 0 :playback-mode/linear :repeat-mode/none)
(playlist/next-song)
(playlist/peek))))))
#_(deftest linear-previous-song)
#_(deftest shuffled-previous-song)
(deftest linear-previous-song
(testing "Should always give the same track when repeat-mode is single"
(let [queue (song-queue 3)
playing-idx (rand-int 3)
playlist (playlist/->playlist queue playing-idx
:playback-mode/linear :repeat-mode/single)
played-back (map playlist/peek (iterate playlist/next-song playlist))]
(is (same-song? (nth queue playing-idx) (nth played-back 0)))
(is (same-song? (nth queue playing-idx) (nth played-back 1)))
(is (same-song? (nth queue playing-idx) (nth played-back 2)))
(is (same-song? (nth queue playing-idx) (nth played-back 3)) "wrapping around")))
(testing "Should keep the linear order when repeat-mode is not single"
(doseq [repeat-mode '(:repeat-mode/none :repeat-mode/all)]
(let [queue (song-queue 3)
playlist (playlist/->playlist queue 0 :playback-mode/linear repeat-mode)]
(is (same-song? (nth queue 1) (-> (playlist/next-song playlist)
(playlist/next-song)
(playlist/previous-song)
(playlist/peek)))))))
(testing "Should repeatedly give the first song when repeat-mode is none"
(let [queue (song-queue 3)
playlist (playlist/->playlist queue 0 :playback-mode/linear :repeat-mode/none)]
(is (same-song? (first queue) (-> (playlist/previous-song playlist)
(playlist/peek))))))
(testing "Should wrap around to last song when repeat-mode is all"
(let [queue (song-queue 3)
playlist (playlist/->playlist queue 0 :playback-mode/linear :repeat-mode/all)]
(is (same-song? (last queue) (-> (playlist/previous-song playlist)
(playlist/peek)))))))
(deftest shuffled-previous-song
(with-redefs [shuffle reverse]
(testing "Should always give the same track when repeat-mode is single"
(let [queue (song-queue 3)
playing-idx (rand-int 3)
playlist (playlist/->playlist queue playing-idx
:playback-mode/shuffled :repeat-mode/single)
played-back (map playlist/peek (iterate playlist/next-song playlist))]
(is (same-song? (nth queue playing-idx) (nth played-back 0)))
(is (same-song? (nth queue playing-idx) (nth played-back 1)))
(is (same-song? (nth queue playing-idx) (nth played-back 2)))
(is (same-song? (nth queue playing-idx) (nth played-back 3)) "wrapping around")))
(testing "Should keep the playing order when repeat-mode is not single"
(doseq [repeat-mode '(:repeat-mode/none :repeat-mode/all)]
(let [queue (song-queue 3)
playlist' (playlist/->playlist queue 0 :playback-mode/shuffled repeat-mode)
[first-idx _] (find-where #(= (:order %) 0) (:queue playlist'))
playlist (playlist/set-current-song playlist' first-idx)]
(is (same-song? (playlist/peek playlist)
(-> playlist
(playlist/next-song)
(playlist/previous-song)
(playlist/peek)))
(str "for repeat mode " repeat-mode))
(is (same-song? (-> (playlist/next-song playlist)
(playlist/peek))
(-> (playlist/next-song playlist)
(playlist/next-song)
(playlist/previous-song)
(playlist/peek)))
(str "for repeat mode " repeat-mode)))))
(testing "Should re-shuffle when repeat-mode is all and we pass the start"
(with-redefs [shuffle identity]
(let [playlist (playlist/->playlist (song-queue 2) 0 :playback-mode/shuffled :repeat-mode/all)
playlist' (with-redefs [shuffle reverse]
(playlist/previous-song playlist))]
(is (not= (map :order (:queue playlist)) (map :order (:queue playlist')))))))))
(deftest set-current-song
(testing "Should correctly set the new song"
(let [queue (song-queue 3)
playlist (playlist/->playlist queue 0 :playback-mode/shuffled :repeat-mode/single)
current-track (first queue)
next-track (-> (playlist/set-current-song playlist 1)
(playlist/peek))]
(is (not (nil? next-track)))
(is (not (same-song? current-track next-track))))))

View file

@ -0,0 +1,14 @@
(ns airsonic-ui.utils.helpers-test
(:require [cljs.test :refer [deftest testing is]]
[airsonic-ui.utils.helpers :as helpers]))
(deftest find-where
(testing "Finds the correct item and index"
(is (= [0 1] (helpers/find-where (partial = 1) (range 1 10))))
(is (= [2 {:foo true, :bar false}] (helpers/find-where :foo '({}
{:foo false
:bar true}
{:foo true
:bar false})))))
(testing "Returns nil when nothing is found"
(is (nil? (helpers/find-where (partial = 2) (range 2))))))