File indexing completed on 2024-05-05 04:49:43

0001 /****************************************************************************************
0002  * Copyright (c) 2011 Ralf Engels <ralf-engels@gmx.de>                                  *
0003  *                                                                                      *
0004  * This program is free software; you can redistribute it and/or modify it under        *
0005  * the terms of the GNU General Public License as published by the Free Software        *
0006  * Foundation; either version 2 of the License, or (at your option) any later           *
0007  * version.                                                                             *
0008  *                                                                                      *
0009  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
0010  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
0011  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
0012  *                                                                                      *
0013  * You should have received a copy of the GNU General Public License along with         *
0014  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
0015  ****************************************************************************************/
0016 
0017 #include "TestDynamicModel.h"
0018 
0019 #include "amarokconfig.h"
0020 #include "dynamic/Bias.h"
0021 #include "dynamic/BiasedPlaylist.h"
0022 #include "dynamic/DynamicModel.h"
0023 
0024 #include "core/support/Amarok.h"
0025 #include "core/support/Debug.h"
0026 
0027 #include <QByteArray>
0028 #include <QDataStream>
0029 #include <QMimeData>
0030 #include <QSignalSpy>
0031 #include <QTemporaryDir>
0032 
0033 
0034 Q_DECLARE_METATYPE(QModelIndex);
0035 
0036 QTemporaryDir *s_tmpDir = nullptr;   // Memory leak here now, but if it's deleted, we have a segfault
0037 
0038 // We return a special saveLocation.
0039 QString Amarok::saveLocation( const QString &directory )
0040 {
0041     return s_tmpDir->path() + directory;
0042 }
0043 
0044 QTEST_GUILESS_MAIN( TestDynamicModel )
0045 
0046 TestDynamicModel::TestDynamicModel()
0047 {
0048     qRegisterMetaType<QModelIndex>();
0049 }
0050 
0051 void
0052 TestDynamicModel::init()
0053 {
0054     AmarokConfig::instance("amarokrc");
0055 
0056     s_tmpDir = new QTemporaryDir();
0057     QVERIFY( s_tmpDir->isValid() );
0058 }
0059 
0060 void
0061 TestDynamicModel::cleanup()
0062 {
0063 }
0064 
0065 void
0066 TestDynamicModel::testData()
0067 {
0068     Dynamic::DynamicModel *model = Dynamic::DynamicModel::instance();
0069 
0070     // load from the empty directory
0071     model->loadPlaylists();
0072 
0073     // now we should have the four default playlists
0074     QModelIndex playlistIndex = model->index( 0, 0 );
0075     QCOMPARE( model->data( playlistIndex ).toString(), QString("Random") );
0076     QCOMPARE( model->data( playlistIndex, Qt::EditRole ).toString(), QString("Random") );
0077     QVERIFY(  model->data( playlistIndex, Dynamic::DynamicModel::PlaylistRole ).isValid() );
0078     QVERIFY( !model->data( playlistIndex, Dynamic::DynamicModel::BiasRole ).isValid() );
0079 
0080     QModelIndex biasIndex = model->index( 0, 0, playlistIndex );
0081     QVERIFY( !model->data( biasIndex ).toString().isEmpty() );
0082     QVERIFY( !model->data( biasIndex, Dynamic::DynamicModel::PlaylistRole ).isValid() );
0083     QVERIFY(  model->data( biasIndex, Dynamic::DynamicModel::BiasRole ).isValid() );
0084 }
0085 
0086 void
0087 TestDynamicModel::testPlaylistIndex()
0088 {
0089     Dynamic::DynamicModel *model = Dynamic::DynamicModel::instance();
0090 
0091     // load from the empty directory
0092     model->loadPlaylists();
0093 
0094     // now we should have the four default playlists
0095     QCOMPARE( model->rowCount(), 4 );
0096     QCOMPARE( model->columnCount(), 1 );
0097 
0098     // -- random playlist with one bias
0099     QModelIndex playlistIndex = model->index( 0, 0 );
0100     QModelIndex biasIndex = model->index( 0, 0, playlistIndex );
0101 
0102     QCOMPARE( model->rowCount( playlistIndex ), 1 );
0103     QCOMPARE( model->rowCount( biasIndex ), 0 );
0104     QCOMPARE( playlistIndex.parent(), QModelIndex() );
0105     QCOMPARE( biasIndex.parent(), playlistIndex );
0106 
0107     // -- albumplay playlist with bias structure
0108     playlistIndex = model->index( 2, 0 );
0109     biasIndex = model->index( 0, 0, playlistIndex );
0110     QModelIndex subBiasIndex = model->index( 1, 0, biasIndex );
0111 
0112     QCOMPARE( model->rowCount( playlistIndex ), 1 );
0113     QCOMPARE( model->rowCount( biasIndex ), 2 );
0114     QCOMPARE( model->rowCount( subBiasIndex ), 0 );
0115     QCOMPARE( playlistIndex.parent(), QModelIndex() );
0116     QCOMPARE( biasIndex.parent(), playlistIndex );
0117     QCOMPARE( subBiasIndex.parent(), biasIndex );
0118 
0119 
0120     // and now the non-model index functions:
0121     model->setActivePlaylist( 2 );
0122     Dynamic::DynamicPlaylist* playlist = model->activePlaylist();
0123     playlistIndex = model->index( model->activePlaylistIndex(), 0 );
0124     QCOMPARE( model->index( playlist ), playlistIndex );
0125 
0126     Dynamic::BiasPtr bias = qobject_cast<Dynamic::BiasedPlaylist*>(playlist)->bias();
0127     biasIndex = model->index( 0, 0, playlistIndex );
0128     QCOMPARE( model->index( bias ), biasIndex );
0129 
0130     Dynamic::BiasPtr subBias = qobject_cast<Dynamic::AndBias*>(bias.data())->biases().at(0);
0131     subBiasIndex = model->index( 0, 0, biasIndex );
0132     QCOMPARE( model->index( subBias ), subBiasIndex );
0133 }
0134 
0135 void
0136 TestDynamicModel::testSlots()
0137 {
0138     Dynamic::DynamicModel *model = Dynamic::DynamicModel::instance();
0139 
0140     // load from the empty directory
0141     model->loadPlaylists();
0142 
0143     QSignalSpy spy1( model, &Dynamic::DynamicModel::rowsAboutToBeRemoved );
0144     QSignalSpy spy2( model, &Dynamic::DynamicModel::rowsRemoved );
0145     QSignalSpy spy3( model, &Dynamic::DynamicModel::rowsAboutToBeInserted );
0146     QSignalSpy spy4( model, &Dynamic::DynamicModel::rowsInserted );
0147 
0148     // -- removeAt with playlist
0149     QModelIndex playlistIndex = model->index( 1, 0 );
0150     QString oldName = model->data( playlistIndex ).toString();
0151 
0152     model->removeAt( playlistIndex );
0153 
0154     QCOMPARE( spy1.count(), 1 );
0155     QCOMPARE( spy3.count(), 0 );
0156     QList<QVariant> args1 = spy1.takeFirst();
0157     QVERIFY( args1.value(0).canConvert<QModelIndex>() );
0158     QCOMPARE( args1.value(0).value<QModelIndex>(), QModelIndex() );
0159     QCOMPARE( args1.value(1).toInt(), 1 );
0160     QCOMPARE( args1.value(2).toInt(), 1 );
0161     QCOMPARE( spy2.count(), 1 );
0162     spy2.takeFirst();
0163 
0164     // name should be different
0165     playlistIndex = model->index( 1, 0 );
0166     QVERIFY( model->data( playlistIndex ).toString() != oldName );
0167 
0168     QCOMPARE( model->rowCount(), 3 );
0169 
0170     // -- removeAt with bias
0171     playlistIndex = model->index( 1, 0 );
0172     QModelIndex biasIndex = model->index( 0, 0, playlistIndex );
0173     QModelIndex subBiasIndex = model->index( 0, 0, biasIndex );
0174     QCOMPARE( model->rowCount( biasIndex ), 2 );
0175 
0176     model->removeAt( subBiasIndex );
0177 
0178     QCOMPARE( spy1.count(), 1 );
0179     QCOMPARE( spy3.count(), 0 );
0180     args1 = spy1.takeFirst();
0181     QCOMPARE( args1.count(), 3 );
0182     QVERIFY( args1.value(0).canConvert<QModelIndex>() );
0183     QCOMPARE( args1.value(0).value<QModelIndex>(), biasIndex );
0184     QCOMPARE( args1.value(1).toInt(), 0 );
0185     QCOMPARE( args1.value(2).toInt(), 0 );
0186     QCOMPARE( spy2.count(), 1 );
0187     spy2.takeFirst();
0188 
0189     QCOMPARE( model->rowCount( biasIndex ), 1 );
0190     QCOMPARE( model->rowCount(), 3 ); // only the bias was removed
0191 
0192     // -- cloneAt with level 2 bias
0193     playlistIndex = model->index( 1, 0 );
0194 
0195     biasIndex = model->index( 0, 0, playlistIndex );
0196     subBiasIndex = model->index( 0, 0, biasIndex );
0197     QCOMPARE( model->rowCount( biasIndex ), 1 );
0198 
0199     QModelIndex resultIndex = model->cloneAt(subBiasIndex);
0200     QCOMPARE( resultIndex.row(), 1 );
0201     QCOMPARE( resultIndex.parent(), biasIndex );
0202 
0203     QCOMPARE( spy3.count(), 1 );
0204     args1 = spy3.takeFirst();
0205     QVERIFY( args1.value(0).canConvert<QModelIndex>() );
0206     QCOMPARE( args1.value(0).value<QModelIndex>(), biasIndex );
0207     QCOMPARE( args1.value(1).toInt(), 1 );
0208     QCOMPARE( args1.value(2).toInt(), 1 );
0209     QCOMPARE( spy4.count(), 1 );
0210     spy4.takeFirst();
0211 
0212     QCOMPARE( model->rowCount( biasIndex ), 2 );
0213     QCOMPARE( model->rowCount(), 3 ); // only the bias was cloned
0214 
0215     // -- newPlaylist
0216     QCOMPARE( spy1.count(), 0 );
0217     QCOMPARE( spy3.count(), 0 );
0218 
0219     QCOMPARE( model->rowCount(), 3 );
0220     resultIndex = model->newPlaylist();
0221     QCOMPARE( model->rowCount(), 4 );
0222 
0223     QCOMPARE( resultIndex.row(), 3 );
0224     QCOMPARE( resultIndex.parent(), QModelIndex() );
0225 
0226     QCOMPARE( spy1.count(), 0 );
0227     QCOMPARE( spy3.count(), 1 );
0228     args1 = spy3.takeFirst();
0229     QVERIFY( args1.value(0).canConvert<QModelIndex>() );
0230     QCOMPARE( args1.value(0).value<QModelIndex>(), QModelIndex() );
0231     QCOMPARE( args1.value(1).toInt(), 3 );
0232     QCOMPARE( args1.value(2).toInt(), 3 );
0233     QCOMPARE( spy4.count(), 1 );
0234     spy4.takeFirst();
0235 
0236     // -- cloneAt with playlist
0237     playlistIndex = model->index( 1, 0 );
0238 
0239     QCOMPARE( model->rowCount(), 4 );
0240     resultIndex = model->cloneAt(playlistIndex);
0241     QCOMPARE( model->rowCount(), 5 );
0242 
0243     QCOMPARE( resultIndex.row(), 4 );
0244     QCOMPARE( resultIndex.parent(), QModelIndex() );
0245     QCOMPARE( model->rowCount( resultIndex ), 1 );
0246 
0247     QCOMPARE( spy3.count(), 1 );
0248     args1 = spy3.takeFirst();
0249     QVERIFY( args1.value(0).canConvert<QModelIndex>() );
0250     QCOMPARE( args1.value(0).value<QModelIndex>(), QModelIndex() );
0251     QCOMPARE( args1.value(1).toInt(), 4 );
0252     QCOMPARE( args1.value(2).toInt(), 4 );
0253     QCOMPARE( spy4.count(), 1 );
0254     spy4.takeFirst();
0255 }
0256 
0257 QModelIndex
0258 TestDynamicModel::serializeUnserialize( const QModelIndex& index )
0259 {
0260     Dynamic::DynamicModel *model = Dynamic::DynamicModel::instance();
0261 
0262     QByteArray bytes;
0263     QDataStream stream( &bytes, QIODevice::WriteOnly );
0264     model->serializeIndex( &stream, index );
0265 
0266     QDataStream stream2( &bytes, QIODevice::ReadOnly );
0267     return model->unserializeIndex( &stream2 );
0268 }
0269 
0270 void
0271 TestDynamicModel::testSerializeIndex()
0272 {
0273     Dynamic::DynamicModel *model = Dynamic::DynamicModel::instance();
0274 
0275     // load from the empty directory
0276     model->loadPlaylists();
0277 
0278     QModelIndex playlistIndex = model->index( 2, 0 );
0279     QModelIndex biasIndex = model->index( 0, 0, playlistIndex );
0280     QModelIndex subBiasIndex = model->index( 0, 0, biasIndex );
0281 
0282     QCOMPARE( QModelIndex(), serializeUnserialize( QModelIndex() ) );
0283     QCOMPARE( biasIndex, serializeUnserialize( biasIndex ) );
0284     QCOMPARE( subBiasIndex, serializeUnserialize( subBiasIndex ) );
0285 }
0286 
0287 void
0288 TestDynamicModel::testDnD()
0289 {
0290     Dynamic::DynamicModel *model = Dynamic::DynamicModel::instance();
0291 
0292     // load from the empty directory
0293     model->loadPlaylists();
0294 
0295     // -- copy a playlist
0296     QModelIndex playlistIndex = model->index( 2, 0 );
0297     QModelIndexList indexes;
0298     indexes << playlistIndex;
0299     int oldRowCount = model->rowCount();
0300     QString oldName = model->data( playlistIndex ).toString();
0301     QMimeData* data = model->mimeData( indexes );
0302     QVERIFY( model->dropMimeData( data, Qt::CopyAction, 0, 0, QModelIndex() ) );
0303 
0304     QCOMPARE( model->rowCount(), oldRowCount + 1 );
0305     playlistIndex = model->index( 0, 0 );
0306     QCOMPARE( oldName, model->data( playlistIndex ).toString() );
0307     delete data;
0308 
0309     // -- move a playlist (to the end)
0310     playlistIndex = model->index( 0, 0 );
0311     indexes.clear();
0312     indexes << playlistIndex;
0313 
0314     oldRowCount = model->rowCount();
0315     oldName = model->data( playlistIndex ).toString();
0316     data = model->mimeData( indexes );
0317     QVERIFY( model->dropMimeData( data, Qt::MoveAction, oldRowCount, 0, QModelIndex() ) );
0318 
0319     QCOMPARE( model->rowCount(), oldRowCount );
0320     playlistIndex = model->index( oldRowCount - 1, 0 );
0321     QCOMPARE( oldName, model->data( playlistIndex ).toString() );
0322     delete data;
0323 
0324 
0325     // -- copy a bias
0326     // TODO
0327 //     QModelIndex biasIndex = model->index( 0, 0, playlistIndex );
0328 //     QModelIndex subBiasIndex = model->index( 0, 0, biasIndex );
0329 }
0330 
0331 void
0332 TestDynamicModel::testRemoveActive()
0333 {
0334     Dynamic::DynamicModel *model = Dynamic::DynamicModel::instance();
0335 
0336     // load from the empty directory
0337     model->loadPlaylists();
0338     QCOMPARE( model->rowCount(), 4 );
0339 
0340     // -- try to remove the active playlist
0341     model->setActivePlaylist( 2 );
0342     QCOMPARE( model->activePlaylistIndex(), 2 );
0343     Dynamic::DynamicPlaylist* pl = model->activePlaylist();
0344 
0345     model->removeAt( model->index( pl ) );
0346     QCOMPARE( model->rowCount(), 3 );
0347     QVERIFY( model->activePlaylist() != pl );
0348 
0349     // -- now remove all playlists remaining three playlists
0350     model->removeAt( model->index( model->activePlaylist() ) );
0351     model->removeAt( model->index( model->activePlaylist() ) );
0352     model->removeAt( model->index( model->activePlaylist() ) );
0353 
0354     QCOMPARE( model->rowCount(), 0 );
0355     QCOMPARE( model->activePlaylist(), static_cast<Dynamic::DynamicPlaylist*>(nullptr) );
0356 }
0357