Moving relevant tests to corelib/concurrent
authorHolger Ihrig <holger.ihrig@nokia.com>
Wed, 24 Aug 2011 08:51:34 +0000 (10:51 +0200)
committerHolger Ihrig <holger.ihrig@nokia.com>
Tue, 30 Aug 2011 11:17:07 +0000 (13:17 +0200)
Adding tests for QFutureSynchronizer and QtConcurrentResultStore

Added minor things in QFutureSynchronizer and QtConcurrentResultStore and removed tests for destruction

Task-number: QTBUG-21066

Change-Id: I9f088b89463340f339c914bcb37fb2f9d3b62057
Reviewed-on: http://codereview.qt.nokia.com/3477
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Rohan McGovern <rohan.mcgovern@nokia.com>
Reviewed-by: Jason McDonald <jason.mcdonald@nokia.com>
33 files changed:
tests/auto/corelib.pro
tests/auto/corelib/concurrent/concurrent.pro [new file with mode: 0644]
tests/auto/corelib/concurrent/qfuture/.gitignore [moved from tests/auto/qfuture/.gitignore with 100% similarity]
tests/auto/corelib/concurrent/qfuture/qfuture.pro [moved from tests/auto/qfuture/qfuture.pro with 100% similarity]
tests/auto/corelib/concurrent/qfuture/tst_qfuture.cpp [moved from tests/auto/qfuture/tst_qfuture.cpp with 100% similarity]
tests/auto/corelib/concurrent/qfuture/versioncheck.h [moved from tests/auto/qfuture/versioncheck.h with 100% similarity]
tests/auto/corelib/concurrent/qfuturesynchronizer/qfuturesynchronizer.pro [new file with mode: 0644]
tests/auto/corelib/concurrent/qfuturesynchronizer/tst_qfuturesynchronizer.cpp [new file with mode: 0644]
tests/auto/corelib/concurrent/qfuturewatcher/.gitignore [moved from tests/auto/qfuturewatcher/.gitignore with 100% similarity]
tests/auto/corelib/concurrent/qfuturewatcher/qfuturewatcher.pro [moved from tests/auto/qfuturewatcher/qfuturewatcher.pro with 100% similarity]
tests/auto/corelib/concurrent/qfuturewatcher/tst_qfuturewatcher.cpp [moved from tests/auto/qfuturewatcher/tst_qfuturewatcher.cpp with 99% similarity]
tests/auto/corelib/concurrent/qtconcurrentfilter/.gitignore [moved from tests/auto/qtconcurrentfilter/.gitignore with 100% similarity]
tests/auto/corelib/concurrent/qtconcurrentfilter/qtconcurrentfilter.pro [moved from tests/auto/qtconcurrentfilter/qtconcurrentfilter.pro with 100% similarity]
tests/auto/corelib/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp [moved from tests/auto/qtconcurrentfilter/tst_qtconcurrentfilter.cpp with 100% similarity]
tests/auto/corelib/concurrent/qtconcurrentiteratekernel/.gitignore [moved from tests/auto/qtconcurrentiteratekernel/.gitignore with 100% similarity]
tests/auto/corelib/concurrent/qtconcurrentiteratekernel/qtconcurrentiteratekernel.pro [moved from tests/auto/qtconcurrentiteratekernel/qtconcurrentiteratekernel.pro with 100% similarity]
tests/auto/corelib/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp [moved from tests/auto/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp with 100% similarity]
tests/auto/corelib/concurrent/qtconcurrentmap/.gitignore [moved from tests/auto/qtconcurrentmap/.gitignore with 100% similarity]
tests/auto/corelib/concurrent/qtconcurrentmap/functions.h [moved from tests/auto/qtconcurrentmap/functions.h with 100% similarity]
tests/auto/corelib/concurrent/qtconcurrentmap/qtconcurrentmap.pro [moved from tests/auto/qtconcurrentmap/qtconcurrentmap.pro with 100% similarity]
tests/auto/corelib/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp [moved from tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp with 100% similarity]
tests/auto/corelib/concurrent/qtconcurrentresultstore/qtconcurrentresultstore.pro [new file with mode: 0644]
tests/auto/corelib/concurrent/qtconcurrentresultstore/tst_qtconcurrentresultstore.cpp [new file with mode: 0644]
tests/auto/corelib/concurrent/qtconcurrentrun/.gitignore [moved from tests/auto/qtconcurrentrun/.gitignore with 100% similarity]
tests/auto/corelib/concurrent/qtconcurrentrun/qtconcurrentrun.pro [moved from tests/auto/qtconcurrentrun/qtconcurrentrun.pro with 100% similarity]
tests/auto/corelib/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp [moved from tests/auto/qtconcurrentrun/tst_qtconcurrentrun.cpp with 100% similarity]
tests/auto/corelib/concurrent/qtconcurrentthreadengine/.gitignore [moved from tests/auto/qtconcurrentthreadengine/.gitignore with 100% similarity]
tests/auto/corelib/concurrent/qtconcurrentthreadengine/qtconcurrentthreadengine.pro [moved from tests/auto/qtconcurrentthreadengine/qtconcurrentthreadengine.pro with 100% similarity]
tests/auto/corelib/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp [moved from tests/auto/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp with 100% similarity]
tests/auto/corelib/concurrent/qthreadpool/.gitignore [moved from tests/auto/qthreadpool/.gitignore with 100% similarity]
tests/auto/corelib/concurrent/qthreadpool/qthreadpool.pro [moved from tests/auto/qthreadpool/qthreadpool.pro with 100% similarity]
tests/auto/corelib/concurrent/qthreadpool/tst_qthreadpool.cpp [moved from tests/auto/qthreadpool/tst_qthreadpool.cpp with 100% similarity]
tests/auto/corelib/corelib.pro

