Merge lp:~laney/ubuntu-system-settings/reset-api into lp:ubuntu-system-settings

Proposed by Iain Lane
Status: Merged
Approved by: Sebastien Bacher
Approved revision: 504
Merged at revision: 863
Proposed branch: lp:~laney/ubuntu-system-settings/reset-api
Merge into: lp:ubuntu-system-settings
Diff against target: 541 lines (+268/-30)
17 files modified
debian/control (+2/-0)
lib/SystemSettings/plugin-interface.h (+9/-0)
plugins/battery/plugin/battery-plugin.h (+3/-3)
plugins/brightness/plugin/brightness-plugin.h (+3/-3)
plugins/reset/ResetAllSettings.qml (+4/-2)
plugins/system-update/plugin/update-plugin.h (+4/-3)
src/plugin-manager.cpp (+12/-0)
src/plugin-manager.h (+1/-0)
src/plugin.cpp (+63/-5)
src/plugin.h (+2/-0)
tests/CMakeLists.txt (+4/-0)
tests/data/phone.settings (+9/-0)
tests/test-plugin.cpp (+18/-10)
tests/test-plugin.h (+3/-3)
tests/test-plugin2.cpp (+44/-0)
tests/test-plugin2.h (+41/-0)
tests/tst_plugins.cpp (+46/-1)
To merge this branch: bzr merge lp:~laney/ubuntu-system-settings/reset-api
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Approve
Sebastien Bacher (community) Needs Fixing
Alberto Mardegan Needs Fixing
Review via email: mp+208661@code.launchpad.net

Commit message

Add a 'reset' API so that plugins can reset their settings to default. They can do this in one of two ways: by providing a function 'bool reset()' in their 'plugin' which returns true or by providing a top-level javascript function 'reset' in their page component.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alberto Mardegan (mardy) wrote :

On 02/27/2014 07:55 PM, Iain Lane wrote:
> + // Try to use the plugin's reset method
> + if (d->m_plugin2 && d->m_plugin2->reset())
> + return;
> +
> + // Otherwise, try to use one from the page component
> + QQmlComponent *component = pageComponent();

I'd suggest adding this (to avoid the need of changing the Online
Accounts panel at the same time):

/* If the plugin implements version 1 of the interface but not version
 * 2, we assume that we won't find a "reset()" method in the
 * pageComponent either.
 */
if (d->m_plugin && !d->m_plugin2)
    return;

Revision history for this message
Iain Lane (laney) wrote :

On Fri, Feb 28, 2014 at 08:15:32AM -0000, Alberto Mardegan wrote:
> On 02/27/2014 07:55 PM, Iain Lane wrote:
> > + // Try to use the plugin's reset method
> > + if (d->m_plugin2 && d->m_plugin2->reset())
> > + return;
> > +
> > + // Otherwise, try to use one from the page component
> > + QQmlComponent *component = pageComponent();
>
> I'd suggest adding this (to avoid the need of changing the Online
> Accounts panel at the same time):
>
> /* If the plugin implements version 1 of the interface but not version
> * 2, we assume that we won't find a "reset()" method in the
> * pageComponent either.
> */
> if (d->m_plugin && !d->m_plugin2)
> return;

I did consider that, but I came to the conclusion that I think it should
still be valid to continue to use interface version 1 and provide
resetting via the PageComponent.

--
Iain Lane [ <email address hidden> ]
Debian Developer [ <email address hidden> ]
Ubuntu Developer [ <email address hidden> ]

Revision history for this message
Iain Lane (laney) wrote :

Hold on, I'm going to write some tests / examples

Revision history for this message
Iain Lane (laney) wrote :

ok, tests added, see what you think now please

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Alberto Mardegan (mardy) wrote :

L149: better delete the component here (though it's not leaked because it has the Plugin as its parent, so it's not a big issue)

L284,L285: indent the QML code one space more

L291: is this really needed? If it is, then maybe we should have this code in src/plugin.cpp, and not just in the test plugin.

All the rest looks fine to me, though I'd really like to see the addition of the code I suggested in the previous comment. :-)

review: Needs Fixing
Revision history for this message
Iain Lane (laney) wrote :

