New: QCT_TEST_MAIN
[qtcontacts-tracker:qtcontacts-tracker.git] / tests / ut_qtcontacts_trackerplugin_common / ut_qtcontacts_trackerplugin_common.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the Qt Mobility Components.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file.  Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 **
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef UT_QTCONTACTS_TRACKERPLUGIN_COMMON_H
43 #define UT_QTCONTACTS_TRACKERPLUGIN_COMMON_H
44
45 #include <QContactAbstractRequest>
46 #include <QContactDetailFilter>
47
48 #include <QtSparql>
49 #include <QtTest/QtTest>
50 #include <QtXml/QDomDocument>
51
52 #include <engine/engine.h>
53
54 QTM_USE_NAMESPACE
55
56 // macro to be used if calling another test function from a test function
57 // there could have been a failing test in that function, so the current function
58 // also needs to return at once
59 // giving the file and line number is useful to get to know the call stack
60 #define CHECK_CURRENT_TEST_FAILED                                               \
61                                                                                 \
62 do {                                                                            \
63     if (QTest::currentTestFailed()) {                                           \
64         qWarning("failing test called from %s(%d)", __FILE__, __LINE__);        \
65         return;                                                                 \
66     }                                                                           \
67 } while (0)
68
69 // macros to deal with multiple contacts:
70 // * nickname works for both normal and group contacts
71 // * using the test run's uuid to namespace contacts from different tests in the same database,
72 // * using __func__ to identify contacts from a test
73 // * using an int index to identify the contacts by order of creation
74 // In the tests use SET_TESTNICKNAME_TO_CONTACT to mark created contacts
75 // and TESTNICKNAME_FILTER for fetch requests to limit to contacts from current test,
76 // add it with a QContactIntersectionFilter to the real filter, if used.
77 #define SET_TESTNICKNAME_TO_CONTACT(c)   setTestNicknameToContact(c, QLatin1String(__func__))
78 #define TESTNICKNAME_FILTER              testNicknameFilter(QLatin1String(__func__))
79
80 // replacement for QTEST_MAIN which always uses QCoreApplication
81 #define QCT_TEST_MAIN(TestObject)                                               \
82 int main(int argc, char *argv[])                                                \
83 {                                                                               \
84     QCoreApplication app(argc, argv);                                           \
85     TestObject tc;                                                              \
86     return QTest::qExec(&tc, argc, argv);                                       \
87 }
88
89 typedef QList<QContactLocalId> QContactLocalIdList;
90 typedef QList<QContact> QContactList;
91
92 // create metadata so that those types can be used with QTest library
93 Q_DECLARE_METATYPE(QContact)
94 Q_DECLARE_METATYPE(QContactFilter)
95 Q_DECLARE_METATYPE(QContactLocalIdList)
96 Q_DECLARE_METATYPE(QContactList)
97
98 Q_DECLARE_METATYPE(QList<int>)
99
100 namespace QTest
101 {
102     template<> inline char *toString<QVariant::Type>(const QVariant::Type &type)
103     {
104         return qstrdup(QVariant::typeToName(type));
105     }
106
107     template<> inline char *toString<QContactManager::Error>(const QContactManager::Error &error)
108     {
109 #define DO_CASE(v) case (v): return qstrdup(#v)
110         switch(error) {
111             DO_CASE(QContactManager::NoError);
112             DO_CASE(QContactManager::DoesNotExistError);
113             DO_CASE(QContactManager::AlreadyExistsError);
114             DO_CASE(QContactManager::InvalidDetailError);
115             DO_CASE(QContactManager::InvalidRelationshipError);
116             DO_CASE(QContactManager::LockedError);
117             DO_CASE(QContactManager::DetailAccessError);
118             DO_CASE(QContactManager::PermissionsError);
119             DO_CASE(QContactManager::OutOfMemoryError);
120             DO_CASE(QContactManager::NotSupportedError);
121             DO_CASE(QContactManager::BadArgumentError);
122             DO_CASE(QContactManager::UnspecifiedError);
123             DO_CASE(QContactManager::VersionMismatchError);
124             DO_CASE(QContactManager::LimitReachedError);
125             DO_CASE(QContactManager::InvalidContactTypeError);
126 #undef DO_CASE
127         }
128
129         return qstrdup(qPrintable(QString::fromLatin1("QContactManager::Error(%1)").arg(error)));
130     }
131
132     template<> inline char *toString< QVariantMap >(const QVariantMap &map)
133     {
134         QString result;
135
136         for(QVariantMap::ConstIterator i = map.begin(); i != map.end(); ++i) {
137             if (result.length() > 0) {
138                 result += QLatin1String(", ");
139             }
140
141             char *str(toString(i.value()));
142
143             result +=
144                     QLatin1Char('(') % i.key() % QLatin1String(": ") %
145                     QString::fromLocal8Bit(str) % QLatin1Char(')');
146
147             qFree(str);
148         }
149
150         return qstrdup(qPrintable(QLatin1Char('(') + result + QLatin1Char(')')));
151     }
152
153     template<> inline char *toString< QVariantHash >(const QVariantHash &hash)
154     {
155         QString result;
156
157         for(QVariantHash::ConstIterator i = hash.begin(); i != hash.end(); ++i) {
158             if (result.length() > 0) {
159                 result += QLatin1String(", ");
160             }
161
162             char *str(toString(i.value()));
163
164             result +=
165                     QLatin1Char('(') % i.key() % QLatin1String(": ") %
166                     QString::fromLocal8Bit(str) % QLatin1Char(')');
167
168             qFree(str);
169         }
170
171         return qstrdup(qPrintable(QLatin1Char('(') + result + QLatin1Char(')')));
172     }
173
174     template<> inline char *toString< QList<QString> >(const QList<QString> &list)
175     {
176         return qstrdup(qPrintable(QLatin1String("(\"") +
177                                   QStringList(list).join(QLatin1String("\", \"")) +
178                                   QLatin1String("\")")));
179     }
180
181     template<> inline char *toString< QSet<QString> >(const QSet<QString> &set)
182     {
183         return toString(set.toList());
184     }
185
186     template<> inline char *toString< QList<QUrl> >(const QList<QUrl> &list)
187     {
188         QStringList strList;
189
190         foreach(const QUrl &url, list) {
191             strList += url.toString();
192         }
193
194         return toString< QList<QString> >(strList);
195     }
196
197     template<> inline char *toString< QSet<QUrl> >(const QSet<QUrl> &set)
198     {
199         return toString(set.toList());
200     }
201 }
202
203 class ut_qtcontacts_trackerplugin_common : public QObject
204 {
205     Q_OBJECT
206
207 public:
208     static const int DefaultTimeout = 5000;
209     static const QList<QContactSortOrder> NoSortOrders;
210     static const QContactFetchHint NoFetchHint;
211
212     explicit ut_qtcontacts_trackerplugin_common(const QDir &dataDir, const QDir &srcDir,
213                                                 QObject *parent = 0);
214     virtual ~ut_qtcontacts_trackerplugin_common();
215
216 protected slots:
217     // function setup
218     void cleanup();
219
220 protected:
221     QSet<QString> findTestSlotNames();
222
223     void saveContact(QContact &contact, int timeout = DefaultTimeout);
224     void saveContacts(QList<QContact> &contacts, int timeout = DefaultTimeout);
225     void fetchContact(const QContactLocalId &id, QContact &result, int timeout = DefaultTimeout);
226     void fetchContact(const QContactFilter &filter, QContact &result, int timeout = DefaultTimeout);
227     void fetchContactLocalId(const QContactFilter &filter, QContactLocalId &result, int timeout = DefaultTimeout);
228     void fetchContacts(const QList<QContactLocalId> &ids, QList<QContact> &result, int timeout = DefaultTimeout);
229     void fetchContacts(const QContactFilter &filter, QList<QContact> &result, int timeout = DefaultTimeout);
230     void fetchContacts(const QContactFilter &filter, const QList<QContactSortOrder> &sorting, QList<QContact> &result, int timeout = DefaultTimeout);
231     void fetchContactLocalIds(const QContactFilter &filter, QList<QContactLocalId> &result, int timeout = DefaultTimeout);
232     void fetchContactLocalIds(const QContactFilter &filter, const QList<QContactSortOrder> &sorting, QList<QContactLocalId> &result, int timeout = DefaultTimeout);
233     void saveRelationship(const QContactRelationship &relationship, int timeout = DefaultTimeout);
234     void saveRelationships(const QList<QContactRelationship> &relationships, int timeout = DefaultTimeout);
235     void fetchRelationship(const QContactId &firstId, const QString &relationshipType, const QContactId &secondId, QContactRelationship &result, int timeout = DefaultTimeout);
236     void fetchRelationships(const QString &relationshipType, const QContactId &participantId, QContactRelationship::Role role, QList<QContactRelationship> &result, int timeout = DefaultTimeout);
237     void removeRelationship(const QContactRelationship &relationship, int timeout = DefaultTimeout);
238     void removeRelationships(const QList<QContactRelationship> &relationships, int timeout = DefaultTimeout);
239
240     QList<QContact> parseVCards(const QString &fileName, int limit = INT_MAX);
241     QList<QContact> parseVCards(const QByteArray &vcardData, int limit = INT_MAX);
242
243     virtual QMap<QString, QString> makeEngineParams() const;
244     QContactLocalIdList & localIds() { return m_localIds; }
245     void registerForCleanup(const QContact &contact) { m_localIds.append(contact.localId()); }
246     QContactTrackerEngine *engine() const;
247     void resetEngine();
248
249     QString referenceFileName(const QString &fileName);
250     QString loadReferenceFile(const QString &fileName);
251
252     QSparqlResult * executeQuery(const QString &queryString,
253                                        QSparqlQuery::StatementType type) const;
254
255     QList<QUrl> loadRawTuples(const QString &fileName);
256     QDomDocument loadReferenceContacts(const QString &fileName = QLatin1String("000-contacts.xml"));
257
258     void verifyContacts(const QList<QContact> &candiates, const QDomDocument &reference,
259                         const QStringList &missingIds = QStringList());
260     void verifyContacts(const QList<QContact> &candiates,
261                         const QString &referenceFileName = QLatin1String("000-contacts.xml"),
262                         const QStringList &missingIds = QStringList());
263
264     /// returns the unique identifier of the testrun, extended by the given @p id, if not empty.
265     QString uniqueTestId(const QString& id = QString()) const;
266     /// returns a name which is unique and contains a custom identifier, the given @p id.
267     /// Uniqueness is created by the unique id of the testrun (mNamePrefix) and an increasing number,
268     /// starting from 0000 and ending with 99999 (i.e. ending being useful).
269     /// The number has fixed set of digits, with leading 0, to enable sorting by name in order of creation.
270     /// The created name has this pattern: testClassName:Uuid:idPassedByParameter_12345
271     QString makeUniqueName(const QString &id) const;
272     /// sets a nickname to the contact using the test uuid and the given @p id.
273     /// Use the macro SET_TESTNICKNAME_TO_CONTACT(c) to get the function name as id.
274     void setTestNicknameToContact(QContact &contact, const QString &id) const;
275     /// returns a filter on nicknames using the test uuid and the given @p id.
276     /// Use the macro TESTNICKNAME_FILTER to get a filter with the function name as id.
277     QContactDetailFilter testNicknameFilter(const QString &id) const;
278
279 private:
280     mutable QContactTrackerEngine *m_engine;
281     QContactLocalIdList m_localIds;
282     QDir m_dataDir, m_srcDir;
283     /// unique identifier for a testrun, used e.g. to mark contacts stored in tracker
284     QString m_uuid;
285
286 protected: // fields
287     bool m_verbose : 1;
288 };
289
290 Q_DECL_DEPRECATED QContactLocalId parseContactIri(const QString &iri, bool *ok = 0);
291 Q_DECL_DEPRECATED QUrl makeContactIri(const QContactLocalId &localId);
292
293 Q_DECL_DEPRECATED QContactLocalId parseContactGroupIri(const QString &iri, bool *ok = 0);
294 Q_DECL_DEPRECATED QUrl makeContactGroupIri(const QContactLocalId &localId);
295
296 #endif /* UT_QTCONTACTS_TRACKERPLUGIN_COMMON_H */