@qooxdoo/framework 7.8.0 → 7.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/Manifest.json +2 -2
  2. package/lib/compiler/compile-info.json +72 -70
  3. package/lib/compiler/index.js +2255 -1385
  4. package/lib/resource/qx/tool/website/build/404.html +3 -25
  5. package/lib/resource/qx/tool/website/build/about.html +3 -25
  6. package/lib/resource/qx/tool/website/build/assets/common.js +20 -0
  7. package/lib/resource/qx/tool/website/build/diagnostics/dependson.html +3 -25
  8. package/lib/resource/qx/tool/website/build/diagnostics/requiredby.html +3 -22
  9. package/lib/resource/qx/tool/website/build/index.html +3 -25
  10. package/lib/resource/qx/tool/website/partials/footer.html +3 -21
  11. package/lib/resource/qx/tool/website/partials/head.html +0 -1
  12. package/package.json +2 -1
  13. package/source/class/qx/Bootstrap.js +6 -3
  14. package/source/class/qx/Promise.js +93 -6964
  15. package/source/class/qx/core/Environment.js +1 -0
  16. package/source/class/qx/data/marshal/Json.js +64 -11
  17. package/source/class/qx/event/handler/TouchCore.js +3 -1
  18. package/source/class/qx/lang/Type.js +36 -3
  19. package/source/class/qx/promise/BluebirdImpl.js +6918 -0
  20. package/source/class/qx/promise/NativeWrapper.js +738 -0
  21. package/source/class/qx/test/Promise.js +1145 -22
  22. package/source/class/qx/test/data/controller/List.js +6 -0
  23. package/source/class/qx/test/data/marshal/Json.js +29 -0
  24. package/source/class/qx/test/io/request/Xhr.js +16 -0
  25. package/source/class/qx/test/lang/Type.js +151 -0
  26. package/source/class/qx/theme/indigo/ColorDark.js +1 -1
  27. package/source/class/qx/ui/core/MPlacement.js +18 -7
  28. package/source/class/qx/ui/table/pane/Scroller.js +1 -1
  29. package/source/class/qx/util/ConcurrencyLimiter.js +78 -0
  30. package/source/resource/qx/tool/website/build/404.html +3 -25
  31. package/source/resource/qx/tool/website/build/about.html +3 -25
  32. package/source/resource/qx/tool/website/build/assets/common.js +20 -0
  33. package/source/resource/qx/tool/website/build/diagnostics/dependson.html +3 -25
  34. package/source/resource/qx/tool/website/build/diagnostics/requiredby.html +3 -22
  35. package/source/resource/qx/tool/website/build/index.html +3 -25
  36. package/source/resource/qx/tool/website/partials/footer.html +3 -21
  37. package/source/resource/qx/tool/website/partials/head.html +0 -1
  38. package/lib/resource/qx/tool/website/build/assets/bluebird.min.js +0 -4615
  39. package/lib/resource/qx/tool/website/src/assets/bluebird.min.js +0 -4615
  40. package/source/resource/qx/tool/website/build/assets/bluebird.min.js +0 -4615
  41. package/source/resource/qx/tool/website/src/assets/bluebird.min.js +0 -4615
