Merge lp:~autopilot/autopilot-qt/experimental into lp:autopilot-qt
- experimental
- Merge into trunk
Proposed by
Thomi Richards
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Approved by: | Thomi Richards | ||||||||
Approved revision: | 85 | ||||||||
Merged at revision: | 71 | ||||||||
Proposed branch: | lp:~autopilot/autopilot-qt/experimental | ||||||||
Merge into: | lp:autopilot-qt | ||||||||
Diff against target: |
1194 lines (+610/-161) 15 files modified
debian/changelog (+7/-0) debian/control (+4/-2) driver/autopilot_types.h (+26/-0) driver/dbus_adaptor.cpp (+1/-1) driver/dbus_object.cpp (+4/-2) driver/driver.pro (+2/-1) driver/introspection.cpp (+62/-25) driver/introspection.h (+1/-1) driver/qtnode.cpp (+125/-50) driver/qtnode.h (+29/-8) driver/qttestability.cpp (+3/-0) driver/rootnode.cpp (+15/-26) driver/rootnode.h (+2/-4) tests/unittests/tst_introspection.cpp (+326/-39) tests/unittests/unittests.pro (+3/-2) |
||||||||
To merge this branch: | bzr merge lp:~autopilot/autopilot-qt/experimental | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Approve | |
Autopilot Hackers | Pending | ||
Review via email:
|
Commit message
1.4 wire protocol changes.
Description of the change
Merge 1.4 changes.
To post a comment you must log in.
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
review:
Needs Fixing
(continuous-integration)
- 85. By Thomi Richards
-
Add Breaks clause on binary package.
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:85
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
review:
Approve
(continuous-integration)
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'debian/changelog' |
2 | --- debian/changelog 2013-08-14 02:04:35 +0000 |
3 | +++ debian/changelog 2013-09-16 18:00:39 +0000 |
4 | @@ -1,3 +1,10 @@ |
5 | +autopilot-qt (1.4-0ubuntu1) saucy; urgency=low |
6 | + |
7 | + [ Thomi Richards ] |
8 | + * Update to new xpathselect 1.4 API. Version bump to 1.4. |
9 | + |
10 | + -- Thomi Richards <thomi.richards@canonical.com> Thu, 15 Aug 2013 11:23:33 +1200 |
11 | + |
12 | autopilot-qt (1.3+13.10.20130814-0ubuntu1) saucy; urgency=low |
13 | |
14 | [ Robert Bruce Park ] |
15 | |
16 | === modified file 'debian/control' |
17 | --- debian/control 2013-08-13 22:39:44 +0000 |
18 | +++ debian/control 2013-09-16 18:00:39 +0000 |
19 | @@ -6,7 +6,7 @@ |
20 | libgl1-mesa-dev, |
21 | libgles2-mesa-dev, |
22 | libqt4-dev, |
23 | - libxpathselect-dev (>= 1.3), |
24 | + libxpathselect-dev (>= 1.4), |
25 | mesa-common-dev, |
26 | pkg-config, |
27 | qt4-qmake, |
28 | @@ -27,9 +27,11 @@ |
29 | Package: libautopilot-qt |
30 | Section: libs |
31 | Architecture: any |
32 | -Depends: libxpathselect1.3, |
33 | +Depends: libxpathselect1.4, |
34 | ${misc:Depends}, |
35 | ${shlibs:Depends}, |
36 | +Breaks: python-autopilot (<< 1.4), |
37 | + python3-autopilot (<< 1.4) |
38 | Replaces: autopilot-qt, |
39 | autopilot-qt5, |
40 | Conflicts: autopilot-qt, |
41 | |
42 | === added file 'driver/autopilot_types.h' |
43 | --- driver/autopilot_types.h 1970-01-01 00:00:00 +0000 |
44 | +++ driver/autopilot_types.h 2013-09-16 18:00:39 +0000 |
45 | @@ -0,0 +1,26 @@ |
46 | +/* |
47 | +Copyright 2012 Canonical |
48 | + |
49 | +This program is free software: you can redistribute it and/or modify it |
50 | +under the terms of the GNU General Public License version 3, as published |
51 | +by the Free Software Foundation. |
52 | +*/ |
53 | + |
54 | + |
55 | +#ifndef AUTOPILOT_TYPES_H |
56 | +#define AUTOPILOT_TYPES_H |
57 | + |
58 | +/// IMPORTANT: THese constants are taken from the autopilot XPathSelect protocol document. |
59 | +/// Only add options here if the support has been added for them in autopilot itself. |
60 | +enum autopilot_type_id |
61 | +{ |
62 | + TYPE_PLAIN = 0, |
63 | + TYPE_RECT = 1, |
64 | + TYPE_POINT = 2, |
65 | + TYPE_SIZE = 3, |
66 | + TYPE_COLOR = 4, |
67 | + TYPE_DATETIME = 5, |
68 | + TYPE_TIME = 6, |
69 | +}; |
70 | + |
71 | +#endif |
72 | |
73 | === modified file 'driver/dbus_adaptor.cpp' |
74 | --- driver/dbus_adaptor.cpp 2013-05-07 23:46:49 +0000 |
75 | +++ driver/dbus_adaptor.cpp 2013-09-16 18:00:39 +0000 |
76 | @@ -51,7 +51,7 @@ |
77 | void AutopilotAdaptor::GetVersion(const QDBusMessage &message) |
78 | { |
79 | QDBusMessage reply = message.createReply(); |
80 | - reply << QVariant(QString("1.3")); |
81 | + reply << QVariant(QString("1.4")); |
82 | QDBusConnection::sessionBus().send(reply); |
83 | } |
84 | |
85 | |
86 | === modified file 'driver/dbus_object.cpp' |
87 | --- driver/dbus_object.cpp 2013-06-27 16:27:11 +0000 |
88 | +++ driver/dbus_object.cpp 2013-09-16 18:00:39 +0000 |
89 | @@ -294,10 +294,12 @@ |
90 | void DBusObject::ProcessQuery() |
91 | { |
92 | Query query = _queries.takeFirst(); |
93 | - QList<QVariant> state = Introspect(query.first); |
94 | + QList<NodeIntrospectionData> state = Introspect(query.first); |
95 | |
96 | QDBusMessage msg = query.second; |
97 | - msg << QVariant(state); |
98 | + QVariant var; |
99 | + var.setValue(state); |
100 | + msg << var; |
101 | |
102 | QDBusConnection::sessionBus().send(msg); |
103 | } |
104 | |
105 | === modified file 'driver/driver.pro' |
106 | --- driver/driver.pro 2013-01-17 20:20:44 +0000 |
107 | +++ driver/driver.pro 2013-09-16 18:00:39 +0000 |
108 | @@ -29,7 +29,8 @@ |
109 | rootnode.h \ |
110 | qtnode.h \ |
111 | introspection.h \ |
112 | - dbus_adaptor_qt.h |
113 | + dbus_adaptor_qt.h \ |
114 | + autopilot_types.h |
115 | |
116 | target.file = libtestability* |
117 | |
118 | |
119 | === modified file 'driver/introspection.cpp' |
120 | --- driver/introspection.cpp 2013-06-26 09:00:13 +0000 |
121 | +++ driver/introspection.cpp 2013-09-16 18:00:39 +0000 |
122 | @@ -37,6 +37,7 @@ |
123 | #include <QUrl> |
124 | #include <QDateTime> |
125 | |
126 | +#include "autopilot_types.h" |
127 | #include "introspection.h" |
128 | #include "qtnode.h" |
129 | #include "rootnode.h" |
130 | @@ -47,13 +48,13 @@ |
131 | QStringList GetNodeChildNames(QObject* obj); |
132 | void AddCustomProperties(QObject* obj, QVariantMap& properties); |
133 | |
134 | -QList<QVariant> Introspect(QString const& query_string) |
135 | +QList<NodeIntrospectionData> Introspect(QString const& query_string) |
136 | { |
137 | - QList<QVariant> state; |
138 | + QList<NodeIntrospectionData> state; |
139 | QList<QtNode::Ptr> node_list = GetNodesThatMatchQuery(query_string); |
140 | foreach (QtNode::Ptr obj, node_list) |
141 | { |
142 | - state.append(obj->IntrospectNode()); |
143 | + state.append(obj->GetIntrospectionData()); |
144 | } |
145 | |
146 | return state; |
147 | @@ -85,11 +86,11 @@ |
148 | #endif |
149 | QList<QtNode::Ptr> node_list; |
150 | |
151 | - xpathselect::NodeList list = xpathselect::SelectNodes(root, query_string.toStdString()); |
152 | + xpathselect::NodeVector list = xpathselect::SelectNodes(root, query_string.toStdString()); |
153 | for (auto node : list) |
154 | { |
155 | // node may be our root node wrapper *or* an ordinary qobject wrapper |
156 | - auto object_ptr = std::static_pointer_cast<QtNode>(node); |
157 | + auto object_ptr = std::static_pointer_cast<const QtNode>(node); |
158 | if (object_ptr) |
159 | { |
160 | node_list.append(object_ptr); |
161 | @@ -154,7 +155,7 @@ |
162 | // add the 'Children' pseudo-property: |
163 | QStringList children = GetNodeChildNames(obj); |
164 | if (!children.empty()) |
165 | - object_properties["Children"] = children; |
166 | + object_properties["Children"] = PackProperty(children); |
167 | |
168 | return object_properties; |
169 | } |
170 | @@ -211,69 +212,105 @@ |
171 | case QVariant::StringList: |
172 | case QVariant::Double: |
173 | { |
174 | - return prop; |
175 | + return QList<QVariant> { |
176 | + QVariant(TYPE_PLAIN), |
177 | + prop |
178 | + }; |
179 | } |
180 | |
181 | case QVariant::ByteArray: |
182 | { |
183 | - return QVariant(QString(qvariant_cast<QByteArray>(prop))); |
184 | + return QList<QVariant> { |
185 | + QVariant(TYPE_PLAIN), |
186 | + QVariant(QString(qvariant_cast<QByteArray>(prop))) |
187 | + }; |
188 | } |
189 | |
190 | case QVariant::Point: |
191 | { |
192 | QPoint p = qvariant_cast<QPoint>(prop); |
193 | - QList<QVariant> l = {QVariant(p.x()), QVariant(p.y())}; |
194 | - return QVariant(l); |
195 | + return QList<QVariant> { |
196 | + QVariant(TYPE_POINT), |
197 | + QVariant(p.x()), |
198 | + QVariant(p.y()) |
199 | + }; |
200 | } |
201 | |
202 | case QVariant::Rect: |
203 | { |
204 | QRect r = qvariant_cast<QRect>(prop); |
205 | - QList<QVariant> l = { |
206 | + return QList<QVariant> { |
207 | + QVariant(TYPE_RECT), |
208 | QVariant(r.x()), |
209 | QVariant(r.y()), |
210 | QVariant(r.width()), |
211 | QVariant(r.height()) }; |
212 | - return QVariant(l); |
213 | } |
214 | |
215 | case QVariant::Size: |
216 | { |
217 | QSize s = qvariant_cast<QSize>(prop); |
218 | - QList<QVariant> l = { QVariant(s.width()), QVariant(s.height()) }; |
219 | - return QVariant(l); |
220 | + return QList<QVariant> { |
221 | + QVariant(TYPE_SIZE), |
222 | + QVariant(s.width()), |
223 | + QVariant(s.height()) |
224 | + }; |
225 | } |
226 | |
227 | case QVariant::Color: |
228 | { |
229 | QColor color = qvariant_cast<QColor>(prop).toRgb(); |
230 | - QList<QVariant> l = { QVariant(color.red()), |
231 | - QVariant(color.green()), |
232 | - QVariant(color.blue()), |
233 | - QVariant(color.alpha()) |
234 | - }; |
235 | - return QVariant(l); |
236 | + return QList<QVariant> { |
237 | + QVariant(TYPE_COLOR), |
238 | + QVariant(color.red()), |
239 | + QVariant(color.green()), |
240 | + QVariant(color.blue()), |
241 | + QVariant(color.alpha()) |
242 | + }; |
243 | } |
244 | |
245 | case QVariant::Url: |
246 | { |
247 | - return QVariant(prop.toUrl().toString()); |
248 | + return QList<QVariant> { |
249 | + QVariant(TYPE_PLAIN), |
250 | + QVariant(prop.toUrl().toString()) |
251 | + }; |
252 | } |
253 | |
254 | // Depending on the architecture, floating points might be of type QMetaType::Float instead of QVariant::Double |
255 | // QDBus however, can only carry QVariant types, so lets convert it to QVariant::Double |
256 | case QMetaType::Float: |
257 | { |
258 | - return QVariant(prop.toDouble()); |
259 | + return QList<QVariant> { |
260 | + QVariant(TYPE_PLAIN), |
261 | + QVariant(prop.toDouble()) |
262 | + }; |
263 | } |
264 | + |
265 | case QVariant::Date: |
266 | case QVariant::DateTime: |
267 | - return QVariant(prop.toDateTime().toTime_t()); |
268 | + { |
269 | + return QList<QVariant> { |
270 | + QVariant(TYPE_DATETIME), |
271 | + QVariant(prop.toDateTime().toTime_t()) |
272 | + }; |
273 | + } |
274 | + |
275 | case QVariant::Time: |
276 | - return QVariant(prop.toTime().toString("hh:mm:ss")); |
277 | + { |
278 | + QTime t = qvariant_cast<QTime>(prop); |
279 | + return QList<QVariant> { |
280 | + QVariant(TYPE_TIME), |
281 | + QVariant(t.hour()), |
282 | + QVariant(t.minute()), |
283 | + QVariant(t.second()), |
284 | + QVariant(t.msec()) |
285 | + }; |
286 | + } |
287 | + |
288 | default: |
289 | { |
290 | - return QVariant(); |
291 | + return QVariant(); // unsupported type, will not be sent to the client. |
292 | } |
293 | } |
294 | } |
295 | |
296 | === modified file 'driver/introspection.h' |
297 | --- driver/introspection.h 2012-08-23 22:01:03 +0000 |
298 | +++ driver/introspection.h 2013-09-16 18:00:39 +0000 |
299 | @@ -14,7 +14,7 @@ |
300 | #include <QVariantMap> |
301 | |
302 | /// Introspect 'obj' and return it's properties in a QVariantMap. |
303 | -QList<QVariant> Introspect(const QString& query_string); |
304 | +QList<NodeIntrospectionData> Introspect(const QString& query_string); |
305 | |
306 | /// Get a list of QtNode pointers that match the given query. |
307 | QList<QtNode::Ptr> GetNodesThatMatchQuery(QString const& query_string); |
308 | |
309 | === modified file 'driver/qtnode.cpp' |
310 | --- driver/qtnode.cpp 2013-06-19 10:56:21 +0000 |
311 | +++ driver/qtnode.cpp 2013-09-16 18:00:39 +0000 |
312 | @@ -15,41 +15,54 @@ |
313 | #include <QGraphicsScene> |
314 | #include <QGraphicsObject> |
315 | #endif |
316 | +#include <QDBusArgument> |
317 | + |
318 | +// Marshall the NodeIntrospectionData data into a D-Bus argument |
319 | + QDBusArgument &operator<<(QDBusArgument &argument, const NodeIntrospectionData &node_data) |
320 | + { |
321 | + argument.beginStructure(); |
322 | + argument << node_data.object_path << node_data.state; |
323 | + argument.endStructure(); |
324 | + return argument; |
325 | + } |
326 | + |
327 | + // Retrieve the NodeIntrospectionData data from the D-Bus argument |
328 | + const QDBusArgument &operator>>(const QDBusArgument &argument, NodeIntrospectionData &node_data) |
329 | + { |
330 | + argument.beginStructure(); |
331 | + argument >> node_data.object_path >> node_data.state; |
332 | + argument.endStructure(); |
333 | + return argument; |
334 | + } |
335 | |
336 | const QByteArray AP_ID_NAME("_autopilot_id"); |
337 | |
338 | -QtNode::QtNode(QObject *obj, std::string const& parent_path) |
339 | - : object_(obj) |
340 | +QtNode::QtNode(QObject *obj, QtNode::Ptr parent) |
341 | +: object_(obj) |
342 | +, parent_(parent) |
343 | { |
344 | + std::string parent_path = parent ? parent->GetPath() : ""; |
345 | full_path_ = parent_path + "/" + GetName(); |
346 | } |
347 | |
348 | +QtNode::QtNode(QObject* obj) |
349 | +: object_(obj) |
350 | +{ |
351 | + full_path_ = "/" + GetName(); |
352 | +} |
353 | + |
354 | QObject* QtNode::getWrappedObject() const |
355 | { |
356 | return object_; |
357 | } |
358 | |
359 | -QVariant QtNode::IntrospectNode() const |
360 | -{ |
361 | - // return must be (name, state_map) |
362 | - QString object_name = QString::fromStdString(GetPath()); |
363 | - QVariantMap object_properties = GetNodeProperties(object_); |
364 | - object_properties["id"] = GetObjectId(); |
365 | - QList<QVariant> object_tuple = { QVariant(object_name), QVariant(object_properties) }; |
366 | - return QVariant(object_tuple); |
367 | -} |
368 | - |
369 | -qint64 QtNode::GetObjectId() const |
370 | -{ |
371 | - // Note: This starts at 1 for a reason - 1 is reserved for the pseudo root node, and |
372 | - // so must never be allocated to a regular object. |
373 | - static qint64 next_id=1; |
374 | - |
375 | - QList<QByteArray> property_names = object_->dynamicPropertyNames(); |
376 | - if (!property_names.contains(AP_ID_NAME)) |
377 | - object_->setProperty(AP_ID_NAME, QVariant(++next_id)); |
378 | - return object_->property(AP_ID_NAME).toLongLong(); |
379 | - |
380 | +NodeIntrospectionData QtNode::GetIntrospectionData() const |
381 | +{ |
382 | + NodeIntrospectionData data; |
383 | + data.object_path = QString::fromStdString(GetPath()); |
384 | + data.state = GetNodeProperties(object_); |
385 | + data.state["id"] = PackProperty(GetId()); |
386 | + return data; |
387 | } |
388 | |
389 | std::string QtNode::GetName() const |
390 | @@ -68,30 +81,86 @@ |
391 | return full_path_; |
392 | } |
393 | |
394 | -bool QtNode::MatchProperty(const std::string& name, const std::string& value) const |
395 | +int32_t QtNode::GetId() const |
396 | +{ |
397 | + // Note: This method is used to assign ids to both the root node (with a QApplication object) and |
398 | + // child nodes. This used to be separate code, but now that we export QApplication properties, |
399 | + // we can use this one method everywhere. |
400 | + static int32_t next_id=0; |
401 | + |
402 | + QList<QByteArray> property_names = object_->dynamicPropertyNames(); |
403 | + if (!property_names.contains(AP_ID_NAME)) |
404 | + { |
405 | + int32_t new_id = ++next_id; |
406 | + object_->setProperty(AP_ID_NAME, QVariant(new_id)); |
407 | + } |
408 | + return qvariant_cast<int32_t>(object_->property(AP_ID_NAME)); |
409 | +} |
410 | + |
411 | +bool QtNode::MatchStringProperty(const std::string& name, const std::string& value) const |
412 | +{ |
413 | + QVariantMap properties = GetNodeProperties(object_); |
414 | + |
415 | + QString qname = QString::fromStdString(name); |
416 | + if (! properties.contains(qname)) |
417 | + return false; |
418 | + |
419 | + QVariant object_value = qvariant_cast<QVariantList>(properties[qname]).at(1); |
420 | + QVariant check_value(QString::fromStdString(value)); |
421 | + if (check_value.canConvert(object_value.type())) |
422 | + { |
423 | + check_value.convert(object_value.type()); |
424 | + return check_value == object_value; |
425 | + } |
426 | + |
427 | + return false; |
428 | +} |
429 | + |
430 | +bool QtNode::MatchIntegerProperty(const std::string& name, int32_t value) const |
431 | { |
432 | if (name == "id") |
433 | - return QString::fromStdString(value).toLongLong() == GetObjectId(); |
434 | - QVariantMap properties = GetNodeProperties(object_); |
435 | - |
436 | - QString qname = QString::fromStdString(name); |
437 | - if (! properties.contains(qname)) |
438 | - return false; |
439 | - |
440 | - QVariant object_value = properties[qname]; |
441 | - QVariant check_value(QString::fromStdString(value)); |
442 | - if (check_value.canConvert(object_value.type())) |
443 | - { |
444 | - check_value.convert(object_value.type()); |
445 | - return check_value == object_value; |
446 | - } |
447 | - |
448 | - return false; |
449 | -} |
450 | - |
451 | -xpathselect::NodeList QtNode::Children() const |
452 | -{ |
453 | - xpathselect::NodeList children; |
454 | + return value == GetId(); |
455 | + |
456 | + QVariantMap properties = GetNodeProperties(object_); |
457 | + |
458 | + QString qname = QString::fromStdString(name); |
459 | + if (! properties.contains(qname)) |
460 | + return false; |
461 | + |
462 | + QVariant object_value = qvariant_cast<QVariantList>(properties[qname]).at(1); |
463 | + QVariant check_value(value); |
464 | + if (check_value.canConvert(object_value.type())) |
465 | + { |
466 | + check_value.convert(object_value.type()); |
467 | + return check_value == object_value; |
468 | + } |
469 | + |
470 | + return false; |
471 | +} |
472 | + |
473 | +bool QtNode::MatchBooleanProperty(const std::string& name, bool value) const |
474 | +{ |
475 | + QVariantMap properties = GetNodeProperties(object_); |
476 | + |
477 | + QString qname = QString::fromStdString(name); |
478 | + if (! properties.contains(qname)) |
479 | + return false; |
480 | + |
481 | + QVariant object_value = qvariant_cast<QVariantList>(properties[qname]).at(1); |
482 | + QVariant check_value(value); |
483 | + |
484 | + if (check_value.canConvert(object_value.type())) |
485 | + { |
486 | + check_value.convert(object_value.type()); |
487 | + return check_value == object_value; |
488 | + } |
489 | + |
490 | + return false; |
491 | +} |
492 | + |
493 | +xpathselect::NodeVector QtNode::Children() const |
494 | +{ |
495 | + xpathselect::NodeVector children; |
496 | |
497 | #ifdef QT5_SUPPORT |
498 | // Qt5's hierarchy for QML has changed a bit: |
499 | @@ -101,21 +170,21 @@ |
500 | |
501 | QQuickView *view = qobject_cast<QQuickView*>(object_); |
502 | if (view && view->rootObject() != 0) { |
503 | - children.push_back(std::make_shared<QtNode>(view->rootObject(), GetPath())); |
504 | + children.push_back(std::make_shared<QtNode>(view->rootObject(), shared_from_this())); |
505 | } |
506 | |
507 | QQuickItem* item = qobject_cast<QQuickItem*>(object_); |
508 | if (item) { |
509 | foreach (QQuickItem *childItem, item->childItems()) { |
510 | if (childItem->parentItem() == item) { |
511 | - children.push_back(std::make_shared<QtNode>(childItem, GetPath())); |
512 | + children.push_back(std::make_shared<QtNode>(childItem, shared_from_this())); |
513 | } |
514 | } |
515 | } else { |
516 | foreach (QObject *child, object_->children()) |
517 | { |
518 | if (child->parent() == object_) |
519 | - children.push_back(std::make_shared<QtNode>(child, GetPath())); |
520 | + children.push_back(std::make_shared<QtNode>(child, shared_from_this())); |
521 | } |
522 | } |
523 | |
524 | @@ -123,7 +192,7 @@ |
525 | foreach (QObject *child, object_->children()) |
526 | { |
527 | if (child->parent() == object_) |
528 | - children.push_back(std::make_shared<QtNode>(child, GetPath())); |
529 | + children.push_back(std::make_shared<QtNode>(child, shared_from_this())); |
530 | } |
531 | |
532 | // If our wrapped object is a QGraphicsScene, we need to explicitly grab any child graphics |
533 | @@ -137,10 +206,16 @@ |
534 | { |
535 | QGraphicsObject *obj = item->toGraphicsObject(); |
536 | if (obj && ! obj->parent()) |
537 | - children.push_back(std::make_shared<QtNode>(obj, GetPath())); |
538 | + children.push_back(std::make_shared<QtNode>(obj, shared_from_this())); |
539 | } |
540 | } |
541 | #endif |
542 | |
543 | return children; |
544 | } |
545 | + |
546 | + |
547 | +xpathselect::Node::Ptr QtNode::GetParent() const |
548 | +{ |
549 | + return parent_; |
550 | +} |
551 | |
552 | === modified file 'driver/qtnode.h' |
553 | --- driver/qtnode.h 2013-04-18 03:44:31 +0000 |
554 | +++ driver/qtnode.h 2013-09-16 18:00:39 +0000 |
555 | @@ -1,33 +1,54 @@ |
556 | #ifndef QTNODE_H |
557 | #define QTNODE_H |
558 | |
559 | +#include <cstdint> |
560 | #include <QVariant> |
561 | +#include <QDBusArgument> |
562 | #include <xpathselect/node.h> |
563 | |
564 | +/// A simple data structure representing the state of a single node: |
565 | +struct NodeIntrospectionData |
566 | +{ |
567 | + QString object_path; |
568 | + QVariantMap state; |
569 | +}; |
570 | + |
571 | +Q_DECLARE_METATYPE(NodeIntrospectionData); |
572 | +Q_DECLARE_METATYPE(QList<NodeIntrospectionData>); |
573 | + |
574 | +QDBusArgument &operator<<(QDBusArgument &argument, const NodeIntrospectionData &node_data); |
575 | +const QDBusArgument &operator>>(const QDBusArgument &argument, NodeIntrospectionData &node_data); |
576 | + |
577 | /// Base class for all Qt-based object nodes. |
578 | /// |
579 | /// QtNode wraps a single QObject pointer. It derives from xpathselect::Node and, |
580 | /// like that class, is designed to be allocated on the heap and stored in a |
581 | /// std::shared_ptr. |
582 | -class QtNode: public xpathselect::Node |
583 | +class QtNode: public xpathselect::Node, public std::enable_shared_from_this<QtNode> |
584 | { |
585 | public: |
586 | - typedef std::shared_ptr<QtNode> Ptr; |
587 | + typedef std::shared_ptr<const QtNode> Ptr; |
588 | |
589 | - QtNode(QObject* object, std::string const& parent_path); |
590 | + QtNode(QObject* object, Ptr parent); |
591 | + explicit QtNode(QObject* object); |
592 | |
593 | QObject* getWrappedObject() const; |
594 | - |
595 | - virtual QVariant IntrospectNode() const; |
596 | - virtual qint64 GetObjectId() const; |
597 | + xpathselect::Node::Ptr GetParent() const; |
598 | + |
599 | + virtual NodeIntrospectionData GetIntrospectionData() const; |
600 | + |
601 | |
602 | virtual std::string GetName() const; |
603 | virtual std::string GetPath() const; |
604 | - virtual bool MatchProperty(const std::string& name, const std::string& value) const; |
605 | - virtual xpathselect::NodeList Children() const; |
606 | + virtual int32_t GetId() const; |
607 | + virtual bool MatchStringProperty(const std::string& name, const std::string& value) const; |
608 | + virtual bool MatchIntegerProperty(const std::string& name, int32_t value) const; |
609 | + virtual bool MatchBooleanProperty(const std::string& name, bool value) const; |
610 | + virtual xpathselect::NodeVector Children() const; |
611 | private: |
612 | QObject *object_; |
613 | std::string full_path_; |
614 | + Ptr parent_; |
615 | }; |
616 | |
617 | #endif // QTNODE_H |
618 | |
619 | === modified file 'driver/qttestability.cpp' |
620 | --- driver/qttestability.cpp 2012-12-19 12:27:25 +0000 |
621 | +++ driver/qttestability.cpp 2013-09-16 18:00:39 +0000 |
622 | @@ -10,6 +10,7 @@ |
623 | #include "dbus_adaptor.h" |
624 | #include "dbus_adaptor_qt.h" |
625 | #include "dbus_object.h" |
626 | +#include "qtnode.h" |
627 | |
628 | #include <QCoreApplication> |
629 | #include <QDebug> |
630 | @@ -20,6 +21,8 @@ |
631 | void qt_testability_init(void) |
632 | { |
633 | qDebug() << "Loading testability driver."; |
634 | + qDBusRegisterMetaType<NodeIntrospectionData>(); |
635 | + qDBusRegisterMetaType<QList<NodeIntrospectionData> >(); |
636 | |
637 | DBusObject* obj = new DBusObject; |
638 | new AutopilotAdaptor(obj); |
639 | |
640 | === modified file 'driver/rootnode.cpp' |
641 | --- driver/rootnode.cpp 2013-04-18 04:46:44 +0000 |
642 | +++ driver/rootnode.cpp 2013-09-16 18:00:39 +0000 |
643 | @@ -1,35 +1,32 @@ |
644 | #include "rootnode.h" |
645 | +#include "introspection.h" |
646 | |
647 | #include <QObject> |
648 | #include <QCoreApplication> |
649 | #include <QStringList> |
650 | +#include <QDebug> |
651 | |
652 | RootNode::RootNode(QCoreApplication* application) |
653 | - : QtNode(application, std::string()) |
654 | + : QtNode(application) |
655 | , application_(application) |
656 | { |
657 | } |
658 | |
659 | -QVariant RootNode::IntrospectNode() const |
660 | + |
661 | +NodeIntrospectionData RootNode::GetIntrospectionData() const |
662 | { |
663 | - // return must be (name, state_map) |
664 | - QString object_name = QString::fromStdString(GetPath()); |
665 | + NodeIntrospectionData data; |
666 | + data.object_path = QString::fromStdString(GetPath()); |
667 | + data.state = GetNodeProperties(application_); |
668 | QStringList child_names; |
669 | foreach(QObject* child, children_) |
670 | { |
671 | child_names.append(child->metaObject()->className()); |
672 | } |
673 | |
674 | - QVariantMap object_properties; |
675 | - object_properties["Children"] = child_names; |
676 | - object_properties["id"] = GetObjectId(); |
677 | - QList<QVariant> object_tuple = { QVariant(object_name), QVariant(object_properties) }; |
678 | - return QVariant(object_tuple); |
679 | -} |
680 | - |
681 | -qint64 RootNode::GetObjectId() const |
682 | -{ |
683 | - return 1; |
684 | + data.state["Children"] = PackProperty(child_names); |
685 | + data.state["id"] = PackProperty(GetId()); |
686 | + return data; |
687 | } |
688 | |
689 | void RootNode::AddChild(QObject* child) |
690 | @@ -48,18 +45,10 @@ |
691 | return "/" + GetName(); |
692 | } |
693 | |
694 | -bool RootNode::MatchProperty(const std::string& name, const std::string& value) const |
695 | -{ |
696 | - if (name == "id") |
697 | - return QString::fromStdString(value).toLongLong() == GetObjectId(); |
698 | - |
699 | - return false; |
700 | -} |
701 | - |
702 | -xpathselect::NodeList RootNode::Children() const |
703 | -{ |
704 | - xpathselect::NodeList children; |
705 | +xpathselect::NodeVector RootNode::Children() const |
706 | +{ |
707 | + xpathselect::NodeVector children; |
708 | foreach(QObject* child, children_) |
709 | - children.push_back(std::make_shared<QtNode>(child, GetPath())); |
710 | + children.push_back(std::make_shared<QtNode>(child, shared_from_this())); |
711 | return children; |
712 | } |
713 | |
714 | === modified file 'driver/rootnode.h' |
715 | --- driver/rootnode.h 2013-04-18 04:46:44 +0000 |
716 | +++ driver/rootnode.h 2013-09-16 18:00:39 +0000 |
717 | @@ -13,15 +13,13 @@ |
718 | public: |
719 | RootNode(QCoreApplication* application); |
720 | |
721 | - virtual QVariant IntrospectNode() const; |
722 | - virtual qint64 GetObjectId() const; |
723 | + virtual NodeIntrospectionData GetIntrospectionData() const; |
724 | |
725 | void AddChild(QObject* child); |
726 | |
727 | virtual std::string GetName() const; |
728 | virtual std::string GetPath() const; |
729 | - virtual bool MatchProperty(const std::string& name, const std::string& value) const; |
730 | - virtual xpathselect::NodeList Children() const; |
731 | + virtual xpathselect::NodeVector Children() const; |
732 | private: |
733 | QCoreApplication* application_; |
734 | QList<QObject*> children_; |
735 | |
736 | === modified file 'tests/unittests/tst_introspection.cpp' |
737 | --- tests/unittests/tst_introspection.cpp 2013-06-26 09:00:13 +0000 |
738 | +++ tests/unittests/tst_introspection.cpp 2013-09-16 18:00:39 +0000 |
739 | @@ -26,6 +26,7 @@ |
740 | #include <QPushButton> |
741 | |
742 | #include "introspection.h" |
743 | +#include "qtnode.h" |
744 | |
745 | QVariant IntrospectNode(QObject* obj); |
746 | |
747 | @@ -46,6 +47,8 @@ |
748 | void test_properties_data(); |
749 | void test_properties(); |
750 | |
751 | + void test_property_matching(); |
752 | + |
753 | private: |
754 | QMainWindow *m_object; |
755 | }; |
756 | @@ -74,6 +77,7 @@ |
757 | |
758 | m_object->setObjectName("testWindow"); |
759 | m_object->setProperty("dynamicTestProperty", "testValue"); |
760 | + m_object->setProperty("dynamicStringProperty", QString("testValue")); |
761 | m_object->setProperty("myUInt", QVariant(quint8(5))); |
762 | m_object->setProperty("myStringList", QVariant(QStringList() << "string1" << "string2" << "string3")); |
763 | m_object->setProperty("myColor", QColor("red")); |
764 | @@ -113,25 +117,155 @@ |
765 | QTest::addColumn<QVariant>("firstResultPropertyValue"); |
766 | |
767 | #ifdef QT5_SUPPORT |
768 | - QTest::newRow("/") << "/" << 1 << "/tst_introspection" << "Children" << QVariant(QStringList() << "QMainWindow" << "QWidgetWindow"); |
769 | - QTest::newRow("//QWidget[id=6]") << "//QWidget[id=6]" << 1 << "/tst_introspection/QMainWindow/QWidget" << "objectName" << QVariant("centralTestWidget"); |
770 | - QTest::newRow("//QPushButton[id=9]") << "//QPushButton[id=9]" << 1 << "/tst_introspection/QMainWindow/QWidget/QPushButton" << "objectName" << QVariant("myButton2"); |
771 | + QTest::newRow("/") |
772 | + << "/" |
773 | + << 1 |
774 | + << "/tst_introspection" |
775 | + << "Children" |
776 | + << QVariant( |
777 | + QVariantList() |
778 | + << 0 |
779 | + << QVariant( |
780 | + QStringList() |
781 | + << "QMainWindow" |
782 | + << "QWidgetWindow" |
783 | + ) |
784 | + ); |
785 | + |
786 | + QTest::newRow("//QWidget[id=6]") |
787 | + << "//QWidget[id=6]" |
788 | + << 1 |
789 | + << "/tst_introspection/QMainWindow/QWidget" |
790 | + << "objectName" |
791 | + << QVariant( |
792 | + QVariantList() |
793 | + << 0 |
794 | + << "centralTestWidget" |
795 | + ); |
796 | + |
797 | + QTest::newRow("//QPushButton[id=9]") |
798 | + << "//QPushButton[id=9]" |
799 | + << 1 |
800 | + << "/tst_introspection/QMainWindow/QWidget/QPushButton" |
801 | + << "objectName" |
802 | + << QVariant( |
803 | + QVariantList() |
804 | + << 0 |
805 | + << "myButton2" |
806 | + ); |
807 | #else |
808 | - QTest::newRow("/") << "/" << 1 << "/tst_introspection" << "Children" << QVariant(QStringList() << "QMainWindow"); |
809 | - QTest::newRow("//QWidget[id=5]") << "//QWidget[id=5]" << 1 << "/tst_introspection/QMainWindow/QWidget" << "objectName" << QVariant("centralTestWidget"); |
810 | + QTest::newRow("/") |
811 | + << "/" |
812 | + << 1 |
813 | + << "/tst_introspection" |
814 | + << "Children" |
815 | + << QVariant( |
816 | + QVariantList() |
817 | + << 0 |
818 | + << "QMainWindow" |
819 | + ); |
820 | + |
821 | + QTest::newRow("//QWidget[id=5]") |
822 | + << "//QWidget[id=5]" |
823 | + << 1 |
824 | + << "/tst_introspection/QMainWindow/QWidget" |
825 | + << "objectName" |
826 | + << QVariant( |
827 | + QVariantList() |
828 | + << 0 |
829 | + << "centralTestWidget" |
830 | + ); |
831 | |
832 | // Depending on the environment, Qt4 could add a second QWidget at position 6. That moves other items down by one. |
833 | - if (Introspect("//QWidget[id=6]").count() > 0) { |
834 | - QTest::newRow("//QPushButton[id=9]") << "//QPushButton[id=9]" << 1 << "/tst_introspection/QMainWindow/QWidget/QPushButton" << "objectName" << QVariant("myButton2"); |
835 | - } else { |
836 | - QTest::newRow("//QPushButton[id=8]") << "//QPushButton[id=8]" << 1 << "/tst_introspection/QMainWindow/QWidget/QPushButton" << "objectName" << QVariant("myButton2"); |
837 | + if (Introspect("//QWidget[id=6]").count() > 0) |
838 | + { |
839 | + QTest::newRow("//QPushButton[id=9]") |
840 | + << "//QPushButton[id=9]" |
841 | + << 1 |
842 | + << "/tst_introspection/QMainWindow/QWidget/QPushButton" |
843 | + << "objectName" |
844 | + << QVariant( |
845 | + QVariantList() |
846 | + << 0 |
847 | + << "myButton2" |
848 | + ); |
849 | + } |
850 | + else |
851 | + { |
852 | + QTest::newRow("//QPushButton[id=8]") |
853 | + << "//QPushButton[id=8]" |
854 | + << 1 |
855 | + << "/tst_introspection/QMainWindow/QWidget/QPushButton" |
856 | + << "objectName" |
857 | + << QVariant( |
858 | + QVariantList() |
859 | + << 0 |
860 | + << "myButton2" |
861 | + ); |
862 | } |
863 | #endif |
864 | |
865 | - QTest::newRow("//GridLayout") << "//QGridLayout" << 1 << "/tst_introspection/QMainWindow/QWidget/QGridLayout" << "objectName" << QVariant("myTestLayout"); |
866 | - QTest::newRow("//QPushButton") << "//QPushButton" << 2 << "/tst_introspection/QMainWindow/QWidget/QPushButton" << "objectName" << QVariant("myButton1"); |
867 | - QTest::newRow("//QWidget/*") << "//QWidget/*" << 5 << "/tst_introspection/QMainWindow/QWidget/QGridLayout" << "objectName" << QVariant("myTestLayout"); |
868 | - QTest::newRow("broken query") << "broken query" << 0 << QString() << QString() << QVariant(); |
869 | + QTest::newRow("/tst_introspection/QMainWindow/QWidget/QGridLayout") |
870 | + << "//QGridLayout" |
871 | + << 1 |
872 | + << "/tst_introspection/QMainWindow/QWidget/QGridLayout" |
873 | + << "objectName" |
874 | + << QVariant( |
875 | + QVariantList() |
876 | + << 0 |
877 | + << "myTestLayout" |
878 | + ); |
879 | + |
880 | + QTest::newRow("parent of leaf node") |
881 | + << "/tst_introspection/QMainWindow/QWidget/QGridLayout/.." |
882 | + << 1 |
883 | + << "/tst_introspection/QMainWindow/QWidget" |
884 | + << "objectName" |
885 | + << QVariant( |
886 | + QVariantList() |
887 | + << 0 |
888 | + << "centralTestWidget" |
889 | + ); |
890 | + |
891 | + QTest::newRow("parent of root node") |
892 | + << "/tst_introspection/.." |
893 | + << 1 |
894 | + << "/tst_introspection" |
895 | + << "id" |
896 | + << QVariant( |
897 | + QVariantList() |
898 | + << 0 |
899 | + << 1 |
900 | + ); |
901 | + |
902 | + QTest::newRow("//QPushButton") |
903 | + << "//QPushButton" |
904 | + << 2 |
905 | + << "/tst_introspection/QMainWindow/QWidget/QPushButton" |
906 | + << "objectName" |
907 | + << QVariant( |
908 | + QVariantList() |
909 | + << 0 |
910 | + << "myButton1" |
911 | + ); |
912 | + |
913 | + QTest::newRow("//QWidget/*") |
914 | + << "//QWidget/*" |
915 | + << 5 |
916 | + << "/tst_introspection/QMainWindow/QWidget/QGridLayout" |
917 | + << "objectName" |
918 | + << QVariant( |
919 | + QVariantList() |
920 | + << 0 |
921 | + << "myTestLayout" |
922 | + ); |
923 | + |
924 | + QTest::newRow("broken query") |
925 | + << "broken query" |
926 | + << 0 |
927 | + << QString() |
928 | + << QString() |
929 | + << QVariant(); |
930 | } |
931 | |
932 | void tst_Introspection::test_introspect() |
933 | @@ -142,16 +276,15 @@ |
934 | QFETCH(QString, firstResultPropertyName); |
935 | QFETCH(QVariant, firstResultPropertyValue); |
936 | |
937 | - QList<QVariant> resultList = Introspect(xpath); |
938 | + QList<NodeIntrospectionData> resultList = Introspect(xpath); |
939 | |
940 | QCOMPARE(resultList.count(), resultCount); |
941 | |
942 | if (resultCount > 0) { |
943 | - QVariant firstResult = resultList.first(); |
944 | - QVariantMap firstResultProperties = firstResult.toList().last().toMap(); |
945 | + NodeIntrospectionData first_object = resultList.first(); |
946 | |
947 | - QCOMPARE(firstResult.toList().first().toString(), firstResultType); |
948 | - QCOMPARE(firstResultProperties.value(firstResultPropertyName), firstResultPropertyValue); |
949 | + QCOMPARE(first_object.object_path, firstResultType); |
950 | + QCOMPARE(first_object.state.value(firstResultPropertyName), firstResultPropertyValue); |
951 | } |
952 | } |
953 | |
954 | @@ -171,9 +304,9 @@ |
955 | qApp->setApplicationName(app_name); |
956 | |
957 | #ifdef QT5_SUPPORT |
958 | - QList<QVariant> result = Introspect("//QWidgetWindow"); |
959 | + QList<NodeIntrospectionData> result = Introspect("//QWidgetWindow"); |
960 | #else |
961 | - QList<QVariant> result = Introspect("//QMainWindow"); |
962 | + QList<NodeIntrospectionData> result = Introspect("//QMainWindow"); |
963 | #endif |
964 | |
965 | QVERIFY(!result.isEmpty()); |
966 | @@ -185,25 +318,169 @@ |
967 | QTest::addColumn<QVariant>("propertyValue"); |
968 | QTest::addColumn<bool>("fuzzyCompare"); |
969 | |
970 | - QTest::newRow("static property") << "objectName" << QVariant(m_object->objectName()) << false; |
971 | - QTest::newRow("dynamic property") << "dynamicTestProperty" << m_object->property("dynamicTestProperty") << false; |
972 | - |
973 | - QTest::newRow("int") << "width" << QVariant(m_object->width()) << false; |
974 | - QTest::newRow("uint") << "myUInt" << m_object->property("myUInt") << false; |
975 | - QTest::newRow("bool") << "visible" << QVariant(m_object->isVisible()) << false; |
976 | - QTest::newRow("double") << "windowOpacity" << QVariant(m_object->windowOpacity()) << true; |
977 | - |
978 | - QTest::newRow("QString") << "objectName" << QVariant(m_object->objectName()) << false; |
979 | - QTest::newRow("QStringList") << "myStringList" << m_object->property("myStringList") << false; |
980 | - QTest::newRow("QSize") << "maximumSize" << QVariant(QList<QVariant>() << m_object->maximumWidth() << m_object->maximumHeight()) << false; |
981 | - QTest::newRow("QPoint") << "pos" << QVariant(QList<QVariant>() << m_object->x() << m_object->y()) << false; |
982 | - QTest::newRow("QRect") << "geometry" << QVariant(QList<QVariant>() << m_object->geometry().x() << m_object->geometry().y() << m_object->geometry().width() << m_object->geometry().height()) << false; |
983 | - QTest::newRow("QColor") << "myColor" << QVariant(QList<QVariant>() << 255 << 0 << 0 << 255) << false; |
984 | - QTest::newRow("QByteArray") << "myByteArray" << m_object->property("myByteArray") << false; |
985 | - QTest::newRow("QUrl") << "myUrl" << m_object->property("myUrl") << false; |
986 | - QTest::newRow("QDateTime") << "myDateTime" << QVariant(m_object->property("myDateTime").toDateTime().toTime_t()) << false; |
987 | - QTest::newRow("QDate") << "myDate" << QVariant(m_object->property("myDate").toDateTime().toTime_t()) << false; |
988 | - QTest::newRow("QTime") << "myTime" << QVariant(m_object->property("myTime").toTime().toString("hh:mm:ss")) << false; |
989 | + QTest::newRow("static property") |
990 | + << "objectName" |
991 | + << QVariant( |
992 | + QVariantList() |
993 | + << 0 |
994 | + << m_object->objectName() |
995 | + ) |
996 | + << false; |
997 | + |
998 | + QTest::newRow("dynamic property") |
999 | + << "dynamicTestProperty" |
1000 | + << QVariant( |
1001 | + QVariantList() |
1002 | + << 0 |
1003 | + << m_object->property("dynamicTestProperty") |
1004 | + ) |
1005 | + << false; |
1006 | + |
1007 | + QTest::newRow("int") |
1008 | + << "width" |
1009 | + << QVariant( |
1010 | + QVariantList() |
1011 | + << 0 |
1012 | + << m_object->width() |
1013 | + ) |
1014 | + << false; |
1015 | + |
1016 | + QTest::newRow("uint") |
1017 | + << "myUInt" |
1018 | + << QVariant( |
1019 | + QVariantList() |
1020 | + << 0 |
1021 | + << m_object->property("myUInt") |
1022 | + ) |
1023 | + << false; |
1024 | + |
1025 | + QTest::newRow("bool") |
1026 | + << "visible" |
1027 | + << QVariant( |
1028 | + QVariantList() |
1029 | + << 0 |
1030 | + << m_object->isVisible() |
1031 | + ) |
1032 | + << false; |
1033 | + |
1034 | + QTest::newRow("double") |
1035 | + << "windowOpacity" |
1036 | + << QVariant( |
1037 | + QVariantList() |
1038 | + << 0 |
1039 | + << m_object->windowOpacity() |
1040 | + ) |
1041 | + << true; |
1042 | + |
1043 | + QTest::newRow("QString") |
1044 | + << "objectName" |
1045 | + << QVariant( |
1046 | + QVariantList() |
1047 | + << 0 |
1048 | + << m_object->objectName() |
1049 | + ) |
1050 | + << false; |
1051 | + |
1052 | + QTest::newRow("QStringList") |
1053 | + << "myStringList" |
1054 | + << QVariant( |
1055 | + QVariantList() |
1056 | + << 0 |
1057 | + << m_object->property("myStringList") |
1058 | + ) |
1059 | + << false; |
1060 | + |
1061 | + QTest::newRow("QSize") |
1062 | + << "maximumSize" |
1063 | + << QVariant( |
1064 | + QVariantList() |
1065 | + << 3 |
1066 | + << m_object->maximumWidth() |
1067 | + << m_object->maximumHeight() |
1068 | + ) |
1069 | + << false; |
1070 | + |
1071 | + QTest::newRow("QPoint") |
1072 | + << "pos" |
1073 | + << QVariant( |
1074 | + QVariantList() |
1075 | + << 2 |
1076 | + << m_object->x() |
1077 | + << m_object->y() |
1078 | + ) |
1079 | + << false; |
1080 | + |
1081 | + QTest::newRow("QRect") |
1082 | + << "geometry" |
1083 | + << QVariant( |
1084 | + QVariantList() |
1085 | + << 1 |
1086 | + << m_object->geometry().x() |
1087 | + << m_object->geometry().y() |
1088 | + << m_object->geometry().width() |
1089 | + << m_object->geometry().height() |
1090 | + ) |
1091 | + << false; |
1092 | + |
1093 | + QTest::newRow("QColor") |
1094 | + << "myColor" |
1095 | + << QVariant( |
1096 | + QVariantList() |
1097 | + << 4 |
1098 | + << qvariant_cast<QColor>(m_object->property("myColor")).red() |
1099 | + << qvariant_cast<QColor>(m_object->property("myColor")).green() |
1100 | + << qvariant_cast<QColor>(m_object->property("myColor")).blue() |
1101 | + << qvariant_cast<QColor>(m_object->property("myColor")).alpha() |
1102 | + ) |
1103 | + << false; |
1104 | + |
1105 | + QTest::newRow("QByteArray") |
1106 | + << "myByteArray" |
1107 | + << QVariant( |
1108 | + QVariantList() |
1109 | + << 0 |
1110 | + << m_object->property("myByteArray") |
1111 | + ) |
1112 | + << false; |
1113 | + |
1114 | + QTest::newRow("QUrl") |
1115 | + << "myUrl" |
1116 | + << QVariant( |
1117 | + QVariantList() |
1118 | + << 0 |
1119 | + << m_object->property("myUrl") |
1120 | + ) |
1121 | + << false; |
1122 | + |
1123 | + QTest::newRow("QDateTime") |
1124 | + << "myDateTime" |
1125 | + << QVariant( |
1126 | + QVariantList() |
1127 | + << 5 |
1128 | + << m_object->property("myDateTime").toDateTime().toTime_t() |
1129 | + ) |
1130 | + << false; |
1131 | + |
1132 | + QTest::newRow("QDate") |
1133 | + << "myDate" |
1134 | + << QVariant( |
1135 | + QVariantList() |
1136 | + << 5 |
1137 | + << m_object->property("myDate").toDateTime().toTime_t() |
1138 | + ) |
1139 | + << false; |
1140 | + |
1141 | + QTest::newRow("QTime") |
1142 | + << "myTime" |
1143 | + << QVariant( |
1144 | + QVariantList() |
1145 | + << 6 |
1146 | + << m_object->property("myTime").toTime().hour() |
1147 | + << m_object->property("myTime").toTime().minute() |
1148 | + << m_object->property("myTime").toTime().second() |
1149 | + << m_object->property("myTime").toTime().msec() |
1150 | + ) |
1151 | + << false; |
1152 | } |
1153 | |
1154 | void tst_Introspection::test_properties() |
1155 | @@ -224,6 +501,16 @@ |
1156 | } |
1157 | } |
1158 | |
1159 | +void tst_Introspection::test_property_matching() |
1160 | +{ |
1161 | + QtNode n(m_object); |
1162 | + |
1163 | + QVERIFY(n.MatchStringProperty("dynamicStringProperty", "testValue") == true); |
1164 | + QVERIFY(n.MatchStringProperty("dynamicTestProperty", "testValue") == true); |
1165 | + QVERIFY(n.MatchIntegerProperty("myUInt", 5) == true); |
1166 | + QVERIFY(n.MatchBooleanProperty("visible", true) == true); |
1167 | +} |
1168 | + |
1169 | QTEST_MAIN(tst_Introspection) |
1170 | |
1171 | #include "tst_introspection.moc" |
1172 | |
1173 | === modified file 'tests/unittests/unittests.pro' |
1174 | --- tests/unittests/unittests.pro 2013-03-17 16:53:30 +0000 |
1175 | +++ tests/unittests/unittests.pro 2013-09-16 18:00:39 +0000 |
1176 | @@ -5,7 +5,7 @@ |
1177 | |
1178 | QT += testlib dbus widgets quick |
1179 | |
1180 | -CONFIG += link_pkgconfig |
1181 | +CONFIG += link_pkgconfig debug |
1182 | PKGCONFIG += xpathselect |
1183 | QMAKE_CXXFLAGS += -std=c++0x -Wl,--no-undefined |
1184 | |
1185 | @@ -15,7 +15,8 @@ |
1186 | |
1187 | INCLUDEPATH += ../../driver |
1188 | |
1189 | -SOURCES += tst_introspection.cpp \ |
1190 | +SOURCES += \ |
1191 | + tst_introspection.cpp \ |
1192 | ../../driver/introspection.cpp \ |
1193 | ../../driver/rootnode.cpp \ |
1194 | ../../driver/qtnode.cpp |
FAILED: Continuous integration, rev:84 jenkins. qa.ubuntu. com/job/ autopilot- qt-ci/70/ jenkins. qa.ubuntu. com/job/ autopilot- qt-saucy- amd64-ci/ 12/console jenkins. qa.ubuntu. com/job/ autopilot- qt-saucy- armhf-ci/ 12/console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins: 8080/job/ autopilot- qt-ci/70/ rebuild
http://