Move helpers in separate file and add unit tests

Gather helpers in `promisehelpers.h` and add a global include file to make easier integration with the lib (`#include <QtPromise>`).
This commit is contained in:
Simon Brunel 2017-05-25 09:19:36 +02:00
parent ce3ed72dd4
commit 596855f579
14 changed files with 315 additions and 43 deletions

8
include/QtPromise Normal file
View File

@ -0,0 +1,8 @@
#ifndef _QTPROMISE_MODULE_H
#define _QTPROMISE_MODULE_H
#include "../src/qtpromise/qpromise.h"
#include "../src/qtpromise/qpromisefuture.h"
#include "../src/qtpromise/qpromisehelpers.h"
#endif // ifndef _QTPROMISE_MODULE_H

View File

@ -1,2 +1,2 @@
INCLUDEPATH += $$PWD/src
DEPENDPATH += $$PWD/src
INCLUDEPATH += $$PWD/include $$PWD/src
DEPENDPATH += $$PWD/include $$PWD/src

View File

@ -1,10 +1,12 @@
TEMPLATE = subdirs
SUBDIRS = \
src \
tests
tests.depends = src
_qt_creator_ {
SUBDIRS += src
}
OTHER_FILES = \
package/features/*.prf \
include/* \
qtpromise.pri

View File

@ -104,6 +104,5 @@ private:
} // namespace QtPromise
#include "qpromise.inl"
#include "qpromise_qfuture.inl"
#endif // ifndef _QTPROMISE_QPROMISE_H

View File

@ -311,37 +311,4 @@ inline void QPromise<void>::notify(const typename QtPromisePrivate::PromiseData<
});
}
// Helpers
template <typename T>
typename QtPromisePrivate::PromiseDeduce<T>::Type qPromise(const T& value)
{
using namespace QtPromisePrivate;
using Promise = typename PromiseDeduce<T>::Type;
return Promise([=](
const QPromiseResolve<typename Promise::Type>& resolve,
const QPromiseReject<typename Promise::Type>& reject) {
PromiseFulfill<T>::call(value, resolve, reject);
});
}
QPromise<void> qPromise()
{
return QPromise<void>([](
const QPromiseResolve<void>& resolve) {
resolve();
});
}
template <typename T>
QPromise<QVector<T> > qPromiseAll(const QVector<QPromise<T> >& promises)
{
return QPromise<T>::all(promises);
}
QPromise<void> qPromiseAll(const QVector<QPromise<void> >& promises)
{
return QPromise<void>::all(promises);
}
} // namespace QtPromise

View File

@ -6,7 +6,6 @@
#include "qpromiseglobal.h"
// Qt
#include <QCoreApplication>
#include <QTimer>
#include <QSharedData>
#include <QVector>

View File

@ -1,3 +1,6 @@
#ifndef _QTPROMISE_QPROMISEFUTURE_P_H
#define _QTPROMISE_QPROMISEFUTURE_P_H
#include <QFutureWatcher>
#include <QFuture>
@ -62,3 +65,5 @@ struct PromiseFulfill<QFuture<void> >
};
} // namespace QtPromise
#endif // _QTPROMISE_QPROMISEFUTURE_P_H

View File

@ -0,0 +1,42 @@
#ifndef _QTPROMISE_QPROMISEHELPERS_H
#define _QTPROMISE_QPROMISEHELPERS_H
// QtPromise
#include "qpromise_p.h"
namespace QtPromise {
template <typename T>
typename QtPromisePrivate::PromiseDeduce<T>::Type qPromise(const T& value)
{
using namespace QtPromisePrivate;
using Promise = typename PromiseDeduce<T>::Type;
return Promise([=](
const QPromiseResolve<typename Promise::Type>& resolve,
const QPromiseReject<typename Promise::Type>& reject) {
PromiseFulfill<T>::call(value, resolve, reject);
});
}
QPromise<void> qPromise()
{
return QPromise<void>([](
const QPromiseResolve<void>& resolve) {
resolve();
});
}
template <typename T>
QPromise<QVector<T> > qPromiseAll(const QVector<QPromise<T> >& promises)
{
return QPromise<T>::all(promises);
}
QPromise<void> qPromiseAll(const QVector<QPromise<void> >& promises)
{
return QPromise<void>::all(promises);
}
} // namespace QtPromise
#endif // _QTPROMISE_QPROMISEHELPERS_H

View File

@ -2,6 +2,7 @@ HEADERS += \
$$PWD/qpromise.h \
$$PWD/qpromise.inl \
$$PWD/qpromise_p.h \
$$PWD/qpromise_qfuture.inl \
$$PWD/qpromiseerror.h \
$$PWD/qpromiseglobal.h
$$PWD/qpromisefuture.h \
$$PWD/qpromiseglobal.h \
$$PWD/qpromisehelpers.h

View File

@ -1,4 +1,5 @@
TEMPLATE = subdirs
SUBDIRS += \
helpers \
qpromise \
requirements

View File

@ -0,0 +1,4 @@
TARGET = tst_helpers
SOURCES += $$PWD/tst_helpers.cpp
include(../tests.pri)

View File

@ -0,0 +1,244 @@
// QtPromise
#include <QtPromise>
// Qt
#include <QtTest>
using namespace QtPromise;
class tst_helpers: public QObject
{
Q_OBJECT
private Q_SLOTS:
void resolve();
void resolve_void();
void resolve_promise();
void resolve_promise_void();
void allFulfilled();
void allFulfilled_void();
void allRejected();
void allRejected_void();
void allEmpty();
void allEmpty_void();
}; // class tst_helpers
QTEST_MAIN(tst_helpers)
#include "tst_helpers.moc"
void tst_helpers::resolve()
{
int value = -1;
auto p = QtPromise::qPromise(42);
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<int> >::value));
QCOMPARE(p.isFulfilled(), true);
p.then([&](int res) {
value = res;
}).wait();
QCOMPARE(value, 42);
}
void tst_helpers::resolve_void()
{
int value = -1;
auto p = QtPromise::qPromise();
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<void> >::value));
QCOMPARE(p.isFulfilled(), true);
p.then([&]() {
value = 42;
}).wait();
QCOMPARE(value, 42);
}
void tst_helpers::resolve_promise()
{
QString value;
auto p = QtPromise::qPromise(
QPromise<QString>([](const QPromiseResolve<QString>& resolve) {
QtPromisePrivate::qtpromise_defer([=](){
resolve("foo");
});
}));
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QString> >::value));
QCOMPARE(p.isPending(), true);
p.then([&](const QString& res) {
value = res;
}).wait();
QCOMPARE(p.isFulfilled(), true);
QCOMPARE(value, QString("foo"));
}
void tst_helpers::resolve_promise_void()
{
QList<int> values;
auto p = QtPromise::qPromise(
QPromise<void>([&](const QPromiseResolve<void>& resolve) {
QtPromisePrivate::qtpromise_defer([=, &values](){
values << 42;
resolve();
});
}));
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<void> >::value));
QCOMPARE(p.isPending(), true);
p.then([&]() {
values << 43;
}).wait();
QCOMPARE(p.isFulfilled(), true);
QCOMPARE(values, QList<int>({42, 43}));
}
void tst_helpers::allFulfilled()
{
auto p0 = QtPromise::qPromise(42);
auto p1 = QtPromise::qPromise(44);
auto p2 = QPromise<int>([](const QPromiseResolve<int>& resolve) {
QtPromisePrivate::qtpromise_defer([=](){
resolve(43);
});
});
auto p = qPromiseAll(QVector<QPromise<int> >{p0, p2, p1});
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<int> > >::value));
QCOMPARE(p.isPending(), true);
QCOMPARE(p0.isFulfilled(), true);
QCOMPARE(p1.isFulfilled(), true);
QCOMPARE(p2.isPending(), true);
QVector<int> values;
p.then([&](const QVector<int>& res) {
values = res;
}).wait();
QCOMPARE(p.isFulfilled(), true);
QCOMPARE(p2.isFulfilled(), true);
QCOMPARE(values, QVector<int>({42, 43, 44}));
}
void tst_helpers::allFulfilled_void()
{
auto p0 = QtPromise::qPromise();
auto p1 = QtPromise::qPromise();
auto p2 = QPromise<void>([](const QPromiseResolve<void>& resolve) {
QtPromisePrivate::qtpromise_defer([=](){
resolve();
});
});
auto p = qPromiseAll(QVector<QPromise<void> >{p0, p2, p1});
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<void> >::value));
QCOMPARE(p.isPending(), true);
QCOMPARE(p0.isFulfilled(), true);
QCOMPARE(p1.isFulfilled(), true);
QCOMPARE(p2.isPending(), true);
p.wait();
QCOMPARE(p.isFulfilled(), true);
QCOMPARE(p2.isFulfilled(), true);
}
void tst_helpers::allRejected()
{
auto p0 = QtPromise::qPromise(42);
auto p1 = QtPromise::qPromise(44);
auto p2 = QPromise<int>([](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
QtPromisePrivate::qtpromise_defer([=](){
reject(QString("foo"));
});
});
auto p = qPromiseAll(QVector<QPromise<int> >{p0, p2, p1});
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<int> > >::value));
QCOMPARE(p.isPending(), true);
QCOMPARE(p0.isFulfilled(), true);
QCOMPARE(p1.isFulfilled(), true);
QCOMPARE(p2.isPending(), true);
QString error;
p.fail([&](const QString& err) {
error = err;
return QVector<int>();
}).wait();
QCOMPARE(p.isRejected(), true);
QCOMPARE(p2.isRejected(), true);
QCOMPARE(error, QString("foo"));
}
void tst_helpers::allRejected_void()
{
auto p0 = QtPromise::qPromise();
auto p1 = QtPromise::qPromise();
auto p2 = QPromise<void>([](const QPromiseResolve<void>&, const QPromiseReject<void>& reject) {
QtPromisePrivate::qtpromise_defer([=](){
reject(QString("foo"));
});
});
auto p = qPromiseAll(QVector<QPromise<void> >{p0, p2, p1});
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<void> >::value));
QCOMPARE(p.isPending(), true);
QCOMPARE(p0.isFulfilled(), true);
QCOMPARE(p1.isFulfilled(), true);
QCOMPARE(p2.isPending(), true);
QString error;
p.fail([&](const QString& err) {
error = err;
}).wait();
QCOMPARE(p.isRejected(), true);
QCOMPARE(p2.isRejected(), true);
QCOMPARE(error, QString("foo"));
}
void tst_helpers::allEmpty()
{
auto p = qPromiseAll(QVector<QPromise<int> >());
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<int> > >::value));
QCOMPARE(p.isFulfilled(), true);
QVector<int> values;
p.then([&](const QVector<int>& res) {
values = res;
}).wait();
QCOMPARE(values, QVector<int>());
}
void tst_helpers::allEmpty_void()
{
auto p = qPromiseAll(QVector<QPromise<void> >());
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<void> >::value));
QCOMPARE(p.isFulfilled(), true);
}

View File

@ -1,5 +1,5 @@
// QtPromise
#include <qtpromise/qpromise.h>
#include <QtPromise>
// Qt
#include <QtTest>

View File

@ -1,5 +1,5 @@
// QtPromise
#include <qtpromise/qpromise.h>
#include <QtPromise>
// Qt
#include <QtTest>