File indexing completed on 2024-05-12 07:47:14
0001 /* 0002 This file is part of the kcalcore library. 0003 0004 SPDX-FileCopyrightText: 2006, 2008 Allen Winter <winter@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 #include "testtodo.h" 0009 #include "attachment.h" 0010 #include "event.h" 0011 #include "sorting.h" 0012 #include "todo.h" 0013 0014 #include <QTest> 0015 #include <QTimeZone> 0016 QTEST_MAIN(TodoTest) 0017 0018 using namespace KCalendarCore; 0019 0020 const auto TEST_TZ = "UTC"; 0021 0022 void TodoTest::initTestCase() 0023 { 0024 qputenv("TZ", TEST_TZ); 0025 } 0026 0027 void TodoTest::testValidity() 0028 { 0029 QDate dt = QDate::currentDate(); 0030 Todo todo; 0031 todo.setDtStart(QDateTime(dt, {})); 0032 todo.setDtDue(QDateTime(dt, {}).addDays(1)); 0033 todo.setSummary(QStringLiteral("To-do1 Summary")); 0034 todo.setDescription(QStringLiteral("This is a description of the first to-do")); 0035 todo.setLocation(QStringLiteral("the place")); 0036 todo.setPercentComplete(5); 0037 0038 QCOMPARE(todo.summary(), QStringLiteral("To-do1 Summary")); 0039 QCOMPARE(todo.location(), QStringLiteral("the place")); 0040 QCOMPARE(todo.percentComplete(), 5); 0041 } 0042 0043 void TodoTest::testCompare() 0044 { 0045 QDate dt = QDate::currentDate(); 0046 Todo todo1; 0047 todo1.setDtStart(QDateTime(dt, {})); 0048 todo1.setDtDue(QDateTime(dt, {}).addDays(1)); 0049 todo1.setSummary(QStringLiteral("To-do1 Summary")); 0050 todo1.setDescription(QStringLiteral("This is a description of the first to-do")); 0051 todo1.setLocation(QStringLiteral("the place")); 0052 todo1.setCompleted(true); 0053 0054 Todo todo2; 0055 todo2.setDtStart(QDateTime(dt, {}).addDays(1)); 0056 todo2.setDtDue(QDateTime(dt, {}).addDays(2)); 0057 todo2.setSummary(QStringLiteral("To-do2 Summary")); 0058 todo2.setDescription(QStringLiteral("This is a description of the second to-do")); 0059 todo2.setLocation(QStringLiteral("the other place")); 0060 todo2.setCompleted(false); 0061 0062 QVERIFY(!(todo1 == todo2)); 0063 QCOMPARE(todo1.dtDue(), todo2.dtStart()); 0064 QCOMPARE(todo2.summary(), QStringLiteral("To-do2 Summary")); 0065 QVERIFY(!(todo1.isCompleted() == todo2.isCompleted())); 0066 } 0067 0068 void TodoTest::testDtDueEqual() 0069 { 0070 QDateTime dt {QDate::currentDate(), QTime::currentTime(), QTimeZone(TEST_TZ)}; 0071 QVERIFY(dt.timeSpec() == Qt::TimeZone); 0072 0073 Todo t1; 0074 t1.setDtDue(dt); 0075 auto t2 = t1.clone(); 0076 QVERIFY(t1 == *t2); 0077 0078 // Create a "floating" datetime, which represents the same instant in real time 0079 // because we're still running in the test's time zone. 0080 dt.setTimeZone(QTimeZone::LocalTime); 0081 0082 t1.setDtDue(dt); 0083 QVERIFY(t1 != *t2); 0084 t2->setDtDue(dt); 0085 QVERIFY(t1 == *t2); 0086 } 0087 0088 void TodoTest::testClone() 0089 { 0090 QDate dt = QDate::currentDate(); 0091 Todo todo1; 0092 todo1.setDtStart(QDateTime(dt, {})); 0093 todo1.setDtDue(QDateTime(dt, {}).addDays(1)); 0094 todo1.setSummary(QStringLiteral("Todo1 Summary")); 0095 todo1.setDescription(QStringLiteral("This is a description of the first todo")); 0096 todo1.setLocation(QStringLiteral("the place")); 0097 0098 Todo *todo2 = todo1.clone(); 0099 QCOMPARE(todo1.summary(), todo2->summary()); 0100 QCOMPARE(todo1.dtStart(), todo2->dtStart()); 0101 QCOMPARE(todo1.dtDue(), todo2->dtDue()); 0102 QCOMPARE(todo1.description(), todo2->description()); 0103 QCOMPARE(todo1.location(), todo2->location()); 0104 QCOMPARE(todo1.isCompleted(), todo2->isCompleted()); 0105 delete todo2; 0106 } 0107 0108 void TodoTest::testCopyIncidence() 0109 { 0110 QDate dt = QDate::currentDate(); 0111 Event event; 0112 event.setDtStart(QDateTime(dt, {})); 0113 event.setSummary(QStringLiteral("Event1 Summary")); 0114 event.setDescription(QStringLiteral("This is a description of the first event")); 0115 event.setLocation(QStringLiteral("the place")); 0116 0117 Todo todo(event); 0118 QCOMPARE(todo.uid(), event.uid()); 0119 QCOMPARE(todo.dtStart(), event.dtStart()); 0120 QCOMPARE(todo.summary(), event.summary()); 0121 QCOMPARE(todo.description(), event.description()); 0122 QCOMPARE(todo.location(), event.location()); 0123 } 0124 0125 void TodoTest::testCopyConstructor() 0126 { 0127 QDate dt = QDate::currentDate(); 0128 Todo todo1; 0129 todo1.setDtStart(QDateTime(dt, {})); 0130 todo1.setDtDue(QDateTime(dt, {}).addDays(1)); 0131 todo1.setSummary(QStringLiteral("Todo1 Summary")); 0132 todo1.setDescription(QStringLiteral("This is a description of the first todo")); 0133 todo1.setLocation(QStringLiteral("the place")); 0134 0135 Todo todo2 {todo1}; 0136 QVERIFY(todo1 == todo2); 0137 } 0138 0139 void TodoTest::testAssign() 0140 { 0141 QDate dt = QDate::currentDate(); 0142 Todo todo1; 0143 todo1.setDtStart(QDateTime(dt, {})); 0144 todo1.setDtDue(QDateTime(dt, {}).addDays(1)); 0145 todo1.setSummary(QStringLiteral("Todo1 Summary")); 0146 todo1.setDescription(QStringLiteral("This is a description of the first todo")); 0147 todo1.setLocation(QStringLiteral("the place")); 0148 0149 IncidenceBase *todo2 = new Todo; 0150 *todo2 = todo1; // Use IncidenceBase's virtual assignment. 0151 QVERIFY(todo1 == *todo2); 0152 0153 // release todo2 0154 delete todo2; 0155 } 0156 0157 void TodoTest::testSetCompletedWithDate() 0158 { 0159 Todo t; 0160 t.setStatus(Incidence::StatusNone); 0161 QVERIFY(!t.isCompleted()); 0162 QVERIFY(!t.hasCompletedDate()); 0163 QVERIFY(t.status() != Incidence::StatusCompleted); 0164 QVERIFY(t.percentComplete() != 100); 0165 0166 const auto now = QDateTime::currentDateTimeUtc(); 0167 t.setCompleted(now); 0168 QVERIFY(t.isCompleted()); 0169 QVERIFY(t.completed() == now); 0170 QVERIFY(t.hasCompletedDate()); 0171 QVERIFY(t.status() == Incidence::StatusNone); 0172 QVERIFY(t.percentComplete() == 100); 0173 } 0174 0175 void TodoTest::testSetCompletedWithoutDate() 0176 { 0177 Todo t; 0178 t.setStatus(Incidence::StatusNeedsAction); 0179 QVERIFY(!t.isCompleted()); 0180 QVERIFY(!t.hasCompletedDate()); 0181 QVERIFY(t.status() != Incidence::StatusCompleted); 0182 QVERIFY(t.percentComplete() != 100); 0183 0184 t.setCompleted(QDateTime()); 0185 QVERIFY(t.isCompleted()); 0186 QVERIFY(!t.hasCompletedDate()); 0187 QVERIFY(t.status() == Incidence::StatusCompleted); 0188 QVERIFY(t.percentComplete() == 100); 0189 } 0190 0191 void TodoTest::testSetCompleted() 0192 { 0193 Todo todo1; 0194 todo1.setSummary(QStringLiteral("Todo Summary")); 0195 QDateTime today = QDateTime::currentDateTimeUtc(); 0196 0197 // due yesterday 0198 QDateTime originalDueDate = today.addDays(-1); 0199 0200 todo1.setDtStart(originalDueDate); 0201 todo1.setDtDue(originalDueDate); 0202 todo1.recurrence()->setDaily(1); 0203 todo1.setCompleted(today); 0204 QVERIFY(originalDueDate != todo1.dtDue()); 0205 QVERIFY(!todo1.isCompleted()); 0206 } 0207 0208 void TodoTest::testSetCompletedBool() 0209 { 0210 Todo t; 0211 QVERIFY(!t.isCompleted()); 0212 QVERIFY(!t.hasCompletedDate()); 0213 QVERIFY(t.status() != Incidence::StatusCompleted); 0214 QVERIFY(t.percentComplete() != 100); 0215 0216 t.setCompleted(true); 0217 QVERIFY(t.isCompleted()); 0218 QVERIFY(!t.hasCompletedDate()); 0219 QVERIFY(t.status() == Incidence::StatusCompleted); 0220 QVERIFY(t.percentComplete() == 100); 0221 0222 const auto yesterday = QDateTime::currentDateTimeUtc().addDays(-1); 0223 t.setCompleted(yesterday); 0224 t.setCompleted(true); 0225 QVERIFY(t.isCompleted()); 0226 QVERIFY(t.completed() == yesterday); 0227 QVERIFY(t.status() == Incidence::StatusCompleted); 0228 QVERIFY(t.percentComplete() == 100); 0229 0230 t.setCompleted(false); 0231 QVERIFY(!t.isCompleted()); 0232 QVERIFY(!t.hasCompletedDate()); 0233 QVERIFY(t.status() == Incidence::StatusNone); 0234 QVERIFY(t.percentComplete() == 0); 0235 } 0236 0237 void TodoTest::testSetPercent() 0238 { 0239 Todo t; 0240 t.setStatus(Incidence::StatusCompleted); 0241 t.setCompleted(QDateTime::currentDateTimeUtc()); 0242 t.setPercentComplete(100); 0243 QVERIFY(t.percentComplete() == 100); 0244 QVERIFY(t.isCompleted()); 0245 0246 // Completion reset if necessary. 0247 QVERIFY(t.hasCompletedDate()); 0248 t.setPercentComplete(99); 0249 QVERIFY(t.percentComplete() == 99); 0250 QVERIFY(!t.isCompleted()); 0251 QVERIFY(!t.hasCompletedDate()); 0252 QVERIFY(t.status() != Incidence::StatusCompleted); 0253 0254 t.setPercentComplete(0); 0255 QVERIFY(t.percentComplete() == 0); 0256 QVERIFY(!t.isCompleted()); 0257 QVERIFY(!t.hasCompletedDate()); 0258 QVERIFY(t.status() != Incidence::StatusCompleted); 0259 } 0260 0261 void TodoTest::testStatus() 0262 { 0263 QDateTime today = QDateTime::currentDateTimeUtc(); 0264 QDateTime yesterday = today.addDays(-1); 0265 0266 Todo todo1; 0267 todo1.setAllDay(true); 0268 todo1.setDtStart(yesterday); 0269 todo1.setDtDue(today); 0270 todo1.setPercentComplete(50); 0271 QVERIFY(todo1.isInProgress(false)); 0272 QVERIFY(!todo1.isNotStarted(false)); 0273 QVERIFY(!todo1.isOverdue()); 0274 todo1.setPercentComplete(100); 0275 QVERIFY(todo1.isCompleted()); 0276 0277 Todo todo2 = todo1; 0278 todo2.setPercentComplete(33); 0279 todo2.setDtDue(QDateTime()); 0280 QVERIFY(todo2.isOpenEnded()); 0281 } 0282 0283 void TodoTest::testSerializer_data() 0284 { 0285 QTest::addColumn<KCalendarCore::Todo::Ptr>("todo"); 0286 0287 QDateTime today = QDateTime::currentDateTimeUtc(); 0288 QDateTime yesterday = today.addDays(-1); 0289 0290 Todo::Ptr todo1 = Todo::Ptr(new Todo()); 0291 Todo::Ptr todo2 = Todo::Ptr(new Todo()); 0292 Todo::Ptr todo3 = Todo::Ptr(new Todo()); 0293 Todo::Ptr todo4 = Todo::Ptr(new Todo()); 0294 Todo::Ptr todo5 = Todo::Ptr(new Todo()); 0295 Todo::Ptr todo6 = Todo::Ptr(new Todo()); 0296 0297 todo1->setSummary(QStringLiteral("Summary"), false); 0298 todo1->setDescription(QStringLiteral("description"), false); 0299 todo1->setCreated(yesterday); 0300 todo1->setRevision(50); 0301 todo1->setDtDue(yesterday); 0302 todo1->setDtStart(today); 0303 todo1->setPercentComplete(50); 0304 todo1->setLocation(QStringLiteral("<b>location</b>"), false); 0305 0306 todo2->setDescription(QStringLiteral("<b>description</b>"), true); 0307 todo2->setSummary(QStringLiteral("<b>Summary2</b>"), true); 0308 todo2->setLocation(QStringLiteral("<b>location</b>"), true); 0309 todo2->setDtDue(yesterday); 0310 todo2->setPercentComplete(100); 0311 0312 todo3->setDtStart(today); 0313 todo3->setPercentComplete(100); 0314 todo3->setCategories(QStringList() << QStringLiteral("a") << QStringLiteral("b") << QStringLiteral("c") << QStringLiteral("d")); 0315 todo3->setResources(QStringList() << QStringLiteral("a") << QStringLiteral("b") << QStringLiteral("c") << QStringLiteral("d")); 0316 todo3->setPriority(5); 0317 0318 QVERIFY(!todo4->dirtyFields().contains(IncidenceBase::FieldRecurrence)); 0319 todo4->recurrence()->setDaily(1); 0320 QVERIFY(todo4->dirtyFields().contains(IncidenceBase::FieldRecurrence)); 0321 0322 Attachment attachment(QStringLiteral("http://www.kde.org")); 0323 todo4->addAttachment(attachment); 0324 0325 todo5->recurrence()->setDaily(1); 0326 todo5->setCompleted(today); 0327 todo5->setStatus(Incidence::StatusDraft); 0328 todo5->setSecrecy(Incidence::SecrecyPrivate); 0329 todo5->setRelatedTo(QStringLiteral("uid1"), Incidence::RelTypeParent); 0330 todo5->setGeoLatitude(40); 0331 todo5->setGeoLongitude(40); 0332 todo5->setOrganizer(QStringLiteral("organizer@mail.com")); 0333 0334 todo6->recurrence()->setDaily(1); 0335 todo6->setCompleted(today); 0336 todo6->setRecurrenceId(yesterday); 0337 todo6->setStatus(Incidence::StatusDraft); 0338 todo6->setSecrecy(Incidence::SecrecyPrivate); 0339 todo6->setRelatedTo(QStringLiteral("uid1"), Incidence::RelTypeParent); 0340 todo6->setGeoLatitude(40); 0341 todo6->setGeoLongitude(40); 0342 todo6->setUid(QStringLiteral("uid22")); 0343 todo6->setLastModified(today); 0344 todo6->addContact(QStringLiteral("addContact")); 0345 0346 // Remaining properties tested in testevent.cpp 0347 0348 QTest::newRow("todo1") << todo1; 0349 QTest::newRow("todo2") << todo2; 0350 QTest::newRow("todo3") << todo3; 0351 QTest::newRow("todo4") << todo4; 0352 QTest::newRow("todo5") << todo5; 0353 QTest::newRow("todo6") << todo6; 0354 } 0355 0356 void TodoTest::testSerializer() 0357 { 0358 QFETCH(KCalendarCore::Todo::Ptr, todo); 0359 IncidenceBase::Ptr incidenceBase = todo.staticCast<KCalendarCore::IncidenceBase>(); 0360 0361 QByteArray array; 0362 QDataStream stream(&array, QIODevice::WriteOnly); 0363 stream << incidenceBase; 0364 0365 Todo::Ptr todo2 = Todo::Ptr(new Todo()); 0366 IncidenceBase::Ptr incidenceBase2 = todo2.staticCast<KCalendarCore::IncidenceBase>(); 0367 QVERIFY(*todo != *todo2); 0368 QDataStream stream2(&array, QIODevice::ReadOnly); 0369 stream2 >> incidenceBase2; 0370 QVERIFY(*todo == *todo2); 0371 } 0372 0373 void TodoTest::testRoles() 0374 { 0375 const QDateTime today = QDateTime::currentDateTimeUtc(); 0376 const QDateTime yesterday = today.addDays(-1); 0377 Todo todo; 0378 todo.setDtStart(today.addDays(-1)); 0379 todo.setDtDue(today); 0380 QCOMPARE(todo.dateTime(Incidence::RoleDisplayStart), today); 0381 QCOMPARE(todo.dateTime(Incidence::RoleDisplayEnd), today); 0382 todo.setDtDue(QDateTime()); 0383 QCOMPARE(todo.dateTime(Incidence::RoleDisplayStart), yesterday); 0384 QCOMPARE(todo.dateTime(Incidence::RoleDisplayEnd), yesterday); 0385 } 0386 0387 void TodoTest::testIconNameOneoff() 0388 { 0389 const QDateTime now = QDateTime::currentDateTime(); 0390 Todo todo; 0391 todo.setDtStart(now); 0392 0393 QCOMPARE(todo.iconName(), QLatin1String("view-calendar-tasks")); 0394 todo.setCompleted(now); 0395 QCOMPARE(todo.iconName(), QLatin1String("task-complete")); 0396 } 0397 0398 void TodoTest::testIconNameRecurringNeverDue() 0399 { 0400 const QDateTime now = QDateTime::currentDateTime(); 0401 Todo todo; 0402 todo.setDtStart(now); 0403 todo.recurrence()->setDaily(1); 0404 0405 QCOMPARE(todo.iconName(now), QLatin1String("view-calendar-tasks")); 0406 0407 todo.setCompleted(now); 0408 QCOMPARE(todo.iconName(now), QLatin1String("task-complete")); 0409 QCOMPARE(todo.iconName(now.addDays(1)), QLatin1String("view-calendar-tasks")); 0410 } 0411 0412 void TodoTest::testIconNameRecurringDue() 0413 { 0414 const QDateTime now = QDateTime::currentDateTime(); 0415 const QDateTime later = now.addSecs(3600); 0416 Todo todo; 0417 todo.setDtStart(now); 0418 todo.setDtDue(later, /*first=*/true); 0419 todo.recurrence()->setDaily(1); 0420 0421 QCOMPARE(todo.iconName(now), QLatin1String("view-calendar-tasks")); 0422 QCOMPARE(todo.iconName(later), QLatin1String("view-calendar-tasks")); // Legacy case 0423 0424 todo.setCompleted(now); 0425 QCOMPARE(todo.iconName(now), QLatin1String("task-complete")); 0426 QCOMPARE(todo.iconName(later), QLatin1String("task-complete")); // Legacy case 0427 QCOMPARE(todo.iconName(now.addDays(1)), QLatin1String("view-calendar-tasks")); 0428 } 0429 0430 void TodoTest::testCategoriesComparison() 0431 { 0432 QSharedPointer<Todo> small(new Todo); 0433 small->setCategories({QStringLiteral("alpha")}); 0434 small->setSummary(QStringLiteral("alpha")); 0435 0436 QSharedPointer<Todo> medium(new Todo); 0437 medium->setCategories({QStringLiteral("beta")}); 0438 medium->setSummary(QStringLiteral("beta 1")); 0439 0440 QSharedPointer<Todo> large(new Todo); 0441 large->setCategories({QStringLiteral("beta")}); 0442 large->setSummary(QStringLiteral("beta 2")); 0443 0444 QVERIFY(Incidences::categoriesLessThan(small, medium)); 0445 QVERIFY(!Incidences::categoriesLessThan(medium, small)); 0446 QVERIFY(Incidences::categoriesLessThan(medium, large)); 0447 QVERIFY(!Incidences::categoriesLessThan(large, medium)); 0448 QVERIFY(!Incidences::categoriesLessThan(small, small)); 0449 0450 QVERIFY(!Incidences::categoriesMoreThan(small, medium)); 0451 QVERIFY(Incidences::categoriesMoreThan(medium, small)); 0452 QVERIFY(!Incidences::categoriesMoreThan(medium, large)); 0453 QVERIFY(Incidences::categoriesMoreThan(large, medium)); 0454 QVERIFY(!Incidences::categoriesMoreThan(small, small)); 0455 } 0456 0457 void TodoTest::testDtDueComparison() 0458 { 0459 auto now = QDateTime::currentDateTime(); 0460 auto later = now.addSecs(1); 0461 0462 QSharedPointer<Todo> small(new Todo); 0463 small->setDtDue(now); 0464 small->setAllDay(false); 0465 small->setSummary(QStringLiteral("now")); 0466 0467 QSharedPointer<Todo> medium(new Todo); 0468 medium->setDtDue(later); 0469 medium->setAllDay(false); 0470 medium->setSummary(QStringLiteral("later 1")); 0471 0472 QSharedPointer<Todo> large(new Todo); 0473 large->setDtDue(later); 0474 large->setAllDay(false); 0475 large->setSummary(QStringLiteral("later 2")); 0476 0477 QSharedPointer<Todo> never(new Todo); 0478 never->setDtDue(QDateTime()); 0479 never->setAllDay(false); 0480 never->setSummary(QStringLiteral("never")); 0481 0482 QVERIFY(Todos::dueDateLessThan(small, medium)); 0483 QVERIFY(!Todos::dueDateLessThan(medium, small)); 0484 QVERIFY(Todos::dueDateLessThan(medium, large)); 0485 QVERIFY(!Todos::dueDateLessThan(large, medium)); 0486 QVERIFY(Todos::dueDateLessThan(large, never)); 0487 QVERIFY(!Todos::dueDateLessThan(never, large)); 0488 QVERIFY(!Todos::dueDateLessThan(small, small)); 0489 QVERIFY(!Todos::dueDateLessThan(never, never)); 0490 0491 QVERIFY(!Todos::dueDateMoreThan(small, medium)); 0492 QVERIFY(Todos::dueDateMoreThan(medium, small)); 0493 QVERIFY(!Todos::dueDateMoreThan(medium, large)); 0494 QVERIFY(Todos::dueDateMoreThan(large, medium)); 0495 QVERIFY(!Todos::dueDateMoreThan(large, never)); 0496 QVERIFY(Todos::dueDateMoreThan(never, large)); 0497 QVERIFY(!Todos::dueDateMoreThan(small, small)); 0498 QVERIFY(!Todos::dueDateLessThan(never, never)); 0499 } 0500 0501 void TodoTest::testDtDueChange() 0502 { 0503 const QDate date {QDate::currentDate()}; 0504 const QTime time {1, 0, 0}; 0505 Todo todo; 0506 // Note: QDateTime's default timespec QTimeZone::LocalTime => "floating" time. 0507 todo.setDtDue(QDateTime(date, time)); 0508 0509 todo.resetDirtyFields(); 0510 todo.setDtDue(QDateTime(date, time)); // No change. 0511 QVERIFY(todo.dirtyFields().empty()); 0512 0513 todo.setDtDue(QDateTime(date, time).addDays(1)); // Normal change. 0514 QCOMPARE(todo.dirtyFields(), QSet<IncidenceBase::Field>{IncidenceBase::FieldDtDue}); 0515 0516 todo.resetDirtyFields(); 0517 todo.setDtDue(QDateTime()); // "Unset" dtDue. 0518 QCOMPARE(todo.dirtyFields(), QSet<IncidenceBase::Field>{IncidenceBase::FieldDtDue}); 0519 0520 todo.resetDirtyFields(); 0521 todo.setDtDue(QDateTime(date, time)); // Setting an unset due datetime. 0522 QCOMPARE(todo.dirtyFields(), QSet<IncidenceBase::Field>{IncidenceBase::FieldDtDue}); 0523 0524 // Change from a floating time to the same time in a fixed time zone. 0525 todo.resetDirtyFields(); 0526 todo.setDtDue(QDateTime(date, time, QTimeZone(TEST_TZ))); 0527 QCOMPARE(todo.dirtyFields(), QSet<IncidenceBase::Field>{IncidenceBase::FieldDtDue}); 0528 0529 // Change from a time in a fixed time zone to a floating time. 0530 todo.resetDirtyFields(); 0531 todo.setDtDue(QDateTime(date, time, QTimeZone::LocalTime)); 0532 QCOMPARE(todo.dirtyFields(), QSet<IncidenceBase::Field>{IncidenceBase::FieldDtDue}); 0533 } 0534 0535 #include "moc_testtodo.cpp"