On Mon, Mar 03, 2014 at 09:45:11AM -0000, Alberto Mardegan wrote:
> Review: Needs Fixing
>
> L149: better delete the component here (though it's not leaked because it has the Plugin as its parent, so it's not a big issue)
>
> L284,L285: indent the QML code one space more

Fixing, thanks - actually 284 is redundant now so I'll delete that.

> L291: is this really needed? If it is, then maybe we should have this code in src/plugin.cpp, and not just in the test plugin.

Something is broken here. I was trying to see if it worked on the CI,
but it doesn't as you can see; will try to fix some other way soon.

  QWARN : PluginsTest::testReset() QQmlComponent: Component is not ready
  INFO : PluginsTest::testReset() Did not receive message: "Hello"
  FAIL! : PluginsTest::testReset() Not all expected messages were received

& my last revision just makes it hang altogether. I guess it probably
/should/ be in plugin.cpp though, yeah, if it's generally possible that
the returned component is not ready (which I suppose is true).

>
> All the rest looks fine to me, though I'd really like to see the addition of the code I suggested in the previous comment. :-)

I'll let Seb or another reviewer adjudicate. I gave my reasons already,
but I'm happy to defer if I get outvoted. :-)

--
Iain Lane [ <email address hidden> ]
Debian Developer [ <email address hidden> ]
Ubuntu Developer [ <email address hidden> ]

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Sebastien Bacher (seb128) wrote :

> though I'd really like to see the addition of the code I suggested in the previous comment. :-)

what is going to happen without that code if we don't land -online at the same time? it seems the code is checking for a reset() and handle it not being there, so it shouldn't be an issue?

Revision history for this message
Iain Lane (laney) wrote :

On Mon, Mar 03, 2014 at 02:12:14PM -0000, Sebastien Bacher wrote:
> > though I'd really like to see the addition of the code I suggested in the previous comment. :-)
>
> what is going to happen without that code if we don't land -online at the same time? it seems the code is checking for a reset() and handle it not being there, so it shouldn't be an issue?

Because online accounts does something weird when you ask for its page
component - it unconditionally shows itself. So if you invoke the reset
action then the online accounts panel pops up.

Alberto's solution avoids this because online accounts doesn't implement
the '2' interface, so we would just skip resetting it completely.

--
Iain Lane [ <email address hidden> ]
Debian Developer [ <email address hidden> ]
Ubuntu Developer [ <email address hidden> ]

Revision history for this message
Sebastien Bacher (seb128) wrote :

thanks for the explanation, to me it looks like that check is low cost and makes things a bit more robust, so +1 for including it (though in practice it's likely only online-account is going to have the issue and we can batch those so it doesn't really matter much easier way)

Revision history for this message
Alberto Mardegan (mardy) wrote :

If that extra code bothers you, we can add it now and remove it later. :-)

Revision history for this message
Iain Lane (laney) wrote :

On Mon, Mar 03, 2014 at 02:46:35PM -0000, Sebastien Bacher wrote:
> thanks for the explanation, to me it looks like that check is low cost and makes things a bit more robust, so +1 for including it (though in practice it's likely only online-account is going to have the issue and we can batch those so it doesn't really matter much easier way)

OK then. I'll have to upgrade the plugins we provide to 2, and we need
to make sure that any future ones are 2, otherwise they won't be able to
be reset via qml/js.

I think it'll be a bit confusing and hard to debug if that ever happens,
so try to keep it in mind.

--
Iain Lane [ <email address hidden> ]
Debian Developer [ <email address hidden> ]
Ubuntu Developer [ <email address hidden> ]

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Jonas G. Drange (jonas-drange) wrote :

This looks great, thanks.

Revision history for this message
Sebastien Bacher (seb128) wrote :

needs to be rebased on trunk

review: Needs Fixing
504. By Iain Lane

Merge trunk

Revision history for this message
Iain Lane (laney) wrote :

