--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/qtmobility/plugins/contacts/qtcontacts-tracker/tests/ut_qtcontacts_trackerplugin_definitions/ut_qtcontacts_trackerplugin_definitions.cpp Mon May 03 13:18:40 2010 +0300
@@ -0,0 +1,483 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "ut_qtcontacts_trackerplugin_definitions.h"
+
+#include <QContactInvalidFilter>
+
+typedef QSet<QString> QStringSet;
+
+void ut_qtcontacts_trackerplugin_definitions::checkAllDefitionsTested()
+{
+ const QStringSet testSlots(testSlotNames());
+
+ foreach(const QContactDetailDefinition d, mContactManager->detailDefinitions()) {
+ const QString saveAndFetchOne(QLatin1String("saveAndFetchOne") + d.name());
+ QVERIFY2(testSlots.contains(saveAndFetchOne), qPrintable(d.name()));
+ const QString saveAndFetchMany(QLatin1String("saveAndFetchMany") + d.name());
+ QVERIFY2(testSlots.contains(saveAndFetchMany), qPrintable(d.name()));
+ const QString saveAndFetchAll(QLatin1String("saveAndFetchAll") + d.name());
+ QVERIFY2(testSlots.contains(saveAndFetchAll), qPrintable(d.name()));
+ }
+}
+
+class SampleGenerator
+{
+public:
+ SampleGenerator(QVariant::Type type, const QVariantList &allowedValues) :
+ mType(type), mComplete(false), mIndex(0)
+ {
+ if (allowedValues.isEmpty()) {
+ QVariant sample;
+
+ switch(type) {
+ case QVariant::Date:
+ sample.setValue(QDate::currentDate());
+ break;
+
+ case QVariant::DateTime:
+ sample.setValue(QDateTime::currentDateTime());
+ break;
+
+ case QVariant::Double:
+ sample.setValue(double(qrand()) / RAND_MAX);
+ break;
+
+ case QVariant::Pixmap:
+ sample.setValue(QPixmap(2, 2));
+ break;
+
+ case QVariant::String:
+ sample.setValue(QUuid::createUuid().toString());
+ break;
+
+ case QVariant::StringList:
+ sample.setValue(QStringList(QUuid::createUuid().toString()) <<
+ QLatin1String("1") << QLatin1String("2") <<
+ QLatin1String("3"));
+ break;
+
+ default:
+ QFAIL(qPrintable(QString("unsupported variant type: %1").
+ arg(QVariant::typeToName(type))));
+ }
+
+ mValues.append(sample);
+ } else {
+ mValues.append(allowedValues);
+
+ switch(type) {
+ case QVariant::StringList:
+ for(int i = 2; i <= allowedValues.count(); ++i) {
+ QStringList stringList;
+
+ for(int j = 0; j < i; ++j)
+ stringList.append(allowedValues[j].toString());
+
+ mValues.append(QVariant(stringList));
+ }
+
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ void nextSample(QVariant &result)
+ {
+ currentSample(result);
+
+ if (++mIndex == mValues.count()) {
+ mComplete = true;
+ mIndex = 0;
+ }
+ }
+
+ void currentSample(QVariant &result)
+ {
+ result.setValue(mValues[mIndex]);
+
+ if (result.isValid()) {
+ QVERIFY2(result.convert(mType), QVariant::typeToName(mType));
+ }
+ }
+
+ bool isComplete() const
+ {
+ return mComplete;
+ }
+
+private:
+ QVariant::Type mType;
+ QVariantList mValues;
+ bool mComplete;
+ int mIndex;
+};
+
+void ut_qtcontacts_trackerplugin_definitions::createTestContacts(const QString &definitionName, QList<QContact> &result)
+{
+ const QContactDetailDefinition &definition
+ (mContactManager->detailDefinition(definitionName));
+
+ typedef QMap<QString, QContactDetailFieldDefinition> FieldMap;
+ const FieldMap fields(definition.fields());
+
+ typedef QHash<QString, SampleGenerator> GeneratorMap;
+ GeneratorMap generators;
+
+ for(FieldMap::const_iterator i(fields.begin()), e(fields.end()); i != e; ++i) {
+ const QContactDetailFieldDefinition &field(i.value());
+ generators.insert(i.key(), SampleGenerator(field.dataType(), field.allowableValues()));
+ CHECK_CURRENT_TEST_FAILED;
+ }
+
+ QList<QContactDetail> detailList;
+
+ for(GeneratorMap::iterator i(generators.begin()), e(generators.end()); i != e; ++i) {
+ QVariant sample;
+ SampleGenerator &generator(i.value());
+ generator.currentSample(sample);
+ CHECK_CURRENT_TEST_FAILED;
+
+ QContactDetail detail(definition.name());
+ detail.setValue(i.key(), sample);
+ detailList.append(detail);
+ }
+
+ forever {
+ QContactDetail detail(definition.name());
+ bool samplesComplete = true;
+
+ for(GeneratorMap::iterator i(generators.begin()), e(generators.end()); i != e; ++i) {
+ QVariant sample;
+ SampleGenerator &generator(i.value());
+ generator.nextSample(sample);
+ CHECK_CURRENT_TEST_FAILED;
+
+ if (not generator.isComplete())
+ samplesComplete = false;
+
+ if (sample.isValid())
+ detail.setValue(i.key(), sample);
+ }
+
+ detailList.append(detail);
+
+ if (samplesComplete)
+ break;
+ }
+
+ foreach(QContactDetail detail, detailList) {
+ QContact contact;
+ QVERIFY(contact.saveDetail(&detail));
+ result.append(contact);
+ }
+}
+
+static bool localIdOrder(const QContact &a, const QContact &b)
+{
+ return a.localId() < b.localId();
+}
+
+static bool isEmpty(const QVariant &value)
+{
+ const QVariant empty(value.type());
+ return value == empty;
+}
+
+static const QStringSet newBrokenDetails()
+{
+ return (QStringSet() <<
+ QLatin1String("Anniversary") << // FIXME: doesn't load at all
+ QLatin1String("Avatar") << // FIXME: doesn't load at all
+ QLatin1String("Birthday") << // FIXME: doesn't load at all
+ QLatin1String("EmailAddress") << // FIXME: doesn't load for work context
+ QLatin1String("Gender") << // FIXME: doesn't load at all
+ QLatin1String("GeoLocation") << // FIXME: doesn't load at all
+ QLatin1String("Guid") << // FIXME: doesn't load at all
+ QLatin1String("Note") << // FIXME: doesn't load at all
+ QLatin1String("OnlineAccount") << // FIXME: doesn't load at all
+ QLatin1String("Organization") << // FIXME: doesn't load at all
+ QLatin1String("StreetAddress") << // FIXME: doesn't load at all
+ QLatin1String("SyncTarget") << // FIXME: doesn't load at all
+ QLatin1String("Timestamp") << // FIXME: doesn't load at all
+ QLatin1String("Url")); // FIXME: doesn't load at all
+}
+
+static const QHash<QString, QStringSet> newBrokenFields()
+{
+ QHash<QString, QStringSet> brokenFields;
+
+ brokenFields.insert(QLatin1String("EmailAddress"),
+ QStringSet() << QLatin1String("Context"));
+
+ brokenFields.insert(QLatin1String("Name"),
+ QStringSet() << QLatin1String("Context") // FIXME: meaning of this field?
+ << QLatin1String("CustomLabel") // FIXME: meaning of this field?
+ << QLatin1String("Suffix"));
+
+ brokenFields.insert(QLatin1String("Nickname"),
+ QStringSet() << QLatin1String("Context")); // FIXME: meaning of this field?
+
+ brokenFields.insert(QLatin1String("PhoneNumber"),
+ QStringSet() << QLatin1String("Context")
+ << QLatin1String("PhoneNumber")
+ << QLatin1String("SubTypes"));
+
+ return brokenFields;
+}
+
+static const QStringSet newSynthesizedDetails()
+{
+ return (QStringSet() <<
+ QLatin1String("DisplayLabel") <<
+ QLatin1String("Type"));
+}
+
+static const QStringSet brokenDetails(newBrokenDetails());
+static const QHash<QString, QStringSet> brokenFields(newBrokenFields());
+static const QStringSet synthesizedDetails(newSynthesizedDetails());
+
+void ut_qtcontacts_trackerplugin_definitions::verifyContacts(const QString &definitionName,
+ QList<QContact> &savedContacts,
+ QList<QContact> &fetchedContacts)
+{
+ qSort(savedContacts.begin(), savedContacts.end(), localIdOrder);
+ qSort(fetchedContacts.begin(), fetchedContacts.end(), localIdOrder);
+
+ QCOMPARE(fetchedContacts.count(), savedContacts.count());
+
+ for(int i = 0, l = savedContacts.count(); i < l; ++i) {
+ const QList<QContactDetail> &savedDetails(savedContacts[i].details(definitionName));
+ const QList<QContactDetail> &fetchedDetails(fetchedContacts[i].details(definitionName));
+
+ QCOMPARE(savedDetails.count(), 1);
+ QCOMPARE(fetchedDetails.count(), 1);
+
+ QVariantMap savedValues(savedDetails[0].variantValues());
+ QVariantMap fetchedValues(fetchedDetails[0].variantValues());
+
+ QStringSet fieldNames(savedValues.keys().toSet());
+ fieldNames.unite(fetchedValues.keys().toSet());
+
+ foreach(const QString &key, fieldNames) {
+ if (brokenFields[definitionName].contains(key)) {
+ const QString msg(QString::fromLatin1("ignoring broken %1 field").arg(key));
+ QEXPECT_FAIL("", qPrintable(msg), Continue);
+ }
+
+ if (not savedValues.contains(key)) {
+ QVERIFY(isEmpty(fetchedValues[key]));
+ } else if (not fetchedValues.contains(key)) {
+ QVERIFY(isEmpty(savedValues[key]));
+ } else {
+ QCOMPARE(savedValues[key], fetchedValues[key]);
+ }
+ }
+ }
+}
+
+void ut_qtcontacts_trackerplugin_definitions::saveAndFetchOne(const QString &definitionName)
+{
+ qDebug() << "===============================================================================";
+ qDebug() << qPrintable(definitionName);
+ qDebug() << "===============================================================================";
+
+ if (brokenDetails.contains(definitionName)) {
+ QSKIP("support for this detail is broken right now", SkipAll);
+ }
+
+ if (synthesizedDetails.contains(definitionName)) {
+ QSKIP("synthesized details are out of scope for now", SkipAll);
+ }
+
+ QList<QContact> savedContacts;
+ QList<QContactLocalId> savedContactIds;
+
+ createTestContacts(definitionName, savedContacts);
+ CHECK_CURRENT_TEST_FAILED;
+
+ saveContacts(savedContacts);
+ CHECK_CURRENT_TEST_FAILED;
+
+ foreach(const QContact &contact, savedContacts) {
+ savedContactIds.append(contact.localId());
+ }
+
+ QCOMPARE(savedContactIds.toSet().count(), savedContacts.count());
+
+ QList<QContact> fetchedContacts;
+
+ foreach(const QContactLocalId &id, savedContactIds) {
+ QContact contact;
+ fetchContact(id, contact);
+ CHECK_CURRENT_TEST_FAILED;
+ fetchedContacts.append(contact);
+ }
+
+ verifyContacts(definitionName, savedContacts, fetchedContacts);
+}
+
+void ut_qtcontacts_trackerplugin_definitions::saveAndFetchMany(const QString &definitionName)
+{
+ qDebug() << "===============================================================================";
+ qDebug() << qPrintable(definitionName);
+ qDebug() << "===============================================================================";
+
+ if (brokenDetails.contains(definitionName)) {
+ QSKIP("support for this detail is broken right now", SkipAll);
+ }
+
+ if (synthesizedDetails.contains(definitionName)) {
+ QSKIP("synthesized details are out of scope for now", SkipAll);
+ }
+
+ QList<QContact> savedContacts;
+ QList<QContactLocalId> savedContactIds;
+
+ createTestContacts(definitionName, savedContacts);
+ CHECK_CURRENT_TEST_FAILED;
+
+ saveContacts(savedContacts);
+ CHECK_CURRENT_TEST_FAILED;
+
+ foreach(const QContact &contact, savedContacts) {
+ savedContactIds.append(contact.localId());
+ }
+
+ QCOMPARE(savedContactIds.toSet().count(), savedContacts.count());
+
+ QList<QContact> fetchedContacts;
+ fetchContacts(savedContactIds, fetchedContacts);
+ CHECK_CURRENT_TEST_FAILED;
+
+ verifyContacts(definitionName, savedContacts, fetchedContacts);
+}
+
+void ut_qtcontacts_trackerplugin_definitions::saveAndFetchAll(const QString &definitionName)
+{
+ qDebug() << "===============================================================================";
+ qDebug() << qPrintable(definitionName);
+ qDebug() << "===============================================================================";
+
+ if (brokenDetails.contains(definitionName)) {
+ QSKIP("support for this detail is broken right now", SkipAll);
+ }
+
+ if (synthesizedDetails.contains(definitionName)) {
+ QSKIP("synthesized details are out of scope for now", SkipAll);
+ }
+
+ QList<QContact> savedContacts;
+ QSet<QContactLocalId> savedContactIds;
+
+ createTestContacts(definitionName, savedContacts);
+ CHECK_CURRENT_TEST_FAILED;
+
+ saveContacts(savedContacts);
+ CHECK_CURRENT_TEST_FAILED;
+
+ foreach(const QContact &contact, savedContacts) {
+ savedContactIds.insert(contact.localId());
+ }
+
+ QCOMPARE(savedContactIds.count(), savedContacts.count());
+
+ QList<QContact> fetchedContacts;
+ fetchContacts(QContactInvalidFilter(), fetchedContacts);
+ CHECK_CURRENT_TEST_FAILED;
+
+ QList<QContact>::iterator i = fetchedContacts.begin();
+
+ while (i != fetchedContacts.end()) {
+ if (not savedContactIds.contains(i->localId())) {
+ i = fetchedContacts.erase(i);
+ } else {
+ ++i;
+ }
+ }
+
+ verifyContacts(definitionName, savedContacts, fetchedContacts);
+}
+
+#define IMPLEMENT_SAVE_AND_FETCH(DefinitionName) \
+ \
+void ut_qtcontacts_trackerplugin_definitions::saveAndFetchOne##DefinitionName() \
+{ \
+ saveAndFetchOne(QString::fromLatin1(#DefinitionName)); \
+ CHECK_CURRENT_TEST_FAILED; \
+} \
+ \
+void ut_qtcontacts_trackerplugin_definitions::saveAndFetchMany##DefinitionName() \
+{ \
+ saveAndFetchMany(QString::fromLatin1(#DefinitionName)); \
+ CHECK_CURRENT_TEST_FAILED; \
+} \
+ \
+void ut_qtcontacts_trackerplugin_definitions::saveAndFetchAll##DefinitionName() \
+{ \
+ saveAndFetchAll(QString::fromLatin1(#DefinitionName)); \
+ CHECK_CURRENT_TEST_FAILED; \
+}
+
+IMPLEMENT_SAVE_AND_FETCH(Anniversary)
+IMPLEMENT_SAVE_AND_FETCH(Avatar)
+IMPLEMENT_SAVE_AND_FETCH(Birthday)
+IMPLEMENT_SAVE_AND_FETCH(DisplayLabel)
+IMPLEMENT_SAVE_AND_FETCH(EmailAddress)
+IMPLEMENT_SAVE_AND_FETCH(Gender)
+IMPLEMENT_SAVE_AND_FETCH(GeoLocation)
+IMPLEMENT_SAVE_AND_FETCH(Guid)
+IMPLEMENT_SAVE_AND_FETCH(Name)
+IMPLEMENT_SAVE_AND_FETCH(Nickname)
+IMPLEMENT_SAVE_AND_FETCH(Note)
+IMPLEMENT_SAVE_AND_FETCH(OnlineAccount)
+IMPLEMENT_SAVE_AND_FETCH(Organization)
+IMPLEMENT_SAVE_AND_FETCH(PhoneNumber)
+IMPLEMENT_SAVE_AND_FETCH(StreetAddress)
+IMPLEMENT_SAVE_AND_FETCH(SyncTarget)
+IMPLEMENT_SAVE_AND_FETCH(Timestamp)
+IMPLEMENT_SAVE_AND_FETCH(Type)
+IMPLEMENT_SAVE_AND_FETCH(Url)
+
+QTEST_MAIN(ut_qtcontacts_trackerplugin_definitions)