1 /****************************************************************************************
2 * Copyright (c) 2010 Nikolaj Hald Nielsen <nhn@kde.com> *
3 * *
4 * This program is free software; you can redistribute it and/or modify it under *
5 * the terms of the GNU General Public License as published by the Free Software *
6 * Foundation; either version 2 of the License, or (at your option) any later *
7 * version. *
8 * *
9 * This program is distributed in the hope that it will be useful, but WITHOUT ANY *
10 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A *
11 * PARTICULAR PURPOSE. See the GNU General Pulic License for more details. *
12 * *
13 * You should have received a copy of the GNU General Public License along with *
14 * this program. If not, see <http://www.gnu.org/licenses/>. *
15 ****************************************************************************************/
16
17 #include "TestPlaylistModels.h"
18
19 #include "amarokconfig.h"
20 #include "core/support/Components.h"
21 #include "EngineController.h"
22
23 #include "playlist/PlaylistActions.h"
24 #include "playlist/PlaylistController.h"
25 #include "playlist/PlaylistModelStack.h"
26 #include "playlist/PlaylistModel.h"
27 #include "playlist/UndoCommands.h"
28
29 #include "mocks/MetaMock.h"
30 #include "mocks/MockTrack.h"
31
32 #include <QtDebug>
33 #include <QTest>
34
35
36 using namespace Playlist;
37
QTEST_GUILESS_MAIN(TestPlaylistModels)38 QTEST_GUILESS_MAIN( TestPlaylistModels )
39
40
41 TestPlaylistModels::TestPlaylistModels()
42 : QObject()
43 {
44 }
45
initTestCase()46 void TestPlaylistModels::initTestCase()
47 {
48 AmarokConfig::instance("amarokrc");
49
50 //apparently the engine controller is needed somewhere, or we will get a crash...
51 EngineController *controller = new EngineController();
52 Amarok::Components::setEngineController( controller );
53
54 // Initialize playlistAction before we set the playlist, lest our playlist be overwritten with Art Of Nations
55 The::playlistActions();
56 The::playlistController()->removeRow( 0 );
57
58 //we want to add a few tracks to the playlist so we can test sorting, filtering and so on. So first create a bunch of dummy tracks we can use.
59
60 Meta::TrackList tracks;
61
62 QVariantMap map1;
63 map1.insert( Meta::Field::TITLE, QString( "Cool as honey" ) );
64 MetaMock * metaMock = new MetaMock( map1 );
65 metaMock->m_artist = new MockArtist( "Bonzai Bees" );
66 metaMock->m_album = new MockAlbum( "The Hive", metaMock->m_artist );
67 tracks << Meta::TrackPtr( metaMock );
68
69 QVariantMap map2;
70 map2.insert( Meta::Field::TITLE, QString( "xTreme buzzing sound" ) );
71 metaMock = new MetaMock( map2 );
72 metaMock->m_artist = new MockArtist( "Bonzai Bees" );
73 metaMock->m_album = new MockAlbum( "The Hive", metaMock->m_artist );
74 tracks << Meta::TrackPtr( metaMock );
75
76 QVariantMap map3;
77 map3.insert( Meta::Field::TITLE, QString( "Alphabet soup" ) );
78 metaMock = new MetaMock( map3 );
79 metaMock->m_artist = new MockArtist( "Grumpy Grizzlies" );
80 metaMock->m_album = new MockAlbum( "The Hive", metaMock->m_artist );
81 tracks << Meta::TrackPtr( metaMock );
82
83 QVariantMap map4;
84 map4.insert( Meta::Field::TITLE, QString( "Zlick" ) );
85 metaMock = new MetaMock( map4 );
86 metaMock->m_artist = new MockArtist( "Grumpy Grizzlies" );
87 metaMock->m_album = new MockAlbum( "Nice Long Nap", metaMock->m_artist );
88 tracks << Meta::TrackPtr( metaMock );
89
90 QVariantMap map5;
91 map5.insert( Meta::Field::TITLE, QString( "23 hours is not enough" ) );
92 metaMock = new MetaMock( map5 );
93 metaMock->m_artist = new MockArtist( "Grumpy Grizzlies" );
94 metaMock->m_album = new MockAlbum( "Nice Long Nap", metaMock->m_artist );
95 tracks << Meta::TrackPtr( metaMock );
96
97 QVariantMap map6;
98 map6.insert( Meta::Field::TITLE, QString( "1 song to rule them all" ) );
99 metaMock = new MetaMock( map6 );
100 metaMock->m_artist = new MockArtist( "Bonzai Bees" );
101 metaMock->m_album = new MockAlbum( "Pretty Flowers", metaMock->m_artist );
102 tracks << Meta::TrackPtr( metaMock );
103
104 QVariantMap map7;
105 map7.insert( Meta::Field::TITLE, QString( "zz ambience sound" ) );
106 metaMock = new MetaMock( map7 );
107 // note: no artist, no album!
108 tracks << Meta::TrackPtr( metaMock );
109
110 The::playlistController()->insertTracks( 0, tracks );
111
112 QCOMPARE( The::playlist()->trackAt( 3 )->prettyName(), QString( "Zlick" ) );
113 }
114
cleanup()115 void TestPlaylistModels::cleanup()
116 {
117 SortScheme scheme = SortScheme();
118 ModelStack::instance()->sortProxy()->updateSortMap( scheme );
119 ModelStack::instance()->filterProxy()->clearSearchTerm();
120 }
121
testSorting()122 void TestPlaylistModels::testSorting()
123 {
124 //simple sort by title
125 //******************************//
126
127 SortScheme scheme = SortScheme();
128 scheme.addLevel( SortLevel( Playlist::Title, Qt::AscendingOrder ) );
129 ModelStack::instance()->sortProxy()->updateSortMap( scheme );
130
131 AbstractModel * topModel = The::playlist();
132
133 QCOMPARE( topModel->trackAt( 0 )->prettyName(), QString( "1 song to rule them all" ) );
134 QCOMPARE( topModel->trackAt( 1 )->prettyName(), QString( "23 hours is not enough" ) );
135 QCOMPARE( topModel->trackAt( 2 )->prettyName(), QString( "Alphabet soup" ) );
136 QCOMPARE( topModel->trackAt( 3 )->prettyName(), QString( "Cool as honey" ) );
137 QCOMPARE( topModel->trackAt( 4 )->prettyName(), QString( "xTreme buzzing sound" ) );
138 QCOMPARE( topModel->trackAt( 5 )->prettyName(), QString( "Zlick" ) );
139
140
141 //Sort by Artist - Album - Title
142 //******************************//
143
144 SortScheme scheme2 = SortScheme();
145
146 scheme2.addLevel( SortLevel( Playlist::Artist, Qt::AscendingOrder ) );
147 scheme2.addLevel( SortLevel( Playlist::Album, Qt::AscendingOrder ) );
148 scheme2.addLevel( SortLevel( Playlist::Title, Qt::AscendingOrder ) );
149
150 QCOMPARE( scheme2.length(), 3 );
151
152 ModelStack::instance()->sortProxy()->updateSortMap( scheme2 );
153 topModel->qaim()->revert();
154
155 // the one without artist or album comes first
156 QCOMPARE( topModel->trackAt( 0 )->prettyName(), QString( "zz ambience sound" ) );
157 QCOMPARE( topModel->trackAt( 1 )->prettyName(), QString( "1 song to rule them all" ) );
158 QCOMPARE( topModel->trackAt( 2 )->prettyName(), QString( "Cool as honey" ) );
159 QCOMPARE( topModel->trackAt( 3 )->prettyName(), QString( "xTreme buzzing sound" ) );
160 QCOMPARE( topModel->trackAt( 4 )->prettyName(), QString( "23 hours is not enough" ) );
161 QCOMPARE( topModel->trackAt( 5 )->prettyName(), QString( "Zlick" ) );
162 QCOMPARE( topModel->trackAt( 6 )->prettyName(), QString( "Alphabet soup" ) );
163
164 //reverse some stuff
165 //******************************//
166
167 SortScheme scheme3 = SortScheme();
168
169 scheme3.addLevel( SortLevel( Playlist::Artist, Qt::AscendingOrder ) );
170 scheme3.addLevel( SortLevel( Playlist::Album, Qt::DescendingOrder ) );
171 scheme3.addLevel( SortLevel( Playlist::Title, Qt::AscendingOrder ) );
172
173 ModelStack::instance()->sortProxy()->updateSortMap( scheme3 );
174 topModel->qaim()->revert();
175
176 QCOMPARE( topModel->trackAt( 0 )->prettyName(), QString( "zz ambience sound" ) );
177 QCOMPARE( topModel->trackAt( 1 )->prettyName(), QString( "Cool as honey" ) );
178 QCOMPARE( topModel->trackAt( 2 )->prettyName(), QString( "xTreme buzzing sound" ) );
179 QCOMPARE( topModel->trackAt( 3 )->prettyName(), QString( "1 song to rule them all" ) );
180 QCOMPARE( topModel->trackAt( 4 )->prettyName(), QString( "Alphabet soup" ) );
181 QCOMPARE( topModel->trackAt( 5 )->prettyName(), QString( "23 hours is not enough" ) );
182 QCOMPARE( topModel->trackAt( 6 )->prettyName(), QString( "Zlick" ) );
183
184 //Sort by album when tracks have same album name and different artists
185 //******************************//
186
187 SortScheme scheme4 = SortScheme();
188
189 scheme4.addLevel( SortLevel( Playlist::Album, Qt::AscendingOrder ) );
190 scheme4.addLevel( SortLevel( Playlist::Title, Qt::AscendingOrder ) );
191
192 ModelStack::instance()->sortProxy()->updateSortMap( scheme4 );
193 topModel->qaim()->revert();
194
195 QCOMPARE( topModel->trackAt( 0 )->prettyName(), QString( "zz ambience sound" ) );
196 QCOMPARE( topModel->trackAt( 1 )->prettyName(), QString( "23 hours is not enough" ) );
197 QCOMPARE( topModel->trackAt( 2 )->prettyName(), QString( "Zlick" ) );
198 QCOMPARE( topModel->trackAt( 3 )->prettyName(), QString( "1 song to rule them all" ) );
199 QCOMPARE( topModel->trackAt( 4 )->prettyName(), QString( "Cool as honey" ) );
200 QCOMPARE( topModel->trackAt( 5 )->prettyName(), QString( "xTreme buzzing sound" ) );
201 QCOMPARE( topModel->trackAt( 6 )->prettyName(), QString( "Alphabet soup" ) );
202 }
203
testFiltering()204 void TestPlaylistModels::testFiltering()
205 {
206 ModelStack::instance()->filterProxy()->showOnlyMatches( true );
207 ModelStack::instance()->filterProxy()->find( "ou" );
208 ModelStack::instance()->filterProxy()->filterUpdated();
209
210 AbstractModel * topModel = The::playlist();
211
212 QCOMPARE( topModel->qaim()->rowCount(), 4 );
213 QCOMPARE( topModel->trackAt( 0 )->prettyName(), QString( "xTreme buzzing sound" ) );
214 QCOMPARE( topModel->trackAt( 1 )->prettyName(), QString( "Alphabet soup" ) );
215 QCOMPARE( topModel->trackAt( 2 )->prettyName(), QString( "23 hours is not enough" ) );
216 QCOMPARE( topModel->trackAt( 3 )->prettyName(), QString( "zz ambience sound" ) );
217 //TODO: More advanced filtering tests go here
218
219 }
220
testSearching()221 void TestPlaylistModels::testSearching()
222 {
223 }
224
testShuffling()225 void TestPlaylistModels::testShuffling()
226 {
227 Meta::TrackList oldTrackList = The::playlist()->tracks();
228
229 The::playlistActions()->shuffle();
230
231 QVERIFY( oldTrackList != The::playlist()->tracks() );
232
233 The::playlistController()->undo();
234
235 QCOMPARE( oldTrackList, The::playlist()->tracks() );
236 }
237