1/****************************************************************************
2**
3** Copyright (C) 2015 The Qt Company Ltd.
4** Contact: http://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL21$
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 The Qt Company. For licensing terms
14** and conditions see http://www.qt.io/terms-conditions. For further
15** information use the contact form at http://www.qt.io/contact-us.
16**
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 or version 3 as published by the Free
20** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22** following information to ensure the GNU Lesser General Public License
23** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25**
26** As a special exception, The Qt Company gives you certain additional
27** rights. These rights are described in The Qt Company LGPL Exception
28** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29**
30** $QT_END_LICENSE$
31**
32****************************************************************************/
33
34#include <QtTest/QtTest>
35
36#include <QtCore/qset.h>
37
38#include <QtOrganizer/qorganizer.h>
39#include <QtOrganizer/qorganizeritemid.h>
40
41//TESTED_COMPONENT=src/organizer
42
43QTORGANIZER_USE_NAMESPACE
44
45static inline QOrganizerCollectionId makeId(const QString &managerName, uint id)
46{
47 return QOrganizerCollectionId(QStringLiteral("qtorganizer:%1:").arg(a: managerName), QByteArray(reinterpret_cast<const char *>(&id), sizeof(uint)));
48}
49
50
51class tst_QOrganizerCollection: public QObject
52{
53Q_OBJECT
54
55public:
56 tst_QOrganizerCollection();
57 virtual ~tst_QOrganizerCollection();
58
59private slots:
60 void metaData();
61 void compare();
62 void idComparison();
63 void idHash();
64 void idStringFunctions();
65 void hash();
66 void datastream();
67 void traits();
68 void idTraits();
69};
70
71tst_QOrganizerCollection::tst_QOrganizerCollection()
72{
73}
74
75tst_QOrganizerCollection::~tst_QOrganizerCollection()
76{
77}
78
79void tst_QOrganizerCollection::metaData()
80{
81 QOrganizerCollection c;
82 QVERIFY(c.metaData().isEmpty());
83 c.setExtendedMetaData(key: QString(QStringLiteral("test")), value: 5);
84 QCOMPARE(c.extendedMetaData(QString(QStringLiteral("test"))).toInt(), 5);
85
86 QMap<QOrganizerCollection::MetaDataKey, QVariant> mdm;
87 mdm.insert(akey: QOrganizerCollection::KeyName, avalue: QString(QStringLiteral("test2")));
88 c.setMetaData(mdm);
89 QCOMPARE(c.metaData(), mdm);
90 QCOMPARE(c.metaData(QOrganizerCollection::KeyName).toString(), QString(QStringLiteral("test2")));
91}
92
93void tst_QOrganizerCollection::compare()
94{
95 QOrganizerCollection c, c2;
96 QVERIFY(c == c2);
97 c.setExtendedMetaData(QStringLiteral("test"), value: 5);
98 QVERIFY(c != c2);
99 c2.setExtendedMetaData(QStringLiteral("test"), value: 5);
100 QVERIFY(c == c2);
101
102 QMap<QOrganizerCollection::MetaDataKey, QVariant> mdm;
103 mdm.insert(akey: QOrganizerCollection::KeyName, QStringLiteral("test2"));
104 c.setMetaData(mdm);
105 QVERIFY(c != c2);
106 c2.setMetaData(mdm);
107 QVERIFY(c == c2);
108
109 c2 = QOrganizerCollection();
110 QVERIFY(c != c2);
111 c2 = c;
112 QVERIFY(c == c2);
113
114 c.setId(makeId(QStringLiteral("a"), id: 1));
115 QVERIFY(c != c2);
116 c2.setId(makeId(QStringLiteral("a"), id: 1));
117 QVERIFY(c == c2);
118 c.setId(makeId(QStringLiteral("b"), id: 1));
119 QVERIFY(c != c2);
120 c2.setId(c.id());
121 QVERIFY(c == c2);
122 c.setId(makeId(QStringLiteral("b"), id: 2));
123}
124
125void tst_QOrganizerCollection::idComparison()
126{
127 QOrganizerCollectionId id1(makeId(managerName: "a", id: 1));
128 QOrganizerCollectionId id2(makeId(managerName: "a", id: 1));
129 QVERIFY(!(id1 < id2));
130 QVERIFY(!(id2 < id1));
131 QVERIFY(id1 == id2);
132
133 QOrganizerCollectionId id3(makeId(managerName: "a", id: 2));
134 QOrganizerCollectionId id4(makeId(managerName: "b", id: 1));
135 QOrganizerCollectionId id5(makeId(managerName: "b", id: 2));
136 QVERIFY((((id1 < id3) && !(id3 < id1)) || ((id3 < id1) && !(id1 < id3))) && (id1 != id3));
137 QVERIFY((((id1 < id4) && !(id4 < id1)) || ((id4 < id1) && !(id1 < id4))) && (id1 != id4));
138 QVERIFY((((id3 < id4) && !(id4 < id3)) || ((id4 < id3) && !(id3 < id4))) && (id3 != id4));
139 QVERIFY((((id1 < id5) && !(id5 < id1)) || ((id5 < id1) && !(id1 < id5))) && (id3 != id4));
140
141 QOrganizerCollectionId id6;
142 QOrganizerCollectionId id7(QString(), "1");
143 QOrganizerCollectionId id8(QString(), "2");
144 QOrganizerCollectionId id9(QStringLiteral("qtorganizer:basic:"), QByteArray());
145 QVERIFY(id6.isNull());
146 QVERIFY(id7.isNull());
147 QVERIFY(id8.isNull());
148 QVERIFY(id9.isNull());
149 QVERIFY(id6 == id7);
150 QVERIFY(!(id6 < id7));
151 QVERIFY(id7 == id6);
152 QVERIFY(!(id7 < id6));
153 QVERIFY(id7 == id8);
154 QVERIFY(!(id7 < id8));
155 QVERIFY(id8 == id7);
156 QVERIFY(!(id9 < id8));
157 QVERIFY(id8 == id9);
158 QVERIFY(!(id8 < id9));
159 QVERIFY(id9 == id8);
160 QVERIFY(!(id9 < id8));
161
162 QVERIFY(!(id1 == id6));
163 QVERIFY(!(id1 < id6));
164 QVERIFY(id6 < id1);
165 QVERIFY(!(id1 == id7));
166 QVERIFY(!(id1 < id7));
167 QVERIFY(id7 < id1);
168 QVERIFY(!(id1 == id8));
169 QVERIFY(!(id1 < id8));
170 QVERIFY(id8 < id1);
171 QVERIFY(!(id1 == id9));
172 QVERIFY(!(id1 < id9));
173 QVERIFY(id9 < id1);
174}
175
176void tst_QOrganizerCollection::idHash()
177{
178 QOrganizerCollectionId id1(makeId(managerName: "a", id: 1));
179 QOrganizerCollectionId id2(makeId(managerName: "a", id: 1));
180 QOrganizerCollectionId id3(makeId(managerName: "b", id: 1));
181 QOrganizerCollectionId id4(makeId(managerName: "a", id: 2));
182 // note that the hash function ignores the managerUri
183 QCOMPARE(qHash(id1), qHash(id2));
184 QCOMPARE(qHash(id1), qHash(id3));
185 QVERIFY(qHash(id1) != qHash(id4));
186
187 QSet<QOrganizerCollectionId> set;
188 set.insert(value: id1);
189 set.insert(value: id2);
190 set.insert(value: id3);
191 set.insert(value: id4);
192 QCOMPARE(set.size(), 3);
193}
194
195void tst_QOrganizerCollection::idStringFunctions()
196{
197 // TODO: review test
198 QOrganizerCollectionId id1(makeId(managerName: "a", id: 1));
199 QOrganizerCollectionId id2(makeId(managerName: "a", id: 1));
200 QOrganizerCollectionId id3(makeId(managerName: "b", id: 1));
201 QOrganizerCollectionId id4(makeId(managerName: "a", id: 2));
202 QVERIFY(qHash(id1) == qHash(id2));
203 QVERIFY(qHash(id1) != qHash(id4));
204
205 // note that the toString and fromString functions are
206 // engine and id specific. This test merely checks that
207 // the API is hooked up correctly.
208
209 QVERIFY(id1.toString() == id2.toString());
210 QVERIFY(id1.toString() != id3.toString());
211 QVERIFY(id1.toString() != id4.toString());
212 QVERIFY(id3.toString() != id4.toString());
213
214 // this should "work" -- string of the correct format
215 const uint numericId2 = 2u;
216 const QByteArray localId2 = QByteArray(reinterpret_cast<const char *>(&numericId2), sizeof(uint));
217 QString prebuiltidstring = QString("qtorganizer") + QString(":") + QString("a") + QString("::") + localId2.toHex();
218 QOrganizerCollectionId rebuiltid = QOrganizerCollectionId::fromString(idString: prebuiltidstring);
219 QVERIFY(rebuiltid == id4);
220 QVERIFY(rebuiltid.localId() == id4.localId());
221
222 // this string has the right format and one parameter, but requires a working backend
223 prebuiltidstring = QString("qtorganizer") + QString(":") + QString("a") + QString(":") + QString("key=value") + QString(":") + localId2.toHex();
224 rebuiltid = QOrganizerCollectionId::fromString(idString: prebuiltidstring);
225 QVERIFY(rebuiltid != id4);
226 QVERIFY(rebuiltid.localId() == id4.localId());
227
228 // this string has the right format and some parameters, but requires a working backend
229 prebuiltidstring = QString("qtorganizer") + QString(":") + QString("a") + QString(":") + QString("key=value&key2=value2") + QString(":") + localId2.toHex();
230 rebuiltid = QOrganizerCollectionId::fromString(idString: prebuiltidstring);
231 QVERIFY(rebuiltid != id4);
232 QVERIFY(rebuiltid.localId() == id4.localId());
233
234 // this string has the right format but misses the value for a parameter
235 prebuiltidstring = QString("qtorganizer") + QString(":") + QString("a") + QString(":") + QString("key=value&key2=") + QString(":") + localId2.toHex();
236 rebuiltid = QOrganizerCollectionId::fromString(idString: prebuiltidstring);
237 QVERIFY(rebuiltid != id4);
238 QVERIFY(rebuiltid.localId() == id4.localId());
239
240 // this string misses a field (the parameters)
241 prebuiltidstring = QString("qtorganizer") + QString(":") + QString("a") + QString(":") + localId2.toHex();
242 rebuiltid = QOrganizerCollectionId::fromString(idString: prebuiltidstring);
243 QVERIFY(rebuiltid == QOrganizerCollectionId()); // invalid so should be null.
244
245 // this string misses two fields (params plus manager uri)
246 prebuiltidstring = QString("qtorganizer") + QString(":") + QString::number(2);
247 rebuiltid = QOrganizerCollectionId::fromString(idString: prebuiltidstring);
248 QVERIFY(rebuiltid == QOrganizerCollectionId()); // invalid so should be null.
249
250 // this string misses the prefix (qtorganizer)
251 prebuiltidstring = QString("notorganizer") + QString(":") + QString("a") + QString("::") + localId2.toHex();
252 rebuiltid = QOrganizerCollectionId::fromString(idString: prebuiltidstring);
253 QVERIFY(rebuiltid == QOrganizerCollectionId()); // invalid so should be null.
254
255 // this string misses the manager uri
256 prebuiltidstring = QString("notorganizer") + QString(":::") + localId2.toHex();
257 rebuiltid = QOrganizerCollectionId::fromString(idString: prebuiltidstring);
258 QVERIFY(rebuiltid == QOrganizerCollectionId()); // invalid so should be null.
259}
260
261void tst_QOrganizerCollection::hash()
262{
263 // TODO: review tests
264 QOrganizerCollectionId id(makeId(managerName: "a", id: 1));
265 QOrganizerCollection c1;
266 c1.setId(id);
267 c1.setExtendedMetaData(key: "key", value: "value");
268 QOrganizerCollection c2;
269 c2.setId(id);
270 c2.setExtendedMetaData(key: "key", value: "value");
271 QOrganizerCollection c3;
272 c3.setId(id);
273 c3.setExtendedMetaData(key: "key", value: "another value");
274 QOrganizerCollection c4; // no details
275 c4.setId(id);
276 QOrganizerCollection c5;
277 c5.setId(id);
278 c5.setExtendedMetaData(key: "key", value: "value");
279 QVERIFY(qHash(c1) == qHash(c2));
280 QVERIFY(qHash(c1) != qHash(c3));
281 QVERIFY(qHash(c1) != qHash(c4));
282 QVERIFY(qHash(c1) == qHash(c5));
283}
284
285void tst_QOrganizerCollection::datastream()
286{
287 // collection datastreaming
288 QByteArray buffer;
289 QOrganizerCollection collectionIn;
290 collectionIn.setExtendedMetaData(key: "key", value: "value");
291 QOrganizerCollection collectionOut;
292 QOrganizerCollectionId originalId;
293
294 // first, stream an item with a complete id
295 {
296 QDataStream stream1(&buffer, QIODevice::WriteOnly);
297 QOrganizerManager om("memory");
298 QVERIFY(om.saveCollection(&collectionIn)); // fill in its ID
299 originalId = collectionIn.id();
300 stream1 << collectionIn;
301 QVERIFY(buffer.size() > 0);
302 QDataStream stream2(buffer);
303 stream2 >> collectionOut;
304 QCOMPARE(collectionOut, collectionIn); // can use QCOMPARE for collections, since no detail keys.
305 }
306
307 // second, stream an item with an id with the mgr uri set, local id null
308 {
309 QDataStream stream1(&buffer, QIODevice::WriteOnly);
310 collectionIn.setId(QOrganizerCollectionId());
311 stream1 << collectionIn;
312 QVERIFY(buffer.size() > 0);
313 QDataStream stream2(buffer);
314 stream2 >> collectionOut;
315 QCOMPARE(collectionOut, collectionIn); // can use QCOMPARE for collections, since no detail keys.
316 }
317
318 /* TODO: Review tests
319 // third, stream an item with an id with the mgr uri null, local id set
320 {
321 QDataStream stream1(&buffer, QIODevice::WriteOnly);
322 QOrganizerCollectionId modifiedId = originalId;
323 modifiedId.setManagerUri(QString()); // this will clear the local id!
324 modifiedId.setId(originalId.localId()); // so reset it and make sure nothing bad happens.
325 collectionIn.setId(modifiedId);
326 stream1 << collectionIn;
327 QVERIFY(buffer.size() > 0);
328 QDataStream stream2(buffer);
329 stream2 >> collectionOut;
330 QVERIFY(collectionOut.metaData() == collectionIn.metaData());
331 QVERIFY(collectionOut.id() != collectionIn.id()); // no manager uri of input :. won't be serialized.
332 }*/
333
334 // fourth, stream an item with a null id
335 {
336 QDataStream stream1(&buffer, QIODevice::WriteOnly);
337 collectionIn.setId(QOrganizerCollectionId());
338 stream1 << collectionIn;
339 QVERIFY(buffer.size() > 0);
340 QDataStream stream2(buffer);
341 stream2 >> collectionOut;
342 QVERIFY(collectionOut.metaData() == collectionIn.metaData());
343 QVERIFY(collectionOut.id() == collectionIn.id()); // should both be null ids.
344 }
345
346 // id datastreaming
347 buffer.clear();
348 QOrganizerCollectionId inputId;
349 QOrganizerCollectionId outputId;
350
351 // first, stream the whole id (mgr uri set, local id set)
352 {
353 inputId = originalId;
354 QString serializedId = inputId.toString();
355 outputId = QOrganizerCollectionId::fromString(idString: serializedId);
356 QCOMPARE(inputId, outputId);
357
358 inputId = originalId;
359 buffer.clear();
360 QDataStream stream1(&buffer, QIODevice::WriteOnly);
361 stream1 << inputId;
362 QVERIFY(buffer.size() > 0);
363 QDataStream stream2(buffer);
364 stream2 >> outputId;
365 QCOMPARE(inputId, outputId);
366 }
367
368 /* TODO: review test
369 // second, stream a partial id (mgr uri null, local id set)
370 {
371 inputId.setManagerUri(QString());
372 inputId.setId(originalId.localId());
373 buffer.clear();
374 QDataStream stream1(&buffer, QIODevice::WriteOnly);
375 stream1 << inputId;
376 QVERIFY(buffer.size() > 0);
377 QDataStream stream2(buffer);
378 stream2 >> outputId;
379
380 // because the manager uri is null, we cannot stream it in.
381 QVERIFY(outputId.isNull());
382 QVERIFY(!inputId.isNull());
383 }
384
385 // third, stream a partial id (mgr uri set, local id null).
386 {
387 inputId.setManagerUri(originalId.managerUri());
388 inputId.setId(QOrganizerCollectionId());
389 buffer.clear();
390 QDataStream stream1(&buffer, QIODevice::WriteOnly);
391 stream1 << inputId;
392 QVERIFY(buffer.size() > 0);
393 QDataStream stream2(buffer);
394 stream2 >> outputId;
395 QCOMPARE(inputId, outputId);
396 }*/
397
398 // fourth, stream a null id
399 {
400 inputId = QOrganizerCollectionId();
401 QString serializedId = inputId.toString();
402 outputId = QOrganizerCollectionId::fromString(idString: serializedId);
403 QCOMPARE(inputId, outputId);
404
405 inputId = QOrganizerCollectionId();
406 buffer.clear();
407 QDataStream stream1(&buffer, QIODevice::WriteOnly);
408 stream1 << inputId;
409 QVERIFY(buffer.size() > 0);
410 QDataStream stream2(buffer);
411 stream2 >> outputId;
412 QCOMPARE(inputId, outputId);
413 }
414
415 /* TODO: review test
416 // fifth, stream an id after changing it's manager uri.
417 {
418 inputId.setManagerUri(originalId.managerUri());
419 inputId.setId(originalId.localId());
420 inputId.setManagerUri("test manager uri"); // should clear the local id.
421 QVERIFY(inputId.localId() == QOrganizerCollectionId());
422 buffer.clear();
423 QDataStream stream1(&buffer, QIODevice::WriteOnly);
424 stream1 << inputId;
425 QVERIFY(buffer.size() > 0);
426 QDataStream stream2(buffer);
427 stream2 >> outputId;
428 QCOMPARE(inputId, outputId);
429 }
430
431 // sixth, stream an id after changing it's manager uri and resetting the local id.
432 // this should cause great problems, because the manager doesn't exist so it shouldn't
433 // be able to deserialize. Make sure it's handled gracefully.
434 {
435 inputId.setManagerUri(originalId.managerUri());
436 inputId.setManagerUri("test manager uri"); // should clear the local id.
437 inputId.setId(originalId.localId());
438 buffer.clear();
439 QDataStream stream1(&buffer, QIODevice::WriteOnly);
440 stream1 << inputId;
441 QVERIFY(buffer.size() > 0);
442 QDataStream stream2(buffer);
443 stream2 >> outputId;
444 QVERIFY(outputId.isNull());
445 } */
446}
447
448void tst_QOrganizerCollection::traits()
449{
450 QCOMPARE(sizeof(QOrganizerCollection), sizeof(void *));
451 QVERIFY(QTypeInfo<QOrganizerCollection>::isComplex);
452 QVERIFY(!QTypeInfo<QOrganizerCollection>::isStatic);
453 QVERIFY(!QTypeInfo<QOrganizerCollection>::isLarge);
454 QVERIFY(!QTypeInfo<QOrganizerCollection>::isPointer);
455 QVERIFY(!QTypeInfo<QOrganizerCollection>::isDummy);
456}
457
458void tst_QOrganizerCollection::idTraits()
459{
460 QCOMPARE(sizeof(QOrganizerCollectionId), 2*sizeof(void *));
461 QVERIFY(QTypeInfo<QOrganizerCollectionId>::isComplex);
462 QVERIFY(!QTypeInfo<QOrganizerCollectionId>::isStatic);
463 QVERIFY(QTypeInfo<QOrganizerCollectionId>::isLarge);
464 QVERIFY(!QTypeInfo<QOrganizerCollectionId>::isPointer);
465 QVERIFY(!QTypeInfo<QOrganizerCollectionId>::isDummy);
466}
467
468QTEST_MAIN(tst_QOrganizerCollection)
469#include "tst_qorganizercollection.moc"
470

source code of qtpim/tests/auto/organizer/qorganizercollection/tst_qorganizercollection.cpp