Add test for collection model container nodes

This commit is contained in:
Jonas Kvinge 2020-09-10 22:13:20 +02:00
parent 4056f00169
commit 0b7b4c12e4
1 changed files with 334 additions and 2 deletions

View File

@ -23,6 +23,7 @@
#include <gtest/gtest.h>
#include <QMap>
#include <QString>
#include <QUrl>
#include <QThread>
@ -32,6 +33,7 @@
#include "test_utils.h"
#include "core/logging.h"
#include "core/database.h"
#include "collection/collectionmodel.h"
#include "collection/collectionbackend.h"
@ -54,9 +56,10 @@ class CollectionModelTest : public ::testing::Test {
model_sorted_->setSortRole(CollectionModel::Role_SortText);
model_sorted_->setDynamicSortFilter(true);
model_sorted_->sort(0);
}
Song AddSong(Song& song) {
Song AddSong(Song &song) {
song.set_directory_id(1);
if (song.mtime() == 0) song.set_mtime(1);
if (song.ctime() == 0) song.set_ctime(1);
@ -72,7 +75,7 @@ class CollectionModelTest : public ::testing::Test {
return song;
}
Song AddSong(const QString& title, const QString& artist, const QString& album, int length) {
Song AddSong(const QString &title, const QString &artist, const QString &album, const int length) {
Song song;
song.Init(title, artist, album, length);
song.set_mtime(0);
@ -338,4 +341,333 @@ TEST_F(CollectionModelTest, RemoveEmptyArtists) {
}
// Test to check that the container nodes are created identical and unique all through the model with all possible collection groupings.
// model1 - Nodes are created from a complete reset done through lazy-loading.
// model2 - Initial container nodes are created in SongsDiscovered.
// model3 - All container nodes are created in SongsDiscovered.
// WARNING: This test can take up to 30 minutes to complete.
TEST_F(CollectionModelTest, TestContainerNodes) {
SongList songs;
int year = 1960;
// Add some normal albums.
for (int artist_number = 1; artist_number <= 3 ; ++artist_number) {
Song song(Song::Source_Collection);
song.set_artist(QString("Artist %1").arg(artist_number));
song.set_composer(QString("Composer %1").arg(artist_number));
song.set_performer(QString("Performer %1").arg(artist_number));
song.set_mtime(1);
song.set_ctime(1);
song.set_directory_id(1);
song.set_filetype(Song::FileType_FLAC);
song.set_filesize(1);
for (int album_number = 1; album_number <= 3 ; ++album_number) {
if (year > 2020) year = 1960;
song.set_album(QString("Artist %1 - Album %2").arg(artist_number).arg(album_number));
song.set_album_id(QString::number(album_number));
song.set_year(year++);
song.set_genre("Rock");
for (int song_number = 1; song_number <= 5 ; ++song_number) {
song.set_url(QUrl(QString("file:///mnt/music/Artist %1/Album %2/%3 - artist song-n-%3").arg(artist_number).arg(album_number).arg(song_number)));
song.set_title(QString("Title %1").arg(song_number));
song.set_track(song_number);
songs << song;
}
}
}
// Add some albums with 'album artist'.
for (int album_artist_number = 1; album_artist_number <= 3 ; ++album_artist_number) {
Song song(Song::Source_Collection);
song.set_albumartist(QString("Album Artist %1").arg(album_artist_number));
song.set_composer(QString("Composer %1").arg(album_artist_number));
song.set_performer(QString("Performer %1").arg(album_artist_number));
song.set_mtime(1);
song.set_ctime(1);
song.set_directory_id(1);
song.set_filetype(Song::FileType_FLAC);
song.set_filesize(1);
for (int album_number = 1; album_number <= 3 ; ++album_number) {
if (year > 2020) year = 1960;
song.set_album(QString("Album Artist %1 - Album %2").arg(album_artist_number).arg(album_number));
song.set_album_id(QString::number(album_number));
song.set_year(year++);
song.set_genre("Rock");
int artist_number = 1;
for (int song_number = 1; song_number <= 5 ; ++song_number) {
song.set_url(QUrl(QString("file:///mnt/music/Album Artist %1/Album %2/%3 - album artist song-n-%3").arg(album_artist_number).arg(album_number).arg(QString::number(song_number))));
song.set_title("Title " + QString::number(song_number));
song.set_track(song_number);
song.set_artist("Artist " + QString::number(artist_number));
songs << song;
++artist_number;
}
}
}
// Add some compilation albums.
for (int album_number = 1; album_number <= 3 ; ++album_number) {
if (year > 2020) year = 1960;
Song song(Song::Source_Collection);
song.set_mtime(1);
song.set_ctime(1);
song.set_directory_id(1);
song.set_filetype(Song::FileType_FLAC);
song.set_filesize(1);
song.set_album(QString("Compilation Album %1").arg(album_number));
song.set_album_id(QString::number(album_number));
song.set_year(year++);
song.set_genre("Pop");
song.set_compilation(true);
int artist_number = 1;
for (int song_number = 1; song_number <= 4 ; ++song_number) {
song.set_url(QUrl(QString("file:///mnt/music/Compilation Artist %1/Compilation Album %2/%3 - compilation song-n-%3").arg(artist_number).arg(album_number).arg(QString::number(song_number))));
song.set_artist(QString("Compilation Artist %1").arg(artist_number));
song.set_composer(QString("Composer %1").arg(artist_number));
song.set_performer(QString("Performer %1").arg(artist_number));
song.set_title(QString("Title %1").arg(song_number));
song.set_track(song_number);
songs << song;
++artist_number;
}
}
// Songs with only title
{
Song song(Song::Source_Collection);
song.set_mtime(1);
song.set_ctime(1);
song.set_directory_id(1);
song.set_filetype(Song::FileType_FLAC);
song.set_filesize(1);
song.set_url(QUrl(QString("file:///mnt/music/no album song 1/song-only-1")));
song.set_title("Only Title 1");
songs << song;
song.set_url(QUrl(QString("file:///mnt/music/no album song 2/song-only-2")));
song.set_title("Only Title 2");
songs << song;
}
// Song with only artist, album and title.
{
Song song(Song::Source_Collection);
song.set_url(QUrl(QString("file:///tmp/artist-album-title-song")));
song.set_artist("Not Only Artist");
song.set_album("Not Only Album");
song.set_title("Not Only Title");
song.set_mtime(1);
song.set_ctime(1);
song.set_directory_id(1);
song.set_filetype(Song::FileType_FLAC);
song.set_filesize(1);
song.set_year(1970);
song.set_track(1);
songs << song;
}
// Add possible Various artists conflicting songs.
{
Song song(Song::Source_Collection);
song.set_url(QUrl(QString("file:///tmp/song-va-conflicting-1")));
song.set_artist("Various artists");
song.set_album("VA Album");
song.set_title("VA Title");
song.set_mtime(1);
song.set_ctime(1);
song.set_directory_id(1);
song.set_filetype(Song::FileType_FLAC);
song.set_filesize(1);
song.set_year(1970);
song.set_track(1);
songs << song;
}
{
Song song(Song::Source_Collection);
song.set_url(QUrl(QString("file:///tmp/song-va-conflicting-2")));
song.set_artist("Various artists");
song.set_albumartist("Various artists");
song.set_album("VA Album");
song.set_title("VA Title");
song.set_mtime(1);
song.set_ctime(1);
song.set_directory_id(1);
song.set_filetype(Song::FileType_FLAC);
song.set_filesize(1);
song.set_year(1970);
song.set_track(1);
songs << song;
}
{
Song song(Song::Source_Collection);
song.set_url(QUrl(QString("file:///tmp/song-va-conflicting-3")));
song.set_albumartist("Various artists");
song.set_album("VA Album");
song.set_title("VA Title");
song.set_mtime(1);
song.set_ctime(1);
song.set_directory_id(1);
song.set_filetype(Song::FileType_FLAC);
song.set_filesize(1);
song.set_year(1970);
song.set_track(1);
songs << song;
}
for (int f = CollectionModel::GroupBy_None + 1 ; f < CollectionModel::GroupByCount ; ++f) {
for (int s = CollectionModel::GroupBy_None ; s < CollectionModel::GroupByCount ; ++s) {
for (int t = CollectionModel::GroupBy_None ; t < CollectionModel::GroupByCount ; ++t) {
qLog(Debug) << "Testing collection model grouping: " << f << s << t;
std::unique_ptr<Database> database1;
std::unique_ptr<Database> database2;
std::unique_ptr<Database> database3;
std::unique_ptr<CollectionBackend> backend1;
std::unique_ptr<CollectionBackend> backend2;
std::unique_ptr<CollectionBackend> backend3;
std::unique_ptr<CollectionModel> model1;
std::unique_ptr<CollectionModel> model2;
std::unique_ptr<CollectionModel> model3;
database1.reset(new MemoryDatabase(nullptr));
database2.reset(new MemoryDatabase(nullptr));
database3.reset(new MemoryDatabase(nullptr));
backend1.reset(new CollectionBackend);
backend2.reset(new CollectionBackend);
backend3.reset(new CollectionBackend);
backend1->Init(database1.get(), Song::Source_Collection, SCollection::kSongsTable, SCollection::kDirsTable, SCollection::kSubdirsTable, SCollection::kFtsTable);
backend2->Init(database2.get(), Song::Source_Collection, SCollection::kSongsTable, SCollection::kDirsTable, SCollection::kSubdirsTable, SCollection::kFtsTable);
backend3->Init(database3.get(), Song::Source_Collection, SCollection::kSongsTable, SCollection::kDirsTable, SCollection::kSubdirsTable, SCollection::kFtsTable);
model1.reset(new CollectionModel(backend1.get(), nullptr));
model2.reset(new CollectionModel(backend2.get(), nullptr));
model3.reset(new CollectionModel(backend3.get(), nullptr));
backend1->AddDirectory("/mnt/music");
backend2->AddDirectory("/mnt/music");
backend3->AddDirectory("/mut/music");
model1->SetGroupBy(CollectionModel::Grouping(CollectionModel::GroupBy(f), CollectionModel::GroupBy(s), CollectionModel::GroupBy(t)));
model2->SetGroupBy(CollectionModel::Grouping(CollectionModel::GroupBy(f), CollectionModel::GroupBy(s), CollectionModel::GroupBy(t)));
model3->SetGroupBy(CollectionModel::Grouping(CollectionModel::GroupBy(f), CollectionModel::GroupBy(s), CollectionModel::GroupBy(t)));
model3->set_use_lazy_loading(false);
QSignalSpy model1_update(model1.get(), SIGNAL(rowsInserted(QModelIndex, int, int)));
QSignalSpy model2_update(model2.get(), SIGNAL(rowsInserted(QModelIndex, int, int)));
QSignalSpy model3_update(model3.get(), SIGNAL(rowsInserted(QModelIndex, int, int)));
backend1->AddOrUpdateSongs(songs);
backend2->AddOrUpdateSongs(songs);
backend3->AddOrUpdateSongs(songs);
ASSERT_EQ(model1->song_nodes().count(), 0);
ASSERT_EQ(model2->song_nodes().count(), 0);
ASSERT_EQ(model3->song_nodes().count(), songs.count());
model1->Init(false);
model1->ExpandAll();
model2->ExpandAll();
// All nodes in model3 should be created already.
ASSERT_EQ(model1->song_nodes().count(), songs.count());
ASSERT_EQ(model2->song_nodes().count(), songs.count());
ASSERT_EQ(model3->song_nodes().count(), songs.count());
// Container nodes for all models should now be indentical.
for (int i = 0 ; i < 3 ; ++i) {
for (CollectionItem *node : model1->container_nodes(i).values()) {
ASSERT_TRUE(model2->container_nodes(i).keys().contains(node->key));
CollectionItem *node2 = model2->container_nodes(i)[node->key];
ASSERT_EQ(node->key, node2->key);
ASSERT_EQ(node->display_text, node2->display_text);
ASSERT_EQ(node->sort_text, node2->sort_text);
}
for (CollectionItem *node : model1->container_nodes(i).values()) {
ASSERT_TRUE(model3->container_nodes(i).keys().contains(node->key));
CollectionItem *node2 = model2->container_nodes(i)[node->key];
ASSERT_EQ(node->key, node2->key);
ASSERT_EQ(node->display_text, node2->display_text);
ASSERT_EQ(node->sort_text, node2->sort_text);
}
for (CollectionItem *node : model2->container_nodes(i).values()) {
ASSERT_TRUE(model1->container_nodes(i).keys().contains(node->key));
CollectionItem *node2 = model2->container_nodes(i)[node->key];
ASSERT_EQ(node->key, node2->key);
ASSERT_EQ(node->display_text, node2->display_text);
ASSERT_EQ(node->sort_text, node2->sort_text);
}
for (CollectionItem *node : model2->container_nodes(i).values()) {
ASSERT_TRUE(model3->container_nodes(i).keys().contains(node->key));
CollectionItem *node2 = model2->container_nodes(i)[node->key];
ASSERT_EQ(node->key, node2->key);
ASSERT_EQ(node->display_text, node2->display_text);
ASSERT_EQ(node->sort_text, node2->sort_text);
}
for (CollectionItem *node : model3->container_nodes(i).values()) {
ASSERT_TRUE(model1->container_nodes(i).keys().contains(node->key));
CollectionItem *node2 = model2->container_nodes(i)[node->key];
ASSERT_EQ(node->key, node2->key);
ASSERT_EQ(node->display_text, node2->display_text);
ASSERT_EQ(node->sort_text, node2->sort_text);
}
for (CollectionItem *node : model3->container_nodes(i).values()) {
ASSERT_TRUE(model2->container_nodes(i).keys().contains(node->key));
CollectionItem *node2 = model2->container_nodes(i)[node->key];
ASSERT_EQ(node->key, node2->key);
ASSERT_EQ(node->display_text, node2->display_text);
ASSERT_EQ(node->sort_text, node2->sort_text);
}
}
QSignalSpy database_reset_1(backend1.get(), SIGNAL(DatabaseReset()));
QSignalSpy database_reset_2(backend2.get(), SIGNAL(DatabaseReset()));
QSignalSpy database_reset_3(backend3.get(), SIGNAL(DatabaseReset()));
backend1->DeleteAll();
backend2->DeleteAll();
backend3->DeleteAll();
ASSERT_EQ(database_reset_1.count(), 1);
ASSERT_EQ(database_reset_2.count(), 1);
ASSERT_EQ(database_reset_3.count(), 1);
// Make sure all nodes are deleted.
ASSERT_EQ(model1->container_nodes(0).count(), 0);
ASSERT_EQ(model1->container_nodes(1).count(), 0);
ASSERT_EQ(model1->container_nodes(2).count(), 0);
ASSERT_EQ(model2->container_nodes(0).count(), 0);
ASSERT_EQ(model2->container_nodes(1).count(), 0);
ASSERT_EQ(model2->container_nodes(2).count(), 0);
ASSERT_EQ(model3->container_nodes(0).count(), 0);
ASSERT_EQ(model3->container_nodes(1).count(), 0);
ASSERT_EQ(model3->container_nodes(2).count(), 0);
ASSERT_EQ(model1->song_nodes().count(), 0);
ASSERT_EQ(model2->song_nodes().count(), 0);
ASSERT_EQ(model3->song_nodes().count(), 0);
ASSERT_EQ(model1->divider_nodes_count(), 0);
ASSERT_EQ(model2->divider_nodes_count(), 0);
ASSERT_EQ(model3->divider_nodes_count(), 0);
backend1->Close();
backend2->Close();
backend3->Close();
}
}
}
}
} // namespace