Split QPromise tests per feature in separate .pro

This commit is contained in:
Simon Brunel 2017-09-18 23:33:44 +02:00
parent 36a0eed12a
commit d3b69f1248
20 changed files with 1031 additions and 780 deletions

View File

@ -1,7 +1,7 @@
<a href="https://promisesaplus.com/" title="Promises/A+ 1.1"><img src="http://promisesaplus.com/assets/logo-small.png" alt="Promises/A+" align="right"/></a> <a href="https://promisesaplus.com/" title="Promises/A+ 1.1"><img src="http://promisesaplus.com/assets/logo-small.png" alt="Promises/A+" align="right"/></a>
# QtPromise # QtPromise
[![qpm](https://img.shields.io/github/release/simonbrunel/qtpromise.svg?style=flat-square&label=qpm&colorB=4CAF50)](http://www.qpm.io/packages/com.github.simonbrunel.qtpromise/index.html) [![Travis](https://img.shields.io/travis/simonbrunel/qtpromise.svg?style=flat-square)](https://travis-ci.org/simonbrunel/qtpromise) [![coverage](https://img.shields.io/codecov/c/github/simonbrunel/qtpromise.svg?style=flat-square)](https://codecov.io/gh/simonbrunel/qtpromise) [![qpm](https://img.shields.io/github/release/simonbrunel/qtpromise.svg?style=flat-square&label=qpm&colorB=4CAF50)](http://www.qpm.io/packages/com.github.simonbrunel.qtpromise/index.html) [![Travis](https://img.shields.io/travis/simonbrunel/qtpromise/master.svg?style=flat-square)](https://travis-ci.org/simonbrunel/qtpromise) [![coverage](https://img.shields.io/codecov/c/github/simonbrunel/qtpromise.svg?style=flat-square)](https://codecov.io/gh/simonbrunel/qtpromise)
[Promises/A+](https://promisesaplus.com/) implementation for [Qt/C++](https://www.qt.io/). [Promises/A+](https://promisesaplus.com/) implementation for [Qt/C++](https://www.qt.io/).

View File

@ -0,0 +1,4 @@
TARGET = tst_qpromise_construct
SOURCES += $$PWD/tst_construct.cpp
include(../../qtpromise.pri)

View File

@ -0,0 +1,230 @@
// Tests
#include "../../shared/utils.h"
// QtPromise
#include <QtPromise>
// Qt
#include <QtTest>
using namespace QtPromise;
class tst_qpromise_construct : public QObject
{
Q_OBJECT
private Q_SLOTS:
void resolveSyncOneArg();
void resolveSyncOneArg_void();
void resolveSyncTwoArgs();
void resolveSyncTwoArgs_void();
void resolveAsyncOneArg();
void resolveAsyncOneArg_void();
void resolveAsyncTwoArgs();
void resolveAsyncTwoArgs_void();
void rejectThrowOneArg();
void rejectThrowOneArg_void();
void rejectThrowTwoArgs();
void rejectThrowTwoArgs_void();
void rejectSync();
void rejectSync_void();
void rejectAsync();
void rejectAsync_void();
};
QTEST_MAIN(tst_qpromise_construct)
#include "tst_construct.moc"
void tst_qpromise_construct::resolveSyncOneArg()
{
QPromise<int> p([](const QPromiseResolve<int>& resolve) {
resolve(42);
});
QCOMPARE(p.isFulfilled(), true);
QCOMPARE(waitForError(p, QString()), QString());
QCOMPARE(waitForValue(p, -1), 42);
}
void tst_qpromise_construct::resolveSyncOneArg_void()
{
QPromise<void> p([](const QPromiseResolve<void>& resolve) {
resolve();
});
QCOMPARE(p.isFulfilled(), true);
QCOMPARE(waitForError(p, QString()), QString());
QCOMPARE(waitForValue(p, -1, 42), 42);
}
void tst_qpromise_construct::resolveSyncTwoArgs()
{
QPromise<int> p([](const QPromiseResolve<int>& resolve, const QPromiseReject<int>&) {
resolve(42);
});
QCOMPARE(p.isFulfilled(), true);
QCOMPARE(waitForError(p, QString()), QString());
QCOMPARE(waitForValue(p, -1), 42);
}
void tst_qpromise_construct::resolveSyncTwoArgs_void()
{
QPromise<void> p([](const QPromiseResolve<void>& resolve, const QPromiseReject<void>&) {
resolve();
});
QCOMPARE(p.isFulfilled(), true);
QCOMPARE(waitForError(p, QString()), QString());
QCOMPARE(waitForValue(p, -1, 42), 42);
}
void tst_qpromise_construct::resolveAsyncOneArg()
{
QPromise<int> p([](const QPromiseResolve<int>& resolve) {
QtPromisePrivate::qtpromise_defer([=]() {
resolve(42);
});
});
QCOMPARE(p.isPending(), true);
QCOMPARE(waitForError(p, QString()), QString());
QCOMPARE(waitForValue(p, -1), 42);
QCOMPARE(p.isFulfilled(), true);
}
void tst_qpromise_construct::resolveAsyncOneArg_void()
{
QPromise<void> p([](const QPromiseResolve<void>& resolve) {
QtPromisePrivate::qtpromise_defer([=]() {
resolve();
});
});
QCOMPARE(p.isPending(), true);
QCOMPARE(waitForError(p, QString()), QString());
QCOMPARE(waitForValue(p, -1, 42), 42);
QCOMPARE(p.isFulfilled(), true);
}
void tst_qpromise_construct::resolveAsyncTwoArgs()
{
QPromise<int> p([](const QPromiseResolve<int>& resolve, const QPromiseReject<int>&) {
QtPromisePrivate::qtpromise_defer([=]() {
resolve(42);
});
});
QCOMPARE(p.isPending(), true);
QCOMPARE(waitForError(p, QString()), QString());
QCOMPARE(waitForValue(p, -1), 42);
QCOMPARE(p.isFulfilled(), true);
}
void tst_qpromise_construct::resolveAsyncTwoArgs_void()
{
QPromise<void> p([](const QPromiseResolve<void>& resolve, const QPromiseReject<void>&) {
QtPromisePrivate::qtpromise_defer([=]() {
resolve();
});
});
QCOMPARE(p.isPending(), true);
QCOMPARE(waitForError(p, QString()), QString());
QCOMPARE(waitForValue(p, -1, 42), 42);
QCOMPARE(p.isFulfilled(), true);
}
void tst_qpromise_construct::rejectSync()
{
QPromise<int> p([](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
reject(QString("foo"));
});
QCOMPARE(p.isRejected(), true);
QCOMPARE(waitForValue(p, -1), -1);
QCOMPARE(waitForError(p, QString()), QString("foo"));
}
void tst_qpromise_construct::rejectSync_void()
{
QPromise<void> p([](const QPromiseResolve<void>&, const QPromiseReject<void>& reject) {
reject(QString("foo"));
});
QCOMPARE(p.isRejected(), true);
QCOMPARE(waitForValue(p, -1, 42), -1);
QCOMPARE(waitForError(p, QString()), QString("foo"));
}
void tst_qpromise_construct::rejectAsync()
{
QPromise<int> p([](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
QtPromisePrivate::qtpromise_defer([=]() {
reject(QString("foo"));
});
});
QCOMPARE(p.isPending(), true);
QCOMPARE(waitForValue(p, -1), -1);
QCOMPARE(waitForError(p, QString()), QString("foo"));
QCOMPARE(p.isRejected(), true);
}
void tst_qpromise_construct::rejectAsync_void()
{
QPromise<void> p([](const QPromiseResolve<void>&, const QPromiseReject<void>& reject) {
QtPromisePrivate::qtpromise_defer([=]() {
reject(QString("foo"));
});
});
QCOMPARE(p.isPending(), true);
QCOMPARE(waitForValue(p, -1, 42), -1);
QCOMPARE(waitForError(p, QString()), QString("foo"));
QCOMPARE(p.isRejected(), true);
}
void tst_qpromise_construct::rejectThrowOneArg()
{
QPromise<int> p([](const QPromiseResolve<int>&) {
throw QString("foo");
});
QCOMPARE(p.isRejected(), true);
QCOMPARE(waitForValue(p, -1), -1);
QCOMPARE(waitForError(p, QString()), QString("foo"));
}
void tst_qpromise_construct::rejectThrowOneArg_void()
{
QPromise<void> p([](const QPromiseResolve<void>&) {
throw QString("foo");
});
QCOMPARE(p.isRejected(), true);
QCOMPARE(waitForValue(p, -1, 42), -1);
QCOMPARE(waitForError(p, QString()), QString("foo"));
}
void tst_qpromise_construct::rejectThrowTwoArgs()
{
QPromise<int> p([](const QPromiseResolve<int>&, const QPromiseReject<int>&) {
throw QString("foo");
});
QCOMPARE(p.isRejected(), true);
QCOMPARE(waitForValue(p, -1), -1);
QCOMPARE(waitForError(p, QString()), QString("foo"));
}
void tst_qpromise_construct::rejectThrowTwoArgs_void()
{
QPromise<void> p([](const QPromiseResolve<void>&, const QPromiseReject<void>&) {
throw QString("foo");
});
QCOMPARE(p.isRejected(), true);
QCOMPARE(waitForValue(p, -1, 42), -1);
QCOMPARE(waitForError(p, QString()), QString("foo"));
}

View File

@ -0,0 +1,4 @@
TARGET = tst_qpromise_delay
SOURCES += $$PWD/tst_delay.cpp
include(../../qtpromise.pri)

View File

@ -0,0 +1,55 @@
// Tests
#include "../../shared/utils.h"
// QtPromise
#include <QtPromise>
// Qt
#include <QtTest>
using namespace QtPromise;
class tst_qpromise_delay : public QObject
{
Q_OBJECT
private Q_SLOTS:
void fulfilled();
void rejected();
};
QTEST_MAIN(tst_qpromise_delay)
#include "tst_delay.moc"
void tst_qpromise_delay::fulfilled()
{
QElapsedTimer timer;
qint64 elapsed = -1;
timer.start();
auto p = QPromise<int>::resolve(42).delay(1000).finally([&]() {
elapsed = timer.elapsed();
});
QCOMPARE(waitForValue(p, -1), 42);
QCOMPARE(p.isFulfilled(), true);
QVERIFY(elapsed >= 1000 * 0.95); // Qt::CoarseTimer (default) Coarse timers try to
QVERIFY(elapsed <= 1000 * 1.05); // keep accuracy within 5% of the desired interval.
}
void tst_qpromise_delay::rejected()
{
QElapsedTimer timer;
qint64 elapsed = -1;
timer.start();
auto p = QPromise<int>::reject(QString("foo")).delay(1000).finally([&]() {
elapsed = timer.elapsed();
});
QCOMPARE(waitForError(p, QString()), QString("foo"));
QCOMPARE(p.isRejected(), true);
QVERIFY(elapsed < 5);
}

View File

@ -0,0 +1,4 @@
TARGET = tst_qpromise_fail
SOURCES += $$PWD/tst_fail.cpp
include(../../qtpromise.pri)

View File

@ -0,0 +1,83 @@
// Tests
#include "../../shared/utils.h"
// QtPromise
#include <QtPromise>
// Qt
#include <QtTest>
using namespace QtPromise;
class tst_qpromise_fail : public QObject
{
Q_OBJECT
private Q_SLOTS:
void sameType();
void baseClass();
void catchAll();
// TODO: sync / async
};
QTEST_MAIN(tst_qpromise_fail)
#include "tst_fail.moc"
void tst_qpromise_fail::sameType()
{
// http://en.cppreference.com/w/cpp/error/exception
auto p = QPromise<int>::reject(std::out_of_range("foo"));
QString error;
p.fail([&](const std::domain_error& e) {
error += QString(e.what()) + "0";
return -1;
}).fail([&](const std::out_of_range& e) {
error += QString(e.what()) + "1";
return -1;
}).fail([&](const std::exception& e) {
error += QString(e.what()) + "2";
return -1;
}).wait();
QCOMPARE(error, QString("foo1"));
}
void tst_qpromise_fail::baseClass()
{
// http://en.cppreference.com/w/cpp/error/exception
auto p = QPromise<int>::reject(std::out_of_range("foo"));
QString error;
p.fail([&](const std::runtime_error& e) {
error += QString(e.what()) + "0";
return -1;
}).fail([&](const std::logic_error& e) {
error += QString(e.what()) + "1";
return -1;
}).fail([&](const std::exception& e) {
error += QString(e.what()) + "2";
return -1;
}).wait();
QCOMPARE(error, QString("foo1"));
}
void tst_qpromise_fail::catchAll()
{
auto p = QPromise<int>::reject(std::out_of_range("foo"));
QString error;
p.fail([&](const std::runtime_error& e) {
error += QString(e.what()) + "0";
return -1;
}).fail([&]() {
error += "bar";
return -1;
}).fail([&](const std::exception& e) {
error += QString(e.what()) + "2";
return -1;
}).wait();
QCOMPARE(error, QString("bar"));
}

View File

@ -0,0 +1,4 @@
TARGET = tst_qpromise_finally
SOURCES += $$PWD/tst_finally.cpp
include(../../qtpromise.pri)

View File

@ -0,0 +1,204 @@
// Tests
#include "../../shared/utils.h"
// QtPromise
#include <QtPromise>
// Qt
#include <QtTest>
using namespace QtPromise;
class tst_qpromise_finally : public QObject
{
Q_OBJECT
private Q_SLOTS:
void fulfilledSync();
void fulfilledSync_void();
void fulfilledThrows();
void fulfilledThrows_void();
void fulfilledAsyncResolve();
void fulfilledAsyncReject();
void rejectedSync();
void rejectedSync_void();
void rejectedThrows();
void rejectedThrows_void();
void rejectedAsyncResolve();
void rejectedAsyncReject();
};
QTEST_MAIN(tst_qpromise_finally)
#include "tst_finally.moc"
void tst_qpromise_finally::fulfilledSync()
{
int value = -1;
auto p = QPromise<int>::resolve(42).finally([&]() {
value = 8;
return 16; // ignored!
});
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<int> >::value));
QCOMPARE(waitForValue(p, -1), 42);
QCOMPARE(p.isFulfilled(), true);
QCOMPARE(value, 8);
}
void tst_qpromise_finally::fulfilledSync_void()
{
int value = -1;
auto p = QPromise<void>::resolve().finally([&]() {
value = 8;
return 16; // ignored!
});
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<void> >::value));
QCOMPARE(waitForValue(p, -1, 42), 42);
QCOMPARE(p.isFulfilled(), true);
QCOMPARE(value, 8);
}
void tst_qpromise_finally::fulfilledThrows()
{
auto p = QPromise<int>::resolve(42).finally([&]() {
throw QString("bar");
});
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<int> >::value));
QCOMPARE(waitForError(p, QString()), QString("bar"));
QCOMPARE(p.isRejected(), true);
}
void tst_qpromise_finally::fulfilledThrows_void()
{
auto p = QPromise<void>::resolve().finally([&]() {
throw QString("bar");
});
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<void> >::value));
QCOMPARE(waitForError(p, QString()), QString("bar"));
QCOMPARE(p.isRejected(), true);
}
void tst_qpromise_finally::fulfilledAsyncResolve()
{
QVector<int> values;
auto p = QPromise<int>::resolve(42).finally([&]() {
QPromise<int> p([&](const QPromiseResolve<int>& resolve) {
QtPromisePrivate::qtpromise_defer([=, &values]() {
values << 64;
resolve(16); // ignored!
});
});
values << 8;
return p;
});
QCOMPARE(waitForValue(p, -1), 42);
QCOMPARE(p.isFulfilled(), true);
QCOMPARE(values, QVector<int>({8, 64}));
}
void tst_qpromise_finally::fulfilledAsyncReject()
{
auto p = QPromise<int>::resolve(42).finally([]() {
return QPromise<int>([](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
QtPromisePrivate::qtpromise_defer([=]() {
reject(QString("bar"));
});
});
});
QCOMPARE(waitForError(p, QString()), QString("bar"));
QCOMPARE(p.isRejected(), true);
}
void tst_qpromise_finally::rejectedSync()
{
int value = -1;
auto p = QPromise<int>::reject(QString("foo")).finally([&]() {
value = 8;
return 16; // ignored!
});
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<int> >::value));
QCOMPARE(waitForError(p, QString()), QString("foo"));
QCOMPARE(p.isRejected(), true);
QCOMPARE(value, 8);
}
void tst_qpromise_finally::rejectedSync_void()
{
int value = -1;
auto p = QPromise<void>::reject(QString("foo")).finally([&]() {
value = 8;
return 16; // ignored!
});
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<void> >::value));
QCOMPARE(waitForError(p, QString()), QString("foo"));
QCOMPARE(p.isRejected(), true);
QCOMPARE(value, 8);
}
void tst_qpromise_finally::rejectedThrows()
{
auto p = QPromise<int>::reject(QString("foo")).finally([&]() {
throw QString("bar");
});
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<int> >::value));
QCOMPARE(waitForError(p, QString()), QString("bar"));
QCOMPARE(p.isRejected(), true);
}
void tst_qpromise_finally::rejectedThrows_void()
{
auto p = QPromise<void>::reject(QString("foo")).finally([&]() {
throw QString("bar");
});
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<void> >::value));
QCOMPARE(waitForError(p, QString()), QString("bar"));
QCOMPARE(p.isRejected(), true);
}
void tst_qpromise_finally::rejectedAsyncResolve()
{
QVector<int> values;
auto p = QPromise<int>::reject(QString("foo")).finally([&]() {
QPromise<int> p([&](const QPromiseResolve<int>& resolve) {
QtPromisePrivate::qtpromise_defer([=, &values]() {
values << 64;
resolve(16); // ignored!
});
});
values << 8;
return p;
});
p.then([&](int r) {
values << r;
}).wait();
QCOMPARE(waitForError(p, QString()), QString("foo"));
QCOMPARE(p.isRejected(), true);
QCOMPARE(values, QVector<int>({8, 64}));
}
void tst_qpromise_finally::rejectedAsyncReject()
{
auto p = QPromise<int>::reject(QString("foo")).finally([]() {
return QPromise<int>([](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
QtPromisePrivate::qtpromise_defer([=]() {
reject(QString("bar"));
});
});
});
QCOMPARE(waitForError(p, QString()), QString("bar"));
QCOMPARE(p.isRejected(), true);
}

