1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Copyright (C) 2016 Intel Corporation. |
5 | ** Contact: https://www.qt.io/licensing/ |
6 | ** |
7 | ** This file is part of the FOO module of the Qt Toolkit. |
8 | ** |
9 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
10 | ** Commercial License Usage |
11 | ** Licensees holding valid commercial Qt licenses may use this file in |
12 | ** accordance with the commercial license agreement provided with the |
13 | ** Software or, alternatively, in accordance with the terms contained in |
14 | ** a written agreement between you and The Qt Company. For licensing terms |
15 | ** and conditions see https://www.qt.io/terms-conditions. For further |
16 | ** information use the contact form at https://www.qt.io/contact-us. |
17 | ** |
18 | ** GNU General Public License Usage |
19 | ** Alternatively, this file may be used under the terms of the GNU |
20 | ** General Public License version 3 as published by the Free Software |
21 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
22 | ** included in the packaging of this file. Please review the following |
23 | ** information to ensure the GNU General Public License requirements will |
24 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
25 | ** |
26 | ** $QT_END_LICENSE$ |
27 | ** |
28 | ****************************************************************************/ |
29 | |
30 | #include <QtTest/QtTest> |
31 | #include <QtCore/QCoreApplication> |
32 | |
33 | #include <QtDBus/private/qdbusutil_p.h> |
34 | #include <QtDBus/private/qdbus_symbols_p.h> |
35 | |
36 | DEFINEFUNC(dbus_bool_t, dbus_signature_validate, (const char *signature, |
37 | DBusError *error), |
38 | (signature, error), return) |
39 | DEFINEFUNC(dbus_bool_t, dbus_signature_validate_single, (const char *signature, |
40 | DBusError *error), |
41 | (signature, error), return) |
42 | DEFINEFUNC(dbus_bool_t, dbus_type_is_basic, (int typecode), |
43 | (typecode), return) |
44 | DEFINEFUNC(dbus_bool_t, dbus_type_is_fixed, (int typecode), |
45 | (typecode), return) |
46 | |
47 | class tst_QDBusType : public QObject |
48 | { |
49 | Q_OBJECT |
50 | |
51 | private Q_SLOTS: |
52 | void isValidFixedType_data(); |
53 | void isValidFixedType(); |
54 | void isValidBasicType_data(); |
55 | void isValidBasicType(); |
56 | void isValidSingleSignature_data(); |
57 | void isValidSingleSignature(); |
58 | void isValidArray_data(); |
59 | void isValidArray(); |
60 | void isValidSignature_data(); |
61 | void isValidSignature(); |
62 | }; |
63 | |
64 | enum { Invalid = false, Valid = true }; |
65 | |
66 | static void addColumns() |
67 | { |
68 | // All tests use these two columns only |
69 | QTest::addColumn<QString>(name: "data" ); |
70 | QTest::addColumn<bool>(name: "result" ); |
71 | QTest::addColumn<bool>(name: "isValid" ); |
72 | } |
73 | |
74 | // ---- type adds --- |
75 | static void addFixedTypes() |
76 | { |
77 | QTest::newRow(dataTag: "bool" ) << DBUS_TYPE_BOOLEAN_AS_STRING << true << true; |
78 | QTest::newRow(dataTag: "byte" ) << DBUS_TYPE_BYTE_AS_STRING << true << true; |
79 | QTest::newRow(dataTag: "int16" ) << DBUS_TYPE_INT16_AS_STRING << true << true; |
80 | QTest::newRow(dataTag: "uint16" ) << DBUS_TYPE_UINT16_AS_STRING << true << true; |
81 | QTest::newRow(dataTag: "int32" ) << DBUS_TYPE_INT32_AS_STRING << true << true; |
82 | QTest::newRow(dataTag: "uint32" ) << DBUS_TYPE_UINT32_AS_STRING << true << true; |
83 | QTest::newRow(dataTag: "int64" ) << DBUS_TYPE_INT64_AS_STRING << true << true; |
84 | QTest::newRow(dataTag: "uint64" ) << DBUS_TYPE_UINT64_AS_STRING << true << true; |
85 | QTest::newRow(dataTag: "double" ) << DBUS_TYPE_DOUBLE_AS_STRING << true << true; |
86 | |
87 | #ifdef DBUS_TYPE_UNIX_FD_AS_STRING |
88 | # ifndef QT_LINKED_LIBDBUS |
89 | // We have got the macro from dbus_minimal_p.h, so we need to check if |
90 | // the library recognizes this as valid type first. |
91 | // The following function was added for Unix FD support, so if it is |
92 | // present, so is support for Unix FDs. |
93 | # if QT_CONFIG(library) |
94 | bool supportsUnixFds = qdbus_resolve_conditionally("dbus_connection_can_send_type" ); |
95 | # else |
96 | bool supportsUnixFds = false; |
97 | # endif |
98 | # else |
99 | bool supportsUnixFds = true; |
100 | # endif |
101 | if (supportsUnixFds) |
102 | QTest::newRow(dataTag: "unixfd" ) << DBUS_TYPE_UNIX_FD_AS_STRING << true << true; |
103 | #endif |
104 | } |
105 | |
106 | static void addInvalidSingleLetterTypes() |
107 | { |
108 | QChar nulString[] = { 0 }; |
109 | QTest::newRow(dataTag: "nul" ) << QString(nulString, 1) << false << false; |
110 | QTest::newRow(dataTag: "tilde" ) << "~" << false << false; |
111 | QTest::newRow(dataTag: "struct-begin" ) << "(" << false << false; |
112 | QTest::newRow(dataTag: "struct-end" ) << ")" << false << false; |
113 | QTest::newRow(dataTag: "dict-entry-begin" ) << "{" << false << false; |
114 | QTest::newRow(dataTag: "dict-entry-end" ) << "}" << false << false; |
115 | QTest::newRow(dataTag: "array-no-element" ) << "a" << false << false; |
116 | } |
117 | |
118 | static void addBasicTypes(bool basicsAreValid) |
119 | { |
120 | addFixedTypes(); |
121 | QTest::newRow(dataTag: "string" ) << DBUS_TYPE_STRING_AS_STRING << basicsAreValid << true; |
122 | QTest::newRow(dataTag: "object-path" ) << DBUS_TYPE_OBJECT_PATH_AS_STRING << basicsAreValid << true; |
123 | QTest::newRow(dataTag: "signature" ) << DBUS_TYPE_SIGNATURE_AS_STRING << basicsAreValid << true; |
124 | } |
125 | |
126 | static void addVariant(bool variantIsValid) |
127 | { |
128 | QTest::newRow(dataTag: "variant" ) << "v" << variantIsValid << true; |
129 | } |
130 | |
131 | static void addSingleSignatures() |
132 | { |
133 | addBasicTypes(basicsAreValid: Valid); |
134 | addVariant(variantIsValid: Valid); |
135 | QTest::newRow(dataTag: "struct-1" ) << "(y)" << true; |
136 | QTest::newRow(dataTag: "struct-2" ) << "(yy)" << true; |
137 | QTest::newRow(dataTag: "struct-3" ) << "(yyv)" << true; |
138 | |
139 | QTest::newRow(dataTag: "struct-nested-1" ) << "((y))" << true; |
140 | QTest::newRow(dataTag: "struct-nested-2" ) << "((yy))" << true; |
141 | QTest::newRow(dataTag: "struct-nested-3" ) << "(y(y))" << true; |
142 | QTest::newRow(dataTag: "struct-nested-4" ) << "((y)y)" << true; |
143 | QTest::newRow(dataTag: "struct-nested-5" ) << "(y(y)y)" << true; |
144 | QTest::newRow(dataTag: "struct-nested-6" ) << "((y)(y))" << true; |
145 | |
146 | QTest::newRow(dataTag: "array-1" ) << "as" << true; |
147 | QTest::newRow(dataTag: "struct-array-1" ) << "(as)" << true; |
148 | QTest::newRow(dataTag: "struct-array-2" ) << "(yas)" << true; |
149 | QTest::newRow(dataTag: "struct-array-3" ) << "(asy)" << true; |
150 | QTest::newRow(dataTag: "struct-array-4" ) << "(yasy)" << true; |
151 | |
152 | QTest::newRow(dataTag: "dict-1" ) << "a{sy}" << true; |
153 | QTest::newRow(dataTag: "dict-2" ) << "a{sv}" << true; |
154 | QTest::newRow(dataTag: "dict-struct-1" ) << "a{s(y)}" << true; |
155 | QTest::newRow(dataTag: "dict-struct-2" ) << "a{s(yyyy)}" << true; |
156 | QTest::newRow(dataTag: "dict-struct-array" ) << "a{s(ay)}" << true; |
157 | QTest::newRow(dataTag: "dict-array" ) << "a{sas}" << true; |
158 | QTest::newRow(dataTag: "dict-array-struct" ) << "a{sa(y)}" << true; |
159 | |
160 | addInvalidSingleLetterTypes(); |
161 | QTest::newRow(dataTag: "naked-dict-empty" ) << "{}" << false; |
162 | QTest::newRow(dataTag: "naked-dict-missing-value" ) << "{i}" << false; |
163 | |
164 | QTest::newRow(dataTag: "dict-empty" ) << "a{}" << false; |
165 | QTest::newRow(dataTag: "dict-missing-value" ) << "a{i}" << false; |
166 | QTest::newRow(dataTag: "dict-non-basic-key" ) << "a{vi}" << false; |
167 | QTest::newRow(dataTag: "dict-struct-key" ) << "a{(y)y}" << false; |
168 | QTest::newRow(dataTag: "dict-missing-close" ) << "a{sv" << false; |
169 | QTest::newRow(dataTag: "dict-mismatched-close" ) << "a{sv)" << false; |
170 | QTest::newRow(dataTag: "dict-missing-value-close" ) << "a{s" << false; |
171 | |
172 | QTest::newRow(dataTag: "empty-struct" ) << "()" << false; |
173 | QTest::newRow(dataTag: "struct-missing-close" ) << "(s" << false; |
174 | QTest::newRow(dataTag: "struct-nested-missing-close-1" ) << "((s)" << false; |
175 | QTest::newRow(dataTag: "struct-nested-missing-close-2" ) << "((s" << false; |
176 | |
177 | QTest::newRow(dataTag: "struct-ending-array-no-element" ) << "(a)" << false; |
178 | } |
179 | |
180 | static void addNakedDictEntry() |
181 | { |
182 | QTest::newRow(dataTag: "naked-dict-entry" ) << "{sv}" << false; |
183 | } |
184 | |
185 | // ---- tests ---- |
186 | |
187 | void tst_QDBusType::isValidFixedType_data() |
188 | { |
189 | addColumns(); |
190 | addFixedTypes(); |
191 | addBasicTypes(basicsAreValid: Invalid); |
192 | addVariant(variantIsValid: Invalid); |
193 | addInvalidSingleLetterTypes(); |
194 | } |
195 | |
196 | void tst_QDBusType::isValidFixedType() |
197 | { |
198 | QFETCH(QString, data); |
199 | QFETCH(bool, result); |
200 | QFETCH(bool, isValid); |
201 | QVERIFY2(data.length() == 1, "Test is malformed, this function must test only one-letter types" ); |
202 | QVERIFY(isValid || (!isValid && !result)); |
203 | |
204 | int type = data.at(i: 0).unicode(); |
205 | if (isValid) |
206 | QCOMPARE(bool(q_dbus_type_is_fixed(type)), result); |
207 | QCOMPARE(QDBusUtil::isValidFixedType(type), result); |
208 | } |
209 | |
210 | void tst_QDBusType::isValidBasicType_data() |
211 | { |
212 | addColumns(); |
213 | addBasicTypes(basicsAreValid: Valid); |
214 | addVariant(variantIsValid: Invalid); |
215 | addInvalidSingleLetterTypes(); |
216 | } |
217 | |
218 | void tst_QDBusType::isValidBasicType() |
219 | { |
220 | QFETCH(QString, data); |
221 | QFETCH(bool, result); |
222 | QFETCH(bool, isValid); |
223 | QVERIFY2(data.length() == 1, "Test is malformed, this function must test only one-letter types" ); |
224 | QVERIFY(isValid || (!isValid && !result)); |
225 | |
226 | int type = data.at(i: 0).unicode(); |
227 | if (isValid) |
228 | QCOMPARE(bool(q_dbus_type_is_basic(type)), result); |
229 | QCOMPARE(QDBusUtil::isValidBasicType(type), result); |
230 | } |
231 | |
232 | void tst_QDBusType::isValidSingleSignature_data() |
233 | { |
234 | addColumns(); |
235 | addSingleSignatures(); |
236 | addNakedDictEntry(); |
237 | } |
238 | |
239 | void tst_QDBusType::isValidSingleSignature() |
240 | { |
241 | QFETCH(QString, data); |
242 | QFETCH(bool, result); |
243 | |
244 | QCOMPARE(bool(q_dbus_signature_validate_single(data.toLatin1(), 0)), result); |
245 | QCOMPARE(QDBusUtil::isValidSingleSignature(data), result); |
246 | } |
247 | |
248 | void tst_QDBusType::isValidArray_data() |
249 | { |
250 | addColumns(); |
251 | addSingleSignatures(); |
252 | } |
253 | |
254 | void tst_QDBusType::isValidArray() |
255 | { |
256 | QFETCH(QString, data); |
257 | QFETCH(bool, result); |
258 | |
259 | data.prepend(c: QLatin1Char('a')); |
260 | QCOMPARE(bool(q_dbus_signature_validate_single(data.toLatin1(), 0)), result); |
261 | QCOMPARE(QDBusUtil::isValidSingleSignature(data), result); |
262 | |
263 | data.prepend(c: QLatin1Char('a')); |
264 | QCOMPARE(bool(q_dbus_signature_validate_single(data.toLatin1(), 0)), result); |
265 | QCOMPARE(QDBusUtil::isValidSingleSignature(data), result); |
266 | } |
267 | |
268 | void tst_QDBusType::isValidSignature_data() |
269 | { |
270 | isValidSingleSignature_data(); |
271 | } |
272 | |
273 | void tst_QDBusType::isValidSignature() |
274 | { |
275 | QFETCH(QString, data); |
276 | QFETCH(bool, result); |
277 | |
278 | data.append(s: data); |
279 | if (data.at(i: 0).unicode()) |
280 | QCOMPARE(bool(q_dbus_signature_validate(data.toLatin1(), 0)), result); |
281 | QCOMPARE(QDBusUtil::isValidSignature(data), result); |
282 | } |
283 | |
284 | QTEST_MAIN(tst_QDBusType) |
285 | |
286 | #include "tst_qdbustype.moc" |
287 | |