File indexing completed on 2024-05-12 16:46:18
0001 /*************************************************************************** 0002 Copyright (C) 2011 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 "filtertest.h" 0028 0029 #include "../filter.h" 0030 #include "../entry.h" 0031 #include "../collections/bookcollection.h" 0032 #include "../collections/videocollection.h" 0033 #include "../images/imageinfo.h" 0034 #include "../images/imagefactory.h" 0035 0036 #include <QTest> 0037 #include <QStandardPaths> 0038 0039 QTEST_GUILESS_MAIN( FilterTest ) 0040 0041 void FilterTest::initTestCase() { 0042 QStandardPaths::setTestModeEnabled(true); 0043 Tellico::ImageFactory::init(); 0044 } 0045 0046 void FilterTest::testFilter() { 0047 Tellico::Data::CollPtr coll(new Tellico::Data::Collection(true, QStringLiteral("TestCollection"))); 0048 Tellico::Data::EntryPtr entry(new Tellico::Data::Entry(coll)); 0049 entry->setField(QStringLiteral("title"), QStringLiteral("Star Wars")); 0050 0051 Tellico::FilterRule* rule1 = new Tellico::FilterRule(QStringLiteral("title"), 0052 QStringLiteral("Star Wars"), 0053 Tellico::FilterRule::FuncEquals); 0054 QCOMPARE(rule1->fieldName(), QStringLiteral("title")); 0055 QCOMPARE(rule1->pattern(), QStringLiteral("Star Wars")); 0056 QCOMPARE(rule1->function(), Tellico::FilterRule::FuncEquals); 0057 0058 Tellico::Filter filter(Tellico::Filter::MatchAny); 0059 filter.append(rule1); 0060 QVERIFY(filter.matches(entry)); 0061 rule1->setFunction(Tellico::FilterRule::FuncNotEquals); 0062 QVERIFY(!filter.matches(entry)); 0063 0064 rule1->setFunction(Tellico::FilterRule::FuncContains); 0065 QVERIFY(filter.matches(entry)); 0066 0067 rule1->setFieldName(QStringLiteral("author")); 0068 QVERIFY(!filter.matches(entry)); 0069 rule1->setFunction(Tellico::FilterRule::FuncNotContains); 0070 QVERIFY(filter.matches(entry)); 0071 0072 rule1->setFieldName(QString()); 0073 rule1->setFunction(Tellico::FilterRule::FuncEquals); 0074 QVERIFY(filter.matches(entry)); 0075 0076 Tellico::FilterRule* rule2 = new Tellico::FilterRule(QStringLiteral("title"), 0077 QStringLiteral("Star"), 0078 Tellico::FilterRule::FuncEquals); 0079 filter.clear(); 0080 filter.append(rule2); 0081 QVERIFY(!filter.matches(entry)); 0082 0083 rule2->setFunction(Tellico::FilterRule::FuncContains); 0084 QVERIFY(filter.matches(entry)); 0085 rule2->setFunction(Tellico::FilterRule::FuncNotContains); 0086 QVERIFY(!filter.matches(entry)); 0087 0088 rule2->setFieldName(QStringLiteral("author")); 0089 rule2->setFunction(Tellico::FilterRule::FuncContains); 0090 QVERIFY(!filter.matches(entry)); 0091 0092 rule2->setFieldName(QString()); 0093 QVERIFY(filter.matches(entry)); 0094 0095 Tellico::FilterRule* rule3 = new Tellico::FilterRule(QStringLiteral("title"), 0096 QStringLiteral("Sta[rt]"), 0097 Tellico::FilterRule::FuncRegExp); 0098 QCOMPARE(rule3->pattern(), QStringLiteral("Sta[rt]")); 0099 filter.clear(); 0100 filter.append(rule3); 0101 QVERIFY(filter.matches(entry)); 0102 0103 rule3->setFunction(Tellico::FilterRule::FuncNotRegExp); 0104 QVERIFY(!filter.matches(entry)); 0105 0106 rule3->setFieldName(QStringLiteral("author")); 0107 QVERIFY(filter.matches(entry)); 0108 0109 rule3->setFieldName(QString()); 0110 rule3->setFunction(Tellico::FilterRule::FuncRegExp); 0111 QVERIFY(filter.matches(entry)); 0112 0113 entry->setField(QStringLiteral("title"), QStringLiteral("Tmavomodrý Svět")); 0114 0115 Tellico::FilterRule* rule4 = new Tellico::FilterRule(QStringLiteral("title"), 0116 QStringLiteral("Tmavomodrý Svět"), 0117 Tellico::FilterRule::FuncEquals); 0118 filter.clear(); 0119 filter.append(rule4); 0120 QVERIFY(filter.matches(entry)); 0121 0122 rule4->setFunction(Tellico::FilterRule::FuncContains); 0123 QVERIFY(filter.matches(entry)); 0124 0125 rule4->setFunction(Tellico::FilterRule::FuncRegExp); 0126 QVERIFY(filter.matches(entry)); 0127 0128 Tellico::FilterRule* rule5 = new Tellico::FilterRule(QStringLiteral("title"), 0129 QStringLiteral("Tmavomodry Svet"), 0130 Tellico::FilterRule::FuncEquals); 0131 0132 filter.clear(); 0133 filter.append(rule5); 0134 QVERIFY(!filter.matches(entry)); 0135 0136 rule5->setFunction(Tellico::FilterRule::FuncContains); 0137 QVERIFY(filter.matches(entry)); 0138 0139 rule5->setFunction(Tellico::FilterRule::FuncRegExp); 0140 QVERIFY(!filter.matches(entry)); 0141 0142 Tellico::Data::FieldPtr date(new Tellico::Data::Field(QStringLiteral("date"), 0143 QStringLiteral("Date"), 0144 Tellico::Data::Field::Date)); 0145 coll->addField(date); 0146 0147 Tellico::FilterRule* rule6 = new Tellico::FilterRule(QStringLiteral("date"), 0148 QStringLiteral("2011-01-24"), 0149 Tellico::FilterRule::FuncAfter); 0150 QCOMPARE(rule6->pattern(), QStringLiteral("2011-01-24")); 0151 filter.clear(); 0152 filter.append(rule6); 0153 // test Bug 361625 0154 entry->setField(QStringLiteral("date"), QStringLiteral("2011-1-25")); 0155 QVERIFY(filter.matches(entry)); 0156 entry->setField(QStringLiteral("date"), QStringLiteral("2011-01-25")); 0157 QVERIFY(filter.matches(entry)); 0158 0159 rule6->setFunction(Tellico::FilterRule::FuncBefore); 0160 QVERIFY(!filter.matches(entry)); 0161 0162 // check that a date match is neither before or after 0163 entry->setField(QStringLiteral("date"), rule6->pattern()); 0164 rule6->setFunction(Tellico::FilterRule::FuncAfter); 0165 QVERIFY(!filter.matches(entry)); 0166 rule6->setFunction(Tellico::FilterRule::FuncBefore); 0167 QVERIFY(!filter.matches(entry)); 0168 0169 // check that an invalid date never matches 0170 entry->setField(QStringLiteral("date"), QStringLiteral("test")); 0171 rule6->setFunction(Tellico::FilterRule::FuncAfter); 0172 QVERIFY(!filter.matches(entry)); 0173 rule6->setFunction(Tellico::FilterRule::FuncBefore); 0174 QVERIFY(!filter.matches(entry)); 0175 0176 Tellico::Data::FieldPtr number(new Tellico::Data::Field(QStringLiteral("number"), 0177 QStringLiteral("Number"), 0178 Tellico::Data::Field::Number)); 0179 coll->addField(number); 0180 entry->setField(QStringLiteral("number"), QStringLiteral("3")); 0181 0182 Tellico::FilterRule* rule7 = new Tellico::FilterRule(QStringLiteral("number"), 0183 QStringLiteral("5.0"), 0184 Tellico::FilterRule::FuncLess); 0185 QCOMPARE(rule7->pattern(), QStringLiteral("5.0")); 0186 filter.clear(); 0187 filter.append(rule7); 0188 QVERIFY(filter.matches(entry)); 0189 0190 rule7->setFunction(Tellico::FilterRule::FuncGreater); 0191 QVERIFY(!filter.matches(entry)); 0192 0193 entry->setField(QStringLiteral("number"), QStringLiteral("6")); 0194 QVERIFY(filter.matches(entry)); 0195 0196 // check that a rating can use greater than 0197 Tellico::Data::FieldPtr rating(new Tellico::Data::Field(QStringLiteral("rating"), 0198 QStringLiteral("Rating"), 0199 Tellico::Data::Field::Rating)); 0200 coll->addField(rating); 0201 entry->setField(QStringLiteral("rating"), QStringLiteral("3")); 0202 0203 Tellico::FilterRule* rule8 = new Tellico::FilterRule(QStringLiteral("rating"), 0204 QStringLiteral("2.0"), 0205 Tellico::FilterRule::FuncGreater); 0206 QCOMPARE(rule8->pattern(), QStringLiteral("2.0")); 0207 filter.clear(); 0208 filter.append(rule8); 0209 QVERIFY(filter.matches(entry)); 0210 0211 rule8->setFunction(Tellico::FilterRule::FuncLess); 0212 QVERIFY(!filter.matches(entry)); 0213 0214 entry->setField(QStringLiteral("rating"), QStringLiteral("1")); 0215 QVERIFY(filter.matches(entry)); 0216 0217 // check image size comparisons 0218 Tellico::Data::FieldPtr imageField(new Tellico::Data::Field(QStringLiteral("image"), 0219 QStringLiteral("image"), 0220 Tellico::Data::Field::Image)); 0221 coll->addField(imageField); 0222 const QString imageName(QStringLiteral("image.png")); 0223 entry->setField(QStringLiteral("image"), imageName); 0224 // insert image size into cache (128x128) 0225 Tellico::Data::ImageInfo imageInfo(imageName, "PNG", 128, 96, false); 0226 Tellico::ImageFactory::cacheImageInfo(imageInfo); 0227 0228 Tellico::FilterRule* rule9 = new Tellico::FilterRule(QStringLiteral("image"), 0229 QStringLiteral("96"), 0230 Tellico::FilterRule::FuncGreater); 0231 QVERIFY(!rule9->isEmpty()); 0232 QCOMPARE(rule9->pattern(), QStringLiteral("96")); 0233 filter.clear(); 0234 filter.append(rule9); 0235 // compares against larger image dimension, so 128 > 96 matches 0236 QVERIFY(filter.matches(entry)); 0237 0238 // compares against larger image dimension, so 128 < 96 fails 0239 rule9->setFunction(Tellico::FilterRule::FuncLess); 0240 QVERIFY(!filter.matches(entry)); 0241 0242 Tellico::Data::ImageInfo imageInfo2(imageName, "PNG", 96, 96, false); 0243 Tellico::ImageFactory::cacheImageInfo(imageInfo2); 0244 0245 rule9->setFunction(Tellico::FilterRule::FuncLess); 0246 QVERIFY(!filter.matches(entry)); 0247 rule9->setFunction(Tellico::FilterRule::FuncEquals); 0248 QVERIFY(filter.matches(entry)); 0249 // an empty image should also match less than size 0250 entry->setField(QStringLiteral("image"), QString()); 0251 rule9->setFunction(Tellico::FilterRule::FuncLess); 0252 QVERIFY(filter.matches(entry)); 0253 0254 // test a filter for matching against an empty string 0255 Tellico::Data::FieldPtr testField(new Tellico::Data::Field(QStringLiteral("test"), 0256 QStringLiteral("Test"))); 0257 coll->addField(testField); 0258 Tellico::FilterRule* rule10 = new Tellico::FilterRule(QStringLiteral("test"), 0259 QString(), 0260 Tellico::FilterRule::FuncEquals); 0261 QVERIFY(!rule10->isEmpty()); 0262 filter.clear(); 0263 filter.append(rule10); 0264 QVERIFY(filter.matches(entry)); 0265 rule10->setFunction(Tellico::FilterRule::FuncNotEquals); 0266 QVERIFY(!rule10->isEmpty()); 0267 QVERIFY(!filter.matches(entry)); 0268 } 0269 0270 void FilterTest::testGroupViewFilter() { 0271 // ideally, I'd instantiate a GroupView object and test that, but it's tough with all the dependencies 0272 // so this code is identical to what is in Tellico::GroupView::slotFilterGroup() 0273 Tellico::Data::CollPtr coll(new Tellico::Data::BookCollection(true, QStringLiteral("TestCollection"))); 0274 Tellico::Data::EntryPtr entry1(new Tellico::Data::Entry(coll)); 0275 entry1->setField(QStringLiteral("author"), QStringLiteral("John Author")); 0276 Tellico::Data::EntryPtr entry2(new Tellico::Data::Entry(coll)); 0277 entry2->setField(QStringLiteral("author"), QStringLiteral("John Q. Author")); 0278 Tellico::Data::EntryPtr entry3(new Tellico::Data::Entry(coll)); 0279 entry3->setField(QStringLiteral("author"), QStringLiteral("John Author") + 0280 Tellico::FieldFormat::delimiterString() + 0281 QStringLiteral("James Author")); 0282 Tellico::Data::EntryPtr entry4(new Tellico::Data::Entry(coll)); 0283 entry4->setField(QStringLiteral("author"), QStringLiteral("James Author") + 0284 Tellico::FieldFormat::delimiterString() + 0285 QStringLiteral("John Author")); 0286 Tellico::Data::EntryPtr entry5(new Tellico::Data::Entry(coll)); 0287 entry5->setField(QStringLiteral("author"), QStringLiteral("James Author") + 0288 Tellico::FieldFormat::delimiterString() + 0289 QStringLiteral("John Q. Author")); 0290 0291 QString pattern(entry1->formattedField(QStringLiteral("author"))); 0292 // the filter should match all since it was the initial way the group view filter was constructed 0293 Tellico::Filter filter1(Tellico::Filter::MatchAny); 0294 filter1.append(new Tellico::FilterRule(QStringLiteral("author"), pattern, Tellico::FilterRule::FuncContains)); 0295 QVERIFY(filter1.matches(entry1)); 0296 QVERIFY(filter1.matches(entry2)); 0297 QVERIFY(filter1.matches(entry3)); 0298 QVERIFY(filter1.matches(entry4)); 0299 QVERIFY(filter1.matches(entry5)); 0300 0301 QString rxPattern = Tellico::FieldFormat::matchValueRegularExpression(pattern); 0302 // the filter should match entry1, entry3, and entry 4 but not entry2 or entry5 0303 Tellico::Filter filter2(Tellico::Filter::MatchAny); 0304 filter2.append(new Tellico::FilterRule(QStringLiteral("author"), rxPattern, Tellico::FilterRule::FuncRegExp)); 0305 QVERIFY(filter2.matches(entry1)); 0306 QVERIFY(!filter2.matches(entry2)); // does not match 0307 QVERIFY(filter2.matches(entry3)); 0308 QVERIFY(filter2.matches(entry4)); 0309 QVERIFY(!filter2.matches(entry5)); 0310 0311 // Bug 415886 0312 Tellico::Data::CollPtr coll2(new Tellico::Data::VideoCollection(true, QStringLiteral("TestCollection2"))); 0313 Tellico::Data::EntryPtr movie(new Tellico::Data::Entry(coll2)); 0314 movie->setField(QStringLiteral("cast"), QStringLiteral("John Author") + 0315 Tellico::FieldFormat::columnDelimiterString() + 0316 QStringLiteral("role")); 0317 Tellico::Filter castFilter(Tellico::Filter::MatchAny); 0318 castFilter.append(new Tellico::FilterRule(QStringLiteral("cast"), rxPattern, Tellico::FilterRule::FuncRegExp)); 0319 // single table row with value 0320 QVERIFY(castFilter.matches(movie)); 0321 movie->setField(QStringLiteral("cast"), QStringLiteral("John Author") + 0322 Tellico::FieldFormat::rowDelimiterString() + 0323 QStringLiteral("Second Author")); 0324 // multiple table row with value only 0325 QVERIFY(castFilter.matches(movie)); 0326 movie->setField(QStringLiteral("cast"), QStringLiteral("No one") + 0327 Tellico::FieldFormat::rowDelimiterString() + 0328 QStringLiteral("John Author") + 0329 Tellico::FieldFormat::rowDelimiterString() + 0330 QStringLiteral("Second Author")); 0331 // multiple table row with value second 0332 QVERIFY(castFilter.matches(movie)); 0333 } 0334 0335 void FilterTest::testQuickFilter() { 0336 Tellico::Data::CollPtr coll(new Tellico::Data::BookCollection(true, QStringLiteral("TestCollection"))); 0337 Tellico::Data::EntryPtr entry(new Tellico::Data::Entry(coll)); 0338 entry->setField(QStringLiteral("title"), QStringLiteral("C++ Coding Standards")); 0339 0340 Tellico::FilterPtr filter(new Tellico::Filter(Tellico::Filter::MatchAll)); 0341 QString fieldName; // empty means any field 0342 0343 Tellico::Filter::populateQuickFilter(filter, fieldName, QStringLiteral("C++")); 0344 QVERIFY(filter->matches(entry)); 0345 }