1# This program is free software; you can redistribute it and/or modify
2# it under the terms of the GNU General Public License as published by
3# the Free Software Foundation; either version 2 of the License, or
4# (at your option) any later version.
5
6from collections import defaultdict
7
8from quodlibet.formats import AudioFile
9from quodlibet.order import OrderInOrder
10from quodlibet.order.reorder import OrderWeighted, OrderShuffle
11from quodlibet.order.repeat import OneSong
12from quodlibet.qltk.songmodel import PlaylistModel
13from tests import TestCase
14
15r0 = AudioFile({'~#rating': 0})
16r1 = AudioFile({'~#rating': 0.33})
17r2 = AudioFile({'~#rating': 0.66})
18r3 = AudioFile({'~#rating': 1.0})
19
20
21class TOrderWeighted(TestCase):
22
23    def test_weighted(self):
24        pl = PlaylistModel()
25        pl.set([r3, r1, r2, r0])
26        order = OrderWeighted()
27        scores = defaultdict(int)
28        for i in range(500):
29            order.reset(pl)
30            cur = pl.current_iter
31            for j in range(3, -1, -1):
32                cur = order.next_explicit(pl, cur)
33                scores[pl[cur][0]] += j
34        self.failUnless(scores[r1] > scores[r0])
35        self.failUnless(scores[r2] > scores[r1])
36        self.failUnless(scores[r3] > scores[r2])
37
38
39class TOrderShuffle(TestCase):
40
41    def test_remaining(self):
42        order = OrderShuffle()
43        pl = PlaylistModel()
44        songs = [r3, r1, r2, r0]
45        pl.set(songs)
46        cur = pl.current_iter
47        for i in range(4, 0, -1):
48            cur = order.next_explicit(pl, cur)
49            self.failUnlessEqual(len(order.remaining(pl)), i)
50        # The playlist should reset after the last song
51        cur = order.next_explicit(pl, cur)
52        self.failUnlessEqual(len(order.remaining(pl)), len(songs))
53
54
55class TOrderOneSong(TestCase):
56
57    def test_remaining(self):
58        order = OneSong(OrderInOrder())
59        pl = PlaylistModel(OrderInOrder)
60        pl.set([r0, r1])
61        for i in range(2):
62            self.failUnlessEqual(order.next(pl, pl.current_iter), None)
63