View File

@ -1,4 +1,9 @@
TARGET = tst_qpromise TEMPLATE = subdirs
SOURCES += $$PWD/tst_qpromise.cpp SUBDIRS += \
construct \
include(../qtpromise.pri) delay \
fail \
finally \
tap \
then \
timeout

View File

@ -0,0 +1,4 @@
TARGET = tst_qpromise_tap
SOURCES += $$PWD/tst_tap.cpp
include(../../qtpromise.pri)

View File

@ -0,0 +1,145 @@
// Tests
#include "../../shared/utils.h"
// QtPromise
#include <QtPromise>
// Qt
#include <QtTest>
using namespace QtPromise;
class tst_qpromise_tap : public QObject
{
Q_OBJECT
private Q_SLOTS:
void fulfilledSync();
void fulfilledSync_void();
void fulfilledThrows();
void fulfilledThrows_void();
void fulfilledAsyncResolve();
void fulfilledAsyncReject();
void rejectedSync();
void rejectedSync_void();
};
QTEST_MAIN(tst_qpromise_tap)
#include "tst_tap.moc"
void tst_qpromise_tap::fulfilledSync()
{
int value = -1;
auto p = QPromise<int>::resolve(42).tap([&](int res) {
value = res + 1;
return 8;
});
QCOMPARE(waitForValue(p, 42), 42);
QCOMPARE(p.isFulfilled(), true);
QCOMPARE(value, 43);
}
void tst_qpromise_tap::fulfilledSync_void()
{
int value = -1;
auto p = QPromise<void>::resolve().tap([&]() {
value = 43;
return 8;
});
QCOMPARE(waitForValue(p, -1, 42), 42);
QCOMPARE(p.isFulfilled(), true);
QCOMPARE(value, 43);
}
void tst_qpromise_tap::fulfilledThrows()
{
auto p = QPromise<int>::resolve(42).tap([&](int) {
throw QString("foo");
});
QCOMPARE(waitForError(p, QString()), QString("foo"));
QCOMPARE(p.isRejected(), true);
}
void tst_qpromise_tap::fulfilledThrows_void()
{
auto p = QPromise<void>::resolve().tap([&]() {
throw QString("foo");
});
QCOMPARE(waitForError(p, QString()), QString("foo"));
QCOMPARE(p.isRejected(), true);
}
void tst_qpromise_tap::fulfilledAsyncResolve()
{
QVector<int> values;
auto p = QPromise<int>::resolve(1).tap([&](int) {
QPromise<int> p([&](const QPromiseResolve<int>& resolve) {
QtPromisePrivate::qtpromise_defer([=, &values]() {
values << 3;
resolve(4); // ignored!
});
});
values << 2;
return p;
});
p.then([&](int r) {
values << r;
}).wait();
QCOMPARE(p.isFulfilled(), true);
QCOMPARE(values, QVector<int>({2, 3, 1}));
}
void tst_qpromise_tap::fulfilledAsyncReject()
{
QVector<int> values;
auto p = QPromise<int>::resolve(1).tap([&](int) {
QPromise<int> p([&](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
QtPromisePrivate::qtpromise_defer([=, &values]() {
values << 3;
reject(QString("foo"));
});
});
values << 2;
return p;
});
p.then([&](int r) {
values << r;
}).wait();
QCOMPARE(waitForError(p, QString()), QString("foo"));
QCOMPARE(p.isRejected(), true);
QCOMPARE(values, QVector<int>({2, 3}));
}
void tst_qpromise_tap::rejectedSync()
{
int value = -1;
auto p = QPromise<int>::reject(QString("foo")).tap([&](int res) {
value = res + 1;
});
QCOMPARE(waitForError(p, QString()), QString("foo"));
QCOMPARE(p.isRejected(), true);
QCOMPARE(value, -1);
}
void tst_qpromise_tap::rejectedSync_void()
{
int value = -1;
auto p = QPromise<void>::reject(QString("foo")).tap([&]() {
value = 43;
});
QCOMPARE(waitForError(p, QString()), QString("foo"));
QCOMPARE(p.isRejected(), true);
QCOMPARE(value, -1);
}

