on xenial help sign in
merged with lp:~nick-dedekind/unity8/sharedunitymenumodel
commit2a3f68a8d816ea76abd3a2afa7709d9cd25c1cc2 authorNick Dedekind <nick.dedekind@canonical.com> dateFri 26 Sep 2014, 11:37 (12 years ago) parent086f3bb82045e4
17 files changed+329−210
plugins/Unity/Indicators/CMakeLists.txt+1 plugins/Unity/Indicators/plugin.cpp+6−1 plugins/Unity/Indicators/sharedunitymenumodel.cpp+87 plugins/Unity/Indicators/sharedunitymenumodel.h+66 plugins/Unity/Indicators/unitymenumodelcache.cpp+27−12 plugins/Unity/Indicators/unitymenumodelcache.h+11−6 qml/Greeter/Clock.qml+9−9 qml/Panel/Indicators/CachedUnityMenuModel.qml−39 qml/Panel/Indicators/IndicatorBase.qml+2−2 tests/mocks/Unity/Indicators/CMakeLists.txt+1 tests/mocks/Unity/Indicators/fakeplugin.cpp+6−1 tests/mocks/Unity/Indicators/fakeunitymenumodelcache.cpp+13−2 tests/mocks/Unity/Indicators/fakeunitymenumodelcache.h+7 tests/plugins/Unity/Indicators/CMakeLists.txt+1 tests/plugins/Unity/Indicators/sharedunitymenumodeltest.cpp+92 tests/qmltests/CMakeLists.txt−1 tests/qmltests/Panel/Indicators/tst_CachedUnityMenuModel.qml−137
plugins/Unity/Indicators/CMakeLists.txt+1
@@ -24,6 +24,7 @@ set(IndicatorsQML_SOURCES
2424 modelprinter.cpp
2525 plugin.cpp
2626 rootactionstate.cpp
27+ sharedunitymenumodel.cpp
2728 unitymenumodelcache.cpp
2829 unitymenumodelstack.cpp
2930 visibleindicatorsmodel.cpp
plugins/Unity/Indicators/plugin.cpp+6−1
@@ -30,19 +30,23 @@
3030#include "menucontentactivator.h"
3131#include "modelprinter.h"
3232#include "rootactionstate.h"
33+#include "sharedunitymenumodel.h"
3334#include "unitymenumodelcache.h"
3435#include "unitymenumodelstack.h"
3536#include "visibleindicatorsmodel.h"
3637
38+#include <unitymenumodel.h>
39+
3740static QObject* menuModelCacheSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) {
3841 Q_UNUSED(engine);
3942 Q_UNUSED(scriptEngine);
40− return new UnityMenuModelCache;
43+ return UnityMenuModelCache::singleton();
4144}
4245
4346void Indicators2Plugin::registerTypes(const char *uri)
4447{
4548 Q_INIT_RESOURCE(indicators);
49+ qRegisterMetaType<UnityMenuModel*>("UnityMenuModel*");
4650
4751 qmlRegisterType<IndicatorsManager>(uri, 0, 1, "IndicatorsManager");
4852 qmlRegisterType<IndicatorsModel>(uri, 0, 1, "IndicatorsModel");
@@ -51,6 +55,7 @@ void Indicators2Plugin::registerTypes(const char *uri)
5155 qmlRegisterType<RootActionState>(uri, 0, 1, "RootActionState");
5256 qmlRegisterType<ModelPrinter>(uri, 0, 1, "ModelPrinter");
5357 qmlRegisterType<VisibleIndicatorsModel>(uri, 0, 1, "VisibleIndicatorsModel");
58+ qmlRegisterType<SharedUnityMenuModel>(uri, 0, 1, "SharedUnityMenuModel");
5459
5560 qmlRegisterSingletonType<UnityMenuModelCache>(uri, 0, 1, "UnityMenuModelCache", menuModelCacheSingleton);
5661
plugins/Unity/Indicators/sharedunitymenumodel.cppnew file+87
@@ -0,0 +1,87 @@
1+/*
2+ * Copyright 2014 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ */
17+
18+#include "sharedunitymenumodel.h"
19+#include "unitymenumodelcache.h"
20+
21+SharedUnityMenuModel::SharedUnityMenuModel(QObject* parent)
22+ : QObject(parent)
23+{
24+}
25+
26+QByteArray SharedUnityMenuModel::busName() const
27+{
28+ return m_busName;
29+}
30+
31+void SharedUnityMenuModel::setBusName(const QByteArray& busName)
32+{
33+ if (m_busName != busName) {
34+ m_busName = busName;
35+ Q_EMIT busNameChanged();
36+ initialize();
37+ }
38+}
39+
40+QByteArray SharedUnityMenuModel::menuObjectPath() const
41+{
42+ return m_menuObjectPath;
43+}
44+
45+void SharedUnityMenuModel::setMenuObjectPath(const QByteArray& menuObjectPath)
46+{
47+ if (m_menuObjectPath != menuObjectPath) {
48+ m_menuObjectPath = menuObjectPath;
49+ Q_EMIT menuObjectPathChanged();
50+ initialize();
51+ }
52+}
53+
54+QVariantMap SharedUnityMenuModel::actions() const
55+{
56+ return m_actions;
57+}
58+
59+void SharedUnityMenuModel::setActions(const QVariantMap& actions)
60+{
61+ if (m_actions != actions) {
62+ m_actions = actions;
63+ Q_EMIT actionsChanged();
64+ initialize();
65+ }
66+}
67+
68+UnityMenuModel* SharedUnityMenuModel::model() const
69+{
70+ return m_model ? m_model.data() : nullptr;
71+}
72+
73+void SharedUnityMenuModel::initialize()
74+{
75+ if (m_busName.isEmpty() || m_menuObjectPath.isEmpty() || m_actions.isEmpty()) {
76+ if (!m_model.isNull()) {
77+ m_model.clear();
78+ Q_EMIT modelChanged();
79+ }
80+ } else {
81+ QSharedPointer<UnityMenuModel> model = UnityMenuModelCache::singleton()->model(m_busName, m_menuObjectPath, m_actions);
82+ if (model != m_model) {
83+ m_model = model;
84+ Q_EMIT modelChanged();
85+ }
86+ }
87+}
plugins/Unity/Indicators/sharedunitymenumodel.hnew file+66
@@ -0,0 +1,66 @@
1+/*
2+ * Copyright 2014 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ */
17+
18+#ifndef SHAREDUNITYMENUMODEL_H
19+#define SHAREDUNITYMENUMODEL_H
20+
21+#include "unityindicatorsglobal.h"
22+
23+#include <QObject>
24+#include <QSharedPointer>
25+#include <QVariantMap>
26+
27+class UnityMenuModel;
28+
29+class UNITYINDICATORS_EXPORT SharedUnityMenuModel : public QObject
30+{
31+ Q_OBJECT
32+ Q_PROPERTY(QByteArray busName READ busName WRITE setBusName NOTIFY busNameChanged)
33+ Q_PROPERTY(QByteArray menuObjectPath READ menuObjectPath WRITE setMenuObjectPath NOTIFY menuObjectPathChanged)
34+ Q_PROPERTY(QVariantMap actions READ actions WRITE setActions NOTIFY actionsChanged)
35+ Q_PROPERTY(UnityMenuModel* model READ model NOTIFY modelChanged)
36+
37+public:
38+ SharedUnityMenuModel(QObject* parent = nullptr);
39+
40+ QByteArray busName() const;
41+ void setBusName(const QByteArray&);
42+
43+ QByteArray menuObjectPath() const;
44+ void setMenuObjectPath(const QByteArray&);
45+
46+ QVariantMap actions() const;
47+ void setActions(const QVariantMap&);
48+
49+ UnityMenuModel* model() const;
50+
51+Q_SIGNALS:
52+ void busNameChanged();
53+ void menuObjectPathChanged();
54+ void actionsChanged();
55+ void modelChanged();
56+
57+private:
58+ void initialize();
59+
60+ QByteArray m_busName;
61+ QByteArray m_menuObjectPath;
62+ QVariantMap m_actions;
63+ QSharedPointer<UnityMenuModel> m_model;
64+};
65+
66+#endif // SHAREDUNITYMENUMODEL_H
plugins/Unity/Indicators/unitymenumodelcache.cpp+27−12
@@ -20,30 +20,45 @@
2020#include "unitymenumodelcache.h"
2121#include <unitymenumodel.h>
2222
23−UnityMenuModelCache::UnityMenuModelCache(QObject* parent)
24− : QObject(parent)
23+#include <QQmlEngine>
24+
25+UnityMenuModelCache* UnityMenuModelCache::theCache = nullptr;
26+
27+
28+UnityMenuModelCache* UnityMenuModelCache::singleton()
2529{
30+ if (!theCache) {
31+ theCache = new UnityMenuModelCache();
32+ }
33+ return theCache;
2634}
2735
28−UnityMenuModelCache::~UnityMenuModelCache()
36+UnityMenuModelCache::UnityMenuModelCache(QObject* parent)
37+ : QObject(parent)
2938{
3039}
3140
32−UnityMenuModel* UnityMenuModelCache::model(const QByteArray& bus,
33− const QByteArray& path,
34− const QVariantMap& actions)
41+QSharedPointer<UnityMenuModel> UnityMenuModelCache::model(const QByteArray& bus,
42+ const QByteArray& path,
43+ const QVariantMap& actions)
3544{
3645 if (m_registry.contains(path))
3746 return m_registry[path];
3847
39− UnityMenuModel* menuModel = new UnityMenuModel;
40− connect(menuModel, &QObject::destroyed, this, [menuModel, this](QObject*) {
41− QList<QByteArray> keys = m_registry.keys(menuModel);
42− Q_FOREACH(const QByteArray& key, keys) {
43− m_registry.remove(key);
48+ UnityMenuModel* model = new UnityMenuModel;
49+ QQmlEngine::setObjectOwnership(model, QQmlEngine::CppOwnership);
50+
51+ QSharedPointer<UnityMenuModel> menuModel(model);
52+ connect(model, &QObject::destroyed, this, [this] {
53+ QMutableHashIterator<QByteArray, QWeakPointer<UnityMenuModel>> iter(m_registry);
54+ while(iter.hasNext()) {
55+ auto keyVal = iter.next();
56+ if (keyVal.value().toStrongRef().isNull()) {
57+ iter.remove();
58+ }
4459 }
4560 });
46− m_registry[path] = menuModel;
61+ m_registry[path] = menuModel.toWeakRef();
4762
4863 menuModel->setBusName(bus);
4964 menuModel->setMenuObjectPath(path);
plugins/Unity/Indicators/unitymenumodelcache.h+11−6
@@ -24,6 +24,7 @@
2424
2525#include <QObject>
2626#include <QHash>
27+#include <QWeakPointer>
2728
2829class UnityMenuModel;
2930
@@ -32,15 +33,19 @@ class UNITYINDICATORS_EXPORT UnityMenuModelCache : public QObject
3233 Q_OBJECT
3334public:
3435 UnityMenuModelCache(QObject*parent=nullptr);
35− ~UnityMenuModelCache();
3636
37− Q_INVOKABLE UnityMenuModel* model(const QByteArray& bus,
38− const QByteArray& path,
39− const QVariantMap& actions);
37+ static UnityMenuModelCache* singleton();
38+
39+ QSharedPointer<UnityMenuModel> model(const QByteArray& bus,
40+ const QByteArray& path,
41+ const QVariantMap& actions);
42+
43+ // for tests use
4044 Q_INVOKABLE bool contains(const QByteArray& path);
4145
42−private:
43− QHash<QByteArray, UnityMenuModel*> m_registry;
46+protected:
47+ QHash<QByteArray, QWeakPointer<UnityMenuModel>> m_registry;
48+ static UnityMenuModelCache* theCache;
4449};
4550
4651#endif // UNITYMENUMODELCACHE_H
qml/Greeter/Clock.qml+9−9
@@ -34,21 +34,21 @@ Item {
3434 }
3535 }
3636
37− CachedUnityMenuModel {
37+ Indicators.SharedUnityMenuModel {
3838 id: timeModel
3939 objectName: "timeModel"
4040
4141 busName: "com.canonical.indicator.datetime"
42− actionsObjectPath: "/com/canonical/indicator/datetime"
42+ actions: { "indicator": "/com/canonical/indicator/datetime" }
4343 menuObjectPath: clock.visible ? "/com/canonical/indicator/datetime/phone" : ""
44+ }
4445
45− Indicators.RootActionState {
46− menu: timeModel.model
47− onUpdated: {
48− if (timeLabel.text != rightLabel) {
49− timeLabel.text = rightLabel;
50− clock.currentDate = new Date();
51− }
46+ Indicators.RootActionState {
47+ menu: timeModel.model
48+ onUpdated: {
49+ if (timeLabel.text != rightLabel) {
50+ timeLabel.text = rightLabel;
51+ clock.currentDate = new Date();
5252 }
5353 }
5454 }
qml/Panel/Indicators/CachedUnityMenuModel.qmldeleted−39
@@ -1,39 +0,0 @@
1−/*
2− * Copyright 2013 Canonical Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU Lesser General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU Lesser General Public License for more details.
12− *
13− * You should have received a copy of the GNU Lesser General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− *
16− * Authors:
17− * Nick Dedekind <nick.dedekind@canonical.com>
18− */
19−
20−import QtQuick 2.0
21−import QMenuModel 0.1
22−import Unity.Indicators 0.1 as Indicators
23−
24−// Make sure we don't duplicate models.
25−Item {
26− id: cachedModel
27− property string busName
28− property string actionsObjectPath
29− property string menuObjectPath
30− readonly property bool ready: busName!=="" && actionsObjectPath!=="" && menuObjectPath!==""
31−
32− property var model: {
33− if (!ready) return null;
34−
35− return Indicators.UnityMenuModelCache.model(cachedModel.busName,
36− cachedModel.menuObjectPath,
37− { "indicator": cachedModel.actionsObjectPath });
38− }
39−}
qml/Panel/Indicators/IndicatorBase.qml+2−2
@@ -36,10 +36,10 @@ Item {
3636 property alias menuModel: cachedModel.model
3737 property alias rootActionState: rootAction
3838
39− CachedUnityMenuModel {
39+ SharedUnityMenuModel {
4040 id: cachedModel
4141 busName: indicatorItem.busName
42− actionsObjectPath: indicatorItem.actionsObjectPath
42+ actions: { "indicator": indicatorItem.actionsObjectPath }
4343 menuObjectPath: indicatorItem.deviceMenuObjectPath
4444 }
4545
tests/mocks/Unity/Indicators/CMakeLists.txt+1
@@ -16,6 +16,7 @@ set(IndicatorsFakeQml_SOURCES
1616 fakeunitymenumodelcache.cpp
1717 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/indicators.h
1818 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/menucontentactivator.cpp
19+ ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/sharedunitymenumodel.cpp
1920 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/unitymenumodelcache.cpp
2021 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/unitymenumodelstack.cpp
2122 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/visibleindicatorsmodel.cpp
tests/mocks/Unity/Indicators/fakeplugin.cpp+6−1
@@ -26,14 +26,17 @@
2626#include "fakeindicatorsmodel.h"
2727#include "indicators.h"
2828#include "menucontentactivator.h"
29+#include "sharedunitymenumodel.h"
2930#include "fakeunitymenumodelcache.h"
3031#include "unitymenumodelstack.h"
3132#include "visibleindicatorsmodel.h"
3233
34+#include <unitymenumodel.h>
35+
3336static QObject* menuModelCacheSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) {
3437 Q_UNUSED(engine);
3538 Q_UNUSED(scriptEngine);
36− return new FakeUnityMenuModelCache;
39+ return FakeUnityMenuModelCache::singleton();
3740}
3841
3942void IndicatorsFakePlugin::registerTypes(const char * uri)
@@ -42,11 +45,13 @@ void IndicatorsFakePlugin::registerTypes(const char * uri)
4245
4346 // internal
4447 qmlRegisterType<FakeIndicatorsModel>(uri, 0, 1, "FakeIndicatorsModel");
48+ qRegisterMetaType<UnityMenuModel*>("UnityMenuModel*");
4549
4650 // external
4751 qmlRegisterType<MenuContentActivator>(uri, 0, 1, "MenuContentActivator");
4852 qmlRegisterType<UnityMenuModelStack>(uri, 0, 1, "UnityMenuModelStack");
4953 qmlRegisterType<VisibleIndicatorsModel>(uri, 0, 1, "VisibleIndicatorsModel");
54+ qmlRegisterType<SharedUnityMenuModel>(uri, 0, 1, "SharedUnityMenuModel");
5055
5156 qmlRegisterSingletonType<FakeUnityMenuModelCache>(uri, 0, 1, "UnityMenuModelCache", menuModelCacheSingleton);
5257
tests/mocks/Unity/Indicators/fakeunitymenumodelcache.cpp+13−2
@@ -21,6 +21,14 @@
2121#include <unitymenumodel.h>
2222#include <QDebug>
2323
24+UnityMenuModelCache* FakeUnityMenuModelCache::singleton()
25+{
26+ if (!theCache) {
27+ theCache = new UnityMenuModelCache();
28+ }
29+ return theCache;
30+}
31+
2432FakeUnityMenuModelCache::FakeUnityMenuModelCache(QObject* parent)
2533 : UnityMenuModelCache(parent)
2634{
@@ -31,6 +39,9 @@ void FakeUnityMenuModelCache::setCachedModelData(const QByteArray& bus,
3139 const QVariantMap& actions,
3240 const QVariantMap& properties)
3341{
34− UnityMenuModel* menuModel = model(bus, path, actions);
35− menuModel->setRootProperties(properties);
42+ // keep a ref forever!
43+ if (!m_models.contains(path)) {
44+ m_models[path] = model(bus, path, actions);
45+ }
46+ m_models[path]->setRootProperties(properties);
3647}
tests/mocks/Unity/Indicators/fakeunitymenumodelcache.h+7
@@ -22,16 +22,23 @@
2222
2323#include "unitymenumodelcache.h"
2424
25+#include <QHash>
26+
2527class FakeUnityMenuModelCache : public UnityMenuModelCache
2628{
2729 Q_OBJECT
2830public:
2931 FakeUnityMenuModelCache(QObject*parent=nullptr);
3032
33+ static UnityMenuModelCache* singleton();
34+
3135 Q_INVOKABLE void setCachedModelData(const QByteArray& bus,
3236 const QByteArray& path,
3337 const QVariantMap& actions,
3438 const QVariantMap& properties);
39+
40+private:
41+ QHash<QByteArray, QSharedPointer<UnityMenuModel>> m_models;
3542};
3643
3744#endif // FAKEUNITYMENUMODELCACHE_H
tests/plugins/Unity/Indicators/CMakeLists.txt+1
@@ -40,3 +40,4 @@ indicator_test(indicatorsmodeltest ADDITIONAL_LIBS IndicatorsQml)
4040indicator_test(menucontentactivatortest ADDITIONAL_CPPS ${INDICATORS_DIR}/menucontentactivator.cpp)
4141indicator_test(unitymenumodelstacktest ADDITIONAL_CPPS ${TEST_DIR}/mocks/QMenuModel/unitymenumodel.cpp ${INDICATORS_DIR}/unitymenumodelstack.cpp)
4242indicator_test(rootactionstatetest ADDITIONAL_LIBS IndicatorsQml)
43+indicator_test(sharedunitymenumodeltest ADDITIONAL_LIBS IndicatorsQml)
tests/plugins/Unity/Indicators/sharedunitymenumodeltest.cppnew file+92
@@ -0,0 +1,92 @@
1+/*
2+ * Copyright 2014 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ */
17+
18+#include "sharedunitymenumodel.h"
19+#include "unitymenumodelcache.h"
20+
21+#include <QtTest>
22+#include <unitymenumodel.h>
23+
24+class SharedUnityMenuModelTest : public QObject
25+{
26+ Q_OBJECT
27+
28+ SharedUnityMenuModel* createFullModel(const QByteArray& testId)
29+ {
30+ SharedUnityMenuModel* model = new SharedUnityMenuModel;
31+ model->setBusName("com.canonical." + testId);
32+ model->setMenuObjectPath("/com/canonical/" + testId);
33+ QVariantMap actions;
34+ actions["test"] = QString("/com/canonical/%1/actions").arg(QString(testId));
35+ model->setActions(actions);
36+
37+ return model;
38+ }
39+
40+private Q_SLOTS:
41+
42+ void testCreateModel()
43+ {
44+ QSharedPointer<SharedUnityMenuModel> model(createFullModel("test1"));
45+ QVERIFY(model->model() != nullptr);
46+ }
47+
48+ void testDifferentDataCreatesDifferentModels()
49+ {
50+ QSharedPointer<SharedUnityMenuModel> model1(createFullModel("test1"));
51+ QSharedPointer<SharedUnityMenuModel> model2(createFullModel("test2"));
52+
53+ QVERIFY(model1->model() != model2->model());
54+ }
55+
56+ void testSameDataCreatesSameModels()
57+ {
58+ QSharedPointer<SharedUnityMenuModel> model1(createFullModel("test1"));
59+ QSharedPointer<SharedUnityMenuModel> model2(createFullModel("test1"));
60+
61+ QCOMPARE(model1->model(), model2->model());
62+ }
63+
64+ void testSharedOwnership()
65+ {
66+ QSharedPointer<SharedUnityMenuModel> model1(createFullModel("test1"));
67+ QSharedPointer<SharedUnityMenuModel> model2(createFullModel("test1"));
68+
69+ QCOMPARE(UnityMenuModelCache::singleton()->contains("/com/canonical/test1"), true);
70+ model1.clear();
71+ QCOMPARE(UnityMenuModelCache::singleton()->contains("/com/canonical/test1"), true);
72+ model2.clear();
73+ QCOMPARE(UnityMenuModelCache::singleton()->contains("/com/canonical/test1"), false);
74+ }
75+
76+ // Tests that changing cached model data does not change the model path of others
77+ void testLP1328646()
78+ {
79+ QSharedPointer<SharedUnityMenuModel> model1(createFullModel("test1"));
80+ QSharedPointer<SharedUnityMenuModel> model2(createFullModel("test1"));
81+
82+ model2->setMenuObjectPath("/com/canonical/LP1328646");
83+
84+ QVERIFY(model1->model() != model2->model());
85+ QCOMPARE(model1->model()->menuObjectPath(), QByteArray("/com/canonical/test1"));
86+ QCOMPARE(model2->model()->menuObjectPath(), QByteArray("/com/canonical/LP1328646"));
87+ }
88+
89+};
90+
91+QTEST_GUILESS_MAIN(SharedUnityMenuModelTest)
92+#include "sharedunitymenumodeltest.moc"
tests/qmltests/CMakeLists.txt−1
@@ -81,7 +81,6 @@ add_qml_test(Panel/New NewIndicatorsRow ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BIN
8181add_qml_test(Panel/New NewIndicatorsBar ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
8282add_qml_test(Panel/Indicators DefaultIndicatorWidget ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
8383add_qml_test(Panel/Indicators DefaultIndicatorPage ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
84−add_qml_test(Panel/Indicators CachedUnityMenuModel ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
8584# These MenuItemFactory tests need the test/mocks/ to come before plugins/
8685add_qml_test(Panel/Indicators MenuItemFactory IMPORT_PATHS ${CMAKE_BINARY_DIR}/tests/mocks ${qmltest_DEFAULT_IMPORT_PATHS})
8786add_qml_test(Panel/Indicators MessageMenuItemFactory IMPORT_PATHS ${CMAKE_BINARY_DIR}/tests/mocks ${qmltest_DEFAULT_IMPORT_PATHS})
tests/qmltests/Panel/Indicators/tst_CachedUnityMenuModel.qmldeleted−137
@@ -1,137 +0,0 @@
1−/*
2− * Copyright 2014 Canonical Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import QtTest 1.0
19−import Unity.Test 0.1 as UT
20−import QMenuModel 0.1
21−import Unity.Indicators 0.1 as Indicators
22−import "../../../../qml/Panel/Indicators"
23−
24−Item {
25− id: root
26− width: units.gu(40)
27− height: units.gu(70)
28−
29− Component {
30− id: model
31− CachedUnityMenuModel {}
32− }
33−
34− UT.UnityTestCase {
35− name: "CachedUnityMenuModel"
36− when: windowShown
37−
38− function cleanup() {
39− doGC();
40− }
41−
42− function doGC() {
43− // need to put some wait cycles here to get gc going properly.
44− wait(10);
45− gc();
46− wait(10);
47− }
48−
49− function test_createDifferent() {
50− var cachedObject = model.createObject(null,
51− {
52− "busName": "com.canonical.test1",
53− "menuObjectPath": "/com/canonical/test1",
54− "actionsObjectPath": "/com/canonical/test1"
55− });
56−
57− var cachedObject2 = model.createObject(null,
58− {
59− "busName": "com.canonical.test2",
60− "menuObjectPath": "/com/canonical/test2",
61− "actionsObjectPath": "/com/canonical/test2"
62− });
63−
64− verify(cachedObject.model !== cachedObject2.model);
65− }
66−
67− function test_createSame() {
68− var cachedObject = model.createObject(null,
69− {
70− "busName": "com.canonical.test3",
71− "menuObjectPath": "/com/canonical/test3",
72− "actionsObjectPath": "/com/canonical/test3"
73− });
74−
75− var cachedObject2 = model.createObject(null,
76− {
77− "busName": "com.canonical.test3",
78− "menuObjectPath": "/com/canonical/test3",
79− "actionsObjectPath": "/com/canonical/test3"
80− });
81−
82− verify(cachedObject.model === cachedObject2.model);
83− }
84−
85− // Tests that changing cached model data does not change the model path of others
86− function test_lp1328646() {
87− var cachedObject = model.createObject(null,
88− {
89− "busName": "com.canonical.test4",
90− "menuObjectPath": "/com/canonical/test4",
91− "actionsObjectPath": "/com/canonical/test4"
92− });
93−
94− var cachedObject2 = model.createObject(null,
95− {
96− "busName": "com.canonical.test4",
97− "menuObjectPath": "/com/canonical/test4",
98− "actionsObjectPath": "/com/canonical/test4"
99− });
100−
101− cachedObject.menuObjectPath = "/com/canonical/test5";
102− compare(cachedObject.model.menuObjectPath, "/com/canonical/test5");
103− compare(cachedObject2.model.menuObjectPath, "/com/canonical/test4");
104−
105− verify(cachedObject.model !== cachedObject2.model);
106− }
107−
108− function createAndDestroy(test) {
109− var cachedObject = model.createObject(null,
110− {
111− "busName": "com.canonical."+test,
112− "menuObjectPath": "/com/canonical/"+test,
113− "actionsObjectPath": "/com/canonical/"+test
114− });
115− var cachedObject2 = model.createObject(null,
116− {
117− "busName": "com.canonical."+test,
118− "menuObjectPath": "/com/canonical/"+test,
119− "actionsObjectPath": "/com/canonical/"+test
120− });
121− cachedObject.destroy();
122− return cachedObject2;
123− }
124−
125− function test_destroyAllDeletesModel() {
126− createAndDestroy("test6");
127− doGC();
128− compare(Indicators.UnityMenuModelCache.contains("/com/canonical/test6"), false);
129− }
130−
131− function test_destroyPartialKeepsModel() {
132− var model = createAndDestroy("test7");
133− doGC();
134− compare(Indicators.UnityMenuModelCache.contains("/com/canonical/test7"), true);
135− }
136− }
137−}