File indexing completed on 2024-04-28 04:48:15

0001 /****************************************************************************************
0002  * Copyright (c) 2010 Maximilian Kossick <maximilian.kossick@googlemail.com>       *
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 "TestUnionJob.h"
0018 
0019 #include "core/support/Debug.h"
0020 #include "core/collections/CollectionLocation.h"
0021 #include "synchronization/UnionJob.h"
0022 
0023 #include "CollectionTestImpl.h"
0024 #include "mocks/MockTrack.h"
0025 #include "mocks/MockAlbum.h"
0026 #include "mocks/MockArtist.h"
0027 
0028 #include <QList>
0029 #include <QSignalSpy>
0030 
0031 #include <gmock/gmock.h>
0032 
0033 QTEST_GUILESS_MAIN( TestUnionJob )
0034 
0035 using ::testing::Return;
0036 using ::testing::AnyNumber;
0037 
0038 static QList<int> trackCopyCount;
0039 
0040 namespace Collections {
0041 
0042 class MyCollectionLocation : public CollectionLocation
0043 {
0044 public:
0045     Collections::CollectionTestImpl *coll;
0046 
0047     QString prettyLocation() const override { return "foo"; }
0048     bool isWritable() const override { return true; }
0049     bool remove( const Meta::TrackPtr &track )
0050     {
0051         coll->mc->acquireWriteLock();
0052         //theoretically we should clean up the other maps as well...
0053         TrackMap map = coll->mc->trackMap();
0054         map.remove( track->uidUrl() );
0055         coll->mc->setTrackMap( map );
0056         coll->mc->releaseLock();
0057         return true;
0058     }
0059     void copyUrlsToCollection(const QMap<Meta::TrackPtr, QUrl> &sources, const Transcoding::Configuration& conf) override
0060     {
0061         Q_UNUSED( conf )
0062         trackCopyCount << sources.count();
0063         foreach( const Meta::TrackPtr &track, sources.keys() )
0064         {
0065             coll->mc->addTrack( track );
0066         }
0067     }
0068 };
0069 
0070 class MyCollectionTestImpl : public CollectionTestImpl
0071 {
0072 public:
0073     MyCollectionTestImpl( const QString &id ) : CollectionTestImpl( id ) {}
0074 
0075     CollectionLocation* location() override
0076     {
0077         MyCollectionLocation *r = new MyCollectionLocation();
0078         r->coll = this;
0079         return r;
0080     }
0081 };
0082 
0083 } //namespace Collections
0084 
0085 void addMockTrack( Collections::CollectionTestImpl *coll, const QString &trackName, const QString &artistName, const QString &albumName )
0086 {
0087     Meta::MockTrack *track = new Meta::MockTrack();
0088     ::testing::Mock::AllowLeak( track );
0089     Meta::TrackPtr trackPtr( track );
0090     EXPECT_CALL( *track, name() ).Times( AnyNumber() ).WillRepeatedly( Return( trackName ) );
0091     EXPECT_CALL( *track, uidUrl() ).Times( AnyNumber() ).WillRepeatedly( Return( trackName + '_' + artistName + '_' + albumName ) );
0092     EXPECT_CALL( *track, playableUrl() ).Times( AnyNumber() ).WillRepeatedly( Return( QUrl( '/' + track->uidUrl() ) ) );
0093     coll->mc->addTrack( trackPtr );
0094 
0095     Meta::AlbumPtr albumPtr = coll->mc->albumMap().value( albumName, QString() /* no album artist */ );
0096     Meta::MockAlbum *album;
0097     Meta::TrackList albumTracks;
0098     if( albumPtr )
0099     {
0100         album = dynamic_cast<Meta::MockAlbum*>( albumPtr.data() );
0101         if( !album )
0102         {
0103             QFAIL( "expected a Meta::MockAlbum" );
0104             return;
0105         }
0106         albumTracks = albumPtr->tracks();
0107     }
0108     else
0109     {
0110         album = new Meta::MockAlbum();
0111         ::testing::Mock::AllowLeak( album );
0112         albumPtr = Meta::AlbumPtr( album );
0113         EXPECT_CALL( *album, name() ).Times( AnyNumber() ).WillRepeatedly( Return( albumName ) );
0114         EXPECT_CALL( *album, hasAlbumArtist() ).Times( AnyNumber() ).WillRepeatedly( Return( false ) );
0115         EXPECT_CALL( *album, albumArtist() ).Times( AnyNumber() ).WillRepeatedly( Return( Meta::ArtistPtr() ) );
0116         coll->mc->addAlbum( albumPtr );
0117     }
0118     albumTracks << trackPtr;
0119     EXPECT_CALL( *album, tracks() ).Times( AnyNumber() ).WillRepeatedly( Return( albumTracks ) );
0120 
0121     EXPECT_CALL( *track, album() ).Times( AnyNumber() ).WillRepeatedly( Return( albumPtr ) );
0122 
0123     Meta::ArtistPtr artistPtr = coll->mc->artistMap().value( artistName );
0124     Meta::MockArtist *artist;
0125     Meta::TrackList artistTracks;
0126     if( artistPtr )
0127     {
0128         artist = dynamic_cast<Meta::MockArtist*>( artistPtr.data() );
0129         if( !artist )
0130         {
0131             QFAIL( "expected a Meta::MockArtist" );
0132             return;
0133         }
0134         artistTracks = artistPtr->tracks();
0135     }
0136     else
0137     {
0138         artist = new Meta::MockArtist();
0139         ::testing::Mock::AllowLeak( artist );
0140         artistPtr = Meta::ArtistPtr( artist );
0141         EXPECT_CALL( *artist, name() ).Times( AnyNumber() ).WillRepeatedly( Return( artistName ) );
0142         coll->mc->addArtist( artistPtr );
0143     }
0144     artistTracks << trackPtr;
0145     EXPECT_CALL( *artist, tracks() ).Times( AnyNumber() ).WillRepeatedly( Return( artistTracks ) );
0146     EXPECT_CALL( *track, artist() ).Times( AnyNumber() ).WillRepeatedly( Return( artistPtr ) );
0147 }
0148 
0149 TestUnionJob::TestUnionJob() : QObject()
0150 {
0151     int argc = 1;
0152     char **argv = (char **) malloc(sizeof(char *));
0153     argv[0] = strdup( QCoreApplication::applicationName().toLocal8Bit().data() );
0154     ::testing::InitGoogleMock( &argc, argv );
0155     qRegisterMetaType<Meta::TrackList>();
0156     qRegisterMetaType<Meta::AlbumList>();
0157     qRegisterMetaType<Meta::ArtistList>();
0158 }
0159 
0160 void
0161 TestUnionJob::init()
0162 {
0163     trackCopyCount.clear();
0164 }
0165 
0166 void
0167 TestUnionJob::testEmptyA()
0168 {
0169     Collections::CollectionTestImpl *collA = new Collections::MyCollectionTestImpl("A");
0170     Collections::CollectionTestImpl *collB = new Collections::MyCollectionTestImpl("B");
0171 
0172     addMockTrack( collB, "track1", "artist1", "album1" );
0173     QCOMPARE( collA->mc->trackMap().count(), 0 );
0174     QCOMPARE( collB->mc->trackMap().count(), 1 );
0175     QVERIFY( trackCopyCount.isEmpty() );
0176 
0177     UnionJob *job = new UnionJob( collA, collB );
0178     QSignalSpy spy( job, &UnionJob::destroyed );
0179     job->synchronize();
0180     spy.wait( 1000 );
0181 
0182     QCOMPARE( trackCopyCount.size(), 1 );
0183     QVERIFY( trackCopyCount.contains( 1 ) );
0184     QCOMPARE( collA->mc->trackMap().count(), 1 );
0185     QCOMPARE( collB->mc->trackMap().count(), 1 );
0186 
0187     delete collA;
0188     delete collB;
0189 }
0190 
0191 void
0192 TestUnionJob::testEmptyB()
0193 {
0194     Collections::CollectionTestImpl *collA = new Collections::MyCollectionTestImpl("A");
0195     Collections::CollectionTestImpl *collB = new Collections::MyCollectionTestImpl("B");
0196 
0197     addMockTrack( collA, "track1", "artist1", "album1" );
0198     QCOMPARE( collA->mc->trackMap().count(), 1 );
0199     QCOMPARE( collB->mc->trackMap().count(), 0 );
0200     QVERIFY( trackCopyCount.isEmpty() );
0201 
0202     UnionJob *job = new UnionJob( collA, collB );
0203     QSignalSpy spy( job, &UnionJob::destroyed );
0204     job->synchronize();
0205     spy.wait( 1000 );
0206 
0207     QCOMPARE( trackCopyCount.size(), 1 );
0208     QVERIFY( trackCopyCount.contains( 1 ) );
0209     QCOMPARE( collA->mc->trackMap().count(), 1 );
0210     QCOMPARE( collB->mc->trackMap().count(), 1 );
0211 
0212     delete collA;
0213     delete collB;
0214 }
0215 
0216 void
0217 TestUnionJob::testAddTrackToBoth()
0218 {
0219     Collections::CollectionTestImpl *collA = new Collections::MyCollectionTestImpl("A");
0220     Collections::CollectionTestImpl *collB = new Collections::MyCollectionTestImpl("B");
0221 
0222     addMockTrack( collA, "track1", "artist1", "album1" );
0223     addMockTrack( collB, "track2", "artist2", "album2" );
0224     QCOMPARE( collA->mc->trackMap().count(), 1 );
0225     QCOMPARE( collB->mc->trackMap().count(), 1 );
0226     QVERIFY( trackCopyCount.isEmpty() );
0227 
0228     UnionJob *job = new UnionJob( collA, collB );
0229     QSignalSpy spy( job, &UnionJob::destroyed );
0230     job->synchronize();
0231     spy.wait( 1000 );
0232 
0233     QCOMPARE( trackCopyCount.size(), 2 );
0234     QCOMPARE( trackCopyCount.at( 0 ), 1 );
0235     QCOMPARE( trackCopyCount.at( 1 ), 1 );
0236     QCOMPARE( collA->mc->trackMap().count(), 2 );
0237     QCOMPARE( collB->mc->trackMap().count(), 2 );
0238 
0239     delete collA;
0240     delete collB;
0241 }
0242 
0243 void
0244 TestUnionJob::testTrackAlreadyInBoth()
0245 {
0246     Collections::CollectionTestImpl *collA = new Collections::MyCollectionTestImpl("A");
0247     Collections::CollectionTestImpl *collB = new Collections::MyCollectionTestImpl("B");
0248 
0249     addMockTrack( collA, "track1", "artist1", "album1" );
0250     addMockTrack( collB, "track1", "artist1", "album1" );
0251     addMockTrack( collB, "track2", "artist2", "album2" );
0252     QCOMPARE( collA->mc->trackMap().count(), 1 );
0253     QCOMPARE( collB->mc->trackMap().count(), 2 );
0254     QVERIFY( trackCopyCount.isEmpty() );
0255 
0256     UnionJob *job = new UnionJob( collA, collB );
0257     QSignalSpy spy( job, &UnionJob::destroyed );
0258     job->synchronize();
0259     spy.wait( 1000 );
0260 
0261     QCOMPARE( trackCopyCount.size(), 1 );
0262     QVERIFY( trackCopyCount.contains( 1 ) );
0263     QCOMPARE( collA->mc->trackMap().count(), 2 );
0264     QCOMPARE( collB->mc->trackMap().count(), 2 );
0265 
0266     delete collA;
0267     delete collB;
0268 }