mirror of
https://github.com/simonbrunel/qtpromise.git
synced 2025-07-02 07:15:25 +08:00
Implement QPromise<Sequence<T>>::map(mapper) (#15)
Iterate over all the promise value (i.e. `Sequence<T>`) and map the sequence to another using the given `mapper` function. Also provide a static helper to directly map values (`QtPromise::map(values, mapper)`).
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
TEMPLATE = subdirs
|
||||
SUBDIRS += \
|
||||
all \
|
||||
map \
|
||||
reject \
|
||||
resolve
|
||||
|
4
tests/auto/qtpromise/helpers/map/map.pro
Normal file
4
tests/auto/qtpromise/helpers/map/map.pro
Normal file
@ -0,0 +1,4 @@
|
||||
TARGET = tst_helpers_map
|
||||
SOURCES += $$PWD/tst_map.cpp
|
||||
|
||||
include(../../qtpromise.pri)
|
151
tests/auto/qtpromise/helpers/map/tst_map.cpp
Normal file
151
tests/auto/qtpromise/helpers/map/tst_map.cpp
Normal file
@ -0,0 +1,151 @@
|
||||
// Tests
|
||||
#include "../../shared/utils.h"
|
||||
|
||||
// QtPromise
|
||||
#include <QtPromise>
|
||||
|
||||
// Qt
|
||||
#include <QtTest>
|
||||
|
||||
using namespace QtPromise;
|
||||
|
||||
class tst_helpers_map : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private Q_SLOTS:
|
||||
void emptySequence();
|
||||
void modifyValues();
|
||||
void convertValues();
|
||||
void delayedFulfilled();
|
||||
void delayedRejected();
|
||||
void functorThrows();
|
||||
void functorArguments();
|
||||
void preserveOrder();
|
||||
void sequenceTypes();
|
||||
};
|
||||
|
||||
QTEST_MAIN(tst_helpers_map)
|
||||
#include "tst_map.moc"
|
||||
|
||||
namespace {
|
||||
|
||||
template <class Sequence>
|
||||
struct SequenceTester
|
||||
{
|
||||
static void exec()
|
||||
{
|
||||
auto p = QtPromise::map(Sequence{42, 43, 44}, [](int v, ...) {
|
||||
return QString::number(v + 1);
|
||||
});
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<QString>>>::value));
|
||||
QCOMPARE(waitForValue(p, QVector<QString>()), QVector<QString>({"43", "44", "45"}));
|
||||
}
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
void tst_helpers_map::emptySequence()
|
||||
{
|
||||
auto p = QtPromise::map(QVector<int>{}, [](int v, ...) {
|
||||
return v + 1;
|
||||
});
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<int>>>::value));
|
||||
QCOMPARE(waitForValue(p, QVector<int>()), QVector<int>({}));
|
||||
}
|
||||
|
||||
void tst_helpers_map::modifyValues()
|
||||
{
|
||||
auto p = QtPromise::map(QVector<int>{42, 43, 44}, [](int v, ...) {
|
||||
return v + 1;
|
||||
});
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<int>>>::value));
|
||||
QCOMPARE(waitForValue(p, QVector<int>()), QVector<int>({43, 44, 45}));
|
||||
}
|
||||
|
||||
void tst_helpers_map::convertValues()
|
||||
{
|
||||
auto p = QtPromise::map(QVector<int>{42, 43, 44}, [](int v, ...) {
|
||||
return QString::number(v + 1);
|
||||
});
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<QString>>>::value));
|
||||
QCOMPARE(waitForValue(p, QVector<QString>()), QVector<QString>({"43", "44", "45"}));
|
||||
}
|
||||
|
||||
void tst_helpers_map::delayedFulfilled()
|
||||
{
|
||||
auto p = QtPromise::map(QVector<int>{42, 43, 44}, [](int v, ...) {
|
||||
return QPromise<int>([&](const QPromiseResolve<int>& resolve) {
|
||||
QtPromisePrivate::qtpromise_defer([=]() {
|
||||
resolve(v + 1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<int>>>::value));
|
||||
QCOMPARE(waitForValue(p, QVector<int>()), QVector<int>({43, 44, 45}));
|
||||
}
|
||||
|
||||
void tst_helpers_map::delayedRejected()
|
||||
{
|
||||
auto p = QtPromise::map(QVector<int>{42, 43, 44}, [](int v, ...) {
|
||||
return QPromise<int>([&](
|
||||
const QPromiseResolve<int>& resolve,
|
||||
const QPromiseReject<int>& reject) {
|
||||
QtPromisePrivate::qtpromise_defer([=]() {
|
||||
if (v == 43) {
|
||||
reject(QString("foo"));
|
||||
}
|
||||
resolve(v);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<int>>>::value));
|
||||
QCOMPARE(waitForError(p, QString()), QString("foo"));
|
||||
}
|
||||
|
||||
void tst_helpers_map::functorThrows()
|
||||
{
|
||||
auto p = QtPromise::map(QVector<int>{42, 43, 44}, [](int v, ...) {
|
||||
if (v == 43) {
|
||||
throw QString("foo");
|
||||
}
|
||||
return v + 1;
|
||||
});
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<int>>>::value));
|
||||
QCOMPARE(waitForError(p, QString()), QString("foo"));
|
||||
}
|
||||
|
||||
void tst_helpers_map::functorArguments()
|
||||
{
|
||||
auto p = QtPromise::map(QVector<int>{42, 42, 42}, [](int v, int i) {
|
||||
return v * i;
|
||||
});
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<int>>>::value));
|
||||
QCOMPARE(waitForValue(p, QVector<int>()), QVector<int>({0, 42, 84}));
|
||||
}
|
||||
|
||||
void tst_helpers_map::preserveOrder()
|
||||
{
|
||||
auto p = QtPromise::map(QVector<int>{500, 100, 250}, [](int v, ...) {
|
||||
return QPromise<int>::resolve(v + 1).delay(v);
|
||||
});
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<int>>>::value));
|
||||
QCOMPARE(waitForValue(p, QVector<int>()), QVector<int>({501, 101, 251}));
|
||||
}
|
||||
|
||||
void tst_helpers_map::sequenceTypes()
|
||||
{
|
||||
SequenceTester<QList<int>>::exec();
|
||||
SequenceTester<QVector<int>>::exec();
|
||||
SequenceTester<std::list<int>>::exec();
|
||||
SequenceTester<std::vector<int>>::exec();
|
||||
}
|
4
tests/auto/qtpromise/qpromise/map/map.pro
Normal file
4
tests/auto/qtpromise/qpromise/map/map.pro
Normal file
@ -0,0 +1,4 @@
|
||||
TARGET = tst_qpromise_map
|
||||
SOURCES += $$PWD/tst_map.cpp
|
||||
|
||||
include(../../qtpromise.pri)
|
157
tests/auto/qtpromise/qpromise/map/tst_map.cpp
Normal file
157
tests/auto/qtpromise/qpromise/map/tst_map.cpp
Normal file
@ -0,0 +1,157 @@
|
||||
// Tests
|
||||
#include "../../shared/utils.h"
|
||||
|
||||
// QtPromise
|
||||
#include <QtPromise>
|
||||
|
||||
// Qt
|
||||
#include <QtTest>
|
||||
|
||||
using namespace QtPromise;
|
||||
|
||||
class tst_qpromise_map : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private Q_SLOTS:
|
||||
void emptySequence();
|
||||
void modifyValues();
|
||||
void convertValues();
|
||||
void delayedFulfilled();
|
||||
void delayedRejected();
|
||||
void functorThrows();
|
||||
void functorArguments();
|
||||
void preserveOrder();
|
||||
void sequenceTypes();
|
||||
};
|
||||
|
||||
QTEST_MAIN(tst_qpromise_map)
|
||||
#include "tst_map.moc"
|
||||
|
||||
namespace {
|
||||
|
||||
template <class Sequence>
|
||||
struct SequenceTester
|
||||
{
|
||||
static void exec()
|
||||
{
|
||||
auto p = QtPromise::qPromise(Sequence{42, 43, 44}).map([](int v, ...) {
|
||||
return QString::number(v + 1);
|
||||
}).map([](const QString& v, int i) {
|
||||
return QtPromise::qPromise(QString("%1:%2").arg(i).arg(v));
|
||||
}).map([](const QString& v, ...) {
|
||||
return QtPromise::qPromise((v + "!").toUtf8());
|
||||
}).map([](const QByteArray& v, ...) {
|
||||
return QString::fromUtf8(v);
|
||||
});
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<QString>>>::value));
|
||||
QCOMPARE(waitForValue(p, QVector<QString>()), QVector<QString>({"0:43!", "1:44!", "2:45!"}));
|
||||
}
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
void tst_qpromise_map::emptySequence()
|
||||
{
|
||||
auto p = QtPromise::qPromise(QVector<int>{}).map([](int v, ...) {
|
||||
return v + 1;
|
||||
});
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<int>>>::value));
|
||||
QCOMPARE(waitForValue(p, QVector<int>()), QVector<int>({}));
|
||||
}
|
||||
|
||||
void tst_qpromise_map::modifyValues()
|
||||
{
|
||||
auto p = QtPromise::qPromise(QVector<int>{42, 43, 44}).map([](int v, ...) {
|
||||
return v + 1;
|
||||
});
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<int>>>::value));
|
||||
QCOMPARE(waitForValue(p, QVector<int>()), QVector<int>({43, 44, 45}));
|
||||
}
|
||||
|
||||
void tst_qpromise_map::convertValues()
|
||||
{
|
||||
auto p = QtPromise::qPromise(QVector<int>{42, 43, 44}).map([](int v, ...) {
|
||||
return QString::number(v + 1);
|
||||
});
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<QString>>>::value));
|
||||
QCOMPARE(waitForValue(p, QVector<QString>()), QVector<QString>({"43", "44", "45"}));
|
||||
}
|
||||
|
||||
void tst_qpromise_map::delayedFulfilled()
|
||||
{
|
||||
auto p = QtPromise::qPromise(QVector<int>{42, 43, 44}).map([](int v, ...) {
|
||||
return QPromise<int>([&](const QPromiseResolve<int>& resolve) {
|
||||
QtPromisePrivate::qtpromise_defer([=]() {
|
||||
resolve(v + 1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<int>>>::value));
|
||||
QCOMPARE(waitForValue(p, QVector<int>()), QVector<int>({43, 44, 45}));
|
||||
}
|
||||
|
||||
void tst_qpromise_map::delayedRejected()
|
||||
{
|
||||
auto p = QtPromise::qPromise(QVector<int>{42, 43, 44}).map([](int v, ...) {
|
||||
return QPromise<int>([&](
|
||||
const QPromiseResolve<int>& resolve,
|
||||
const QPromiseReject<int>& reject) {
|
||||
QtPromisePrivate::qtpromise_defer([=]() {
|
||||
if (v == 43) {
|
||||
reject(QString("foo"));
|
||||
}
|
||||
resolve(v);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<int>>>::value));
|
||||
QCOMPARE(waitForError(p, QString()), QString("foo"));
|
||||
}
|
||||
|
||||
void tst_qpromise_map::functorThrows()
|
||||
{
|
||||
auto p = QtPromise::qPromise(QVector<int>{42, 43, 44}).map([](int v, ...) {
|
||||
if (v == 43) {
|
||||
throw QString("foo");
|
||||
}
|
||||
return v + 1;
|
||||
});
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<int>>>::value));
|
||||
QCOMPARE(waitForError(p, QString()), QString("foo"));
|
||||
}
|
||||
|
||||
void tst_qpromise_map::functorArguments()
|
||||
{
|
||||
auto p1 = QtPromise::qPromise(QVector<int>{42, 42, 42}).map([](int v, int i) {
|
||||
return v * i;
|
||||
});
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<QVector<int>>>::value));
|
||||
QCOMPARE(waitForValue(p1, QVector<int>()), QVector<int>({0, 42, 84}));
|
||||
}
|
||||
|
||||
void tst_qpromise_map::preserveOrder()
|
||||
{
|
||||
auto p = QtPromise::qPromise(QVector<int>{250, 500, 100}).map([](int v, ...) {
|
||||
return QtPromise::qPromise(v + 1).delay(v);
|
||||
});
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<int>>>::value));
|
||||
QCOMPARE(waitForValue(p, QVector<int>()), QVector<int>({251, 501, 101}));
|
||||
}
|
||||
|
||||
void tst_qpromise_map::sequenceTypes()
|
||||
{
|
||||
SequenceTester<QList<int>>::exec();
|
||||
SequenceTester<QVector<int>>::exec();
|
||||
SequenceTester<std::list<int>>::exec();
|
||||
SequenceTester<std::vector<int>>::exec();
|
||||
}
|
@ -4,6 +4,7 @@ SUBDIRS += \
|
||||
delay \
|
||||
fail \
|
||||
finally \
|
||||
map \
|
||||
operators \
|
||||
tap \
|
||||
tapfail \
|
||||
|
Reference in New Issue
Block a user