@qooxdoo/framework 7.7.1 → 7.8.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 +1 -1
- package/lib/compiler/compile-info.json +69 -69
- package/lib/compiler/index.js +542 -380
- package/lib/resource/qx/tool/schema/compile-1-0-0.json +13 -0
- package/package.json +2 -2
- package/source/class/qx/Class.js +1 -1
- package/source/class/qx/Mixin.js +7 -5
- package/source/class/qx/bom/Input.js +24 -13
- 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 +82 -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/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/Function.js +5 -1
- package/source/class/qx/test/Mixin.js +260 -0
- 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/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/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/tool/cli/api/Test.js +22 -0
- package/source/class/qx/tool/cli/commands/Compile.js +17 -7
- 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 +12 -6
- package/source/class/qx/tool/compiler/MetaExtraction.js +0 -5
- package/source/class/qx/tool/compiler/targets/Target.js +2 -2
- 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 +11 -0
- package/source/class/qx/ui/core/Widget.js +7 -5
- package/source/class/qx/ui/form/AbstractField.js +14 -16
- package/source/class/qx/ui/form/IListItem.js +48 -1
- package/source/class/qx/ui/form/List.js +11 -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 +12 -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 +35 -0
- package/source/class/qx/ui/table/rowrenderer/Default.js +4 -6
- package/source/resource/qx/tool/schema/compile-1-0-0.json +13 -0
|
@@ -60,21 +60,33 @@ qx.Class.define("qx.test.io.jsonrpc.Client", {
|
|
|
60
60
|
},
|
|
61
61
|
|
|
62
62
|
/**
|
|
63
|
-
* Sets up the fake server and instructs it to send the given response
|
|
64
|
-
* @param {String} response
|
|
63
|
+
* Sets up the fake server and instructs it to send the given response
|
|
64
|
+
* @param {String} response Optional server response
|
|
65
65
|
*/
|
|
66
66
|
setUpFakeServer(response) {
|
|
67
67
|
// Not fake transport
|
|
68
68
|
this.getSandbox().restore();
|
|
69
69
|
this.useFakeServer();
|
|
70
70
|
this.setUpRequest();
|
|
71
|
+
if (response) {
|
|
72
|
+
this.setServerResponse(response);
|
|
73
|
+
}
|
|
74
|
+
this.getServer().autoRespond = true;
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Set the fake server's response
|
|
79
|
+
* @param {{String|Object} } response Server response. Will be stringified to a JSON string if not a string
|
|
80
|
+
*/
|
|
81
|
+
setServerResponse(response) {
|
|
82
|
+
if (typeof response != "string") {
|
|
83
|
+
response = JSON.stringify(response);
|
|
84
|
+
}
|
|
71
85
|
this.getServer().respondWith("POST", /.*/, [
|
|
72
86
|
200,
|
|
73
87
|
{ "Content-Type": "application/json; charset=utf-8" },
|
|
74
88
|
response
|
|
75
89
|
]);
|
|
76
|
-
|
|
77
|
-
this.getServer().autoRespond = true;
|
|
78
90
|
},
|
|
79
91
|
|
|
80
92
|
/**
|
|
@@ -103,7 +115,7 @@ qx.Class.define("qx.test.io.jsonrpc.Client", {
|
|
|
103
115
|
if (!(err instanceof qx.io.exception.Exception)) {
|
|
104
116
|
throw err;
|
|
105
117
|
}
|
|
106
|
-
this.assertEquals(exception, err.code, `Error code does not match
|
|
118
|
+
this.assertEquals(exception, err.code, `Error code does not match. Expected ${exception}, got ${err.code}.`);
|
|
107
119
|
} else {
|
|
108
120
|
this.assertInstance(
|
|
109
121
|
err,
|
|
@@ -119,16 +131,20 @@ qx.Class.define("qx.test.io.jsonrpc.Client", {
|
|
|
119
131
|
// check transport promise
|
|
120
132
|
client.send(message_out).catch(errorCallback);
|
|
121
133
|
this.wait(100, () => {
|
|
134
|
+
// in case of a transport error, ...
|
|
135
|
+
const n = qx.core.Environment.select("qx.io.jsonrpc.forwardTransportPromiseRejectionToRequest", {
|
|
136
|
+
true: 1, // ... we are rejecting the request promise only, v8 default
|
|
137
|
+
false: 2 // ... both request promise and transport promise are rejected, v7 default
|
|
138
|
+
})
|
|
122
139
|
if (
|
|
123
|
-
// the request promise will not be
|
|
140
|
+
// the request promise will not be rejected because it already is rejected in this special case
|
|
124
141
|
exception === qx.io.exception.Transport.DUPLICATE_ID ||
|
|
125
|
-
// or the send promise will not be rejected because we have a server-side error
|
|
126
|
-
exception === qx.io.exception.Protocol
|
|
142
|
+
// or the send promise will not be rejected because we have a server-side error, v7 default only
|
|
143
|
+
(exception === qx.io.exception.Protocol && !qx.core.Environment.get("qx.io.jsonrpc.forwardTransportPromiseRejectionToRequest"))
|
|
127
144
|
) {
|
|
128
|
-
this.
|
|
145
|
+
this.assertCallCount(errorCallback, n);
|
|
129
146
|
} else {
|
|
130
|
-
|
|
131
|
-
this.assertCalledThrice(errorCallback);
|
|
147
|
+
this.assertCallCount(errorCallback, n+1);
|
|
132
148
|
}
|
|
133
149
|
});
|
|
134
150
|
},
|
|
@@ -208,10 +224,9 @@ qx.Class.define("qx.test.io.jsonrpc.Client", {
|
|
|
208
224
|
|
|
209
225
|
this.setUpFakeServer(message_in.toString());
|
|
210
226
|
const client = new qx.io.jsonrpc.Client("http://jsonrpc");
|
|
211
|
-
let spy = this.spy(value => this.assertEquals(result, value));
|
|
212
|
-
message_out.getPromise().then(spy);
|
|
213
227
|
await client.send(message_out);
|
|
214
|
-
|
|
228
|
+
const value = await message_out.getPromise();
|
|
229
|
+
this.assertEquals(result, value);
|
|
215
230
|
},
|
|
216
231
|
|
|
217
232
|
async "test: call jsonrpc method and receive batched response"() {
|
|
@@ -225,10 +240,9 @@ qx.Class.define("qx.test.io.jsonrpc.Client", {
|
|
|
225
240
|
.toString();
|
|
226
241
|
this.setUpFakeServer(response);
|
|
227
242
|
const client = new qx.io.jsonrpc.Client("http://jsonrpc");
|
|
228
|
-
let spy = this.spy(value => this.assertEquals(result, value));
|
|
229
|
-
message_out.getPromise().then(spy);
|
|
230
243
|
await client.send(message_out);
|
|
231
|
-
|
|
244
|
+
const value = await message_out.getPromise();
|
|
245
|
+
this.assertEquals(result, value);
|
|
232
246
|
},
|
|
233
247
|
|
|
234
248
|
"test: call jsonrpc method and expect error on invalid reponse "() {
|
|
@@ -321,10 +335,56 @@ qx.Class.define("qx.test.io.jsonrpc.Client", {
|
|
|
321
335
|
spy(message);
|
|
322
336
|
});
|
|
323
337
|
client.sendNotification("ping");
|
|
338
|
+
this.wait(100, () => this.assertCalledTwice(spy) );
|
|
339
|
+
},
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Issue #10739
|
|
343
|
+
*/
|
|
344
|
+
testIssue10739() {
|
|
345
|
+
this.resetId();
|
|
346
|
+
this.setUpFakeServer();
|
|
347
|
+
const successCallback = this.spy(result =>
|
|
348
|
+
this.debug(`Server response is "${result}"`)
|
|
349
|
+
);
|
|
350
|
+
const errorCallback = this.spy(error => console.error(error.message));
|
|
351
|
+
const client = new qx.io.jsonrpc.Client("http://test.local");
|
|
352
|
+
const auth = new qx.io.request.authentication.Bearer("TOKEN");
|
|
353
|
+
client.getTransport().getTransportImpl().setAuthentication(auth);
|
|
354
|
+
this.setServerResponse({
|
|
355
|
+
jsonrpc: "2.0",
|
|
356
|
+
error: {
|
|
357
|
+
code: 8,
|
|
358
|
+
message: "stale or uninitialized auth token/rune"
|
|
359
|
+
},
|
|
360
|
+
id: 1
|
|
361
|
+
});
|
|
362
|
+
const sendRequest = this.spy(() => {
|
|
363
|
+
this.debug("sendRequest() was called");
|
|
364
|
+
client
|
|
365
|
+
.sendRequest("service.method", ["foo"])
|
|
366
|
+
.then(successCallback)
|
|
367
|
+
.catch(err => {
|
|
368
|
+
if (err.code == 8) {
|
|
369
|
+
this.debug(`Received expected error message.`);
|
|
370
|
+
this.setServerResponse({
|
|
371
|
+
jsonrpc: "2.0",
|
|
372
|
+
result: "OK",
|
|
373
|
+
id: 2
|
|
374
|
+
});
|
|
375
|
+
sendRequest(); // second request
|
|
376
|
+
} else {
|
|
377
|
+
errorCallback(err);
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
});
|
|
381
|
+
sendRequest();
|
|
324
382
|
this.wait(
|
|
325
|
-
|
|
383
|
+
250,
|
|
326
384
|
function () {
|
|
327
|
-
this.assertCalledTwice(
|
|
385
|
+
this.assertCalledTwice(sendRequest);
|
|
386
|
+
this.assertCalledOnce(successCallback);
|
|
387
|
+
this.assertNotCalled(errorCallback);
|
|
328
388
|
},
|
|
329
389
|
this
|
|
330
390
|
);
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/* ************************************************************************
|
|
2
|
+
|
|
3
|
+
qooxdoo - the javascript framework for coders
|
|
4
|
+
|
|
5
|
+
http://qooxdoo.org
|
|
6
|
+
|
|
7
|
+
Copyright:
|
|
8
|
+
2025 qooxdoo contributors
|
|
9
|
+
|
|
10
|
+
License:
|
|
11
|
+
MIT: https://opensource.org/licenses/MIT
|
|
12
|
+
See the LICENSE file in the project's top-level directory for details.
|
|
13
|
+
|
|
14
|
+
Authors:
|
|
15
|
+
* Christian Boulanger (cboulanger)
|
|
16
|
+
|
|
17
|
+
************************************************************************ */
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Tests for qx.io.jsonrpc.Client with qx.test.io.request.PostMessage transport
|
|
21
|
+
* @ignore(Worker)
|
|
22
|
+
* @ignore(self)
|
|
23
|
+
*/
|
|
24
|
+
qx.Class.define("qx.test.io.jsonrpc.PostMessageClient", {
|
|
25
|
+
extend: qx.dev.unit.TestCase,
|
|
26
|
+
|
|
27
|
+
include: [qx.dev.unit.MMock, qx.test.io.MAssert],
|
|
28
|
+
|
|
29
|
+
members: {
|
|
30
|
+
setUp() {
|
|
31
|
+
qx.io.jsonrpc.protocol.Request.resetId();
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
tearDown() {
|
|
35
|
+
this.getSandbox().restore();
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Given a function, return a `Worker` object which calls the function
|
|
40
|
+
* with the function whenever the Worker receives a message from the main
|
|
41
|
+
* thread.
|
|
42
|
+
* @param {Function} fn
|
|
43
|
+
* @returns {Worker}
|
|
44
|
+
*/
|
|
45
|
+
createOnMessageWorker(fn) {
|
|
46
|
+
let blob = new Blob(["self.onmessage = ", fn.toString()], {
|
|
47
|
+
type: "text/javascript"
|
|
48
|
+
});
|
|
49
|
+
return new Worker(URL.createObjectURL(blob));
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
async "test: receive 10 out-of-order jsonrpc responses from server, all successful"() {
|
|
53
|
+
qx.io.jsonrpc.protocol.Request.resetId();
|
|
54
|
+
|
|
55
|
+
// create server worker which sends a response with random delay
|
|
56
|
+
const server = this.createOnMessageWorker(evt => {
|
|
57
|
+
let request = JSON.parse(evt.data);
|
|
58
|
+
let id = request.id;
|
|
59
|
+
let response = JSON.stringify({
|
|
60
|
+
jsonrpc: "2.0",
|
|
61
|
+
result: `Result for #${id}`,
|
|
62
|
+
id
|
|
63
|
+
});
|
|
64
|
+
setTimeout(() => {
|
|
65
|
+
console.log(`Sending response for request #${id}`);
|
|
66
|
+
self.postMessage(response);
|
|
67
|
+
}, Math.random() * 1000);
|
|
68
|
+
});
|
|
69
|
+
const transport = new qx.io.transport.PostMessage(server);
|
|
70
|
+
const client = new qx.io.jsonrpc.Client(transport);
|
|
71
|
+
const promises = [];
|
|
72
|
+
// send 10 requests without waiting for the response
|
|
73
|
+
for (let i = 0; i < 10; i++) {
|
|
74
|
+
let request = new qx.io.jsonrpc.protocol.Request("someMethod", ["foo"]);
|
|
75
|
+
await client.send(request);
|
|
76
|
+
promises.push(request.getPromise());
|
|
77
|
+
}
|
|
78
|
+
// Make sure that alle requests have been responded to, i.e. that their promises have
|
|
79
|
+
// been settled.
|
|
80
|
+
const allSettledPromise = Promise.allSettled(promises);
|
|
81
|
+
this.observePromise(allSettledPromise);
|
|
82
|
+
this.assertPromisePending(allSettledPromise);
|
|
83
|
+
this.wait(2000, () => {
|
|
84
|
+
this.assertPromiseFulfilled(
|
|
85
|
+
allSettledPromise,
|
|
86
|
+
"Some request promises were not fulfilled"
|
|
87
|
+
);
|
|
88
|
+
});
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
async "test: receive 100 out-of-order jsonrpc responses from server, with jsonrpc errors"() {
|
|
92
|
+
qx.io.jsonrpc.protocol.Request.resetId();
|
|
93
|
+
|
|
94
|
+
// create server worker which sends a response with random delay
|
|
95
|
+
// some requests fail
|
|
96
|
+
const server = this.createOnMessageWorker(evt => {
|
|
97
|
+
let request = JSON.parse(evt.data);
|
|
98
|
+
let id = request.id;
|
|
99
|
+
let response = JSON.stringify(
|
|
100
|
+
Math.random() > 0.5
|
|
101
|
+
? {
|
|
102
|
+
jsonrpc: "2.0",
|
|
103
|
+
result: "OK",
|
|
104
|
+
id
|
|
105
|
+
}
|
|
106
|
+
: {
|
|
107
|
+
jsonrpc: "2.0",
|
|
108
|
+
error: {
|
|
109
|
+
code: -1,
|
|
110
|
+
message: "error",
|
|
111
|
+
},
|
|
112
|
+
id
|
|
113
|
+
}
|
|
114
|
+
);
|
|
115
|
+
setTimeout(() => {
|
|
116
|
+
self.postMessage(response);
|
|
117
|
+
}, Math.random() * 1000);
|
|
118
|
+
});
|
|
119
|
+
const transport = new qx.io.transport.PostMessage(server);
|
|
120
|
+
const client = new qx.io.jsonrpc.Client(transport);
|
|
121
|
+
const promises = [];
|
|
122
|
+
const spies = [];
|
|
123
|
+
// send 100 requests without waiting for the response
|
|
124
|
+
for (let i = 0; i < 100; i++) {
|
|
125
|
+
let request = new qx.io.jsonrpc.protocol.Request("someMethod", ["foo"]);
|
|
126
|
+
await client.send(request);
|
|
127
|
+
// create a spy to receive error objects
|
|
128
|
+
let spy = this.spy()
|
|
129
|
+
spies.push(spy)
|
|
130
|
+
promises.push(request.getPromise().then(spy,spy));
|
|
131
|
+
}
|
|
132
|
+
// Make sure that alle requests have been responded to, i.e. that their promises have
|
|
133
|
+
// been settled.
|
|
134
|
+
const allSettledPromise = Promise.allSettled(promises);
|
|
135
|
+
this.observePromise(allSettledPromise);
|
|
136
|
+
this.assertPromisePending(allSettledPromise);
|
|
137
|
+
this.wait(2000, () => {
|
|
138
|
+
this.assertPromiseSettled(
|
|
139
|
+
allSettledPromise,
|
|
140
|
+
"Some request promises were not settled"
|
|
141
|
+
);
|
|
142
|
+
for(let spy of spies){
|
|
143
|
+
const firstCallArg = spy.getCall(0)?.args[0];
|
|
144
|
+
this.assert(
|
|
145
|
+
(firstCallArg instanceof qx.io.exception.Protocol || typeof firstCallArg == "string"),
|
|
146
|
+
`An unexpected error occurred: "${firstCallArg}"`
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
});
|
|
@@ -25,11 +25,7 @@ qx.Class.define("qx.test.io.jsonrpc.Protocol", {
|
|
|
25
25
|
},
|
|
26
26
|
members: {
|
|
27
27
|
"test: JSON-RPC request message object"() {
|
|
28
|
-
let message = new qx.io.jsonrpc.protocol.Request("foo", [
|
|
29
|
-
"bar",
|
|
30
|
-
1,
|
|
31
|
-
false
|
|
32
|
-
]);
|
|
28
|
+
let message = new qx.io.jsonrpc.protocol.Request("foo", ["bar",1,false], 1);
|
|
33
29
|
|
|
34
30
|
let expected = {
|
|
35
31
|
id: 1,
|
|
@@ -294,6 +294,10 @@ qx.Class.define("qx.test.ui.form.TextArea", {
|
|
|
294
294
|
this.skip();
|
|
295
295
|
}
|
|
296
296
|
|
|
297
|
+
if ((qx.core.Environment.get("engine.name") === "gecko") && (navigator.plugins.length == 0)) {
|
|
298
|
+
this.skip("test disabled on headless firefox browser");
|
|
299
|
+
}
|
|
300
|
+
|
|
297
301
|
var textArea = this.__textArea;
|
|
298
302
|
textArea.set({
|
|
299
303
|
autoSize: true,
|
|
@@ -24,6 +24,12 @@ qx.Class.define("qx.test.util.DeferredCall", {
|
|
|
24
24
|
if (navigator.plugins.length == 0) {
|
|
25
25
|
this.skip("test disabled on headless browsers");
|
|
26
26
|
}
|
|
27
|
+
|
|
28
|
+
if (qx.core.Environment.get("browser.name") == "safari") {
|
|
29
|
+
this.skip(
|
|
30
|
+
"we can not detect headless mode in safari"
|
|
31
|
+
);
|
|
32
|
+
}
|
|
27
33
|
|
|
28
34
|
var fail = function () {
|
|
29
35
|
throw new Error("fail");
|
|
@@ -30,7 +30,7 @@ qx.Class.define("qx.test.util.Function", {
|
|
|
30
30
|
this.assertNotCalled(test);
|
|
31
31
|
debouncedTest(false);
|
|
32
32
|
this.wait(
|
|
33
|
-
|
|
33
|
+
250,
|
|
34
34
|
function () {
|
|
35
35
|
this.assertCalledOnce(test);
|
|
36
36
|
this.assertCalledWith(test, false);
|
|
@@ -52,7 +52,7 @@ qx.Class.define("qx.test.util.Function", {
|
|
|
52
52
|
debouncedTest(true);
|
|
53
53
|
debouncedTest(false);
|
|
54
54
|
this.wait(
|
|
55
|
-
|
|
55
|
+
250,
|
|
56
56
|
function () {
|
|
57
57
|
this.assertCalledTwice(test);
|
|
58
58
|
this.assertCalledWith(test, false);
|
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
/* ************************************************************************
|
|
2
|
+
|
|
3
|
+
qooxdoo - the new era of web development
|
|
4
|
+
|
|
5
|
+
http://qooxdoo.org
|
|
6
|
+
|
|
7
|
+
Copyright:
|
|
8
|
+
2020 Henner Kollmann
|
|
9
|
+
|
|
10
|
+
License:
|
|
11
|
+
MIT: https://opensource.org/licenses/MIT
|
|
12
|
+
See the LICENSE file in the project"s top-level directory for details.
|
|
13
|
+
************************************************************************ */
|
|
1
14
|
/**
|
|
2
15
|
* This is used to add an test case for qx test
|
|
3
16
|
*/
|
|
@@ -47,6 +60,15 @@ qx.Class.define("qx.tool.cli.api.Test", {
|
|
|
47
60
|
init: true
|
|
48
61
|
},
|
|
49
62
|
|
|
63
|
+
/**
|
|
64
|
+
* If this special test fails exit process
|
|
65
|
+
*/
|
|
66
|
+
failFast: {
|
|
67
|
+
check: "Boolean",
|
|
68
|
+
nullable: false,
|
|
69
|
+
init: false
|
|
70
|
+
},
|
|
71
|
+
|
|
50
72
|
/**
|
|
51
73
|
* The test function called by qx test
|
|
52
74
|
*
|
|
@@ -789,9 +789,6 @@ Framework: v${await this.getQxVersion()} in ${await this.getQxPath()}`);
|
|
|
789
789
|
}
|
|
790
790
|
|
|
791
791
|
for (let filename of classFiles) {
|
|
792
|
-
if (this.argv.verbose) {
|
|
793
|
-
qx.tool.compiler.Console.info(`Processing ${filename} ...`);
|
|
794
|
-
}
|
|
795
792
|
await metaDb.addFile(filename, !!this.argv.clean);
|
|
796
793
|
}
|
|
797
794
|
await metaDb.reparseAll();
|
|
@@ -1348,6 +1345,15 @@ Framework: v${await this.getQxVersion()} in ${await this.getQxPath()}`);
|
|
|
1348
1345
|
if (data.environment) {
|
|
1349
1346
|
maker.setEnvironment(data.environment);
|
|
1350
1347
|
}
|
|
1348
|
+
|
|
1349
|
+
/*
|
|
1350
|
+
Libraries have to be added first because there is qx library
|
|
1351
|
+
which includes a framework version
|
|
1352
|
+
*/
|
|
1353
|
+
for (let library of librariesArray) {
|
|
1354
|
+
maker.getAnalyser().addLibrary(library);
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1351
1357
|
let targetEnvironment = {
|
|
1352
1358
|
"qx.version": maker.getAnalyser().getQooxdooVersion(),
|
|
1353
1359
|
"qx.compiler.targetType": target.getType(),
|
|
@@ -1398,6 +1404,14 @@ Framework: v${await this.getQxVersion()} in ${await this.getQxPath()}`);
|
|
|
1398
1404
|
|
|
1399
1405
|
maker.getAnalyser().setBabelConfig(babelConfig);
|
|
1400
1406
|
|
|
1407
|
+
let browserifyConfig = qx.lang.Object.clone(data.browserify || {}, true);
|
|
1408
|
+
browserifyConfig.options = browserifyConfig.options || {};
|
|
1409
|
+
qx.lang.Object.mergeWith(
|
|
1410
|
+
browserifyConfig.options,
|
|
1411
|
+
targetConfig.browserifyOptions || {}
|
|
1412
|
+
);
|
|
1413
|
+
maker.getAnalyser().setBrowserifyConfig(browserifyConfig);
|
|
1414
|
+
|
|
1401
1415
|
var addCreatedAt =
|
|
1402
1416
|
targetConfig["addCreatedAt"] || t.argv["addCreatedAt"];
|
|
1403
1417
|
if (addCreatedAt) {
|
|
@@ -1409,10 +1423,6 @@ Framework: v${await this.getQxVersion()} in ${await this.getQxPath()}`);
|
|
|
1409
1423
|
maker.getAnalyser().setVerboseCreatedAt(true);
|
|
1410
1424
|
}
|
|
1411
1425
|
|
|
1412
|
-
for (let library of librariesArray) {
|
|
1413
|
-
maker.getAnalyser().addLibrary(library);
|
|
1414
|
-
}
|
|
1415
|
-
|
|
1416
1426
|
let allApplicationTypes = {};
|
|
1417
1427
|
appConfigs.forEach(appConfig => {
|
|
1418
1428
|
var app = (appConfig.app = new qx.tool.compiler.app.Application(
|
|
@@ -99,7 +99,7 @@ qx.Class.define("qx.tool.cli.commands.Test", {
|
|
|
99
99
|
let exitCode = evt.getData();
|
|
100
100
|
// overwrite error code only in case of errors
|
|
101
101
|
if (exitCode !== 0 && argv.failFast) {
|
|
102
|
-
process.exit(exitCode);
|
|
102
|
+
process.exit(Math.min(255, exitCode));
|
|
103
103
|
}
|
|
104
104
|
});
|
|
105
105
|
},
|
|
@@ -152,6 +152,9 @@ qx.Class.define("qx.tool.cli.commands.Test", {
|
|
|
152
152
|
}
|
|
153
153
|
// overwrite error code only in case of errors
|
|
154
154
|
if (exitCode !== 0) {
|
|
155
|
+
if (test.getFailFast()) {
|
|
156
|
+
this.argv.failFast = true;
|
|
157
|
+
}
|
|
155
158
|
this.setExitCode(exitCode);
|
|
156
159
|
}
|
|
157
160
|
});
|
|
@@ -194,6 +197,9 @@ qx.Class.define("qx.tool.cli.commands.Test", {
|
|
|
194
197
|
|
|
195
198
|
this.addListener("afterStart", async () => {
|
|
196
199
|
qx.tool.compiler.Console.info(`Running unit tests`);
|
|
200
|
+
if (this.argv.verbose) {
|
|
201
|
+
console.log(this.argv);
|
|
202
|
+
}
|
|
197
203
|
await this.fireDataEventAsync("runTests", this);
|
|
198
204
|
if (
|
|
199
205
|
this.getCompilerApi() &&
|
|
@@ -126,6 +126,13 @@ qx.Class.define("qx.tool.compiler.Analyser", {
|
|
|
126
126
|
check: "Object"
|
|
127
127
|
},
|
|
128
128
|
|
|
129
|
+
/** configuration of browserify */
|
|
130
|
+
browserifyConfig: {
|
|
131
|
+
init: null,
|
|
132
|
+
nullable: true,
|
|
133
|
+
check: "Object"
|
|
134
|
+
},
|
|
135
|
+
|
|
129
136
|
/** list of global ignores */
|
|
130
137
|
ignores: {
|
|
131
138
|
init: [],
|
|
@@ -962,14 +962,15 @@ qx.Class.define("qx.tool.compiler.ClassFile", {
|
|
|
962
962
|
|
|
963
963
|
CallExpression(path) {
|
|
964
964
|
const name = collapseMemberExpression(path.node.callee);
|
|
965
|
+
const env = t.__analyser.getEnvironment();
|
|
965
966
|
|
|
966
967
|
if (
|
|
968
|
+
env["qx.environment.allowRuntimeMutations"] !== true &&
|
|
967
969
|
(name === "qx.core.Environment.select" ||
|
|
968
970
|
name === "qx.core.Environment.get") &&
|
|
969
|
-
types.isLiteral(path.node.arguments[0])
|
|
971
|
+
types.isLiteral(path.node.arguments[0])
|
|
970
972
|
) {
|
|
971
973
|
const arg = path.node.arguments[0];
|
|
972
|
-
const env = t.__analyser.getEnvironment();
|
|
973
974
|
const envValue = env[arg.value];
|
|
974
975
|
|
|
975
976
|
if (envValue !== undefined) {
|
|
@@ -1349,8 +1350,12 @@ qx.Class.define("qx.tool.compiler.ClassFile", {
|
|
|
1349
1350
|
t.__hasDefer = true;
|
|
1350
1351
|
t.__inDefer = true;
|
|
1351
1352
|
}
|
|
1352
|
-
|
|
1353
|
-
|
|
1353
|
+
var isSpecialFunctionName =
|
|
1354
|
+
Object.keys(FUNCTION_NAMES).includes(keyName);
|
|
1355
|
+
t.__classMeta.functionName = isSpecialFunctionName
|
|
1356
|
+
? FUNCTION_NAMES[keyName]
|
|
1357
|
+
: keyName;
|
|
1358
|
+
if (isSpecialFunctionName) {
|
|
1354
1359
|
makeMeta(keyName, null, functionNode);
|
|
1355
1360
|
}
|
|
1356
1361
|
enterFunction(path, functionNode);
|
|
@@ -1393,8 +1398,9 @@ qx.Class.define("qx.tool.compiler.ClassFile", {
|
|
|
1393
1398
|
}
|
|
1394
1399
|
var keyName = getKeyName(prop.key);
|
|
1395
1400
|
checkValidTopLevel(path);
|
|
1396
|
-
|
|
1397
|
-
|
|
1401
|
+
var isSpecialFunctionName =
|
|
1402
|
+
Object.keys(FUNCTION_NAMES).includes(keyName);
|
|
1403
|
+
if (isSpecialFunctionName) {
|
|
1398
1404
|
let val = path.node.value;
|
|
1399
1405
|
val.leadingComments = (path.node.leadingComments || []).concat(
|
|
1400
1406
|
val.leadingComments || []
|
|
@@ -109,11 +109,6 @@ qx.Class.define("qx.tool.compiler.MetaExtraction", {
|
|
|
109
109
|
|
|
110
110
|
const babelCore = require("@babel/core");
|
|
111
111
|
let src = await fs.promises.readFile(classFilename, "utf8");
|
|
112
|
-
let babelConfig = {
|
|
113
|
-
options: {
|
|
114
|
-
modules: false
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
112
|
|
|
118
113
|
let plugins = [require("@babel/plugin-syntax-jsx"), this.__plugin()];
|
|
119
114
|
|
|
@@ -373,10 +373,10 @@ qx.Class.define("qx.tool.compiler.targets.Target", {
|
|
|
373
373
|
|
|
374
374
|
appMeta.setSourceUri(mapTo ? mapTo : targetUri + "transpiled/");
|
|
375
375
|
mapTo = this.getPathMapping(
|
|
376
|
-
path.join(appRootDir, this.getOutputDir(), "resource
|
|
376
|
+
path.join(appRootDir, this.getOutputDir(), "resource")
|
|
377
377
|
);
|
|
378
378
|
|
|
379
|
-
appMeta.setResourceUri(mapTo ? mapTo : targetUri + "resource
|
|
379
|
+
appMeta.setResourceUri(mapTo ? mapTo : targetUri + "resource");
|
|
380
380
|
|
|
381
381
|
const requiredLibs = application.getRequiredLibraries();
|
|
382
382
|
|
|
@@ -158,12 +158,18 @@ qx.Class.define("qx.tool.compiler.targets.meta.Browserify", {
|
|
|
158
158
|
builtins.process = builtins._process;
|
|
159
159
|
|
|
160
160
|
return new Promise((resolve, reject) => {
|
|
161
|
-
|
|
161
|
+
const options = {
|
|
162
162
|
builtins: builtins,
|
|
163
163
|
ignoreMissing: true,
|
|
164
164
|
insertGlobals: true,
|
|
165
165
|
detectGlobals: true
|
|
166
|
-
}
|
|
166
|
+
};
|
|
167
|
+
qx.lang.Object.mergeWith(
|
|
168
|
+
options,
|
|
169
|
+
this.getAppMeta().getAnalyser().getBrowserifyConfig()?.options || {},
|
|
170
|
+
false
|
|
171
|
+
);
|
|
172
|
+
let b = browserify([], options);
|
|
167
173
|
|
|
168
174
|
b._mdeps.on("missing", (id, parent) => {
|
|
169
175
|
let message = [];
|