@@ -2,6 +2,18 @@ qx.Class.define("qx.test.Promise", {
2
2
  extend: qx.dev.unit.TestCase,
3
3
 
4
4
  members: {
5
+ /**
6
+ * Tests the isPromise method
7
+ */
8
+ testIsPromise() {
9
+ var p = new qx.Promise(function () {});
10
+ this.assertTrue(qx.Promise.isPromise(p));
11
+ this.assertFalse(qx.Promise.isPromise(null));
12
+ this.assertFalse(qx.Promise.isPromise({}));
13
+ this.assertTrue(qx.Promise.isPromise(qx.Promise.resolve()));
14
+ this.assertTrue(qx.Promise.isPromise(Promise.resolve()));
15
+ this.assertTrue(qx.Promise.isPromise({ then: function () {} }));
16
+ },
5
17
  /**
6
18
  * Tests a new promise that resolves with no errors
7
19
  */
@@ -52,8 +64,332 @@ qx.Class.define("qx.test.Promise", {
52
64
  this.wait(1000);
53
65
  },
54
66
 
67
+ /**
68
+ * Tests promise being rejected externally using `reject` method
69
+ * Also tests binding catch
70
+ */
71
+ testExternalReject() {
72
+ var promise = new qx.Promise();
73
+ promise.catch(function (e) {
74
+ this.assertEquals("oops", e.message);
75
+ setTimeout(() => this.resume(), 1);
76
+ }, this);
77
+ promise.reject(new Error("oops"));
78
+ this.wait(1000);
79
+ },
80
+
81
+ /**
82
+ * Tests that cancelling promise will cause `then` and `catch` to not be called
83
+ * (finally must be called)
84
+ */
85
+ testCancel1() {
86
+ if (qx.core.Environment.get("qx.Promise.useNativePromise")) {
87
+ console.warn(
88
+ "Skipping test because the native promise implementation of qx.Promise does not support cancellation"
89
+ );
90
+ return;
91
+ } else {
92
+ let promise = new qx.Promise((resolve, reject) => {
93
+ setTimeout(() => {
94
+ resolve();
95
+ }, 500);
96
+ });
97
+ promise
98
+ .then(() => this.fail("Should not call!"))
99
+ .then(() => this.fail("Should not call!"));
100
+
101
+ promise.catch(() => {
102
+ this.fail("Should not call!");
103
+ });
104
+
105
+ let output = "";
106
+
107
+ promise
108
+ .then(
109
+ () => new qx.Promise((resolve, reject) => reject(new Error("oops")))
110
+ )
111
+ .catch(() => this.fail("Should not call!"))
112
+ .finally(() => {
113
+ output += "1";
114
+ })
115
+ .then(() => {
116
+ this.fail("Should not call!");
117
+ });
118
+
119
+ let f = promise.finally(() => {
120
+ setTimeout(() => {
121
+ output += "2";
122
+ this.assertEquals("12", output);
123
+ this.resume();
124
+ }, 100);
125
+ });
126
+ this.assertInstance(f, qx.Promise);
127
+ promise.cancel();
128
+ this.wait(1000);
129
+ }
130
+ },
131
+
132
+ /**
133
+ * Ensures that non of the handlers in the chain are called when a promise is cancelled immediately
134
+ */
135
+ testCancel2() {
136
+ if (qx.core.Environment.get("qx.Promise.useNativePromise")) {
137
+ console.warn(
138
+ "Skipping test because the native promise implementation of qx.Promise does not support cancellation"
139
+ );
140
+ return;
141
+ } else {
142
+ let output = "";
143
+ let promise = qx.Promise.resolve()
144
+ .then(
145
+ () =>
146
+ new qx.Promise(resolve => {
147
+ output += "1";
148
+ setTimeout(resolve, 100);
149
+ })
150
+ )
151
+ .then(
152
+ () =>
153
+ new qx.Promise(resolve => {
154
+ output += "2";
155
+ setTimeout(resolve, 100);
156
+ })
157
+ )
158
+ .then(
159
+ () =>
160
+ new qx.Promise(resolve => {
161
+ output += "3";
162
+ setTimeout(resolve, 100);
163
+ })
164
+ )
165
+ .finally(() => {
166
+ this.assertEquals("", output);
167
+ this.resume();
168
+ });
169
+
170
+ promise.cancel();
171
+ this.wait(1000);
172
+ }
173
+ },
174
+
175
+ /**
176
+ * Ensures that the promise chain does not continue after a promise is cancelled, except ALL the `finally` calls
177
+ * which are both ancestors and descendants of the cancelled promise, which have not been called yet.
178
+
179
+ */
180
+ testCancel3() {
181
+ if (qx.core.Environment.get("qx.Promise.useNativePromise")) {
182
+ console.warn(
183
+ "Skipping test because the native promise implementation of qx.Promise does not support cancellation"
184
+ );
185
+ return;
186
+ } else {
187
+ let output = "";
188
+ let promise = qx.Promise.resolve()
189
+ .then(
190
+ () =>
191
+ new qx.Promise(resolve => {
192
+ output += "1";
193
+ setTimeout(resolve, 100);
194
+ })
195
+ )
196
+ .then(
197
+ () =>
198
+ new qx.Promise(resolve => {
199
+ output += "2";
200
+ setTimeout(resolve, 100);
201
+ setTimeout(() => promise.cancel(), 150);
202
+ })
203
+ )
204
+ .finally(() => {
205
+ if (output.at(-1) !== "2") {
206
+ this.fail("finally called twice!");
207
+ }
208
+ output += "3";
209
+ })
210
+ .then(
211
+ () =>
212
+ new qx.Promise(resolve => {
213
+ output += "4";
214
+ setTimeout(resolve, 100);
215
+ })
216
+ )
217
+ .then(
218
+ () =>
219
+ new qx.Promise(resolve => {
220
+ this.fail("Should not call!");
221
+ })
222
+ )
223
+ .finally(() => {
224
+ output += "5";
225
+ })
226
+ .then(() => this.fail("should not call!"))
227
+ .finally(() => {
228
+ output += "6";
229
+ });
230
+
231
+ let promise2 = promise
232
+ .then(() => this.fail("should not call!"))
233
+ .finally(() => {
234
+ output += "7";
235
+ })
236
+ .then(() => this.fail("should not call!"))
237
+ .finally(() => {
238
+ output += "8";
239
+ this.assertEquals("12345678", output);
240
+ this.resume();
241
+ });
242
+
243
+ this.wait(1000);
244
+ }
245
+ },
246
+
247
+ /**
248
+ * Tests that cancelling a promise will not stop its chain from executing if there are promises which depend on some stages in the chain
249
+ */
250
+ testCancel4() {
251
+ if (qx.core.Environment.get("qx.Promise.useNativePromise")) {
252
+ console.warn(
253
+ "Skipping test because the native promise implementation of qx.Promise does not support cancellation"
254
+ );
255
+ return;
256
+ } else {
257
+ let output = "";
258
+ let promise1 = qx.Promise.resolve().then(() => {
259
+ output += "1";
260
+ });
261
+
262
+ let branch1 = promise1.then(() => {
263
+ output += "2";
264
+ });
265
+ let branch2 = promise1
266
+ .then(() => (output += "3"))
267
+ .finally(() => {
268
+ setTimeout(() => {
269
+ this.assertEquals("13", output);
270
+ this.resume();
271
+ }, 100);
272
+ });
273
+
274
+ branch1.cancel();
275
+ this.wait(1000);
276
+ }
277
+ },
278
+
279
+ /**
280
+ * Ensures exception is thrown when trying to call `then` for a promise which has already been cancelled.
281
+ */
282
+ testThenAfterCancel() {
283
+ if (qx.core.Environment.get("qx.Promise.useNativePromise")) {
284
+ console.warn(
285
+ "Skipping test because the native promise implementation of qx.Promise does not support cancellation"
286
+ );
287
+ return;
288
+ } else {
289
+ let promise = new qx.Promise((resolve, reject) => {
290
+ setTimeout(() => {
291
+ resolve();
292
+ }, 300);
293
+ });
294
+ promise.cancel();
295
+ promise
296
+ .then(() => this.fail("Should not call!"))
297
+ .catch(e => {
298
+ this.assertEquals("late cancellation observer", e.message);
299
+ setTimeout(this.resume(), 1);
300
+ });
301
+
302
+ this.wait(1000);
303
+ }
304
+ },
305
+
306
+ /**
307
+ * Ensures exception is thrown when trying to call `catch` for a promise which has already been cancelled.
308
+ */
309
+ testCatchAfterCancel() {
310
+ if (qx.core.Environment.get("qx.Promise.useNativePromise")) {
311
+ console.warn(
312
+ "Skipping test because the native promise implementation of qx.Promise does not support cancellation"
313
+ );
314
+ return;
315
+ } else {
316
+ let promise = new qx.Promise((resolve, reject) => {
317
+ setTimeout(() => {
318
+ resolve();
319
+ }, 300);
320
+ });
321
+ promise.cancel();
322
+ promise
323
+ .then(() => {
324
+ this.fail("Should not call!");
325
+ })
326
+ .catch(e => {
327
+ this.assertEquals("late cancellation observer", e.message);
328
+ setTimeout(() => this.resume(), 1);
329
+ });
330
+
331
+ this.wait(1000);
332
+ }
333
+ },
334
+
335
+ /**
336
+ * Ensures exception is thrown when trying to call `finally` for a promise which has already been cancelled.
337
+ */
338
+ testFinallyAfterCancel() {
339
+ if (qx.core.Environment.get("qx.Promise.useNativePromise")) {
340
+ console.warn(
341
+ "Skipping test because the native promise implementation of qx.Promise does not support cancellation"
342
+ );
343
+ return;
344
+ } else {
345
+ let promise = new qx.Promise((resolve, reject) => {
346
+ setTimeout(() => {
347
+ resolve();
348
+ }, 300);
349
+ });
350
+ promise.cancel();
351
+ promise
352
+ .then(() => {
353
+ this.fail("Should not call!");
354
+ })
355
+ .catch(e => {
356
+ this.assertEquals("late cancellation observer", e.message);
357
+ setTimeout(() => this.resume(), 1);
358
+ });
359
+
360
+ this.wait(1000);
361
+ }
362
+ },
363
+
364
+ /**
365
+ * Ensures a promise can still be cancelled after it has been settled
366
+ */
367
+ testCancelAfterSettled() {
368
+ if (qx.core.Environment.get("qx.Promise.useNativePromise")) {
369
+ console.warn(
370
+ "Skipping test because the native promise implementation of qx.Promise does not support cancellation"
371
+ );
372
+ return;
373
+ } else {
374
+ let promise = qx.Promise.resolve();
375
+ promise
376
+ .then(() => {
377
+ promise.cancel();
378
+ })
379
+ .then(() => {
380
+ setTimeout(() => this.resume(), 1);
381
+ });
382
+
383
+ this.wait(1000);
384
+ }
385
+ },
386
+
387
+ /**
388
+ * Ensures that `finally` is run when the promise rejects
389
+ */
55
390
  testCatchFinally() {
56
391
  var caughtException = null;
392
+ var t = this;
57
393
  qx.Promise.resolve()
58
394
  .then(function () {
59
395
  throw new Error("oops");
@@ -63,11 +399,59 @@ qx.Class.define("qx.test.Promise", {
63
399
  })
64
400
  .finally(function () {
65
401
  this.assertNotNull(caughtException);
66
- this.resume();
402
+ this.assertIdentical(this, t);
403
+ setTimeout(() => this.resume(), 1);
67
404
  }, this);
68
405
  this.wait(1000);
69
406
  },
70
407
 
408
+ /**
409
+ * Tests that the `promisify` method works for operations functions.
410
+ * Also ensures the return value of `.then` is a qx.Promise
411
+ */
412
+ testPromisifyResolve() {
413
+ function feedMe(fruit, callback) {
414
+ setTimeout(function () {
415
+ if (fruit == "raspberry") {
416
+ callback(null, "That's nice");
417
+ } else {
418
+ callback(new Error("No thank you!"), null);
419
+ }
420
+ }, 100);
421
+ }
422
+
423
+ let feedMeAsync = qx.Promise.promisify(feedMe);
424
+
425
+ feedMeAsync("raspberry").then(value => {
426
+ this.assertEquals("That's nice", value);
427
+ this.resume();
428
+ });
429
+ this.wait(1000);
430
+ },
431
+
432
+ /**
433
+ * Tests that the `promisify` method works for unsuccessful operations
434
+ */
435
+ testPromisifyReject() {
436
+ function feedMe(fruit, callback) {
437
+ setTimeout(function () {
438
+ if (fruit == "raspberry") {
439
+ callback(null, "That's nice");
440
+ } else {
441
+ callback(new Error("No thank you!"), null);
442
+ }
443
+ }, 100);
444
+ }
445
+
446
+ let feedMeAsync = qx.Promise.promisify(feedMe);
447
+
448
+ feedMeAsync("ping pong balls").catch(err => {
449
+ this.assertEquals("No thank you!", err.message);
450
+ this.resume();
451
+ });
452
+ this.wait(1000);
453
+ },
454
+
71
455
  /**
72
456
  * Tests the qx.Promise.allOf method
73
457
  */
@@ -82,14 +466,16 @@ qx.Class.define("qx.test.Promise", {
82
466
  e: dt
83
467
  };
84
468
 
85
- qx.Promise.allOf(obj).then(function (obj2) {
469
+ let promise = qx.Promise.allOf(obj);
470
+ this.assertInstance(promise, qx.Promise);
471
+ promise.then(function (obj2) {
86
472
  t.assertTrue(obj === obj2);
87
473
  t.assertEquals("one", obj.a);
88
474
  t.assertEquals("two", obj.b);
89
475
  t.assertEquals("three", obj.c);
90
476
  t.assertEquals("four", obj.d);
91
477
  t.assertTrue(obj.e === dt);
92
- t.resume();
478
+ setTimeout(() => t.resume(), 1);
93
479
  });
94
480
  obj.a.then(function () {
95
481
  obj.b.resolve("two");
@@ -101,6 +487,51 @@ qx.Class.define("qx.test.Promise", {
101
487
  t.wait(1000);
102
488
  },
103
489
 
490
+ /**
491
+ * Checks that if one of the promises in the allOf array rejects,
492
+ * the overall result will reject
493
+ */
494
+ testAllOfReject() {
495
+ var t = this;
496
+ var obj = {
497
+ a: new qx.Promise(),
498
+ b: new qx.Promise()
499
+ };
500
+
501
+ qx.Promise.allOf(qx.Promise.resolve(obj)).catch(function (reason) {
502
+ t.assertEquals("two", reason.message);
503
+ setTimeout(() => t.resume(), 1);
504
+ });
505
+
506
+ obj.b.reject(new Error("two"));
507
+ obj.a.resolve("one");
508
+ t.wait(1000);
509
+ },
510
+
511
+ /**
512
+ * Tests the qx.Promise.allOf being passed a promise of an object instead of a straight value
513
+ */
514
+ testAllOfPromiseObj() {
515
+ var t = this;
516
+ var obj = {
517
+ a: new qx.Promise(),
518
+ b: new qx.Promise()
519
+ };
520
+
521
+ qx.Promise.allOf(qx.Promise.resolve(obj)).then(function (obj2) {
522
+ t.assertTrue(obj === obj2);
523
+ t.assertEquals("one", obj.a);
524
+ t.assertEquals("two", obj.b);
525
+
526
+ setTimeout(() => t.resume(), 1);
527
+ });
528
+ obj.a.then(function () {
529
+ obj.b.resolve("two");
530
+ });
531
+ obj.a.resolve("one");
532
+ t.wait(1000);
533
+ },
534
+
104
535
  /**
105
536
  * Tests that setting a property value with a promise will delay setting the
106
537
  * value until the promise is resolved. In this case, the property is *not*
@@ -128,7 +559,7 @@ qx.Class.define("qx.test.Promise", {
128
559
  p.then(function () {
129
560
  t.assertEquals(123, obj.getAlpha());
130
561
  qx.Class.undefine("testPropertySetValueAsPromise1.Clazz");
131
- t.resume();
562
+ setTimeout(() => t.resume(), 1);
132
563
  });
133
564
  this.wait(1000);
134
565
  },
@@ -160,7 +591,7 @@ qx.Class.define("qx.test.Promise", {
160
591
  obj.setAlphaAsync(p).then(function () {
161
592
  t.assertEquals(123, obj.getAlpha());
162
593
  qx.Class.undefine("testPropertySetValueAsPromise2.Clazz");
163
- t.resume();
594
+ setTimeout(() => t.resume(), 1);
164
595
  });
165
596
  this.wait(1000);
166
597
  },
@@ -623,7 +1054,7 @@ qx.Class.define("qx.test.Promise", {
623
1054
  },
624
1055
 
625
1056
  /**
626
- * Tests the each method of promise, using qx.data.Array which the Bluebird implementation
1057
+ * Tests the each method of promise, using qx.data.Array which the native Promise
627
1058
  * does not understand. The values are scalar values
628
1059
  */
629
1060
  testEach1() {
@@ -634,19 +1065,20 @@ qx.Class.define("qx.test.Promise", {
634
1065
  arr.push("c");
635
1066
  var str = "";
636
1067
  var promise = qx.Promise.resolve(arr);
637
- promise
638
- .forEach(function (item) {
639
- str += item;
640
- })
641
- .then(function () {
642
- t.assertEquals("abc", str);
643
- t.resume();
644
- });
1068
+ var forEachReturn = promise.forEach(function (item) {
1069
+ str += item;
1070
+ this.assertIdentical(t, this);
1071
+ }, this);
1072
+ forEachReturn.then(function () {
1073
+ t.assertEquals("abc", str);
1074
+ setTimeout(() => t.resume(), 1);
1075
+ });
1076
+ this.assertInstance(forEachReturn, qx.Promise);
645
1077
  t.wait(1000);
646
1078
  },
647
1079
 
648
1080
  /**
649
- * Tests the each method of promise, using qx.data.Array which the Bluebird implementation
1081
+ * Tests the each method of promise, using qx.data.Array which the native Promise
650
1082
  * does not understand. The values are a mixture of promises and scalar values
651
1083
  */
652
1084
  testEach2() {
@@ -693,6 +1125,39 @@ qx.Class.define("qx.test.Promise", {
693
1125
  t.wait(1000);
694
1126
  },
695
1127
 
1128
+ /**
1129
+ * Checks that the each method will reject if one of the promises in the array rejects
1130
+ */
1131
+ testEachReject() {
1132
+ let arr = [qx.Promise.resolve("a"), qx.Promise.reject(new Error("b"))];
1133
+
1134
+ var str = "";
1135
+ var promiseArr = qx.Promise.resolve(arr);
1136
+ var pEach = qx.Promise.forEach(promiseArr, function (item) {
1137
+ str += item;
1138
+ });
1139
+ pEach.catch(reason => {
1140
+ this.assertEquals("b", reason.message);
1141
+ setTimeout(() => this.resume(), 1);
1142
+ });
1143
+ this.wait(1000);
1144
+ },
1145
+
1146
+ /**
1147
+ * Tests the `each` method being passed with a promise of an array,
1148
+ * not a straight array
1149
+ */
1150
+ testEachPromiseArray() {
1151
+ var promiseArr = qx.Promise.resolve([1, 2, 3]);
1152
+
1153
+ qx.Promise.forEach(promiseArr, (item, index) => {
1154
+ this.assertEquals(index, item - 1);
1155
+ }).then(result => {
1156
+ setTimeout(() => this.resume(), 1);
1157
+ });
1158
+ this.wait(1000);
1159
+ },
1160
+
696
1161
  /**
697
1162
  * Tests unhandled rejections being passed to the global error handler
698
1163
  */
@@ -700,6 +1165,7 @@ qx.Class.define("qx.test.Promise", {
700
1165
  var t = this;
701
1166
  qx.event.GlobalError.setErrorHandler(function (ex) {
702
1167
  t.assertEquals(ex.message, "oops");
1168
+ qx.event.GlobalError.setErrorHandler(null);
703
1169
  t.resume();
704
1170
  });
705
1171
  var self = this;
@@ -726,7 +1192,7 @@ qx.Class.define("qx.test.Promise", {
726
1192
  this.assertInstance(promise, qx.Promise);
727
1193
  promise.then(function (value) {
728
1194
  t.assertEquals(value, "yes");
729
- t.resume();
1195
+ setTimeout(() => t.resume(), 1);
730
1196
  });
731
1197
  this.wait(1000);
732
1198
  },
@@ -739,7 +1205,7 @@ qx.Class.define("qx.test.Promise", {
739
1205
  var p = qx.Promise.resolve("hello").bind(this);
740
1206
  p.then(function (value) {
741
1207
  qx.core.Assert.assertIdentical(t, this);
742
- t.resume();
1208
+ setTimeout(() => this.resume(), 1);
743
1209
  });
744
1210
  this.wait(1000);
745
1211
  },
@@ -757,7 +1223,7 @@ qx.Class.define("qx.test.Promise", {
757
1223
  this
758
1224
  ).then(function (value) {
759
1225
  qx.core.Assert.assertIdentical(t, this);
760
- this.resume();
1226
+ setTimeout(() => this.resume(), 1);
761
1227
  }, this);
762
1228
  this.wait(1000);
763
1229
  },
@@ -775,7 +1241,7 @@ qx.Class.define("qx.test.Promise", {
775
1241
  var t = this;
776
1242
  qx.Promise.resolve(true).then(function () {
777
1243
  qx.core.Assert.assertIdentical(qx.Promise, this);
778
- t.resume();
1244
+ setTimeout(() => t.resume(), 1);
779
1245
  }, qx.Promise);
780
1246
  this.wait(1000);
781
1247
  },
@@ -787,7 +1253,7 @@ qx.Class.define("qx.test.Promise", {
787
1253
  var t = this;
788
1254
  qx.Promise.resolve(true, this).then(function () {
789
1255
  qx.core.Assert.assertIdentical(t, this);
790
- t.resume();
1256
+ setTimeout(() => this.resume(), 1);
791
1257
  });
792
1258
  this.wait(1000);
793
1259
  },
@@ -799,7 +1265,7 @@ qx.Class.define("qx.test.Promise", {
799
1265
  var t = this;
800
1266
  qx.Promise.reject(new Error("Dummy Error"), this).catch(function () {
801
1267
  qx.core.Assert.assertIdentical(t, this);
802
- t.resume();
1268
+ setTimeout(() => this.resume(), 1);
803
1269
  });
804
1270
  this.wait(1000);
805
1271
  },
@@ -819,8 +1285,665 @@ qx.Class.define("qx.test.Promise", {
819
1285
  t.assertEquals(str, "foo");
820
1286
  t.assertInstance(arr, qx.data.Array);
821
1287
  t.assertEquals(arr.join(""), "abc");
822
- t.resume();
1288
+ setTimeout(() => t.resume(), 1);
1289
+ });
1290
+ this.wait(1000);
1291
+ },
1292
+
1293
+ /**
1294
+ * Tests the `race` method when no promises in the array reject
1295
+ */
1296
+ testRaceResolve() {
1297
+ var promiseB = new qx.Promise(function (resolve) {
1298
+ setTimeout(function () {
1299
+ resolve("b");
1300
+ }, 200);
1301
+ });
1302
+ var promiseC = new qx.Promise(function (resolve) {
1303
+ setTimeout(function () {
1304
+ resolve("c");
1305
+ }, 100);
1306
+ });
1307
+ var promiseD = new qx.Promise(function (resolve) {
1308
+ setTimeout(function () {
1309
+ resolve("d");
1310
+ }, 300);
1311
+ });
1312
+ var arr = [promiseB, promiseC, promiseD];
1313
+ let promise = qx.Promise.resolve(arr).race();
1314
+ promise.then(val => {
1315
+ this.assertEquals("c", val);
1316
+ this.resume();
1317
+ });
1318
+ this.assertInstance(promise, qx.Promise);
1319
+ this.wait(1000);
1320
+ },
1321
+
1322
+ /**
1323
+ * Tests the `race` method when one promise in the array rejects
1324
+ */
1325
+ testRaceReject() {
1326
+ var promiseB = new qx.Promise(function (resolve) {
1327
+ setTimeout(function () {
1328
+ resolve("b");
1329
+ }, 200);
1330
+ });
1331
+ var promiseC = new qx.Promise(function (resolve, reject) {
1332
+ setTimeout(function () {
1333
+ reject(new Error("c"));
1334
+ }, 100);
1335
+ });
1336
+ var arr = new qx.data.Array([promiseB, promiseC]);
1337
+ qx.Promise.resolve(arr)
1338
+ .race()
1339
+ .then(val => {
1340
+ this.fail("Should not resolve");
1341
+ })
1342
+ .catch(err => {
1343
+ this.assertEquals("c", err.message);
1344
+ this.resume();
823
1345
  });
1346
+
1347
+ this.wait(1000);
1348
+ },
1349
+
1350
+ /**
1351
+ * Tests the `race` method when the array contains a straight (i.e. non-promise) value
1352
+ */
1353
+ testRaceStraightValue() {
1354
+ var promiseB = new qx.Promise(function (resolve) {
1355
+ setTimeout(function () {
1356
+ resolve("b");
1357
+ }, 200);
1358
+ });
1359
+ var arr = ["a", promiseB];
1360
+ qx.Promise.race(qx.Promise.resolve(arr)).then(val => {
1361
+ this.assertEquals("a", val);
1362
+ setTimeout(() => this.resume(), 1);
1363
+ });
1364
+
1365
+ this.wait(1000);
1366
+ },
1367
+
1368
+ /**
1369
+ * Tests the `any` method when all promises in the array resolve
1370
+ */
1371
+ testAnyResolve() {
1372
+ var promiseB = new qx.Promise(function (resolve) {
1373
+ setTimeout(function () {
1374
+ resolve("b");
1375
+ }, 200);
1376
+ });
1377
+ var promiseC = new qx.Promise(function (resolve) {
1378
+ setTimeout(function () {
1379
+ resolve("c");
1380
+ }, 100);
1381
+ });
1382
+ var promiseD = new qx.Promise(function (resolve) {
1383
+ setTimeout(function () {
1384
+ resolve("d");
1385
+ }, 300);
1386
+ });
1387
+ var arr = [promiseB, promiseC, promiseD];
1388
+ let promise = qx.Promise.resolve(arr).any();
1389
+ promise.then(val => {
1390
+ this.assertEquals("c", val);
1391
+ this.resume();
1392
+ });
1393
+ this.assertInstance(promise, qx.Promise);
1394
+ this.wait(1000);
1395
+ },
1396
+
1397
+ /**
1398
+ * Tests the `any` method when one promise in the array rejects.
1399
+ * The overall result should the result of the first promise that resolves
1400
+ */
1401
+ testAnyOneReject() {
1402
+ var promiseB = new qx.Promise(function (resolve) {
1403
+ setTimeout(function () {
1404
+ resolve("b");
1405
+ }, 200);
1406
+ });
1407
+ var promiseC = new qx.Promise(function (resolve, reject) {
1408
+ setTimeout(function () {
1409
+ reject(new Error("c"));
1410
+ }, 100);
1411
+ });
1412
+ var promiseD = new qx.Promise(function (resolve) {
1413
+ setTimeout(function () {
1414
+ resolve("d");
1415
+ }, 300);
1416
+ });
1417
+ var arr = new qx.data.Array([promiseB, promiseC, promiseD]);
1418
+ qx.Promise.any(qx.Promise.resolve(arr)).then(val => {
1419
+ this.assertEquals("b", val);
1420
+ this.resume();
1421
+ });
1422
+
1423
+ this.wait(1000);
1424
+ },
1425
+
1426
+ /**
1427
+ * Tests the `any` method when all promises in the array reject.
1428
+ */
1429
+ testAnyAllReject() {
1430
+ var promiseB = new qx.Promise(function (resolve, reject) {
1431
+ setTimeout(function () {
1432
+ reject(new Error("b"));
1433
+ }, 200);
1434
+ });
1435
+ var promiseC = new qx.Promise(function (resolve, reject) {
1436
+ setTimeout(function () {
1437
+ reject(new Error("c"));
1438
+ }, 100);
1439
+ });
1440
+ var promiseD = new qx.Promise(function (resolve, reject) {
1441
+ setTimeout(function () {
1442
+ reject(new Error("d"));
1443
+ }, 300);
1444
+ });
1445
+
1446
+ var arr = [promiseB, promiseC, promiseD];
1447
+ qx.Promise.resolve(arr)
1448
+ .any()
1449
+ .catch(aggErr => {
1450
+ this.resume();
1451
+ });
1452
+
1453
+ this.wait(1000);
1454
+ },
1455
+
1456
+ /**
1457
+ * Tests the `any` method when an empty array is passed in.
1458
+ */
1459
+ testAnyEmptyArray() {
1460
+ qx.Promise.resolve([])
1461
+ .any()
1462
+ .catch(aggErr => {
1463
+ setTimeout(() => this.resume(), 1);
1464
+ });
1465
+
1466
+ this.wait(1000);
1467
+ },
1468
+
1469
+ /**
1470
+ * Tests the `any` method when a straight (i.e. non-promise value) is passed in.
1471
+ * It should resolve to that value
1472
+ */
1473
+ testAnyStraightValue() {
1474
+ var promiseB = new qx.Promise(function (resolve) {
1475
+ setTimeout(function () {
1476
+ resolve("b");
1477
+ }, 200);
1478
+ });
1479
+ var arr = ["a", promiseB];
1480
+ qx.Promise.resolve(arr)
1481
+ .any()
1482
+ .then(val => {
1483
+ this.assertEquals("a", val);
1484
+ setTimeout(() => this.resume(), 1);
1485
+ });
1486
+
1487
+ this.wait(1000);
1488
+ },
1489
+
1490
+ /**
1491
+ * Tests that `reduce` succeeds when no promise rejects
1492
+ */
1493
+ testReduceResolve() {
1494
+ var promiseB = qx.Promise.resolve(1);
1495
+
1496
+ var promiseC = qx.Promise.resolve(2);
1497
+ var promiseD = qx.Promise.resolve(3);
1498
+ var arr = [promiseB, promiseC, promiseD];
1499
+ let promise = qx.Promise.resolve(arr).reduce(
1500
+ async (acc, item, index, length) => {
1501
+ this.assertEquals(index, item - 1);
1502
+ this.assertEquals(length, 3);
1503
+ return acc + item;
1504
+ },
1505
+ 0
1506
+ );
1507
+ promise.then(result => {
1508
+ this.assertEquals(6, result);
1509
+ setTimeout(() => this.resume(), 1);
1510
+ });
1511
+ this.assertInstance(promise, qx.Promise);
1512
+ this.wait(1000);
1513
+ },
1514
+
1515
+ /**
1516
+ * Tests that `reduce` rejects when one promise in the array rejects
1517
+ */
1518
+ testReduceOneReject() {
1519
+ var promiseB = new qx.Promise(function (resolve) {
1520
+ setTimeout(function () {
1521
+ resolve(2);
1522
+ }, 200);
1523
+ });
1524
+
1525
+ var promiseC = new qx.Promise(function (resolve, reject) {
1526
+ setTimeout(function () {
1527
+ reject(new Error("oops"));
1528
+ }, 100);
1529
+ });
1530
+ var promiseD = new qx.Promise(function (resolve) {
1531
+ setTimeout(function () {
1532
+ resolve(4);
1533
+ }, 300);
1534
+ });
1535
+ var arr = new qx.data.Array([promiseB, promiseC, promiseD]);
1536
+ qx.Promise.reduce(
1537
+ qx.Promise.resolve(arr),
1538
+ async (acc, item) => acc + item,
1539
+ 0
1540
+ ).catch(err => {
1541
+ this.assertEquals("oops", err.message);
1542
+ this.resume();
1543
+ });
1544
+ this.wait(1000);
1545
+ },
1546
+
1547
+ /**
1548
+ * Tests that `reduce` rejects when the reducer function throws an error
1549
+ */
1550
+ testReduceMapperReject() {
1551
+ var promiseB = qx.Promise.resolve(2);
1552
+ var promiseC = qx.Promise.resolve(3);
1553
+ var promiseD = qx.Promise.resolve(4);
1554
+ var arr = [promiseB, promiseC, promiseD];
1555
+ qx.Promise.resolve(arr)
1556
+ .reduce(async (acc, item) => {
1557
+ throw new Error("oops");
1558
+ }, 0)
1559
+ .catch(err => {
1560
+ this.assertEquals("oops", err.message);
1561
+ setTimeout(() => this.resume(), 1);
1562
+ });
1563
+ this.wait(1000);
1564
+ },
1565
+
1566
+ /**
1567
+ * Tests that `filter` succeeds when no promise rejects
1568
+ */
1569
+ testFilterResolve() {
1570
+ var promiseB = qx.Promise.resolve(2);
1571
+ var promiseC = qx.Promise.resolve(3);
1572
+ var promiseD = qx.Promise.resolve(4);
1573
+ var promiseE = qx.Promise.resolve(5);
1574
+ var arr = [promiseB, promiseC, promiseD, promiseE, 6];
1575
+ let t = this;
1576
+ let p = qx.Promise.resolve(arr).filter(async function (
1577
+ item,
1578
+ index,
1579
+ length
1580
+ ) {
1581
+ t.assertEquals(index, item - 2);
1582
+ t.assertEquals(5, length);
1583
+ t.assertIdentical(t, this);
1584
+ return item % 2 === 0;
1585
+ },
1586
+ this);
1587
+ p.then(evens => {
1588
+ this.assertArrayEquals([2, 4, 6], evens);
1589
+ //force resume to run on next tick so that we call resume after wait
1590
+ setTimeout(() => this.resume(), 1);
1591
+ });
1592
+ this.assertInstance(p, qx.Promise);
1593
+ this.wait(1000);
1594
+ },
1595
+
1596
+ /**
1597
+ * Tests `concurrency` option for method `filter`
1598
+ */
1599
+ testFilterConcurrency() {
1600
+ let arr = new qx.data.Array([qx.Promise.resolve(1), 2, 3, 4]);
1601
+
1602
+ let maxReached = false;
1603
+ let concurrency = 2;
1604
+ let running = 0;
1605
+
1606
+ let t = this;
1607
+
1608
+ qx.Promise.filter(
1609
+ qx.Promise.resolve(arr),
1610
+ async function (item) {
1611
+ running++;
1612
+ if (running > concurrency) {
1613
+ t.fail("Too many running tasks");
1614
+ } else if (running == concurrency) {
1615
+ maxReached = true;
1616
+ }
1617
+ await new Promise(resolve => setTimeout(resolve, 200));
1618
+ running--;
1619
+ return item % 2 === 0;
1620
+ },
1621
+ { concurrency }
1622
+ ).then(result => {
1623
+ this.assertTrue(maxReached);
1624
+ this.assertArrayEquals([2, 4], result);
1625
+ this.resume();
1626
+ });
1627
+
1628
+ this.wait(1000);
1629
+ },
1630
+
1631
+ /**
1632
+ * Tests that `filter` rejects when one promise in the array rejects
1633
+ */
1634
+ testFilterRejectValue() {
1635
+ var promiseB = qx.Promise.reject(new Error("oops"));
1636
+
1637
+ var promiseC = qx.Promise.resolve(3);
1638
+ var promiseD = qx.Promise.resolve(4);
1639
+ var arr = [promiseB, promiseC, promiseD, 6];
1640
+ qx.Promise.resolve(arr)
1641
+ .filter(async (item, index, length) => item % 2 === 0)
1642
+ .catch(e => {
1643
+ this.assertEquals("oops", e.message);
1644
+ setTimeout(() => this.resume(), 1);
1645
+ });
1646
+
1647
+ this.wait(1000);
1648
+ },
1649
+
1650
+ /**
1651
+ * Tests that `filter` rejects when the iterator function throws an error
1652
+ */
1653
+ testFilterRejectFilterer() {
1654
+ var promiseB = qx.Promise.resolve(2);
1655
+
1656
+ var promiseC = qx.Promise.resolve(3);
1657
+ var promiseD = qx.Promise.resolve(4);
1658
+ var arr = [promiseB, promiseC, promiseD, 6];
1659
+ qx.Promise.resolve(arr)
1660
+ .filter(async item => {
1661
+ throw new Error("oops");
1662
+ })
1663
+ .catch(e => {
1664
+ this.assertEquals("oops", e.message);
1665
+ setTimeout(() => this.resume(), 1);
1666
+ });
1667
+
1668
+ this.wait(1000);
1669
+ },
1670
+
1671
+ /**
1672
+ * Tests that the `some` method resolves when no promise rejects
1673
+ */
1674
+ testSomeResolve() {
1675
+ var promiseB = new qx.Promise(function (resolve) {
1676
+ setTimeout(function () {
1677
+ resolve(2);
1678
+ }, 200);
1679
+ });
1680
+
1681
+ var promiseC = new qx.Promise(function (resolve) {
1682
+ setTimeout(function () {
1683
+ resolve(3);
1684
+ }, 100);
1685
+ });
1686
+ var promiseD = new qx.Promise(function (resolve) {
1687
+ setTimeout(function () {
1688
+ resolve(4);
1689
+ }, 300);
1690
+ });
1691
+ var arr = [promiseB, promiseC, promiseD, 6];
1692
+ let p = qx.Promise.resolve(arr).some(2);
1693
+ p.then(result => {
1694
+ this.assertArrayEquals([6, 3], result);
1695
+ this.resume();
1696
+ });
1697
+ this.assertInstance(p, qx.Promise);
1698
+ this.wait(1000);
1699
+ },
1700
+
1701
+ /**
1702
+ * Tests that the `some` method still resolves when one promise rejects
1703
+ * such that enough promises still resolve.
1704
+ * Also tests with a straight value in the array
1705
+ */
1706
+ testSomeOneReject() {
1707
+ var promiseB = new qx.Promise(function (resolve, reject) {
1708
+ setTimeout(function () {
1709
+ reject(new Error("oops"));
1710
+ }, 200);
1711
+ });
1712
+
1713
+ var promiseC = new qx.Promise(function (resolve) {
1714
+ setTimeout(function () {
1715
+ resolve(3);
1716
+ }, 100);
1717
+ });
1718
+ var promiseD = new qx.Promise(function (resolve) {
1719
+ setTimeout(function () {
1720
+ resolve(4);
1721
+ }, 300);
1722
+ });
1723
+ var arr = new qx.data.Array([promiseB, promiseC, promiseD, 6]);
1724
+ qx.Promise.some(qx.Promise.resolve(arr), 3).then(result => {
1725
+ this.assertArrayEquals([6, 3, 4], result);
1726
+ this.resume();
1727
+ });
1728
+ this.wait(1000);
1729
+ },
1730
+
1731
+ /**
1732
+ * Ensures that the `some` method rejects
1733
+ * when too many promises reject such that there aren't enough
1734
+ * resolved promises to satisfy the count
1735
+ */
1736
+ testSomeTooManyReject() {
1737
+ var promiseB = new qx.Promise(function (resolve, reject) {
1738
+ setTimeout(function () {
1739
+ reject(new Error("oops"));
1740
+ }, 200);
1741
+ });
1742
+
1743
+ var promiseC = new qx.Promise(function (resolve, reject) {
1744
+ setTimeout(function () {
1745
+ reject(new Error("oops1"));
1746
+ }, 100);
1747
+ });
1748
+ var promiseD = new qx.Promise(function (resolve) {
1749
+ setTimeout(function () {
1750
+ resolve(4);
1751
+ }, 300);
1752
+ });
1753
+ var arr = [promiseB, promiseC, promiseD, 6];
1754
+ qx.Promise.resolve(arr)
1755
+ .some(3)
1756
+ .catch(error => {
1757
+ let errors = qx.lang.Type.isArray(error.errors)
1758
+ ? error.errors
1759
+ : error;
1760
+
1761
+ this.assertArrayEquals(
1762
+ ["oops1", "oops"],
1763
+ errors.map(e => e.message)
1764
+ );
1765
+ this.resume();
1766
+ });
1767
+ this.wait(1000);
1768
+ },
1769
+
1770
+ /**
1771
+ * Ensures that the `map` method resolves when no promise rejects
1772
+ */
1773
+ testMapResolve() {
1774
+ var promiseB = qx.Promise.resolve(2);
1775
+
1776
+ var promiseC = qx.Promise.resolve(3);
1777
+ var promiseD = qx.Promise.resolve(4);
1778
+ var arr = [promiseB, promiseC, promiseD, 5];
1779
+ var t = this;
1780
+ let p = qx.Promise.resolve(arr).map(function (item, index, length) {
1781
+ t.assertEquals(index, item - 2);
1782
+ t.assertEquals(length, 4);
1783
+ this.assertIdentical(t, this);
1784
+ return item * 2;
1785
+ }, this);
1786
+ p.then(result => {
1787
+ this.assertArrayEquals([4, 6, 8, 10], result);
1788
+ setTimeout(() => this.resume(), 1);
1789
+ });
1790
+ this.assertInstance(p, qx.Promise);
1791
+ this.wait(1000);
1792
+ },
1793
+
1794
+ /**
1795
+ * Tests the `concurrency` option of the `map` method
1796
+ */
1797
+ testMapConcurrency() {
1798
+ let promiseA = qx.Promise.resolve(1);
1799
+ let arr = new qx.data.Array([promiseA, 2, 3, 4]);
1800
+
1801
+ let maxReached = false;
1802
+ let concurrency = 2;
1803
+ let running = 0;
1804
+
1805
+ let t = this;
1806
+
1807
+ let promise = qx.Promise.map(
1808
+ qx.Promise.resolve(arr),
1809
+ async function (item) {
1810
+ running++;
1811
+ if (running > concurrency) {
1812
+ t.fail("Too many running tasks");
1813
+ } else if (running == concurrency) {
1814
+ maxReached = true;
1815
+ }
1816
+ await new qx.Promise(resolve => setTimeout(resolve, 200));
1817
+ running--;
1818
+ return item * 2;
1819
+ },
1820
+ { concurrency }
1821
+ ).then(result => {
1822
+ this.assertTrue(maxReached);
1823
+ this.assertArrayEquals([2, 4, 6, 8], result);
1824
+ this.resume();
1825
+ });
1826
+
1827
+ this.assertInstance(promise, qx.Promise);
1828
+ this.wait(1000);
1829
+ },
1830
+
1831
+ /**
1832
+ * Tests the `map` method when one promise in the array rejects
1833
+ */
1834
+ testMapOneReject() {
1835
+ var promiseB = qx.Promise.resolve(2);
1836
+
1837
+ var promiseC = qx.Promise.reject(new Error("oops"));
1838
+ var promiseD = qx.Promise.resolve(4);
1839
+ var arr = [promiseB, promiseC, promiseD];
1840
+ qx.Promise.resolve(arr)
1841
+ .map(async item => item * 2)
1842
+ .catch(err => {
1843
+ this.assertEquals("oops", err.message);
1844
+ setTimeout(() => this.resume(), 1);
1845
+ });
1846
+ this.wait(1000);
1847
+ },
1848
+
1849
+ /**
1850
+ * Tests the `map` method rejects when the iterator (mapper) function rejects.
1851
+ */
1852
+ testMapMapperReject() {
1853
+ var promiseB = qx.Promise.resolve(2);
1854
+
1855
+ var promiseC = qx.Promise.resolve(3);
1856
+ var promiseD = qx.Promise.resolve(4);
1857
+ var arr = [promiseB, promiseC, promiseD];
1858
+ qx.Promise.resolve(arr)
1859
+ .map(async item => {
1860
+ throw new Error("oops");
1861
+ })
1862
+ .catch(err => {
1863
+ this.assertEquals("oops", err.message);
1864
+ setTimeout(() => this.resume(), 1);
1865
+ });
1866
+ this.wait(1000);
1867
+ },
1868
+
1869
+ /**
1870
+ * Ensures the `mapSeries` method resolves when no promise rejects.
1871
+ * Also tests custom context for the iterator function
1872
+ */
1873
+ testMapSeriesResolve() {
1874
+ var promiseB = qx.Promise.resolve(1);
1875
+ var promiseC = qx.Promise.resolve(2);
1876
+ var promiseD = qx.Promise.resolve(3);
1877
+
1878
+ let checkIndex = 0;
1879
+
1880
+ var arr = [promiseB, promiseC, promiseD, 4];
1881
+ let p = qx.Promise.resolve(arr).mapSeries(async (item, index, length) => {
1882
+ this.assertEquals(checkIndex++, index);
1883
+ this.assertEquals(4, length);
1884
+ return item * 2;
1885
+ });
1886
+ p.then(doubles => {
1887
+ this.assertArrayEquals([2, 4, 6, 8], doubles);
1888
+ setTimeout(() => this.resume(), 1);
1889
+ });
1890
+ this.assertInstance(p, qx.Promise);
1891
+ this.wait(1000);
1892
+ },
1893
+
1894
+ /**
1895
+ * Tests the `mapSeries` method when one promise in the array rejects.
1896
+ * The returned promise should reject.
1897
+ */
1898
+ testMapSeriesOneReject() {
1899
+ var promiseB = qx.Promise.reject(new Error("oops"));
1900
+ var promiseC = qx.Promise.resolve(2);
1901
+ var promiseD = qx.Promise.resolve(3);
1902
+
1903
+ var arr = [promiseB, promiseC, promiseD];
1904
+ qx.Promise.resolve(arr)
1905
+ .mapSeries(async item => item * 2)
1906
+ .catch(e => {
1907
+ this.assertEquals("oops", e.message);
1908
+ setTimeout(() => this.resume(), 1);
1909
+ });
1910
+
1911
+ this.wait(1000);
1912
+ },
1913
+
1914
+ /**
1915
+ * Tests the `mapSeries` method when the iterator rejects.
1916
+ * The returned promise should reject.
1917
+ */
1918
+ testMapSeriesMapperReject() {
1919
+ var promiseB = qx.Promise.resolve(2);
1920
+ var promiseC = qx.Promise.resolve(3);
1921
+ var promiseD = qx.Promise.resolve(4);
1922
+ var arr = [promiseB, promiseC, promiseD];
1923
+ qx.Promise.resolve(arr)
1924
+ .mapSeries(async item => {
1925
+ throw new Error("oops");
1926
+ })
1927
+ .catch(err => {
1928
+ this.assertEquals("oops", err.message);
1929
+ setTimeout(() => this.resume(), 1);
1930
+ });
1931
+ this.wait(1000);
1932
+ },
1933
+
1934
+ /**
1935
+ * Tests the `mapSeries` being passed with the promise of the array,
1936
+ * which is also a qx.data.Array, which the native Promise does not understand
1937
+ */
1938
+ testMapSeriesPromiseArray() {
1939
+ var promiseArr = qx.Promise.resolve(new qx.data.Array([1, 2, 3]));
1940
+
1941
+ qx.Promise.mapSeries(promiseArr, (item, index) => {
1942
+ this.assertEquals(index, item - 1);
1943
+ return item * 2;
1944
+ }).then(result => {
1945
+ setTimeout(() => this.resume(), 1);
1946
+ });
824
1947
  this.wait(1000);
825
1948
  }
826
1949
  },