tst_all.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /*
  2. * Copyright (c) Simon Brunel, https://github.com/simonbrunel
  3. *
  4. * This source code is licensed under the MIT license found in
  5. * the LICENSE file in the root directory of this source tree.
  6. */
  7. #include "../shared/utils.h"
  8. #include <QtPromise>
  9. #include <QtTest>
  10. class tst_helpers_all : public QObject
  11. {
  12. Q_OBJECT
  13. private Q_SLOTS:
  14. void emptySequence();
  15. void emptySequence_void();
  16. void allPromisesSucceed();
  17. void allPromisesSucceed_void();
  18. void atLeastOnePromiseReject();
  19. void atLeastOnePromiseReject_void();
  20. void preserveOrder();
  21. void sequenceTypes();
  22. void sequenceTypes_void();
  23. };
  24. QTEST_MAIN(tst_helpers_all)
  25. #include "tst_all.moc"
  26. namespace {
  27. template<class Sequence>
  28. struct SequenceTester
  29. {
  30. Q_STATIC_ASSERT((std::is_same<typename Sequence::value_type, QtPromise::QPromise<int>>::value));
  31. static void exec()
  32. {
  33. Sequence promises{QtPromise::resolve(42), QtPromise::resolve(43), QtPromise::resolve(44)};
  34. promises.push_back(QtPromise::resolve(45));
  35. promises.insert(++promises.begin(), QtPromise::resolve(46));
  36. promises.pop_back();
  37. auto p = QtPromise::all(promises);
  38. Q_STATIC_ASSERT((std::is_same<decltype(p), QtPromise::QPromise<QVector<int>>>::value));
  39. QCOMPARE(p.isPending(), true);
  40. QCOMPARE(waitForValue(p, QVector<int>{}), (QVector<int>{42, 46, 43, 44}));
  41. }
  42. };
  43. template<template<typename, typename...> class Sequence, typename... Args>
  44. struct SequenceTester<Sequence<QtPromise::QPromise<void>, Args...>>
  45. {
  46. static void exec()
  47. {
  48. Sequence<QtPromise::QPromise<void>, Args...> promises{QtPromise::resolve(),
  49. QtPromise::resolve(),
  50. QtPromise::resolve()};
  51. promises.push_back(QtPromise::resolve());
  52. promises.insert(++promises.begin(), QtPromise::resolve());
  53. promises.pop_back();
  54. auto p = QtPromise::all(promises);
  55. Q_STATIC_ASSERT((std::is_same<decltype(p), QtPromise::QPromise<void>>::value));
  56. QCOMPARE(p.isPending(), true);
  57. QCOMPARE(waitForValue(p, -1, 42), 42);
  58. }
  59. };
  60. } // anonymous namespace
  61. void tst_helpers_all::emptySequence()
  62. {
  63. auto p = QtPromise::all(QVector<QtPromise::QPromise<int>>());
  64. Q_STATIC_ASSERT((std::is_same<decltype(p), QtPromise::QPromise<QVector<int>>>::value));
  65. QCOMPARE(p.isFulfilled(), true);
  66. QCOMPARE(waitForValue(p, QVector<int>{}), QVector<int>{});
  67. }
  68. void tst_helpers_all::emptySequence_void()
  69. {
  70. auto p = QtPromise::all(QVector<QtPromise::QPromise<void>>());
  71. Q_STATIC_ASSERT((std::is_same<decltype(p), QtPromise::QPromise<void>>::value));
  72. QCOMPARE(p.isFulfilled(), true);
  73. QCOMPARE(waitForValue(p, -1, 42), 42);
  74. }
  75. void tst_helpers_all::allPromisesSucceed()
  76. {
  77. auto p0 = QtPromise::resolve(42);
  78. auto p1 = QtPromise::resolve(44);
  79. auto p2 = QtPromise::QPromise<int>{[](const QtPromise::QPromiseResolve<int>& resolve) {
  80. QtPromisePrivate::qtpromise_defer([=]() {
  81. resolve(43);
  82. });
  83. }};
  84. auto p = QtPromise::all(QVector<QtPromise::QPromise<int>>{p0, p2, p1});
  85. Q_STATIC_ASSERT((std::is_same<decltype(p), QtPromise::QPromise<QVector<int>>>::value));
  86. QCOMPARE(p0.isFulfilled(), true);
  87. QCOMPARE(p1.isFulfilled(), true);
  88. QCOMPARE(p2.isPending(), true);
  89. QCOMPARE(p.isPending(), true);
  90. QCOMPARE(waitForValue(p, QVector<int>{}), (QVector<int>{42, 43, 44}));
  91. QCOMPARE(p2.isFulfilled(), true);
  92. }
  93. void tst_helpers_all::allPromisesSucceed_void()
  94. {
  95. auto p0 = QtPromise::resolve();
  96. auto p1 = QtPromise::resolve();
  97. auto p2 = QtPromise::QPromise<void>{[](const QtPromise::QPromiseResolve<void>& resolve) {
  98. QtPromisePrivate::qtpromise_defer([=]() {
  99. resolve();
  100. });
  101. }};
  102. auto p = QtPromise::all(QVector<QtPromise::QPromise<void>>{p0, p2, p1});
  103. Q_STATIC_ASSERT((std::is_same<decltype(p), QtPromise::QPromise<void>>::value));
  104. QCOMPARE(p0.isFulfilled(), true);
  105. QCOMPARE(p1.isFulfilled(), true);
  106. QCOMPARE(p2.isPending(), true);
  107. QCOMPARE(p.isPending(), true);
  108. QCOMPARE(waitForValue(p, -1, 42), 42);
  109. QCOMPARE(p2.isFulfilled(), true);
  110. }
  111. void tst_helpers_all::atLeastOnePromiseReject()
  112. {
  113. auto p0 = QtPromise::resolve(42);
  114. auto p1 = QtPromise::resolve(44);
  115. auto p2 = QtPromise::QPromise<int>{
  116. [](const QtPromise::QPromiseResolve<int>&, const QtPromise::QPromiseReject<int>& reject) {
  117. QtPromisePrivate::qtpromise_defer([=]() {
  118. reject(QString{"foo"});
  119. });
  120. }};
  121. auto p = QtPromise::all(QVector<QtPromise::QPromise<int>>{p0, p2, p1});
  122. Q_STATIC_ASSERT((std::is_same<decltype(p), QtPromise::QPromise<QVector<int>>>::value));
  123. QCOMPARE(p0.isFulfilled(), true);
  124. QCOMPARE(p1.isFulfilled(), true);
  125. QCOMPARE(p2.isPending(), true);
  126. QCOMPARE(p.isPending(), true);
  127. QCOMPARE(waitForError(p, QString{}), QString{"foo"});
  128. QCOMPARE(p2.isRejected(), true);
  129. }
  130. void tst_helpers_all::atLeastOnePromiseReject_void()
  131. {
  132. auto p0 = QtPromise::resolve();
  133. auto p1 = QtPromise::resolve();
  134. auto p2 = QtPromise::QPromise<void>{
  135. [](const QtPromise::QPromiseResolve<void>&, const QtPromise::QPromiseReject<void>& reject) {
  136. QtPromisePrivate::qtpromise_defer([=]() {
  137. reject(QString{"foo"});
  138. });
  139. }};
  140. auto p = QtPromise::all(QVector<QtPromise::QPromise<void>>{p0, p2, p1});
  141. Q_STATIC_ASSERT((std::is_same<decltype(p), QtPromise::QPromise<void>>::value));
  142. QCOMPARE(p0.isFulfilled(), true);
  143. QCOMPARE(p1.isFulfilled(), true);
  144. QCOMPARE(p2.isPending(), true);
  145. QCOMPARE(p.isPending(), true);
  146. QCOMPARE(waitForError(p, QString{}), QString{"foo"});
  147. QCOMPARE(p2.isRejected(), true);
  148. }
  149. void tst_helpers_all::preserveOrder()
  150. {
  151. auto p0 = QtPromise::resolve(42).delay(500);
  152. auto p1 = QtPromise::resolve(43).delay(100);
  153. auto p2 = QtPromise::resolve(44).delay(250);
  154. auto p = QtPromise::all(QVector<QtPromise::QPromise<int>>{p0, p1, p2});
  155. Q_STATIC_ASSERT((std::is_same<decltype(p), QtPromise::QPromise<QVector<int>>>::value));
  156. QCOMPARE(p0.isPending(), true);
  157. QCOMPARE(p1.isPending(), true);
  158. QCOMPARE(p2.isPending(), true);
  159. QCOMPARE(p.isPending(), true);
  160. QCOMPARE(waitForValue(p, QVector<int>{}), (QVector<int>{42, 43, 44}));
  161. QCOMPARE(p0.isFulfilled(), true);
  162. QCOMPARE(p1.isFulfilled(), true);
  163. QCOMPARE(p2.isFulfilled(), true);
  164. }
  165. // QVector::push_back/append isn't supported since it requires a default
  166. // constructor (see https://github.com/simonbrunel/qtpromise/issues/3)
  167. void tst_helpers_all::sequenceTypes()
  168. {
  169. SequenceTester<QList<QtPromise::QPromise<int>>>::exec();
  170. // SequenceTester<QVector<QPromise<int>>>::exec();
  171. SequenceTester<std::list<QtPromise::QPromise<int>>>::exec();
  172. SequenceTester<std::vector<QtPromise::QPromise<int>>>::exec();
  173. }
  174. void tst_helpers_all::sequenceTypes_void()
  175. {
  176. SequenceTester<QList<QtPromise::QPromise<void>>>::exec();
  177. // SequenceTester<QVector<QPromise<void>>>::exec();
  178. SequenceTester<std::list<QtPromise::QPromise<void>>>::exec();
  179. SequenceTester<std::vector<QtPromise::QPromise<void>>>::exec();
  180. }