View File

@ -0,0 +1,4 @@
TARGET = tst_qpromise_then
SOURCES += $$PWD/tst_then.cpp
include(../../qtpromise.pri)

View File

@ -0,0 +1,126 @@
// Tests
#include "../../shared/utils.h"
// QtPromise
#include <QtPromise>
// Qt
#include <QtTest>
using namespace QtPromise;
class tst_qpromise_then : public QObject
{
Q_OBJECT
private Q_SLOTS:
void resolveSync();
void resolveAsync();
void rejectSync();
void rejectAsync();
void skipResult();
void noHandler();
};
QTEST_MAIN(tst_qpromise_then)
#include "tst_then.moc"
void tst_qpromise_then::resolveSync()
{
QVariantList values;
auto input = QPromise<int>::resolve(42);
auto output = input.then([&](int res) {
values << res;
return QString::number(res+1);
});
output.then([&](const QString& res) {
values << res;
}).then([&]() {
values << 44;
}).wait();
QCOMPARE(values, QVariantList({42, QString("43"), 44}));
QCOMPARE(input.isFulfilled(), true);
QCOMPARE(output.isFulfilled(), true);
}
void tst_qpromise_then::resolveAsync()
{
auto p = QPromise<int>::resolve(42).then([](int res) {
return QPromise<QString>([=](const QPromiseResolve<QString>& resolve) {
QtPromisePrivate::qtpromise_defer([=]() {
resolve(QString("foo%1").arg(res));
});
});
});
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QString> >::value));
QCOMPARE(waitForValue(p, QString()), QString("foo42"));
QCOMPARE(p.isFulfilled(), true);
}
void tst_qpromise_then::rejectSync()
{
auto input = QPromise<int>::resolve(42);
auto output = input.then([](int res) {
throw QString("foo%1").arg(res);
return 42;
});
QString error;
output.then([&](int res) {
error += "bar" + QString::number(res);
}).fail([&](const QString& err) {
error += err;
}).wait();
QCOMPARE(error, QString("foo42"));
QCOMPARE(input.isFulfilled(), true);
QCOMPARE(output.isRejected(), true);
}
void tst_qpromise_then::rejectAsync()
{
auto p = QPromise<int>::resolve(42).then([](int res) {
return QPromise<void>([=](const QPromiseResolve<void>&, const QPromiseReject<void>& reject) {
QtPromisePrivate::qtpromise_defer([=]() {
reject(QString("foo%1").arg(res));
});
});
});
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<void> >::value));
QCOMPARE(waitForError(p, QString()), QString("foo42"));
QCOMPARE(p.isRejected(), true);
}
void tst_qpromise_then::skipResult()
{
auto p = QPromise<int>::resolve(42);
int value = -1;
p.then([&]() {
value = 43;
}).wait();
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<int> >::value));
QCOMPARE(value, 43);
}
void tst_qpromise_then::noHandler()
{
{ // resolved
auto p = QPromise<int>::resolve(42).then(nullptr);
QCOMPARE(waitForValue(p, -1), 42);
QCOMPARE(p.isFulfilled(), true);
}
{ // rejected
auto p = QPromise<int>::reject(QString("foo")).then(nullptr);
QCOMPARE(waitForError(p, QString()), QString("foo"));
QCOMPARE(p.isRejected(), true);
}
}

