Merge lp:~3v1n0/qmenumodel/converter-improvements into lp:qmenumodel
- converter-improvements
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Lukáš Tinkl |
Approved revision: | 150 |
Merged at revision: | 125 |
Proposed branch: | lp:~3v1n0/qmenumodel/converter-improvements |
Merge into: | lp:qmenumodel |
Prerequisite: | lp:~3v1n0/qmenumodel/variant-string-parser |
Diff against target: |
527 lines (+202/-91) 3 files modified
CMakeLists.txt (+2/-1) libqmenumodel/src/converter.cpp (+105/-81) tests/client/convertertest.cpp (+95/-9) |
To merge this branch: | bzr merge lp:~3v1n0/qmenumodel/converter-improvements |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Marco Trevisan (Treviño) | Abstain | ||
Lukáš Tinkl (community) | Approve | ||
Review via email:
|
Commit message
converter: cleanup and add support for more variant types
Description of the change

Nick Dedekind (nick-dedekind) wrote : | # |

Lukáš Tinkl (lukas-kde) wrote : | # |
Suggest using this code simplification: https:/
Otherwise it looks good

Lukáš Tinkl (lukas-kde) wrote : | # |
There's a TODO:
/* TODO: implement convertions to others types
* G_VARIANT_
* G_VARIANT_
* G_VARIANT_
* G_VARIANT_TYPE_ANY
* G_VARIANT_
* G_VARIANT_
* G_VARIANT_TYPE_UNIT
* G_VARIANT_
* G_VARIANT_
* G_VARIANT_
*/
Needs cleanup imo
Plus one fix comment inline
- 145. By Lukáš Tinkl
-
converter: use qUtf8Printable function
- 146. By Marco Trevisan (Treviño)
-
Merged variant-
string- parser into converter- improvements. - 147. By Marco Trevisan (Treviño)
-
converter: free the strv container
- 148. By Marco Trevisan (Treviño)
-
converter: free schema type on destruction

Lukáš Tinkl (lukas-kde) wrote : | # |
Yup, works fine, tests passing
- 149. By Marco Trevisan (Treviño)
-
converter: verify integer type conversions
- 150. By Marco Trevisan (Treviño)
-
converter: return a variant when the schema is a variant
- 151. By Marco Trevisan (Treviño)
-
converterTest: add conversion to GVariant and back to verify content is correct
- 152. By Marco Trevisan (Treviño)
-
converter: properly set the QByteArray using ctor, or it will be created twice
- 153. By Marco Trevisan (Treviño)
-
converterTest: add content conversions back and further from gvariant

Marco Trevisan (Treviño) (3v1n0) wrote : | # |
> Are there specific use cases for the addition of the newly supported types?
No, it's just that there might be such cases.. So I've improved the status also for existing types that were converted using more generic (and expensive) ways.

