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 tests import TestCase
7
8from gi.repository import Gtk
9from senf import fsnative
10
11import quodlibet.browsers.search
12import quodlibet.config
13
14from quodlibet.browsers.search import SearchBar
15from quodlibet.formats import AudioFile
16from quodlibet.library import SongLibrary, SongLibrarian
17from quodlibet.qltk.songlist import SongList
18
19# Don't sort yet, album_key makes it complicated...
20SONGS = [AudioFile({
21                "title": "one",
22                "artist": "piman",
23                "~filename": fsnative(u"/dev/null")}),
24         AudioFile({
25                "title": "two",
26                "artist": "mu",
27                "~#length": 234,
28                "~filename": fsnative(u"/dev/zero")}),
29         AudioFile({
30                "title": "three",
31                "artist": "boris",
32                "~filename": fsnative(u"/bin/ls")}),
33         AudioFile({
34                "title": "four",
35                "artist": "random",
36                "album": "don't stop",
37                "labelid": "65432-1",
38                "~filename": fsnative(u"/dev/random")}),
39         AudioFile({
40                "title": "five € and a £",
41                "artist": "shell",
42                "album": "don't stop",
43                "labelid": "12345-6",
44                "~filename": fsnative(u"/tmp/five € and £!")})]
45
46
47class TSearchBar(TestCase):
48    Bar = SearchBar
49
50    def setUp(self):
51        quodlibet.config.init()
52        quodlibet.browsers.search.library = SongLibrary()
53        quodlibet.browsers.search.library.librarian = SongLibrarian()
54        for af in SONGS:
55            af.sanitize()
56        quodlibet.browsers.search.library.add(SONGS)
57        self.bar = self.Bar(quodlibet.browsers.search.library)
58        self.bar.connect('songs-selected', self._expected)
59        self.success = False
60
61    def _expected(self, bar, songs, sort):
62        songs.sort()
63        self.failUnlessEqual(self.expected, songs)
64        self.success = True
65
66    def _do(self):
67        while Gtk.events_pending():
68            Gtk.main_iteration()
69        self.failUnless(self.success or self.expected is None)
70
71    def test_can_filter(self):
72        for key in ["foo", "title", "fake~key", "~woobar", "~#huh"]:
73            self.failUnless(self.bar.can_filter(key))
74
75    def test_empty_is_all(self):
76        self.bar.filter_text("")
77        self.expected = list(sorted(SONGS))
78        self._do()
79
80    def test_active_filter(self):
81        self.assertTrue(self.bar.active_filter(SONGS[0]))
82        self.bar.filter_text("this does not match any song")
83        self.expected = []
84        self.assertFalse(self.bar.active_filter(SONGS[0]))
85        self._do()
86
87    def test_filter(self):
88        self.expected = [SONGS[1]]
89        self.bar.filter("title", ["two"])
90        self._do()
91
92    def test_filter_again(self):
93        self.expected = sorted(SONGS[3:5])
94        self.bar.filter("album", ["don't stop"])
95        self._do()
96
97    def test_filter_notvalue(self):
98        self.expected = sorted(SONGS[0:2])
99        self.bar.filter("artist", ["notvalue", "mu", "piman"])
100        self._do()
101
102    def test_filter_none(self):
103        self.expected = []
104        self.bar.filter("title", ["not a value"])
105        self._do()
106
107    def test_filter_album_by_labelid(self):
108        self.expected = [SONGS[3]]
109        self.bar.filter("labelid", [("65432-1")])
110        self._do()
111
112    def test_filter_numeric(self):
113        self.expected = sorted([SONGS[0]] + SONGS[2:])
114        self.bar.filter("~#length", [0])
115        self._do()
116
117    def test_search_text_artist(self):
118        self.bar._set_text("boris")
119        self.expected = [SONGS[2]]
120        self.bar._sb_box.changed()
121        self._do()
122
123    def test_search_text_custom_star(self):
124        old = SongList.star
125        SongList.star = ["artist", "labelid"]
126        self.bar._set_text("65432-1")
127        self.expected = [SONGS[3]]
128        self.bar._sb_box.changed()
129        try:
130            self._do()
131        finally:
132            SongList.star = old
133
134    def test_saverestore(self):
135        self.bar.filter_text("title = %s" % SONGS[0]["title"])
136        self.expected = [SONGS[0]]
137        self._do()
138        self.bar.save()
139        self.bar.filter_text("")
140        self.expected = list(sorted(SONGS))
141        self._do()
142        self.bar.restore()
143        self.bar.activate()
144        self.expected = [SONGS[0]]
145        self._do()
146
147    def tearDown(self):
148        self.bar.destroy()
149        quodlibet.browsers.search.library.destroy()
150        quodlibet.config.quit()
151