View File

@ -0,0 +1,4 @@
TARGET = tst_qpromise_timeout
SOURCES += $$PWD/tst_timeout.cpp
include(../../qtpromise.pri)

View File

@ -0,0 +1,92 @@
// Tests
#include "../../shared/utils.h"
// QtPromise
#include <QtPromise>
// Qt
#include <QtTest>
using namespace QtPromise;
class tst_qpromise_timeout : public QObject
{
Q_OBJECT
private Q_SLOTS:
void fulfilled();
void rejected();
void timeout();
};
QTEST_MAIN(tst_qpromise_timeout)
#include "tst_timeout.moc"
void tst_qpromise_timeout::fulfilled()
{
QElapsedTimer timer;
qint64 elapsed = -1;
timer.start();
auto p = QPromise<int>([](const QPromiseResolve<int>& resolve) {
QTimer::singleShot(1000, [=]() {
resolve(42);
});
}).timeout(2000).finally([&]() {
elapsed = timer.elapsed();
});
QCOMPARE(waitForValue(p, -1), 42);
QCOMPARE(p.isFulfilled(), true);
QVERIFY(elapsed < 2000);
}
void tst_qpromise_timeout::rejected()
{
QElapsedTimer timer;
qint64 elapsed = -1;
timer.start();
auto p = QPromise<int>([](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
QTimer::singleShot(1000, [=]() {
reject(QString("foo"));
});
}).timeout(2000).finally([&]() {
elapsed = timer.elapsed();
});
QCOMPARE(waitForError(p, QString()), QString("foo"));
QCOMPARE(p.isRejected(), true);
QVERIFY(elapsed < 2000);
}
void tst_qpromise_timeout::timeout()
{
QElapsedTimer timer;
qint64 elapsed = -1;
bool failed = false;
timer.start();
auto p = QPromise<int>([](const QPromiseResolve<int>& resolve) {
QTimer::singleShot(4000, [=]() {
resolve(42);
});
}).timeout(2000).finally([&]() {
elapsed = timer.elapsed();
});
p.fail([&](const QPromiseTimeoutException&) {
failed = true;
return -1;
}).wait();
QCOMPARE(waitForValue(p, -1), -1);
QCOMPARE(p.isRejected(), true);
QCOMPARE(failed, true);
QVERIFY(elapsed >= 2000 * 0.95); // Qt::CoarseTimer (default) Coarse timers try to
QVERIFY(elapsed <= 2000 * 1.05); // keep accuracy within 5% of the desired interval.
}

