/****************************************************************************
**
** Copyright (C) 2010 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 "../../../src/publishsubscribe/psmapperserver_symbian/qcrmlparser_p.h"
#include <qmobilityglobal.h>
#include <QtTest/QTest>
#include <QDebug>
#include <QDir>
#if defined(Q_OS_SYMBIAN)
# define TESTDATA_DIR "."
#endif
QTM_USE_NAMESPACE
class tst_QCrmlParser : public QObject
{
Q_OBJECT
private slots:
void init();
void empty();
void simple();
void keyRangeSequence();
void bitmaskKey();
void keyWithUnknownElements();
void keyRangeNoSequence();
void singleKey();
void multipleKeyRanges();
void multipleBitmaskKeys();
void wrongXmlFile();
void noRepositoryUidValue();
void keyMissingEndTag();
void outOfPlaceEndTag();
void invalidTarget();
private:
bool verifyKeyData(const QHash<QString,KeyData> &keyHash, const QString &key,
quint64 uid, KeyData::Target target = KeyData::CRepository, quint32 bitIndex = 0);
QHash<QString,KeyData> makeHash(const QList<KeyData> &keyList);
void printKeyList(const QList<KeyData> &list);
QDir testData;
};
void tst_QCrmlParser::init()
{
testData.setPath(TESTDATA_DIR "/testdata");
}
void tst_QCrmlParser::empty()
{
QList<KeyData> keyData;
KeyData *key = new KeyData();
keyData.append(*key);
KeyData::Target target = KeyData::RProperty;
QHash<QString, KeyData> keyHash = makeHash(keyData);
QVERIFY(verifyKeyData(keyHash, "", 0, target));
}
void tst_QCrmlParser::simple()
{
QCrmlParser parser;
QList<KeyData> keyData;
keyData = parser.parseQCrml("dontexist");
QVERIFY(parser.error() == QCrmlParser::FileNotFound);
QCOMPARE(parser.errorString(), QString("File does not exist: dontexist"));
QVERIFY(keyData.count() == 0);
keyData = parser.parseQCrml(testData.absoluteFilePath("test1.qcrml"));
QVERIFY(parser.error() == QCrmlParser::NoError);
QHash<QString, KeyData> keyHash = makeHash(keyData);
KeyData::Target target = KeyData::CRepository;
QVERIFY(verifyKeyData(keyHash, "/sensors/accelerometer/x",
Q_UINT64_C(0x4815162300000000),target));
QVERIFY(verifyKeyData(keyHash, "/sensors/accelerometer/y",
Q_UINT64_C(0x4815162300000001),target));
QVERIFY(verifyKeyData(keyHash, "/sensors/accelerometer/z",
Q_UINT64_C(0x4815162300000002),target));
QVERIFY(parser.error() == QCrmlParser::NoError);
for (int i = 0; i < keyData.count(); ++i) {
QVERIFY(keyData.at(i).keyId() == quint32(i));
QVERIFY(keyData.at(i).repoId() == (keyData.at(i).uid() >> 32));
}
}
void tst_QCrmlParser::keyRangeSequence()
{
QCrmlParser parser;
QList<KeyData> keyData;
keyData = parser.parseQCrml(testData.absoluteFilePath("test2.qcrml"));
QCOMPARE(keyData.count(), 763);
QHash<QString,KeyData> keyHash = makeHash(keyData);
quint64 repoUID = Q_UINT64_C(0x81531600000000);
quint32 settingsIdentifier = 0x07000000;
quint32 itemSettingIndex = 0x00010000;
quint32 itemSettingIndexOffset = 0x00020000;
quint64 uidPrefix = 0;
QVERIFY(verifyKeyData(keyHash, QString("/PIM/Contact"), repoUID + settingsIdentifier));
for(int i=0; i < 254; i++) {
uidPrefix = repoUID + settingsIdentifier + itemSettingIndex * i + itemSettingIndexOffset;
QVERIFY(verifyKeyData(keyHash,QString("/PIM/Contact/") + QString::number(i) + "/firstName",
uidPrefix + 0x1));
QVERIFY(verifyKeyData(keyHash,QString("/PIM/Contact/") + QString::number(i) + "/lastName",
uidPrefix + 0x2));
QVERIFY(verifyKeyData(keyHash,QString("/PIM/Contact/") + QString::number(i) + "/group",
uidPrefix + 0xf00f));
}
for (int i = 0; i < keyData.count(); ++i) {
QVERIFY(keyData.at(i).keyId() == (keyData.at(i).uid() & 0xFFFFFFFF));
QVERIFY(keyData.at(i).repoId() == (keyData.at(i).uid() >> 32));
}
}
void tst_QCrmlParser::bitmaskKey()
{
QCrmlParser parser;
QList<KeyData> keyData;
keyData = parser.parseQCrml(testData.absoluteFilePath("test3.qcrml"));
QCOMPARE(keyData.count(), 4);
QHash<QString, KeyData> keyHash = makeHash(keyData);
quint64 uid = Q_UINT64_C(0x1234567800000001);
KeyData::Target target = KeyData::CRepository;
QVERIFY(verifyKeyData(keyHash, QString("/Dharma/Swan"), uid, target, 1));
QVERIFY(verifyKeyData(keyHash, QString("/Dharma/Pearl"), uid, target, 2));
QVERIFY(verifyKeyData(keyHash, QString("/Dharma/Hydra"), uid, target,32));
QVERIFY(verifyKeyData(keyHash, QString("/Dharma/LookingGlass"), uid, target, 4));
for (int i = 0; i < keyData.count(); ++i) {
QVERIFY(keyData.at(i).keyId() == (keyData.at(i).uid() & 0xFFFFFFFF));
QVERIFY(keyData.at(i).repoId() == (keyData.at(i).uid() >> 32));
}
}
void tst_QCrmlParser::keyWithUnknownElements()
{
QCrmlParser parser;
QList<KeyData> keyData;
keyData = parser.parseQCrml(testData.absoluteFilePath("test4.qcrml"));
QCOMPARE(keyData.count(), 3);
QHash<QString, KeyData> keyHash = makeHash(keyData);
KeyData::Target target = KeyData::RProperty;
QVERIFY(verifyKeyData(keyHash, "/sensors/accelerometer/x",
Q_UINT64_C(0x4815162300000000),target));
QVERIFY(verifyKeyData(keyHash, "/sensors/accelerometer/y",
Q_UINT64_C(0x4815162300000001),target));
QVERIFY(verifyKeyData(keyHash, "/sensors/accelerometer/z",
Q_UINT64_C(0x4815162300000002),target));
for (int i = 0; i < keyData.count(); ++i) {
QVERIFY(keyData.at(i).keyId() == (keyData.at(i).uid() & 0xFFFFFFFF));
QVERIFY(keyData.at(i).repoId() == (keyData.at(i).uid() >> 32));
}
}
void tst_QCrmlParser::keyRangeNoSequence()
{
QCrmlParser parser;
QList<KeyData> keyData;
keyData = parser.parseQCrml(testData.absoluteFilePath("test5.qcrml"));
QCOMPARE(keyData.count(), 65535);
QHash<QString,KeyData> keyHash = makeHash(keyData);
quint64 repoUid = Q_UINT64_C(0x8765432100000000);
quint32 firstAddr = 0x1;
quint64 uidPrefix = repoUid + firstAddr;
for (int i = 0; i < 65535; ++i) {
QVERIFY(verifyKeyData(keyHash, QString("/MyFeature/MyNumbers/") + QString::number(i),
uidPrefix + i));
}
for (int i = 0; i < keyData.count(); ++i) {
QVERIFY(keyData.at(i).keyId() == (keyData.at(i).uid() & 0xFFFFFFFF));
QVERIFY(keyData.at(i).repoId() == (keyData.at(i).uid() >> 32));
}
}
void tst_QCrmlParser::singleKey()
{
QCrmlParser parser;
QList<KeyData> keyData;
keyData = parser.parseQCrml(testData.absoluteFilePath("test6.qcrml"));
QCOMPARE(keyData.count(), 1);
QHash<QString, KeyData> keyHash = makeHash(keyData);
QVERIFY(verifyKeyData(keyHash, "/compass",
Q_UINT64_C(0x1111222298765432)));
for (int i = 0; i < keyData.count(); ++i) {
QVERIFY(keyData.at(i).keyId() == (keyData.at(i).uid() & 0xFFFFFFFF));
QVERIFY(keyData.at(i).repoId() == (keyData.at(i).uid() >> 32));
}
}
void tst_QCrmlParser::multipleKeyRanges()
{
QCrmlParser parser;
QList<KeyData> keyData;
keyData = parser.parseQCrml(testData.absoluteFilePath("test7.qcrml"));
QCOMPARE(keyData.count(),33 );
QHash<QString, KeyData> keyHash = makeHash(keyData);
for(int i = 0x8; i <=0xC; ++i) {
QVERIFY(verifyKeyData(keyHash, QString("/section31/") + QString::number(i - 0x8,10),
Q_UINT64_C(0x1212989800000000)+i));
}
for(int i = 0xE; i <= 0x13; ++i) {
QVERIFY(verifyKeyData(keyHash, QString("/talshiar/") + QString::number(i - 0xE,10),
Q_UINT64_C(0x1212989800000000)+i));
}
quint64 repoUID = Q_UINT64_C(0x1212989800000000);
quint32 settingsIdentifier = 0x200;
quint32 itemSettingIndex = 0x020;
quint64 uidPrefix = 0;
for(int i = 0; i < 11; i++) {
uidPrefix = repoUID + settingsIdentifier + itemSettingIndex * i;
QVERIFY(verifyKeyData(keyHash,QString("/obsidian/") + QString::number(i) + "/name",
uidPrefix + 0x1));
QVERIFY(verifyKeyData(keyHash,QString("/obsidian/") + QString::number(i) + "/rank",
uidPrefix + 0x2));
}
for (int i = 0; i < keyData.count(); ++i) {
QVERIFY(keyData.at(i).keyId() == (keyData.at(i).uid() & 0xFFFFFFFF));
QVERIFY(keyData.at(i).repoId() == (keyData.at(i).uid() >> 32));
}
}
void tst_QCrmlParser::multipleBitmaskKeys()
{
QCrmlParser parser;
QList<KeyData> keyData;
keyData = parser.parseQCrml(testData.absoluteFilePath("test8.qcrml"));
QCOMPARE(keyData.count(), 7);
QHash<QString, KeyData> keyHash = makeHash(keyData);
KeyData::Target target = KeyData::CRepository;
QVERIFY(verifyKeyData(keyHash, QString("/Dharma/Swan"),Q_UINT64_C(0x1234567800000001),target,1));
QVERIFY(verifyKeyData(keyHash, QString("/Dharma/Pearl"),Q_UINT64_C(0x1234567800000001),target,2));
QVERIFY(verifyKeyData(keyHash, QString("/Dharma/Hydra"),Q_UINT64_C(0x1234567800000001),target,32));
QVERIFY(verifyKeyData(keyHash, QString("/Dharma/LookingGlass"),Q_UINT64_C(0x1234567800000001),target,4));
QVERIFY(verifyKeyData(keyHash, QString("/Ben"),Q_UINT64_C(0x123456780000000A),target,2));
QVERIFY(verifyKeyData(keyHash, QString("/Tom"),Q_UINT64_C(0x123456780000000A),target,4));
QVERIFY(verifyKeyData(keyHash, QString("/Ethan"),Q_UINT64_C(0x123456780000000A),target,5));
for (int i = 0; i < keyData.count(); ++i) {
QVERIFY(keyData.at(i).keyId() == (keyData.at(i).uid() & 0xFFFFFFFF));
QVERIFY(keyData.at(i).repoId() == (keyData.at(i).uid() >> 32));
}
}
void tst_QCrmlParser::wrongXmlFile()
{
QCrmlParser parser;
QList<KeyData> keyData;
keyData = parser.parseQCrml(testData.absoluteFilePath("error1.qcrml"));
QVERIFY(parser.error() == QCrmlParser::ParseError);
}
void tst_QCrmlParser::noRepositoryUidValue()
{
QCrmlParser parser;
QList<KeyData> keyData;
keyData = parser.parseQCrml(testData.absoluteFilePath("error2.qcrml"));
QVERIFY(parser.error() == QCrmlParser::ParseError);
}
void tst_QCrmlParser::keyMissingEndTag()
{
QCrmlParser parser;
QList<KeyData> keyData;
keyData = parser.parseQCrml(testData.absoluteFilePath("error3.qcrml"));
QVERIFY(parser.error() == QCrmlParser::ParseError);
}
void tst_QCrmlParser::outOfPlaceEndTag()
{
QCrmlParser parser;
QList<KeyData> keyData;
keyData = parser.parseQCrml(testData.absoluteFilePath("error4.qcrml"));
QVERIFY(parser.error() == QCrmlParser::ParseError);
QVERIFY(keyData.count() == 0);
}
void tst_QCrmlParser::invalidTarget()
{
QCrmlParser parser;
QList<KeyData> keyData;
keyData = parser.parseQCrml(testData.absoluteFilePath("error5.qcrml"));
QVERIFY(parser.error() == QCrmlParser::ParseError);
QVERIFY(keyData.count() == 0);
}
bool tst_QCrmlParser::verifyKeyData(const QHash<QString,KeyData> &keyHash, const QString &key,
quint64 uid, KeyData::Target target, quint32 bitIndex) {
KeyData data = keyHash.value(key);
if (data.target() != target) {
qWarning() << "Target does not match, expected" << target
<< "\n actual:" << data.target();
return false;
}
if ( data.uid()!= uid ) {
qWarning() << "UID does not match expected:" << QString::number(uid,16) << "\n actual:"
<< QString::number(data.uid(),16);
return false;
}
if (data.bitIndex() != bitIndex) {
qWarning() << "BitIndex does not match, expected: " << QString::number(bitIndex,16)
<< "\n actual:" << QString::number(data.bitIndex(),16);
return false;
}
return true;
}
QHash<QString,KeyData> tst_QCrmlParser::makeHash(const QList<KeyData> &keyList)
{
QHash<QString,KeyData> rv;
for (int i = 0; i < keyList.count(); ++i) {
rv.insert(keyList.at(i).path(), keyList.at(i));
}
return rv;
}
void tst_QCrmlParser::printKeyList(const QList<KeyData> &keyList)
{
for (int i=0; i < keyList.count(); ++i) {
qDebug() << "KeyPath = " << keyList.at(i).path();
qDebug() << "UID = " << QString::number(keyList.at(i).uid(), 16);
qDebug() << "bitIndex"<< QString::number(keyList.at(i).bitIndex());
}
}
QTEST_MAIN(tst_QCrmlParser)
#include "tst_qcrmlparser.moc"