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