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