Marco Trevisan (Treviño) (3v1n0) : | # |
Preview Diff
1 | === modified file 'CMakeLists.txt' |
2 | --- CMakeLists.txt 2013-06-05 14:29:43 +0000 |
3 | +++ CMakeLists.txt 2016-10-26 12:58:34 +0000 |
4 | @@ -13,6 +13,7 @@ |
5 | pkg_check_modules(GIO REQUIRED gio-2.0>=2.32) |
6 | set(CMAKE_AUTOMOC ON) |
7 | set(CMAKE_INCLUDE_CURRENT_DIR ON) |
8 | +SET(CMAKE_CXX_FLAGS "-std=c++11") |
9 | add_definitions(-DQT_NO_KEYWORDS) |
10 | |
11 | find_program(DBUS_RUNNER dbus-test-runner) |
12 | @@ -26,7 +27,7 @@ |
13 | message(FATAL_ERROR "gcov command not found") |
14 | endif() |
15 | SET(CMAKE_C_FLAGS "-g -O0 -Wall --coverage") |
16 | - SET(CMAKE_CXX_FLAGS "-g -O0 -Wall --coverage") |
17 | + SET(CMAKE_CXX_FLAGS "-g -O0 -Wall -std=c++11 --coverage") |
18 | SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage") |
19 | include(${CMAKE_SOURCE_DIR}/cmake/lcov.cmake) |
20 | endif() |
21 | |
22 | === modified file 'libqmenumodel/src/converter.cpp' |
23 | --- libqmenumodel/src/converter.cpp 2016-10-26 12:58:34 +0000 |
24 | +++ libqmenumodel/src/converter.cpp 2016-10-26 12:58:34 +0000 |
25 | @@ -1,5 +1,5 @@ |
26 | /* |
27 | - * Copyright 2012 Canonical Ltd. |
28 | + * Copyright 2012-2016 Canonical Ltd. |
29 | * |
30 | * This program is free software; you can redistribute it and/or modify |
31 | * it under the terms of the GNU Lesser General Public License as published by |
32 | @@ -15,6 +15,7 @@ |
33 | * |
34 | * Authors: |
35 | * Renato Araujo Oliveira Filho <renato@canonical.com> |
36 | + * Marco Trevisan <marco.trevisan@canonical.com> |
37 | */ |
38 | |
39 | extern "C" { |
40 | @@ -58,6 +59,26 @@ |
41 | gsize size = 0; |
42 | const gchar *v = g_variant_get_string(value, &size); |
43 | result.setValue(QString::fromUtf8(v, size)); |
44 | + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_STRING_ARRAY)) { |
45 | + gsize size = 0; |
46 | + const gchar **sa = g_variant_get_strv(value, &size); |
47 | + QStringList list; |
48 | + for (gsize i = 0; i < size; ++i) { |
49 | + list << QString::fromUtf8(sa[i]); |
50 | + } |
51 | + result.setValue(list); |
52 | + g_free(sa); |
53 | + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_BYTESTRING)) { |
54 | + result.setValue(QByteArray(g_variant_get_bytestring(value))); |
55 | + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_BYTESTRING_ARRAY)) { |
56 | + gsize size = 0; |
57 | + const gchar **bsa = g_variant_get_bytestring_array(value, &size); |
58 | + QByteArrayList list; |
59 | + for (gsize i = 0; i < size; ++i) { |
60 | + list << bsa[i]; |
61 | + } |
62 | + result.setValue(list); |
63 | + g_free(bsa); |
64 | } else if (g_variant_type_equal(type, G_VARIANT_TYPE_VARIANT)) { |
65 | GVariant *var = g_variant_get_variant(value); |
66 | result = toQVariant(var); |
67 | @@ -110,34 +131,12 @@ |
68 | * G_VARIANT_TYPE_UNIT |
69 | * G_VARIANT_TYPE_DICT_ENTRY |
70 | * G_VARIANT_TYPE_DICTIONARY |
71 | - * G_VARIANT_TYPE_STRING_ARRAY |
72 | - * G_VARIANT_TYPE_BYTESTRING |
73 | * G_VARIANT_TYPE_OBJECT_PATH_ARRAY |
74 | - * G_VARIANT_TYPE_BYTESTRING_ARRAY |
75 | */ |
76 | |
77 | return result; |
78 | } |
79 | |
80 | -static GVariant* toGVariant(const QString &typeName, const QVariant &value) |
81 | -{ |
82 | - if (typeName == "uchar") { |
83 | - return g_variant_new_byte(value.value<uchar>()); |
84 | - } else if (typeName == "short") { |
85 | - return g_variant_new_int16(value.value<short>()); |
86 | - } else if (typeName == "ushort") { |
87 | - return g_variant_new_uint16(value.value<ushort>()); |
88 | - } else if (typeName == "long") { |
89 | - return g_variant_new_int64(value.value<long>()); |
90 | - } else if (typeName == "ulong") { |
91 | - return g_variant_new_uint64(value.value<ulong>()); |
92 | - } else { |
93 | - qWarning() << "QVariant type not supported:" << typeName; |
94 | - } |
95 | - |
96 | - return NULL; |
97 | -} |
98 | - |
99 | QVariant Converter::toQVariantFromVariantString(const QString &variantString) |
100 | { |
101 | GVariant *gvariant; |
102 | @@ -147,7 +146,7 @@ |
103 | return QVariant(); |
104 | } |
105 | |
106 | - gvariant = g_variant_parse (NULL, variantString.toUtf8().data(), NULL, NULL, &error); |
107 | + gvariant = g_variant_parse (NULL, qUtf8Printable(variantString), NULL, NULL, &error); |
108 | |
109 | if (error) { |
110 | qWarning() << "Impossible to parse" << variantString << "as variant string:"<< error->message; |
111 | @@ -184,7 +183,7 @@ |
112 | result = g_variant_new_int64(value.toLongLong()); |
113 | break; |
114 | case QVariant::String: |
115 | - result = g_variant_new_string(value.toString().toUtf8().data()); |
116 | + result = g_variant_new_string(qUtf8Printable(value.toString())); |
117 | break; |
118 | case QVariant::UInt: |
119 | result = g_variant_new_uint32(value.toUInt()); |
120 | @@ -192,6 +191,21 @@ |
121 | case QVariant::ULongLong: |
122 | result = g_variant_new_uint64(value.toULongLong()); |
123 | break; |
124 | + case QMetaType::UChar: |
125 | + result = g_variant_new_byte(value.value<uchar>()); |
126 | + break; |
127 | + case QMetaType::Short: |
128 | + result = g_variant_new_int16(value.value<short>()); |
129 | + break; |
130 | + case QMetaType::UShort: |
131 | + result = g_variant_new_uint16(value.value<ushort>()); |
132 | + break; |
133 | + case QMetaType::Long: |
134 | + result = g_variant_new_int64(value.value<long>()); |
135 | + break; |
136 | + case QMetaType::ULong: |
137 | + result = g_variant_new_uint64(value.value<ulong>()); |
138 | + break; |
139 | case QVariant::Map: |
140 | { |
141 | GVariantBuilder *b; |
142 | @@ -201,7 +215,19 @@ |
143 | QMapIterator<QString, QVariant> i(value.toMap()); |
144 | while (i.hasNext()) { |
145 | i.next(); |
146 | - g_variant_builder_add(b, "{sv}", i.key().toUtf8().data(), toGVariant(i.value())); |
147 | + g_variant_builder_add(b, "{sv}", qUtf8Printable(i.key()), toGVariant(i.value())); |
148 | + } |
149 | + result = g_variant_builder_end(b); |
150 | + g_variant_builder_unref(b); |
151 | + break; |
152 | + } |
153 | + case QMetaType::QByteArrayList: |
154 | + { |
155 | + const QByteArrayList &list = qvariant_cast<QByteArrayList>(value); |
156 | + GVariantBuilder *b = g_variant_builder_new(G_VARIANT_TYPE_BYTESTRING_ARRAY); |
157 | + |
158 | + for (const QByteArray &ba : list) { |
159 | + g_variant_builder_add_value(b, g_variant_new_bytestring(ba)); |
160 | } |
161 | result = g_variant_builder_end(b); |
162 | g_variant_builder_unref(b); |
163 | @@ -209,17 +235,28 @@ |
164 | } |
165 | case QVariant::List: |
166 | { |
167 | - QVariantList lst = value.toList(); |
168 | - GVariant **vars = g_new(GVariant*, lst.size()); |
169 | - for (int i=0; i < lst.size(); i++) { |
170 | - vars[i] = toGVariant(lst[i]); |
171 | - } |
172 | - result = g_variant_new_tuple(vars, lst.size()); |
173 | - g_free(vars); |
174 | + GVariantBuilder *b = g_variant_builder_new(G_VARIANT_TYPE_TUPLE); |
175 | + |
176 | + for (const QVariant &v : value.toList()) { |
177 | + g_variant_builder_add_value(b, toGVariant(v)); |
178 | + } |
179 | + result = g_variant_builder_end(b); |
180 | + g_variant_builder_unref(b); |
181 | + break; |
182 | + } |
183 | + case QVariant::StringList: |
184 | + { |
185 | + GVariantBuilder *b = g_variant_builder_new(G_VARIANT_TYPE_STRING_ARRAY); |
186 | + |
187 | + for (const QString &s : value.toStringList()) { |
188 | + g_variant_builder_add(b, "s", qUtf8Printable(s)); |
189 | + } |
190 | + result = g_variant_builder_end(b); |
191 | + g_variant_builder_unref(b); |
192 | break; |
193 | } |
194 | default: |
195 | - result = ::toGVariant(value.typeName(), value); |
196 | + qWarning() << "QVariant type not supported:" << value.type(); |
197 | } |
198 | |
199 | return result; |
200 | @@ -232,8 +269,7 @@ |
201 | } |
202 | |
203 | GVariant* result = NULL; |
204 | - const GVariantType* schema_type; |
205 | - schema_type = g_variant_type_new(schema); |
206 | + GVariantType* schema_type = g_variant_type_new(schema); |
207 | |
208 | if (g_variant_type_equal(schema_type, G_VARIANT_TYPE_BOOLEAN)) { |
209 | if (value.canConvert<bool>()) { |
210 | @@ -273,80 +309,65 @@ |
211 | } |
212 | } else if (g_variant_type_equal(schema_type, G_VARIANT_TYPE_STRING)) { |
213 | if (value.canConvert<QString>()) { |
214 | - result = g_variant_new_string(value.toString().toUtf8().data()); |
215 | + result = g_variant_new_string(qUtf8Printable(value.toString())); |
216 | } |
217 | } else if (g_variant_type_equal(schema_type, G_VARIANT_TYPE_VARIANT)) { |
218 | - result = Converter::toGVariant(value); |
219 | + result = g_variant_new_variant(Converter::toGVariant(value)); |
220 | } else if (g_variant_type_equal(schema_type, G_VARIANT_TYPE_VARDICT)) { |
221 | if (value.canConvert(QVariant::Map)) { |
222 | result = Converter::toGVariant(value.toMap()); |
223 | } |
224 | } else if (g_variant_type_is_array(schema_type)) { |
225 | if (value.canConvert(QVariant::List)) { |
226 | - |
227 | - const GVariantType* entry_type; |
228 | - GVariant* data; |
229 | - entry_type = g_variant_type_element(schema_type); |
230 | - gchar* entryTypeString = g_variant_type_dup_string(entry_type); |
231 | - |
232 | - QVariantList lst = value.toList(); |
233 | - GVariant **vars = g_new(GVariant*, lst.size()); |
234 | - |
235 | + const GVariantType* entryType = g_variant_type_element(schema_type); |
236 | + const gchar* entryTypeString = g_variant_type_peek_string(entryType); |
237 | + |
238 | + GVariantBuilder *b = g_variant_builder_new(G_VARIANT_TYPE_ARRAY); |
239 | bool ok = true; |
240 | - for (int i=0; i < lst.size(); i++) { |
241 | - data = Converter::toGVariantWithSchema(lst[i], entryTypeString); |
242 | + |
243 | + for (const QVariant &v : value.toList()) { |
244 | + GVariant *data = toGVariantWithSchema(v, entryTypeString); |
245 | |
246 | if (data) { |
247 | - vars[i] = data; |
248 | - } |
249 | - else { |
250 | + g_variant_builder_add_value(b, data); |
251 | + } else { |
252 | ok = false; |
253 | qWarning() << "Failed to convert list to array with schema:" << schema; |
254 | break; |
255 | } |
256 | } |
257 | if (ok) { |
258 | - result = g_variant_new_array(entry_type, vars, lst.size()); |
259 | + result = g_variant_builder_end(b); |
260 | } |
261 | - g_free(entryTypeString); |
262 | - g_free(vars); |
263 | + g_variant_builder_unref(b); |
264 | } |
265 | } else if (g_variant_type_is_tuple(schema_type)) { |
266 | if (value.canConvert(QVariant::List)) { |
267 | - GVariant* data; |
268 | - |
269 | - QVariantList lst = value.toList(); |
270 | - GVariant **vars = g_new(GVariant*, lst.size()); |
271 | - |
272 | - const GVariantType* entry_type = g_variant_type_first(schema_type); |
273 | - |
274 | + const GVariantType* entryType = g_variant_type_first(schema_type); |
275 | + |
276 | + GVariantBuilder *b = g_variant_builder_new(G_VARIANT_TYPE_TUPLE); |
277 | bool ok = true; |
278 | - for (int i=0; i < lst.size(); i++) { |
279 | - |
280 | - gchar* entryTypeString = g_variant_type_dup_string(entry_type); |
281 | - |
282 | - data = Converter::toGVariantWithSchema(lst[i], entryTypeString); |
283 | - |
284 | - if (data) { |
285 | - vars[i] = data; |
286 | - } |
287 | - else { |
288 | - ok = false; |
289 | - qWarning() << "Failed to convert list to tuple with schema:" << schema; |
290 | - g_free(entryTypeString); |
291 | - break; |
292 | - } |
293 | + |
294 | + for (const QVariant &v : value.toList()) { |
295 | + gchar* entryTypeString = g_variant_type_dup_string(entryType); |
296 | + GVariant *data = toGVariantWithSchema(v, entryTypeString); |
297 | g_free(entryTypeString); |
298 | |
299 | - entry_type = g_variant_type_next(entry_type); |
300 | - if (!entry_type) { |
301 | + if (data) { |
302 | + g_variant_builder_add_value(b, data); |
303 | + entryType = g_variant_type_next(entryType); |
304 | + if (!entryType) |
305 | + break; |
306 | + } else { |
307 | + ok = false; |
308 | + qWarning() << "Failed to convert list to array with schema:" << schema; |
309 | break; |
310 | } |
311 | } |
312 | if (ok) { |
313 | - result = g_variant_new_tuple(vars, lst.size()); |
314 | + result = g_variant_builder_end(b); |
315 | } |
316 | - g_free(vars); |
317 | + g_variant_builder_unref(b); |
318 | } |
319 | } |
320 | |
321 | @@ -354,6 +375,9 @@ |
322 | if (!result) { |
323 | result = Converter::toGVariant(value); |
324 | } |
325 | + |
326 | + g_free(schema_type); |
327 | + |
328 | return result; |
329 | } |
330 | |
331 | |
332 | === modified file 'tests/client/convertertest.cpp' |
333 | --- tests/client/convertertest.cpp 2016-10-26 12:58:34 +0000 |
334 | +++ tests/client/convertertest.cpp 2016-10-26 12:58:34 +0000 |
335 | @@ -28,13 +28,11 @@ |
336 | #include <QtTest> |
337 | #include <QDebug> |
338 | |
339 | -class QGVariantType : public QObject |
340 | +class QGVariantType |
341 | { |
342 | - Q_OBJECT |
343 | public: |
344 | QGVariantType() : type(NULL) {} |
345 | QGVariantType(const GVariantType *gvtype) : type(gvtype) {} |
346 | - QGVariantType(const QGVariantType &other) : type(other.type) {} |
347 | const GVariantType *getType() const { return type; } |
348 | operator const GVariantType*() const { return type; } |
349 | |
350 | @@ -43,14 +41,13 @@ |
351 | }; |
352 | Q_DECLARE_METATYPE(QGVariantType); |
353 | |
354 | -class QGVariant : public QObject |
355 | +class QGVariant |
356 | { |
357 | - Q_OBJECT |
358 | public: |
359 | QGVariant() : variant(NULL) {} |
360 | ~QGVariant() { if (variant) g_variant_unref(variant); } |
361 | QGVariant(GVariant *gv) : variant(g_variant_ref_sink(gv)) {} |
362 | - QGVariant(const QGVariant &other) : variant(g_variant_ref_sink(other.variant)) {} |
363 | + QGVariant(const QGVariant &other) : QGVariant(other.variant) {} |
364 | GVariant *gvariant() const { return variant; } |
365 | operator GVariant*() const { return variant; } |
366 | |
367 | @@ -104,6 +101,7 @@ |
368 | << "Expected:"<< g_variant_type_peek_string(expected_type); |
369 | } |
370 | g_variant_unref(gv); |
371 | + g_variant_type_free(expected_type); |
372 | return result; |
373 | } |
374 | |
375 | @@ -130,9 +128,16 @@ |
376 | QTest::newRow("UInt64") << QVariant::fromValue<qulonglong>(42) << QGVariantType(G_VARIANT_TYPE_UINT64); |
377 | QTest::newRow("Double") << QVariant((double)42.42) << QGVariantType(G_VARIANT_TYPE_DOUBLE); |
378 | QTest::newRow("String") << QVariant(QString("42")) << QGVariantType(G_VARIANT_TYPE_STRING); |
379 | + QTest::newRow("String List") << QVariant(QStringList({"42", "42"})) << QGVariantType(G_VARIANT_TYPE_STRING_ARRAY); |
380 | QTest::newRow("ByteArray") << QVariant(QByteArray("42")) << QGVariantType(G_VARIANT_TYPE_BYTESTRING); |
381 | QTest::newRow("Map") << QVariant(QVariantMap()) << QGVariantType(G_VARIANT_TYPE_VARDICT); |
382 | + QTest::newRow("Map Filled") << QVariant(QVariantMap({{"fooBar", 0xdeadbeef}})) << QGVariantType(G_VARIANT_TYPE_VARDICT); |
383 | QTest::newRow("List") << QVariant(QVariantList()) << QGVariantType(G_VARIANT_TYPE_UNIT); |
384 | + QTest::newRow("List Filled") << QVariant(QVariantList({"fooBar", 0xdeadbeef})) << QGVariantType(G_VARIANT_TYPE("(su)")); |
385 | + |
386 | + QVariant result; |
387 | + result.setValue(QByteArrayList({"42", "53"})); |
388 | + QTest::newRow("ByteArrayList") << result << QGVariantType(G_VARIANT_TYPE_BYTESTRING_ARRAY); |
389 | } |
390 | |
391 | void testConvertToGVariant() |
392 | @@ -143,6 +148,23 @@ |
393 | QVERIFY(compare(value, expectedType)); |
394 | } |
395 | |
396 | + void testConvertToGVariantAndBack_data() |
397 | + { |
398 | + testConvertToGVariant_data(); |
399 | + } |
400 | + |
401 | + void testConvertToGVariantAndBack() |
402 | + { |
403 | + QFETCH(QVariant, value); |
404 | + |
405 | + GVariant *gv = Converter::toGVariant(value); |
406 | + QVERIFY(gv != NULL); |
407 | + |
408 | + QCOMPARE(Converter::toQVariant(gv), value); |
409 | + |
410 | + g_variant_unref(gv); |
411 | + } |
412 | + |
413 | void testTupleConversion() |
414 | { |
415 | QVariantList qTuple; |
416 | @@ -175,9 +197,22 @@ |
417 | QTest::addColumn<QVariant>("value"); |
418 | QTest::addColumn<QString>("schema"); |
419 | |
420 | + // convert to byte |
421 | + QTest::newRow("byte") << QVariant::fromValue<int>(1) << "y"; |
422 | + |
423 | // convert to integer |
424 | QTest::newRow("integer") << QVariant::fromValue<int>(1) << "i"; |
425 | QTest::newRow("integer from double") << QVariant::fromValue<double>(1.1) << "i"; |
426 | + QTest::newRow("int16") << QVariant::fromValue<int>(-1) << "n"; |
427 | + QTest::newRow("uint16") << QVariant::fromValue<int>(1) << "q"; |
428 | + QTest::newRow("uint32") << QVariant::fromValue<int>(1) << "u"; |
429 | + QTest::newRow("int64") << QVariant::fromValue<int>(1) << "x"; |
430 | + QTest::newRow("uint64") << QVariant::fromValue<int>(1) << "t"; |
431 | + |
432 | + // convert to variant |
433 | + QTest::newRow("variant from int") << QVariant::fromValue<int>(1) << "v"; |
434 | + QTest::newRow("variant from double") << QVariant::fromValue<double>(1.1) << "v"; |
435 | + QTest::newRow("variant from string") << QVariant::fromValue<QString>("string") << "v"; |
436 | |
437 | // convert to bool |
438 | QTest::newRow("bool") << QVariant::fromValue<bool>(true) << "b"; |
439 | @@ -242,17 +277,24 @@ |
440 | QTest::newRow("UInt64") << QGVariant(g_variant_new_uint64(53)) << (unsigned) QVariant::ULongLong; |
441 | QTest::newRow("Double") << QGVariant(g_variant_new_double(53.3)) << (unsigned) QVariant::Double; |
442 | QTest::newRow("String") << QGVariant(g_variant_new_string("53")) << (unsigned) QVariant::String; |
443 | + QTest::newRow("Byte string") << QGVariant(g_variant_new_bytestring("53")) << (unsigned) QVariant::ByteArray; |
444 | QTest::newRow("Tuple") << QGVariant(g_variant_new("(si)", "foo", 53)) << (unsigned) QVariant::List; |
445 | |
446 | - GVariantBuilder* builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); |
447 | - g_variant_builder_add(builder, "{sv}", "fooo", g_variant_new_variant(g_variant_new_int64(53))); |
448 | - QTest::newRow("Map") << QGVariant(g_variant_new("a{sv}", builder)) << (unsigned) QVariant::Map; |
449 | + GVariantBuilder* builder = g_variant_builder_new(G_VARIANT_TYPE_VARDICT); |
450 | + g_variant_builder_add(builder, "{sv}", "fooo", g_variant_new_int64(53)); |
451 | + QTest::newRow("Map") << QGVariant(g_variant_builder_end(builder)) << (unsigned) QVariant::Map; |
452 | g_variant_builder_unref(builder); |
453 | |
454 | builder = g_variant_builder_new(G_VARIANT_TYPE("ai")); |
455 | g_variant_builder_add(builder, "i", g_variant_new_int32(53)); |
456 | QTest::newRow("List") << QGVariant(g_variant_new("ai", builder)) << (unsigned) QVariant::List; |
457 | g_variant_builder_unref(builder); |
458 | + |
459 | + QTest::newRow("Tuple") << QGVariant(g_variant_new("(i)", 53)) << (unsigned) QVariant::List; |
460 | + |
461 | + const gchar *byteArray[] = {"42", "53", NULL}; |
462 | + QTest::newRow("ByteArrayList") << QGVariant(g_variant_new_bytestring_array(byteArray, -1)) << (unsigned) QMetaType::QByteArrayList; |
463 | + QTest::newRow("String List") << QGVariant(g_variant_new_strv(byteArray, -1)) << (unsigned) QVariant::StringList; |
464 | } |
465 | |
466 | void testConvertToQVariant() |
467 | @@ -263,6 +305,47 @@ |
468 | QVERIFY(compare(value, (QVariant::Type) expectedType)); |
469 | } |
470 | |
471 | + void testConvertToQVariantAndBack_data() |
472 | + { |
473 | + testConvertToQVariant_data(); |
474 | + } |
475 | + |
476 | + void testConvertToQVariantAndBack() |
477 | + { |
478 | + QFETCH(QGVariant, value); |
479 | + |
480 | + QVariant qv = Converter::toQVariant(value); |
481 | + QVERIFY(qv.isValid()); |
482 | + |
483 | + GVariant *gv = Converter::toGVariant(qv); |
484 | + gboolean equals = g_variant_equal(value, gv); |
485 | + |
486 | + if (!equals && qv.type() == QVariant::List) { |
487 | + QVERIFY(g_variant_type_is_array(g_variant_get_type(value))); |
488 | + QVERIFY(g_variant_type_is_tuple(g_variant_get_type(gv))); |
489 | + |
490 | + gsize vsize = g_variant_n_children(value); |
491 | + QCOMPARE(vsize, g_variant_n_children(gv)); |
492 | + |
493 | + for (gsize i = 0; i < vsize; ++i) { |
494 | + equals = g_variant_equal(g_variant_get_child_value(value, i), g_variant_get_child_value(gv, i)); |
495 | + if (!equals) |
496 | + break; |
497 | + } |
498 | + } |
499 | + |
500 | + if (!equals) { |
501 | + gchar *vs = g_variant_print(value, TRUE); |
502 | + gchar *gvs = g_variant_print(gv, TRUE); |
503 | + qWarning() << "Values do not match. Old" << vs << "converted" << gvs; |
504 | + g_free(vs); |
505 | + g_free(gvs); |
506 | + } |
507 | + |
508 | + g_variant_unref(gv); |
509 | + QVERIFY(equals != FALSE); |
510 | + } |
511 | + |
512 | void testConvertToQVariantFromString_data() |
513 | { |
514 | QTest::addColumn<QString>("value"); |
515 | @@ -279,9 +362,12 @@ |
516 | QTest::newRow("Double") << "double 65" << (unsigned) QVariant::Double; |
517 | QTest::newRow("String") << "string '65'" << (unsigned) QVariant::String; |
518 | QTest::newRow("String simple") << "\"65\"" << (unsigned) QVariant::String; |
519 | + QTest::newRow("String List") << "['foo', 'bar']" << (unsigned) QVariant::StringList; |
520 | + QTest::newRow("Byte string") << "b'fooo'" << (unsigned) QVariant::ByteArray; |
521 | QTest::newRow("Map") << "{'foo': <65>}" << (unsigned) QVariant::Map; |
522 | QTest::newRow("List") << "[65, 66]" << (unsigned) QVariant::List; |
523 | QTest::newRow("Tuple") << "('foo', 65)" << (unsigned) QVariant::List; |
524 | + QTest::newRow("ByteArrayList") << "[b'foo', b'bar']" << (unsigned) QMetaType::QByteArrayList; |
525 | } |
526 | |
527 | void testConvertToQVariantFromString() |
Are there specific use cases for the addition of the newly supported types?