View File

@ -1,766 +0,0 @@
// QtPromise
#include <QtPromise>
// Qt
#include <QtTest>
#include <QElapsedTimer>
using namespace QtPromise;
using namespace QtPromisePrivate;
class tst_qpromise : public QObject
{
Q_OBJECT
private Q_SLOTS:
void resolveSync();
void resolveSync_void();
void resolveDelayed();
void rejectSync();
void rejectDelayed();
void rejectThrows();
void thenReturns();
void thenThrows();
void thenNullPtr();
void thenSkipResult();
void thenDelayedResolved();
void thenDelayedRejected();
void failSameType();
void failBaseClass();
void failCatchAll();
void finallyFulfilled();
void finallyFulfilled_void();
void finallyRejected();
void finallyRejected_void();
void finallyThrows();
void finallyThrows_void();
void finallyDelayedResolved();
void finallyDelayedRejected();
void tapFulfilled();
void tapFulfilled_void();
void tapRejected();
void tapRejected_void();
void tapThrows();
void tapThrows_void();
void tapDelayedResolved();
void tapDelayedRejected();
void timeoutFulfilled();
void timeoutRejected();
void timeoutReject();
void delayFulfilled();
void delayRejected();
}; // class tst_qpromise
QTEST_MAIN(tst_qpromise)
#include "tst_qpromise.moc"
template <typename T>
T waitForValue(const QPromise<T>& promise, const T& initial)
{
T value(initial);
promise.then([&](const T& res) {
value = res;
}).wait();
return value;
}
template <typename T>
T waitForValue(const QPromise<void>& promise, const T& initial, const T& expected)
{
T value(initial);
promise.then([&]() {
value = expected;
}).wait();
return value;
}
template <typename T, typename E>
E waitForError(const QPromise<T>& promise, const E& initial)
{
E error(initial);
promise.fail([&](const E& err) {
error = err;
return T();
}).wait();
return error;
}
template <typename E>
E waitForError(const QPromise<void>& promise, const E& initial)
{
E error(initial);
promise.fail([&](const E& err) {
error = err;
}).wait();
return error;
}
void tst_qpromise::resolveSync()
{
{ // resolver(resolve)
QPromise<int> p([](const QPromiseResolve<int>& resolve) {
resolve(42);
});
QCOMPARE(p.isFulfilled(), true);
QCOMPARE(waitForError(p, QString()), QString());
QCOMPARE(waitForValue(p, -1), 42);
}
{ // resolver(resolve, reject)
QPromise<int> p([](const QPromiseResolve<int>& resolve, const QPromiseReject<int>&) {
resolve(42);
});
QCOMPARE(p.isFulfilled(), true);
QCOMPARE(waitForError(p, QString()), QString());
QCOMPARE(waitForValue(p, -1), 42);
}
}
void tst_qpromise::resolveSync_void()
{
{ // resolver(resolve)
QPromise<void> p([](const QPromiseResolve<void>& resolve) {
resolve();
});
QCOMPARE(p.isFulfilled(), true);
QCOMPARE(waitForError(p, QString()), QString());
QCOMPARE(waitForValue(p, -1, 42), 42);
}
{ // resolver(resolve, reject)
QPromise<void> p([](const QPromiseResolve<void>& resolve, const QPromiseReject<void>&) {
resolve();
});
QCOMPARE(p.isFulfilled(), true);
QCOMPARE(waitForError(p, QString()), QString());
QCOMPARE(waitForValue(p, -1, 42), 42);
}
}
void tst_qpromise::resolveDelayed()
{
{ // resolver(resolve)
QPromise<int> p([](const QPromiseResolve<int>& resolve) {
QtPromisePrivate::qtpromise_defer([=]() {
resolve(42);
});
});
QCOMPARE(p.isPending(), true);
QCOMPARE(waitForError(p, QString()), QString());
QCOMPARE(waitForValue(p, -1), 42);
QCOMPARE(p.isFulfilled(), true);
}
{ // resolver(resolve, reject)
QPromise<int> p([](const QPromiseResolve<int>& resolve, const QPromiseReject<int>&) {
QtPromisePrivate::qtpromise_defer([=]() {
resolve(42);
});
});
QCOMPARE(p.isPending(), true);
QCOMPARE(waitForError(p, QString()), QString());
QCOMPARE(waitForValue(p, -1), 42);
QCOMPARE(p.isFulfilled(), true);
}
}
void tst_qpromise::rejectSync()
{
QPromise<int> p([](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
reject(QString("foo"));
});
QCOMPARE(p.isRejected(), true);
QCOMPARE(waitForValue(p, -1), -1);
QCOMPARE(waitForError(p, QString()), QString("foo"));
}
void tst_qpromise::rejectDelayed()
{
QPromise<int> p([](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
QtPromisePrivate::qtpromise_defer([=]() {
reject(QString("foo"));
});
});
QCOMPARE(p.isPending(), true);
QCOMPARE(waitForValue(p, -1), -1);
QCOMPARE(waitForError(p, QString()), QString("foo"));
QCOMPARE(p.isRejected(), true);
}
void tst_qpromise::rejectThrows()
{
{ // resolver(resolve)
QPromise<int> p([](const QPromiseResolve<int>&) {
throw QString("foo");
});
QCOMPARE(p.isRejected(), true);
QCOMPARE(waitForValue(p, -1), -1);
QCOMPARE(waitForError(p, QString()), QString("foo"));
}
{ // resolver(resolve, reject)
QPromise<int> p([](const QPromiseResolve<int>&, const QPromiseReject<int>&) {
throw QString("foo");
});
QCOMPARE(p.isRejected(), true);
QCOMPARE(waitForValue(p, -1), -1);
QCOMPARE(waitForError(p, QString()), QString("foo"));
}
}
void tst_qpromise::thenReturns()
{
auto p = QPromise<int>::resolve(42);
QVariantList values;
p.then([&](int res) {
values << res;
return QString::number(res+1);
}).then([&](const QString& res) {
values << res;
}).then([&]() {
values << 44;
}).wait();
QCOMPARE(values, QVariantList({42, QString("43"), 44}));
}
void tst_qpromise::thenThrows()
{
auto input = QPromise<int>::resolve(42);
auto output = input.then([](int res) {
throw QString("foo%1").arg(res);
return 42;
});
QString error;
output.then([&](int res) {
error += "bar" + QString::number(res);
}).fail([&](const QString& err) {
error += err;
}).wait();
QCOMPARE(input.isFulfilled(), true);
QCOMPARE(output.isRejected(), true);
QCOMPARE(error, QString("foo42"));
}
void tst_qpromise::thenNullPtr()
{
{ // resolved
auto p = QPromise<int>::resolve(42).then(nullptr);
QCOMPARE(waitForValue(p, -1), 42);
QCOMPARE(p.isFulfilled(), true);
}
{ // rejected
auto p = QPromise<int>::reject(QString("foo")).then(nullptr);
QCOMPARE(waitForError(p, QString()), QString("foo"));
QCOMPARE(p.isRejected(), true);
}
}
void tst_qpromise::thenSkipResult()
{
auto p = QPromise<int>::resolve(42);
int value = -1;
p.then([&]() {
value = 43;
}).wait();
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<int> >::value));
QCOMPARE(value, 43);
}
void tst_qpromise::thenDelayedResolved()
{
auto p = QPromise<int>::resolve(42).then([](int res) {
return QPromise<QString>([=](const QPromiseResolve<QString>& resolve) {
QtPromisePrivate::qtpromise_defer([=]() {
resolve(QString("foo%1").arg(res));
});
});
});
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QString> >::value));
QCOMPARE(waitForValue(p, QString()), QString("foo42"));
}
void tst_qpromise::thenDelayedRejected()
{
auto p = QPromise<int>::resolve(42).then([](int res) {
return QPromise<void>([=](const QPromiseResolve<void>&, const QPromiseReject<void>& reject) {
QtPromisePrivate::qtpromise_defer([=]() {
reject(QString("foo%1").arg(res));
});
});
});
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<void> >::value));
QCOMPARE(waitForError(p, QString()), QString("foo42"));
}
void tst_qpromise::failSameType()
{
// http://en.cppreference.com/w/cpp/error/exception
auto p = QPromise<int>::reject(std::out_of_range("foo"));
QString error;
p.fail([&](const std::domain_error& e) {
error += QString(e.what()) + "0";
return -1;
}).fail([&](const std::out_of_range& e) {
error += QString(e.what()) + "1";
return -1;
}).fail([&](const std::exception& e) {
error += QString(e.what()) + "2";
return -1;
}).wait();
QCOMPARE(error, QString("foo1"));
}
void tst_qpromise::failBaseClass()
{
// http://en.cppreference.com/w/cpp/error/exception
auto p = QPromise<int>::reject(std::out_of_range("foo"));
QString error;
p.fail([&](const std::runtime_error& e) {
error += QString(e.what()) + "0";
return -1;
}).fail([&](const std::logic_error& e) {
error += QString(e.what()) + "1";
return -1;
}).fail([&](const std::exception& e) {
error += QString(e.what()) + "2";
return -1;
}).wait();
QCOMPARE(error, QString("foo1"));
}
void tst_qpromise::failCatchAll()
{
auto p = QPromise<int>::reject(std::out_of_range("foo"));
QString error;
p.fail([&](const std::runtime_error& e) {
error += QString(e.what()) + "0";
return -1;
}).fail([&]() {
error += "bar";
return -1;
}).fail([&](const std::exception& e) {
error += QString(e.what()) + "2";
return -1;
}).wait();
QCOMPARE(error, QString("bar"));
}
void tst_qpromise::finallyFulfilled()
{
int value = -1;
auto p = QPromise<int>::resolve(42).finally([&]() {
value = 8;
return 16; // ignored!
});
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<int> >::value));
QCOMPARE(waitForValue(p, -1), 42);
QCOMPARE(p.isFulfilled(), true);
QCOMPARE(value, 8);
}
void tst_qpromise::finallyFulfilled_void()
{
int value = -1;
auto p = QPromise<void>::resolve().finally([&]() {
value = 8;
return 16; // ignored!
});
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<void> >::value));
QCOMPARE(waitForValue(p, -1, 42), 42);
QCOMPARE(p.isFulfilled(), true);
QCOMPARE(value, 8);
}
void tst_qpromise::finallyRejected()
{
int value = -1;
auto p = QPromise<int>::reject(QString("foo")).finally([&]() {
value = 8;
return 16; // ignored!
});
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<int> >::value));
QCOMPARE(waitForError(p, QString()), QString("foo"));
QCOMPARE(p.isRejected(), true);
QCOMPARE(value, 8);
}
void tst_qpromise::finallyRejected_void()
{
int value = -1;
auto p = QPromise<void>::reject(QString("foo")).finally([&]() {
value = 8;
return 16; // ignored!
});
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<void> >::value));
QCOMPARE(waitForError(p, QString()), QString("foo"));
QCOMPARE(p.isRejected(), true);
QCOMPARE(value, 8);
}
void tst_qpromise::finallyThrows()
{
{ // fulfilled
auto p = QPromise<int>::resolve(42).finally([&]() {
throw QString("bar");
});
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<int> >::value));
QCOMPARE(waitForError(p, QString()), QString("bar"));
QCOMPARE(p.isRejected(), true);
}
{ // rejected
auto p = QPromise<int>::reject(QString("foo")).finally([&]() {
throw QString("bar");
});
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<int> >::value));
QCOMPARE(waitForError(p, QString()), QString("bar"));
QCOMPARE(p.isRejected(), true);
}
}
void tst_qpromise::finallyThrows_void()
{
{ // fulfilled
auto p = QPromise<void>::resolve().finally([&]() {
throw QString("bar");
});
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<void> >::value));
QCOMPARE(waitForError(p, QString()), QString("bar"));
QCOMPARE(p.isRejected(), true);
}
{ // rejected
auto p = QPromise<void>::reject(QString("foo")).finally([&]() {
throw QString("bar");
});
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<void> >::value));
QCOMPARE(waitForError(p, QString()), QString("bar"));
QCOMPARE(p.isRejected(), true);
}
}
void tst_qpromise::finallyDelayedResolved()
{
{ // fulfilled
QVector<int> values;
auto p = QPromise<int>::resolve(42).finally([&]() {
QPromise<int> p([&](const QPromiseResolve<int>& resolve) {
qtpromise_defer([=, &values]() {
values << 64;
resolve(16); // ignored!
});
});
values << 8;
return p;
});
QCOMPARE(waitForValue(p, -1), 42);
QCOMPARE(p.isFulfilled(), true);
QCOMPARE(values, QVector<int>({8, 64}));
}
{ // rejected
QVector<int> values;
auto p = QPromise<int>::reject(QString("foo")).finally([&]() {
QPromise<int> p([&](const QPromiseResolve<int>& resolve) {
qtpromise_defer([=, &values]() {
values << 64;
resolve(16); // ignored!
});
});
values << 8;
return p;
});
p.then([&](int r) {
values << r;
}).wait();
QCOMPARE(waitForError(p, QString()), QString("foo"));
QCOMPARE(p.isRejected(), true);
QCOMPARE(values, QVector<int>({8, 64}));
}
}
void tst_qpromise::finallyDelayedRejected()
{
{ // fulfilled
auto p = QPromise<int>::resolve(42).finally([]() {
return QPromise<int>([](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
qtpromise_defer([=]() {
reject(QString("bar"));
});
});
});
QCOMPARE(waitForError(p, QString()), QString("bar"));
QCOMPARE(p.isRejected(), true);
}
{ // rejected
auto p = QPromise<int>::reject(QString("foo")).finally([]() {
return QPromise<int>([](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
qtpromise_defer([=]() {
reject(QString("bar"));
});
});
});
QCOMPARE(waitForError(p, QString()), QString("bar"));
QCOMPARE(p.isRejected(), true);
}
}
void tst_qpromise::tapFulfilled()
{
int value = -1;
auto p = QPromise<int>::resolve(42).tap([&](int res) {
value = res + 1;
return 8;
});
QCOMPARE(waitForValue(p, 42), 42);
QCOMPARE(p.isFulfilled(), true);
QCOMPARE(value, 43);
}
void tst_qpromise::tapFulfilled_void()
{
int value = -1;
auto p = QPromise<void>::resolve().tap([&]() {
value = 43;
return 8;
});
QCOMPARE(waitForValue(p, -1, 42), 42);
QCOMPARE(p.isFulfilled(), true);
QCOMPARE(value, 43);
}
void tst_qpromise::tapRejected()
{
int value = -1;
auto p = QPromise<int>::reject(QString("foo")).tap([&](int res) {
value = res + 1;
});
QCOMPARE(waitForError(p, QString()), QString("foo"));
QCOMPARE(p.isRejected(), true);
QCOMPARE(value, -1);
}
void tst_qpromise::tapRejected_void()
{
int value = -1;
auto p = QPromise<void>::reject(QString("foo")).tap([&]() {
value = 43;
});
QCOMPARE(waitForError(p, QString()), QString("foo"));
QCOMPARE(p.isRejected(), true);
QCOMPARE(value, -1);
}
void tst_qpromise::tapThrows()
{
auto p = QPromise<int>::resolve(42).tap([&](int) {
throw QString("foo");
});
QCOMPARE(waitForError(p, QString()), QString("foo"));
QCOMPARE(p.isRejected(), true);
}
void tst_qpromise::tapThrows_void()
{
auto p = QPromise<void>::resolve().tap([&]() {
throw QString("foo");
});
QCOMPARE(waitForError(p, QString()), QString("foo"));
QCOMPARE(p.isRejected(), true);
}
void tst_qpromise::tapDelayedResolved()
{
QVector<int> values;
auto p = QPromise<int>::resolve(1).tap([&](int) {
QPromise<int> p([&](const QPromiseResolve<int>& resolve) {
qtpromise_defer([=, &values]() {
values << 3;
resolve(4); // ignored!
});
});
values << 2;
return p;
});
p.then([&](int r) {
values << r;
}).wait();
QCOMPARE(p.isFulfilled(), true);
QCOMPARE(values, QVector<int>({2, 3, 1}));
}
void tst_qpromise::tapDelayedRejected()
{
QVector<int> values;
auto p = QPromise<int>::resolve(1).tap([&](int) {
QPromise<int> p([&](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
qtpromise_defer([=, &values]() {
values << 3;
reject(QString("foo"));
});
});
values << 2;
return p;
});
p.then([&](int r) {
values << r;
}).wait();
QCOMPARE(waitForError(p, QString()), QString("foo"));
QCOMPARE(p.isRejected(), true);
QCOMPARE(values, QVector<int>({2, 3}));
}
void tst_qpromise::timeoutFulfilled()
{
QElapsedTimer timer;
qint64 elapsed = -1;
timer.start();
auto p = QPromise<int>([](const QPromiseResolve<int>& resolve) {
QTimer::singleShot(1000, [=]() {
resolve(42);
});
}).timeout(2000).finally([&]() {
elapsed = timer.elapsed();
});
QCOMPARE(waitForValue(p, -1), 42);
QCOMPARE(p.isFulfilled(), true);
QVERIFY(elapsed < 2000);
}
void tst_qpromise::timeoutRejected()
{
QElapsedTimer timer;
qint64 elapsed = -1;
timer.start();
auto p = QPromise<int>([](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
QTimer::singleShot(1000, [=]() {
reject(QString("foo"));
});
}).timeout(2000).finally([&]() {
elapsed = timer.elapsed();
});
QCOMPARE(waitForError(p, QString()), QString("foo"));
QCOMPARE(p.isRejected(), true);
QVERIFY(elapsed < 2000);
}
void tst_qpromise::timeoutReject()
{
QElapsedTimer timer;
qint64 elapsed = -1;
bool failed = false;
timer.start();
auto p = QPromise<int>([](const QPromiseResolve<int>& resolve) {
QTimer::singleShot(4000, [=]() {
resolve(42);
});
}).timeout(2000).finally([&]() {
elapsed = timer.elapsed();
});
p.fail([&](const QPromiseTimeoutException&) {
failed = true;
return -1;
}).wait();
QCOMPARE(waitForValue(p, -1), -1);
QCOMPARE(p.isRejected(), true);
QCOMPARE(failed, true);
QVERIFY(elapsed >= 2000 * 0.95); // Qt::CoarseTimer (default) Coarse timers try to
QVERIFY(elapsed <= 2000 * 1.05); // keep accuracy within 5% of the desired interval.
}
void tst_qpromise::delayFulfilled()
{
QElapsedTimer timer;
qint64 elapsed = -1;
timer.start();
auto p = QPromise<int>::resolve(42).delay(1000).finally([&]() {
elapsed = timer.elapsed();
});
QCOMPARE(waitForValue(p, -1), 42);
QCOMPARE(p.isFulfilled(), true);
QVERIFY(elapsed >= 1000 * 0.95); // Qt::CoarseTimer (default) Coarse timers try to
QVERIFY(elapsed <= 1000 * 1.05); // keep accuracy within 5% of the desired interval.
}
void tst_qpromise::delayRejected()
{
QElapsedTimer timer;
qint64 elapsed = -1;
timer.start();
auto p = QPromise<int>::reject(QString("foo")).delay(1000).finally([&]() {
elapsed = timer.elapsed();
});
QCOMPARE(waitForError(p, QString()), QString("foo"));
QCOMPARE(p.isRejected(), true);
QVERIFY(elapsed < 5);
}