index f9434d5..927d439 100644 (file)
@@ -27,8 +27,6 @@ SUBDIRS=\
    qfilesystemwatcher \
    qflags \
    qfreelist \
-   qfuture \
-   qfuturewatcher \
    qgetputenv \
    qglobal \
    qhash \
@@ -73,16 +71,10 @@ SUBDIRS=\
    qstringlist \
    qstringmatcher \
    qstringref \
-   qtconcurrentfilter \
-   qtconcurrentiteratekernel \
-   qtconcurrentmap \
-   qtconcurrentrun \
-   qtconcurrentthreadengine \
    qtemporaryfile \
    qtextboundaryfinder \
    qthread \
    qthreadonce \
-   qthreadpool \
    qthreadstorage \
    qtime \
    qtimeline \
@@ -101,13 +93,6 @@ SUBDIRS=\
    qfilesystementry \
    qabstractfileengine
 
-symbian:SUBDIRS -= \
-   qtconcurrentfilter \
-   qtconcurrentiteratekernel \
-   qtconcurrentmap \
-   qtconcurrentrun \
-   qtconcurrentthreadengine \
-
 !contains(QT_CONFIG, private_tests): SUBDIRS -= \
     qfileinfo \
 
diff --git a/tests/auto/corelib/concurrent/concurrent.pro b/tests/auto/corelib/concurrent/concurrent.pro
new file mode 100644 (file)
index 0000000..6d7850b
--- /dev/null
@@ -0,0 +1,19 @@
+TEMPLATE=subdirs
+SUBDIRS=\
+   qfuture \
+   qfuturesynchronizer \
+   qfuturewatcher \
+   qtconcurrentfilter \
+   qtconcurrentiteratekernel \
+   qtconcurrentmap \
+   qtconcurrentresultstore \
+   qtconcurrentrun \
+   qtconcurrentthreadengine \
+   qthreadpool
+
+symbian:SUBDIRS -= \
+   qtconcurrentfilter \
+   qtconcurrentiteratekernel \
+   qtconcurrentmap \
+   qtconcurrentrun \
+   qtconcurrentthreadengine \
diff --git a/tests/auto/corelib/concurrent/qfuturesynchronizer/qfuturesynchronizer.pro b/tests/auto/corelib/concurrent/qfuturesynchronizer/qfuturesynchronizer.pro
new file mode 100644 (file)
index 0000000..11012cc
--- /dev/null
@@ -0,0 +1,5 @@
+load(qttest_p4)
+QT = core
+SOURCES  += tst_qfuturesynchronizer.cpp \
+
+CONFIG += parallel_test
diff --git a/tests/auto/corelib/concurrent/qfuturesynchronizer/tst_qfuturesynchronizer.cpp b/tests/auto/corelib/concurrent/qfuturesynchronizer/tst_qfuturesynchronizer.cpp
new file mode 100644 (file)
index 0000000..5aced3f
--- /dev/null
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest>
+
+#include <QtCore/qfuturesynchronizer.h>
+#include <QtCore/qfuture.h>
+
+class tst_QFutureSynchronizer : public QObject
+{
+    Q_OBJECT
+
+
+private Q_SLOTS:
+    void construction();
+    void addFuture();
+    void cancelOnWait();
+    void clearFutures();
+    void futures();
+    void setFuture();
+    void waitForFinished();
+};
+
+
+void tst_QFutureSynchronizer::construction()
+{
+
+    QFuture<void> future;
+    QFutureSynchronizer<void> synchronizer;
+    QFutureSynchronizer<void> synchronizerWithFuture(future);
+
+    QCOMPARE(synchronizer.futures().size(), 0);
+    QCOMPARE(synchronizerWithFuture.futures().size(), 1);
+}
+
+void tst_QFutureSynchronizer::addFuture()
+{
+    QFutureSynchronizer<void> synchronizer;
+
+    synchronizer.addFuture(QFuture<void>());
+    QFuture<void> future;
+    synchronizer.addFuture(future);
+    synchronizer.addFuture(future);
+
+    QCOMPARE(synchronizer.futures().size(), 3);
+}
+
+void tst_QFutureSynchronizer::cancelOnWait()
+{
+    QFutureSynchronizer<void> synchronizer;
+    QVERIFY(!synchronizer.cancelOnWait());
+    synchronizer.setCancelOnWait(true);
+    QVERIFY(synchronizer.cancelOnWait());
+    synchronizer.setCancelOnWait(false);
+    QVERIFY(!synchronizer.cancelOnWait());
+    synchronizer.setCancelOnWait(true);
+    QVERIFY(synchronizer.cancelOnWait());
+}
+
+void tst_QFutureSynchronizer::clearFutures()
+{
+    QFutureSynchronizer<void> synchronizer;
+    synchronizer.clearFutures();
+    QVERIFY(synchronizer.futures().isEmpty());
+
+    synchronizer.addFuture(QFuture<void>());
+    QFuture<void> future;
+    synchronizer.addFuture(future);
+    synchronizer.addFuture(future);
+    synchronizer.clearFutures();
+    QVERIFY(synchronizer.futures().isEmpty());
+}
+
+void tst_QFutureSynchronizer::futures()
+{
+    QFutureSynchronizer<void> synchronizer;
+
+    QList<QFuture<void> > futures;
+    for (int i=0; i<100; i++) {
+        QFuture<void> future;
+        futures.append(future);
+        synchronizer.addFuture(future);
+    }
+
+    QCOMPARE(futures, synchronizer.futures());
+}
+
+void tst_QFutureSynchronizer::setFuture()
+{
+    QFutureSynchronizer<void> synchronizer;
+
+    for (int i=0; i<100; i++) {
+        synchronizer.addFuture(QFuture<void>());
+    }
+    QCOMPARE(synchronizer.futures().size(), 100);
+
+    QFuture<void> future;
+    synchronizer.setFuture(future);
+    QCOMPARE(synchronizer.futures().size(), 1);
+    QCOMPARE(synchronizer.futures().first(), future);
+}
+
+void tst_QFutureSynchronizer::waitForFinished()
+{
+    QFutureSynchronizer<void> synchronizer;
+
+    for (int i=0; i<100; i++) {
+        synchronizer.addFuture(QFuture<void>());
+    }
+    synchronizer.waitForFinished();
+    const QList<QFuture<void> > futures = synchronizer.futures();
+
+    for (int i=0; i<100; i++) {
+        QVERIFY(futures.at(i).isFinished());
+    }
+}
+
+QTEST_MAIN(tst_QFutureSynchronizer)
+
+#include "tst_qfuturesynchronizer.moc"
@@ -47,7 +47,7 @@
 #include <qfuturewatcher.h>
 #include <qtconcurrentrun.h>
 #include <qtconcurrentmap.h>