merged, fyi

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:504
http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-ci/1111/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/2835
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/2256
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-amd64-ci/303
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/303
        deb: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/303/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-i386-ci/303
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/2914
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/4078
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/4078/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/10783
    SUCCESS: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/1868
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/2519
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/2519/artifact/work/output/*zip*/output.zip

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/ubuntu-system-settings-ci/1111/rebuild

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/control'
2--- debian/control 2014-07-30 19:47:49 +0000
3+++ debian/control 2014-07-31 14:07:19 +0000
4@@ -25,6 +25,8 @@
5 qtbase5-private-dev,
6 qtdeclarative5-dev,
7 libapt-pkg-dev,
8+# test-deps
9+ qtdeclarative5-qtquick2-plugin,
10 libubuntuoneauth-2.0-dev,
11 libubuntu-download-manager-client-dev,
12 libubuntu-download-manager-common-dev,
13
14=== modified file 'lib/SystemSettings/plugin-interface.h'
15--- lib/SystemSettings/plugin-interface.h 2013-05-09 11:03:58 +0000
16+++ lib/SystemSettings/plugin-interface.h 2014-07-31 14:07:19 +0000
17@@ -35,9 +35,18 @@
18 QObject *parent = 0) = 0;
19 };
20
21+class PluginInterface2: public PluginInterface
22+{
23+public:
24+ /* Return true if a reset has been performed */
25+ virtual bool reset() { return false; }
26+};
27+
28 } // namespace
29
30 Q_DECLARE_INTERFACE(SystemSettings::PluginInterface,
31 "com.ubuntu.SystemSettings.PluginInterface")
32+Q_DECLARE_INTERFACE(SystemSettings::PluginInterface2,
33+ "com.ubuntu.SystemSettings.PluginInterface/2.0")
34
35 #endif // SYSTEM_SETTINGS_PLUGIN_INTERFACE_H
36
37=== modified file 'plugins/battery/plugin/battery-plugin.h'
38--- plugins/battery/plugin/battery-plugin.h 2013-08-20 12:12:07 +0000
39+++ plugins/battery/plugin/battery-plugin.h 2014-07-31 14:07:19 +0000
40@@ -24,11 +24,11 @@
41 #include <QObject>
42 #include <SystemSettings/PluginInterface>
43
44-class BatteryPlugin: public QObject, public SystemSettings::PluginInterface
45+class BatteryPlugin: public QObject, public SystemSettings::PluginInterface2
46 {
47 Q_OBJECT
48- Q_PLUGIN_METADATA(IID "com.ubuntu.SystemSettings.PluginInterface")
49- Q_INTERFACES(SystemSettings::PluginInterface)
50+ Q_PLUGIN_METADATA(IID "com.ubuntu.SystemSettings.PluginInterface/2.0")
51+ Q_INTERFACES(SystemSettings::PluginInterface2)
52
53 public:
54 BatteryPlugin();
55
56=== modified file 'plugins/brightness/plugin/brightness-plugin.h'
57--- plugins/brightness/plugin/brightness-plugin.h 2014-01-27 13:01:26 +0000
58+++ plugins/brightness/plugin/brightness-plugin.h 2014-07-31 14:07:19 +0000
59@@ -24,11 +24,11 @@
60 #include <QObject>
61 #include <SystemSettings/PluginInterface>
62
63-class BrightnessPlugin: public QObject, public SystemSettings::PluginInterface
64+class BrightnessPlugin: public QObject, public SystemSettings::PluginInterface2
65 {
66 Q_OBJECT
67- Q_PLUGIN_METADATA(IID "com.ubuntu.SystemSettings.PluginInterface")
68- Q_INTERFACES(SystemSettings::PluginInterface)
69+ Q_PLUGIN_METADATA(IID "com.ubuntu.SystemSettings.PluginInterface/2.0")
70+ Q_INTERFACES(SystemSettings::PluginInterface2)
71
72 public:
73 SystemSettings::ItemBase *createItem(const QVariantMap &staticData,
74
75=== modified file 'plugins/reset/ResetAllSettings.qml'
76--- plugins/reset/ResetAllSettings.qml 2013-08-23 14:05:39 +0000
77+++ plugins/reset/ResetAllSettings.qml 2014-07-31 14:07:19 +0000
78@@ -29,8 +29,10 @@
79 text: i18n.tr("The contents and layout of the launcher, and the filters in the home screen will be returned to their original settings.")
80 Button {
81 text: i18n.tr("Reset all system settings")
82- enabled: false /* TODO: enable when there is a backend */
83- onClicked: PopupUtils.close(dialog)
84+ onClicked: {
85+ pluginManager.resetPlugins()
86+ PopupUtils.close(dialog)
87+ }
88 }
89 Button {
90 text: i18n.tr("Cancel")
91
92=== modified file 'plugins/system-update/plugin/update-plugin.h'
93--- plugins/system-update/plugin/update-plugin.h 2014-01-31 15:07:01 +0000
94+++ plugins/system-update/plugin/update-plugin.h 2014-07-31 14:07:19 +0000
95@@ -24,11 +24,12 @@
96 #include <QObject>
97 #include <SystemSettings/PluginInterface>
98
99-class CheckUpdatesPlugin: public QObject, public SystemSettings::PluginInterface
100+class CheckUpdatesPlugin: public QObject,
101+ public SystemSettings::PluginInterface2
102 {
103 Q_OBJECT
104- Q_PLUGIN_METADATA(IID "com.ubuntu.SystemSettings.PluginInterface")
105- Q_INTERFACES(SystemSettings::PluginInterface)
106+ Q_PLUGIN_METADATA(IID "com.ubuntu.SystemSettings.PluginInterface/2.0")
107+ Q_INTERFACES(SystemSettings::PluginInterface2)
108
109 public:
110 CheckUpdatesPlugin();
111
112=== modified file 'src/plugin-manager.cpp'
113--- src/plugin-manager.cpp 2013-09-19 11:30:44 +0000
114+++ src/plugin-manager.cpp 2014-07-31 14:07:19 +0000
115@@ -127,6 +127,18 @@
116 return d->m_plugins.value(category);
117 }
118
119+void PluginManager::resetPlugins()
120+{
121+ Q_D(const PluginManager);
122+
123+ typedef QMap<QString, Plugin *> Plugins;
124+ Q_FOREACH (const Plugins &plugins, d->m_plugins.values()) {
125+ Q_FOREACH (Plugin *plugin, plugins.values()) {
126+ plugin->reset();
127+ }
128+ }
129+}
130+
131 QAbstractItemModel *PluginManager::itemModel(const QString &category)
132 {
133 Q_D(PluginManager);
134
135=== modified file 'src/plugin-manager.h'
136--- src/plugin-manager.h 2013-09-19 11:30:44 +0000
137+++ src/plugin-manager.h 2014-07-31 14:07:19 +0000
138@@ -50,6 +50,7 @@
139
140 Q_INVOKABLE QObject *getByName(const QString &name) const;
141 Q_INVOKABLE QAbstractItemModel *itemModel(const QString &category);
142+ Q_INVOKABLE void resetPlugins();
143 QString getFilter();
144 void setFilter(const QString &filter);
145
146
147=== modified file 'src/plugin.cpp'
148--- src/plugin.cpp 2013-12-05 17:40:46 +0000
149+++ src/plugin.cpp 2014-07-31 14:07:19 +0000
150@@ -21,6 +21,7 @@
151 #include "debug.h"
152 #include "plugin.h"
153
154+#include <QEventLoop>
155 #include <QDir>
156 #include <QFileInfo>
157 #include <QJsonDocument>
158@@ -55,6 +56,8 @@
159 mutable Plugin *q_ptr;
160 mutable ItemBase *m_item;
161 mutable QPluginLoader m_loader;
162+ mutable PluginInterface *m_plugin;
163+ mutable PluginInterface2 *m_plugin2;
164 QString m_baseName;
165 QVariantMap m_data;
166 };
167@@ -64,7 +67,9 @@
168 PluginPrivate::PluginPrivate(Plugin *q, const QFileInfo &manifest):
169 q_ptr(q),
170 m_item(0),
171- m_baseName(manifest.completeBaseName())
172+ m_baseName(manifest.completeBaseName()),
173+ m_plugin(0),
174+ m_plugin2(0)
175 {
176 QFile file(manifest.filePath());
177 if (Q_UNLIKELY(!file.open(QIODevice::ReadOnly | QIODevice::Text))) {
178@@ -105,14 +110,21 @@
179 return false;
180 }
181
182- PluginInterface *interface =
183- qobject_cast<SystemSettings::PluginInterface*>(m_loader.instance());
184- if (Q_UNLIKELY(interface == 0)) {
185+ m_plugin2 = qobject_cast<SystemSettings::PluginInterface2*>(
186+ m_loader.instance());
187+
188+ if (m_plugin2)
189+ m_plugin = m_plugin2;
190+ else
191+ m_plugin = qobject_cast<SystemSettings::PluginInterface*>(
192+ m_loader.instance());
193+
194+ if (Q_UNLIKELY(m_plugin == 0)) {
195 qWarning() << name << "doesn't implement PluginInterface";
196 return false;
197 }
198
199- m_item = interface->createItem(m_data);
200+ m_item = m_plugin->createItem(m_data);
201 if (m_item == 0) return false;
202
203 QObject::connect(m_item, SIGNAL(iconChanged()),
204@@ -222,6 +234,52 @@
205 return d->m_data.value(keyHideByDefault, false).toBool();
206 }
207
208+void Plugin::reset()
209+{
210+ Q_D(const Plugin);
211+
212+ d->ensureLoaded();
213+
214+ /* If the plugin implements version 1 of the interface but not version
215+ * 2, we assume that we won't find a "reset()" method in the
216+ * pageComponent either.
217+ */
218+ if (d->m_plugin && !d->m_plugin2)
219+ return;
220+
221+ // Try to use the plugin's reset method
222+ if (d->m_plugin2 && d->m_plugin2->reset())
223+ return;
224+
225+ // Otherwise, try to use one from the page component
226+ QQmlComponent *component = pageComponent();
227+
228+ if (!component)
229+ return;
230+
231+ QObject *object = component->create();
232+
233+ // If it's there, try to search for the method
234+ if (!object) {
235+ delete component;
236+ return;
237+ }
238+
239+ const QMetaObject *metaObject = object->metaObject();
240+ int index = metaObject->indexOfMethod(
241+ QMetaObject::normalizedSignature("reset(void)"));
242+
243+ // and if that exists, call it
244+ if (index >= 0) {
245+ QMetaMethod method = metaObject->method(index);
246+ method.invoke(object, Qt::DirectConnection);
247+ }
248+
249+ delete object;
250+ delete component;
251+
252+}
253+
254 QQmlComponent *Plugin::entryComponent()
255 {
256 Q_D(const Plugin);
257
258=== modified file 'src/plugin.h'
259--- src/plugin.h 2013-12-05 17:40:46 +0000
260+++ src/plugin.h 2014-07-31 14:07:19 +0000
261@@ -60,6 +60,8 @@
262 bool isVisible() const;
263 bool hideByDefault() const;
264
265+ void reset();
266+
267 QQmlComponent *entryComponent();
268 QQmlComponent *pageComponent();
269
270
271=== modified file 'tests/CMakeLists.txt'
272--- tests/CMakeLists.txt 2014-07-22 18:29:46 +0000
273+++ tests/CMakeLists.txt 2014-07-31 14:07:19 +0000
274@@ -9,6 +9,10 @@
275 target_link_librarieS(test-plugin SystemSettings)
276 qt5_use_modules(test-plugin Core Qml)
277
278+add_library(test-plugin2 SHARED test-plugin2.cpp test-plugin2.h)
279+target_link_librarieS(test-plugin2 SystemSettings)
280+qt5_use_modules(test-plugin2 Core Qml)
281+
282 add_executable(tst-plugins
283 tst_plugins.cpp
284 ../src/debug.cpp
285
286=== added file 'tests/data/phone.settings'
287--- tests/data/phone.settings 1970-01-01 00:00:00 +0000
288+++ tests/data/phone.settings 2014-07-31 14:07:19 +0000
289@@ -0,0 +1,9 @@
290+{
291+ "name": "Phone",
292+ "icon": "nm-device-wireless",
293+ "category": "misc",
294+ "priority": 0,
295+ "has-dynamic-keywords": true,
296+ "has-dynamic-visibility": false,
297+ "plugin": "test-plugin2"
298+}
299
300=== modified file 'tests/test-plugin.cpp'
301--- tests/test-plugin.cpp 2013-05-13 07:39:05 +0000
302+++ tests/test-plugin.cpp 2014-07-31 14:07:19 +0000
303@@ -38,10 +38,13 @@
304 QObject *parent = 0);
305 virtual QQmlComponent *pageComponent(QQmlEngine *engine,
306 QObject *parent = 0);
307+private:
308+ QQmlComponent *m_pageComponent;
309 };
310
311 TestItem::TestItem(const QVariantMap &staticData, QObject *parent):
312- ItemBase(staticData, parent)
313+ ItemBase(staticData, parent),
314+ m_pageComponent(0)
315 {
316 QStringList keywords;
317 keywords << "one" << "two" << "three";
318@@ -59,17 +62,22 @@
319 return 0;
320 }
321
322+
323 QQmlComponent *TestItem::pageComponent(QQmlEngine *engine, QObject *parent)
324 {
325- QQmlComponent *page = new QQmlComponent(engine, parent);
326- page->setData("import QtQuick 2.0\n"
327- "Rectangle {\n"
328- " width: 200; height: 200;\n"
329- " objectName: \"myRect\"\n"
330- " color: \"red\""
331- "}",
332- QUrl());
333- return page;
334+ if (m_pageComponent == NULL) {
335+ QQmlComponent *page = new QQmlComponent(engine, parent);
336+ page->setData("import QtQuick 2.0\n"
337+ "Rectangle {\n"
338+ " function reset() { console.log('Hello') }\n"
339+ " width: 200; height: 200;\n"
340+ " objectName: \"myRect\"\n"
341+ " color: \"red\""
342+ "}",
343+ QUrl());
344+ m_pageComponent = page;
345+ }
346+ return m_pageComponent;
347 }
348
349 TestPlugin::TestPlugin():
350
351=== modified file 'tests/test-plugin.h'
352--- tests/test-plugin.h 2013-05-09 11:03:58 +0000
353+++ tests/test-plugin.h 2014-07-31 14:07:19 +0000
354@@ -24,11 +24,11 @@
355 #include <QObject>
356 #include <SystemSettings/PluginInterface>
357
358-class TestPlugin: public QObject, public SystemSettings::PluginInterface
359+class TestPlugin: public QObject, public SystemSettings::PluginInterface2
360 {
361 Q_OBJECT
362- Q_PLUGIN_METADATA(IID "com.ubuntu.SystemSettings.PluginInterface")
363- Q_INTERFACES(SystemSettings::PluginInterface)
364+ Q_PLUGIN_METADATA(IID "com.ubuntu.SystemSettings.PluginInterface/2.0")
365+ Q_INTERFACES(SystemSettings::PluginInterface2)
366
367 public:
368 TestPlugin();
369
370=== added file 'tests/test-plugin2.cpp'
371--- tests/test-plugin2.cpp 1970-01-01 00:00:00 +0000
372+++ tests/test-plugin2.cpp 2014-07-31 14:07:19 +0000
373@@ -0,0 +1,44 @@
374+/*
375+ * This file is part of system-settings
376+ *
377+ * Copyright (C) 2014 Canonical Ltd.
378+ *
379+ * Contact: Iain Lane <iain.lane@canonical.com>
380+ *
381+ * This program is free software: you can redistribute it and/or modify it
382+ * under the terms of the GNU General Public License version 3, as published
383+ * by the Free Software Foundation.
384+ *
385+ * This program is distributed in the hope that it will be useful, but
386+ * WITHOUT ANY WARRANTY; without even the implied warranties of
387+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
388+ * PURPOSE. See the GNU General Public License for more details.
389+ *
390+ * You should have received a copy of the GNU General Public License along
391+ * with this program. If not, see <http://www.gnu.org/licenses/>.
392+ */
393+
394+#include "test-plugin2.h"
395+
396+#include <QDebug>
397+
398+using namespace SystemSettings;
399+
400+TestPlugin2::TestPlugin2():
401+ QObject()
402+{
403+}
404+
405+ItemBase *TestPlugin2::createItem(const QVariantMap &staticData,
406+ QObject *parent)
407+{
408+ return NULL;
409+}
410+
411+bool TestPlugin2::reset()
412+{
413+ qDebug() << "reset function in plugin";
414+ return true;
415+}
416+
417+#include "test-plugin2.moc"
418
419=== added file 'tests/test-plugin2.h'
420--- tests/test-plugin2.h 1970-01-01 00:00:00 +0000
421+++ tests/test-plugin2.h 2014-07-31 14:07:19 +0000
422@@ -0,0 +1,41 @@
423+/*
424+ * This file is part of system-settings
425+ *
426+ * Copyright (C) 2014 Canonical Ltd.
427+ *
428+ * Contact: Iain Lane <iain.lane@canonical.com>
429+ *
430+ * This program is free software: you can redistribute it and/or modify it
431+ * under the terms of the GNU General Public License version 3, as published
432+ * by the Free Software Foundation.
433+ *
434+ * This program is distributed in the hope that it will be useful, but
435+ * WITHOUT ANY WARRANTY; without even the implied warranties of
436+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
437+ * PURPOSE. See the GNU General Public License for more details.
438+ *
439+ * You should have received a copy of the GNU General Public License along
440+ * with this program. If not, see <http://www.gnu.org/licenses/>.
441+ */
442+
443+#ifndef SYSTEM_SETTINGS_TEST_PLUGIN2_H
444+#define SYSTEM_SETTINGS_TEST_PLUGIN2_H
445+
446+#include <QObject>
447+#include <SystemSettings/PluginInterface>
448+
449+class TestPlugin2: public QObject, public SystemSettings::PluginInterface2
450+{
451+ Q_OBJECT
452+ Q_PLUGIN_METADATA(IID "com.ubuntu.SystemSettings.PluginInterface/2.0")
453+ Q_INTERFACES(SystemSettings::PluginInterface2)
454+
455+public:
456+ TestPlugin2();
457+
458+ SystemSettings::ItemBase *createItem(const QVariantMap &staticData,
459+ QObject *parent = 0);
460+ bool reset();
461+};
462+
463+#endif // SYSTEM_SETTINGS_TEST_PLUGIN2_H
464
465=== modified file 'tests/tst_plugins.cpp'
466--- tests/tst_plugins.cpp 2013-09-18 13:32:17 +0000
467+++ tests/tst_plugins.cpp 2014-07-31 14:07:19 +0000
468@@ -24,6 +24,8 @@
469
470 #include <QDebug>
471 #include <QObject>
472+#include <QQmlContext>
473+#include <QQmlEngine>
474 #include <QSignalSpy>
475 #include <QTest>
476
477@@ -40,6 +42,8 @@
478 void testCategory();
479 void testKeywords();
480 void testSorting();
481+ void testReset();
482+ void testResetInPlugin();
483 };
484
485 void PluginsTest::testCategory()
486@@ -49,7 +53,7 @@
487 manager.componentComplete();
488
489 QSet<QString> expectedCategories;
490- expectedCategories << "phone" << "network";
491+ expectedCategories << "phone" << "network" << "misc";
492 QCOMPARE(manager.categories().toSet(), expectedCategories);
493
494 QMap<QString, Plugin *> plugins = manager.plugins("phone");
495@@ -118,5 +122,46 @@
496 QCOMPARE(cellular->displayName(), QString("Bluetooth"));
497 }
498
499+void PluginsTest::testReset()
500+{
501+
502+ PluginManager manager;
503+ manager.classBegin();
504+ manager.componentComplete();
505+
506+ QAbstractItemModel *model(manager.itemModel("network"));
507+ Plugin *wireless = (Plugin *) model->data(model->index(0, 0),
508+ ItemModel::ItemRole).value<QObject *>();
509+
510+ QQmlEngine engine;
511+ QQmlContext *context = new QQmlContext(engine.rootContext());
512+ QQmlEngine::setContextForObject(wireless, context);
513+
514+ /* This is how you check that a debug message was printed */
515+ QTest::ignoreMessage(QtDebugMsg, "Hello");
516+ wireless->reset();
517+}
518+
519+void PluginsTest::testResetInPlugin()
520+{
521+ PluginManager manager;
522+ manager.classBegin();
523+ manager.componentComplete();
524+
525+ QAbstractItemModel *model(manager.itemModel("misc"));
526+ Plugin *phone = (Plugin *) model->data(model->index(0, 0),
527+ ItemModel::ItemRole).value<QObject *>();
528+
529+ QQmlEngine engine;
530+ QQmlContext *context = new QQmlContext(engine.rootContext());
531+ QQmlEngine::setContextForObject(phone, context);
532+
533+ /* This is how you check that a debug message was printed */
534+ /* qDebug() inserts a space at the end */
535+ QTest::ignoreMessage(QtDebugMsg, "reset function in plugin ");
536+
537+ phone->reset();
538+}
539+
540 QTEST_MAIN(PluginsTest);
541 #include "tst_plugins.moc"

Subscribers

People subscribed via source and target branches