tests/auto/qvaluespace/tst_qvaluespace.cpp
changeset 0 876b1a06bc25
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/auto/qvaluespace/tst_qvaluespace.cpp	Wed Aug 25 15:49:42 2010 +0300
@@ -0,0 +1,422 @@
+/****************************************************************************
+**
+** 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 <qvaluespace_p.h>
+#include <qvaluespacesubscriber.h>
+#include <qvaluespacepublisher.h>
+
+#include <QtTest/QTest>
+#include <QSet>
+#include <QFile>
+
+#include <QDebug>
+
+QTM_USE_NAMESPACE
+class FakeLayer : public QAbstractValueSpaceLayer
+{
+    Q_OBJECT
+
+public:
+    QString name() { return QString("Fake Layer"); }
+
+    bool startup(Type) { return true; }
+    void shutdown() { }
+
+    QUuid id() { return QUuid(0x76c95ddc, 0xe38d, 0x42f8, 0xb2,
+                              0x54, 0x21, 0xff, 0xa3, 0x63, 0x74, 0xf7); }
+    unsigned int order() { return 0x20000000; }
+
+    Handle item(Handle parent, const QString &subPath);
+    void removeHandle(Handle handle);
+    void setProperty(Handle, Properties) { }
+
+    bool value(Handle handle, QVariant *data);
+    bool value(Handle handle, const QString &subPath, QVariant *data);
+    QSet<QString> children(Handle handle);
+
+    QValueSpace::LayerOptions layerOptions() const;
+
+    /* QValueSpaceSubscriber functions */
+    bool supportsInterestNotification() const;
+    bool notifyInterest(Handle handle, bool interested);
+
+    /* QValueSpacePublisher functions */
+    bool setValue(QValueSpacePublisher *creator, Handle handle,
+                  const QString &subPath, const QVariant &value);
+    bool removeValue(QValueSpacePublisher *creator, Handle handle, const QString &subPath);
+    bool removeSubTree(QValueSpacePublisher *creator, Handle handle);
+    void addWatch(QValueSpacePublisher *creator, Handle handle);
+    void removeWatches(QValueSpacePublisher *creator, Handle parent);
+    void sync() { }
+
+    QStringList testErrors();
+
+private:
+    bool testPath(const QString &path);
+
+    QMap<uint, QString> handles;
+    QMap<uint, uint> interest;
+
+    QStringList m_testErrors;
+};
+
+bool FakeLayer::testPath(const QString &path)
+{
+    if (path.isEmpty())
+        m_testErrors << QLatin1String("path is empty");
+    else if (path.at(0) != '/') {
+        m_testErrors << QLatin1String("path does not start with /");
+    } else {
+        if (path.length() > 1 && path.endsWith('/')) {
+            m_testErrors << QLatin1String("path ends with /");
+        } else if (path.contains("//")) {
+            m_testErrors << QLatin1String("path contains //");
+        } else {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+QAbstractValueSpaceLayer::Handle FakeLayer::item(Handle parent, const QString &subPath)
+{
+    if (parent == InvalidHandle) {
+        if (testPath(subPath)) {
+            if (!handles.contains(qHash(subPath)))
+                handles.insert(qHash(subPath), subPath);
+            return Handle(qHash(subPath));
+        }
+    } else {
+        qDebug() << "relative" << subPath;
+        m_testErrors << QLatin1String("Relative subPath, not an error not done yet");
+    }
+
+    return InvalidHandle;
+}
+
+void FakeLayer::removeHandle(Handle handle)
+{
+    if (!handles.contains(handle))
+        m_testErrors << QLatin1String("Unknown handle");
+    else
+        handles.remove(handle);
+}
+
+bool FakeLayer::value(Handle handle, QVariant *data)
+{
+    if (!handles.contains(handle))
+        m_testErrors << QLatin1String("Unknown handle");
+
+    if (!data)
+        m_testErrors << QLatin1String("data is null");
+
+    *data = QVariant();
+    return true;
+}
+
+bool FakeLayer::value(Handle handle, const QString &subPath, QVariant *data)
+{
+    if (!handles.contains(handle))
+        m_testErrors << QLatin1String("Unknown handle");
+
+    if (!data)
+        m_testErrors << QLatin1String("data is null");
+
+    if (testPath(subPath)) {
+        *data = QVariant();
+        return true;
+    } else {
+        return false;
+    }
+}
+
+QSet<QString> FakeLayer::children(Handle handle)
+{
+    if (!handles.contains(handle))
+        m_testErrors << QLatin1String("Unknown handle");
+
+    return QSet<QString>();
+}
+
+QValueSpace::LayerOptions FakeLayer::layerOptions() const
+{
+    return QValueSpace::TransientLayer;
+}
+
+bool FakeLayer::supportsInterestNotification() const
+{
+    return true;
+}
+
+bool FakeLayer::notifyInterest(Handle handle, bool interested)
+{
+    if (!handles.contains(handle))
+        m_testErrors << QLatin1String("Unknown handle");
+
+    if (interested) {
+        if (interest.contains(handle))
+            m_testErrors << QLatin1String("path has been registered for interest");
+        ++interest[handle];
+    } else {
+        if (!interest.contains(handle))
+            m_testErrors << QLatin1String("path has not been registered for interest");
+        --interest[handle];
+        if (interest[handle] == 0)
+            interest.remove(handle);
+    }
+
+    return true;
+}
+
+bool FakeLayer::setValue(QValueSpacePublisher *creator, Handle handle,
+                         const QString &subPath, const QVariant &)
+{
+    if (!creator)
+        m_testErrors << QLatin1String("creator is null");
+
+    if (!handles.contains(handle))
+        m_testErrors << QLatin1String("Unknown handle");
+
+    testPath(subPath);
+
+    return true;
+}
+
+bool FakeLayer::removeValue(QValueSpacePublisher *creator, Handle handle, const QString &subPath)
+{
+    if (!creator)
+        m_testErrors << QLatin1String("creator is null");
+
+    if (!handles.contains(handle))
+        m_testErrors << QLatin1String("Unknown handle");
+
+    testPath(subPath);
+
+    return true;
+}
+
+bool FakeLayer::removeSubTree(QValueSpacePublisher *creator, Handle handle)
+{
+    if (!creator)
+        m_testErrors << QLatin1String("creator is null");
+
+    if (!handles.contains(handle))
+        m_testErrors << QLatin1String("Unknown handle");
+
+    return true;
+}
+
+void FakeLayer::addWatch(QValueSpacePublisher *creator, Handle handle)
+{
+    if (!creator)
+        m_testErrors << QLatin1String("creator is null");
+
+    if (!handles.contains(handle))
+        m_testErrors << QLatin1String("Unknown handle");
+}
+
+void FakeLayer::removeWatches(QValueSpacePublisher *creator, Handle parent)
+{
+    if (!creator)
+        m_testErrors << QLatin1String("creator is null");
+
+    if (!handles.contains(parent))
+        m_testErrors << QLatin1String("Unknown handle");
+}
+
+QStringList FakeLayer::testErrors()
+{
+    QStringList result = m_testErrors;
+    m_testErrors.clear();
+    return result;
+}
+
+class tst_QValueSpace: public QObject
+{
+    Q_OBJECT
+
+private slots:
+    void initTestCase();
+    void cleanupTestCase();
+
+    void availableLayers();
+
+    void layerInterface_data();
+    void layerInterface();
+
+private:
+    FakeLayer *fakeLayer;
+};
+
+void tst_QValueSpace::initTestCase()
+{
+#ifdef Q_OS_UNIX
+    QFile::remove("/tmp/qt-0/valuespace_shmlayer");
+#endif
+
+    qRegisterMetaType<QVariant>("QVariant");
+
+    fakeLayer = new FakeLayer;
+    QValueSpace::installLayer(fakeLayer);
+    QValueSpace::initValueSpaceServer();
+}
+
+void tst_QValueSpace::cleanupTestCase()
+{
+    delete fakeLayer;
+}
+
+void tst_QValueSpace::availableLayers()
+{
+    QList<QUuid> layers = QValueSpace::availableLayers();
+
+#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) && !defined(Q_WS_MAEMO_5) && !defined(Q_WS_MAEMO_6)
+    QVERIFY(layers.contains(QVALUESPACE_SHAREDMEMORY_LAYER));
+#else
+    QVERIFY(!layers.contains(QVALUESPACE_SHAREDMEMORY_LAYER));
+#endif
+
+#ifdef Q_OS_WIN
+    QVERIFY(layers.contains(QVALUESPACE_VOLATILEREGISTRY_LAYER));
+    QVERIFY(layers.contains(QVALUESPACE_NONVOLATILEREGISTRY_LAYER));
+#else
+    QVERIFY(!layers.contains(QVALUESPACE_VOLATILEREGISTRY_LAYER));
+    QVERIFY(!layers.contains(QVALUESPACE_NONVOLATILEREGISTRY_LAYER));
+#endif
+
+#ifdef Q_WS_MAEMO_5
+    QVERIFY(layers.contains(QVALUESPACE_GCONF_LAYER));
+#endif
+
+#ifdef Q_WS_MAEMO_6
+    QVERIFY(layers.contains(QVALUESPACE_CONTEXTKIT_LAYER));
+#else
+    QVERIFY(!layers.contains(QVALUESPACE_CONTEXTKIT_LAYER));
+#endif
+
+    QVERIFY(layers.contains(fakeLayer->id()));
+}
+
+#define CHECK_ERRORS(x) do { \
+    x; \
+    QStringList testErrors = fakeLayer->testErrors(); \
+    if (!testErrors.isEmpty()) { \
+        qDebug() << testErrors; \
+        QFAIL(#x); \
+    } \
+} while (false)
+
+void tst_QValueSpace::layerInterface_data()
+{
+    QTest::addColumn<QString>("path");
+    QTest::addColumn<QString>("attribute");
+
+    QStringList paths;
+    paths << QString() << QString("/") << QString("//")
+          << QString("layerInterface") << QString("layerInterface/")
+          << QString("/layerInterface") << QString("//layerInterface")
+          << QString("/layerInterface/") << QString("/layerInterface//")
+          << QString("/layerInterface/subpath") << QString("/layerInterface//subpath")
+          << QString("/layerInterface/subpath/") << QString("/layerInterface/subpath//");
+
+    QStringList attributes;
+    attributes << QString()
+               << QString("/")
+               << QString("//")
+               << QString("value")
+               << QString("value/")
+               << QString("value//")
+               << QString("/value")
+               << QString("//value")
+               << QString("/value/")
+               << QString("subpath/value")
+               << QString("subpath//value");
+
+    foreach (const QString &path, paths) {
+        foreach (const QString &attribute, attributes) {
+            QString id = QString("p:%1 a:%2").arg(path, attribute);
+            QTest::newRow(id.toLocal8Bit().constData()) << path << attribute;
+        }
+    }
+}
+
+class SignalSink : public QObject
+{
+    Q_OBJECT
+
+public slots:
+    void slot() { }
+};
+
+void tst_QValueSpace::layerInterface()
+{
+    QFETCH(QString, path);
+    QFETCH(QString, attribute);
+
+    QValueSpaceSubscriber *subscriber;
+
+    CHECK_ERRORS(subscriber = new QValueSpaceSubscriber(path));
+
+    CHECK_ERRORS(subscriber->value(attribute));
+    CHECK_ERRORS(subscriber->children());
+
+    CHECK_ERRORS(delete subscriber);
+
+
+    QValueSpacePublisher *publisher;
+
+    CHECK_ERRORS(publisher = new QValueSpacePublisher(fakeLayer->id(), path));
+
+    QVERIFY(publisher->isConnected());
+
+    CHECK_ERRORS(publisher->setValue(attribute, 10));
+    CHECK_ERRORS(publisher->resetValue(attribute));
+
+    SignalSink sink;
+    CHECK_ERRORS(connect(publisher, SIGNAL(interestChanged(QString,bool)),
+                         &sink, SLOT(slot())));
+
+    CHECK_ERRORS(delete publisher);
+}
+
+QTEST_MAIN(tst_QValueSpace)
+#include "tst_qvaluespace.moc"