@qooxdoo/framework 7.7.2 → 7.9.0
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.
- package/Manifest.json +2 -2
- package/lib/compiler/compile-info.json +91 -89
- package/lib/compiler/index.js +2517 -1488
- package/lib/resource/qx/tool/schema/compile-1-0-0.json +13 -0
- package/lib/resource/qx/tool/website/build/404.html +3 -25
- package/lib/resource/qx/tool/website/build/about.html +3 -25
- package/lib/resource/qx/tool/website/build/assets/common.js +20 -0
- package/lib/resource/qx/tool/website/build/diagnostics/dependson.html +3 -25
- package/lib/resource/qx/tool/website/build/diagnostics/requiredby.html +3 -22
- package/lib/resource/qx/tool/website/build/index.html +3 -25
- package/lib/resource/qx/tool/website/partials/footer.html +3 -21
- package/lib/resource/qx/tool/website/partials/head.html +0 -1
- package/package.json +2 -2
- package/source/class/qx/Bootstrap.js +6 -3
- package/source/class/qx/Promise.js +93 -6964
- package/source/class/qx/bom/Label.js +82 -2
- package/source/class/qx/bom/webfonts/WebFont.js +1 -0
- package/source/class/qx/core/Environment.js +83 -1
- package/source/class/qx/data/controller/List.js +50 -21
- package/source/class/qx/data/controller/MSelection.js +45 -12
- package/source/class/qx/data/marshal/Json.js +64 -11
- package/source/class/qx/dev/unit/AsyncWrapper.js +8 -0
- package/source/class/qx/event/Manager.js +163 -124
- package/source/class/qx/io/ImageLoader.js +6 -3
- package/source/class/qx/io/exception/Transport.js +1 -0
- package/source/class/qx/io/jsonrpc/Client.js +64 -8
- package/source/class/qx/io/jsonrpc/protocol/Request.js +10 -6
- package/source/class/qx/lang/Type.js +36 -3
- package/source/class/qx/promise/BluebirdImpl.js +6918 -0
- package/source/class/qx/promise/NativeWrapper.js +738 -0
- package/source/class/qx/test/Promise.js +1145 -22
- package/source/class/qx/test/bom/client/Pdfjs.js +4 -0
- package/source/class/qx/test/bom/element/AnimationJs.js +3 -0
- package/source/class/qx/test/bom/element/Style.js +1 -0
- package/source/class/qx/test/bom/media/MediaTestCase.js +6 -0
- package/source/class/qx/test/core/Environment.js +44 -0
- package/source/class/qx/test/data/controller/List.js +6 -0
- package/source/class/qx/test/data/marshal/Json.js +29 -0
- package/source/class/qx/test/io/MAssert.js +94 -0
- package/source/class/qx/test/io/TestMAssert.js +47 -0
- package/source/class/qx/test/io/jsonrpc/Client.js +79 -19
- package/source/class/qx/test/io/jsonrpc/PostMessageClient.js +152 -0
- package/source/class/qx/test/io/jsonrpc/Protocol.js +1 -5
- package/source/class/qx/test/io/request/Xhr.js +16 -0
- package/source/class/qx/test/lang/Type.js +151 -0
- package/source/class/qx/test/ui/embed/Iframe.js +1 -1
- package/source/class/qx/test/ui/form/TextArea.js +4 -0
- package/source/class/qx/test/util/DeferredCall.js +6 -0
- package/source/class/qx/test/util/Function.js +2 -2
- package/source/class/qx/theme/indigo/ColorDark.js +1 -1
- package/source/class/qx/tool/cli/api/Test.js +22 -0
- package/source/class/qx/tool/cli/commands/Compile.js +17 -4
- package/source/class/qx/tool/cli/commands/Test.js +7 -1
- package/source/class/qx/tool/compiler/Analyser.js +7 -0
- package/source/class/qx/tool/compiler/ClassFile.js +3 -2
- package/source/class/qx/tool/compiler/MetaExtraction.js +0 -5
- package/source/class/qx/tool/compiler/targets/meta/Browserify.js +8 -2
- package/source/class/qx/ui/basic/Image.js +72 -8
- package/source/class/qx/ui/basic/Label.js +4 -6
- package/source/class/qx/ui/control/DateChooser.js +4 -6
- package/source/class/qx/ui/core/Blocker.js +4 -6
- package/source/class/qx/ui/core/LayoutItem.js +4 -6
- package/source/class/qx/ui/core/MPlacement.js +23 -1
- package/source/class/qx/ui/core/Widget.js +7 -5
- package/source/class/qx/ui/form/AbstractField.js +4 -6
- package/source/class/qx/ui/form/MForm.js +4 -6
- package/source/class/qx/ui/form/Spinner.js +4 -6
- package/source/class/qx/ui/form/renderer/AbstractRenderer.js +4 -6
- package/source/class/qx/ui/menu/AbstractButton.js +7 -11
- package/source/class/qx/ui/mobile/basic/Label.js +4 -6
- package/source/class/qx/ui/mobile/form/Label.js +4 -6
- package/source/class/qx/ui/mobile/list/List.js +4 -6
- package/source/class/qx/ui/progressive/renderer/table/Row.js +35 -7
- package/source/class/qx/ui/progressive/renderer/table/cell/Boolean.js +4 -6
- package/source/class/qx/ui/table/Table.js +4 -6
- package/source/class/qx/ui/table/cellrenderer/Abstract.js +4 -6
- package/source/class/qx/ui/table/cellrenderer/Boolean.js +4 -6
- package/source/class/qx/ui/table/pane/Scroller.js +1 -1
- package/source/class/qx/ui/table/rowrenderer/Default.js +4 -6
- package/source/class/qx/util/ConcurrencyLimiter.js +78 -0
- package/source/resource/qx/tool/schema/compile-1-0-0.json +13 -0
- package/source/resource/qx/tool/website/build/404.html +3 -25
- package/source/resource/qx/tool/website/build/about.html +3 -25
- package/source/resource/qx/tool/website/build/assets/common.js +20 -0
- package/source/resource/qx/tool/website/build/diagnostics/dependson.html +3 -25
- package/source/resource/qx/tool/website/build/diagnostics/requiredby.html +3 -22
- package/source/resource/qx/tool/website/build/index.html +3 -25
- package/source/resource/qx/tool/website/partials/footer.html +3 -21
- package/source/resource/qx/tool/website/partials/head.html +0 -1
- package/lib/resource/qx/tool/website/build/assets/bluebird.min.js +0 -4615
- package/lib/resource/qx/tool/website/src/assets/bluebird.min.js +0 -4615
- package/source/resource/qx/tool/website/build/assets/bluebird.min.js +0 -4615
- 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.
|
|
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)
|
|
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
|
|
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
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
},
|