-#include "../../shared/util.h"
+#include "../../../../shared/util.h"
 
 #ifndef QT_NO_CONCURRENT_TEST
 #include <private/qfutureinterface_p.h>
diff --git a/tests/auto/corelib/concurrent/qtconcurrentresultstore/qtconcurrentresultstore.pro b/tests/auto/corelib/concurrent/qtconcurrentresultstore/qtconcurrentresultstore.pro
new file mode 100644 (file)
index 0000000..8bc20c3
--- /dev/null
@@ -0,0 +1,5 @@
+load(qttest_p4)
+DEFINES += QT_STRICT_ITERATORS
+SOURCES += tst_qtconcurrentresultstore.cpp
+QT = core core-private
+CONFIG += parallel_test
diff --git a/tests/auto/corelib/concurrent/qtconcurrentresultstore/tst_qtconcurrentresultstore.cpp b/tests/auto/corelib/concurrent/qtconcurrentresultstore/tst_qtconcurrentresultstore.cpp
new file mode 100644 (file)
index 0000000..1728be6
--- /dev/null
@@ -0,0 +1,491 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+
+#include <qtconcurrentresultstore.h>
+
+using namespace QtConcurrent;
+
+class tst_QtConcurrentResultStore : public QObject
+{
+    Q_OBJECT
+public slots:
+    void init();
+private slots:
+    void construction();
+    void iterators();
+    void addResult();
+    void addResults();
+    void resultIndex();
+    void resultAt();
+    void contains();
+    void filterMode();
+    void addCanceledResult();
+    void count();
+private:
+    int int0;
+    int int1;
+    int int2;
+    QVector<int> vec0;
+    QVector<int> vec1;
+};
+
+void tst_QtConcurrentResultStore::init()
+{
+    int0 = 0;
+    int1 = 1;
+    int2 = 2;
+    vec0 = QVector<int>() << 2 << 3;
+    vec1 = QVector<int>() << 4 << 5;
+}
+
+void tst_QtConcurrentResultStore::construction()
+{
+    ResultStore<int> store;
+    QCOMPARE(store.count(), 0);
+}
+
+void tst_QtConcurrentResultStore::iterators()
+{
+    {
+        ResultStore<int> store;
+        ResultIteratorBase it = store.begin();
+        QVERIFY(store.begin() == store.end());
+        QVERIFY(store.resultAt(0) == store.end());
+        QVERIFY(store.resultAt(1) == store.end());
+    }
+    {
+        ResultStoreBase storebase;
+        storebase.addResult(-1, &int0); // note to self: adding a pointer to the stack here is ok since
+        storebase.addResult(1, &int1);  // ResultStoreBase does not take ownership, only ResultStore<> does.
+        ResultIteratorBase it = storebase.begin();
+        QCOMPARE(it.resultIndex(), 0);
+        QVERIFY(it == storebase.begin());
+        QVERIFY(it != storebase.end());
+
+        ++it;
+        QCOMPARE(it.resultIndex(), 1);
+        QVERIFY(it != storebase.begin());
+        QVERIFY(it != storebase.end());
+
+        ++it;
+        QVERIFY(it != storebase.begin());
+        QVERIFY(it == storebase.end());
+    }
+}
+
+void tst_QtConcurrentResultStore::addResult()
+{
+    {
+        // test addResult return value
+        ResultStore<int> store;
+        store.setFilterMode(true);
+
+        QCOMPARE(store.addResult(0, &int0), 0);
+        QCOMPARE(store.count(), 1); // result 0 becomes available
+        QCOMPARE(store.contains(0), true);
+
+        QCOMPARE(store.addResult(2, &int0), 2);
+        QCOMPARE(store.count(), 1);
+        QCOMPARE(store.contains(2), false);
+
+        QCOMPARE(store.addCanceledResult(1), 1);
+        QCOMPARE(store.count(), 2); // result 2 is renamed to 1 and becomes available
+
+        QCOMPARE(store.contains(0), true);
+        QCOMPARE(store.contains(1), true);
+        QCOMPARE(store.contains(2), false);
+
+        QCOMPARE(store.addResult(3, &int0), 3);
+        QCOMPARE(store.count(), 3);
+        QCOMPARE(store.contains(2), true);
+
+        QCOMPARE(store.addResult(6, &int0), 6);
+        QCOMPARE(store.count(), 3);
+        QCOMPARE(store.addResult(7, &int0), 7);
+        QCOMPARE(store.count(), 3);
+        QCOMPARE(store.contains(3), false);
+
+        QCOMPARE(store.addCanceledResult(4), 4);
+        QCOMPARE(store.addCanceledResult(5), 5);
+        QCOMPARE(store.count(), 5); // 6 and 7 is renamed to 3 and 4 and becomes available
+
+        QCOMPARE(store.contains(3), true);
+        QCOMPARE(store.contains(4), true);
+
+        QCOMPARE(store.addResult(8, &int0), 8);
+        QCOMPARE(store.contains(5), true);
+        QCOMPARE(store.count(), 6);
+
+        QCOMPARE(store.contains(6), false);
+        QCOMPARE(store.contains(7), false);
+    }
+}
+
+void tst_QtConcurrentResultStore::addResults()
+{
+
+    ResultStoreBase store;
+    store.addResults(-1, &vec0, 2, 2);
+    store.addResults(-1, &vec1, 2, 2);
+    ResultIteratorBase it = store.begin();
+    QCOMPARE(it.resultIndex(), 0);
+    QVERIFY(it == store.begin());
+    QVERIFY(it != store.end());
+
+    ++it;
+    QCOMPARE(it.resultIndex(), 1);
+    QVERIFY(it != store.begin());
+    QVERIFY(it != store.end());
+
+    ++it;
+    QCOMPARE(it.resultIndex(), 2);
+
+    ++it;
+    QCOMPARE(it.resultIndex(), 3);
+
+    ++it;
+    QVERIFY(it == store.end());
+}
+
+void tst_QtConcurrentResultStore::resultIndex()
+{
+    ResultStore<int> store;
+    store.addResult(-1, &int0);
+    store.addResults(-1, &vec0);
+    store.addResult(-1, &int1);
+
+    ResultIteratorBase it = store.begin();
+    QCOMPARE(it.resultIndex(), 0);
+    QVERIFY(it == store.begin());
+    QVERIFY(it != store.end());
+
+    ++it;
+    QCOMPARE(it.resultIndex(), 1);
+    QVERIFY(it != store.begin());
+    QVERIFY(it != store.end());
+
+    ++it;
+    QCOMPARE(it.resultIndex(), 2);
+    QVERIFY(it != store.end());
+    ++it;
+    QCOMPARE(it.resultIndex(), 3);
+    QVERIFY(it != store.end());
+    ++it;
+    QVERIFY(it == store.end());
+
+    QCOMPARE(store.resultAt(0).value(), int0);
+    QCOMPARE(store.resultAt(1).value(), vec0[0]);
+    QCOMPARE(store.resultAt(2).value(), vec0[1]);
+    QCOMPARE(store.resultAt(3).value(), int1);
+}
+
+void tst_QtConcurrentResultStore::resultAt()
+{
+    {
+        ResultStore<int> store;
+        store.addResult(-1, &int0);
+        store.addResults(-1, &vec0);
+        store.addResult(200, &int1);
+
+        QCOMPARE(store.resultAt(0).value(), int0);
+        QCOMPARE(store.resultAt(1).value(), vec0[0]);
+        QCOMPARE(store.resultAt(2).value(), vec0[1]);
+        QCOMPARE(store.resultAt(200).value(), int1);
+    }
+    {
+        ResultStore<int> store;
+        store.addResult(1, &int1);
+        store.addResult(0, &int0);
+        store.addResult(-1, &int2);
+
+        QCOMPARE(store.resultAt(0).value(), int0);
+        QCOMPARE(store.resultAt(1).value(), int1);
+        QCOMPARE(store.resultAt(2).value(), int2);
+    }
+}
+
+void tst_QtConcurrentResultStore::contains()
+{
+    {
+        ResultStore<int> store;
+        QCOMPARE(store.contains(0), false);
+        QCOMPARE(store.contains(1), false);
+        QCOMPARE(store.contains(INT_MAX), false);
+        store.addResult(1, &int1);
+        QVERIFY(store.contains(int1));
+        store.addResult(0, &int0);
+        QVERIFY(store.contains(int0));
+        store.addResult(-1, &int2);
+        QVERIFY(store.contains(int2));
+    }
+    {
+        ResultStore<int> store;
+        store.addResult(1, &int0);
+        store.addResult(3, &int0);
+        store.addResults(6, &vec0);
+        QCOMPARE(store.contains(0), false);
+        QCOMPARE(store.contains(1), true);
+        QCOMPARE(store.contains(2), false);
+        QCOMPARE(store.contains(3), true);
+        QCOMPARE(store.contains(4), false);
+        QCOMPARE(store.contains(5), false);
+        QCOMPARE(store.contains(6), true);
+        QCOMPARE(store.contains(7), true);
+    }
+
+    {
+        ResultStore<int> store;
+        store.setFilterMode(true);
+        store.addResult(1, &int0);
+        store.addResult(3, &int0);
+        store.addResults(6, &vec0);
+        QCOMPARE(store.contains(0), false);
+        QCOMPARE(store.contains(1), false);
+        QCOMPARE(store.contains(2), false);
+        QCOMPARE(store.contains(3), false);
+        QCOMPARE(store.contains(4), false);
+        QCOMPARE(store.contains(5), false);
+        QCOMPARE(store.contains(6), false);
+        QCOMPARE(store.contains(7), false);
+
+        store.addCanceledResult(0);
+        store.addCanceledResult(2);
+        store.addCanceledResults(4, 2);
+
+        QCOMPARE(store.contains(0), true);
+        QCOMPARE(store.contains(1), true);
+        QCOMPARE(store.contains(2), true);
+        QCOMPARE(store.contains(3), true);
+        QCOMPARE(store.contains(4), false);
+        QCOMPARE(store.contains(5), false);
+        QCOMPARE(store.contains(6), false);
+        QCOMPARE(store.contains(7), false);
+    }
+    {
+        ResultStore<int> store;
+        store.setFilterMode(true);
+        store.addCanceledResult(0);
+        QCOMPARE(store.contains(0), false);
+
+        store.addResult(1, &int0);
+        QCOMPARE(store.contains(0), true);
+        QCOMPARE(store.contains(1), false);
+    }
+}
+
+void tst_QtConcurrentResultStore::filterMode()
+{
+    // Test filter mode, where "gaps" in the result array aren't allowed.
+    ResultStore<int> store;
+    QCOMPARE(store.filterMode(), false);
+    store.setFilterMode(true);
+    QVERIFY(store.filterMode());
+
+    store.addResult(0, &int0);
+    QCOMPARE(store.contains(0), true);
+
+    store.addResult(2, &int2); // add result at index 2
+    QCOMPARE(store.contains(2), false); // but 1 is missing, so this 2 won't be reported yet.
+
+    store.addResult(1, &int1);
+    QCOMPARE(store.contains(1), true);
+    QCOMPARE(store.contains(2), true); // 2 should be visible now.
+
+    store.addResult(4, &int0);
+    store.addResult(5, &int0);
+    store.addResult(7, &int0);
+    QCOMPARE(store.contains(4), false);
+    QCOMPARE(store.contains(5), false);
+    QCOMPARE(store.contains(7), false);
+
+    store.addResult(3, &int0);  // adding 3 makes 4 and 5 visible
+    QCOMPARE(store.contains(4), true);
+    QCOMPARE(store.contains(5), true);
+    QCOMPARE(store.contains(7), false);
+
+    store.addResult(6, &int0);  // adding 6 makes 7 visible
+
+    QCOMPARE(store.contains(6), true);
+    QCOMPARE(store.contains(7), true);
+    QCOMPARE(store.contains(8), false);
+}
+
+void tst_QtConcurrentResultStore::addCanceledResult()
+{
+    // test canceled results
+    ResultStore<int> store;
+    store.setFilterMode(true);
+
+    store.addResult(0, &int0);
+    QCOMPARE(store.contains(0), true);
+
+    store.addResult(2, &int0);
+    QCOMPARE(store.contains(2), false);
+
+    store.addCanceledResult(1); // report no result at 1
+
+    QCOMPARE(store.contains(0), true);
+    QCOMPARE(store.contains(1), true); // 2 gets renamed to 1
+    QCOMPARE(store.contains(2), false);
+
+    store.addResult(3, &int0);
+    QCOMPARE(store.contains(2), true); //3 gets renamed to 2
+
+    store.addResult(6, &int0);
+    store.addResult(7, &int0);
+    QCOMPARE(store.contains(3), false);
+
+    store.addCanceledResult(4);
+    store.addCanceledResult(5);
+
+    QCOMPARE(store.contains(3), true); //6 gets renamed to 3
+    QCOMPARE(store.contains(4), true); //7 gets renamed to 4
+
+    store.addResult(8, &int0);
+    QCOMPARE(store.contains(5), true); //8 gets renamed to 4
+
+    QCOMPARE(store.contains(6), false);
+    QCOMPARE(store.contains(7), false);
+}
+
+void tst_QtConcurrentResultStore::count()
+{
+    {
+        // test resultCount in non-filtered mode. It should always be possible
+        // to iterate through the results 0 to resultCount.
+        ResultStore<int> store;
+        store.addResult(0, &int0);
+
+        QCOMPARE(store.count(), 1);
+
+        store.addResult(2, &int0);
+
+        QCOMPARE(store.count(), 1);
+
+        store.addResult(1, &int0);
+        QCOMPARE(store.count(), 3);
+    }
+
+    {
+        ResultStore<int> store;
+        store.addResult(2, &int0);
+        QCOMPARE(store.count(), 0);
+
+        store.addResult(1, &int0);
+        QCOMPARE(store.count(), 0);
+
+        store.addResult(0, &int0);
+        QCOMPARE(store.count(), 3);
+    }
+
+    {
+        ResultStore<int> store;
+        store.addResults(2, &vec1);
+        QCOMPARE(store.count(), 0);
+
+        store.addResult(1, &int0);
+        QCOMPARE(store.count(), 0);
+
+        store.addResult(0, &int0);
+        QCOMPARE(store.count(), 4);
+    }
+
+    {
+        ResultStore<int> store;
+        store.addResults(2, &vec1);
+        QCOMPARE(store.count(), 0);
+
+        store.addResults(0, &vec0);
+        QCOMPARE(store.count(), 4);
+    }
+    {
+        ResultStore<int> store;
+        store.addResults(3, &vec1);
+        QCOMPARE(store.count(), 0);
+
+        store.addResults(0, &vec0);
+        QCOMPARE(store.count(), 2);
+
+        store.addResult(2, &int0);
+        QCOMPARE(store.count(), 5);
+    }
+
+    {
+        ResultStore<int> store;
+        store.setFilterMode(true);
+        store.addResults(3, &vec1);
+        QCOMPARE(store.count(), 0);
+
+        store.addResults(0, &vec0);
+        QCOMPARE(store.count(), 2);
+
+        store.addCanceledResult(2);
+        QCOMPARE(store.count(), 4);
+    }
+
+    {
+        ResultStore<int> store;
+        store.setFilterMode(true);
+        store.addResults(3, &vec1);
+        QCOMPARE(store.count(), 0);
+
+        store.addCanceledResults(0, 3);
+        QCOMPARE(store.count(), 2);
+    }
+
+    {
+        ResultStore<int> store;
+        store.setFilterMode(true);
+        store.addResults(3, &vec1);
+        QCOMPARE(store.count(), 0);
+
+        store.addCanceledResults(0, 3);
+        QCOMPARE(store.count(), 2);  // results at 3 and 4 become available at index 0, 1
+
+        store.addResult(5, &int0);
+        QCOMPARE(store.count(), 3);// result 5 becomes available at index 2
+    }
+}
+
+QTEST_MAIN(tst_QtConcurrentResultStore)
+#include "tst_qtconcurrentresultstore.moc"
index 4c84fbb..122c834 100644 (file)
@@ -1,4 +1,5 @@
 TEMPLATE=subdirs
 SUBDIRS=\
    animation \
-   codecs
+   codecs \
+   concurrent