@qooxdoo/framework 7.0.0-beta.2 → 7.0.0-beta.6
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/CHANGELOG.md +12 -0
- package/Manifest.json +2 -3
- package/README.md +7 -3
- package/bin/deploy/qx +0 -0
- package/lib/compiler/compile-info.json +44 -45
- package/lib/compiler/index.js +1971 -8371
- package/lib/resource/qx/tool/cli/templates/loader/loader-node.tmpl.js +3 -1
- package/lib/resource/qx/tool/cli/templates/skeleton/mobile/source/theme/custom/css/custom.css +1 -1
- package/lib/resource/qx/tool/cli/templates/skeleton/mobile/source/theme/custom/css/custom.css.map +1 -1
- package/lib/resource/qx/tool/cli/templates/template_vars.js +1 -1
- package/lib/resource/qx/tool/loadsass.js +6 -12
- package/lib/resource/qx/tool/schema/Manifest-1-0-0.json +1 -2
- package/lib/resource/qx/tool/schema/Manifest-2-0-0.json +1 -2
- package/lib/resource/qx/tool/schema/compile-1-0-0.json +3 -7
- package/package.json +25 -12
- package/source/class/qx/io/__init__.js +5 -3
- package/source/class/qx/io/exception/Cancel.js +34 -0
- package/source/class/qx/io/exception/Exception.js +38 -0
- package/source/class/qx/{tool/compiler/Version.js → io/exception/Protocol.js} +13 -7
- package/source/class/qx/io/exception/Transport.js +39 -0
- package/source/class/qx/io/exception/__init__.js +4 -0
- package/source/class/qx/io/graphql/Client.js +112 -0
- package/source/class/qx/io/graphql/__init__.js +9 -0
- package/source/class/qx/io/graphql/protocol/Message.js +65 -0
- package/source/class/qx/io/graphql/protocol/Request.js +95 -0
- package/source/class/qx/io/graphql/protocol/Response.js +61 -0
- package/source/class/qx/io/graphql/protocol/__init__.js +6 -0
- package/source/class/qx/io/jsonrpc/Client.js +323 -0
- package/source/class/qx/io/jsonrpc/__init__.js +15 -0
- package/source/class/qx/io/jsonrpc/protocol/Batch.js +97 -0
- package/source/class/qx/io/jsonrpc/protocol/Error.js +63 -0
- package/source/class/qx/io/jsonrpc/protocol/Message.js +48 -0
- package/source/class/qx/io/jsonrpc/protocol/Notification.js +45 -0
- package/source/class/qx/io/jsonrpc/protocol/Parser.js +81 -0
- package/source/class/qx/io/jsonrpc/protocol/Request.js +93 -0
- package/source/class/qx/io/jsonrpc/protocol/Result.js +48 -0
- package/source/class/qx/io/jsonrpc/protocol/__init__.js +5 -0
- package/source/class/qx/io/request/authentication/Bearer.js +52 -0
- package/source/class/qx/io/transport/AbstractClient.js +100 -0
- package/source/class/qx/io/transport/AbstractTransport.js +41 -0
- package/source/class/qx/io/transport/Fetch.js +95 -0
- package/source/class/qx/io/transport/ITransport.js +40 -0
- package/source/class/qx/io/transport/PostMessage.js +55 -0
- package/source/class/qx/io/transport/Websocket.js +97 -0
- package/source/class/qx/io/transport/Xhr.js +139 -0
- package/source/class/qx/io/transport/__init__.js +18 -0
- package/source/class/qx/test/io/MAssert.js +46 -0
- package/source/class/qx/test/io/graphql/Client.js +169 -0
- package/source/class/qx/test/io/graphql/ClientFetch.js +34 -0
- package/source/class/qx/test/io/graphql/Request.js +42 -0
- package/source/class/qx/test/io/jsonrpc/Client.js +267 -0
- package/source/class/qx/test/io/jsonrpc/Protocol.js +80 -0
- package/source/class/qx/test/io/transport/PostMessage.js +56 -0
- package/source/class/qx/test/io/transport/Websocket.js +63 -0
- package/source/class/qx/test/ui/embed/Iframe.js +1 -0
- package/source/class/qx/test/ui/form/ComboBox.js +0 -42
- package/source/class/qx/test/util/DateFormat.js +45 -6
- package/source/class/qx/theme/manager/Decoration.js +0 -0
- package/source/class/qx/theme/tangible/ColorDark.js +0 -0
- package/source/class/qx/tool/cli/Cli.js +5 -3
- package/source/class/qx/tool/cli/api/CompilerApi.js +15 -5
- package/source/class/qx/tool/cli/commands/Command.js +7 -0
- package/source/class/qx/tool/cli/commands/Compile.js +4 -4
- package/source/class/qx/tool/cli/commands/Lint.js +30 -11
- package/source/class/qx/tool/cli/commands/Package.js +1 -2
- package/source/class/qx/tool/cli/commands/package/Publish.js +33 -10
- package/source/class/qx/tool/compiler/Analyser.js +21 -22
- package/source/class/qx/tool/compiler/app/WebFont.js +1 -1
- package/source/class/qx/tool/compiler/makers/AppMaker.js +15 -14
- package/source/class/qx/tool/compiler/targets/Target.js +2 -1
- package/source/class/qx/tool/compiler/targets/TypeScriptWriter.js +1 -2
- package/source/class/qx/tool/compiler/targets/meta/PolyfillJs.js +17 -9
- package/source/class/qx/tool/config/Abstract.js +3 -3
- package/source/class/qx/tool/config/Utils.js +10 -1
- package/source/class/qx/tool/utils/Json.js +1 -1
- package/source/class/qx/ui/container/SlideBar.js +3 -0
- package/source/class/qx/ui/core/Widget.js +70 -0
- package/source/class/qx/ui/core/scroll/NativeScrollBar.js +3 -0
- package/source/class/qx/ui/core/scroll/ScrollBar.js +3 -0
- package/source/class/qx/ui/form/AbstractSelectBox.js +38 -6
- package/source/class/qx/ui/form/Button.js +3 -0
- package/source/class/qx/ui/form/CheckBox.js +25 -1
- package/source/class/qx/ui/form/ComboBox.js +41 -27
- package/source/class/qx/ui/form/DateField.js +16 -1
- package/source/class/qx/ui/form/List.js +3 -0
- package/source/class/qx/ui/form/MenuButton.js +28 -2
- package/source/class/qx/ui/form/RadioButton.js +7 -0
- package/source/class/qx/ui/form/RadioButtonGroup.js +3 -0
- package/source/class/qx/ui/form/RadioGroup.js +19 -0
- package/source/class/qx/ui/form/SelectBox.js +28 -1
- package/source/class/qx/ui/form/Slider.js +15 -0
- package/source/class/qx/ui/form/SplitButton.js +3 -0
- package/source/class/qx/ui/form/ToggleButton.js +8 -0
- package/source/class/qx/ui/menu/AbstractButton.js +28 -0
- package/source/class/qx/ui/menu/Button.js +3 -0
- package/source/class/qx/ui/menu/CheckBox.js +8 -0
- package/source/class/qx/ui/menu/Manager.js +2 -0
- package/source/class/qx/ui/menu/Menu.js +74 -2
- package/source/class/qx/ui/menu/RadioButton.js +10 -1
- package/source/class/qx/ui/menubar/Button.js +0 -27
- package/source/class/qx/ui/menubar/MenuBar.js +12 -0
- package/source/class/qx/ui/splitpane/Blocker.js +3 -0
- package/source/class/qx/ui/splitpane/Pane.js +3 -0
- package/source/class/qx/ui/table/Table.js +24 -2
- package/source/class/qx/ui/table/cellrenderer/Abstract.js +3 -1
- package/source/class/qx/ui/table/cellrenderer/AbstractImage.js +7 -3
- package/source/class/qx/ui/table/headerrenderer/HeaderCell.js +3 -0
- package/source/class/qx/ui/table/pane/Header.js +3 -0
- package/source/class/qx/ui/table/pane/Model.js +10 -4
- package/source/class/qx/ui/table/pane/Scroller.js +3 -7
- package/source/class/qx/ui/table/rowrenderer/Default.js +1 -1
- package/source/class/qx/ui/tabview/Page.js +26 -0
- package/source/class/qx/ui/tabview/TabView.js +3 -0
- package/source/class/qx/ui/toolbar/Button.js +2 -27
- package/source/class/qx/ui/toolbar/CheckBox.js +0 -27
- package/source/class/qx/ui/toolbar/RadioButton.js +21 -0
- package/source/class/qx/ui/toolbar/SplitButton.js +0 -28
- package/source/class/qx/ui/toolbar/ToolBar.js +3 -0
- package/source/class/qx/ui/window/Window.js +8 -0
- package/source/class/qx/util/format/DateFormat.js +44 -17
- package/source/class/qxWeb.js +2 -0
- package/source/resource/qx/decoration/Indigo/font/JosefinSlab-SemiBold.ttf +0 -0
- package/source/resource/qx/decoration/Indigo/font/SIL Open Font License 1.1.txt +0 -0
- package/source/resource/qx/iconfont/MaterialIcons/fetch-fonts.sh +0 -0
- package/source/resource/qx/tool/bin/build-devtools +0 -0
- package/source/resource/qx/tool/bin/build-website +0 -0
- package/source/resource/qx/tool/bin/download-assets +0 -0
- package/source/resource/qx/tool/cli/templates/loader/loader-node.tmpl.js +3 -1
- package/source/resource/qx/tool/cli/templates/template_vars.js +1 -1
- package/source/resource/qx/tool/loadsass.js +6 -12
- package/source/resource/qx/tool/schema/Manifest-1-0-0.json +1 -2
- package/source/resource/qx/tool/schema/Manifest-2-0-0.json +1 -2
- package/source/resource/qx/tool/schema/compile-1-0-0.json +3 -7
- package/source/translation/hr.po +297 -0
- package/lib/resource/qx/tool/website/.gitignore +0 -2
- package/source/class/qx/io/request/auth/.gitignore +0 -0
- package/source/class/qx/test/bom/client/.gitignore +0 -0
- package/source/class/qx/test/ui/control/.gitignore +0 -0
- package/source/resource/qx/decoration/Modern/treevirtual/.gitignore +0 -0
- package/source/resource/qx/mobile/css/.gitignore +0 -3
- package/source/resource/qx/tool/website/.gitignore +0 -2
- package/source/resource/qx/website/.gitignore +0 -1
- package/source/resource/qx/website/scss/.gitignore +0 -1
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The implementation of a HTTP Transport using the {@link qx.io.request} API,
|
|
3
|
+
* so any special configuration of the HTTP request must be done on the
|
|
4
|
+
* underlying implementation of {@link qx.io.request.AbstractRequest}.
|
|
5
|
+
*
|
|
6
|
+
* The assumption is that the payload will be JSON in both request and response.
|
|
7
|
+
* If that is not what you want, override the {@link #_createTransportImpl()} method.
|
|
8
|
+
*
|
|
9
|
+
*/
|
|
10
|
+
qx.Class.define("qx.io.transport.Xhr", {
|
|
11
|
+
extend: qx.io.transport.AbstractTransport,
|
|
12
|
+
implement : qx.io.transport.ITransport,
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Constructor.
|
|
16
|
+
*
|
|
17
|
+
* @param {String} url The URL of the http endpoint
|
|
18
|
+
*/
|
|
19
|
+
construct(url) {
|
|
20
|
+
this.base(arguments, url);
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
members: {
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Internal implementation of the transport
|
|
27
|
+
* @var {qx.io.request.Xhr}
|
|
28
|
+
*/
|
|
29
|
+
__tranportImpl : null,
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Returns the object which implements the transport on the
|
|
33
|
+
* underlying level, so that transport-specific configuration
|
|
34
|
+
* can be done on it. Note that since in the HTTP transport,
|
|
35
|
+
* this object cannot be reused, it will return a new object
|
|
36
|
+
* each time which will be used in the immediately next request.
|
|
37
|
+
*
|
|
38
|
+
* @return {qx.io.request.Xhr}
|
|
39
|
+
*/
|
|
40
|
+
getTransportImpl() {
|
|
41
|
+
this.__tranportImpl = this._createTransportImpl();
|
|
42
|
+
return this.__tranportImpl;
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Transport the given message to the endpoint
|
|
47
|
+
*
|
|
48
|
+
* @param {String} message
|
|
49
|
+
*
|
|
50
|
+
* @return {qx.Promise} Promise that resolves (with no data)
|
|
51
|
+
* when the message has been successfully sent out, and rejects
|
|
52
|
+
* when there is an error or a cancellation up to that point.
|
|
53
|
+
*/
|
|
54
|
+
async send(message) {
|
|
55
|
+
qx.core.Assert.assertString(message);
|
|
56
|
+
const req = this.__tranportImpl || this.getTransportImpl();
|
|
57
|
+
req.setRequestData(message);
|
|
58
|
+
this.__tranportImpl = null; // free the internal reference for the next request
|
|
59
|
+
try {
|
|
60
|
+
await req.sendWithPromise();
|
|
61
|
+
} catch (e) {
|
|
62
|
+
if (e instanceof qx.type.BaseError) {
|
|
63
|
+
switch (e.getComment()) {
|
|
64
|
+
case "timeout":
|
|
65
|
+
throw new qx.io.exception.Transport(
|
|
66
|
+
e.toString(),
|
|
67
|
+
qx.io.exception.Transport.TIMEOUT,
|
|
68
|
+
{message}
|
|
69
|
+
);
|
|
70
|
+
case "parseError":
|
|
71
|
+
throw new qx.io.exception.Transport(
|
|
72
|
+
e.toString(),
|
|
73
|
+
qx.io.exception.Transport.INVALID_MSG_DATA,
|
|
74
|
+
{message}
|
|
75
|
+
);
|
|
76
|
+
case "abort":
|
|
77
|
+
throw new qx.io.exception.Cancel(
|
|
78
|
+
e.toString(),
|
|
79
|
+
{message}
|
|
80
|
+
);
|
|
81
|
+
case "statusError":
|
|
82
|
+
if (req.getStatus() === 400) {
|
|
83
|
+
// "400 Bad Request" is a really a protocol error (syntax error)
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
// fallthrough
|
|
87
|
+
case "error":
|
|
88
|
+
throw new qx.io.exception.Transport(
|
|
89
|
+
e.toString(),
|
|
90
|
+
qx.io.exception.Transport.FAILED,
|
|
91
|
+
{
|
|
92
|
+
message,
|
|
93
|
+
response: req.getResponse()
|
|
94
|
+
}
|
|
95
|
+
);
|
|
96
|
+
default:
|
|
97
|
+
// unknown error
|
|
98
|
+
throw new qx.io.exception.Exception(
|
|
99
|
+
e.toString(),
|
|
100
|
+
undefined,
|
|
101
|
+
{message, error:e}
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// notify listeners
|
|
107
|
+
this.fireDataEvent("message", req.getResponse());
|
|
108
|
+
// discard old object
|
|
109
|
+
req.dispose();
|
|
110
|
+
},
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Factory method to create a request object. By default, a POST
|
|
114
|
+
* request will be made, and the expected response type will be
|
|
115
|
+
* "application/json", but differently to the standard behavior,
|
|
116
|
+
* the response will not be parsed into a javascript object.
|
|
117
|
+
*
|
|
118
|
+
* Classes extending this one may override this method to obtain
|
|
119
|
+
* a Request object with different parameters and/or different
|
|
120
|
+
* authentication settings. The object must be a subclass of {@link
|
|
121
|
+
* qx.io.request.AbstractRequest} or implement its public API.
|
|
122
|
+
*
|
|
123
|
+
* @return {qx.io.request.Xhr}
|
|
124
|
+
*/
|
|
125
|
+
_createTransportImpl() {
|
|
126
|
+
const req = new qx.io.request.Xhr(this.getEndpoint(), "POST");
|
|
127
|
+
req.setAccept("application/json");
|
|
128
|
+
req.setCache(false);
|
|
129
|
+
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
|
|
130
|
+
// disable parsing, we are going to parse the JSON ourselves
|
|
131
|
+
req.setParser(response => response);
|
|
132
|
+
return req;
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
defer() {
|
|
137
|
+
qx.io.jsonrpc.Client.registerTransport(/^http/, qx.io.transport.Xhr);
|
|
138
|
+
}
|
|
139
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* <p>This namespace contains an interface for and different implementations of
|
|
3
|
+
* a transport for higher-level protocol data.</p>
|
|
4
|
+
*
|
|
5
|
+
* <p>{@link qx.io.transport.ITransport} specifies that a
|
|
6
|
+
* transport has to provide for three things:</p>
|
|
7
|
+
* <ol>
|
|
8
|
+
* <li>It must have an "endpoint" property which is a representation of the
|
|
9
|
+
* the endpoint. In most cases, it will be an URI which identifies where the
|
|
10
|
+
* the server is located, but it can also be an object with which the transport
|
|
11
|
+
* can interact.</li>
|
|
12
|
+
* <li>It must have a "send" method which knows how to deliver an UTF-8
|
|
13
|
+
* encoded message string to the endpoint, and</li>
|
|
14
|
+
* <li>It must fire a "message" event when it receives such a message from
|
|
15
|
+
* the peer, regardless if this message is a normal "response" (like in a
|
|
16
|
+
* HTTP request) or an incoming message in a duplex communication channel.</li>
|
|
17
|
+
* </ol>
|
|
18
|
+
*/
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mixin containing special assert methods
|
|
3
|
+
*/
|
|
4
|
+
qx.Mixin.define("qx.test.io.MAssert", {
|
|
5
|
+
|
|
6
|
+
members : {
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Deep equal comparison, using Sinon's `deepEqual` comparison.
|
|
10
|
+
* Two values are "deep equal" if:
|
|
11
|
+
*
|
|
12
|
+
* - They are equal, according to samsam.identical
|
|
13
|
+
* (https://sinonjs.github.io/samsam/)
|
|
14
|
+
* - They are both date objects representing the same time
|
|
15
|
+
* - They are both arrays containing elements that are all deepEqual
|
|
16
|
+
* - They are objects with the same set of properties, and each property
|
|
17
|
+
* in obj1 is deepEqual to the corresponding property in obj2
|
|
18
|
+
*
|
|
19
|
+
* Supports cyclic objects.
|
|
20
|
+
* @param {*} expected
|
|
21
|
+
* @param {*} actual
|
|
22
|
+
* @param {String?} msg
|
|
23
|
+
*/
|
|
24
|
+
assertDeepEquals : function(expected, actual, msg) {
|
|
25
|
+
if (!msg) {
|
|
26
|
+
msg = `Failed to assert that ${qx.lang.Json.stringify(actual)} deeply equals ${qx.lang.Json.stringify(expected)}.`;
|
|
27
|
+
}
|
|
28
|
+
this.assert(qx.dev.unit.Sinon.getSinon().deepEqual(expected, actual), msg);
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Asserts that a string fragment is contained in a result
|
|
33
|
+
* @param {String} expectedFragment
|
|
34
|
+
* @param {String} actual
|
|
35
|
+
* @param {String?} msg
|
|
36
|
+
*/
|
|
37
|
+
assertContains: function(expectedFragment, actual, msg) {
|
|
38
|
+
this.assertString(expectedFragment);
|
|
39
|
+
this.assertString(actual);
|
|
40
|
+
if (!msg) {
|
|
41
|
+
msg = `Failed to assert that '${actual}' contains '${expectedFragment}'.`;
|
|
42
|
+
}
|
|
43
|
+
this.assert(actual.includes(expectedFragment), msg);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
});
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/* ************************************************************************
|
|
2
|
+
|
|
3
|
+
qooxdoo - the new era of web development
|
|
4
|
+
|
|
5
|
+
http://qooxdoo.org
|
|
6
|
+
|
|
7
|
+
Copyright:
|
|
8
|
+
2020 Christian Boulanger
|
|
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
|
+
* @require(qx.io.transport.Xhr)
|
|
21
|
+
* @ignore(fetch)
|
|
22
|
+
*/
|
|
23
|
+
qx.Class.define("qx.test.io.graphql.Client",
|
|
24
|
+
{
|
|
25
|
+
extend : qx.dev.unit.TestCase,
|
|
26
|
+
include : [qx.test.io.MAssert],
|
|
27
|
+
statics: {
|
|
28
|
+
TEST_ENDPOINT: "https://countries.trevorblades.com/"
|
|
29
|
+
},
|
|
30
|
+
construct() {
|
|
31
|
+
this.base(arguments);
|
|
32
|
+
let transport = new qx.io.transport.Xhr(this.constructor.TEST_ENDPOINT);
|
|
33
|
+
transport.getTransportImpl();
|
|
34
|
+
this.client = new qx.io.graphql.Client(transport);
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
members : {
|
|
38
|
+
|
|
39
|
+
__hasEndpoint: false,
|
|
40
|
+
__skipMsg: "Skipping test as endpoint is not available.",
|
|
41
|
+
|
|
42
|
+
async runQuery(query, expected) {
|
|
43
|
+
let req = new qx.io.graphql.protocol.Request({query});
|
|
44
|
+
let result = await this.client.send(req);
|
|
45
|
+
this.assertDeepEquals(expected, result)
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
async runQueryWithVariables(query, variables, expected) {
|
|
49
|
+
let req = new qx.io.graphql.protocol.Request({query});
|
|
50
|
+
req.setVariables(variables);
|
|
51
|
+
let result = await this.client.send(req);
|
|
52
|
+
this.assertDeepEquals(expected, result)
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
async "test: check endpoint"() {
|
|
56
|
+
try {
|
|
57
|
+
let url = this.constructor.TEST_ENDPOINT;
|
|
58
|
+
let body = '{"query":"{__typename}"}';
|
|
59
|
+
let init = {method:"POST", headers:{"Content-Type":"application/json"}, body};
|
|
60
|
+
let response = await fetch(url, init);
|
|
61
|
+
let result = await response.json();
|
|
62
|
+
this.assertDeepEquals({
|
|
63
|
+
"data": {
|
|
64
|
+
"__typename": "Query"
|
|
65
|
+
}
|
|
66
|
+
}, result);
|
|
67
|
+
this.__hasEndpoint = true;
|
|
68
|
+
} catch(e) {
|
|
69
|
+
console.error(`Endpoint ${this.constructor.TEST_ENDPOINT} is not accessible: ${e.message}`);
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
async "test: execute query"() {
|
|
74
|
+
if (!this.__hasEndpoint) {
|
|
75
|
+
return this.skip(this.__skipMsg);
|
|
76
|
+
}
|
|
77
|
+
await this.runQuery(`{
|
|
78
|
+
country(code: "BR") {
|
|
79
|
+
name
|
|
80
|
+
native
|
|
81
|
+
capital
|
|
82
|
+
currency
|
|
83
|
+
languages {
|
|
84
|
+
code
|
|
85
|
+
name
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}`, {
|
|
89
|
+
"country": {
|
|
90
|
+
"name": "Brazil",
|
|
91
|
+
"native": "Brasil",
|
|
92
|
+
"capital": "Brasília",
|
|
93
|
+
"currency": "BRL",
|
|
94
|
+
"languages": [
|
|
95
|
+
{
|
|
96
|
+
"code": "pt",
|
|
97
|
+
"name": "Portuguese"
|
|
98
|
+
}
|
|
99
|
+
]
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
async "test: execute query with variables"() {
|
|
105
|
+
if (!this.__hasEndpoint) {
|
|
106
|
+
return this.skip(this.__skipMsg);
|
|
107
|
+
}
|
|
108
|
+
await this.runQueryWithVariables(`query ($countryCode:ID!){
|
|
109
|
+
country(code: $countryCode) {
|
|
110
|
+
name
|
|
111
|
+
languages {
|
|
112
|
+
code
|
|
113
|
+
name
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}`,
|
|
117
|
+
{"countryCode": "BE"},
|
|
118
|
+
{
|
|
119
|
+
"country": {
|
|
120
|
+
"name": "Belgium",
|
|
121
|
+
"languages": [
|
|
122
|
+
{
|
|
123
|
+
"code": "nl",
|
|
124
|
+
"name": "Dutch"
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"code": "fr",
|
|
128
|
+
"name": "French"
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"code": "de",
|
|
132
|
+
"name": "German"
|
|
133
|
+
}
|
|
134
|
+
]
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
},
|
|
138
|
+
|
|
139
|
+
async "test: expect error after invalid query"() {
|
|
140
|
+
if (!this.__hasEndpoint) {
|
|
141
|
+
return this.skip(this.__skipMsg);
|
|
142
|
+
}
|
|
143
|
+
try {
|
|
144
|
+
await this.runQuery(`query { invalidSyntax }`);
|
|
145
|
+
} catch (e) {
|
|
146
|
+
this.assertInstance(e, qx.io.exception.Protocol);
|
|
147
|
+
this.assertContains("invalidSyntax", JSON.stringify(e.data));
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
throw new Error("Query should return an error after invalid query");
|
|
151
|
+
},
|
|
152
|
+
|
|
153
|
+
async "test: expect transport error"() {
|
|
154
|
+
if (!this.__hasEndpoint) {
|
|
155
|
+
return this.skip(this.__skipMsg);
|
|
156
|
+
}
|
|
157
|
+
try {
|
|
158
|
+
const client = new qx.io.graphql.Client("https://doesnotexist.org/"+Math.random());
|
|
159
|
+
const query = "query { doesnotmatter }";
|
|
160
|
+
const request = new qx.io.graphql.protocol.Request({query});
|
|
161
|
+
await client.send(request);
|
|
162
|
+
} catch (e) {
|
|
163
|
+
this.assertInstance(e, qx.io.exception.Transport);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
throw new Error("Query should throw qx.io.exception.Transport");
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/* ************************************************************************
|
|
2
|
+
|
|
3
|
+
qooxdoo - the new era of web development
|
|
4
|
+
|
|
5
|
+
http://qooxdoo.org
|
|
6
|
+
|
|
7
|
+
Copyright:
|
|
8
|
+
2020 Christian Boulanger
|
|
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
|
+
* GraphQL tests using the Fetch API
|
|
21
|
+
*/
|
|
22
|
+
qx.Class.define("qx.test.io.graphql.ClientFetch",
|
|
23
|
+
{
|
|
24
|
+
extend : qx.test.io.graphql.Client,
|
|
25
|
+
statics: {
|
|
26
|
+
TEST_ENDPOINT: "https://countries.trevorblades.com/"
|
|
27
|
+
},
|
|
28
|
+
construct() {
|
|
29
|
+
this.base(arguments);
|
|
30
|
+
let transport = new qx.io.transport.Fetch(this.constructor.TEST_ENDPOINT);
|
|
31
|
+
transport.getTransportImpl();
|
|
32
|
+
this.client = new qx.io.graphql.Client(transport);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @require(qx.io.transport.Xhr)
|
|
3
|
+
*/
|
|
4
|
+
qx.Class.define("qx.test.io.graphql.Request", {
|
|
5
|
+
extend: qx.dev.unit.TestCase,
|
|
6
|
+
include: [qx.test.io.MAssert],
|
|
7
|
+
|
|
8
|
+
members: {
|
|
9
|
+
|
|
10
|
+
"test: request can be converted to json": function() {
|
|
11
|
+
const query = "query { SomeRandomStuff }";
|
|
12
|
+
const variables = {"testKey": "testValue"};
|
|
13
|
+
|
|
14
|
+
const request = new qx.io.graphql.protocol.Request({query});
|
|
15
|
+
request.setVariables(variables);
|
|
16
|
+
|
|
17
|
+
const expected = "{\"query\":\"query { SomeRandomStuff }\",\"variables\":{\"testKey\":\"testValue\"}}";
|
|
18
|
+
this.assertEquals(expected, request.toString());
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
"test: no variables in the final string": function() {
|
|
22
|
+
const query = "query { SomeRandomStuff }";
|
|
23
|
+
const request = new qx.io.graphql.protocol.Request({query});
|
|
24
|
+
const expected = "{\"query\":\"query { SomeRandomStuff }\"}";
|
|
25
|
+
this.assertEquals(expected, request.toString());
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
"test: variables can be bound": function() {
|
|
29
|
+
const query = "query { SomeRandomStuff }";
|
|
30
|
+
const variables = {"testKey": "testValue"};
|
|
31
|
+
const request = new qx.io.graphql.protocol.Request({query});
|
|
32
|
+
request.setVariables(variables);
|
|
33
|
+
|
|
34
|
+
const model = qx.data.marshal.Json.createModel({source: "test"});
|
|
35
|
+
model.bind("source", request, "variables.testKey");
|
|
36
|
+
model.setSource("newTestValue");
|
|
37
|
+
|
|
38
|
+
this.assertMatch(request.toString(), /newTestValue/);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|