File indexing completed on 2024-05-12 16:46:24

0001 /***************************************************************************
0002     Copyright (C) 2017 Robby Stephenson <robby@periapsis.org>
0003  ***************************************************************************/
0004 
0005 /***************************************************************************
0006  *                                                                         *
0007  *   This program is free software; you can redistribute it and/or         *
0008  *   modify it under the terms of the GNU General Public License as        *
0009  *   published by the Free Software Foundation; either version 2 of        *
0010  *   the License or (at your option) version 3 or any later version        *
0011  *   accepted by the membership of KDE e.V. (or its successor approved     *
0012  *   by the membership of KDE e.V.), which shall act as a proxy            *
0013  *   defined in Section 14 of version 3 of the license.                    *
0014  *                                                                         *
0015  *   This program is distributed in the hope that it will be useful,       *
0016  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0017  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0018  *   GNU General Public License for more details.                          *
0019  *                                                                         *
0020  *   You should have received a copy of the GNU General Public License     *
0021  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
0022  *                                                                         *
0023  ***************************************************************************/
0024 
0025 #undef QT_NO_CAST_FROM_ASCII
0026 
0027 #include "tellicomodeltest.h"
0028 #include "modeltest.h"
0029 #include "../models/entrymodel.h"
0030 #include "../models/entryiconmodel.h"
0031 #include "../models/entrysortmodel.h"
0032 #include "../models/filtermodel.h"
0033 #include "../models/entrygroupmodel.h"
0034 #include "../models/groupsortmodel.h"
0035 #include "../models/modeliterator.h"
0036 #include "../models/entryselectionmodel.h"
0037 #include "../collections/bookcollection.h"
0038 #include "../collectionfactory.h"
0039 #include "../document.h"
0040 #include "../entrygroup.h"
0041 #include "../images/imagefactory.h"
0042 
0043 #include <QTest>
0044 #include <QSignalSpy>
0045 #include <QStandardPaths>
0046 
0047 QTEST_GUILESS_MAIN( TellicoModelTest )
0048 
0049 void TellicoModelTest::initTestCase() {
0050   QStandardPaths::setTestModeEnabled(true);
0051   Tellico::ImageFactory::init();
0052   Tellico::RegisterCollection<Tellico::Data::BookCollection> registerBook(Tellico::Data::Collection::Book, "book");
0053 }
0054 
0055 void TellicoModelTest::testEntryModel() {
0056   Tellico::Data::CollPtr coll(new Tellico::Data::Collection(true)); // add default fields
0057   Tellico::Data::EntryPtr entry1(new Tellico::Data::Entry(coll));
0058   entry1->setField(QStringLiteral("title"), QStringLiteral("Star Wars"));
0059   coll->addEntries(entry1);
0060 
0061   Tellico::EntryModel entryModel(this);
0062   ModelTest test1(&entryModel);
0063 
0064   Tellico::EntryIconModel iconModel(this);
0065   ModelTest test2(&iconModel);
0066 
0067   Tellico::EntrySortModel sortModel(this);
0068   ModelTest test3(&sortModel);
0069 
0070   iconModel.setSourceModel(&entryModel);
0071   sortModel.setSourceModel(&entryModel);
0072 
0073   entryModel.setFields(coll->fields());
0074   entryModel.setEntries(coll->entries());
0075   QCOMPARE(entryModel.index(0, 0), entryModel.indexFromEntry(entry1));
0076 
0077   Tellico::Data::FieldPtr field1(new Tellico::Data::Field(QStringLiteral("test"), QStringLiteral("test")));
0078   coll->addField(field1);
0079   entryModel.setFields(coll->fields());
0080 
0081   Tellico::Data::EntryPtr entry2(new Tellico::Data::Entry(coll));
0082   coll->addEntries(entry2);
0083   entryModel.addEntries(Tellico::Data::EntryList() << entry2);
0084 
0085   Tellico::Data::FieldPtr field2(new Tellico::Data::Field(QStringLiteral("test2"), QStringLiteral("test2")));
0086   coll->addField(field2);
0087   entryModel.addFields(Tellico::Data::FieldList() << field2);
0088 
0089   // Check FieldPtrRole in model data
0090   QModelIndex index = entryModel.index(0, entryModel.columnCount()-1);
0091   QVERIFY(index.isValid());
0092   QCOMPARE(entryModel.data(index, Tellico::FieldPtrRole),
0093            QVariant::fromValue(field2));
0094   //check FieldPtrRole in header model data
0095   QCOMPARE(entryModel.headerData(entryModel.columnCount()-1, Qt::Horizontal, Tellico::FieldPtrRole),
0096            QVariant::fromValue(field2));
0097 
0098   Tellico::FilterRule* rule1 = new Tellico::FilterRule(QStringLiteral("title"),
0099                                                        QStringLiteral("Star Wars"),
0100                                                        Tellico::FilterRule::FuncEquals);
0101   Tellico::FilterPtr filter(new Tellico::Filter(Tellico::Filter::MatchAny));
0102   filter->append(rule1);
0103 
0104   sortModel.setFilter(filter);
0105 
0106   entryModel.clear();
0107   entryModel.setFields(coll->fields());
0108   entryModel.setEntries(coll->entries());
0109   QCOMPARE(entryModel.index(0, 0), entryModel.indexFromEntry(entry1));
0110 
0111   Tellico::Data::FieldPtr field3(new Tellico::Data::Field(QStringLiteral("test"), QStringLiteral("test-new")));
0112   coll->modifyField(field3);
0113   QCOMPARE(coll->fields().count(), entryModel.columnCount(QModelIndex()));
0114   entryModel.modifyField(field2, field3);
0115 
0116   coll->removeField(field3);
0117   entryModel.removeFields(Tellico::Data::FieldList() << field3);
0118   QCOMPARE(coll->fields().count(), entryModel.columnCount(QModelIndex()));
0119 
0120   QCOMPARE(coll->entries().count(), entryModel.rowCount(QModelIndex()));
0121   coll->removeEntries(Tellico::Data::EntryList() << entry2);
0122   QCOMPARE(coll->entries().count() + 1, entryModel.rowCount(QModelIndex()));
0123   entryModel.removeEntries(Tellico::Data::EntryList() << entry2);
0124   QCOMPARE(coll->entries().count(), entryModel.rowCount(QModelIndex()));
0125 
0126   for(Tellico::ModelIterator eIt(&entryModel); eIt.entry(); ++eIt) {
0127     QVERIFY(eIt.isValid());
0128   }
0129 }
0130 
0131 void TellicoModelTest::testFilterModel() {
0132   Tellico::FilterModel filterModel(this);
0133   ModelTest test1(&filterModel);
0134 
0135   Tellico::FilterRule* rule1 = new Tellico::FilterRule(QStringLiteral("title"),
0136                                                        QStringLiteral("Star Wars"),
0137                                                        Tellico::FilterRule::FuncEquals);
0138   Tellico::FilterPtr filter(new Tellico::Filter(Tellico::Filter::MatchAny));
0139   filter->append(rule1);
0140   filterModel.addFilter(filter);
0141 
0142   Tellico::Data::CollPtr c = Tellico::Data::Document::self()->collection();
0143   Tellico::Data::EntryPtr entry1(new Tellico::Data::Entry(c));
0144   entry1->setField(QStringLiteral("title"), QStringLiteral("Star Wars"));
0145   c->addEntries(entry1);
0146 
0147   filterModel.clear();
0148   filterModel.addFilter(filter);
0149   QCOMPARE(filter, filterModel.filter(filterModel.index(0, 0)));
0150   QVERIFY(filterModel.indexContainsEntry(filterModel.index(0, 0), entry1));
0151 
0152   filterModel.invalidate(filterModel.index(0, 0));
0153   QCOMPARE(filter, filterModel.filter(filterModel.index(0, 0)));
0154   QVERIFY(filterModel.indexContainsEntry(filterModel.index(0, 0), entry1));
0155 }
0156 
0157 void TellicoModelTest::testGroupModel() {
0158   Tellico::Data::CollPtr coll(new Tellico::Data::BookCollection(true)); // add default fields
0159   Tellico::Data::EntryPtr entry1(new Tellico::Data::Entry(coll));
0160   entry1->setField(QStringLiteral("title"), QStringLiteral("Star Wars"));
0161   entry1->setField(QStringLiteral("author"), QStringLiteral("George Lucas"));
0162   coll->addEntries(entry1);
0163 
0164   Tellico::EntryGroupModel groupModel(this);
0165   ModelTest test1(&groupModel);
0166 
0167   Tellico::GroupSortModel sortModel(this);
0168   ModelTest test2(&sortModel);
0169 
0170   sortModel.setSourceModel(&groupModel);
0171 
0172   Tellico::Data::EntryGroupDict* dict = coll->entryGroupDictByName(QStringLiteral("author"));
0173   groupModel.addGroups(dict->values(), QString());
0174   QCOMPARE(sortModel.rowCount(), 1);
0175 
0176   for(Tellico::ModelIterator gIt(&groupModel); gIt.group(); ++gIt) {
0177     QVERIFY(gIt.isValid());
0178     Tellico::Data::EntryGroup* group = gIt.group();
0179     QVERIFY(group);
0180     QCOMPARE(group->groupName(), QStringLiteral("Lucas, George"));
0181     QCOMPARE(group->fieldName(), QStringLiteral("author"));
0182     QCOMPARE(group->size(), 1);
0183     QVERIFY(!group->hasEmptyGroupName());
0184   }
0185 }
0186 
0187 void TellicoModelTest::testSelectionModel() {
0188   qRegisterMetaType<Tellico::Data::EntryList>("Tellico::Data::EntryList");
0189   // this mimics the model dependencies used in mainwindow.cpp
0190   Tellico::EntryModel entryModel(this);
0191   ModelTest test1(&entryModel);
0192   Tellico::EntryIconModel iconModel(this);
0193   ModelTest test2(&iconModel);
0194   iconModel.setSourceModel(&entryModel);
0195 
0196   QItemSelectionModel selModel(&entryModel, this);
0197   Tellico::EntrySelectionModel proxySelect(&iconModel, &selModel, this);
0198 
0199 //  connect(proxySelect, SIGNAL(entriesSelected(Tellico::Data::EntryList)),
0200   Tellico::Data::CollPtr coll(new Tellico::Data::Collection(true)); // add default fields
0201   Tellico::Data::EntryPtr entry1(new Tellico::Data::Entry(coll));
0202   entry1->setField(QStringLiteral("title"), QStringLiteral("test1"));
0203   coll->addEntries(entry1);
0204 
0205   entryModel.setFields(coll->fields());
0206   entryModel.setEntries(coll->entries());
0207 
0208   QSignalSpy entriesSelectedSpy(&proxySelect, SIGNAL(entriesSelected(Tellico::Data::EntryList)));
0209   selModel.select(entryModel.index(0,0), QItemSelectionModel::Select);
0210   QCOMPARE(entriesSelectedSpy.count(), 1);
0211 
0212   Tellico::Data::EntryList entries = proxySelect.selectedEntries();
0213   QCOMPARE(entries.count(), 1);
0214   QCOMPARE(entries.at(0)->title(), QStringLiteral("test1"));
0215 
0216   Tellico::Data::EntryPtr entry2(new Tellico::Data::Entry(coll));
0217   entry2->setField(QStringLiteral("title"), QStringLiteral("test2"));
0218   coll->addEntries(entry2);
0219   entryModel.addEntries(Tellico::Data::EntryList() << entry2);
0220 
0221   entries = proxySelect.selectedEntries();
0222   QCOMPARE(entries.count(), 1);
0223   QCOMPARE(entries.at(0)->title(), QStringLiteral("test1"));
0224 
0225   selModel.select(entryModel.index(1,0), QItemSelectionModel::Select);
0226   entries = proxySelect.selectedEntries();
0227   QCOMPARE(entries.count(), 2);
0228   QCOMPARE(entries.at(0)->title(), QStringLiteral("test1"));
0229   QCOMPARE(entries.at(1)->title(), QStringLiteral("test2"));
0230 
0231   selModel.select(entryModel.index(0,0), QItemSelectionModel::Toggle);
0232   entries = proxySelect.selectedEntries();
0233   QCOMPARE(entries.count(), 1);
0234   QCOMPARE(entries.at(0)->title(), QStringLiteral("test2"));
0235 
0236   entryModel.clear();
0237   // now there should be no selection since EntryModel::clear calls modelReset()
0238   // and the proxy selection is connected to that signal
0239   entries = proxySelect.selectedEntries();
0240   QCOMPARE(entries.count(), 0);
0241 }