diff options
author | Dan Vrátil <dvratil@redhat.com> | 2015-02-08 12:02:04 +0100 |
---|---|---|
committer | Dan Vrátil <dvratil@redhat.com> | 2015-02-09 14:33:45 +0100 |
commit | adc6a443776820b5ae36c982baf92b1d29bbaa4b (patch) | |
tree | ed278ffbcd8fc8c3759fbcc4afd4240fc1a72fc3 /async/autotests/asynctest.cpp | |
parent | cbb192ffe865ffb3eed4c940177ffecaecfa570f (diff) | |
download | sink-adc6a443776820b5ae36c982baf92b1d29bbaa4b.tar.gz sink-adc6a443776820b5ae36c982baf92b1d29bbaa4b.zip |
Async: introduce sync executors
Sync executors don't pass Async::Future into the user-provided tasks, but
instead work with return values of the task methods, wrapping them into the
Async::Future internally. Sync tasks are of course possible since forever, but
not the API for those tasks is much cleaner, for users don't have to deal with
"future" in synchronous tasks, for instance when synchronously processing results
of an async task before passing the data to another async task.
Diffstat (limited to 'async/autotests/asynctest.cpp')
-rw-r--r-- | async/autotests/asynctest.cpp | 138 |
1 files changed, 127 insertions, 11 deletions
diff --git a/async/autotests/asynctest.cpp b/async/autotests/asynctest.cpp index 9240d28..4ebe65e 100644 --- a/async/autotests/asynctest.cpp +++ b/async/autotests/asynctest.cpp | |||
@@ -42,9 +42,14 @@ private Q_SLOTS: | |||
42 | void testAsyncPromises(); | 42 | void testAsyncPromises(); |
43 | void testAsyncPromises2(); | 43 | void testAsyncPromises2(); |
44 | void testNestedAsync(); | 44 | void testNestedAsync(); |
45 | void testAsyncThen(); | ||
46 | void testSyncThen(); | ||
47 | void testAsyncEach(); | ||
45 | void testSyncEach(); | 48 | void testSyncEach(); |
49 | void testAsyncReduce(); | ||
46 | void testSyncReduce(); | 50 | void testSyncReduce(); |
47 | void testErrorHandler(); | 51 | void testErrorHandler(); |
52 | |||
48 | }; | 53 | }; |
49 | 54 | ||
50 | void AsyncTest::testSyncPromises() | 55 | void AsyncTest::testSyncPromises() |
@@ -155,17 +160,92 @@ void AsyncTest::testNestedAsync() | |||
155 | QTRY_VERIFY(done); | 160 | QTRY_VERIFY(done); |
156 | } | 161 | } |
157 | 162 | ||
158 | void AsyncTest::testSyncEach() | 163 | void AsyncTest::testAsyncThen() |
164 | { | ||
165 | auto job = Async::start<int>( | ||
166 | [](Async::Future<int> &future) { | ||
167 | QTimer *timer = new QTimer; | ||
168 | QObject::connect(timer, &QTimer::timeout, | ||
169 | [&]() { | ||
170 | future.setValue(42); | ||
171 | future.setFinished(); | ||
172 | }); | ||
173 | QObject::connect(timer, &QTimer::timeout, | ||
174 | timer, &QObject::deleteLater); | ||
175 | timer->setSingleShot(true); | ||
176 | timer->start(0); | ||
177 | }); | ||
178 | |||
179 | auto future = job.exec(); | ||
180 | future.waitForFinished(); | ||
181 | |||
182 | QVERIFY(future.isFinished()); | ||
183 | QCOMPARE(future.value(), 42); | ||
184 | } | ||
185 | |||
186 | |||
187 | void AsyncTest::testSyncThen() | ||
188 | { | ||
189 | auto job = Async::start<int>( | ||
190 | []() -> int { | ||
191 | return 42; | ||
192 | }).then<int, int>( | ||
193 | [](int in) -> int { | ||
194 | return in * 2; | ||
195 | }); | ||
196 | |||
197 | auto future = job.exec(); | ||
198 | QVERIFY(future.isFinished()); | ||
199 | QCOMPARE(future.value(), 84); | ||
200 | } | ||
201 | |||
202 | void AsyncTest::testAsyncEach() | ||
159 | { | 203 | { |
160 | auto job = Async::start<QList<int>>( | 204 | auto job = Async::start<QList<int>>( |
161 | [](Async::Future<QList<int>> &future) { | 205 | [](Async::Future<QList<int>> &future) { |
162 | future.setValue(QList<int>{ 1, 2, 3, 4 }); | 206 | QTimer *timer = new QTimer; |
163 | future.setFinished(); | 207 | QObject::connect(timer, &QTimer::timeout, |
208 | [&future]() { | ||
209 | future.setValue({ 1, 2, 3, 4 }); | ||
210 | future.setFinished(); | ||
211 | }); | ||
212 | QObject::connect(timer, &QTimer::timeout, | ||
213 | timer, &QObject::deleteLater); | ||
214 | timer->setSingleShot(true); | ||
215 | timer->start(0); | ||
164 | }) | 216 | }) |
165 | .each<QList<int>, int>( | 217 | .each<QList<int>, int>( |
166 | [](const int &v, Async::Future<QList<int>> &future) { | 218 | [](const int &v, Async::Future<QList<int>> &future) { |
167 | future.setValue(QList<int>{ v + 1 }); | 219 | QTimer *timer = new QTimer; |
168 | future.setFinished(); | 220 | QObject::connect(timer, &QTimer::timeout, |
221 | [v, &future]() { | ||
222 | future.setValue({ v + 1 }); | ||
223 | future.setFinished(); | ||
224 | }); | ||
225 | QObject::connect(timer, &QTimer::timeout, | ||
226 | timer, &QObject::deleteLater); | ||
227 | timer->setSingleShot(true); | ||
228 | timer->start(0); | ||
229 | }); | ||
230 | |||
231 | auto future = job.exec(); | ||
232 | future.waitForFinished(); | ||
233 | |||
234 | const QList<int> expected({ 2, 3, 4, 5 }); | ||
235 | QVERIFY(future.isFinished()); | ||
236 | QCOMPARE(future.value(), expected); | ||
237 | } | ||
238 | |||
239 | |||
240 | void AsyncTest::testSyncEach() | ||
241 | { | ||
242 | auto job = Async::start<QList<int>>( | ||
243 | []() -> QList<int> { | ||
244 | return { 1, 2, 3, 4 }; | ||
245 | }) | ||
246 | .each<QList<int>, int>( | ||
247 | [](const int &v) -> QList<int> { | ||
248 | return { v + 1 }; | ||
169 | }); | 249 | }); |
170 | 250 | ||
171 | Async::Future<QList<int>> future = job.exec(); | 251 | Async::Future<QList<int>> future = job.exec(); |
@@ -175,19 +255,55 @@ void AsyncTest::testSyncEach() | |||
175 | QCOMPARE(future.value(), expected); | 255 | QCOMPARE(future.value(), expected); |
176 | } | 256 | } |
177 | 257 | ||
178 | void AsyncTest::testSyncReduce() | 258 | void AsyncTest::testAsyncReduce() |
179 | { | 259 | { |
180 | auto job = Async::start<QList<int>>( | 260 | auto job = Async::start<QList<int>>( |
181 | [](Async::Future<QList<int>> &future) { | 261 | [](Async::Future<QList<int>> &future) { |
182 | future.setValue(QList<int>{ 1, 2, 3, 4 }); | 262 | QTimer *timer = new QTimer(); |
183 | future.setFinished(); | 263 | QObject::connect(timer, &QTimer::timeout, |
264 | [&future]() { | ||
265 | future.setValue({ 1, 2, 3, 4 }); | ||
266 | future.setFinished(); | ||
267 | }); | ||
268 | QObject::connect(timer, &QTimer::timeout, | ||
269 | timer, &QObject::deleteLater); | ||
270 | timer->setSingleShot(true); | ||
271 | timer->start(0); | ||
184 | }) | 272 | }) |
185 | .reduce<int, QList<int>>( | 273 | .reduce<int, QList<int>>( |
186 | [](const QList<int> &list, Async::Future<int> &future) { | 274 | [](const QList<int> &list, Async::Future<int> &future) { |
275 | QTimer *timer = new QTimer(); | ||
276 | QObject::connect(timer, &QTimer::timeout, | ||
277 | [list, &future]() { | ||
278 | int sum = 0; | ||
279 | for (int i : list) sum += i; | ||
280 | future.setValue(sum); | ||
281 | future.setFinished(); | ||
282 | }); | ||
283 | QObject::connect(timer, &QTimer::timeout, | ||
284 | timer, &QObject::deleteLater); | ||
285 | timer->setSingleShot(true); | ||
286 | timer->start(0); | ||
287 | }); | ||
288 | |||
289 | Async::Future<int> future = job.exec(); | ||
290 | future.waitForFinished(); | ||
291 | |||
292 | QVERIFY(future.isFinished()); | ||
293 | QCOMPARE(future.value(), 10); | ||
294 | } | ||
295 | |||
296 | void AsyncTest::testSyncReduce() | ||
297 | { | ||
298 | auto job = Async::start<QList<int>>( | ||
299 | []() -> QList<int> { | ||
300 | return { 1, 2, 3, 4 }; | ||
301 | }) | ||
302 | .reduce<int, QList<int>>( | ||
303 | [](const QList<int> &list) -> int { | ||
187 | int sum = 0; | 304 | int sum = 0; |
188 | for (int i : list) sum += i; | 305 | for (int i : list) sum += i; |
189 | future.setValue(sum); | 306 | return sum; |
190 | future.setFinished(); | ||
191 | }); | 307 | }); |
192 | 308 | ||
193 | Async::Future<int> future = job.exec(); | 309 | Async::Future<int> future = job.exec(); |
@@ -213,7 +329,7 @@ void AsyncTest::testErrorHandler() | |||
213 | ); | 329 | ); |
214 | auto future = job.exec(); | 330 | auto future = job.exec(); |
215 | future.waitForFinished(); | 331 | future.waitForFinished(); |
216 | QVERIFY(error == 1); | 332 | QCOMPARE(error, 1); |
217 | QVERIFY(future.isFinished()); | 333 | QVERIFY(future.isFinished()); |
218 | } | 334 | } |
219 | 335 | ||