1
/****************************************************************************
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4
** Contact: http://www.qt-project.org/legal
6
** This file is part of the test suite of the Qt Toolkit.
8
** $QT_BEGIN_LICENSE:LGPL$
9
** Commercial License Usage
10
** Licensees holding valid commercial Qt licenses may use this file in
11
** accordance with the commercial license agreement provided with the
12
** Software or, alternatively, in accordance with the terms contained in
13
** a written agreement between you and Digia. For licensing terms and
14
** conditions see http://qt.digia.com/licensing. For further information
15
** use the contact form at http://qt.digia.com/contact-us.
17
** GNU Lesser General Public License Usage
18
** Alternatively, this file may be used under the terms of the GNU Lesser
19
** General Public License version 2.1 as published by the Free Software
20
** Foundation and appearing in the file LICENSE.LGPL included in the
21
** packaging of this file. Please review the following information to
22
** ensure the GNU Lesser General Public License version 2.1 requirements
23
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25
** In addition, as a special exception, Digia gives you certain additional
26
** rights. These rights are described in the Digia Qt LGPL Exception
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29
** GNU General Public License Usage
30
** Alternatively, this file may be used under the terms of the GNU
31
** General Public License version 3.0 as published by the Free Software
32
** Foundation and appearing in the file LICENSE.GPL included in the
33
** packaging of this file. Please review the following information to
34
** ensure the GNU General Public License version 3.0 requirements will be
35
** met: http://www.gnu.org/copyleft/gpl.html.
40
****************************************************************************/
42
#include <QtTest/QtTest>
44
#include "qorganizer.h"
47
//TESTED_COMPONENT=src/organizer
49
QTORGANIZER_USE_NAMESPACE
50
class tst_QOrganizerItemDetail : public QObject
55
tst_QOrganizerItemDetail();
56
virtual ~tst_QOrganizerItemDetail();
63
void classHierarchy();
73
tst_QOrganizerItemDetail::tst_QOrganizerItemDetail()
77
tst_QOrganizerItemDetail::~tst_QOrganizerItemDetail()
81
void tst_QOrganizerItemDetail::init()
85
void tst_QOrganizerItemDetail::cleanup()
89
/* Test class that doesn't do the right thing */
90
class NonMacroCustomDetail : public QOrganizerItemDetail
93
NonMacroCustomDetail() : QOrganizerItemDetail(QOrganizerItemDetail::TypeUndefined) {}
94
void doAssign(const QOrganizerItemDetail& other) {assign(other, QOrganizerItemDetail::TypeUndefined);}
95
NonMacroCustomDetail(const QOrganizerItemDetail& other)
96
: QOrganizerItemDetail(other, QOrganizerItemDetail::TypeUndefined) {}
99
class NonMacroCustomDetail2 : public QOrganizerItemDetail
102
NonMacroCustomDetail2() : QOrganizerItemDetail(QOrganizerItemDetail::TypeUndefined) {}
103
void doAssign(const QOrganizerItemDetail& other) {assign(other, QOrganizerItemDetail::TypeUndefined);}
104
NonMacroCustomDetail2(const QOrganizerItemDetail& other)
105
: QOrganizerItemDetail(other, QOrganizerItemDetail::TypeUndefined) {}
108
void tst_QOrganizerItemDetail::classHierarchy()
110
QOrganizerItemDetail f1;
111
QOrganizerItemDetail f2;
113
QVERIFY(f1.isEmpty());
114
QVERIFY(f2.isEmpty());
116
QOrganizerItemPriority p1;
117
p1.setPriority(QOrganizerItemPriority::VeryHighPriority);
118
QVERIFY(!p1.isEmpty());
119
QVERIFY(p1.type() == QOrganizerItemDetail::TypePriority);
121
QOrganizerItemComment m1;
122
m1.setComment("Bob");
123
QVERIFY(!m1.isEmpty());
124
QVERIFY(m1.type() == QOrganizerItemDetail::TypeComment);
129
f1 = p1; // f1 is a priority
132
f1 = f1; // assign to itself
138
p1 = p1; // assign leaf class to itself
143
f2 = f1; // f2 = f1 = priority
149
f1 = m1; // f1 = name, f2 = priority
154
QOrganizerItemPriority p2(f2); // p2 = f2 = priority
157
QCOMPARE(p2.priority(), p1.priority());
158
QCOMPARE(p2.priority(), QOrganizerItemPriority::VeryHighPriority);
160
p2 = p1; // priority to priority
163
QCOMPARE(p2.priority(), p1.priority());
164
QCOMPARE(p2.priority(), QOrganizerItemPriority::VeryHighPriority);
166
p2.setPriority(QOrganizerItemPriority::VeryLowPriority); // NOTE: implicitly shared, this has caused a detach so p1 != 2
170
QCOMPARE(p2.priority(), QOrganizerItemPriority::VeryLowPriority);
171
QCOMPARE(p1.priority(), QOrganizerItemPriority::VeryHighPriority);
174
p2 = m1; // assign a comment to a priority
176
QVERIFY(p2.type() == QOrganizerItemDetail::TypePriority);
177
QVERIFY(p2.isEmpty());
180
QOrganizerItemComment m2(m1);
183
/* another bad assignment */
184
m2 = p2; // priority to a comment
186
QVERIFY(m2.type() == QOrganizerItemDetail::TypeComment);
187
QVERIFY(m2.isEmpty());
189
/* Copy ctor from valid type */
190
QOrganizerItemDetail f3(p2);
192
QVERIFY(f3.type() == QOrganizerItemDetail::TypePriority);
194
/* Copy ctor from invalid type */
195
QOrganizerItemPriority p3(m1);
197
QVERIFY(p3.type() == QOrganizerItemDetail::TypePriority);
198
QVERIFY(p3.isEmpty());
200
/* Copy ctore from invalid type, through base type */
202
QOrganizerItemPriority p4(f3);
204
QVERIFY(p4.type() == QOrganizerItemDetail::TypePriority);
205
QVERIFY(p4.isEmpty());
207
/* Try a reference */
208
p1.setPriority(QOrganizerItemPriority::VeryLowPriority);
209
QOrganizerItemDetail& ref = p1;
210
QVERIFY(p1.priority() == QOrganizerItemPriority::VeryLowPriority);
211
QVERIFY(p1.value(QOrganizerItemPriority::FieldPriority).toInt() == static_cast<int>(QOrganizerItemPriority::VeryLowPriority));
212
QVERIFY(ref.value(QOrganizerItemPriority::FieldPriority).toInt() == static_cast<int>(QOrganizerItemPriority::VeryLowPriority));
216
/* Try changing the original */
217
p1.setPriority(QOrganizerItemPriority::MediumPriority);
218
QVERIFY(p1.priority() == QOrganizerItemPriority::MediumPriority);
219
QVERIFY(p1.value(QOrganizerItemPriority::FieldPriority).toInt() == static_cast<int>(QOrganizerItemPriority::MediumPriority));
220
QVERIFY(ref.value(QOrganizerItemPriority::FieldPriority).toInt() == static_cast<int>(QOrganizerItemPriority::MediumPriority));
224
/* Try changing the reference */
225
ref.setValue(QOrganizerItemPriority::FieldPriority, QOrganizerItemPriority::LowPriority);
226
QVERIFY(p1.priority() == QOrganizerItemPriority::LowPriority);
227
QVERIFY(p1.value(QOrganizerItemPriority::FieldPriority).toInt() == static_cast<int>(QOrganizerItemPriority::LowPriority));
228
QVERIFY(ref.value(QOrganizerItemPriority::FieldPriority).toInt() == static_cast<int>(QOrganizerItemPriority::LowPriority));
232
/* Random other test */
233
NonMacroCustomDetail md;
234
QVERIFY(md.type() == QOrganizerItemDetail::TypeUndefined);
235
QVERIFY(md.setValue(1, "value"));
236
QVERIFY(!md.isEmpty());
237
md.doAssign(md); // self assignment
238
QVERIFY(!md.isEmpty());
239
QVERIFY(md.value(1) == "value");
241
QOrganizerItemDetail mdv;
243
QVERIFY(mdv.type() == QOrganizerItemDetail::TypeUndefined);
244
QVERIFY(mdv.value(1) == "value");
247
QVERIFY(md.type() == QOrganizerItemDetail::TypeUndefined);
248
QVERIFY(md.value(1) == "value");
250
NonMacroCustomDetail2 md2;
251
QVERIFY(md2.setValue(1, "value"));
252
QVERIFY(md2.type() == QOrganizerItemDetail::TypeUndefined);
253
QVERIFY(md2.value(1) == "value");
257
QVERIFY(md.type() == QOrganizerItemDetail::TypeUndefined);
258
QVERIFY(md.value(1) == "value");
262
QVERIFY(md2.type() == QOrganizerItemDetail::TypeUndefined);
263
QVERIFY(md2.value(1) == "value");
268
// Assigning something else
269
QOrganizerItemPriority pn;
270
pn.setPriority(QOrganizerItemPriority::LowestPriority);
272
QVERIFY(md2.isEmpty());
273
QVERIFY(md2.type() == QOrganizerItemDetail::TypeUndefined);
275
NonMacroCustomDetail mdb(pn);
276
QVERIFY(mdb.isEmpty());
277
QVERIFY(mdb.type() == QOrganizerItemDetail::TypeUndefined);
279
NonMacroCustomDetail2 md2b(pn);
280
QVERIFY(md2b.isEmpty());
281
QVERIFY(md2b.type() == QOrganizerItemDetail::TypeUndefined);
284
void tst_QOrganizerItemDetail::assignment()
286
QOrganizerItemPriority p1, p2;
287
p1.setPriority(QOrganizerItemPriority::LowPriority);
288
p2.setPriority(QOrganizerItemPriority::HighPriority);
294
QOrganizerItemComment c1;
295
c1.setComment("test comment");
298
QVERIFY(c1 != p1); // assignment across types shouldn't work
299
QVERIFY(c1.comment() == QString()); // should reset the detail
300
QCOMPARE(c1, QOrganizerItemComment());
303
void tst_QOrganizerItemDetail::templates()
306
QOrganizerItemPriority p1, p2;
307
p1.setPriority(QOrganizerItemPriority::HighPriority);
308
p2.setPriority(QOrganizerItemPriority::HighestPriority);
309
QVERIFY(c.saveDetail(&p1));
310
QVERIFY(c.saveDetail(&p2));
312
QList<QOrganizerItemDetail> l = c.details(QOrganizerItemDetail::TypePriority);
314
QCOMPARE(l.count(), 2);
315
QCOMPARE(QOrganizerItemPriority(l.at(0)), p1);
316
QCOMPARE(QOrganizerItemPriority(l.at(1)), p2);
318
QList<QOrganizerItemDetail> l2 = c.details(QOrganizerItemDetail::TypePriority);
319
QCOMPARE(l2.count(), 2);
320
QCOMPARE(static_cast<QOrganizerItemPriority>(l2.at(0)), p1);
321
QCOMPARE(static_cast<QOrganizerItemPriority>(l2.at(1)), p2);
324
void tst_QOrganizerItemDetail::values()
326
QOrganizerItemDetail p;
328
QCOMPARE(p.values(), (QMap<int, QVariant>()));
330
QDateTime dt = QDateTime::currentDateTime();
332
t.setHMS(t.hour(), t.minute(), t.second(), 0); // milliseconds don't round trip through ISODate
336
QDateTime ddt(d); // DateTime version of a Date (QTime())
338
p.setValue(101, "This is a string");
341
p.setValue(104, (int)6);
343
p.setValue(105, d.toString(Qt::ISODate));
344
p.setValue(106, dt.toString(Qt::ISODate));
346
// Test the setter that takes a QString
347
p.setValue(107, "123");
349
// and the setter that takes a QL1C
350
p.setValue(QOrganizerItemPriority::FieldPriority, QVariant::fromValue(static_cast<int>(QOrganizerItemPriority::ExtremelyHighPriority)));
353
QVERIFY(p.hasValue(101));
354
QVERIFY(p.hasValue(102));
355
QVERIFY(p.hasValue(103));
356
QVERIFY(p.hasValue(104));
357
QVERIFY(p.hasValue(105));
358
QVERIFY(p.hasValue(106));
359
QVERIFY(p.hasValue(107));
360
QVERIFY(p.hasValue(QOrganizerItemPriority::FieldPriority));
361
QVERIFY(!p.hasValue(666));
363
QVERIFY(p.hasValue(QOrganizerItemPriority::FieldPriority));
365
/* Variant accessor */
366
QCOMPARE(p.value(101), QVariant(QString("This is a string")));
367
QCOMPARE(p.value(102), QVariant(d));
368
QCOMPARE(p.value(103), QVariant(dt));
369
QCOMPARE(p.value(104), QVariant((int)6));
370
QCOMPARE(p.value(105), QVariant(d.toString(Qt::ISODate)));
371
QCOMPARE(p.value(106), QVariant(dt.toString(Qt::ISODate)));
372
QCOMPARE(p.value(107), QVariant(QString("123")));
373
QCOMPARE(p.value(QOrganizerItemPriority::FieldPriority).toInt(), static_cast<int>(QOrganizerItemPriority::ExtremelyHighPriority));
375
/* Typed accessors */
376
QCOMPARE(p.value<QString>(101), QString("This is a string"));
377
QCOMPARE(p.value<QString>(102), d.toString(Qt::ISODate));
378
QCOMPARE(p.value<QString>(103), dt.toString(Qt::ISODate));
379
QCOMPARE(p.value<QString>(104), QString("6"));
380
QCOMPARE(p.value<QString>(105), d.toString(Qt::ISODate));
381
QCOMPARE(p.value<QString>(106), dt.toString(Qt::ISODate));
382
QCOMPARE(p.value<QString>(107), QString("123"));
383
QCOMPARE(p.value<int>(QOrganizerItemPriority::FieldPriority), static_cast<int>(QOrganizerItemPriority::ExtremelyHighPriority));
385
/* Now individual original types */
386
QCOMPARE(p.value<QDate>(102), d);
387
QCOMPARE(p.value<QDateTime>(103), dt);
388
QCOMPARE(p.value<int>(104), 6);
390
/* Now cross types that should fail */
393
QCOMPARE(p.value<QDate>(101), id);
394
QCOMPARE(p.value<QDate>(104), id);
395
QCOMPARE(p.value<QDate>(107), id);
396
QCOMPARE(p.value<QDateTime>(101), idt);
397
QCOMPARE(p.value<QDateTime>(104), idt);
398
QCOMPARE(p.value<QDateTime>(107), idt);
399
QCOMPARE(p.value<int>(102), 0);
400
QCOMPARE(p.value<int>(103), 0);
401
QCOMPARE(p.value<int>(101), 0);
402
QCOMPARE(p.value<int>(105), 0);
403
QCOMPARE(p.value<int>(106), 0);
405
/* Cross types that should work.. */
406
QCOMPARE(p.value<int>(107), 123);
407
QCOMPARE(p.value<QDate>(105), d);
408
QCOMPARE(p.value<QDateTime>(106), dt);
409
QCOMPARE(p.value<QDate>(103), d);
410
QCOMPARE(p.value<QDate>(106), d);
411
QCOMPARE(p.value<QDateTime>(102), ddt);
412
QCOMPARE(p.value<QDateTime>(105), ddt);
414
/* Now set everything again */
415
QMap<int, QVariant> emptyValues;
416
QMap<int, QVariant> values = p.values();
417
QList<int> keys = values.keys();
418
foreach (int key, keys)
419
QVERIFY(p.setValue(key, QVariant()));
421
QCOMPARE(p.values(), emptyValues);
422
QVERIFY(p.values().count() == 0);
423
QVERIFY(!p.hasValue(101));
424
QVERIFY(!p.hasValue(102));
425
QVERIFY(!p.hasValue(103));
426
QVERIFY(!p.hasValue(104));
427
QVERIFY(!p.hasValue(105));
428
QVERIFY(!p.hasValue(106));
429
QVERIFY(!p.hasValue(107));
430
QVERIFY(!p.hasValue(666));
432
QVERIFY(p.value(101).toString() == QString());
433
QVERIFY(p.value(101) == QVariant());
435
values.insert(101, "This is a string");
436
values.insert(102, d);
437
values.insert(103, dt);
438
values.insert(104, (int)6);
440
values.insert(105, d.toString(Qt::ISODate));
441
values.insert(106, dt.toString(Qt::ISODate));
442
values.insert(107, "123");
443
values.insert(101, QString("This is a string"));
446
keys = values.keys();
447
foreach (int key, keys)
448
QVERIFY(p.setValue(key, values.value(key)));
450
/* Now repeat the tests with our bulk set map */
451
QVERIFY(p.hasValue(101));
452
QVERIFY(p.hasValue(102));
453
QVERIFY(p.hasValue(103));
454
QVERIFY(p.hasValue(104));
455
QVERIFY(p.hasValue(105));
456
QVERIFY(p.hasValue(106));
457
QVERIFY(p.hasValue(107));
458
QVERIFY(!p.hasValue(666));
460
/* String accessors */
461
QCOMPARE(p.value(101).toString(), QString("This is a string"));
462
QCOMPARE(p.value(102).toString(), d.toString(Qt::ISODate));
463
QCOMPARE(p.value(103).toString(), dt.toString(Qt::ISODate));
464
QCOMPARE(p.value(104).toString(), QString("6"));
465
QCOMPARE(p.value(105).toString(), d.toString(Qt::ISODate));
466
QCOMPARE(p.value(106).toString(), dt.toString(Qt::ISODate));
467
QCOMPARE(p.value(107).toString(), QString("123"));
469
/* Typed accessors, string first */
470
QCOMPARE(p.value<QString>(101), QString("This is a string"));
471
QCOMPARE(p.value<QString>(102), d.toString(Qt::ISODate));
472
QCOMPARE(p.value<QString>(103), dt.toString(Qt::ISODate));
473
QCOMPARE(p.value<QString>(104), QString("6"));
474
QCOMPARE(p.value<QString>(105), d.toString(Qt::ISODate));
475
QCOMPARE(p.value<QString>(106), dt.toString(Qt::ISODate));
476
QCOMPARE(p.value<QString>(107), QString("123"));
478
/* Now individual original types */
479
QCOMPARE(p.value<QDate>(102), d);
480
QCOMPARE(p.value<QDateTime>(103), dt);
481
QCOMPARE(p.value<int>(104), 6);
483
/* Now cross types that should fail */
484
QCOMPARE(p.value<QDate>(101), id);
485
QCOMPARE(p.value<QDate>(104), id);
486
QCOMPARE(p.value<QDate>(107), id);
487
QCOMPARE(p.value<QDateTime>(101), idt);
488
QCOMPARE(p.value<QDateTime>(104), idt);
489
QCOMPARE(p.value<QDateTime>(107), idt);
490
QCOMPARE(p.value<int>(101), 0);
491
QCOMPARE(p.value<int>(102), 0);
492
QCOMPARE(p.value<int>(103), 0);
493
QCOMPARE(p.value<int>(105), 0);
494
QCOMPARE(p.value<int>(106), 0);
496
/* Cross types that should work.. */
497
QCOMPARE(p.value<int>(107), 123);
498
QCOMPARE(p.value<QDate>(105), d);
499
QCOMPARE(p.value<QDateTime>(106), dt);
500
QCOMPARE(p.value<QDate>(103), d);
501
QCOMPARE(p.value<QDate>(106), d);
502
QCOMPARE(p.value<QDateTime>(102), ddt);
503
QCOMPARE(p.value<QDateTime>(105), ddt);
507
keys = values.keys();
508
foreach (int key, keys)
509
QVERIFY(p.setValue(key, QVariant()));
510
QCOMPARE(p.values(), emptyValues);
512
/* Check that we can add a null variant */
513
//QVERIFY(p.setValue("nullvariant", QVariant()));
514
//QVERIFY(p.hasValue("nullvariant"));
515
//QCOMPARE(p.value("nullvariant"), QString());
516
//QCOMPARE(p.value("nullvariant"), QVariant());
517
//QVERIFY(p.removeValue("nullvariant"));
518
//QVERIFY(p.values().count() == 0);
520
/* Check that adding a value, then setting it to null updates it */
521
//QVERIFY(p.setValue("string", QString("string value")));
522
//QCOMPARE(p.values().count(), 1);
523
//QCOMPARE(p.value("string"), QString("string value"));
524
//QVERIFY(p.setValue("string", QVariant()));
525
//QCOMPARE(p.values().count(), 1);
526
//QVERIFY(p.hasValue("string"));
527
//QVERIFY(p.removeValue("string"));
528
//QCOMPARE(p.values().count(), 0);
530
/* See if adding a null QString triggers the same behaviour */
531
//QVERIFY(p.setValue("string", QString("string value")));
532
//QCOMPARE(p.values().count(), 1);
533
//QCOMPARE(p.value("string"), QString("string value"));
534
//QVERIFY(p.setValue("string", QString()));
535
//QCOMPARE(p.values().count(), 1);
536
//QVERIFY(p.hasValue("string"));
537
//QVERIFY(p.removeValue("string"));
538
//QCOMPARE(p.values().count(), 0);
540
/* Check adding a null value removes the field */
541
p.setValue(101, "stringvalue");
542
QVERIFY(p.values().contains(101));
543
QVERIFY(p.value(101) == QString("stringvalue"));
544
p.setValue(101, QVariant());
545
QVERIFY(!p.values().contains(101));
547
/* Check adding a field whose value is an empty string */
549
QVERIFY(p.values().contains(101));
550
QVERIFY(p.value(101) == QString(""));
552
/* Check accessing a missing value */
553
QCOMPARE(p.value(666).toString(), QString());
554
QVERIFY(p.setValue(666, "changed my mind"));
555
QCOMPARE(p.value(666).toString(), QString("changed my mind"));
557
/* Check removing a missing value */
558
QVERIFY(!p.removeValue(777));
559
QVERIFY(!p.removeValue(QOrganizerItemComment::FieldComment));
561
p.setValue(107, "555");
562
p.setValue(QOrganizerItemPriority::FieldPriority, "1234");
564
/* Check removing a real value */
565
QVERIFY(p.removeValue(101));
566
QVERIFY(p.removeValue(107));
567
QVERIFY(p.removeValue(QOrganizerItemPriority::FieldPriority));
570
void tst_QOrganizerItemDetail::hash()
572
QOrganizerItemDetail detail1(QOrganizerItemDetail::TypeComment);
573
detail1.setValue(QOrganizerItemComment::FieldComment, "value");
574
QOrganizerItemDetail detail2(QOrganizerItemDetail::TypeComment);
575
detail2.setValue(QOrganizerItemComment::FieldComment, "value");
576
QOrganizerItemDetail detail3(QOrganizerItemDetail::TypeComment);
577
detail3.setValue(QOrganizerItemComment::FieldComment, "different value");
578
QVERIFY(qHash(detail1) == qHash(detail2));
579
QVERIFY(qHash(detail1) != qHash(detail3));
580
QSet<QOrganizerItemDetail> set;
584
QCOMPARE(set.size(), 2);
587
void tst_QOrganizerItemDetail::datastream()
590
QDataStream stream1(&buffer, QIODevice::WriteOnly);
591
QOrganizerItemDetail detailIn(QOrganizerItemDetail::TypeComment);
592
detailIn.setValue(QOrganizerItemComment::FieldComment, "value1");
595
QVERIFY(buffer.size() > 0);
597
QDataStream stream2(buffer);
598
QOrganizerItemDetail detailOut;
599
stream2 >> detailOut;
600
QCOMPARE(detailOut, detailIn);
603
void tst_QOrganizerItemDetail::traits()
605
QCOMPARE(sizeof(QOrganizerItemDetail), sizeof(void *));
606
QTypeInfo<QOrganizerItemDetail> ti;
607
QVERIFY(ti.isComplex);
608
QVERIFY(!ti.isStatic);
609
QVERIFY(!ti.isLarge);
610
QVERIFY(!ti.isPointer);
611
QVERIFY(!ti.isDummy);
614
void tst_QOrganizerItemDetail::keys()
616
QOrganizerItemDetail d;
617
QOrganizerItemDetail d2;
618
QVERIFY(d.key() != d2.key());
621
QVERIFY(d.key() == d2.key());
623
QVERIFY(d.key() != d2.key());
626
QTEST_MAIN(tst_QOrganizerItemDetail)
627
#include "tst_qorganizeritemdetail.moc"