Merge lp:~zsombi/ubuntu-ui-toolkit/serviceproperties-component into lp:ubuntu-ui-toolkit/staging
- serviceproperties-component
- Merge into staging
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Cris Dywan | ||||
Approved revision: | 1354 | ||||
Merged at revision: | 1360 | ||||
Proposed branch: | lp:~zsombi/ubuntu-ui-toolkit/serviceproperties-component | ||||
Merge into: | lp:ubuntu-ui-toolkit/staging | ||||
Diff against target: |
1073 lines (+989/-5) 12 files modified
debian/control (+2/-0) modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.cpp (+226/-0) modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.h (+55/-0) modules/Ubuntu/Components/plugin/ucserviceproperties.cpp (+317/-0) modules/Ubuntu/Components/plugin/ucserviceproperties.h (+83/-0) modules/Ubuntu/Components/plugin/ucserviceproperties_p.h (+53/-0) tests/unit/runtest.sh (+5/-5) tests/unit_x11/tst_serviceproperties/IncomingCallVibrateWatcher.qml (+31/-0) tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher.qml (+31/-0) tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher2.qml (+32/-0) tests/unit_x11/tst_serviceproperties/tst_serviceproperties.cpp (+146/-0) tests/unit_x11/tst_serviceproperties/tst_serviceproperties.pro (+8/-0) |
||||
To merge this branch: | bzr merge lp:~zsombi/ubuntu-ui-toolkit/serviceproperties-component | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Cris Dywan | Approve | ||
PS Jenkins bot | continuous-integration | Approve | |
Review via email: mp+243496@code.launchpad.net |
Commit message
ServiceProperties component to Ubuntu.Components 1.1.
Description of the change
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1353
http://
Executed test runs:
UNSTABLE: http://
FAILURE: http://
SUCCESS: http://
deb: http://
FAILURE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1354. By Zsombor Egri
-
review comments applied
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1354
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'debian/control' |
2 | --- debian/control 2014-11-21 08:23:22 +0000 |
3 | +++ debian/control 2014-12-03 10:22:28 +0000 |
4 | @@ -38,6 +38,8 @@ |
5 | libdbus-1-dev, |
6 | libnih-dbus-dev, |
7 | dbus, |
8 | + dbus-test-runner, |
9 | + accountsservice, |
10 | xvfb, |
11 | libgl1-mesa-dri, |
12 | locales, |
13 | |
14 | === added file 'modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.cpp' |
15 | --- modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.cpp 1970-01-01 00:00:00 +0000 |
16 | +++ modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.cpp 2014-12-03 10:22:28 +0000 |
17 | @@ -0,0 +1,226 @@ |
18 | +/* |
19 | + * Copyright 2014 Canonical Ltd. |
20 | + * |
21 | + * This program is free software; you can redistribute it and/or modify |
22 | + * it under the terms of the GNU Lesser General Public License as published by |
23 | + * the Free Software Foundation; version 3. |
24 | + * |
25 | + * This program is distributed in the hope that it will be useful, |
26 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
27 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
28 | + * GNU Lesser General Public License for more details. |
29 | + * |
30 | + * You should have received a copy of the GNU Lesser General Public License |
31 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
32 | + */ |
33 | + |
34 | +#include "dbuspropertywatcher_p.h" |
35 | +#include <QtDBus/QDBusReply> |
36 | +#include <unistd.h> |
37 | +#include <sys/types.h> |
38 | +#include "i18n.h" |
39 | +#include <QtQml/QQmlInfo> |
40 | + |
41 | +#define DYNAMIC_PROPERTY "__q_property" |
42 | + |
43 | +UCServicePropertiesPrivate *createServicePropertiesAdapter(UCServiceProperties *owner) |
44 | +{ |
45 | + return new DBusServiceProperties(owner); |
46 | +} |
47 | + |
48 | +DBusServiceProperties::DBusServiceProperties(UCServiceProperties *qq) |
49 | + : UCServicePropertiesPrivate(qq) |
50 | + , connection("") |
51 | + , watcher(0) |
52 | + , iface(0) |
53 | +{ |
54 | +} |
55 | + |
56 | +bool DBusServiceProperties::init() |
57 | +{ |
58 | + // crear previous connections |
59 | + setStatus(UCServiceProperties::Inactive); |
60 | + delete iface; |
61 | + iface = 0; |
62 | + delete watcher; |
63 | + watcher = 0; |
64 | + setError(QString()); |
65 | + |
66 | + if (service.isEmpty() || path.isEmpty()) { |
67 | + setStatus(UCServiceProperties::ConnectionError); |
68 | + setError(UbuntuI18n::instance().tr("No service/path specified")); |
69 | + return false; |
70 | + } |
71 | + |
72 | + switch (type) { |
73 | + case UCServiceProperties::System: |
74 | + { |
75 | + connection = QDBusConnection::systemBus(); |
76 | + break; |
77 | + } |
78 | + case UCServiceProperties::Session: |
79 | + { |
80 | + connection = QDBusConnection::sessionBus(); |
81 | + break; |
82 | + } |
83 | + default: |
84 | + { |
85 | + setStatus(UCServiceProperties::ConnectionError); |
86 | + setError(UbuntuI18n::instance().tr("Invalid bus type: %1.").arg(type)); |
87 | + return false; |
88 | + } |
89 | + } |
90 | + |
91 | + Q_Q(UCServiceProperties); |
92 | + // connect dbus watcher to catch OwnerChanged |
93 | + watcher = new QDBusServiceWatcher(service, connection, QDBusServiceWatcher::WatchForOwnerChange, q); |
94 | + // connect interface |
95 | + iface = new QDBusInterface(service, path, interface, connection, q); |
96 | + if (!iface->isValid()) { |
97 | + setStatus(UCServiceProperties::ConnectionError); |
98 | + setError(iface->lastError().message()); |
99 | + return false; |
100 | + } |
101 | + // connect watcher to get owner changes |
102 | + QObject::connect(watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)), |
103 | + this, SLOT(changeServiceOwner(QString,QString,QString))); |
104 | + return setupInterface(); |
105 | +} |
106 | + |
107 | +/* |
108 | + * Connect dbus signal identified by (service, path, iface, name) quaduple to a |
109 | + * slot to receive property changes. |
110 | + */ |
111 | +bool DBusServiceProperties::setupInterface() |
112 | +{ |
113 | + QDBusReply<QDBusObjectPath> dbusObjectPath = iface->call("FindUserById", qlonglong(getuid())); |
114 | + if (dbusObjectPath.isValid()) { |
115 | + objectPath = dbusObjectPath.value().path(); |
116 | + iface->connection().connect( |
117 | + service, |
118 | + objectPath, |
119 | + "org.freedesktop.DBus.Properties", |
120 | + "PropertiesChanged", |
121 | + this, |
122 | + SLOT(updateProperties(QString,QVariantMap,QStringList))); |
123 | + return true; |
124 | + } |
125 | + |
126 | + setStatus(UCServiceProperties::ConnectionError); |
127 | + setError(dbusObjectPath.error().message()); |
128 | + return false; |
129 | +} |
130 | + |
131 | +bool DBusServiceProperties::fetchPropertyValues() |
132 | +{ |
133 | + scannedProperties = properties; |
134 | + Q_FOREACH(QString property, properties) { |
135 | + readProperty(property); |
136 | + } |
137 | + return true; |
138 | +} |
139 | + |
140 | +/* |
141 | + * Reads a property value from the adaptorInterface asynchronously. |
142 | + */ |
143 | +bool DBusServiceProperties::readProperty(const QString &property) |
144 | +{ |
145 | + if ((status < UCServiceProperties::Synchronizing) || objectPath.isEmpty()) { |
146 | + return false; |
147 | + } |
148 | + Q_Q(UCServiceProperties); |
149 | + QDBusInterface readIFace(iface->interface(), objectPath, "org.freedesktop.DBus.Properties", connection); |
150 | + if (!readIFace.isValid()) { |
151 | + // report invalid interface only if the property's first letter was with capital one! |
152 | + if (property[0].isUpper()) { |
153 | + qmlInfo(q) << readIFace.lastError().message(); |
154 | + } |
155 | + return false; |
156 | + } |
157 | + QDBusPendingCall pending = readIFace.asyncCall("Get", adaptor, property); |
158 | + if (pending.isError()) { |
159 | + qmlInfo(q) << pending.error().message(); |
160 | + return false; |
161 | + } |
162 | + QDBusPendingCallWatcher *callWatcher = new QDBusPendingCallWatcher(pending, q); |
163 | + QObject::connect(callWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), |
164 | + this, SLOT(readFinished(QDBusPendingCallWatcher*))); |
165 | + |
166 | + // set a dynamic property so we know which property are we reading |
167 | + callWatcher->setProperty(DYNAMIC_PROPERTY, property); |
168 | + return true; |
169 | +} |
170 | + |
171 | +/* |
172 | + * Writes a property value to theadaptorInterface synchronously. It is for pure testing purposes. |
173 | + */ |
174 | +bool DBusServiceProperties::testProperty(const QString &property, const QVariant &value) |
175 | +{ |
176 | + if (objectPath.isEmpty()) { |
177 | + return false; |
178 | + } |
179 | + QDBusInterface writeIFace(iface->interface(), objectPath, "org.freedesktop.DBus.Properties", connection); |
180 | + if (!writeIFace.isValid()) { |
181 | + // invalid interface |
182 | + return false; |
183 | + } |
184 | + QDBusMessage msg = writeIFace.call("Set", adaptor, property, QVariant::fromValue(QDBusVariant(value))); |
185 | + return msg.type() == QDBusMessage::ReplyMessage; |
186 | +} |
187 | + |
188 | +/* |
189 | + * Slot called when the async read operation finishes. |
190 | + */ |
191 | +void DBusServiceProperties::readFinished(QDBusPendingCallWatcher *call) |
192 | +{ |
193 | + Q_Q(UCServiceProperties); |
194 | + QDBusPendingReply<QVariant> reply = *call; |
195 | + QString property = call->property(DYNAMIC_PROPERTY).toString(); |
196 | + scannedProperties.removeAll(property); |
197 | + if (reply.isError()) { |
198 | + // remove the property from being watched, as it has no property like that |
199 | + properties.removeAll(property); |
200 | + if (property[0].isUpper()) { |
201 | + // report error! |
202 | + qmlInfo(q) << reply.error().message(); |
203 | + } |
204 | + } else { |
205 | + // update watched property value |
206 | + // make sure we have lower case when the property value is updated |
207 | + property[0] = property[0].toLower(); |
208 | + q->setProperty(property.toLocal8Bit().constData(), reply.value()); |
209 | + } |
210 | + |
211 | + if ((status == UCServiceProperties::Synchronizing) && scannedProperties.isEmpty()) { |
212 | + // set status to active |
213 | + setStatus(UCServiceProperties::Active); |
214 | + } |
215 | + |
216 | + // delete watcher |
217 | + call->deleteLater(); |
218 | +} |
219 | + |
220 | +/* |
221 | + * Slot called when service owner is changed. |
222 | + */ |
223 | +void DBusServiceProperties::changeServiceOwner(const QString &serviceName, const QString &oldOwner, const QString &newOwner) |
224 | +{ |
225 | + Q_UNUSED(oldOwner); |
226 | + Q_UNUSED(newOwner); |
227 | + if (serviceName != service) { |
228 | + return; |
229 | + } |
230 | + setupInterface(); |
231 | +} |
232 | + |
233 | +/* |
234 | + * Slot called when the properties are changed in the service. |
235 | + */ |
236 | +void DBusServiceProperties::updateProperties(const QString &onInterface, const QVariantMap &map, const QStringList &invalidated) |
237 | +{ |
238 | + Q_UNUSED(onInterface); |
239 | + Q_UNUSED(map); |
240 | + Q_FOREACH(const QString &property, invalidated) { |
241 | + readProperty(property); |
242 | + } |
243 | +} |
244 | |
245 | === added file 'modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.h' |
246 | --- modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.h 1970-01-01 00:00:00 +0000 |
247 | +++ modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.h 2014-12-03 10:22:28 +0000 |
248 | @@ -0,0 +1,55 @@ |
249 | +/* |
250 | + * Copyright 2014 Canonical Ltd. |
251 | + * |
252 | + * This program is free software; you can redistribute it and/or modify |
253 | + * it under the terms of the GNU Lesser General Public License as published by |
254 | + * the Free Software Foundation; version 3. |
255 | + * |
256 | + * This program is distributed in the hope that it will be useful, |
257 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
258 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
259 | + * GNU Lesser General Public License for more details. |
260 | + * |
261 | + * You should have received a copy of the GNU Lesser General Public License |
262 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
263 | + */ |
264 | + |
265 | +#ifndef DBUSPROPERTYWATCHER_P_H |
266 | +#define DBUSPROPERTYWATCHER_P_H |
267 | + |
268 | +#include <QtCore/QObject> |
269 | +#include <QtDBus/QDBusConnection> |
270 | +#include <QtDBus/QDBusServiceWatcher> |
271 | +#include <QtDBus/QDBusInterface> |
272 | + |
273 | +#include "ucserviceproperties_p.h" |
274 | + |
275 | +class QDBusPendingCallWatcher; |
276 | +class DBusServiceProperties : public QObject, public UCServicePropertiesPrivate |
277 | +{ |
278 | + Q_OBJECT |
279 | + Q_DECLARE_PUBLIC(UCServiceProperties) |
280 | +public: |
281 | + DBusServiceProperties(UCServiceProperties *qq); |
282 | + |
283 | + bool init(); |
284 | + bool fetchPropertyValues(); |
285 | + bool readProperty(const QString &property); |
286 | + // for testing purposes only!!! |
287 | + bool testProperty(const QString &property, const QVariant &value); |
288 | + |
289 | + QStringList scannedProperties; |
290 | + QDBusConnection connection; |
291 | + QDBusServiceWatcher *watcher; |
292 | + QDBusInterface *iface; |
293 | + QString objectPath; |
294 | + |
295 | + bool setupInterface(); |
296 | + |
297 | +public Q_SLOTS: |
298 | + void readFinished(QDBusPendingCallWatcher *watcher); |
299 | + void changeServiceOwner(const QString &serviceName, const QString &oldOwner, const QString &newOwner); |
300 | + void updateProperties(const QString &iface, const QVariantMap &map, const QStringList &invalidated); |
301 | +}; |
302 | + |
303 | +#endif // DBUSPROPERTYWATCHER_P_H |
304 | |
305 | === added file 'modules/Ubuntu/Components/plugin/ucserviceproperties.cpp' |
306 | --- modules/Ubuntu/Components/plugin/ucserviceproperties.cpp 1970-01-01 00:00:00 +0000 |
307 | +++ modules/Ubuntu/Components/plugin/ucserviceproperties.cpp 2014-12-03 10:22:28 +0000 |
308 | @@ -0,0 +1,317 @@ |
309 | +/* |
310 | + * Copyright 2014 Canonical Ltd. |
311 | + * |
312 | + * This program is free software; you can redistribute it and/or modify |
313 | + * it under the terms of the GNU Lesser General Public License as published by |
314 | + * the Free Software Foundation; version 3. |
315 | + * |
316 | + * This program is distributed in the hope that it will be useful, |
317 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
318 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
319 | + * GNU Lesser General Public License for more details. |
320 | + * |
321 | + * You should have received a copy of the GNU Lesser General Public License |
322 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
323 | + */ |
324 | + |
325 | +#include "ucserviceproperties.h" |
326 | +#include "ucserviceproperties_p.h" |
327 | +#include "i18n.h" |
328 | +#include <QtQml/QQmlInfo> |
329 | +#include <QtCore/QMetaProperty> |
330 | +#include <QtQml/QQmlProperty> |
331 | +#include <QtQml/private/qqmlproperty_p.h> |
332 | + |
333 | +UCServicePropertiesPrivate::UCServicePropertiesPrivate(UCServiceProperties *qq) |
334 | + : q_ptr(qq) |
335 | + , ready(false) |
336 | + , status(UCServiceProperties::Inactive) |
337 | + , type(UCServiceProperties::System) |
338 | +{ |
339 | +} |
340 | + |
341 | +UCServicePropertiesPrivate::~UCServicePropertiesPrivate() |
342 | +{ |
343 | +} |
344 | + |
345 | +UCServicePropertiesPrivate *UCServicePropertiesPrivate::get(UCServiceProperties *service) |
346 | +{ |
347 | + return service->d_func(); |
348 | +} |
349 | + |
350 | +void UCServicePropertiesPrivate::setError(const QString &msg) |
351 | +{ |
352 | + if (error == msg) { |
353 | + return; |
354 | + } |
355 | + error = msg; |
356 | + Q_EMIT q_ptr->errorChanged(); |
357 | +} |
358 | + |
359 | +void UCServicePropertiesPrivate::setStatus(UCServiceProperties::Status status) |
360 | +{ |
361 | + if (this->status == status) { |
362 | + return; |
363 | + } |
364 | + this->status = status; |
365 | + Q_EMIT q_ptr->statusChanged(); |
366 | +} |
367 | + |
368 | +void printLocked(UCServiceProperties *owner) |
369 | +{ |
370 | + qmlInfo(owner) << UbuntuI18n::instance().tr("Changing connection parameters forbidden."); |
371 | +} |
372 | + |
373 | +/*! |
374 | + * \qmltype ServiceProperties |
375 | + * \instantiates UCServiceProperties |
376 | + * \inqmlmodule Ubuntu.Components 1.1 |
377 | + * \since Ubuntu.Components 1.1 |
378 | + * \ingroup ubuntu-services |
379 | + * \brief The component enables accessing service properties from QML. |
380 | + * |
381 | + * The services accessed by the component are ones providing their interfaces |
382 | + * through DBus. The component is specialized to read properties exposed by these |
383 | + * services, andf to keep these property values up to date. It is not meant to |
384 | + * access signals or slots exposed, nor to change the values of the properties |
385 | + * watched. |
386 | + * |
387 | + * Properties watched should be declared within the body of the component like |
388 | + * any other QML property, preferably defining a default value for them. The component |
389 | + * will enumerate these properties and will ask the service to provide values for |
390 | + * those. When enumerating properties, each property will be checked twice, with |
391 | + * the case specified as well as with the first letter capitalized. |
392 | + * \qml |
393 | + * import QtQuick 2.3 |
394 | + * import Ubuntu.Components 1.1 |
395 | + * |
396 | + * ServiceProperties { |
397 | + * service: "org.freenode.AccountsService" |
398 | + * path: "/org/freenode/AccountsService" |
399 | + * serviceInterface: "org.freenode.AccountsService" |
400 | + * adaptorInterface: "com.ubuntu.touch.Accounts.Sound" |
401 | + * // listing properties to watch |
402 | + * // each property name existence will be checked against the current case |
403 | + * // as well as with first character capitalized |
404 | + * property bool incomingCallVibrate: true |
405 | + * } |
406 | + * \endqml |
407 | + * |
408 | + * Note that there are few properties which must be set in order the component |
409 | + * to work. These are \l service, \l path and \l adaptorInterface. Also, once |
410 | + * specified, \l service, \l serviceInterface and \l adaptorInterface values |
411 | + * should not be changed as it cannot be guaranteed that properties watched will |
412 | + * be available on those service. Therefore any change on these properties after |
413 | + * the component completion will be ignored. Property bindings on properties |
414 | + * watched will be ignored as well, as service will report changes in these property |
415 | + * values. |
416 | + * |
417 | + * The service is connected once the component gets completed (Component.onCompleted). |
418 | + * The \l error property specifies any error occured during connection, and the |
419 | + * \l status property notifies whether the connection to the service is active or not. |
420 | + * |
421 | + * \note Pay attention when chosing the service watched, and set your application's |
422 | + * AppArmor rights to ensure a successful service connection. |
423 | + */ |
424 | +UCServiceProperties::UCServiceProperties(QObject *parent) |
425 | + : QObject(parent) |
426 | + , d_ptr(createServicePropertiesAdapter(this)) |
427 | +{ |
428 | +} |
429 | +UCServiceProperties::~UCServiceProperties() |
430 | +{ |
431 | + delete d_ptr; |
432 | + d_ptr = 0; |
433 | +} |
434 | + |
435 | +void UCServiceProperties::classBegin() |
436 | +{ |
437 | +} |
438 | + |
439 | +void UCServiceProperties::componentComplete() |
440 | +{ |
441 | + Q_D(UCServiceProperties); |
442 | + d->ready = true; |
443 | + // enumerate properties |
444 | + const QMetaObject *mo = metaObject(); |
445 | + for (int i = mo->propertyOffset(); i < mo->propertyCount(); i++) { |
446 | + const QMetaProperty prop = mo->property(i); |
447 | + QString property(prop.name()); |
448 | + |
449 | + // check the binding on the property and warn if there is one. |
450 | + QQmlProperty qmlProperty(this, property); |
451 | + if (QQmlPropertyPrivate::binding(qmlProperty)) { |
452 | + qmlInfo(this) << UbuntuI18n::instance(). |
453 | + tr("Binding detected on property '%1' will be removed by the service updates."). |
454 | + arg(property); |
455 | + } |
456 | + // insert both the declared and capitalized first character properties |
457 | + d->properties << property; |
458 | + property[0] = property[0].toUpper(); |
459 | + d->properties << property; |
460 | + } |
461 | + // initialize DBus |
462 | + if (d->init()) { |
463 | + d->setStatus(UCServiceProperties::Synchronizing); |
464 | + d->fetchPropertyValues(); |
465 | + } |
466 | +} |
467 | + |
468 | +/*! |
469 | + * \qmlproperty enum ServiceProperties::type |
470 | + * Specifies the DBus connection session type. It can get the following values: |
471 | + * \list |
472 | + * \li - \e ServiceProperties.System when system bus is used (default) |
473 | + * \li - \e ServiceProperties.Session when session bus is used |
474 | + * \endlist |
475 | + */ |
476 | +UCServiceProperties::ServiceType UCServiceProperties::type() const |
477 | +{ |
478 | + Q_D(const UCServiceProperties); |
479 | + return d->type; |
480 | +} |
481 | +void UCServiceProperties::setType(ServiceType type) |
482 | +{ |
483 | + Q_D(UCServiceProperties); |
484 | + if (d->type == type) { |
485 | + return; |
486 | + } |
487 | + if (d->ready) { |
488 | + printLocked(this); |
489 | + return; |
490 | + } |
491 | + d->type = type; |
492 | + Q_EMIT typeChanged(); |
493 | +} |
494 | + |
495 | +/*! |
496 | + * \qmlproperty string ServiceProperties::service |
497 | + * The proeprty specifies the DBus service URI. It is mandatory to be specified. |
498 | + */ |
499 | +QString UCServiceProperties::service() const |
500 | +{ |
501 | + Q_D(const UCServiceProperties); |
502 | + return d->service; |
503 | +} |
504 | +void UCServiceProperties::setService(const QString &value) |
505 | +{ |
506 | + Q_D(UCServiceProperties); |
507 | + if (d->service == value) { |
508 | + return; |
509 | + } |
510 | + if (d->ready) { |
511 | + printLocked(this); |
512 | + return; |
513 | + } |
514 | + d->service = value; |
515 | + Q_EMIT serviceChanged(); |
516 | +} |
517 | + |
518 | +/*! |
519 | + * \qmlproperty string ServiceProperties::path |
520 | + * The property specifies the DBus service connection path. It is mandatory to be |
521 | + * specified. |
522 | + */ |
523 | +QString UCServiceProperties::path() const |
524 | +{ |
525 | + Q_D(const UCServiceProperties); |
526 | + return d->path; |
527 | +} |
528 | +void UCServiceProperties::setPath(const QString &value) |
529 | +{ |
530 | + Q_D(UCServiceProperties); |
531 | + if (d->path == value) { |
532 | + return; |
533 | + } |
534 | + d->path = value; |
535 | + Q_EMIT pathChanged(); |
536 | + if (d->ready) { |
537 | + // need to re-initialize connections |
538 | + d->init(); |
539 | + } |
540 | +} |
541 | + |
542 | +/*! |
543 | + * \qmlproperty string ServiceProperties::serviceInterface |
544 | + * The property specifies the service intertface. If it is an empty string, the |
545 | + * component will refer to the merging of all interfaces found in the service. |
546 | + */ |
547 | +QString UCServiceProperties::interface() const |
548 | +{ |
549 | + Q_D(const UCServiceProperties); |
550 | + return d->interface; |
551 | +} |
552 | +void UCServiceProperties::setInterface(const QString &value) |
553 | +{ |
554 | + Q_D(UCServiceProperties); |
555 | + if (d->interface == value) { |
556 | + return; |
557 | + } |
558 | + if (d->ready) { |
559 | + printLocked(this); |
560 | + return; |
561 | + } |
562 | + d->interface = value; |
563 | + Q_EMIT serviceInterfaceChanged(); |
564 | +} |
565 | +/*! |
566 | + * \qmlproperty string ServiceProperties::adaptorInterface |
567 | + * The proeprty specifies the dbus adaptor interface which provides the properties |
568 | + * watched. This can be a different interface that the one specified in \l serviceInterface, |
569 | + * and in the same way, it can be empty, in which case all the properties from all |
570 | + * interfaces of the service will be watched. |
571 | + */ |
572 | +QString UCServiceProperties::adaptor() const |
573 | +{ |
574 | + Q_D(const UCServiceProperties); |
575 | + return d->adaptor; |
576 | +} |
577 | +void UCServiceProperties::setAdaptor(const QString &value) |
578 | +{ |
579 | + Q_D(UCServiceProperties); |
580 | + if (d->adaptor == value) { |
581 | + return; |
582 | + } |
583 | + if (d->ready) { |
584 | + printLocked(this); |
585 | + return; |
586 | + } |
587 | + d->adaptor = value; |
588 | + Q_EMIT adaptorInterfaceChanged(); |
589 | +} |
590 | + |
591 | +/*! |
592 | + * \qmlproperty string ServiceProperties::error |
593 | + * The property is set with a human readablestring each time an error occurrs |
594 | + * during the service connection. Empty string means no error. |
595 | + */ |
596 | +QString UCServiceProperties::error() |
597 | +{ |
598 | + Q_D(UCServiceProperties); |
599 | + return d->error; |
600 | +} |
601 | + |
602 | +/*! |
603 | + * \qmlproperty enum ServiceProperties::status |
604 | + * The property presents the status of the component. |
605 | + * \list |
606 | + * \li - \e ServiceProperties.Inactive - the component is inactive, initial state |
607 | + * \li - \e ServiceProperties.ConnectionError - there was a connection error, the |
608 | + * \l error contains the error string. |
609 | + * \li - \e ServiceProperties.Synchronizing - the connection to the service succeeded, |
610 | + * and the properties are being synchronized; |
611 | + * \li - \e ServiceProperties.Active - the service watcher is active and initial |
612 | + * property synchronization completed. |
613 | + * \endlist |
614 | + * \note While the status is set to \e Synchronizing, the properties are checked |
615 | + * against their existence in the service. Each proeprty will be checked as declared |
616 | + * as well with capital first letter. If neither of these exists in the service, |
617 | + * it will be reported in the \l error property separately. |
618 | + */ |
619 | +UCServiceProperties::Status UCServiceProperties::status() const |
620 | +{ |
621 | + Q_D(const UCServiceProperties); |
622 | + return d->status; |
623 | +} |
624 | + |
625 | +#include "moc_ucserviceproperties.cpp" |
626 | |
627 | === added file 'modules/Ubuntu/Components/plugin/ucserviceproperties.h' |
628 | --- modules/Ubuntu/Components/plugin/ucserviceproperties.h 1970-01-01 00:00:00 +0000 |
629 | +++ modules/Ubuntu/Components/plugin/ucserviceproperties.h 2014-12-03 10:22:28 +0000 |
630 | @@ -0,0 +1,83 @@ |
631 | +/* |
632 | + * Copyright 2014 Canonical Ltd. |
633 | + * |
634 | + * This program is free software; you can redistribute it and/or modify |
635 | + * it under the terms of the GNU Lesser General Public License as published by |
636 | + * the Free Software Foundation; version 3. |
637 | + * |
638 | + * This program is distributed in the hope that it will be useful, |
639 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
640 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
641 | + * GNU Lesser General Public License for more details. |
642 | + * |
643 | + * You should have received a copy of the GNU Lesser General Public License |
644 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
645 | + */ |
646 | + |
647 | +#ifndef UCSERVICEPROPERTIES_H |
648 | +#define UCSERVICEPROPERTIES_H |
649 | + |
650 | +#include <QtCore/QObject> |
651 | +#include <QtQml/QQmlParserStatus> |
652 | + |
653 | +class UCServicePropertiesPrivate; |
654 | +class UCServiceProperties : public QObject, public QQmlParserStatus |
655 | +{ |
656 | + Q_OBJECT |
657 | + Q_INTERFACES(QQmlParserStatus) |
658 | + |
659 | + Q_PROPERTY(ServiceType type READ type WRITE setType NOTIFY typeChanged REVISION 1) |
660 | + Q_PROPERTY(QString service READ service WRITE setService NOTIFY serviceChanged REVISION 1) |
661 | + Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged REVISION 1) |
662 | + Q_PROPERTY(QString serviceInterface READ interface WRITE setInterface NOTIFY serviceInterfaceChanged REVISION 1) |
663 | + Q_PROPERTY(QString adaptorInterface READ adaptor WRITE setAdaptor NOTIFY adaptorInterfaceChanged REVISION 1) |
664 | + Q_PROPERTY(QString error READ error NOTIFY errorChanged REVISION 1) |
665 | + Q_PROPERTY(Status status READ status NOTIFY statusChanged REVISION 1) |
666 | + |
667 | + Q_ENUMS(ServiceType Status) |
668 | +public: |
669 | + enum ServiceType { |
670 | + Undefined, |
671 | + System, |
672 | + Session |
673 | + }; |
674 | + enum Status { |
675 | + Inactive, |
676 | + ConnectionError, |
677 | + Synchronizing, |
678 | + Active |
679 | + }; |
680 | + |
681 | + explicit UCServiceProperties(QObject *parent = 0); |
682 | + ~UCServiceProperties(); |
683 | + void classBegin(); |
684 | + void componentComplete(); |
685 | + |
686 | + ServiceType type() const; |
687 | + void setType(ServiceType type); |
688 | + QString service() const; |
689 | + void setService(const QString &value); |
690 | + QString path() const; |
691 | + void setPath(const QString &value); |
692 | + QString interface() const; |
693 | + void setInterface(const QString &value); |
694 | + QString adaptor() const; |
695 | + void setAdaptor(const QString &value); |
696 | + QString error(); |
697 | + Status status() const; |
698 | + |
699 | +Q_SIGNALS: |
700 | + void typeChanged(); |
701 | + void serviceChanged(); |
702 | + void pathChanged(); |
703 | + void serviceInterfaceChanged(); |
704 | + void adaptorInterfaceChanged(); |
705 | + void errorChanged(); |
706 | + void statusChanged(); |
707 | + |
708 | +private: |
709 | + UCServicePropertiesPrivate *d_ptr; |
710 | + Q_DECLARE_PRIVATE_D(d_ptr, UCServiceProperties) |
711 | +}; |
712 | + |
713 | +#endif // UCSERVICEPROPERTIES_H |
714 | |
715 | === added file 'modules/Ubuntu/Components/plugin/ucserviceproperties_p.h' |
716 | --- modules/Ubuntu/Components/plugin/ucserviceproperties_p.h 1970-01-01 00:00:00 +0000 |
717 | +++ modules/Ubuntu/Components/plugin/ucserviceproperties_p.h 2014-12-03 10:22:28 +0000 |
718 | @@ -0,0 +1,53 @@ |
719 | +/* |
720 | + * Copyright 2014 Canonical Ltd. |
721 | + * |
722 | + * This program is free software; you can redistribute it and/or modify |
723 | + * it under the terms of the GNU Lesser General Public License as published by |
724 | + * the Free Software Foundation; version 3. |
725 | + * |
726 | + * This program is distributed in the hope that it will be useful, |
727 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
728 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
729 | + * GNU Lesser General Public License for more details. |
730 | + * |
731 | + * You should have received a copy of the GNU Lesser General Public License |
732 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
733 | + */ |
734 | + |
735 | +#ifndef UCSERVICEPROPERTIES_P_H |
736 | +#define UCSERVICEPROPERTIES_P_H |
737 | + |
738 | +#include "ucserviceproperties.h" |
739 | +#include <QtCore/QStringList> |
740 | + |
741 | +class UCServicePropertiesPrivate |
742 | +{ |
743 | +public: |
744 | + UCServicePropertiesPrivate(UCServiceProperties *qq); |
745 | + virtual ~UCServicePropertiesPrivate(); |
746 | + |
747 | + static UCServicePropertiesPrivate *get(UCServiceProperties *service); |
748 | + void setError(const QString &msg); |
749 | + void setStatus(UCServiceProperties::Status status); |
750 | + |
751 | + virtual bool init() = 0; |
752 | + virtual bool fetchPropertyValues() = 0; |
753 | + virtual bool readProperty(const QString &property) = 0; |
754 | + virtual bool testProperty(const QString &property, const QVariant &value) = 0; |
755 | + |
756 | + // data |
757 | + UCServiceProperties *q_ptr; |
758 | + bool ready:1; |
759 | + UCServiceProperties::Status status; |
760 | + UCServiceProperties::ServiceType type; |
761 | + QString service; |
762 | + QString path; |
763 | + QString interface; |
764 | + QString adaptor; |
765 | + QString error; |
766 | + QStringList properties; |
767 | +}; |
768 | + |
769 | +UCServicePropertiesPrivate *createServicePropertiesAdapter(UCServiceProperties *owner); |
770 | + |
771 | +#endif // UCSERVICEPROPERTIES_P_H |
772 | |
773 | === modified file 'tests/unit/runtest.sh' |
774 | --- tests/unit/runtest.sh 2014-11-18 14:31:53 +0000 |
775 | +++ tests/unit/runtest.sh 2014-12-03 10:22:28 +0000 |
776 | @@ -22,18 +22,18 @@ |
777 | _TESTFILE=$2 |
778 | _MINIMAL=$3 |
779 | _XML="../../test_$_TARGET_$_TESTFILE.xml" |
780 | -_ARGS="-o $_XML,xunitxml -o -,txt" |
781 | +_ARGS="-p -o -p $_XML,xunitxml -p -o -p -,txt" |
782 | set +e |
783 | |
784 | function create_test_cmd { |
785 | - _CMD="./$_TARGET" |
786 | + _CMD="dbus-test-runner --task ./$_TARGET -n $_TESTFILE -m 300" |
787 | if [ "$_MINIMAL" = "minimal" ]; then |
788 | - _CMD="$_CMD -platform minimal" |
789 | + _CMD="$_CMD -p -platform -p minimal" |
790 | fi |
791 | if [ $_TARGET != $_TESTFILE ]; then |
792 | - _CMD="$_CMD -input $_TESTFILE" |
793 | + _CMD="$_CMD -p -input -p $_TESTFILE" |
794 | fi |
795 | - _CMD="$_CMD -maxwarnings 40" |
796 | + _CMD="$_CMD -p -maxwarnings -p 40" |
797 | } |
798 | |
799 | function execute_test_cmd { |
800 | |
801 | === added directory 'tests/unit_x11/tst_serviceproperties' |
802 | === added file 'tests/unit_x11/tst_serviceproperties/IncomingCallVibrateWatcher.qml' |
803 | --- tests/unit_x11/tst_serviceproperties/IncomingCallVibrateWatcher.qml 1970-01-01 00:00:00 +0000 |
804 | +++ tests/unit_x11/tst_serviceproperties/IncomingCallVibrateWatcher.qml 2014-12-03 10:22:28 +0000 |
805 | @@ -0,0 +1,31 @@ |
806 | +/* |
807 | + * Copyright 2014 Canonical Ltd. |
808 | + * |
809 | + * This program is free software; you can redistribute it and/or modify |
810 | + * it under the terms of the GNU Lesser General Public License as published by |
811 | + * the Free Software Foundation; version 3. |
812 | + * |
813 | + * This program is distributed in the hope that it will be useful, |
814 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
815 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
816 | + * GNU Lesser General Public License for more details. |
817 | + * |
818 | + * You should have received a copy of the GNU Lesser General Public License |
819 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
820 | + */ |
821 | + |
822 | +import QtQuick 2.3 |
823 | +import Ubuntu.Components 1.1 |
824 | + |
825 | +Item { |
826 | + property alias service: service |
827 | + ServiceProperties { |
828 | + id: service |
829 | + service: "org.freedesktop.Accounts" |
830 | + serviceInterface: "org.freedesktop.Accounts" |
831 | + path: "/org/freedesktop/Accounts" |
832 | + adaptorInterface: "com.ubuntu.touch.AccountsService.Sound" |
833 | + |
834 | + property bool incomingCallVibrate: true |
835 | + } |
836 | +} |
837 | |
838 | === added file 'tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher.qml' |
839 | --- tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher.qml 1970-01-01 00:00:00 +0000 |
840 | +++ tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher.qml 2014-12-03 10:22:28 +0000 |
841 | @@ -0,0 +1,31 @@ |
842 | +/* |
843 | + * Copyright 2014 Canonical Ltd. |
844 | + * |
845 | + * This program is free software; you can redistribute it and/or modify |
846 | + * it under the terms of the GNU Lesser General Public License as published by |
847 | + * the Free Software Foundation; version 3. |
848 | + * |
849 | + * This program is distributed in the hope that it will be useful, |
850 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
851 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
852 | + * GNU Lesser General Public License for more details. |
853 | + * |
854 | + * You should have received a copy of the GNU Lesser General Public License |
855 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
856 | + */ |
857 | + |
858 | +import QtQuick 2.3 |
859 | +import Ubuntu.Components 1.1 |
860 | + |
861 | +Item { |
862 | + property alias service: service |
863 | + ServiceProperties { |
864 | + id: service |
865 | + service: "org.freedesktop.Accounts" |
866 | + serviceInterface: "org.freedesktop.Accounts" |
867 | + path: "/org/freedesktop/Accounts" |
868 | + adaptorInterface: "com.ubuntu.touch.AccountsService.Sound" |
869 | + |
870 | + property bool thisIsAnInvalidPropertyToWatch: true |
871 | + } |
872 | +} |
873 | |
874 | === added file 'tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher2.qml' |
875 | --- tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher2.qml 1970-01-01 00:00:00 +0000 |
876 | +++ tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher2.qml 2014-12-03 10:22:28 +0000 |
877 | @@ -0,0 +1,32 @@ |
878 | +/* |
879 | + * Copyright 2014 Canonical Ltd. |
880 | + * |
881 | + * This program is free software; you can redistribute it and/or modify |
882 | + * it under the terms of the GNU Lesser General Public License as published by |
883 | + * the Free Software Foundation; version 3. |
884 | + * |
885 | + * This program is distributed in the hope that it will be useful, |
886 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
887 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
888 | + * GNU Lesser General Public License for more details. |
889 | + * |
890 | + * You should have received a copy of the GNU Lesser General Public License |
891 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
892 | + */ |
893 | + |
894 | +import QtQuick 2.3 |
895 | +import Ubuntu.Components 1.1 |
896 | + |
897 | +Item { |
898 | + property alias service: service |
899 | + ServiceProperties { |
900 | + id: service |
901 | + service: "org.freedesktop.Accounts" |
902 | + serviceInterface: "org.freedesktop.Accounts" |
903 | + path: "/org/freedesktop/Accounts" |
904 | + adaptorInterface: "com.ubuntu.touch.AccountsService.Sound" |
905 | + |
906 | + property bool thisIsAnInvalidPropertyToWatch: true |
907 | + property bool incomingCallVibrate: true |
908 | + } |
909 | +} |
910 | |
911 | === added file 'tests/unit_x11/tst_serviceproperties/tst_serviceproperties.cpp' |
912 | --- tests/unit_x11/tst_serviceproperties/tst_serviceproperties.cpp 1970-01-01 00:00:00 +0000 |
913 | +++ tests/unit_x11/tst_serviceproperties/tst_serviceproperties.cpp 2014-12-03 10:22:28 +0000 |
914 | @@ -0,0 +1,146 @@ |
915 | +/* |
916 | + * Copyright 2014 Canonical Ltd. |
917 | + * |
918 | + * This program is free software; you can redistribute it and/or modify |
919 | + * it under the terms of the GNU Lesser General Public License as published by |
920 | + * the Free Software Foundation; version 3. |
921 | + * |
922 | + * This program is distributed in the hope that it will be useful, |
923 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
924 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
925 | + * GNU Lesser General Public License for more details. |
926 | + * |
927 | + * You should have received a copy of the GNU Lesser General Public License |
928 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
929 | + */ |
930 | + |
931 | +#include "uctestcase.h" |
932 | +#include "ucserviceproperties.h" |
933 | +#include "ucserviceproperties_p.h" |
934 | +#include <QtCore/QString> |
935 | +#include <QtCore/QDebug> |
936 | +#include <QtTest/QTest> |
937 | +#include <QtTest/QSignalSpy> |
938 | + |
939 | +class tst_ServiceProperties : public QObject |
940 | +{ |
941 | + Q_OBJECT |
942 | + |
943 | +public: |
944 | + tst_ServiceProperties() {} |
945 | + |
946 | +private: |
947 | + |
948 | + QString error; |
949 | + |
950 | + // FIXME use UbuntuTestCase::ignoreWaring in Vivid |
951 | + void ignoreWarning(const QString& fileName, uint line, uint column, const QString& message, uint occurences=1) |
952 | + { |
953 | + for (uint i = 0; i < occurences; i++) { |
954 | + QString url(QUrl::fromLocalFile(QFileInfo(fileName).absoluteFilePath()).toEncoded()); |
955 | + QString warning(QString("%1:%2:%3: %4").arg(url).arg(line).arg(column).arg(message)); |
956 | + QTest::ignoreMessage(QtWarningMsg, warning.toUtf8()); |
957 | + } |
958 | + } |
959 | + |
960 | + |
961 | +private Q_SLOTS: |
962 | + |
963 | + void initTestCase() |
964 | + { |
965 | + // check if the connection is possible, otherwise we must skip all tests |
966 | + QScopedPointer<UbuntuTestCase> test(new UbuntuTestCase("IncomingCallVibrateWatcher.qml")); |
967 | + UCServiceProperties *watcher = static_cast<UCServiceProperties*>(test->rootObject()->property("service").value<QObject*>()); |
968 | + QVERIFY(watcher); |
969 | + if (watcher->status() == UCServiceProperties::Synchronizing || |
970 | + watcher->status() == UCServiceProperties::Inactive) { |
971 | + QSignalSpy wait(watcher, SIGNAL(statusChanged())); |
972 | + wait.wait(); |
973 | + } |
974 | + if (watcher->status() == UCServiceProperties::ConnectionError) { |
975 | + error = "Skip test: " + watcher->error(); |
976 | + } |
977 | + } |
978 | + |
979 | + void test_change_property() |
980 | + { |
981 | + if (!error.isEmpty()) { |
982 | + QSKIP(qPrintable(error)); |
983 | + } |
984 | + QScopedPointer<UbuntuTestCase> test(new UbuntuTestCase("IncomingCallVibrateWatcher.qml")); |
985 | + UCServiceProperties *watcher = static_cast<UCServiceProperties*>(test->rootObject()->property("service").value<QObject*>()); |
986 | + QVERIFY(watcher); |
987 | + |
988 | + bool backup = watcher->property("incomingCallVibrate").toBool(); |
989 | + UCServicePropertiesPrivate *pWatcher = UCServicePropertiesPrivate::get(watcher); |
990 | + QSignalSpy spy(watcher, SIGNAL(incomingCallVibrateChanged())); |
991 | + pWatcher->testProperty("IncomingCallVibrate", !backup); |
992 | + spy.wait(400); |
993 | + QCOMPARE(spy.count(), 1); |
994 | + QCOMPARE(watcher->property("incomingCallVibrate").toBool(), !backup); |
995 | + |
996 | + // restore value |
997 | + spy.clear(); |
998 | + pWatcher->testProperty("IncomingCallVibrate", backup); |
999 | + spy.wait(400); |
1000 | + } |
1001 | + |
1002 | + void test_invalid_property() |
1003 | + { |
1004 | + if (!error.isEmpty()) { |
1005 | + QSKIP(qPrintable(error)); |
1006 | + } |
1007 | + ignoreWarning("InvalidPropertyWatcher.qml", 22, 5, "QML ServiceProperties: No such property 'ThisIsAnInvalidPropertyToWatch'"); |
1008 | + QScopedPointer<UbuntuTestCase> test(new UbuntuTestCase("InvalidPropertyWatcher.qml")); |
1009 | + UCServiceProperties *watcher = static_cast<UCServiceProperties*>(test->rootObject()->property("service").value<QObject*>()); |
1010 | + QVERIFY(watcher); |
1011 | + // error should not be set |
1012 | + QCOMPARE(watcher->property("error").toString(), QString()); |
1013 | + } |
1014 | + |
1015 | + void test_one_valid_one_invalid_property() |
1016 | + { |
1017 | + if (!error.isEmpty()) { |
1018 | + QSKIP(qPrintable(error)); |
1019 | + } |
1020 | + ignoreWarning("InvalidPropertyWatcher2.qml", 22, 5, "QML ServiceProperties: No such property 'ThisIsAnInvalidPropertyToWatch'"); |
1021 | + QScopedPointer<UbuntuTestCase> test(new UbuntuTestCase("InvalidPropertyWatcher2.qml")); |
1022 | + UCServiceProperties *watcher = static_cast<UCServiceProperties*>(test->rootObject()->property("service").value<QObject*>()); |
1023 | + QVERIFY(watcher); |
1024 | + // error should not be set |
1025 | + QCOMPARE(watcher->property("error").toString(), QString()); |
1026 | + } |
1027 | + |
1028 | + void test_change_connection_props_data() |
1029 | + { |
1030 | + QTest::addColumn<QString>("property"); |
1031 | + QTest::addColumn<QString>("value"); |
1032 | + |
1033 | + QTest::newRow("Changing servcie") << "service" << "anything.else"; |
1034 | + QTest::newRow("Changing interface") << "serviceInterface" << "anything.else"; |
1035 | + QTest::newRow("Changing adaptor") << "adaptorInterface" << "anything.else"; |
1036 | + } |
1037 | + void test_change_connection_props() |
1038 | + { |
1039 | + QFETCH(QString, property); |
1040 | + QFETCH(QString, value); |
1041 | + |
1042 | + if (!error.isEmpty()) { |
1043 | + QSKIP(qPrintable(error)); |
1044 | + } |
1045 | + ignoreWarning("IncomingCallVibrateWatcher.qml", 22, 5, "QML ServiceProperties: Changing connection parameters forbidden."); |
1046 | + QScopedPointer<UbuntuTestCase> test(new UbuntuTestCase("IncomingCallVibrateWatcher.qml")); |
1047 | + UCServiceProperties *watcher = static_cast<UCServiceProperties*>(test->rootObject()->property("service").value<QObject*>()); |
1048 | + QVERIFY(watcher); |
1049 | + |
1050 | + // try to change the property |
1051 | + watcher->setProperty(property.toLocal8Bit().constData(), value); |
1052 | + // no error should be reported |
1053 | + QCOMPARE(watcher->property("error").toString(), QString()); |
1054 | + } |
1055 | + |
1056 | +}; |
1057 | + |
1058 | +QTEST_MAIN(tst_ServiceProperties) |
1059 | + |
1060 | +#include "tst_serviceproperties.moc" |
1061 | |
1062 | === added file 'tests/unit_x11/tst_serviceproperties/tst_serviceproperties.pro' |
1063 | --- tests/unit_x11/tst_serviceproperties/tst_serviceproperties.pro 1970-01-01 00:00:00 +0000 |
1064 | +++ tests/unit_x11/tst_serviceproperties/tst_serviceproperties.pro 2014-12-03 10:22:28 +0000 |
1065 | @@ -0,0 +1,8 @@ |
1066 | +include(../test-include.pri) |
1067 | +SOURCES += \ |
1068 | + tst_serviceproperties.cpp |
1069 | + |
1070 | +OTHER_FILES += \ |
1071 | + IncomingCallVibrateWatcher.qml \ |
1072 | + InvalidPropertyWatcher.qml \ |
1073 | + InvalidPropertyWatcher2.qml |
We need a test case for when accountservice is not available - if we don't want a hard dependency it can't be causing errors at runtime.
995 + QVERIFY( watcher- >property( "error" ).toString( ).isEmpty( )); watcher- >property( "error" ).toString( ).isEmpty( )); errorSpy. count() , 0);
1009 + QVERIFY(
1039 + QCOMPARE(
Please change all 3 cases where error is checked to a COMPARE so that the error becomes visible in the log.
785 - _CMD="./$_TARGET" test-runner --task ./$_TARGET -n $_TESTFILE -m 30"
786 + _CMD="dbus-
This must be 300 otherwise some tests time out.