View File

@ -15,4 +15,7 @@ coverage {
} }
} }
HEADERS += \
$$PWD/shared/utils.h
include(../../../qtpromise.pri) include(../../../qtpromise.pri)

View File

@ -5,7 +5,6 @@
#include <QtTest> #include <QtTest>
using namespace QtPromise; using namespace QtPromise;
using namespace QtPromisePrivate;
// https://promisesaplus.com/#requirements // https://promisesaplus.com/#requirements
class tst_requirements : public QObject class tst_requirements : public QObject
@ -41,7 +40,7 @@ void tst_requirements::statePending()
// 2.1.1.1. may transition to either the fulfilled state // 2.1.1.1. may transition to either the fulfilled state
{ {
QPromise<int> p([&](const QPromiseResolve<int>& resolve) { QPromise<int> p([&](const QPromiseResolve<int>& resolve) {
qtpromise_defer([=]() { resolve(42); }); QtPromisePrivate::qtpromise_defer([=]() { resolve(42); });
}); });
QVERIFY(p.isPending()); QVERIFY(p.isPending());
@ -58,7 +57,7 @@ void tst_requirements::statePending()
// 2.1.1.1. ... or the rejected state // 2.1.1.1. ... or the rejected state
{ {
QPromise<int> p([&](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) { QPromise<int> p([&](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
qtpromise_defer([=]() { reject(QString("foo")); }); QtPromisePrivate::qtpromise_defer([=]() { reject(QString("foo")); });
}); });
QVERIFY(p.isPending()); QVERIFY(p.isPending());
@ -82,7 +81,7 @@ void tst_requirements::stateFulfilled()
QPromise<int> p([]( QPromise<int> p([](
const QPromiseResolve<int>& resolve, const QPromiseResolve<int>& resolve,
const QPromiseReject<int>& reject) { const QPromiseReject<int>& reject) {
qtpromise_defer([=]() { QtPromisePrivate::qtpromise_defer([=]() {
// 2.1.2.2. must have a value, which must not change. // 2.1.2.2. must have a value, which must not change.
resolve(42); resolve(42);
resolve(43); resolve(43);
@ -115,7 +114,7 @@ void tst_requirements::stateRejected()
QPromise<int> p([]( QPromise<int> p([](
const QPromiseResolve<int>& resolve, const QPromiseResolve<int>& resolve,
const QPromiseReject<int>& reject) { const QPromiseReject<int>& reject) {
qtpromise_defer([=]() { QtPromisePrivate::qtpromise_defer([=]() {
// 2.1.3.2. must have a reason, which must not change. // 2.1.3.2. must have a reason, which must not change.
reject(QString("foo")); reject(QString("foo"));
reject(QString("bar")); reject(QString("bar"));
@ -196,7 +195,7 @@ void tst_requirements::thenOnFulfilled()
// 2.2.2. If onFulfilled is a function: // 2.2.2. If onFulfilled is a function:
QVector<int> values; QVector<int> values;
QPromise<int> p0([](const QPromiseResolve<int>& resolve) { QPromise<int> p0([](const QPromiseResolve<int>& resolve) {
qtpromise_defer([=]() { QtPromisePrivate::qtpromise_defer([=]() {
// 2.2.2.3. it must not be called more than once // 2.2.2.3. it must not be called more than once
resolve(42); resolve(42);
resolve(43); resolve(43);
@ -224,7 +223,7 @@ void tst_requirements::thenOnRejected()
// 2.2.3. If onRejected is a function: // 2.2.3. If onRejected is a function:
QStringList errors; QStringList errors;
QPromise<void> p0([](const QPromiseResolve<void>&, const QPromiseReject<void>& reject) { QPromise<void> p0([](const QPromiseResolve<void>&, const QPromiseReject<void>& reject) {
qtpromise_defer([=]() { QtPromisePrivate::qtpromise_defer([=]() {
// 2.2.3.3. it must not be called more than once. // 2.2.3.3. it must not be called more than once.
reject(QString("foo")); reject(QString("foo"));
reject(QString("bar")); reject(QString("bar"));
@ -275,7 +274,7 @@ void tst_requirements::thenMultipleCalls()
{ {
QVector<int> values; QVector<int> values;
QPromise<int> p([](const QPromiseResolve<int>& resolve) { QPromise<int> p([](const QPromiseResolve<int>& resolve) {
qtpromise_defer([=]() { QtPromisePrivate::qtpromise_defer([=]() {
resolve(42); resolve(42);
}); });
}); });
@ -294,7 +293,7 @@ void tst_requirements::thenMultipleCalls()
{ {
QVector<int> values; QVector<int> values;
QPromise<int> p([](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) { QPromise<int> p([](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
qtpromise_defer([=]() { QtPromisePrivate::qtpromise_defer([=]() {
reject(8); reject(8);
}); });
}); });

View File

@ -0,0 +1,47 @@
#ifndef QTPROMISE_TESTS_AUTO_SHARED_UTILS_H
#define QTPROMISE_TESTS_AUTO_SHARED_UTILS_H
#include <QtPromise>
template <typename T>
static inline T waitForValue(const QtPromise::QPromise<T>& promise, const T& initial)
{
T value(initial);
promise.then([&](const T& res) {
value = res;
}).wait();
return value;
}
template <typename T>
static inline T waitForValue(const QtPromise::QPromise<void>& promise, const T& initial, const T& expected)
{
T value(initial);
promise.then([&]() {
value = expected;
}).wait();
return value;
}
template <typename T, typename E>
static inline E waitForError(const QtPromise::QPromise<T>& promise, const E& initial)
{
E error(initial);
promise.fail([&](const E& err) {
error = err;
return T();
}).wait();
return error;
}
template <typename E>
static inline E waitForError(const QtPromise::QPromise<void>& promise, const E& initial)
{
E error(initial);
promise.fail([&](const E& err) {
error = err;
}).wait();
return error;
}
#endif // QTPROMISE_TESTS_AUTO_SHARED_UTILS_H