qtmobility/plugins/contacts/qtcontacts-tracker/tests/ut_qtcontacts_trackerplugin_definitions/ut_qtcontacts_trackerplugin_definitions.cpp
changeset 4 90517678cc4f
child 11 06b8e2af4411
equal deleted inserted replaced
1:2b40d63a9c3d 4:90517678cc4f
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 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 #include "ut_qtcontacts_trackerplugin_definitions.h"
       
    43 
       
    44 #include <QContactInvalidFilter>
       
    45 
       
    46 typedef QSet<QString> QStringSet;
       
    47 
       
    48 void ut_qtcontacts_trackerplugin_definitions::checkAllDefitionsTested()
       
    49 {
       
    50     const QStringSet testSlots(testSlotNames());
       
    51 
       
    52     foreach(const QContactDetailDefinition d, mContactManager->detailDefinitions()) {
       
    53         const QString saveAndFetchOne(QLatin1String("saveAndFetchOne") + d.name());
       
    54         QVERIFY2(testSlots.contains(saveAndFetchOne), qPrintable(d.name()));
       
    55         const QString saveAndFetchMany(QLatin1String("saveAndFetchMany") + d.name());
       
    56         QVERIFY2(testSlots.contains(saveAndFetchMany), qPrintable(d.name()));
       
    57         const QString saveAndFetchAll(QLatin1String("saveAndFetchAll") + d.name());
       
    58         QVERIFY2(testSlots.contains(saveAndFetchAll), qPrintable(d.name()));
       
    59     }
       
    60 }
       
    61 
       
    62 class SampleGenerator
       
    63 {
       
    64 public:
       
    65     SampleGenerator(QVariant::Type type, const QVariantList &allowedValues) :
       
    66             mType(type), mComplete(false), mIndex(0)
       
    67     {
       
    68         if (allowedValues.isEmpty()) {
       
    69             QVariant sample;
       
    70 
       
    71             switch(type) {
       
    72             case QVariant::Date:
       
    73                 sample.setValue(QDate::currentDate());
       
    74                 break;
       
    75 
       
    76             case QVariant::DateTime:
       
    77                 sample.setValue(QDateTime::currentDateTime());
       
    78                 break;
       
    79 
       
    80             case QVariant::Double:
       
    81                 sample.setValue(double(qrand()) / RAND_MAX);
       
    82                 break;
       
    83 
       
    84             case QVariant::Pixmap:
       
    85                 sample.setValue(QPixmap(2, 2));
       
    86                 break;
       
    87 
       
    88             case QVariant::String:
       
    89                 sample.setValue(QUuid::createUuid().toString());
       
    90                 break;
       
    91 
       
    92             case QVariant::StringList:
       
    93                 sample.setValue(QStringList(QUuid::createUuid().toString()) <<
       
    94                                 QLatin1String("1") << QLatin1String("2") <<
       
    95                                 QLatin1String("3"));
       
    96                 break;
       
    97 
       
    98             default:
       
    99                 QFAIL(qPrintable(QString("unsupported variant type: %1").
       
   100                                  arg(QVariant::typeToName(type))));
       
   101             }
       
   102 
       
   103             mValues.append(sample);
       
   104         } else {
       
   105             mValues.append(allowedValues);
       
   106 
       
   107             switch(type) {
       
   108             case QVariant::StringList:
       
   109                 for(int i = 2; i <= allowedValues.count(); ++i) {
       
   110                     QStringList stringList;
       
   111 
       
   112                     for(int j = 0; j < i; ++j)
       
   113                         stringList.append(allowedValues[j].toString());
       
   114 
       
   115                     mValues.append(QVariant(stringList));
       
   116                 }
       
   117 
       
   118                 break;
       
   119 
       
   120             default:
       
   121                 break;
       
   122             }
       
   123         }
       
   124     }
       
   125 
       
   126     void nextSample(QVariant &result)
       
   127     {
       
   128         currentSample(result);
       
   129 
       
   130         if (++mIndex == mValues.count()) {
       
   131             mComplete = true;
       
   132             mIndex = 0;
       
   133         }
       
   134     }
       
   135 
       
   136     void currentSample(QVariant &result)
       
   137     {
       
   138         result.setValue(mValues[mIndex]);
       
   139 
       
   140         if (result.isValid()) {
       
   141             QVERIFY2(result.convert(mType), QVariant::typeToName(mType));
       
   142         }
       
   143     }
       
   144 
       
   145     bool isComplete() const
       
   146     {
       
   147         return mComplete;
       
   148     }
       
   149 
       
   150 private:
       
   151     QVariant::Type mType;
       
   152     QVariantList mValues;
       
   153     bool mComplete;
       
   154     int mIndex;
       
   155 };
       
   156 
       
   157 void ut_qtcontacts_trackerplugin_definitions::createTestContacts(const QString &definitionName, QList<QContact> &result)
       
   158 {
       
   159     const QContactDetailDefinition &definition
       
   160             (mContactManager->detailDefinition(definitionName));
       
   161 
       
   162     typedef QMap<QString, QContactDetailFieldDefinition> FieldMap;
       
   163     const FieldMap fields(definition.fields());
       
   164 
       
   165     typedef QHash<QString, SampleGenerator> GeneratorMap;
       
   166     GeneratorMap generators;
       
   167 
       
   168     for(FieldMap::const_iterator i(fields.begin()), e(fields.end()); i != e; ++i) {
       
   169         const QContactDetailFieldDefinition &field(i.value());
       
   170         generators.insert(i.key(), SampleGenerator(field.dataType(), field.allowableValues()));
       
   171         CHECK_CURRENT_TEST_FAILED;
       
   172     }
       
   173 
       
   174     QList<QContactDetail> detailList;
       
   175 
       
   176     for(GeneratorMap::iterator i(generators.begin()), e(generators.end()); i != e; ++i) {
       
   177         QVariant sample;
       
   178         SampleGenerator &generator(i.value());
       
   179         generator.currentSample(sample);
       
   180         CHECK_CURRENT_TEST_FAILED;
       
   181 
       
   182         QContactDetail detail(definition.name());
       
   183         detail.setValue(i.key(), sample);
       
   184         detailList.append(detail);
       
   185     }
       
   186 
       
   187     forever {
       
   188         QContactDetail detail(definition.name());
       
   189         bool samplesComplete = true;
       
   190 
       
   191         for(GeneratorMap::iterator i(generators.begin()), e(generators.end()); i != e; ++i) {
       
   192             QVariant sample;
       
   193             SampleGenerator &generator(i.value());
       
   194             generator.nextSample(sample);
       
   195             CHECK_CURRENT_TEST_FAILED;
       
   196 
       
   197             if (not generator.isComplete())
       
   198                 samplesComplete = false;
       
   199 
       
   200             if (sample.isValid())
       
   201                 detail.setValue(i.key(), sample);
       
   202         }
       
   203 
       
   204         detailList.append(detail);
       
   205 
       
   206         if (samplesComplete)
       
   207             break;
       
   208     }
       
   209 
       
   210     foreach(QContactDetail detail, detailList) {
       
   211         QContact contact;
       
   212         QVERIFY(contact.saveDetail(&detail));
       
   213         result.append(contact);
       
   214     }
       
   215 }
       
   216 
       
   217 static bool localIdOrder(const QContact &a, const QContact &b)
       
   218 {
       
   219     return a.localId() < b.localId();
       
   220 }
       
   221 
       
   222 static bool isEmpty(const QVariant &value)
       
   223 {
       
   224     const QVariant empty(value.type());
       
   225     return value == empty;
       
   226 }
       
   227 
       
   228 static const QStringSet newBrokenDetails()
       
   229 {
       
   230     return (QStringSet() <<
       
   231             QLatin1String("Anniversary") <<         // FIXME: doesn't load at all
       
   232             QLatin1String("Avatar") <<              // FIXME: doesn't load at all
       
   233             QLatin1String("Birthday") <<            // FIXME: doesn't load at all
       
   234             QLatin1String("EmailAddress") <<        // FIXME: doesn't load for work context
       
   235             QLatin1String("Gender") <<              // FIXME: doesn't load at all
       
   236             QLatin1String("GeoLocation") <<         // FIXME: doesn't load at all
       
   237             QLatin1String("Guid") <<                // FIXME: doesn't load at all
       
   238             QLatin1String("Note") <<                // FIXME: doesn't load at all
       
   239             QLatin1String("OnlineAccount") <<       // FIXME: doesn't load at all
       
   240             QLatin1String("Organization") <<        // FIXME: doesn't load at all
       
   241             QLatin1String("StreetAddress") <<       // FIXME: doesn't load at all
       
   242             QLatin1String("SyncTarget") <<          // FIXME: doesn't load at all
       
   243             QLatin1String("Timestamp") <<           // FIXME: doesn't load at all
       
   244             QLatin1String("Url"));                  // FIXME: doesn't load at all
       
   245 }
       
   246 
       
   247 static const QHash<QString, QStringSet> newBrokenFields()
       
   248 {
       
   249     QHash<QString, QStringSet> brokenFields;
       
   250 
       
   251     brokenFields.insert(QLatin1String("EmailAddress"),
       
   252                         QStringSet() << QLatin1String("Context"));
       
   253 
       
   254     brokenFields.insert(QLatin1String("Name"),
       
   255                         QStringSet() << QLatin1String("Context")        // FIXME: meaning of this field?
       
   256                                      << QLatin1String("CustomLabel")    // FIXME: meaning of this field?
       
   257                                      << QLatin1String("Suffix"));
       
   258 
       
   259     brokenFields.insert(QLatin1String("Nickname"),
       
   260                         QStringSet() << QLatin1String("Context"));      // FIXME: meaning of this field?
       
   261 
       
   262     brokenFields.insert(QLatin1String("PhoneNumber"),
       
   263                         QStringSet() << QLatin1String("Context")
       
   264                                      << QLatin1String("PhoneNumber")
       
   265                                      << QLatin1String("SubTypes"));
       
   266 
       
   267     return brokenFields;
       
   268 }
       
   269 
       
   270 static const QStringSet newSynthesizedDetails()
       
   271 {
       
   272     return (QStringSet() <<
       
   273             QLatin1String("DisplayLabel") <<
       
   274             QLatin1String("Type"));
       
   275 }
       
   276 
       
   277 static const QStringSet brokenDetails(newBrokenDetails());
       
   278 static const QHash<QString, QStringSet> brokenFields(newBrokenFields());
       
   279 static const QStringSet synthesizedDetails(newSynthesizedDetails());
       
   280 
       
   281 void ut_qtcontacts_trackerplugin_definitions::verifyContacts(const QString &definitionName,
       
   282                                          QList<QContact> &savedContacts,
       
   283                                          QList<QContact> &fetchedContacts)
       
   284 {
       
   285     qSort(savedContacts.begin(), savedContacts.end(), localIdOrder);
       
   286     qSort(fetchedContacts.begin(), fetchedContacts.end(), localIdOrder);
       
   287 
       
   288     QCOMPARE(fetchedContacts.count(), savedContacts.count());
       
   289 
       
   290     for(int i = 0, l = savedContacts.count(); i < l; ++i) {
       
   291         const QList<QContactDetail> &savedDetails(savedContacts[i].details(definitionName));
       
   292         const QList<QContactDetail> &fetchedDetails(fetchedContacts[i].details(definitionName));
       
   293 
       
   294         QCOMPARE(savedDetails.count(), 1);
       
   295         QCOMPARE(fetchedDetails.count(), 1);
       
   296 
       
   297         QVariantMap savedValues(savedDetails[0].variantValues());
       
   298         QVariantMap fetchedValues(fetchedDetails[0].variantValues());
       
   299 
       
   300         QStringSet fieldNames(savedValues.keys().toSet());
       
   301         fieldNames.unite(fetchedValues.keys().toSet());
       
   302 
       
   303         foreach(const QString &key, fieldNames) {
       
   304             if (brokenFields[definitionName].contains(key)) {
       
   305                 const QString msg(QString::fromLatin1("ignoring broken %1 field").arg(key));
       
   306                 QEXPECT_FAIL("", qPrintable(msg), Continue);
       
   307             }
       
   308 
       
   309             if (not savedValues.contains(key)) {
       
   310                 QVERIFY(isEmpty(fetchedValues[key]));
       
   311             } else if (not fetchedValues.contains(key)) {
       
   312                 QVERIFY(isEmpty(savedValues[key]));
       
   313             } else {
       
   314                 QCOMPARE(savedValues[key], fetchedValues[key]);
       
   315             }
       
   316         }
       
   317     }
       
   318 }
       
   319 
       
   320 void ut_qtcontacts_trackerplugin_definitions::saveAndFetchOne(const QString &definitionName)
       
   321 {
       
   322     qDebug() << "===============================================================================";
       
   323     qDebug() << qPrintable(definitionName);
       
   324     qDebug() << "===============================================================================";
       
   325 
       
   326     if (brokenDetails.contains(definitionName)) {
       
   327         QSKIP("support for this detail is broken right now", SkipAll);
       
   328     }
       
   329 
       
   330     if (synthesizedDetails.contains(definitionName)) {
       
   331         QSKIP("synthesized details are out of scope for now", SkipAll);
       
   332     }
       
   333 
       
   334     QList<QContact> savedContacts;
       
   335     QList<QContactLocalId> savedContactIds;
       
   336 
       
   337     createTestContacts(definitionName, savedContacts);
       
   338     CHECK_CURRENT_TEST_FAILED;
       
   339 
       
   340     saveContacts(savedContacts);
       
   341     CHECK_CURRENT_TEST_FAILED;
       
   342 
       
   343     foreach(const QContact &contact, savedContacts) {
       
   344         savedContactIds.append(contact.localId());
       
   345     }
       
   346 
       
   347     QCOMPARE(savedContactIds.toSet().count(), savedContacts.count());
       
   348 
       
   349     QList<QContact> fetchedContacts;
       
   350 
       
   351     foreach(const QContactLocalId &id, savedContactIds) {
       
   352         QContact contact;
       
   353         fetchContact(id, contact);
       
   354         CHECK_CURRENT_TEST_FAILED;
       
   355         fetchedContacts.append(contact);
       
   356     }
       
   357 
       
   358     verifyContacts(definitionName, savedContacts, fetchedContacts);
       
   359 }
       
   360 
       
   361 void ut_qtcontacts_trackerplugin_definitions::saveAndFetchMany(const QString &definitionName)
       
   362 {
       
   363     qDebug() << "===============================================================================";
       
   364     qDebug() << qPrintable(definitionName);
       
   365     qDebug() << "===============================================================================";
       
   366 
       
   367     if (brokenDetails.contains(definitionName)) {
       
   368         QSKIP("support for this detail is broken right now", SkipAll);
       
   369     }
       
   370 
       
   371     if (synthesizedDetails.contains(definitionName)) {
       
   372         QSKIP("synthesized details are out of scope for now", SkipAll);
       
   373     }
       
   374 
       
   375     QList<QContact> savedContacts;
       
   376     QList<QContactLocalId> savedContactIds;
       
   377 
       
   378     createTestContacts(definitionName, savedContacts);
       
   379     CHECK_CURRENT_TEST_FAILED;
       
   380 
       
   381     saveContacts(savedContacts);
       
   382     CHECK_CURRENT_TEST_FAILED;
       
   383 
       
   384     foreach(const QContact &contact, savedContacts) {
       
   385         savedContactIds.append(contact.localId());
       
   386     }
       
   387 
       
   388     QCOMPARE(savedContactIds.toSet().count(), savedContacts.count());
       
   389 
       
   390     QList<QContact> fetchedContacts;
       
   391     fetchContacts(savedContactIds, fetchedContacts);
       
   392     CHECK_CURRENT_TEST_FAILED;
       
   393 
       
   394     verifyContacts(definitionName, savedContacts, fetchedContacts);
       
   395 }
       
   396 
       
   397 void ut_qtcontacts_trackerplugin_definitions::saveAndFetchAll(const QString &definitionName)
       
   398 {
       
   399     qDebug() << "===============================================================================";
       
   400     qDebug() << qPrintable(definitionName);
       
   401     qDebug() << "===============================================================================";
       
   402 
       
   403     if (brokenDetails.contains(definitionName)) {
       
   404         QSKIP("support for this detail is broken right now", SkipAll);
       
   405     }
       
   406 
       
   407     if (synthesizedDetails.contains(definitionName)) {
       
   408         QSKIP("synthesized details are out of scope for now", SkipAll);
       
   409     }
       
   410 
       
   411     QList<QContact> savedContacts;
       
   412     QSet<QContactLocalId> savedContactIds;
       
   413 
       
   414     createTestContacts(definitionName, savedContacts);
       
   415     CHECK_CURRENT_TEST_FAILED;
       
   416 
       
   417     saveContacts(savedContacts);
       
   418     CHECK_CURRENT_TEST_FAILED;
       
   419 
       
   420     foreach(const QContact &contact, savedContacts) {
       
   421         savedContactIds.insert(contact.localId());
       
   422     }
       
   423 
       
   424     QCOMPARE(savedContactIds.count(), savedContacts.count());
       
   425 
       
   426     QList<QContact> fetchedContacts;
       
   427     fetchContacts(QContactInvalidFilter(), fetchedContacts);
       
   428     CHECK_CURRENT_TEST_FAILED;
       
   429 
       
   430     QList<QContact>::iterator i = fetchedContacts.begin();
       
   431 
       
   432     while (i != fetchedContacts.end()) {
       
   433         if (not savedContactIds.contains(i->localId())) {
       
   434             i = fetchedContacts.erase(i);
       
   435         } else {
       
   436             ++i;
       
   437         }
       
   438     }
       
   439 
       
   440     verifyContacts(definitionName, savedContacts, fetchedContacts);
       
   441 }
       
   442 
       
   443 #define IMPLEMENT_SAVE_AND_FETCH(DefinitionName)                \
       
   444                                                                 \
       
   445 void ut_qtcontacts_trackerplugin_definitions::saveAndFetchOne##DefinitionName()     \
       
   446 {                                                               \
       
   447     saveAndFetchOne(QString::fromLatin1(#DefinitionName));      \
       
   448     CHECK_CURRENT_TEST_FAILED;                                  \
       
   449 }                                                               \
       
   450                                                                 \
       
   451 void ut_qtcontacts_trackerplugin_definitions::saveAndFetchMany##DefinitionName()    \
       
   452 {                                                               \
       
   453     saveAndFetchMany(QString::fromLatin1(#DefinitionName));     \
       
   454     CHECK_CURRENT_TEST_FAILED;                                  \
       
   455 }                                                               \
       
   456                                                                 \
       
   457 void ut_qtcontacts_trackerplugin_definitions::saveAndFetchAll##DefinitionName()     \
       
   458 {                                                               \
       
   459     saveAndFetchAll(QString::fromLatin1(#DefinitionName));      \
       
   460     CHECK_CURRENT_TEST_FAILED;                                  \
       
   461 }
       
   462 
       
   463 IMPLEMENT_SAVE_AND_FETCH(Anniversary)
       
   464 IMPLEMENT_SAVE_AND_FETCH(Avatar)
       
   465 IMPLEMENT_SAVE_AND_FETCH(Birthday)
       
   466 IMPLEMENT_SAVE_AND_FETCH(DisplayLabel)
       
   467 IMPLEMENT_SAVE_AND_FETCH(EmailAddress)
       
   468 IMPLEMENT_SAVE_AND_FETCH(Gender)
       
   469 IMPLEMENT_SAVE_AND_FETCH(GeoLocation)
       
   470 IMPLEMENT_SAVE_AND_FETCH(Guid)
       
   471 IMPLEMENT_SAVE_AND_FETCH(Name)
       
   472 IMPLEMENT_SAVE_AND_FETCH(Nickname)
       
   473 IMPLEMENT_SAVE_AND_FETCH(Note)
       
   474 IMPLEMENT_SAVE_AND_FETCH(OnlineAccount)
       
   475 IMPLEMENT_SAVE_AND_FETCH(Organization)
       
   476 IMPLEMENT_SAVE_AND_FETCH(PhoneNumber)
       
   477 IMPLEMENT_SAVE_AND_FETCH(StreetAddress)
       
   478 IMPLEMENT_SAVE_AND_FETCH(SyncTarget)
       
   479 IMPLEMENT_SAVE_AND_FETCH(Timestamp)
       
   480 IMPLEMENT_SAVE_AND_FETCH(Type)
       
   481 IMPLEMENT_SAVE_AND_FETCH(Url)
       
   482 
       
   483 QTEST_MAIN(ut_qtcontacts_trackerplugin_definitions)