diff --git a/tests/TestTrackOrganizer.cpp b/tests/TestTrackOrganizer.cpp index c25a631df7..7be1a780dd 100644 --- a/tests/TestTrackOrganizer.cpp +++ b/tests/TestTrackOrganizer.cpp @@ -1,183 +1,183 @@ /*************************************************************************** * Copyright (c) 2010 Casey Link * * Copyright (c) 2010 Maximilian Kossick * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "TestTrackOrganizer.h" #include "dialogs/TrackOrganizer.h" #include "core/support/Debug.h" #include "CollectionTestImpl.h" #include "mocks/MockTrack.h" #include "mocks/MockAlbum.h" #include "mocks/MockArtist.h" #include #include -#include +#include using ::testing::Return; using ::testing::AnyNumber; QTEST_GUILESS_MAIN( TestTrackOrganizer ) namespace Collections { class MyCollectionTestImpl : public CollectionTestImpl { public: MyCollectionTestImpl( const QString &id ) : CollectionTestImpl( id ) {} }; } //namespace Collections TestTrackOrganizer::TestTrackOrganizer() { } void TestTrackOrganizer::init() { mColl = new Collections::MyCollectionTestImpl("A"); } void TestTrackOrganizer::cleanup() { delete mColl; delete mTrackOrganizer; } void TestTrackOrganizer::testBasic() { mTracks = makeTracks( 10 ); mTrackOrganizer = new TrackOrganizer( mTracks, this ); QString folder = "/home/user/Music" ; mTrackOrganizer->setFormatString( "%collectionroot%/%artist%/%album%/%track%-%title%.%filetype%" ); mTrackOrganizer->setFolderPrefix( folder ); QMap dests = mTrackOrganizer->getDestinations(); QVERIFY( dests.size() == 10 ); foreach( Meta::TrackPtr track, mTracks ) { QVERIFY( dests.contains( track ) ); QString format = "%1/%2/%3/%4-%5.%6"; QString trackNum = QString("%1").arg( track->trackNumber(), 2, 10, QChar('0') ); QString result = format.arg( folder, track->artist()->prettyName(), track->album()->prettyName(), trackNum, track->prettyName(), "mp3"); QCOMPARE( dests.value( track ), result ); } } Meta::TrackPtr TestTrackOrganizer::makeMockTrack( const QString &trackName, const QString &artistName, const QString &albumName, int trackNumber ) { Meta::MockTrack *track = new Meta::MockTrack(); ::testing::Mock::AllowLeak( track ); Meta::TrackPtr trackPtr( track ); EXPECT_CALL( *track, name() ).Times( AnyNumber() ).WillRepeatedly( Return( trackName ) ); EXPECT_CALL( *track, prettyName() ).Times( AnyNumber() ).WillRepeatedly( Return( trackName ) ); EXPECT_CALL( *track, uidUrl() ).Times( AnyNumber() ).WillRepeatedly( Return( trackName + '_' + artistName + '_' + albumName ) ); EXPECT_CALL( *track, playableUrl() ).Times( AnyNumber() ).WillRepeatedly( Return( QUrl( '/' + track->uidUrl() ) ) ); EXPECT_CALL( *track, trackNumber() ).Times( AnyNumber() ).WillRepeatedly( Return( trackNumber ) ); EXPECT_CALL( *track, type() ).Times( AnyNumber() ).WillRepeatedly( Return( "mp3" ) ); EXPECT_CALL( *track, composer() ).Times( AnyNumber() ).WillRepeatedly( Return( Meta::ComposerPtr() ) ); EXPECT_CALL( *track, year() ).Times( AnyNumber() ).WillRepeatedly( Return( Meta::YearPtr() ) ); EXPECT_CALL( *track, genre() ).Times( AnyNumber() ).WillRepeatedly( Return( Meta::GenrePtr() ) ); EXPECT_CALL( *track, discNumber() ).Times( AnyNumber() ).WillRepeatedly( Return( 0 ) ); EXPECT_CALL( *track, rating() ).Times( AnyNumber() ).WillRepeatedly( Return( 0 ) ); EXPECT_CALL( *track, filesize() ).Times( AnyNumber() ).WillRepeatedly( Return( 0 ) ); EXPECT_CALL( *track, length() ).Times( AnyNumber() ).WillRepeatedly( Return( 0 ) ); EXPECT_CALL( *track, comment() ).Times( AnyNumber() ).WillRepeatedly( Return( "" ) ); mColl->mc->addTrack( trackPtr ); Meta::AlbumPtr albumPtr = mColl->mc->albumMap().value( albumName, QString() /* no album artist */ ); Meta::MockAlbum *album; Meta::TrackList albumTracks; if( albumPtr ) { album = dynamic_cast( albumPtr.data() ); if( !album ) { qFatal("expected a Meta::MockAlbum"); // QFAIL( "expected a Meta::MockAlbum" ); return trackPtr; } albumTracks = albumPtr->tracks(); } else { album = new Meta::MockAlbum(); ::testing::Mock::AllowLeak( album ); albumPtr = Meta::AlbumPtr( album ); EXPECT_CALL( *album, name() ).Times( AnyNumber() ).WillRepeatedly( Return( albumName ) ); EXPECT_CALL( *album, prettyName() ).Times( AnyNumber() ).WillRepeatedly( Return( albumName ) ); EXPECT_CALL( *album, hasAlbumArtist() ).Times( AnyNumber() ).WillRepeatedly( Return( false ) ); EXPECT_CALL( *album, albumArtist() ).Times( AnyNumber() ).WillRepeatedly( Return( Meta::ArtistPtr() ) ); EXPECT_CALL( *album, isCompilation() ).Times( AnyNumber() ).WillRepeatedly( Return( false ) ); mColl->mc->addAlbum( albumPtr ); } albumTracks << trackPtr; EXPECT_CALL( *album, tracks() ).Times( AnyNumber() ).WillRepeatedly( Return( albumTracks ) ); EXPECT_CALL( *track, album() ).Times( AnyNumber() ).WillRepeatedly( Return( albumPtr ) ); Meta::ArtistPtr artistPtr = mColl->mc->artistMap().value( artistName ); Meta::MockArtist *artist; Meta::TrackList artistTracks; if( artistPtr ) { artist = dynamic_cast( artistPtr.data() ); if( !artist ) { qFatal("expected a Meta::MockArtist"); // QFAIL( "expected a Meta::MockArtist" ); return trackPtr; } artistTracks = artistPtr->tracks(); } else { artist = new Meta::MockArtist(); ::testing::Mock::AllowLeak( artist ); artistPtr = Meta::ArtistPtr( artist ); EXPECT_CALL( *artist, name() ).Times( AnyNumber() ).WillRepeatedly( Return( artistName ) ); EXPECT_CALL( *artist, prettyName() ).Times( AnyNumber() ).WillRepeatedly( Return( artistName ) ); mColl->mc->addArtist( artistPtr ); } artistTracks << trackPtr; EXPECT_CALL( *artist, tracks() ).Times( AnyNumber() ).WillRepeatedly( Return( artistTracks ) ); EXPECT_CALL( *track, artist() ).Times( AnyNumber() ).WillRepeatedly( Return( artistPtr ) ); return trackPtr; } Meta::TrackList TestTrackOrganizer::makeTracks( int numTracks ) { Meta::TrackList tracks; for( int i = 1; i <= numTracks; ++i ) { QString title = "Title" + QString::number(i); Meta::TrackPtr t = makeMockTrack( title, "Artist1", "Album1", i ); if( t ) tracks << t; } return tracks; } diff --git a/tests/browsers/TestSingleCollectionTreeItemModel.cpp b/tests/browsers/TestSingleCollectionTreeItemModel.cpp index 8cf2bbf7a0..b3e93b8ad1 100644 --- a/tests/browsers/TestSingleCollectionTreeItemModel.cpp +++ b/tests/browsers/TestSingleCollectionTreeItemModel.cpp @@ -1,343 +1,343 @@ /**************************************************************************************** * Copyright (c) 2010 Maximilian Kossick * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #include "TestSingleCollectionTreeItemModel.h" #include "amarokconfig.h" #include "core/meta/Meta.h" #include "browsers/CollectionTreeItemModelBase.h" #include "browsers/SingleCollectionTreeItemModel.h" #include "CollectionTestImpl.h" #include "mocks/MockTrack.h" #include "mocks/MockAlbum.h" #include "mocks/MockArtist.h" #include #include #include #include #include -#include +#include using ::testing::Return; using ::testing::AnyNumber; using ::testing::_; QTEST_MAIN( TestSingleCollectionTreeItemModel ) void addMockTrack( Collections::CollectionTestImpl *coll, const QString &trackName, const QString &artistName, const QString &albumName ) { Meta::MockTrack *track = new Meta::MockTrack(); ::testing::Mock::AllowLeak( track ); Meta::TrackPtr trackPtr( track ); EXPECT_CALL( *track, name() ).Times( AnyNumber() ).WillRepeatedly( Return( trackName ) ); EXPECT_CALL( *track, prettyName() ).Times( AnyNumber() ).WillRepeatedly( Return( trackName ) ); EXPECT_CALL( *track, uidUrl() ).Times( AnyNumber() ).WillRepeatedly( Return( trackName + '_' + artistName + '_' + albumName ) ); EXPECT_CALL( *track, playableUrl() ).Times( AnyNumber() ).WillRepeatedly( Return( QUrl( '/' + track->uidUrl() ) ) ); EXPECT_CALL( *track, composer() ).Times( AnyNumber() ).WillRepeatedly( Return( Meta::ComposerPtr() ) ); EXPECT_CALL( *track, genre() ).Times( AnyNumber() ).WillRepeatedly( Return( Meta::GenrePtr() ) ); EXPECT_CALL( *track, year() ).Times( AnyNumber() ).WillRepeatedly( Return( Meta::YearPtr() ) ); coll->mc->addTrack( trackPtr ); Meta::AlbumPtr albumPtr = coll->mc->albumMap().value( albumName, QString() /* no album artist */ ); Meta::MockAlbum *album; Meta::TrackList albumTracks; if( albumPtr ) { album = dynamic_cast( albumPtr.data() ); if( !album ) { QFAIL( "expected a Meta::MockAlbum" ); return; } albumTracks = albumPtr->tracks(); } else { album = new Meta::MockAlbum(); ::testing::Mock::AllowLeak( album ); albumPtr = Meta::AlbumPtr( album ); EXPECT_CALL( *album, name() ).Times( AnyNumber() ).WillRepeatedly( Return( albumName ) ); EXPECT_CALL( *album, prettyName() ).Times( AnyNumber() ).WillRepeatedly( Return( albumName ) ); EXPECT_CALL( *album, hasAlbumArtist() ).Times( AnyNumber() ).WillRepeatedly( Return( false ) ); EXPECT_CALL( *album, isCompilation() ).Times( AnyNumber() ).WillRepeatedly( Return( false ) ); //inconsistent coll->mc->addAlbum( albumPtr ); } albumTracks << trackPtr; EXPECT_CALL( *album, tracks() ).Times( AnyNumber() ).WillRepeatedly( Return( albumTracks ) ); EXPECT_CALL( *track, album() ).Times( AnyNumber() ).WillRepeatedly( Return( albumPtr ) ); Meta::ArtistPtr artistPtr = coll->mc->artistMap().value( artistName ); Meta::MockArtist *artist; Meta::TrackList artistTracks; if( artistPtr ) { artist = dynamic_cast( artistPtr.data() ); if( !artist ) { QFAIL( "expected a Meta::MockArtist" ); return; } artistTracks = artistPtr->tracks(); } else { artist = new Meta::MockArtist(); ::testing::Mock::AllowLeak( artist ); artistPtr = Meta::ArtistPtr( artist ); EXPECT_CALL( *artist, name() ).Times( AnyNumber() ).WillRepeatedly( Return( artistName ) ); EXPECT_CALL( *artist, prettyName() ).Times( AnyNumber() ).WillRepeatedly( Return( artistName ) ); coll->mc->addArtist( artistPtr ); } artistTracks << trackPtr; EXPECT_CALL( *artist, tracks() ).Times( AnyNumber() ).WillRepeatedly( Return( artistTracks ) ); EXPECT_CALL( *track, artist() ).Times( AnyNumber() ).WillRepeatedly( Return( artistPtr ) ); EXPECT_CALL( *album, albumArtist() ).Times( AnyNumber() ).WillRepeatedly( Return( artistPtr ) ); } void TestSingleCollectionTreeItemModel::initTestCase() { qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); AmarokConfig::instance("amarokrc"); } #define loadChildren( itemModel, idx ) \ { \ if( itemModel->canFetchMore( idx ) ) { \ QSignalSpy spy( itemModel, &SingleCollectionTreeItemModel::allQueriesFinished ); \ itemModel->fetchMore( idx ); \ QVERIFY( spy.wait( 5000 ) ); \ } \ } void TestSingleCollectionTreeItemModel::testAddNewArtist() { Collections::CollectionTestImpl *coll = new Collections::CollectionTestImpl( "test" ); addMockTrack( coll, "track1", "artist1", "album1" ); QList levels; levels<< CategoryId::Artist << CategoryId::Album; SingleCollectionTreeItemModel *model = new SingleCollectionTreeItemModel( coll, levels ); loadChildren( model, QModelIndex() ); QCOMPARE( model->rowCount( QModelIndex() ), 1 ); { QModelIndex artist1Index = model->index( 0, 0, QModelIndex() ); QCOMPARE( model->data( artist1Index, Qt::DisplayRole ).toString(), QString( "artist1" ) ); } addMockTrack( coll, "track2", "artist2", "album2" ); model->slotFilter(); loadChildren( model, QModelIndex() ); QCOMPARE( model->rowCount( QModelIndex() ), 2 ); QSet artists; QModelIndex idx1 = model->index( 0, 0, QModelIndex() ); artists << model->data( idx1, Qt::DisplayRole ).toString(); QModelIndex idx2 = model->index( 1, 0, QModelIndex() ); artists << model->data( idx2, Qt::DisplayRole ).toString(); { QSet expected; expected << "artist1" << "artist2"; QCOMPARE( artists, expected ); } delete model; delete coll; } void TestSingleCollectionTreeItemModel::testRemoveArtist() { Collections::CollectionTestImpl *coll = new Collections::CollectionTestImpl( "test" ); addMockTrack( coll, "track1", "artist1", "album1" ); addMockTrack( coll, "track2", "artist2", "album2" ); QList levels; levels<< CategoryId::Artist << CategoryId::Album; SingleCollectionTreeItemModel *model = new SingleCollectionTreeItemModel( coll, levels ); loadChildren( model, QModelIndex() ); QCOMPARE( model->rowCount( QModelIndex() ), 2 ); { QSet artists; QModelIndex idx1 = model->index( 0, 0, QModelIndex() ); artists << model->data( idx1, Qt::DisplayRole ).toString(); QModelIndex idx2 = model->index( 1, 0, QModelIndex() ); artists << model->data( idx2, Qt::DisplayRole ).toString(); QSet expected; expected << "artist1" << "artist2"; QCOMPARE( artists, expected ); } ArtistMap map = coll->mc->artistMap(); map.remove( "artist2" ); //album and track are still part of the collection coll->mc->setArtistMap( map ); model->slotFilter(); loadChildren( model, QModelIndex() ); QCOMPARE( model->rowCount( QModelIndex() ), 1 ); { QModelIndex artist1Index = model->index( 0, 0, QModelIndex() ); QCOMPARE( model->data( artist1Index, Qt::DisplayRole ).toString(), QString( "artist1" ) ); } delete model; delete coll; } void TestSingleCollectionTreeItemModel::testAddTrack() { Collections::CollectionTestImpl *coll = new Collections::CollectionTestImpl( "test" ); addMockTrack( coll, "track1", "artist1", "album1" ); addMockTrack( coll, "track2", "artist2", "album2" ); QList levels; levels<< CategoryId::Artist << CategoryId::Album; SingleCollectionTreeItemModel *model = new SingleCollectionTreeItemModel( coll, levels ); loadChildren( model, QModelIndex() ); QCOMPARE( model->rowCount( QModelIndex() ), 2 ); { QSet artists; QModelIndex idx1 = model->index( 0, 0, QModelIndex() ); artists << model->data( idx1, Qt::DisplayRole ).toString(); QModelIndex idx2 = model->index( 1, 0, QModelIndex() ); artists << model->data( idx2, Qt::DisplayRole ).toString(); QSet expected; expected << "artist1" << "artist2"; QCOMPARE( artists, expected ); } for( int i = 0; i < 2; i++ ) { QModelIndex parent = model->index( i, 0, QModelIndex() ); loadChildren( model, parent ); QCOMPARE( model->rowCount( parent ), 1 ); QModelIndex subParent = model->index( 0, 0, parent ); loadChildren( model, subParent ); QCOMPARE( model->rowCount( subParent ), 1 ); } addMockTrack( coll, "track3", "artist1", "album1" ); model->slotFilter(); QTest::qWait( 30 ); loadChildren( model, QModelIndex() ); QCOMPARE( model->rowCount( QModelIndex() ), 2 ); for( int i = 0; i < 2; i++ ) { QModelIndex parent = model->index( i, 0, QModelIndex() ); loadChildren( model, parent ); QCOMPARE( model->rowCount( parent ), 1 ); QString name = model->data( parent, Qt::DisplayRole ).toString(); int count = (name == "artist1" ? 2 : 1 ); QModelIndex subParent = model->index( 0, 0, parent ); loadChildren( model, subParent ); QCOMPARE( model->rowCount( subParent ), count ); } delete model; delete coll; } void TestSingleCollectionTreeItemModel::testRemoveTrack() { } void TestSingleCollectionTreeItemModel::testAddTrackWithFilter() { Collections::CollectionTestImpl *coll = new Collections::CollectionTestImpl( "test" ); addMockTrack( coll, "track1", "artist1", "album1" ); QList levels; levels << CategoryId::Artist << CategoryId::Album; SingleCollectionTreeItemModel *model = new SingleCollectionTreeItemModel( coll, levels ); loadChildren( model, QModelIndex() ); QCOMPARE( model->rowCount( QModelIndex() ), 1 ); { QModelIndex artist1Index = model->index( 0, 0, QModelIndex() ); QCOMPARE( model->data( artist1Index, Qt::DisplayRole ).toString(), QString( "artist1" ) ); } addMockTrack( coll, "track2", "artist2", "album2" ); model->setCurrentFilter( "track2" ); model->slotFilter(); loadChildren( model, QModelIndex() ); QCOMPARE( model->rowCount( QModelIndex() ), 1 ); model->setCurrentFilter( QString() ); model->slotFilter(); loadChildren( model, QModelIndex() ); QCOMPARE( model->rowCount( QModelIndex() ), 2 ); QModelIndex idx1 = model->index( 0, 0, QModelIndex() ); QCOMPARE( model->data( idx1, Qt::DisplayRole ).toString(), QString( "artist2" ) ); delete model; delete coll; } diff --git a/tests/core-impl/collections/aggregate/TestAggregateMeta.cpp b/tests/core-impl/collections/aggregate/TestAggregateMeta.cpp index 251eb43100..c7af6f0d8f 100644 --- a/tests/core-impl/collections/aggregate/TestAggregateMeta.cpp +++ b/tests/core-impl/collections/aggregate/TestAggregateMeta.cpp @@ -1,513 +1,513 @@ /**************************************************************************************** * Copyright (c) 2010 Maximilian Kossick * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #include "TestAggregateMeta.h" #include "core/capabilities/OrganiseCapability.h" #include "core/meta/Meta.h" #include "core/meta/TrackEditor.h" #include "core/support/Debug.h" #include "core-impl/collections/aggregate/AggregateCollection.h" #include "core-impl/collections/aggregate/AggregateMeta.h" #include "mocks/MetaMock.h" #include "mocks/MockTrack.h" #include #include -#include +#include QTEST_GUILESS_MAIN( TestAggregateMeta ) TestAggregateMeta::TestAggregateMeta() { int argc = 1; char **argv = (char **) malloc(sizeof(char *)); argv[0] = strdup( QCoreApplication::applicationName().toLocal8Bit().data() ); ::testing::InitGoogleMock( &argc, argv ); } class MyTrackMock : public MetaMock { public: MyTrackMock() : MetaMock( QVariantMap() ) {} bool hasCapabilityInterface( Capabilities::Capability::Type type ) const override { bool result = results.value( type ); results.remove( type ); return result; } Capabilities::Capability* createCapabilityInterface(Capabilities::Capability::Type type) override { Capabilities::Capability* cap = capabilities.value( type ); capabilities.remove( type ); return cap; } Meta::TrackEditorPtr editor() override { return trackEditors.isEmpty() ? Meta::TrackEditorPtr() : trackEditors.takeFirst(); } mutable QMap results; mutable QMap capabilities; QList trackEditors; }; class MyAlbumMock : public MockAlbum { public: MyAlbumMock() : MockAlbum( "testAlbum" ) {} bool hasCapabilityInterface( Capabilities::Capability::Type type ) const override { bool result = results.value( type ); results.remove( type ); return result; } Capabilities::Capability* createCapabilityInterface(Capabilities::Capability::Type type) override { Capabilities::Capability* cap = capabilities.value( type ); capabilities.remove( type ); return cap; } mutable QMap results; mutable QMap capabilities; }; class MyArtistMock : public MockArtist { public: MyArtistMock() : MockArtist( "testArtist" ) {} bool hasCapabilityInterface( Capabilities::Capability::Type type ) const override { bool result = results.value( type ); results.remove( type ); return result; } Capabilities::Capability* createCapabilityInterface(Capabilities::Capability::Type type) override { Capabilities::Capability* cap = capabilities.value( type ); capabilities.remove( type ); return cap; } mutable QMap results; mutable QMap capabilities; }; class MyGenreMock : public MockGenre { public: MyGenreMock() : MockGenre( "testGenre" ) {} bool hasCapabilityInterface( Capabilities::Capability::Type type ) const override { bool result = results.value( type ); results.remove( type ); return result; } Capabilities::Capability* createCapabilityInterface(Capabilities::Capability::Type type) override { Capabilities::Capability* cap = capabilities.value( type ); capabilities.remove( type ); return cap; } mutable QMap results; mutable QMap capabilities; }; class MyComposerMock : public MockComposer { public: MyComposerMock() : MockComposer( "testComposer" ) {} bool hasCapabilityInterface( Capabilities::Capability::Type type ) const override { bool result = results.value( type ); results.remove( type ); return result; } Capabilities::Capability* createCapabilityInterface(Capabilities::Capability::Type type) override { Capabilities::Capability* cap = capabilities.value( type ); capabilities.remove( type ); return cap; } mutable QMap results; mutable QMap capabilities; }; class MyYearMock : public MockYear { public: MyYearMock() : MockYear( "testYear" ) {} bool hasCapabilityInterface( Capabilities::Capability::Type type ) const override { bool result = results.value( type ); results.remove( type ); return result; } Capabilities::Capability* createCapabilityInterface(Capabilities::Capability::Type type) override { Capabilities::Capability* cap = capabilities.value( type ); capabilities.remove( type ); return cap; } mutable QMap results; mutable QMap capabilities; }; class MyOrganiseCapability : public Capabilities::OrganiseCapability { public: void deleteTrack() override {} }; void TestAggregateMeta::testHasCapabilityOnSingleTrack() { MyTrackMock *mock = new MyTrackMock(); QMap results; results.insert( Capabilities::Capability::Buyable, false ); results.insert( Capabilities::Capability::BookmarkThis, true ); mock->results = results; Meta::TrackPtr ptr( mock ); Meta::AggregateTrack cut( 0, ptr ); QVERIFY( cut.hasCapabilityInterface( Capabilities::Capability::BookmarkThis ) ); QVERIFY( !cut.hasCapabilityInterface( Capabilities::Capability::Buyable ) ); QCOMPARE( mock->results.count(), 0 ); } void TestAggregateMeta::testCreateCapabilityOnSingleTrack() { MyTrackMock *mock = new MyTrackMock(); QMap capabilities; capabilities.insert( Capabilities::Capability::Buyable, 0 ); Capabilities::Capability *cap = new MyOrganiseCapability(); capabilities.insert( Capabilities::Capability::Organisable, cap ); mock->capabilities = capabilities; Meta::TrackPtr ptr( mock ); Meta::AggregateTrack cut( 0, ptr ); QVERIFY( ! cut.createCapabilityInterface( Capabilities::Capability::Buyable ) ); QCOMPARE( cut.createCapabilityInterface( Capabilities::Capability::Organisable ), cap ); QCOMPARE( mock->capabilities.count(), 0 ); delete cap; } void TestAggregateMeta::testHasCapabilityOnSingleAlbum() { MyAlbumMock *mock = new MyAlbumMock(); QMap results; results.insert( Capabilities::Capability::Buyable, false ); results.insert( Capabilities::Capability::BookmarkThis, true ); mock->results = results; Meta::AlbumPtr ptr( mock ); Meta::AggregateAlbum album( 0, ptr ); QVERIFY( album.hasCapabilityInterface( Capabilities::Capability::BookmarkThis ) ); QVERIFY( !album.hasCapabilityInterface( Capabilities::Capability::Buyable ) ); QCOMPARE( mock->results.count(), 0 ); } void TestAggregateMeta::testCreateCapabilityOnSingleAlbum() { MyAlbumMock *mock = new MyAlbumMock(); QMap capabilities; capabilities.insert( Capabilities::Capability::Buyable, 0 ); Capabilities::Capability *cap = new MyOrganiseCapability(); capabilities.insert( Capabilities::Capability::Organisable, cap ); mock->capabilities = capabilities; Meta::AlbumPtr ptr( mock ); Meta::AggregateAlbum album( 0, ptr ); QVERIFY( ! album.createCapabilityInterface( Capabilities::Capability::Buyable ) ); QCOMPARE( album.createCapabilityInterface( Capabilities::Capability::Organisable ), cap ); QCOMPARE( mock->capabilities.count(), 0 ); delete cap; } void TestAggregateMeta::testHasCapabilityOnSingleArtist() { MyArtistMock *mock = new MyArtistMock(); QMap results; results.insert( Capabilities::Capability::Buyable, false ); results.insert( Capabilities::Capability::BookmarkThis, true ); mock->results = results; Meta::ArtistPtr ptr( mock ); Meta::AggregateArtist artist( 0, ptr ); QVERIFY( artist.hasCapabilityInterface( Capabilities::Capability::BookmarkThis ) ); QVERIFY( !artist.hasCapabilityInterface( Capabilities::Capability::Buyable ) ); QCOMPARE( mock->results.count(), 0 ); } void TestAggregateMeta::testCreateCapabilityOnSingleArtist() { MyArtistMock *mock = new MyArtistMock(); QMap capabilities; capabilities.insert( Capabilities::Capability::Buyable, 0 ); Capabilities::Capability *cap = new MyOrganiseCapability(); capabilities.insert( Capabilities::Capability::Organisable, cap ); mock->capabilities = capabilities; Meta::ArtistPtr ptr( mock ); Meta::AggregateArtist artist( 0, ptr ); QVERIFY( ! artist.createCapabilityInterface( Capabilities::Capability::Buyable ) ); QCOMPARE( artist.createCapabilityInterface( Capabilities::Capability::Organisable ), cap ); QCOMPARE( mock->capabilities.count(), 0 ); delete cap; } void TestAggregateMeta::testHasCapabilityOnSingleComposer() { MyComposerMock *mock = new MyComposerMock(); QMap results; results.insert( Capabilities::Capability::Buyable, false ); results.insert( Capabilities::Capability::BookmarkThis, true ); mock->results = results; Meta::ComposerPtr ptr( mock ); Meta::AggregateComposer cut( 0, ptr ); QVERIFY( cut.hasCapabilityInterface( Capabilities::Capability::BookmarkThis ) ); QVERIFY( !cut.hasCapabilityInterface( Capabilities::Capability::Buyable ) ); QCOMPARE( mock->results.count(), 0 ); } void TestAggregateMeta::testCreateCapabilityOnSingleComposer() { MyComposerMock *mock = new MyComposerMock(); QMap capabilities; capabilities.insert( Capabilities::Capability::Buyable, 0 ); Capabilities::Capability *cap = new MyOrganiseCapability(); capabilities.insert( Capabilities::Capability::Organisable, cap ); mock->capabilities = capabilities; Meta::ComposerPtr ptr( mock ); Meta::AggregateComposer cut( 0, ptr ); QVERIFY( ! cut.createCapabilityInterface( Capabilities::Capability::Buyable ) ); QCOMPARE( cut.createCapabilityInterface( Capabilities::Capability::Organisable ), cap ); QCOMPARE( mock->capabilities.count(), 0 ); delete cap; } void TestAggregateMeta::testHasCapabilityOnSingleGenre() { MyGenreMock *mock = new MyGenreMock(); QMap results; results.insert( Capabilities::Capability::Buyable, false ); results.insert( Capabilities::Capability::BookmarkThis, true ); mock->results = results; Meta::GenrePtr ptr( mock ); Meta::AggregateGenre cut( 0, ptr ); QVERIFY( cut.hasCapabilityInterface( Capabilities::Capability::BookmarkThis ) ); QVERIFY( !cut.hasCapabilityInterface( Capabilities::Capability::Buyable ) ); QCOMPARE( mock->results.count(), 0 ); } void TestAggregateMeta::testCreateCapabilityOnSingleGenre() { MyGenreMock *mock = new MyGenreMock(); QMap capabilities; capabilities.insert( Capabilities::Capability::Buyable, 0 ); Capabilities::Capability *cap = new MyOrganiseCapability(); capabilities.insert( Capabilities::Capability::Organisable, cap ); mock->capabilities = capabilities; Meta::GenrePtr ptr( mock ); Meta::AggregateGenre cut( 0, ptr ); QVERIFY( ! cut.createCapabilityInterface( Capabilities::Capability::Buyable ) ); QCOMPARE( cut.createCapabilityInterface( Capabilities::Capability::Organisable ), cap ); QCOMPARE( mock->capabilities.count(), 0 ); delete cap; } void TestAggregateMeta::testHasCapabilityOnSingleYear() { MyYearMock *mock = new MyYearMock(); QMap results; results.insert( Capabilities::Capability::Buyable, false ); results.insert( Capabilities::Capability::BookmarkThis, true ); mock->results = results; Meta::YearPtr ptr( mock ); Meta::AggreagateYear cut( 0, ptr ); QVERIFY( cut.hasCapabilityInterface( Capabilities::Capability::BookmarkThis ) ); QVERIFY( !cut.hasCapabilityInterface( Capabilities::Capability::Buyable ) ); QCOMPARE( mock->results.count(), 0 ); } void TestAggregateMeta::testCreateCapabilityOnSingleYear() { MyYearMock *mock = new MyYearMock(); QMap capabilities; capabilities.insert( Capabilities::Capability::Buyable, 0 ); Capabilities::Capability *cap = new MyOrganiseCapability(); capabilities.insert( Capabilities::Capability::Organisable, cap ); mock->capabilities = capabilities; Meta::YearPtr ptr( mock ); Meta::AggreagateYear cut( 0, ptr ); QVERIFY( ! cut.createCapabilityInterface( Capabilities::Capability::Buyable ) ); QCOMPARE( cut.createCapabilityInterface( Capabilities::Capability::Organisable ), cap ); QCOMPARE( mock->capabilities.count(), 0 ); delete cap; } class MyTrackEditor : public Meta::TrackEditor { public: MyTrackEditor() : Meta::TrackEditor() , beginCallCount(0) , endCallcount(0) {} void setAlbum( const QString &newAlbum ) override { Q_UNUSED( newAlbum ) } void setAlbumArtist( const QString &newAlbumArtist ) override { Q_UNUSED( newAlbumArtist ) } void setArtist( const QString &newArtist ) override { Q_UNUSED( newArtist ) } void setComposer( const QString &newComposer ) override { Q_UNUSED( newComposer ) }; void setGenre( const QString &newGenre ) override { Q_UNUSED( newGenre ) }; void setYear( int newYear ) override { Q_UNUSED( newYear ) }; void setTitle( const QString &newTitle ) override { Q_UNUSED( newTitle ) }; void setComment( const QString &newComment ) override { Q_UNUSED( newComment ) }; void setTrackNumber( int newTrackNumber ) override { Q_UNUSED( newTrackNumber ) }; void setDiscNumber( int newDiscNumber ) override { Q_UNUSED( newDiscNumber ) }; void setBpm( const qreal newBpm ) override { Q_UNUSED( newBpm ) }; void beginUpdate() override { beginCallCount++; }; void endUpdate() override { endCallcount++; }; int beginCallCount; int endCallcount; }; void TestAggregateMeta::testEditableCapabilityOnMultipleTracks() { MyTrackMock *mock1 = new MyTrackMock(); MyTrackMock *mock2 = new MyTrackMock(); AmarokSharedPointer cap1 ( new MyTrackEditor() ); AmarokSharedPointer cap2 ( new MyTrackEditor() ); mock1->trackEditors << Meta::TrackEditorPtr( cap1.data() ); mock2->trackEditors << Meta::TrackEditorPtr( cap2.data() ); Meta::TrackPtr ptr1( mock1 ); Meta::TrackPtr ptr2( mock2 ); Collections::AggregateCollection *collection = new Collections::AggregateCollection(); QSignalSpy spy( collection, &Collections::AggregateCollection::updated); QVERIFY( spy.isValid() ); Meta::AggregateTrack cut( collection, ptr1 ); cut.add( ptr2 ); Meta::TrackEditorPtr editCap = cut.editor(); QVERIFY( editCap ); QCOMPARE( cap1->beginCallCount, 0 ); QCOMPARE( cap2->beginCallCount, 0 ); editCap->beginUpdate(); QCOMPARE( cap1->beginCallCount, 1 ); QCOMPARE( cap2->beginCallCount, 1 ); QCOMPARE( cap1->endCallcount, 0 ); QCOMPARE( cap2->endCallcount, 0 ); editCap->endUpdate(); QCOMPARE( cap1->endCallcount, 1 ); QCOMPARE( cap2->endCallcount, 1 ); //the signal is delayed a bit, but that is ok QTest::qWait( 50 ); //required so that the collection browser refreshes itself QCOMPARE( spy.count(), 1 ); } using ::testing::Return; using ::testing::AnyNumber; void TestAggregateMeta::testPrettyUrl() { Meta::MockTrack *mock = new ::testing::NiceMock(); EXPECT_CALL( *mock, prettyUrl() ).Times( AnyNumber() ).WillRepeatedly( Return( "foo" ) ); Meta::TrackPtr trackPtr( mock ); Meta::AggregateTrack track( 0, trackPtr ); QCOMPARE( track.prettyUrl(), QString( "foo" ) ); } diff --git a/tests/core-impl/collections/db/sql/ScanManagerMock.h b/tests/core-impl/collections/db/sql/ScanManagerMock.h index 670af4cccd..17b2f70d13 100644 --- a/tests/core-impl/collections/db/sql/ScanManagerMock.h +++ b/tests/core-impl/collections/db/sql/ScanManagerMock.h @@ -1,37 +1,37 @@ /**************************************************************************************** * Copyright (c) 2010 Maximilian Kossick * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #ifndef SCANMANAGERMOCK_H #define SCANMANAGERMOCK_H -#include +#include #include class ScanManagerMock : public ScanManager { public: MOCK_METHOD1( setBlockScan, void( bool ) ); MOCK_METHOD1( isDirInCollection, bool( const QString& ) ); MOCK_METHOD0( startFullScan, void() ); MOCK_METHOD1( startIncrementalScan, void( const QString& ) ); MOCK_METHOD1( abort, void( const QString& ) ); }; #endif diff --git a/tests/core-impl/collections/db/sql/TestSqlCollectionLocation.cpp b/tests/core-impl/collections/db/sql/TestSqlCollectionLocation.cpp index f88734df95..706ee5122f 100644 --- a/tests/core-impl/collections/db/sql/TestSqlCollectionLocation.cpp +++ b/tests/core-impl/collections/db/sql/TestSqlCollectionLocation.cpp @@ -1,277 +1,277 @@ /**************************************************************************************** * Copyright (c) 2009 Maximilian Kossick * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #include "TestSqlCollectionLocation.h" #include "DatabaseUpdater.h" #include "core/support/Debug.h" #include "core/support/Components.h" #include "DefaultSqlQueryMakerFactory.h" #include "core/meta/Meta.h" #include "core-impl/storage/sql/mysqlestorage/MySqlEmbeddedStorage.h" #include "SqlCollection.h" #include "SqlCollectionLocation.h" #include "SqlRegistry.h" #include "SqlMountPointManagerMock.h" #include "core/collections/MockCollectionLocationDelegate.h" #include "config-amarok-test.h" #include #include #include -#include +#include #include using ::testing::AnyNumber; using ::testing::Return; using ::testing::_; /** A SqlCollectionLocation that claims writing is possible even though it doesn't have * a valid directory. */ class MySqlCollectionLocation : public Collections::SqlCollectionLocation { public: MySqlCollectionLocation( Collections::SqlCollection *coll ) : Collections::SqlCollectionLocation( coll ) {} ~MySqlCollectionLocation() override {} bool isWritable() const override { return true; } }; class MyOrganizeCollectionDelegate : public OrganizeCollectionDelegate { public: MyOrganizeCollectionDelegate() : OrganizeCollectionDelegate(), overwrite( false ), migrate( false ) {} ~MyOrganizeCollectionDelegate() override {} void setTracks( const Meta::TrackList &tracks ) override { Q_UNUSED( tracks ) } void setFolders( const QStringList &folders ) override { Q_UNUSED( folders ) } void setIsOrganizing( bool organizing ) override { Q_UNUSED( organizing ) } void setTranscodingConfiguration(const Transcoding::Configuration &configuration) override { Q_UNUSED( configuration ) } void setCaption( const QString& ) override {} void show() override { emit accepted(); } bool overwriteDestinations() const override { return overwrite; } QMap destinations() const override { return dests; } bool migrateLabels() const { return migrate; } bool overwrite; bool migrate; QMap dests; }; class MyOrganizeCollectionDelegateFactory : public OrganizeCollectionDelegateFactory { public: MyOrganizeCollectionDelegateFactory( OrganizeCollectionDelegate *d ) : OrganizeCollectionDelegateFactory() , delegate( d ) {} ~MyOrganizeCollectionDelegateFactory() override {} //warning: SqlCollectionLocation will delete the delegate OrganizeCollectionDelegate* createDelegate() override { return delegate; } OrganizeCollectionDelegate *delegate; }; QTEST_GUILESS_MAIN( TestSqlCollectionLocation ) TestSqlCollectionLocation::TestSqlCollectionLocation() : QObject() , m_collection( 0 ) , m_storage( 0 ) , m_tmpDir( 0 ) { int argc = 1; char **argv = (char **) malloc(sizeof(char *)); argv[0] = strdup( QCoreApplication::applicationName().toLocal8Bit().data() ); ::testing::InitGoogleMock( &argc, argv ); } void TestSqlCollectionLocation::initTestCase() { m_tmpDir = new QTemporaryDir(); m_storage = QSharedPointer( new MySqlEmbeddedStorage() ); QVERIFY( m_storage->init( m_tmpDir->path() ) ); m_collection = new Collections::SqlCollection( m_storage ); SqlMountPointManagerMock *mock = new SqlMountPointManagerMock( this, m_storage ); mock->setCollectionFolders( QStringList() << m_tmpDir->path() ); // the target folder needs to have enough space and be writable m_collection->setMountPointManager( mock ); // I just need the table and not the whole playlist manager m_storage->query( QString( "CREATE TABLE playlist_tracks (" " id " + m_storage->idType() + ", playlist_id INTEGER " ", track_num INTEGER " ", url " + m_storage->exactTextColumnType() + ", title " + m_storage->textColumnType() + ", album " + m_storage->textColumnType() + ", artist " + m_storage->textColumnType() + ", length INTEGER " ", uniqueid " + m_storage->textColumnType(128) + ") ENGINE = MyISAM;" ) ); } void TestSqlCollectionLocation::cleanupTestCase() { delete m_collection; //m_storage is deleted by SqlCollection delete m_tmpDir; } void TestSqlCollectionLocation::init() { //setup base data m_storage->query( "INSERT INTO artists(id, name) VALUES (1, 'artist1');" ); m_storage->query( "INSERT INTO artists(id, name) VALUES (2, 'artist2');" ); m_storage->query( "INSERT INTO artists(id, name) VALUES (3, 'artist3');" ); m_storage->query( "INSERT INTO albums(id,name,artist) VALUES(1,'album1',1);" ); m_storage->query( "INSERT INTO albums(id,name,artist) VALUES(2,'album2',1);" ); m_storage->query( "INSERT INTO albums(id,name,artist) VALUES(3,'album3',2);" ); m_storage->query( "INSERT INTO composers(id, name) VALUES (1, 'composer1');" ); m_storage->query( "INSERT INTO genres(id, name) VALUES (1, 'genre1');" ); m_storage->query( "INSERT INTO years(id, name) VALUES (1, '1');" ); m_storage->query( "INSERT INTO directories(id,deviceid,dir) VALUES (1, -1, '." + m_tmpDir->path() + "/ab/')"); m_storage->query( "INSERT INTO directories(id,deviceid,dir) VALUES (2, -1, '." + m_tmpDir->path() + "/b/')"); m_storage->query( "INSERT INTO directories(id,deviceid,dir) VALUES (3, -1, '." + m_tmpDir->path() + "/c/')"); m_storage->query( QString( "INSERT INTO urls(id, deviceid, rpath, uniqueid, directory ) VALUES (1, -1, '%1', 'uid://1', 1);" ).arg( setupFileInTempDir( "ab/IDoNotExist.mp3" ) ) ); m_storage->query( QString( "INSERT INTO urls(id, deviceid, rpath, uniqueid, directory ) VALUES (2, -1, '%1', 'uid://2', 2);" ).arg( setupFileInTempDir( "b/IDoNotExistAsWell.mp3") ) ); m_storage->query( QString( "INSERT INTO urls(id, deviceid, rpath, uniqueid, directory ) VALUES (3, -1, '%1', 'uid:/3', 3);" ).arg( setupFileInTempDir( "c/MeNeither.mp3" ) ) ); m_storage->query( "INSERT INTO tracks(id,url,title,comment,artist,album,genre,year,composer) " "VALUES(1,1,'track1','comment1',1,1,1,1,1);" ); m_storage->query( "INSERT INTO tracks(id,url,title,comment,artist,album,genre,year,composer) " "VALUES(2,2,'track2','comment2',1,2,1,1,1);" ); m_storage->query( "INSERT INTO tracks(id,url,title,comment,artist,album,genre,year,composer) " "VALUES(3,3,'track3','comment3',2,3,1,1,1);" ); m_collection->registry()->emptyCache(); } void TestSqlCollectionLocation::cleanup() { delete Amarok::Components::setCollectionLocationDelegate( 0 ); m_storage->query( "TRUNCATE TABLE years;" ); m_storage->query( "TRUNCATE TABLE genres;" ); m_storage->query( "TRUNCATE TABLE composers;" ); m_storage->query( "TRUNCATE TABLE albums;" ); m_storage->query( "TRUNCATE TABLE artists;" ); m_storage->query( "TRUNCATE TABLE tracks;" ); m_storage->query( "TRUNCATE TABLE urls;" ); m_storage->query( "TRUNCATE TABLE labels;" ); m_storage->query( "TRUNCATE TABLE urls_labels;" ); m_storage->query( "TRUNCATE TABLE directories;" ); } void TestSqlCollectionLocation::testOrganizingCopiesLabels() { { Collections::MockCollectionLocationDelegate *d = new Collections::MockCollectionLocationDelegate(); EXPECT_CALL( *d, reallyMove( _, _ ) ).Times( AnyNumber() ).WillRepeatedly( Return( true ) ); EXPECT_CALL( *d, transcode( _, _, _, _, _ ) ).WillOnce( Return( Transcoding::Configuration( Transcoding::INVALID ) ) ); Amarok::Components::setCollectionLocationDelegate( d ); } { Meta::TrackPtr track = m_collection->registry()->getTrackFromUid( "uid://1" ); QVERIFY( track ); QVERIFY( track->playableUrl().path().endsWith( "ab/IDoNotExist.mp3" ) ); track->addLabel( "test" ); QCOMPARE( track->labels().count(), 1 ); Collections::SqlCollectionLocation *source = new MySqlCollectionLocation( m_collection ); Collections::SqlCollectionLocation *dest = new MySqlCollectionLocation( m_collection ); QSignalSpy spy( source, &Collections::SqlCollectionLocation::destroyed ); { MyOrganizeCollectionDelegate *delegate = new MyOrganizeCollectionDelegate(); delegate->overwrite = true; delegate->migrate = true; delegate->dests.insert( track, m_tmpDir->path() + "b/IDoNotExist.mp3" ); dest->setOrganizeCollectionDelegateFactory( new MyOrganizeCollectionDelegateFactory( delegate ) ); } source->prepareMove( track, dest ); spy.wait( 1000 ); QCOMPARE( track->labels().count(), 1 ); QVERIFY( track->playableUrl().path().endsWith( "b/IDoNotExist.mp3" ) ); } //force a reload from the database m_collection->registry()->emptyCache(); { // Meta::TrackPtr track = m_collection->registry()->getTrack( m_tmpDir->path() + "/b/IDoNotExist.mp3" ); Meta::TrackPtr track = m_collection->registry()->getTrack(1); QVERIFY( track ); QVERIFY( track->playableUrl().path().endsWith( "b/IDoNotExist.mp3" ) ); // TODO: check that the db urls entry really specifies the exiting directories entry QCOMPARE( track->labels().count(), 1 ); } } void TestSqlCollectionLocation::testCopiesLabelFromExternalTracks() { } void TestSqlCollectionLocation::testCopyTrackToDirectoryWithExistingTracks() { } QString TestSqlCollectionLocation::setupFileInTempDir( const QString &relativeName ) { QString absoluteName = m_tmpDir->path() + '/' + relativeName; //TODO: unix specific //create directory where necessary int index = absoluteName.lastIndexOf( '/' ); if(index > 0 ) { QString dir = absoluteName.left( index ); QProcess::execute( "mkdir", QStringList() << "-p" << dir ); } else { qDebug() << "huh? index was " << index << " relative name was " << relativeName << " tmpDir " << m_tmpDir->path(); } QProcess::execute( "touch", QStringList() << absoluteName ); return '.' + absoluteName; } diff --git a/tests/core-impl/collections/support/TestMemoryQueryMaker.cpp b/tests/core-impl/collections/support/TestMemoryQueryMaker.cpp index 0429883c5f..a440e6510c 100644 --- a/tests/core-impl/collections/support/TestMemoryQueryMaker.cpp +++ b/tests/core-impl/collections/support/TestMemoryQueryMaker.cpp @@ -1,296 +1,296 @@ /**************************************************************************************** * Copyright (c) 2010 Maximilian Kossick * * Copyright (c) 2011 Ralf Engels * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #include "TestMemoryQueryMaker.h" #include "mocks/MetaMock.h" #include "mocks/MockTrack.h" #include "FileType.h" #include #include #include -#include +#include using ::testing::AnyNumber; using ::testing::Return; QTEST_GUILESS_MAIN( TestMemoryQueryMaker ) TestMemoryQueryMaker::TestMemoryQueryMaker() { int argc = 1; char **argv = (char **) malloc(sizeof(char *)); argv[0] = strdup( QCoreApplication::applicationName().toLocal8Bit().data() ); ::testing::InitGoogleMock( &argc, argv ); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); } void TestMemoryQueryMaker::initTestCase() { // prepare a memory collection with some test data m_mc = QSharedPointer( new Collections::MemoryCollection() ); MetaMock *track; QVariantMap map; map.insert( Meta::Field::UNIQUEID, "1" ); map.insert( Meta::Field::TITLE, "Skater Boy" ); map.insert( Meta::Field::RATING, 3 ); // map.insert( Meta::Field::TYPE, int(Amarok::Mp3) ); map.insert( Meta::Field::TRACKNUMBER, 3 ); track = new MetaMock( map ); track->m_artist = new MockArtist("Avril Lavigne"); track->m_album = new MockAlbum("Let Go"); m_mc->addTrack( Meta::TrackPtr( track ) ); map.insert( Meta::Field::UNIQUEID, "2" ); map.insert( Meta::Field::TITLE, "Substitute" ); map.insert( Meta::Field::RATING, 4 ); // map.insert( Meta::Field::TYPE, int(Amarok::Ogg) ); map.insert( Meta::Field::TRACKNUMBER, 1 ); track = new MetaMock( map ); track->m_artist = new MockArtist("Clout" ); track->m_album = new MockAlbum("Substitute" ); m_mc->addTrack( Meta::TrackPtr( track ) ); map.insert( Meta::Field::UNIQUEID, "3" ); map.insert( Meta::Field::TITLE, "I Say A Little Prayer" ); map.insert( Meta::Field::RATING, 2 ); // map.insert( Meta::Field::TYPE, int(Amarok::Wma) ); map.insert( Meta::Field::TRACKNUMBER, 1 ); map.insert( Meta::Field::DISCNUMBER, 2 ); track = new MetaMock( map ); track->m_artist = new MockArtist("The Bosshoss" ); track->m_album = new MockAlbum("Rodeo Radio" ); m_mc->addTrack( Meta::TrackPtr( track ) ); } void TestMemoryQueryMaker::cleanupTestCase() { } void TestMemoryQueryMaker::testDeleteQueryMakerWhileQueryIsRunning() { QSharedPointer mc( new Collections::MemoryCollection() ); mc->addTrack( Meta::TrackPtr( new MetaMock( QVariantMap() ))); mc->addTrack( Meta::TrackPtr( new MetaMock( QVariantMap() ))); Meta::MockTrack *mock = new Meta::MockTrack(); EXPECT_CALL( *mock, uidUrl() ).Times( AnyNumber() ).WillRepeatedly( Return( "track3" ) ); Meta::TrackPtr trackPtr( mock ); mc->addTrack( trackPtr ); Collections::MemoryQueryMaker *qm = new Collections::MemoryQueryMaker( mc.toWeakRef(), "test" ); qm->setQueryType( Collections::QueryMaker::Track ); qm->run(); delete qm; //we cannot wait for a signal here.... //QTest::qWait( 500 ); } void TestMemoryQueryMaker::testDeleteCollectionWhileQueryIsRunning() { QSharedPointer mc( new Collections::MemoryCollection() ); mc->addTrack( Meta::TrackPtr( new MetaMock( QVariantMap() ))); mc->addTrack( Meta::TrackPtr( new MetaMock( QVariantMap() ))); Collections::MemoryQueryMaker *qm = new Collections::MemoryQueryMaker( mc, "test" ); qm->setQueryType( Collections::QueryMaker::Track ); QSignalSpy spy( qm, &Collections::QueryMaker::queryDone); qm->run(); mc.clear(); QTest::qWait( 500 ); QCOMPARE( spy.count(), 1 ); delete qm; } class TestStringMemoryFilter : public StringMemoryFilter { public: TestStringMemoryFilter() : StringMemoryFilter() {} protected: QString value( const Meta::TrackPtr &track ) const override { Q_UNUSED(track); return "abcdef"; } }; void TestMemoryQueryMaker::testStringMemoryFilterSpeedFullMatch() { //Test 1: match complete string TestStringMemoryFilter filter1; filter1.setFilter( QString( "abcdef" ), true, true ); QBENCHMARK { filter1.filterMatches( Meta::TrackPtr() ); } } void TestMemoryQueryMaker::testStringMemoryFilterSpeedMatchBegin() { //Test 2: match beginning of string TestStringMemoryFilter filter2; filter2.setFilter( QString( "abcd" ), true, false ); QBENCHMARK { filter2.filterMatches( Meta::TrackPtr() ); } } void TestMemoryQueryMaker::testStringMemoryFilterSpeedMatchEnd() { //Test 3: match end of string TestStringMemoryFilter filter3; filter3.setFilter( QString( "cdef" ), false, true ); QBENCHMARK { filter3.filterMatches( Meta::TrackPtr() ); } } void TestMemoryQueryMaker::testStringMemoryFilterSpeedMatchAnywhere() { //Test 4: match anywhere in string TestStringMemoryFilter filter4; filter4.setFilter( QString( "bcde" ), false, false ); QBENCHMARK { filter4.filterMatches( Meta::TrackPtr() ); } } Meta::TrackList TestMemoryQueryMaker::executeQueryMaker( Collections::QueryMaker *qm ) { QSignalSpy doneSpy1( qm, &Collections::QueryMaker::queryDone ); QSignalSpy resultSpy1( qm, &Collections::QueryMaker::newTracksReady ); qm->setQueryType( Collections::QueryMaker::Track ); qm->run(); doneSpy1.wait( 1000 ); if( resultSpy1.count() != 1 ) return Meta::TrackList(); if( doneSpy1.count() != 1 ) return Meta::TrackList(); QList args1 = resultSpy1.takeFirst(); if( !args1.value(0).canConvert() ) return Meta::TrackList(); delete qm; return args1.value(0).value(); } void TestMemoryQueryMaker::testFilterTitle() { Meta::TrackList tracks; // -- just get all the tracks Collections::MemoryQueryMaker *qm = new Collections::MemoryQueryMaker( m_mc.toWeakRef(), "test" ); tracks = executeQueryMaker( qm ); QCOMPARE( tracks.count(), 3 ); // -- filter for title qm = new Collections::MemoryQueryMaker( m_mc.toWeakRef(), "test" ); qm->addFilter( Meta::valTitle, "Skater", true, false ); tracks = executeQueryMaker( qm ); QCOMPARE( tracks.count(), 1 ); QCOMPARE( tracks.first()->name(), QString("Skater Boy" ) ); // -- filter for album qm = new Collections::MemoryQueryMaker( m_mc.toWeakRef(), "test" ); qm->addFilter( Meta::valAlbum, "S", false, false ); tracks = executeQueryMaker( qm ); QCOMPARE( tracks.count(), 1 ); QCOMPARE( tracks.first()->name(), QString("Substitute" ) ); // -- filter for artist qm = new Collections::MemoryQueryMaker( m_mc.toWeakRef(), "test" ); qm->addFilter( Meta::valArtist, "Lavigne", false, true ); tracks = executeQueryMaker( qm ); QCOMPARE( tracks.count(), 1 ); QCOMPARE( tracks.first()->name(), QString("Skater Boy" ) ); } void TestMemoryQueryMaker::testFilterRating() { Meta::TrackList tracks; Collections::MemoryQueryMaker *qm = 0; // -- filter for Rating qm = new Collections::MemoryQueryMaker( m_mc.toWeakRef(), "test" ); qm->addNumberFilter( Meta::valRating, 3, Collections::QueryMaker::Equals ); tracks = executeQueryMaker( qm ); QCOMPARE( tracks.count(), 1 ); QCOMPARE( tracks.first()->name(), QString("Skater Boy" ) ); // -- filter for Rating qm = new Collections::MemoryQueryMaker( m_mc.toWeakRef(), "test" ); qm->addNumberFilter( Meta::valRating, 4, Collections::QueryMaker::LessThan ); tracks = executeQueryMaker( qm ); QCOMPARE( tracks.count(), 2 ); } void TestMemoryQueryMaker::testFilterAnd() { Meta::TrackList tracks; Collections::MemoryQueryMaker *qm = 0; qm = new Collections::MemoryQueryMaker( m_mc.toWeakRef(), "test" ); qm->beginAnd(); qm->addNumberFilter( Meta::valTrackNr, 1, Collections::QueryMaker::Equals ); qm->addFilter( Meta::valAlbum, "o", false, false ); qm->endAndOr(); tracks = executeQueryMaker( qm ); QCOMPARE( tracks.count(), 1 ); QCOMPARE( tracks.first()->album()->name(), QString("Rodeo Radio" ) ); } void TestMemoryQueryMaker::testFilterFormat() { Meta::TrackList tracks; Collections::MemoryQueryMaker *qm = 0; // -- filter for title qm = new Collections::MemoryQueryMaker( m_mc.toWeakRef(), "test" ); qm->addNumberFilter( Meta::valFormat, int(Amarok::Mp3), Collections::QueryMaker::Equals ); tracks = executeQueryMaker( qm ); QCOMPARE( tracks.count(), 0 ); } diff --git a/tests/core/collections/CollectionLocationTest.cpp b/tests/core/collections/CollectionLocationTest.cpp index e6f3cc8d69..07ea36ddb1 100644 --- a/tests/core/collections/CollectionLocationTest.cpp +++ b/tests/core/collections/CollectionLocationTest.cpp @@ -1,184 +1,184 @@ /**************************************************************************************** * Copyright (c) 2009,2010 Maximilian Kossick * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #include "CollectionLocationTest.h" #include "core/support/Components.h" #include "core/collections/CollectionLocation.h" #include "core/support/Debug.h" #include "core/meta/support/MetaConstants.h" #include "../tests/mocks/MetaMock.h" #include "MockCollectionLocationDelegate.h" #include #include #include -#include +#include QTEST_GUILESS_MAIN( CollectionLocationTest ) using ::testing::Return; using ::testing::AnyNumber; using ::testing::_; CollectionLocationTest::CollectionLocationTest() { qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); } namespace Collections { class TestRemoveCL : public CollectionLocation { public: void removeUrlsFromCollection( const Meta::TrackList &tracks ) override { count += tracks.count(); slotRemoveOperationFinished(); } MOCK_CONST_METHOD0( isWritable, bool() ); MOCK_CONST_METHOD0( isOrganizable, bool() ); int count; }; } //namespace Collections void CollectionLocationTest::testSuccessfulCopy() { Collections::MockCollectionLocationDelegate *cld = new Collections::MockCollectionLocationDelegate(); EXPECT_CALL( *cld, reallyDelete( _, _) ).Times( AnyNumber() ).WillRepeatedly( Return( true ) ); Amarok::Components::setCollectionLocationDelegate( cld ); Collections::TestRemoveCL *cl = new Collections::TestRemoveCL(); QSignalSpy spy( cl, &Collections::TestRemoveCL::destroyed ); EXPECT_CALL( *cl, isWritable() ).Times( AnyNumber() ).WillRepeatedly( Return( true ) ); cl->setProperty( "removeSources", true ); cl->count = 0; QVariantMap map; map.insert( Meta::Field::URL, QUrl("file:///IDoNotExist.mp3") ); Meta::TrackPtr file1( new MetaMock( map ) ); cl->transferSuccessful( file1 ); QVERIFY2( cl->metaObject()->invokeMethod( cl, "slotFinishCopy", Qt::DirectConnection ), "Calling slot failed" ); QCOMPARE( cl->count, 1 ); QVERIFY( spy.wait( 5000 ) ); delete Amarok::Components::setCollectionLocationDelegate( 0 ); } void CollectionLocationTest::testFailedCopy() { Collections::MockCollectionLocationDelegate *cld = new Collections::MockCollectionLocationDelegate(); EXPECT_CALL( *cld, reallyDelete( _, _) ).Times( AnyNumber() ).WillRepeatedly( Return( true ) ); EXPECT_CALL( *cld, errorDeleting( _, _ ) ).Times( AnyNumber() ); Amarok::Components::setCollectionLocationDelegate( cld ); Collections::TestRemoveCL *cl = new Collections::TestRemoveCL(); EXPECT_CALL( *cl, isWritable() ).Times( AnyNumber() ).WillRepeatedly( Return( true ) ); QSignalSpy spy( cl, &Collections::TestRemoveCL::destroyed ); cl->setProperty( "removeSources", true ); cl->count = 0; QVariantMap map; map.insert( Meta::Field::URL, QUrl("file:///IDoNotExist.mp3") ); Meta::TrackPtr file1( new MetaMock( map ) ); cl->transferError( file1, "Test of CollectionLocation" ); QVERIFY2( cl->metaObject()->invokeMethod( cl, "slotFinishCopy", Qt::DirectConnection ), "Calling slot failed" ); QCOMPARE( cl->count, 0 ); QVERIFY( spy.wait( 5000 ) ); delete Amarok::Components::setCollectionLocationDelegate( 0 ); } void CollectionLocationTest::testCopyMultipleTracks() { Collections::MockCollectionLocationDelegate *cld = new Collections::MockCollectionLocationDelegate(); EXPECT_CALL( *cld, reallyDelete( _, _) ).Times( AnyNumber() ).WillRepeatedly( Return( true ) ); EXPECT_CALL( *cld, errorDeleting( _, _ ) ).Times( AnyNumber() ); Amarok::Components::setCollectionLocationDelegate( cld ); Collections::TestRemoveCL *cl = new Collections::TestRemoveCL(); QSignalSpy spy( cl, &Collections::TestRemoveCL::destroyed ); EXPECT_CALL( *cl, isWritable() ).Times( AnyNumber() ).WillRepeatedly( Return( true ) ); cl->setProperty( "removeSources", true ); cl->count = 0; QVariantMap map; map.insert( Meta::Field::URL, QUrl("file:///IDoNotExist.mp3") ); Meta::TrackPtr file1( new MetaMock( map ) ); map.insert( Meta::Field::URL, QUrl("file:///IDoNotExistAsWell.mp3") ); Meta::TrackPtr file2( new MetaMock( map ) ); map.insert( Meta::Field::URL, QUrl("file:///IDoNotExistAsWell.mp3") ); Meta::TrackPtr file3( new MetaMock( map ) ); cl->transferError( file1, "Test of CollectionLocation" ); cl->transferSuccessful( file2 ); cl->transferSuccessful( file3 ); cl->metaObject()->invokeMethod( cl, "slotFinishCopy", Qt::DirectConnection ); QCOMPARE( cl->count, 2 ); QVERIFY( spy.wait( 5000 ) ); delete Amarok::Components::setCollectionLocationDelegate( 0 ); } void CollectionLocationTest::testFailedCopyWithIncorrectUsageOfCopySuccesful() { Collections::MockCollectionLocationDelegate *cld = new Collections::MockCollectionLocationDelegate(); EXPECT_CALL( *cld, reallyDelete( _, _) ).Times( AnyNumber() ).WillRepeatedly( Return( true ) ); EXPECT_CALL( *cld, errorDeleting( _, _ ) ).Times( AnyNumber() ); Amarok::Components::setCollectionLocationDelegate( cld ); Collections::TestRemoveCL *cl = new Collections::TestRemoveCL(); EXPECT_CALL( *cl, isWritable() ).Times( AnyNumber() ).WillRepeatedly( Return( true ) ); QSignalSpy spy1( cl, &Collections::TestRemoveCL::destroyed ); cl->setProperty( "removeSources", true ); cl->count = 0; QVariantMap map; map.insert( Meta::Field::URL, QUrl("file:///IDoNotExist.mp3") ); Meta::TrackPtr file1( new MetaMock( map ) ); cl->transferError( file1, "Test of CollectionLocation" ); cl->transferSuccessful( file1 ); cl->metaObject()->invokeMethod( cl, "slotFinishCopy", Qt::DirectConnection ); QVERIFY2( cl->count == 0, "Expected no call to remove"); QVERIFY( spy1.wait( 5000 ) ); delete Amarok::Components::setCollectionLocationDelegate( 0 ); cld = new Collections::MockCollectionLocationDelegate(); EXPECT_CALL( *cld, reallyDelete( _, _) ).Times( AnyNumber() ).WillRepeatedly( Return( true ) ); EXPECT_CALL( *cld, errorDeleting( _, _ ) ).Times( AnyNumber() ); Amarok::Components::setCollectionLocationDelegate( cld ); cl = new Collections::TestRemoveCL(); EXPECT_CALL( *cl, isWritable() ).Times( AnyNumber() ).WillRepeatedly( Return( true ) ); QSignalSpy spy2( cl, &Collections::TestRemoveCL::destroyed ); cl->setProperty( "removeSources", true ); cl->count = 0; file1 = Meta::TrackPtr( new MetaMock( map ) ); cl->transferSuccessful( file1 ); cl->transferError( file1, "Test of CollectionLocation" ); cl->metaObject()->invokeMethod( cl, "slotFinishCopy", Qt::DirectConnection ); QVERIFY2( cl->count == 0, "Expected no call to remove after reversed method call"); QVERIFY( spy2.wait( 5000 ) ); delete Amarok::Components::setCollectionLocationDelegate( 0 ); } diff --git a/tests/core/collections/MockCollectionLocationDelegate.h b/tests/core/collections/MockCollectionLocationDelegate.h index 38bad25e3d..a2f4504793 100644 --- a/tests/core/collections/MockCollectionLocationDelegate.h +++ b/tests/core/collections/MockCollectionLocationDelegate.h @@ -1,47 +1,47 @@ /**************************************************************************************** * Copyright (c) 2010 Maximilian Kossick * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #ifndef MOCKCOLLECTIONLOCATIONDELEGATE_H #define MOCKCOLLECTIONLOCATIONDELEGATE_H #include "core/collections/CollectionLocationDelegate.h" #undef kWarning // WORKAROUND: Prevent symbols clash with KDE's kWarning macro -#include +#include namespace Collections { class MockCollectionLocationDelegate : public CollectionLocationDelegate { public: MOCK_CONST_METHOD2( reallyDelete, bool( CollectionLocation *loc, const Meta::TrackList &tracks ) ); MOCK_CONST_METHOD2( reallyMove, bool( CollectionLocation *loc, const Meta::TrackList &tracks ) ); MOCK_CONST_METHOD2( reallyTrash, bool( CollectionLocation *loc, const Meta::TrackList &tracks ) ); MOCK_CONST_METHOD2( errorDeleting, void( CollectionLocation *loc, const Meta::TrackList &tracks ) ); MOCK_CONST_METHOD1( notWriteable, void( CollectionLocation *loc ) ); MOCK_CONST_METHOD1( deleteEmptyDirs, bool( CollectionLocation *loc ) ); MOCK_CONST_METHOD5( transcode, Transcoding::Configuration( const QStringList &playableFileTypes, bool *remember, OperationType operation, const QString &destCollectionName, const Transcoding::Configuration &prevConfiguration ) ); }; } //namespace Collections #endif diff --git a/tests/core/logger/TestLogger.cpp b/tests/core/logger/TestLogger.cpp index b70b8077e0..ec16d401cb 100644 --- a/tests/core/logger/TestLogger.cpp +++ b/tests/core/logger/TestLogger.cpp @@ -1,187 +1,187 @@ /**************************************************************************************** * Copyright (c) 2010 Maximilian Kossick * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #include "TestLogger.h" #include "core/logger/Logger.h" #include "mocks/MockLogger.h" #include #include #include #include -#include +#include QTEST_GUILESS_MAIN( TestLogger ) using ::testing::Return; using ::testing::AnyNumber; using ::testing::_; using ::testing::Mock; class DummyJob : public KJob { public: void start() override {} }; TestLogger::TestLogger() { int argc = 1; char **argv = (char **) malloc(sizeof(char *)); argv[0] = strdup( QCoreApplication::applicationName().toLocal8Bit().data() ); ::testing::InitGoogleMock( &argc, argv ); delete[] argv; } void TestLogger::init() { } void TestLogger::cleanup() { } class ProgressJob : public QObject, public ThreadWeaver::Job { Q_OBJECT public: ProgressJob() : deleteJob( false ), deleteObject( false ) {} void run(ThreadWeaver::JobPointer self, ThreadWeaver::Thread *thread) override { Q_UNUSED(self); Q_UNUSED(thread); KJob *job = new DummyJob(); QObject *obj = new QObject(); Amarok::Logger::newProgressOperation( job, QString( "foo" ), obj ); if( deleteJob ) delete job; if( deleteObject ) delete obj; } bool deleteJob; bool deleteObject; protected: void defaultBegin(const ThreadWeaver::JobPointer& self, ThreadWeaver::Thread *thread) override { Q_EMIT started(self); ThreadWeaver::Job::defaultBegin(self, thread); } void defaultEnd(const ThreadWeaver::JobPointer& self, ThreadWeaver::Thread *thread) override { ThreadWeaver::Job::defaultEnd(self, thread); if (!self->success()) { Q_EMIT failed(self); } Q_EMIT done(self); } Q_SIGNALS: /** This signal is emitted when this job is being processed by a thread. */ void started(ThreadWeaver::JobPointer); /** This signal is emitted when the job has been finished (no matter if it succeeded or not). */ void done(ThreadWeaver::JobPointer); /** This job has failed. * This signal is emitted when success() returns false after the job is executed. */ void failed(ThreadWeaver::JobPointer); }; void TestLogger::testDoNotForwardDeletedJob() { Amarok::MockLogger *mock = new Amarok::MockLogger(); EXPECT_CALL( *mock, newProgressOperationImpl( An(), _, _, _, _ ) ).Times( 0 ); ProgressJob *job = new ProgressJob(); job->deleteJob = true; ThreadWeaver::Queue::instance()->enqueue( QSharedPointer(job) ); QTest::qSleep( 10 ); //ensure that the job has time to run QTest::qWait( 20 ); //give the Logger-internal timer time to fire QVERIFY( Mock::VerifyAndClearExpectations( &mock ) ); delete mock; } void TestLogger::testDoNotForwardDeletedSlot() { Amarok::MockLogger *mock = new Amarok::MockLogger(); EXPECT_CALL( *mock, newProgressOperationImpl( An(), _, nullptr, _, _ ) ).Times( 1 ).WillOnce( Return() ); ProgressJob *job = new ProgressJob(); job->deleteObject = true; ThreadWeaver::Queue::instance()->enqueue( QSharedPointer(job) ); QTest::qSleep( 10 ); //ensure that the job has time to run QTest::qWait( 20 ); //give the Logger-internal timer time to fire QVERIFY( Mock::VerifyAndClearExpectations( &mock ) ); delete mock; } void TestLogger::testForwardLongMessage() { Amarok::MockLogger *mock = new Amarok::MockLogger(); EXPECT_CALL( *mock, longMessageImpl( _, _ ) ).Times( 1 ).WillOnce( Return() ); Amarok::Logger::longMessage( "foo", Amarok::Logger::Information ); QTest::qWait( 20 ); QVERIFY( Mock::VerifyAndClearExpectations( &mock ) ); delete mock; } void TestLogger::testForwardProgressOperation() { Amarok::MockLogger *mock = new Amarok::MockLogger(); EXPECT_CALL( *mock, newProgressOperationImpl( An(), _, _, _, _ ) ).Times( 1 ).WillOnce( Return() ); Amarok::Logger::newProgressOperation( new DummyJob(), QString( "foo" ) ); QTest::qWait( 20 ); QVERIFY( Mock::VerifyAndClearExpectations( &mock ) ); delete mock; } void TestLogger::testForwardShortMessage() { Amarok::MockLogger *mock = new Amarok::MockLogger(); EXPECT_CALL( *mock, shortMessageImpl( _ ) ).Times( 1 ).WillOnce( Return() ); Amarok::Logger::shortMessage( "foo" ); QTest::qWait( 20 ); QVERIFY( Mock::VerifyAndClearExpectations( &mock ) ); delete mock; } #include "TestLogger.moc" diff --git a/tests/importers/ImporterMocks.h b/tests/importers/ImporterMocks.h index ab377db612..c37972e01c 100644 --- a/tests/importers/ImporterMocks.h +++ b/tests/importers/ImporterMocks.h @@ -1,92 +1,92 @@ /**************************************************************************************** * Copyright (c) 2013 Konrad Zemek * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #ifndef IMPORTER_MOCKS_H #define IMPORTER_MOCKS_H #include "importers/ImporterManager.h" #include "importers/ImporterProvider.h" #include "statsyncing/Controller.h" -#include +#include class EngineController; namespace StatSyncing { class Controller; } class MockProvider : public StatSyncing::ImporterProvider { public: MockProvider( const QVariantMap &config, StatSyncing::ImporterManager *manager ); QVariantMap config() const; StatSyncing::ImporterManager *manager() const; MOCK_CONST_METHOD0( reliableTrackMetaData, qint64() ); MOCK_CONST_METHOD0( writableTrackStatsData, qint64() ); MOCK_METHOD0( artists, QSet() ); MOCK_METHOD1( artistTracks, StatSyncing::TrackList(const QString&) ); }; class MockManager : public StatSyncing::ImporterManager { public: MockManager(); StatSyncing::ProviderPtrMap providers(); StatSyncing::ImporterProviderPtr concreteNewInstance( const QVariantMap &cfg ); void providerForgottenProxy( const QString &providerId ); using StatSyncing::ImporterManager::managerConfig; using StatSyncing::ImporterManager::providerConfig; MOCK_CONST_METHOD0( type, QString() ); MOCK_CONST_METHOD0( description, QString() ); MOCK_CONST_METHOD0( prettyName, QString() ); MOCK_CONST_METHOD0( icon, QIcon() ); MOCK_METHOD1( configWidget, StatSyncing::ProviderConfigWidget*(const QVariantMap&) ); MOCK_CONST_METHOD0( pluginInfo, KPluginInfo() ); MOCK_METHOD1( newInstance, StatSyncing::ImporterProviderPtr(const QVariantMap&) ); }; class MockController : public StatSyncing::Controller { public: MockController( QObject *parent = nullptr ); MOCK_METHOD1( registerProvider, void(const StatSyncing::ProviderPtr&) ); MOCK_METHOD1( unregisterProvider, void(const StatSyncing::ProviderPtr&) ); }; class ImporterMocks : public QObject { Q_OBJECT protected: EngineController *m_engineController; MockController *m_mockController; MockManager *m_mockManager; MockProvider *m_mockProvider; private Q_SLOTS: void initTestCase(); void init(); void cleanup(); void cleanupTestCase(); }; #endif // IMPORTER_MOCKS_H diff --git a/tests/mocks/MockAlbum.h b/tests/mocks/MockAlbum.h index 6dad6e1df2..1840ab210c 100644 --- a/tests/mocks/MockAlbum.h +++ b/tests/mocks/MockAlbum.h @@ -1,39 +1,39 @@ /**************************************************************************************** * Copyright (c) 2010 Maximilian Kossick * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #ifndef META_MOCKALBUM_H #define META_MOCKALBUM_H -#include +#include #include "core/meta/Meta.h" namespace Meta { class MockAlbum : public Meta::Album { public: MOCK_CONST_METHOD0( name, QString() ); MOCK_CONST_METHOD0( prettyName, QString() ); MOCK_METHOD0( tracks, Meta::TrackList() ); MOCK_CONST_METHOD0( isCompilation, bool() ); MOCK_CONST_METHOD0( hasAlbumArtist, bool() ); MOCK_CONST_METHOD0( albumArtist, Meta::ArtistPtr() ); }; } #endif diff --git a/tests/mocks/MockArtist.h b/tests/mocks/MockArtist.h index f644458279..37c1236e96 100644 --- a/tests/mocks/MockArtist.h +++ b/tests/mocks/MockArtist.h @@ -1,37 +1,37 @@ /**************************************************************************************** * Copyright (c) 2010 Maximilian Kossick * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #ifndef META_MOCKARTIST_H #define META_MOCKARTIST_H -#include +#include #include "core/meta/Meta.h" namespace Meta { class MockArtist : public Meta::Artist { public: MOCK_CONST_METHOD0( name, QString() ); MOCK_CONST_METHOD0( prettyName, QString() ); MOCK_METHOD0( tracks, Meta::TrackList() ); MOCK_METHOD0( albums, Meta::AlbumList() ); }; } #endif diff --git a/tests/mocks/MockComposer.h b/tests/mocks/MockComposer.h index cbc5db8ec7..c52df45c00 100644 --- a/tests/mocks/MockComposer.h +++ b/tests/mocks/MockComposer.h @@ -1,36 +1,36 @@ /**************************************************************************************** * Copyright (c) 2010 Maximilian Kossick * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #ifndef META_MOCKCOMPOSER_H #define META_MOCKCOMPOSER_H -#include +#include #include "core/meta/Meta.h" namespace Meta { class MockComposer : public Meta::Composer { public: MOCK_CONST_METHOD0( name, QString() ); MOCK_CONST_METHOD0( prettyName, QString() ); MOCK_METHOD0( tracks, Meta::TrackList() ); }; } #endif diff --git a/tests/mocks/MockGenre.h b/tests/mocks/MockGenre.h index 74d6ee31fb..5643531a94 100644 --- a/tests/mocks/MockGenre.h +++ b/tests/mocks/MockGenre.h @@ -1,36 +1,36 @@ /**************************************************************************************** * Copyright (c) 2010 Maximilian Kossick * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #ifndef META_MOCKGENRE_H #define META_MOCKGENRE_H -#include +#include #include "core/meta/Meta.h" namespace Meta { class MockGenre : public Meta::Genre { public: MOCK_CONST_METHOD0( name, QString() ); MOCK_CONST_METHOD0( prettyName, QString() ); MOCK_METHOD0( tracks, Meta::TrackList() ); }; } #endif diff --git a/tests/mocks/MockLogger.h b/tests/mocks/MockLogger.h index cadb8a7098..21dc958c18 100644 --- a/tests/mocks/MockLogger.h +++ b/tests/mocks/MockLogger.h @@ -1,54 +1,54 @@ /**************************************************************************************** * Copyright (c) 2010 Maximilian Kossick * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #ifndef AMAROK_MOCKLOGGER_H #define AMAROK_MOCKLOGGER_H -#include +#include #include "core/logger/Logger.h" using ::testing::Return; using ::testing::An; using ::testing::_; namespace Amarok { class MockLogger : public Amarok::Logger { public: MockLogger() : Amarok::Logger() { ON_CALL( *this, shortMessageImpl( _ ) ).WillByDefault( Return() ); ON_CALL( *this, longMessageImpl( _, _ ) ).WillByDefault( Return() ); ON_CALL( *this, newProgressOperationImpl( An(), _, _, _, _ ) ).WillByDefault( Return() ); ON_CALL( *this, newProgressOperationImpl( An(), _, _, _, _ ) ).WillByDefault( Return() ); ON_CALL( *this, newProgressOperationImpl( An(), _, _, _, _, _, _, _ ) ).WillByDefault( Return() ); } MOCK_METHOD1( shortMessageImpl, void( const QString& ) ); MOCK_METHOD2( longMessageImpl, void( const QString&, Amarok::Logger::MessageType ) ); MOCK_METHOD5( newProgressOperationImpl, void( KJob*, const QString&, QObject*, const std::function&, Qt::ConnectionType ) ); MOCK_METHOD5( newProgressOperationImpl, void( QNetworkReply*, const QString&, QObject*, const std::function&, Qt::ConnectionType ) ); MOCK_METHOD8( newProgressOperationImpl, void( QObject *, const QMetaMethod &, const QMetaMethod &, const QString&, int, QObject*, const std::function&, Qt::ConnectionType ) ); }; } #endif diff --git a/tests/mocks/MockTrack.h b/tests/mocks/MockTrack.h index 43f241f25b..5f9a4e3049 100644 --- a/tests/mocks/MockTrack.h +++ b/tests/mocks/MockTrack.h @@ -1,80 +1,80 @@ /**************************************************************************************** * Copyright (c) 2010 Maximilian Kossick * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #ifndef META_MOCKTRACK_H #define META_MOCKTRACK_H #undef kWarning // WORKAROUND: Prevent symbols clash with KDE's kWarning macro -#include +#include #include "core/meta/Meta.h" using ::testing::Return; namespace Meta { class MockTrack : public Meta::Track { public: MockTrack() : Meta::Track() { ON_CALL( *this, name() ).WillByDefault( Return( "" ) ); ON_CALL( *this, notPlayableReason() ).WillByDefault( Return( QString() ) ); ON_CALL( *this, artist() ).WillByDefault( Return( Meta::ArtistPtr() ) ); ON_CALL( *this, album() ).WillByDefault( Return( Meta::AlbumPtr() ) ); ON_CALL( *this, genre() ).WillByDefault( Return( Meta::GenrePtr() ) ); ON_CALL( *this, year() ).WillByDefault( Return( Meta::YearPtr() ) ); ON_CALL( *this, composer() ).WillByDefault( Return( Meta::ComposerPtr() ) ); } MOCK_CONST_METHOD0( name, QString() ); MOCK_CONST_METHOD0( prettyName, QString() ); MOCK_CONST_METHOD0( playableUrl, QUrl() ); MOCK_CONST_METHOD0( prettyUrl, QString() ); MOCK_CONST_METHOD0( uidUrl, QString() ); MOCK_CONST_METHOD0( notPlayableReason, QString() ); MOCK_CONST_METHOD0( album, Meta::AlbumPtr() ); MOCK_CONST_METHOD0( artist, Meta::ArtistPtr() ); MOCK_CONST_METHOD0( composer, Meta::ComposerPtr() ); MOCK_CONST_METHOD0( genre, Meta::GenrePtr() ); MOCK_CONST_METHOD0( year, Meta::YearPtr() ); MOCK_CONST_METHOD0( bpm, qreal() ); MOCK_CONST_METHOD0( comment, QString() ); MOCK_CONST_METHOD0( score, double() ); MOCK_METHOD1( setScore, void(double score) ); MOCK_CONST_METHOD0( rating, int() ); MOCK_METHOD1( setRating, void(int rating) ); MOCK_CONST_METHOD0( length, qint64() ); MOCK_CONST_METHOD0( filesize, int() ); MOCK_CONST_METHOD0( sampleRate, int() ); MOCK_CONST_METHOD0( bitrate, int() ); MOCK_CONST_METHOD0( createDate, QDateTime() ); MOCK_CONST_METHOD0( trackNumber, int() ); MOCK_CONST_METHOD0( discNumber, int() ); MOCK_CONST_METHOD0( lastPlayed, QDateTime() ); MOCK_CONST_METHOD0( firstPlayed, QDateTime() ); MOCK_CONST_METHOD0( playCount, int() ); MOCK_CONST_METHOD1( replayGain, qreal(Meta::ReplayGainTag mode) ); MOCK_CONST_METHOD0( type, QString() ); MOCK_METHOD0( prepareToPlay, void() ); MOCK_METHOD1( finishedPlaying, void( double playedFraction ) ); MOCK_CONST_METHOD0( inCollection, bool() ); MOCK_CONST_METHOD0( collection, Collections::Collection*() ); MOCK_CONST_METHOD0( cachedLyrics, QString() ); }; } #endif diff --git a/tests/mocks/MockYear.h b/tests/mocks/MockYear.h index 0329e13852..0ec85c6742 100644 --- a/tests/mocks/MockYear.h +++ b/tests/mocks/MockYear.h @@ -1,36 +1,36 @@ /**************************************************************************************** * Copyright (c) 2010 Maximilian Kossick * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #ifndef META_MOCKYEAR_H #define META_MOCKYEAR_H -#include +#include #include "core/meta/Meta.h" namespace Meta { class MockYear : public Meta::Year { public: MOCK_CONST_METHOD0( name, QString() ); MOCK_CONST_METHOD0( prettyName, QString() ); MOCK_METHOD0( tracks, Meta::TrackList() ); }; } #endif diff --git a/tests/synchronization/TestMasterSlaveSynchronizationJob.cpp b/tests/synchronization/TestMasterSlaveSynchronizationJob.cpp index 8ec37d6ce7..3088364e85 100644 --- a/tests/synchronization/TestMasterSlaveSynchronizationJob.cpp +++ b/tests/synchronization/TestMasterSlaveSynchronizationJob.cpp @@ -1,453 +1,453 @@ /**************************************************************************************** * Copyright (c) 2010 Maximilian Kossick * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #include "TestMasterSlaveSynchronizationJob.h" #include "core/support/Debug.h" #include "core/collections/CollectionLocation.h" #include "core/collections/CollectionLocationDelegate.h" #include "core/support/Components.h" #include "synchronization/MasterSlaveSynchronizationJob.h" #include "CollectionTestImpl.h" #include "core/collections/MockCollectionLocationDelegate.h" #include "mocks/MockTrack.h" #include "mocks/MockAlbum.h" #include "mocks/MockArtist.h" -#include +#include #include QTEST_GUILESS_MAIN( TestMasterSlaveSynchronizationJob ) using ::testing::Return; using ::testing::AnyNumber; using ::testing::_; static int trackCopyCount; static int trackRemoveCount; namespace Collections { class MyCollectionLocation : public CollectionLocation { public: Collections::CollectionTestImpl *coll; QString prettyLocation() const override { return "foo"; } bool isWritable() const override { return true; } void removeUrlsFromCollection( const Meta::TrackList &sources ) override { trackRemoveCount += sources.count(); coll->mc->acquireWriteLock(); TrackMap map = coll->mc->trackMap(); foreach( const Meta::TrackPtr &track, sources ) map.remove( track->uidUrl() ); coll->mc->setTrackMap( map ); coll->mc->releaseLock(); slotRemoveOperationFinished(); } void copyUrlsToCollection(const QMap &sources, const Transcoding::Configuration& conf) override { Q_UNUSED( conf ) trackCopyCount = sources.count(); foreach( const Meta::TrackPtr &track, sources.keys() ) { coll->mc->addTrack( track ); } } }; class MyCollectionTestImpl : public CollectionTestImpl { public: MyCollectionTestImpl( const QString &id ) : CollectionTestImpl( id ) {} CollectionLocation* location() override { MyCollectionLocation *r = new MyCollectionLocation(); r->coll = this; return r; } }; } //namespace Collections void addMockTrack( Collections::CollectionTestImpl *coll, const QString &trackName, const QString &artistName, const QString &albumName ) { Meta::MockTrack *track = new Meta::MockTrack(); ::testing::Mock::AllowLeak( track ); Meta::TrackPtr trackPtr( track ); EXPECT_CALL( *track, name() ).Times( AnyNumber() ).WillRepeatedly( Return( trackName ) ); EXPECT_CALL( *track, uidUrl() ).Times( AnyNumber() ).WillRepeatedly( Return( trackName + '_' + artistName + '_' + albumName ) ); EXPECT_CALL( *track, playableUrl() ).Times( AnyNumber() ).WillRepeatedly( Return( QUrl( '/' + track->uidUrl() ) ) ); coll->mc->addTrack( trackPtr ); Meta::AlbumPtr albumPtr = coll->mc->albumMap().value( albumName, QString() /* no album artist */ ); Meta::MockAlbum *album; Meta::TrackList albumTracks; if( albumPtr ) { album = dynamic_cast( albumPtr.data() ); if( !album ) { QFAIL( "expected a Meta::MockAlbum" ); return; } albumTracks = albumPtr->tracks(); } else { album = new Meta::MockAlbum(); ::testing::Mock::AllowLeak( album ); albumPtr = Meta::AlbumPtr( album ); EXPECT_CALL( *album, name() ).Times( AnyNumber() ).WillRepeatedly( Return( albumName ) ); EXPECT_CALL( *album, hasAlbumArtist() ).Times( AnyNumber() ).WillRepeatedly( Return( false ) ); EXPECT_CALL( *album, albumArtist() ).Times( AnyNumber() ).WillRepeatedly( Return( Meta::ArtistPtr() ) ); coll->mc->addAlbum( albumPtr ); } albumTracks << trackPtr; EXPECT_CALL( *album, tracks() ).Times( AnyNumber() ).WillRepeatedly( Return( albumTracks ) ); EXPECT_CALL( *track, album() ).Times( AnyNumber() ).WillRepeatedly( Return( albumPtr ) ); Meta::ArtistPtr artistPtr = coll->mc->artistMap().value( artistName ); Meta::MockArtist *artist; Meta::TrackList artistTracks; if( artistPtr ) { artist = dynamic_cast( artistPtr.data() ); if( !artist ) { QFAIL( "expected a Meta::MockArtist" ); return; } artistTracks = artistPtr->tracks(); } else { artist = new Meta::MockArtist(); ::testing::Mock::AllowLeak( artist ); artistPtr = Meta::ArtistPtr( artist ); EXPECT_CALL( *artist, name() ).Times( AnyNumber() ).WillRepeatedly( Return( artistName ) ); coll->mc->addArtist( artistPtr ); } artistTracks << trackPtr; EXPECT_CALL( *artist, tracks() ).Times( AnyNumber() ).WillRepeatedly( Return( artistTracks ) ); EXPECT_CALL( *track, artist() ).Times( AnyNumber() ).WillRepeatedly( Return( artistPtr ) ); } TestMasterSlaveSynchronizationJob::TestMasterSlaveSynchronizationJob() { int argc = 1; char **argv = (char **) malloc(sizeof(char *)); argv[0] = strdup( QCoreApplication::applicationName().toLocal8Bit().data() ); ::testing::InitGoogleMock( &argc, argv ); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); } void TestMasterSlaveSynchronizationJob::init() { trackCopyCount = 0; trackRemoveCount = 0; } void TestMasterSlaveSynchronizationJob::testAddTracksToEmptySlave() { Collections::CollectionTestImpl *master = new Collections::MyCollectionTestImpl( "master" ); Collections::CollectionTestImpl *slave = new Collections::MyCollectionTestImpl( "slave" ); //setup master addMockTrack( master, "track1", "artist1", "album1" ); QCOMPARE( master->mc->trackMap().count(), 1 ); QCOMPARE( slave->mc->trackMap().count(), 0 ); QCOMPARE( trackCopyCount, 0 ); QCOMPARE( trackRemoveCount, 0 ); MasterSlaveSynchronizationJob *job = new MasterSlaveSynchronizationJob(); QSignalSpy spy( job, &MasterSlaveSynchronizationJob::destroyed ); job->setMaster( master ); job->setSlave( slave ); job->synchronize(); spy.wait( 1000 ); QCOMPARE( trackCopyCount, 1 ); QCOMPARE( trackRemoveCount, 0 ); QCOMPARE( master->mc->trackMap().count(), 1 ); QCOMPARE( slave->mc->trackMap().count(), 1 ); delete master; delete slave; } void TestMasterSlaveSynchronizationJob::testAddSingleTrack() { Collections::CollectionTestImpl *master = new Collections::MyCollectionTestImpl( "master" ); Collections::CollectionTestImpl *slave = new Collections::MyCollectionTestImpl( "slave" ); //setup addMockTrack( master, "track1", "artist1", "album1" ); addMockTrack( slave, "track1", "artist1", "album1" ); addMockTrack( master, "track2", "artist1", "album1" ); QCOMPARE( master->mc->trackMap().count(), 2 ); QCOMPARE( slave->mc->trackMap().count(), 1 ); QCOMPARE( trackCopyCount, 0 ); QCOMPARE( trackRemoveCount, 0 ); //test MasterSlaveSynchronizationJob *job = new MasterSlaveSynchronizationJob(); QSignalSpy spy( job, &MasterSlaveSynchronizationJob::destroyed ); job->setMaster( master ); job->setSlave( slave ); job->synchronize(); spy.wait( 1000 ); //verify QCOMPARE( trackCopyCount, 1 ); QCOMPARE( trackRemoveCount, 0 ); QCOMPARE( master->mc->trackMap().count(), 2 ); QCOMPARE( slave->mc->trackMap().count(), 2 ); delete master; delete slave; } void TestMasterSlaveSynchronizationJob::testAddAlbum() { Collections::CollectionTestImpl *master = new Collections::MyCollectionTestImpl( "master" ); Collections::CollectionTestImpl *slave = new Collections::MyCollectionTestImpl( "slave" ); //setup addMockTrack( master, "track1", "artist1", "album1" ); addMockTrack( slave, "track1", "artist1", "album1" ); addMockTrack( master, "track1", "artist1", "album2" ); QCOMPARE( master->mc->trackMap().count(), 2 ); QCOMPARE( slave->mc->trackMap().count(), 1 ); QCOMPARE( trackCopyCount, 0 ); QCOMPARE( trackRemoveCount, 0 ); //test MasterSlaveSynchronizationJob *job = new MasterSlaveSynchronizationJob(); QSignalSpy spy( job, &MasterSlaveSynchronizationJob::destroyed ); job->setMaster( master ); job->setSlave( slave ); job->synchronize(); spy.wait( 1000 ); //verify QCOMPARE( trackCopyCount, 1 ); QCOMPARE( trackRemoveCount, 0 ); QCOMPARE( master->mc->trackMap().count(), 2 ); QCOMPARE( slave->mc->trackMap().count(), 2 ); delete master; delete slave; } void TestMasterSlaveSynchronizationJob::testAddArtist() { Collections::CollectionTestImpl *master = new Collections::MyCollectionTestImpl( "master" ); Collections::CollectionTestImpl *slave = new Collections::MyCollectionTestImpl( "slave" ); //setup addMockTrack( master, "track1", "artist1", "album1" ); addMockTrack( slave, "track1", "artist1", "album1" ); addMockTrack( master, "track1", "artist2", "album1" ); QCOMPARE( master->mc->trackMap().count(), 2 ); QCOMPARE( slave->mc->trackMap().count(), 1 ); QCOMPARE( trackCopyCount, 0 ); QCOMPARE( trackRemoveCount, 0 ); //test MasterSlaveSynchronizationJob *job = new MasterSlaveSynchronizationJob(); QSignalSpy spy( job, &MasterSlaveSynchronizationJob::destroyed ); job->setMaster( master ); job->setSlave( slave ); job->synchronize(); spy.wait( 1000 ); //verify QCOMPARE( trackCopyCount, 1 ); QCOMPARE( trackRemoveCount, 0 ); QCOMPARE( master->mc->trackMap().count(), 2 ); QCOMPARE( slave->mc->trackMap().count(), 2 ); delete master; delete slave; } void TestMasterSlaveSynchronizationJob::testRemoveSingleTrack() { Collections::CollectionTestImpl *master = new Collections::MyCollectionTestImpl( "master" ); Collections::CollectionTestImpl *slave = new Collections::MyCollectionTestImpl( "slave" ); Collections::MockCollectionLocationDelegate *delegate = new Collections::MockCollectionLocationDelegate(); EXPECT_CALL( *delegate, reallyDelete( _, _) ).Times( AnyNumber() ).WillRepeatedly( Return( true ) ); Amarok::Components::setCollectionLocationDelegate( delegate ); //setup addMockTrack( master, "track1", "artist1", "album1" ); addMockTrack( slave, "track1", "artist1", "album1" ); addMockTrack( slave, "track2", "artist1", "album1" ); QCOMPARE( master->mc->trackMap().count(), 1 ); QCOMPARE( slave->mc->trackMap().count(), 2 ); QCOMPARE( trackCopyCount, 0 ); QCOMPARE( trackRemoveCount, 0 ); //test MasterSlaveSynchronizationJob *job = new MasterSlaveSynchronizationJob(); QSignalSpy spy( job, &MasterSlaveSynchronizationJob::destroyed ); job->setMaster( master ); job->setSlave( slave ); job->synchronize(); spy.wait( 1000 ); //verify QCOMPARE( trackCopyCount, 0 ); QCOMPARE( trackRemoveCount, 1 ); QCOMPARE( master->mc->trackMap().count(), 1 ); QCOMPARE( slave->mc->trackMap().count(), 1 ); delete master; delete slave; delete Amarok::Components::setCollectionLocationDelegate( 0 ); } void TestMasterSlaveSynchronizationJob::testRemoveAlbum() { Collections::CollectionTestImpl *master = new Collections::MyCollectionTestImpl( "master" ); Collections::CollectionTestImpl *slave = new Collections::MyCollectionTestImpl( "slave" ); Collections::MockCollectionLocationDelegate *delegate = new Collections::MockCollectionLocationDelegate(); EXPECT_CALL( *delegate, reallyDelete( _, _) ).Times( AnyNumber() ).WillRepeatedly( Return( true ) ); Amarok::Components::setCollectionLocationDelegate( delegate ); //setup addMockTrack( master, "track1", "artist1", "album1" ); addMockTrack( slave, "track1", "artist1", "album1" ); addMockTrack( slave, "track1", "artist1", "album2" ); QCOMPARE( master->mc->trackMap().count(), 1 ); QCOMPARE( slave->mc->trackMap().count(), 2 ); QCOMPARE( trackCopyCount, 0 ); QCOMPARE( trackRemoveCount, 0 ); //test MasterSlaveSynchronizationJob *job = new MasterSlaveSynchronizationJob(); QSignalSpy spy( job, &MasterSlaveSynchronizationJob::destroyed ); job->setMaster( master ); job->setSlave( slave ); job->synchronize(); spy.wait( 1000 ); //verify QCOMPARE( trackCopyCount, 0 ); QCOMPARE( trackRemoveCount, 1 ); QCOMPARE( master->mc->trackMap().count(), 1 ); QCOMPARE( slave->mc->trackMap().count(), 1 ); delete master; delete slave; delete Amarok::Components::setCollectionLocationDelegate( 0 ); } void TestMasterSlaveSynchronizationJob::testRemoveArtist() { Collections::CollectionTestImpl *master = new Collections::MyCollectionTestImpl( "master" ); Collections::CollectionTestImpl *slave = new Collections::MyCollectionTestImpl( "slave" ); Collections::MockCollectionLocationDelegate *delegate = new Collections::MockCollectionLocationDelegate(); EXPECT_CALL( *delegate, reallyDelete( _, _) ).Times( AnyNumber() ).WillRepeatedly( Return( true ) ); Amarok::Components::setCollectionLocationDelegate( delegate ); //setup addMockTrack( master, "track1", "artist1", "album1" ); addMockTrack( slave, "track1", "artist1", "album1" ); addMockTrack( slave, "track1", "artist2", "album1" ); QCOMPARE( master->mc->trackMap().count(), 1 ); QCOMPARE( slave->mc->trackMap().count(), 2 ); QCOMPARE( trackCopyCount, 0 ); QCOMPARE( trackRemoveCount, 0 ); //test MasterSlaveSynchronizationJob *job = new MasterSlaveSynchronizationJob(); QSignalSpy spy( job, &MasterSlaveSynchronizationJob::destroyed ); job->setMaster( master ); job->setSlave( slave ); job->synchronize(); spy.wait( 1000 ); //verify QCOMPARE( trackCopyCount, 0 ); QCOMPARE( trackRemoveCount, 1 ); QCOMPARE( master->mc->trackMap().count(), 1 ); QCOMPARE( slave->mc->trackMap().count(), 1 ); delete master; delete slave; delete Amarok::Components::setCollectionLocationDelegate( 0 ); } void TestMasterSlaveSynchronizationJob::testEmptyMaster() { Collections::CollectionTestImpl *master = new Collections::MyCollectionTestImpl( "master" ); Collections::CollectionTestImpl *slave = new Collections::MyCollectionTestImpl( "slave" ); Collections::MockCollectionLocationDelegate *delegate = new Collections::MockCollectionLocationDelegate(); EXPECT_CALL( *delegate, reallyDelete( _, _) ).Times( AnyNumber() ).WillRepeatedly( Return( true ) ); Amarok::Components::setCollectionLocationDelegate( delegate ); //setup master addMockTrack( slave, "track1", "artist1", "album1" ); QCOMPARE( master->mc->trackMap().count(), 0 ); QCOMPARE( slave->mc->trackMap().count(), 1 ); QCOMPARE( trackCopyCount, 0 ); QCOMPARE( trackRemoveCount, 0 ); MasterSlaveSynchronizationJob *job = new MasterSlaveSynchronizationJob(); QSignalSpy spy( job, &MasterSlaveSynchronizationJob::destroyed ); job->setMaster( master ); job->setSlave( slave ); job->synchronize(); spy.wait( 1000 ); QCOMPARE( trackCopyCount, 0 ); QCOMPARE( trackRemoveCount, 1 ); QCOMPARE( master->mc->trackMap().count(), 0 ); QCOMPARE( slave->mc->trackMap().count(), 0 ); delete master; delete slave; delete Amarok::Components::setCollectionLocationDelegate( 0 ); } diff --git a/tests/synchronization/TestOneWaySynchronizationJob.cpp b/tests/synchronization/TestOneWaySynchronizationJob.cpp index c842f75303..a9a6061c13 100644 --- a/tests/synchronization/TestOneWaySynchronizationJob.cpp +++ b/tests/synchronization/TestOneWaySynchronizationJob.cpp @@ -1,331 +1,331 @@ /**************************************************************************************** * Copyright (c) 2010 Maximilian Kossick * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #include "TestOneWaySynchronizationJob.h" #include "core/support/Debug.h" #include "core/collections/CollectionLocation.h" #include "synchronization/OneWaySynchronizationJob.h" #include "CollectionTestImpl.h" #include "mocks/MockTrack.h" #include "mocks/MockAlbum.h" #include "mocks/MockArtist.h" -#include +#include #include QTEST_GUILESS_MAIN( TestOneWaySynchronizationJob ) using ::testing::Return; using ::testing::AnyNumber; static int trackCopyCount; namespace Collections { class MyCollectionLocation : public CollectionLocation { public: Collections::CollectionTestImpl *coll; QString prettyLocation() const override { return "foo"; } bool isWritable() const override { return true; } void copyUrlsToCollection(const QMap &sources, const Transcoding::Configuration& conf) override { Q_UNUSED( conf ) // qDebug() << "adding " << sources.count() << " tracks to " << coll->collectionId(); trackCopyCount = sources.count(); foreach( const Meta::TrackPtr &track, sources.keys() ) { coll->mc->addTrack( track ); } } }; class MyCollectionTestImpl : public CollectionTestImpl { public: MyCollectionTestImpl( const QString &id ) : CollectionTestImpl( id ) {} CollectionLocation* location() override { MyCollectionLocation *r = new MyCollectionLocation(); r->coll = this; return r; } }; } //namespace Collections void addMockTrack( Collections::CollectionTestImpl *coll, const QString &trackName, const QString &artistName, const QString &albumName ) { Meta::MockTrack *track = new Meta::MockTrack(); ::testing::Mock::AllowLeak( track ); Meta::TrackPtr trackPtr( track ); EXPECT_CALL( *track, name() ).Times( AnyNumber() ).WillRepeatedly( Return( trackName ) ); EXPECT_CALL( *track, uidUrl() ).Times( AnyNumber() ).WillRepeatedly( Return( trackName + '_' + artistName + '_' + albumName ) ); EXPECT_CALL( *track, playableUrl() ).Times( AnyNumber() ).WillRepeatedly( Return( QUrl( '/' + track->uidUrl() ) ) ); EXPECT_CALL( *track, composer() ).Times( AnyNumber() ).WillRepeatedly( Return( Meta::ComposerPtr() ) ); EXPECT_CALL( *track, genre() ).Times( AnyNumber() ).WillRepeatedly( Return( Meta::GenrePtr() ) ); EXPECT_CALL( *track, year() ).Times( AnyNumber() ).WillRepeatedly( Return( Meta::YearPtr() ) ); coll->mc->addTrack( trackPtr ); Meta::AlbumPtr albumPtr = coll->mc->albumMap().value( albumName, QString() /* no album artist */ ); Meta::MockAlbum *album; Meta::TrackList albumTracks; if( albumPtr ) { album = dynamic_cast( albumPtr.data() ); if( !album ) { QFAIL( "expected a Meta::MockAlbum" ); return; } albumTracks = albumPtr->tracks(); } else { album = new Meta::MockAlbum(); ::testing::Mock::AllowLeak( album ); albumPtr = Meta::AlbumPtr( album ); EXPECT_CALL( *album, name() ).Times( AnyNumber() ).WillRepeatedly( Return( albumName ) ); EXPECT_CALL( *album, hasAlbumArtist() ).Times( AnyNumber() ).WillRepeatedly( Return( false ) ); EXPECT_CALL( *album, albumArtist() ).Times( AnyNumber() ).WillRepeatedly( Return( Meta::ArtistPtr() ) ); coll->mc->addAlbum( albumPtr ); } albumTracks << trackPtr; EXPECT_CALL( *album, tracks() ).Times( AnyNumber() ).WillRepeatedly( Return( albumTracks ) ); EXPECT_CALL( *track, album() ).Times( AnyNumber() ).WillRepeatedly( Return( albumPtr ) ); Meta::ArtistPtr artistPtr = coll->mc->artistMap().value( artistName ); Meta::MockArtist *artist; Meta::TrackList artistTracks; if( artistPtr ) { artist = dynamic_cast( artistPtr.data() ); if( !artist ) { QFAIL( "expected a Meta::MockArtist" ); return; } artistTracks = artistPtr->tracks(); } else { artist = new Meta::MockArtist(); ::testing::Mock::AllowLeak( artist ); artistPtr = Meta::ArtistPtr( artist ); EXPECT_CALL( *artist, name() ).Times( AnyNumber() ).WillRepeatedly( Return( artistName ) ); coll->mc->addArtist( artistPtr ); } artistTracks << trackPtr; EXPECT_CALL( *artist, tracks() ).Times( AnyNumber() ).WillRepeatedly( Return( artistTracks ) ); EXPECT_CALL( *track, artist() ).Times( AnyNumber() ).WillRepeatedly( Return( artistPtr ) ); EXPECT_CALL( *album, albumArtist() ).Times( AnyNumber() ).WillRepeatedly( Return( artistPtr ) ); } TestOneWaySynchronizationJob::TestOneWaySynchronizationJob() : QObject() { int argc = 1; char **argv = (char **) malloc(sizeof(char *)); argv[0] = strdup( QCoreApplication::applicationName().toLocal8Bit().data() ); ::testing::InitGoogleMock( &argc, argv ); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); } void TestOneWaySynchronizationJob::init() { trackCopyCount = 0; } void TestOneWaySynchronizationJob::testAddTrackToTarget() { Collections::CollectionTestImpl *source = new Collections::MyCollectionTestImpl( "source" ); Collections::CollectionTestImpl *target = new Collections::MyCollectionTestImpl( "target" ); addMockTrack( source, "track1", "artist1", "album1" ); addMockTrack( source, "track2", "artist1", "album1" ); addMockTrack( target, "track1", "artist1", "album1" ); QCOMPARE( trackCopyCount, 0 ); QCOMPARE( source->mc->trackMap().count(), 2 ); QCOMPARE( target->mc->trackMap().count(), 1 ); OneWaySynchronizationJob *job = new OneWaySynchronizationJob(); QSignalSpy spy( job, &OneWaySynchronizationJob::destroyed ); job->setSource( source ); job->setTarget( target ); job->synchronize(); spy.wait( 1000 ); QCOMPARE( trackCopyCount, 1 ); QCOMPARE( source->mc->trackMap().count(), 2 ); QCOMPARE( target->mc->trackMap().count(), 2 ); delete source, delete target; } void TestOneWaySynchronizationJob::testAddAlbumToTarget() { Collections::CollectionTestImpl *source = new Collections::MyCollectionTestImpl( "source" ); Collections::CollectionTestImpl *target = new Collections::MyCollectionTestImpl( "target" ); addMockTrack( source, "track1", "artist1", "album1" ); addMockTrack( source, "track1", "artist1", "album2" ); addMockTrack( target, "track1", "artist1", "album1" ); QCOMPARE( trackCopyCount, 0 ); QCOMPARE( source->mc->trackMap().count(), 2 ); QCOMPARE( target->mc->trackMap().count(), 1 ); OneWaySynchronizationJob *job = new OneWaySynchronizationJob(); QSignalSpy spy( job, &OneWaySynchronizationJob::destroyed ); job->setSource( source ); job->setTarget( target ); job->synchronize(); spy.wait( 1000 ); QCOMPARE( trackCopyCount, 1 ); QCOMPARE( source->mc->trackMap().count(), 2 ); QCOMPARE( target->mc->trackMap().count(), 2 ); delete source, delete target; } void TestOneWaySynchronizationJob::testAddArtistToTarget() { Collections::CollectionTestImpl *source = new Collections::MyCollectionTestImpl( "source" ); Collections::CollectionTestImpl *target = new Collections::MyCollectionTestImpl( "target" ); addMockTrack( source, "track1", "artist1", "album1" ); addMockTrack( source, "track1", "artist2", "album1" ); addMockTrack( target, "track1", "artist1", "album1" ); QCOMPARE( trackCopyCount, 0 ); QCOMPARE( source->mc->trackMap().count(), 2 ); QCOMPARE( target->mc->trackMap().count(), 1 ); OneWaySynchronizationJob *job = new OneWaySynchronizationJob(); QSignalSpy spy( job, &OneWaySynchronizationJob::destroyed ); job->setSource( source ); job->setTarget( target ); job->synchronize(); spy.wait( 1000 ); QCOMPARE( trackCopyCount, 1 ); QCOMPARE( source->mc->trackMap().count(), 2 ); QCOMPARE( target->mc->trackMap().count(), 2 ); delete source, delete target; } void TestOneWaySynchronizationJob::testEmptyTarget() { Collections::CollectionTestImpl *source = new Collections::MyCollectionTestImpl( "source" ); Collections::CollectionTestImpl *target = new Collections::MyCollectionTestImpl( "target" ); addMockTrack( source, "track1", "artist1", "album1" ); addMockTrack( source, "track2", "artist1", "album1" ); QCOMPARE( trackCopyCount, 0 ); QCOMPARE( source->mc->trackMap().count(), 2 ); QCOMPARE( target->mc->trackMap().count(), 0 ); OneWaySynchronizationJob *job = new OneWaySynchronizationJob(); QSignalSpy spy( job, &OneWaySynchronizationJob::destroyed ); job->setSource( source ); job->setTarget( target ); job->synchronize(); spy.wait( 1000 ); QCOMPARE( trackCopyCount, 2 ); QCOMPARE( source->mc->trackMap().count(), 2 ); QCOMPARE( target->mc->trackMap().count(), 2 ); delete source, delete target; } void TestOneWaySynchronizationJob::testEmptySourceWithNonEmptyTarget() { Collections::CollectionTestImpl *source = new Collections::MyCollectionTestImpl( "source" ); Collections::CollectionTestImpl *target = new Collections::MyCollectionTestImpl( "target" ); addMockTrack( target, "track1", "artist1", "album1" ); QCOMPARE( trackCopyCount, 0 ); QCOMPARE( source->mc->trackMap().count(), 0 ); QCOMPARE( target->mc->trackMap().count(), 1 ); OneWaySynchronizationJob *job = new OneWaySynchronizationJob(); QSignalSpy spy( job, &OneWaySynchronizationJob::destroyed ); job->setSource( source ); job->setTarget( target ); job->synchronize(); spy.wait( 1000 ); QCOMPARE( trackCopyCount, 0 ); QCOMPARE( source->mc->trackMap().count(), 0 ); QCOMPARE( target->mc->trackMap().count(), 1 ); delete source, delete target; } void TestOneWaySynchronizationJob::testNoActionNecessary() { Collections::CollectionTestImpl *source = new Collections::MyCollectionTestImpl( "source" ); Collections::CollectionTestImpl *target = new Collections::MyCollectionTestImpl( "target" ); addMockTrack( source, "track1", "artist1", "album1" ); addMockTrack( source, "track2", "artist1", "album1" ); addMockTrack( target, "track1", "artist1", "album1" ); addMockTrack( target, "track2", "artist1", "album1" ); QCOMPARE( trackCopyCount, 0 ); QCOMPARE( source->mc->trackMap().count(), 2 ); QCOMPARE( target->mc->trackMap().count(), 2 ); OneWaySynchronizationJob *job = new OneWaySynchronizationJob(); QSignalSpy spy( job, &OneWaySynchronizationJob::destroyed ); job->setSource( source ); job->setTarget( target ); job->synchronize(); spy.wait( 1000 ); QCOMPARE( trackCopyCount, 0 ); QCOMPARE( source->mc->trackMap().count(), 2 ); QCOMPARE( target->mc->trackMap().count(), 2 ); delete source, delete target; } diff --git a/tests/synchronization/TestUnionJob.cpp b/tests/synchronization/TestUnionJob.cpp index f4e858c0f6..a61e1f2355 100644 --- a/tests/synchronization/TestUnionJob.cpp +++ b/tests/synchronization/TestUnionJob.cpp @@ -1,268 +1,268 @@ /**************************************************************************************** * Copyright (c) 2010 Maximilian Kossick * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #include "TestUnionJob.h" #include "core/support/Debug.h" #include "core/collections/CollectionLocation.h" #include "synchronization/UnionJob.h" #include "CollectionTestImpl.h" #include "mocks/MockTrack.h" #include "mocks/MockAlbum.h" #include "mocks/MockArtist.h" #include #include -#include +#include QTEST_GUILESS_MAIN( TestUnionJob ) using ::testing::Return; using ::testing::AnyNumber; static QList trackCopyCount; namespace Collections { class MyCollectionLocation : public CollectionLocation { public: Collections::CollectionTestImpl *coll; QString prettyLocation() const override { return "foo"; } bool isWritable() const override { return true; } bool remove( const Meta::TrackPtr &track ) { coll->mc->acquireWriteLock(); //theoretically we should clean up the other maps as well... TrackMap map = coll->mc->trackMap(); map.remove( track->uidUrl() ); coll->mc->setTrackMap( map ); coll->mc->releaseLock(); return true; } void copyUrlsToCollection(const QMap &sources, const Transcoding::Configuration& conf) override { Q_UNUSED( conf ) trackCopyCount << sources.count(); foreach( const Meta::TrackPtr &track, sources.keys() ) { coll->mc->addTrack( track ); } } }; class MyCollectionTestImpl : public CollectionTestImpl { public: MyCollectionTestImpl( const QString &id ) : CollectionTestImpl( id ) {} CollectionLocation* location() override { MyCollectionLocation *r = new MyCollectionLocation(); r->coll = this; return r; } }; } //namespace Collections void addMockTrack( Collections::CollectionTestImpl *coll, const QString &trackName, const QString &artistName, const QString &albumName ) { Meta::MockTrack *track = new Meta::MockTrack(); ::testing::Mock::AllowLeak( track ); Meta::TrackPtr trackPtr( track ); EXPECT_CALL( *track, name() ).Times( AnyNumber() ).WillRepeatedly( Return( trackName ) ); EXPECT_CALL( *track, uidUrl() ).Times( AnyNumber() ).WillRepeatedly( Return( trackName + '_' + artistName + '_' + albumName ) ); EXPECT_CALL( *track, playableUrl() ).Times( AnyNumber() ).WillRepeatedly( Return( QUrl( '/' + track->uidUrl() ) ) ); coll->mc->addTrack( trackPtr ); Meta::AlbumPtr albumPtr = coll->mc->albumMap().value( albumName, QString() /* no album artist */ ); Meta::MockAlbum *album; Meta::TrackList albumTracks; if( albumPtr ) { album = dynamic_cast( albumPtr.data() ); if( !album ) { QFAIL( "expected a Meta::MockAlbum" ); return; } albumTracks = albumPtr->tracks(); } else { album = new Meta::MockAlbum(); ::testing::Mock::AllowLeak( album ); albumPtr = Meta::AlbumPtr( album ); EXPECT_CALL( *album, name() ).Times( AnyNumber() ).WillRepeatedly( Return( albumName ) ); EXPECT_CALL( *album, hasAlbumArtist() ).Times( AnyNumber() ).WillRepeatedly( Return( false ) ); EXPECT_CALL( *album, albumArtist() ).Times( AnyNumber() ).WillRepeatedly( Return( Meta::ArtistPtr() ) ); coll->mc->addAlbum( albumPtr ); } albumTracks << trackPtr; EXPECT_CALL( *album, tracks() ).Times( AnyNumber() ).WillRepeatedly( Return( albumTracks ) ); EXPECT_CALL( *track, album() ).Times( AnyNumber() ).WillRepeatedly( Return( albumPtr ) ); Meta::ArtistPtr artistPtr = coll->mc->artistMap().value( artistName ); Meta::MockArtist *artist; Meta::TrackList artistTracks; if( artistPtr ) { artist = dynamic_cast( artistPtr.data() ); if( !artist ) { QFAIL( "expected a Meta::MockArtist" ); return; } artistTracks = artistPtr->tracks(); } else { artist = new Meta::MockArtist(); ::testing::Mock::AllowLeak( artist ); artistPtr = Meta::ArtistPtr( artist ); EXPECT_CALL( *artist, name() ).Times( AnyNumber() ).WillRepeatedly( Return( artistName ) ); coll->mc->addArtist( artistPtr ); } artistTracks << trackPtr; EXPECT_CALL( *artist, tracks() ).Times( AnyNumber() ).WillRepeatedly( Return( artistTracks ) ); EXPECT_CALL( *track, artist() ).Times( AnyNumber() ).WillRepeatedly( Return( artistPtr ) ); } TestUnionJob::TestUnionJob() : QObject() { int argc = 1; char **argv = (char **) malloc(sizeof(char *)); argv[0] = strdup( QCoreApplication::applicationName().toLocal8Bit().data() ); ::testing::InitGoogleMock( &argc, argv ); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); } void TestUnionJob::init() { trackCopyCount.clear(); } void TestUnionJob::testEmptyA() { Collections::CollectionTestImpl *collA = new Collections::MyCollectionTestImpl("A"); Collections::CollectionTestImpl *collB = new Collections::MyCollectionTestImpl("B"); addMockTrack( collB, "track1", "artist1", "album1" ); QCOMPARE( collA->mc->trackMap().count(), 0 ); QCOMPARE( collB->mc->trackMap().count(), 1 ); QVERIFY( trackCopyCount.isEmpty() ); UnionJob *job = new UnionJob( collA, collB ); QSignalSpy spy( job, &UnionJob::destroyed ); job->synchronize(); spy.wait( 1000 ); QCOMPARE( trackCopyCount.size(), 1 ); QVERIFY( trackCopyCount.contains( 1 ) ); QCOMPARE( collA->mc->trackMap().count(), 1 ); QCOMPARE( collB->mc->trackMap().count(), 1 ); delete collA; delete collB; } void TestUnionJob::testEmptyB() { Collections::CollectionTestImpl *collA = new Collections::MyCollectionTestImpl("A"); Collections::CollectionTestImpl *collB = new Collections::MyCollectionTestImpl("B"); addMockTrack( collA, "track1", "artist1", "album1" ); QCOMPARE( collA->mc->trackMap().count(), 1 ); QCOMPARE( collB->mc->trackMap().count(), 0 ); QVERIFY( trackCopyCount.isEmpty() ); UnionJob *job = new UnionJob( collA, collB ); QSignalSpy spy( job, &UnionJob::destroyed ); job->synchronize(); spy.wait( 1000 ); QCOMPARE( trackCopyCount.size(), 1 ); QVERIFY( trackCopyCount.contains( 1 ) ); QCOMPARE( collA->mc->trackMap().count(), 1 ); QCOMPARE( collB->mc->trackMap().count(), 1 ); delete collA; delete collB; } void TestUnionJob::testAddTrackToBoth() { Collections::CollectionTestImpl *collA = new Collections::MyCollectionTestImpl("A"); Collections::CollectionTestImpl *collB = new Collections::MyCollectionTestImpl("B"); addMockTrack( collA, "track1", "artist1", "album1" ); addMockTrack( collB, "track2", "artist2", "album2" ); QCOMPARE( collA->mc->trackMap().count(), 1 ); QCOMPARE( collB->mc->trackMap().count(), 1 ); QVERIFY( trackCopyCount.isEmpty() ); UnionJob *job = new UnionJob( collA, collB ); QSignalSpy spy( job, &UnionJob::destroyed ); job->synchronize(); spy.wait( 1000 ); QCOMPARE( trackCopyCount.size(), 2 ); QCOMPARE( trackCopyCount.at( 0 ), 1 ); QCOMPARE( trackCopyCount.at( 1 ), 1 ); QCOMPARE( collA->mc->trackMap().count(), 2 ); QCOMPARE( collB->mc->trackMap().count(), 2 ); delete collA; delete collB; } void TestUnionJob::testTrackAlreadyInBoth() { Collections::CollectionTestImpl *collA = new Collections::MyCollectionTestImpl("A"); Collections::CollectionTestImpl *collB = new Collections::MyCollectionTestImpl("B"); addMockTrack( collA, "track1", "artist1", "album1" ); addMockTrack( collB, "track1", "artist1", "album1" ); addMockTrack( collB, "track2", "artist2", "album2" ); QCOMPARE( collA->mc->trackMap().count(), 1 ); QCOMPARE( collB->mc->trackMap().count(), 2 ); QVERIFY( trackCopyCount.isEmpty() ); UnionJob *job = new UnionJob( collA, collB ); QSignalSpy spy( job, &UnionJob::destroyed ); job->synchronize(); spy.wait( 1000 ); QCOMPARE( trackCopyCount.size(), 1 ); QVERIFY( trackCopyCount.contains( 1 ) ); QCOMPARE( collA->mc->trackMap().count(), 2 ); QCOMPARE( collB->mc->trackMap().count(), 2 ); delete collA; delete collB; }