on xenial help sign in
Added tests for page, MenuItemFactory & MessageMenuItemFactory
739f810Nick Dedekind
Panel/Indicators/DefaultIndicatorPage.qml+39−40
@@ -59,10 +59,17 @@ Indicators.IndicatorBase {
59 menuStack.push(menuStack.rootMenu, 0);
59 menuStack.push(menuStack.rootMenu, 0);
60 }
60 }
61 }
61 }
62+ onModelReset: {
63+ if (menuStack.rootMenu !== menuStack.tail && menuStack.tail.get(0, "type") === rootMenuType) {
64+ menuStack.rootMenu = menuStack.tail.submenu(0);
65+ menuStack.push(menuStack.rootMenu, 0);
66+ }
67+ }
62 }
68 }
63
69
64 ListView {
70 ListView {
65 id: mainMenu
71 id: mainMenu
72+ objectName: "mainMenu"
66 model: menuStack.rootMenu
73 model: menuStack.rootMenu
67
74
68 anchors {
75 anchors {
@@ -115,57 +122,48 @@ Indicators.IndicatorBase {
115 }
122 }
116 }
123 }
117
124
118− delegate: Item {
125+ delegate: Loader {
119− id: menuDelegate
126+ id: loader
127+ objectName: "menuItem" + index
128+ asynchronous: false
129+ visible: height > 0
130+
131+ property int modelIndex: index
120
132
121 anchors {
133 anchors {
122 left: parent.left
134 left: parent.left
123 right: parent.right
135 right: parent.right
124 }
136 }
125− height: loader.height
126− visible: height > 0
127−
128− Loader {
129− id: loader
130− asynchronous: false
131
137
132− property int modelIndex: index
138+ sourceComponent: factory.load(model)
133
139
134− anchors {
140+ onLoaded: {
135− left: parent.left
141+ if (item.hasOwnProperty("menuSelected")) {
136− right: parent.right
142+ item.menuSelected = mainMenu.selectedIndex == index;
143+ item.selectMenu.connect(function() { mainMenu.selectedIndex = index; });
144+ item.deselectMenu.connect(function() { mainMenu.selectedIndex = -1; });
137 }
145 }
138−
139− sourceComponent: factory.load(model)
140−
141− onLoaded: {
142− if (item.hasOwnProperty("menuSelected")) {
146+ if (item.hasOwnProperty("menuData")) {
143− item.menuSelected = mainMenu.selectedIndex == index;
144− item.selectMenu.connect(function() { mainMenu.selectedIndex = index; });
145− item.deselectMenu.connect(function() { mainMenu.selectedIndex = -1; });
146− }
147− if (item.hasOwnProperty("menuData")) {
148− item.menuData = Qt.binding(function() { return model; });
147+ item.menuData = Qt.binding(function() { return model; });
149− }
150− if (item.hasOwnProperty("menuIndex")) {
151− item.menuIndex = Qt.binding(function() { return modelIndex; });
152− }
153 }
148 }
154−
149+ if (item.hasOwnProperty("menuIndex")) {
155− Binding {
150+ item.menuIndex = Qt.binding(function() { return modelIndex; });
156− target: item ? item : null
157− property: "objectName"
158− value: model.action
159 }
151 }
152+ }
153+
154+ Binding {
155+ target: item ? item : null
156+ property: "objectName"
157+ value: model.action
158+ }
160
159
161− // TODO: Fixes lp#1243146
160+ // TODO: Fixes lp#1243146
162− // This is a workaround for a Qt bug. https://bugreports.qt-project.org/browse/QTBUG-34351
161+ // This is a workaround for a Qt bug. https://bugreports.qt-project.org/browse/QTBUG-34351
163− Connections {
162+ Connections {
164− target: mainMenu
163+ target: mainMenu
165− onSelectedIndexChanged: {
164+ onSelectedIndexChanged: {
166− if (loader.item && loader.item.hasOwnProperty("menuSelected")) {
165+ if (loader.item && loader.item.hasOwnProperty("menuSelected")) {
167− loader.item.menuSelected = mainMenu.selectedIndex == index;
166+ loader.item.menuSelected = mainMenu.selectedIndex == index;
168− }
169 }
167 }
170 }
168 }
171 }
169 }
@@ -179,6 +177,7 @@ Indicators.IndicatorBase {
179
177
180 Components.Label {
178 Components.Label {
181 id: emptyLabel
179 id: emptyLabel
180+ objectName: "emptyLabel"
182 visible: mainMenu.count == 0
181 visible: mainMenu.count == 0
183 anchors {
182 anchors {
184 top: parent.top
183 top: parent.top
plugins/Unity/Indicators/Messaging/qml/MessageMenuItemFactory.qml+9−1
@@ -60,6 +60,7 @@ Indicators.BaseMenuItem {
60
60
61 Loader {
61 Loader {
62 id: contents
62 id: contents
63+ objectName: "loader"
63 anchors.fill: parent
64 anchors.fill: parent
64
65
65 sourceComponent: loadMessage(actionsDescription);
66 sourceComponent: loadMessage(actionsDescription);
@@ -67,6 +68,7 @@ Indicators.BaseMenuItem {
67 Component {
68 Component {
68 id: simpleTextMessage
69 id: simpleTextMessage
69 SimpleTextMessage {
70 SimpleTextMessage {
71+ objectName: "simpleTextMessage"
70 // text
72 // text
71 title: menuData && menuData.label || ""
73 title: menuData && menuData.label || ""
72 time: getExtendedProperty(extendedData, "xCanonicalTime", 0)
74 time: getExtendedProperty(extendedData, "xCanonicalTime", 0)
@@ -74,6 +76,8 @@ Indicators.BaseMenuItem {
74 // icons
76 // icons
75 avatar: getExtendedProperty(extendedData, "icon", "qrc:/indicators/artwork/messaging/default_contact.png")
77 avatar: getExtendedProperty(extendedData, "icon", "qrc:/indicators/artwork/messaging/default_contact.png")
76 appIcon: getExtendedProperty(extendedData, "xCanonicalAppIcon", "qrc:/indicators/artwork/messaging/default_app.svg")
78 appIcon: getExtendedProperty(extendedData, "xCanonicalAppIcon", "qrc:/indicators/artwork/messaging/default_app.svg")
79+ // actions
80+ enabled: menuData && menuData.sensitive || false
77
81
78 onActivateApp: {
82 onActivateApp: {
79 menuModel.activate(menuIndex, true);
83 menuModel.activate(menuIndex, true);
@@ -91,6 +95,7 @@ Indicators.BaseMenuItem {
91 Component {
95 Component {
92 id: textMessage
96 id: textMessage
93 TextMessage {
97 TextMessage {
98+ objectName: "textMessage"
94 property var replyActionDescription: actionsDescription && actionsDescription.length > 0 ? actionsDescription[0] : undefined
99 property var replyActionDescription: actionsDescription && actionsDescription.length > 0 ? actionsDescription[0] : undefined
95
100
96 property var replyAction: QMenuModel.UnityMenuAction {
101 property var replyAction: QMenuModel.UnityMenuAction {
@@ -109,6 +114,7 @@ Indicators.BaseMenuItem {
109 appIcon: getExtendedProperty(extendedData, "xCanonicalAppIcon", "qrc:/indicators/artwork/messaging/default_app.svg")
114 appIcon: getExtendedProperty(extendedData, "xCanonicalAppIcon", "qrc:/indicators/artwork/messaging/default_app.svg")
110 // actions
115 // actions
111 replyEnabled: replyAction.valid && replyAction.enabled
116 replyEnabled: replyAction.valid && replyAction.enabled
117+ enabled: menuData && menuData.sensitive || false
112
118
113 onActivateApp: {
119 onActivateApp: {
114 menuModel.activate(menuIndex, true);
120 menuModel.activate(menuIndex, true);
@@ -129,6 +135,7 @@ Indicators.BaseMenuItem {
129 Component {
135 Component {
130 id: snapDecision
136 id: snapDecision
131 SnapDecision {
137 SnapDecision {
138+ objectName: "snapDecision"
132 property var activateActionDescription: actionsDescription && actionsDescription.length > 0 ? actionsDescription[0] : undefined
139 property var activateActionDescription: actionsDescription && actionsDescription.length > 0 ? actionsDescription[0] : undefined
133 property var replyActionDescription: actionsDescription && actionsDescription.length > 1 ? actionsDescription[1] : undefined
140 property var replyActionDescription: actionsDescription && actionsDescription.length > 1 ? actionsDescription[1] : undefined
134
141
@@ -155,7 +162,8 @@ Indicators.BaseMenuItem {
155 appIcon: getExtendedProperty(extendedData, "xCanonicalAppIcon", "qrc:/indicators/artwork/messaging/default_app.svg")
162 appIcon: getExtendedProperty(extendedData, "xCanonicalAppIcon", "qrc:/indicators/artwork/messaging/default_app.svg")
156 // actions
163 // actions
157 activateEnabled: activateAction.valid && activateAction.enabled
164 activateEnabled: activateAction.valid && activateAction.enabled
158− replyEnabled: replyAction.valid && replyAction.enabled
165+ replyEnabled: replyAction.valid && replyAction.enabled
166+ enabled: menuData && menuData.sensitive || false
159
167
160 onActivateApp: {
168 onActivateApp: {
161 menuModel.activate(menuIndex, true);
169 menuModel.activate(menuIndex, true);
plugins/Unity/Indicators/Network/qml/AccessPoint.qml+2−2
@@ -30,7 +30,7 @@ Indicators.BaseMenuItem {
30 property bool secure: false
30 property bool secure: false
31 property bool adHoc: false
31 property bool adHoc: false
32 property int signalStrength: 0
32 property int signalStrength: 0
33− property alias text: label.text
33+ property alias label: _label.text
34
34
35 signal activate()
35 signal activate()
36
36
@@ -89,7 +89,7 @@ Indicators.BaseMenuItem {
89 }
89 }
90
90
91 Label {
91 Label {
92− id: label
92+ id: _label
93 anchors {
93 anchors {
94 left: iconSignal.right
94 left: iconSignal.right
95 leftMargin: units.gu(1)
95 leftMargin: units.gu(1)
plugins/Unity/Indicators/qml/ButtonMenuItem.qml+1−1
@@ -26,7 +26,7 @@ BaseMenuItem {
26 id: menuItem
26 id: menuItem
27 implicitHeight: units.gu(7)
27 implicitHeight: units.gu(7)
28
28
29− property alias text: button.text
29+ property alias buttonText: button.text
30
30
31 signal activate()
31 signal activate()
32
32
plugins/Unity/Indicators/qml/MenuItemFactory.qml+18−3
@@ -57,11 +57,17 @@ Item {
57 return defaultValue;
57 return defaultValue;
58 }
58 }
59
59
60+ Component {
61+ id: divMenu;
60− Component { id: divMenu; Indicators.DivMenuItem {} }
62+ Indicators.DivMenuItem {
63+ objectName: "divMenu"
64+ }
65+ }
61
66
62 Component {
67 Component {
63 id: sliderMenu;
68 id: sliderMenu;
64 Indicators.SliderMenuItem {
69 Indicators.SliderMenuItem {
70+ objectName: "sliderMenu"
65 property QtObject menuData: null
71 property QtObject menuData: null
66 property var menuModel: menuFactory.menuModel
72 property var menuModel: menuFactory.menuModel
67 property int menuIndex: -1
73 property int menuIndex: -1
@@ -106,11 +112,12 @@ Item {
106 Component {
112 Component {
107 id: buttonMenu;
113 id: buttonMenu;
108 Indicators.ButtonMenuItem {
114 Indicators.ButtonMenuItem {
115+ objectName: "buttonMenu"
109 property QtObject menuData: null
116 property QtObject menuData: null
110 property var menuModel: menuFactory.menuModel
117 property var menuModel: menuFactory.menuModel
111 property int menuIndex: -1
118 property int menuIndex: -1
112
119
113− text: menuData && menuData.label || ""
120+ buttonText: menuData && menuData.label || ""
114 enabled: menuData && menuData.sensitive || false
121 enabled: menuData && menuData.sensitive || false
115
122
116 onActivate: {
123 onActivate: {
@@ -122,6 +129,7 @@ Item {
122 Component {
129 Component {
123 id: sectionMenu;
130 id: sectionMenu;
124 Indicators.SectionMenuItem {
131 Indicators.SectionMenuItem {
132+ objectName: "sectionMenu"
125 property QtObject menuData: null
133 property QtObject menuData: null
126 property var menuIndex: undefined
134 property var menuIndex: undefined
127
135
@@ -132,6 +140,7 @@ Item {
132 Component {
140 Component {
133 id: progressMenu;
141 id: progressMenu;
134 Indicators.ProgressMenuItem {
142 Indicators.ProgressMenuItem {
143+ objectName: "progressMenu"
135 property QtObject menuData: null
144 property QtObject menuData: null
136 property int menuIndex: -1
145 property int menuIndex: -1
137
146
@@ -145,6 +154,7 @@ Item {
145 Component {
154 Component {
146 id: standardMenu;
155 id: standardMenu;
147 Indicators.StandardMenuItem {
156 Indicators.StandardMenuItem {
157+ objectName: "standardMenu"
148 property QtObject menuData: null
158 property QtObject menuData: null
149 property int menuIndex: -1
159 property int menuIndex: -1
150
160
@@ -164,6 +174,7 @@ Item {
164 Component {
174 Component {
165 id: switchMenu;
175 id: switchMenu;
166 Indicators.SwitchMenuItem {
176 Indicators.SwitchMenuItem {
177+ objectName: "switchMenu"
167 property QtObject menuData: null
178 property QtObject menuData: null
168 property int menuIndex: -1
179 property int menuIndex: -1
169
180
@@ -182,6 +193,7 @@ Item {
182 Component {
193 Component {
183 id: wifiSection;
194 id: wifiSection;
184 Indicators.SectionMenuItem {
195 Indicators.SectionMenuItem {
196+ objectName: "wifiSection"
185 property QtObject menuData: null
197 property QtObject menuData: null
186 property var menuModel: menuFactory.menuModel
198 property var menuModel: menuFactory.menuModel
187 property int menuIndex: -1
199 property int menuIndex: -1
@@ -207,6 +219,7 @@ Item {
207 Component {
219 Component {
208 id: accessPoint;
220 id: accessPoint;
209 ICNetwork.AccessPoint {
221 ICNetwork.AccessPoint {
222+ objectName: "accessPoint"
210 property QtObject menuData: null
223 property QtObject menuData: null
211 property var menuModel: menuFactory.menuModel
224 property var menuModel: menuFactory.menuModel
212 property int menuIndex: -1
225 property int menuIndex: -1
@@ -218,7 +231,7 @@ Item {
218 name: getExtendedProperty(extendedData, "xCanonicalWifiApStrengthAction", "")
231 name: getExtendedProperty(extendedData, "xCanonicalWifiApStrengthAction", "")
219 }
232 }
220
233
221− text: menuData && menuData.label || ""
234+ label: menuData && menuData.label || ""
222 enabled: menuData && menuData.sensitive || false
235 enabled: menuData && menuData.sensitive || false
223 secure: getExtendedProperty(extendedData, "xCanonicalWifiApIsSecure", false)
236 secure: getExtendedProperty(extendedData, "xCanonicalWifiApIsSecure", false)
224 adHoc: getExtendedProperty(extendedData, "xCanonicalWifiApIsAdhoc", false)
237 adHoc: getExtendedProperty(extendedData, "xCanonicalWifiApIsAdhoc", false)
@@ -248,6 +261,7 @@ Item {
248 Component {
261 Component {
249 id: messageItem
262 id: messageItem
250 ICMessaging.MessageMenuItemFactory {
263 ICMessaging.MessageMenuItemFactory {
264+ objectName: "messageItem"
251 menuModel: menuFactory.menuModel
265 menuModel: menuFactory.menuModel
252 }
266 }
253 }
267 }
@@ -255,6 +269,7 @@ Item {
255 Component {
269 Component {
256 id: groupedMessage
270 id: groupedMessage
257 ICMessaging.GroupedMessage {
271 ICMessaging.GroupedMessage {
272+ objectName: "groupedMessage"
258 property QtObject menuData: null
273 property QtObject menuData: null
259 property var menuModel: menuFactory.menuModel
274 property var menuModel: menuFactory.menuModel
260 property int menuIndex: -1
275 property int menuIndex: -1
tests/mocks/QMenuModel/unitymenumodel.cpp+3
@@ -143,6 +143,9 @@ QVariant UnityMenuModel::data(const QModelIndex &index, int role) const
143
143
144QVariantMap UnityMenuModel::rowData(int row) const
144QVariantMap UnityMenuModel::rowData(int row) const
145{
145{
146+ if (m_modelData.count() <= row) {
147+ return QVariantMap();
148+ }
146 return m_modelData[row].toMap()["rowData"].toMap();
149 return m_modelData[row].toMap()["rowData"].toMap();
147}
150}
148
151
tests/mocks/Unity/Indicators/CMakeLists.txt+2
@@ -7,12 +7,14 @@ include_directories(
7 ${CMAKE_CURRENT_SOURCE_DIR}
7 ${CMAKE_CURRENT_SOURCE_DIR}
8 ${CMAKE_CURRENT_BINARY_DIR}
8 ${CMAKE_CURRENT_BINARY_DIR}
9 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators
9 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators
10+ ${CMAKE_SOURCE_DIR}/tests/mocks/QMenuModel
10)
11)
11
12
12set(IndicatorsFakeQml_SOURCES
13set(IndicatorsFakeQml_SOURCES
13 fakeplugin.cpp
14 fakeplugin.cpp
14 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/indicators.h
15 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/indicators.h
15 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/menucontentactivator.cpp
16 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/menucontentactivator.cpp
17+ ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/unitymenumodelstack.cpp
16 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/visibleindicatorsmodel.cpp
18 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/visibleindicatorsmodel.cpp
17)
19)
18
20
tests/mocks/Unity/Indicators/IndicatorWidget.qmldeleted−28
@@ -1,28 +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 Unity.Indicators 0.1 as Indicators
22−
23−IndicatorBase {
24− id: indicatorWidget
25−
26− enabled: false
27− property int iconSize: height
28−}
tests/mocks/Unity/Indicators/fakeplugin.cpp+2
@@ -25,6 +25,7 @@
25// local
25// local
26#include "indicators.h"
26#include "indicators.h"
27#include "menucontentactivator.h"
27#include "menucontentactivator.h"
28+#include "unitymenumodelstack.h"
28#include "visibleindicatorsmodel.h"
29#include "visibleindicatorsmodel.h"
29
30
30void IndicatorsFakePlugin::registerTypes(const char * uri)
31void IndicatorsFakePlugin::registerTypes(const char * uri)
@@ -32,6 +33,7 @@ void IndicatorsFakePlugin::registerTypes(const char * uri)
32 Q_INIT_RESOURCE(indicators_fake);
33 Q_INIT_RESOURCE(indicators_fake);
33
34
34 qmlRegisterType<MenuContentActivator>(uri, 0, 1, "MenuContentActivator");
35 qmlRegisterType<MenuContentActivator>(uri, 0, 1, "MenuContentActivator");
36+ qmlRegisterType<UnityMenuModelStack>(uri, 0, 1, "UnityMenuModelStack");
35 qmlRegisterType<VisibleIndicatorsModel>(uri, 0, 1, "VisibleIndicatorsModel");
37 qmlRegisterType<VisibleIndicatorsModel>(uri, 0, 1, "VisibleIndicatorsModel");
36
38
37 qmlRegisterUncreatableType<MenuContentState>(uri, 0, 1, "MenuContentState", "Can't create MenuContentState class");
39 qmlRegisterUncreatableType<MenuContentState>(uri, 0, 1, "MenuContentState", "Can't create MenuContentState class");
tests/mocks/Unity/Indicators/qmldir−1
@@ -3,7 +3,6 @@ plugin IndicatorsFakeQml
3
3
4CachedUnityMenuModel 0.1 CachedUnityMenuModel.qml
4CachedUnityMenuModel 0.1 CachedUnityMenuModel.qml
5IndicatorBase 0.1 IndicatorBase.qml
5IndicatorBase 0.1 IndicatorBase.qml
6−IndicatorWidget 0.1 IndicatorWidget.qml
7IndicatorsModel 0.1 IndicatorsModel.qml
6IndicatorsModel 0.1 IndicatorsModel.qml
8FakeMenuPage 0.1 FakeMenuPage.qml
7FakeMenuPage 0.1 FakeMenuPage.qml
9RootActionState 0.1 RootActionState.qml
8RootActionState 0.1 RootActionState.qml
tests/qmltests/CMakeLists.txt+4
@@ -73,6 +73,10 @@ add_qml_test(Panel Panel IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFA
73add_qml_test(Panel SearchIndicator)
73add_qml_test(Panel SearchIndicator)
74add_qml_test(Panel/Indicators DefaultIndicatorWidget IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS}
74add_qml_test(Panel/Indicators DefaultIndicatorWidget IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS}
75 ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
75 ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
76+add_qml_test(Panel/Indicators DefaultIndicatorPage IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins
77+ ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
78+add_qml_test(Panel/Indicators MenuItemFactory IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins)
79+add_qml_test(Panel/Indicators MessageMenuItemFactory IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins)
76add_qml_test(SideStage SideStage IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS}
80add_qml_test(SideStage SideStage IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS}
77 ${CMAKE_BINARY_DIR}/tests/mocks
81 ${CMAKE_BINARY_DIR}/tests/mocks
78 ${CMAKE_BINARY_DIR}/plugins)
82 ${CMAKE_BINARY_DIR}/plugins)
tests/qmltests/Panel/Indicators/tst_DefaultIndicatorPage.qmlnew file+179
@@ -0,0 +1,179 @@
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 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 "../../../../Panel/Indicators"
22+
23+Item {
24+ id: testView
25+ width: units.gu(40)
26+ height: units.gu(70)
27+
28+ DefaultIndicatorPage {
29+ id: page
30+
31+ anchors.fill: parent
32+ contentActive: true
33+
34+ busName: "test"
35+ actionsObjectPath: "test"
36+ menuObjectPath: "test"
37+
38+ rootMenuType: ""
39+ }
40+
41+ property var fullMenuData: [{
42+ "rowData": { // 1
43+ "label": "root",
44+ "sensitive": true,
45+ "isSeparator": false,
46+ "icon": "",
47+ "type": "com.canonical.indicator.root",
48+ "ext": {},
49+ "action": "",
50+ "actionState": {},
51+ "isCheck": false,
52+ "isRadio": false,
53+ "isToggled": false,
54+ },
55+ "submenu": [{
56+ "rowData": { // 1.1
57+ "label": "menu1",
58+ "sensitive": true,
59+ "isSeparator": false,
60+ "icon": "",
61+ "type": "",
62+ "ext": {},
63+ "action": "",
64+ "actionState": {},
65+ "isCheck": false,
66+ "isRadio": false,
67+ "isToggled": false,
68+ }}, {
69+ "rowData": { // 1.2
70+ "label": "menu2",
71+ "sensitive": true,
72+ "isSeparator": false,
73+ "icon": "",
74+ "type": "",
75+ "ext": {},
76+ "action": "",
77+ "actionState": {},
78+ "isCheck": false,
79+ "isRadio": false,
80+ "isToggled": false,
81+ }}, {
82+ "rowData": { // row 1.2
83+ "label": "menu3",
84+ "sensitive": true,
85+ "isSeparator": false,
86+ "icon": "",
87+ "type": "",
88+ "ext": {},
89+ "action": "",
90+ "actionState": {},
91+ "isCheck": false,
92+ "isRadio": false,
93+ "isToggled": false,
94+ }}
95+ ]
96+ }]; // end row 1
97+
98+ property var emptySubMenuData: [{
99+ "rowData": { // 1
100+ "label": "root",
101+ "sensitive": true,
102+ "isSeparator": false,
103+ "icon": "",
104+ "type": "com.canonical.indicator.root",
105+ "ext": {},
106+ "action": "",
107+ "actionState": {},
108+ "isCheck": false,
109+ "isRadio": false,
110+ "isToggled": false,
111+ },
112+ "submenu": []
113+ }]; // end row 1
114+
115+ UT.UnityTestCase {
116+ name: "DefaultIndicatorPage"
117+
118+ function init() {
119+ page.stop();
120+ var mainMenu = findChild(page, "mainMenu");
121+ verify(mainMenu.model === undefined);
122+
123+ page.rootMenuType = "com.canonical.indicator.root";
124+ page.start();
125+
126+ verify(mainMenu.model !== null);
127+ }
128+
129+ function test_reloadData() {
130+ var mainMenu = findChild(page, "mainMenu");
131+
132+ console.log("setting empty data");
133+ page.menuModel.modelData = [];
134+ tryCompare(mainMenu, "count", 0);
135+ console.log("set empty data");
136+
137+ console.log("setting full data");
138+ page.menuModel.modelData = fullMenuData;
139+ console.log("set full data");
140+ tryCompare(mainMenu, "count", 3);
141+
142+ page.menuModel.modelData = [];
143+ tryCompare(mainMenu, "count", 0);
144+
145+ page.menuModel.modelData = fullMenuData;
146+ tryCompare(mainMenu, "count", 3);
147+ }
148+
149+ function test_traverse_rootMenuType_data() {
150+ return [
151+ { tag: "Incorrect", rootMenuType: "com.canonical.indicator", expectedCount: 0},
152+ { tag: "Correct", rootMenuType: "com.canonical.indicator.root", expectedCount: 3},
153+ ]
154+ }
155+
156+ function test_traverse_rootMenuType(data) {
157+ page.rootMenuType = data.rootMenuType;
158+ page.menuModel.modelData = fullMenuData;
159+
160+ var mainMenu = findChild(page, "mainMenu");
161+ tryCompare(mainMenu, "count", data.expectedCount);
162+ }
163+
164+ function test_empty_data() {
165+ return [
166+ { tag: "EmptyNoData", modelData: [], visible: true},
167+ { tag: "EmptySubmenu", modelData: emptySubMenuData, visible: true},
168+ { tag: "NotEmpty", modelData: fullMenuData, visible: false},
169+ ]
170+ }
171+
172+ function test_empty(data) {
173+ page.menuModel.modelData = data.modelData;
174+
175+ var emptyLabel = findChild(page, "emptyLabel");
176+ tryCompare(emptyLabel, "visible", data.visible);
177+ }
178+ }
179+}
tests/qmltests/Panel/Indicators/tst_MenuItemFactory.qmlnew file+523
@@ -0,0 +1,523 @@
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 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+
23+Item {
24+ id: testView
25+ width: units.gu(40)
26+ height: units.gu(70)
27+
28+ Indicators.MenuItemFactory {
29+ id: factory
30+ menuModel: UnityMenuModel {}
31+ }
32+
33+ Loader {
34+ id: loader
35+ property int modelIndex: 0
36+ property var data
37+
38+ onLoaded: {
39+ if (item.hasOwnProperty("menuData")) {
40+ item.menuData = data;
41+ }
42+ }
43+ }
44+
45+ UT.UnityTestCase {
46+ name: "IndicatorPage"
47+
48+ property QtObject menuData: QtObject {
49+ property string label: "root"
50+ property bool sensitive: true
51+ property bool isSeparator: false
52+ property string icon: ""
53+ property string type: ""
54+ property var ext: undefined
55+ property string action: ""
56+ property var actionState: undefined
57+ property bool isCheck: false
58+ property bool isRadio: false
59+ property bool isToggled: false
60+ }
61+
62+ function init() {
63+ menuData.label = "";
64+ menuData.sensitive = true;
65+ menuData.isSeparator = false;
66+ menuData.icon = "";
67+ menuData.type = "";
68+ menuData.ext = undefined;
69+ menuData.action = "";
70+ menuData.actionState = undefined;
71+ menuData.isCheck = false;
72+ menuData.isRadio = false;
73+ menuData.isToggled = false;
74+
75+ loader.sourceComponent = null;
76+ loader.data = undefined;
77+
78+ verify(loader.item == null);
79+ }
80+
81+ function test_createTypes_data() {
82+ return [
83+ { tag: 'volume', type: "unity.widgets.systemsettings.tablet.volumecontrol", objectName: "sliderMenu" },
84+ { tag: 'switch1', type: "unity.widgets.systemsettings.tablet.switch", objectName: "switchMenu" },
85+
86+ { tag: 'button', type: "com.canonical.indicator.button", objectName: "buttonMenu" },
87+ { tag: 'separator', type: "com.canonical.indicator.div", objectName: "divMenu" },
88+ { tag: 'section', type: "com.canonical.indicator.section", objectName: "sectionMenu" },
89+ { tag: 'progress', type: "com.canonical.indicator.progress", objectName: "progressMenu" },
90+ { tag: 'slider1', type: "com.canonical.indicator.slider", objectName: "sliderMenu" },
91+ { tag: 'switch2', type: "com.canonical.indicator.switch", objectName: "switchMenu" },
92+
93+ { tag: 'messageItem', type: "com.canonical.indicator.messages.messageitem", objectName: "messageItem" },
94+ { tag: 'sourceItem', type: "com.canonical.indicator.messages.sourceitem", objectName: "groupedMessage" },
95+
96+ { tag: 'slider2', type: "com.canonical.unity.slider", objectName: "sliderMenu" },
97+ { tag: 'switch3', type: "com.canonical.unity.switch", objectName: "switchMenu" },
98+
99+ { tag: 'mediaplayer', type: "com.canonical.unity.media-player", objectName: "standardMenu" },
100+ { tag: 'playbackitem', type: "com.canonical.unity.playback-item", objectName: "standardMenu" },
101+
102+ { tag: 'wifisection', type: "unity.widgets.systemsettings.tablet.wifisection", objectName: "wifiSection" },
103+ { tag: 'accesspoint', type: "unity.widgets.systemsettings.tablet.accesspoint", objectName: "accessPoint" },
104+
105+ { tag: 'unknown', type: "", objectName: "standardMenu"}
106+ ];
107+ }
108+
109+ function test_createTypes(data) {
110+ menuData.type = data.type;
111+
112+ loader.data = menuData;
113+ loader.sourceComponent = factory.load(menuData);
114+ tryCompareFunction(function() { return loader.item != undefined; }, true);
115+ compare(loader.item.objectName, data.objectName, "Created object name does not match intended object (" + loader.item.objectName + " != " + data.objectName + ")");
116+ }
117+
118+// function test_create_checkable() {
119+// var tmpData = menuData;
120+// tmpData.isCheck = true;
121+
122+// loader.data = tmpData;
123+// loader.sourceComponent = factory.load(tmpData);
124+// tryCompareFunction(function() { return loader.item != undefined; }, true);
125+// compare(loader.item.objectName, "checkableMenu", "Should have created a checkable menu");
126+// }
127+
128+ function test_create_radio() {
129+ skip("No radio component");
130+ menuData.isRadio = true;
131+
132+ loader.data = menuData;
133+ loader.sourceComponent = factory.load(menuData);
134+ tryCompareFunction(function() { return loader.item != undefined; }, true);
135+ compare(loader.item.objectName, "checkableMenu", "Should have created a checkable menu");
136+ }
137+
138+ function test_create_separator() {
139+ menuData.isSeparator = true;
140+
141+ loader.data = menuData;
142+ loader.sourceComponent = factory.load(menuData);
143+ tryCompareFunction(function() { return loader.item != undefined; }, true);
144+ compare(loader.item.objectName, "divMenu", "Should have created a separator menu");
145+ }
146+
147+ function test_create_sliderMenu_data() {
148+ return [
149+ {label: "testLabel1", enabled: false, minValue: 0, maxValue: 100, value: 10.5 },
150+ {label: "testLabel2", enabled: true, minValue: 0, maxValue: 100, value: 100 },
151+ ];
152+ }
153+
154+ function test_create_sliderMenu(data) {
155+ menuData.type = "com.canonical.indicator.slider"
156+ menuData.label = data.label;
157+ menuData.sensitive = data.enabled;
158+ menuData.actionState = data.value;
159+ menuData.ext = {
160+ 'minIcon': "file:///testMinIcon",
161+ 'maxIcon': "file:///testMaxIcon",
162+ 'minValue': data.minValue,
163+ 'maxValue': data.maxValue
164+ };
165+
166+ loader.data = menuData;
167+ loader.sourceComponent = factory.load(menuData);
168+ tryCompareFunction(function() { return loader.item != undefined; }, true);
169+ compare(loader.item.objectName, "sliderMenu", "Should have created a slider menu");
170+
171+ compare(loader.item.text, data.label, "Label does not match data");
172+ compare(loader.item.minIcon, "file:///testMinIcon", "MinIcon does not match data");
173+ compare(loader.item.maxIcon, "file:///testMaxIcon", "MaxIcon does not match data");
174+ compare(loader.item.minimumValue, data.minValue, "MinValue does not match data");
175+ compare(loader.item.maximumValue, data.maxValue, "MaxValue does not match data");
176+ compare(loader.item.value, data.value, "Calue does not match data");
177+ compare(loader.item.enabled, data.enabled, "Enabled does not match data");
178+ }
179+
180+ function test_create_buttonMenu_data() {
181+ return [
182+ {label: "testLabel1", enabled: false },
183+ {label: "testLabel2", enabled: true },
184+ ];
185+ }
186+
187+ function test_create_buttonMenu(data) {
188+ menuData.type = "com.canonical.indicator.button"
189+ menuData.label = data.label;
190+ menuData.sensitive = data.enabled;
191+
192+ loader.data = menuData;
193+ loader.sourceComponent = factory.load(menuData);
194+ tryCompareFunction(function() { return loader.item != undefined; }, true);
195+ compare(loader.item.objectName, "buttonMenu", "Should have created a button menu");
196+
197+ compare(loader.item.buttonText, data.label, "Label does not match data");
198+ compare(loader.item.enabled, data.enabled, "Enabled does not match data");
199+ }
200+
201+ function test_create_sectionMenu_data() {
202+ return [
203+ {label: "testLabel1" },
204+ {label: "testLabel2" },
205+ ];
206+ }
207+
208+ function test_create_sectionMenu(data) {
209+ menuData.type = "com.canonical.indicator.section"
210+ menuData.label = data.label;
211+
212+ loader.data = menuData;
213+ loader.sourceComponent = factory.load(menuData);
214+ tryCompareFunction(function() { return loader.item != undefined; }, true);
215+ compare(loader.item.objectName, "sectionMenu", "Should have created a section menu");
216+
217+ compare(loader.item.text, data.label, "Label does not match data");
218+ }
219+
220+ function test_create_progressMenu_data() {
221+ return [
222+ {label: "testLabel1", enabled: true, value: 10 },
223+ {label: "testLabel2", enabled: false, value: 55 },
224+ ];
225+ }
226+
227+ function test_create_progressMenu(data) {
228+ menuData.type = "com.canonical.indicator.progress"
229+ menuData.label = data.label;
230+ menuData.sensitive = data.enabled;
231+ menuData.actionState = data.value;
232+
233+ loader.data = menuData;
234+ loader.sourceComponent = factory.load(menuData);
235+ tryCompareFunction(function() { return loader.item != undefined; }, true);
236+ compare(loader.item.objectName, "progressMenu", "Should have created a progress menu");
237+
238+ compare(loader.item.text, data.label, "Label does not match data");
239+ compare(loader.item.value, data.value, "Value does not match data");
240+ compare(loader.item.enabled, data.enabled, "Enabled does not match data");
241+ }
242+
243+ function test_create_standardMenu_data() {
244+ return [
245+ {label: "testLabel1", enabled: true, icon: "file:///testIcon" },
246+ {label: "testLabel2", enabled: false, icon: "file:///testIcon2"},
247+ ];
248+ }
249+
250+ function test_create_standardMenu(data) {
251+ menuData.type = ""
252+ menuData.label = data.label;
253+ menuData.sensitive = data.enabled;
254+ menuData.icon = data.icon;
255+
256+ loader.data = menuData;
257+ loader.sourceComponent = factory.load(menuData);
258+ tryCompareFunction(function() { return loader.item != undefined; }, true);
259+ compare(loader.item.objectName, "standardMenu", "Should have created a standard menu");
260+
261+ compare(loader.item.text, data.label, "Label does not match data");
262+ compare(loader.item.iconSource, data.icon, "MaxIcon does not match data");
263+ compare(loader.item.enabled, data.enabled, "Enabled does not match data");
264+ }
265+
266+// function test_create_checkableMenu_data() {
267+// return [
268+// {label: "testLabel1", enabled: true, checked: false },
269+// {label: "testLabel2", enabled: false, checked: true },
270+// ];
271+// }
272+
273+// function test_create_checkableMenu(data) {
274+// var menuData = {
275+// 'label': data.label,
276+// 'sensitive': data.enabled,
277+// 'isSeparator': false,
278+// 'icon': "",
279+// 'type': undefined,
280+// 'ext': {},
281+// 'action': "",
282+// 'actionState': undefined,
283+// 'isCheck': true,
284+// 'isRadio': false,
285+// 'isToggled': data.checked,
286+// };
287+
288+// loader.data = menuData;
289+// loader.sourceComponent = factory.load(menuData);
290+// tryCompareFunction(function() { return loader.item != undefined; }, true);
291+// compare(loader.item.objectName, "checkableMenu", "Should have created a standard menu");
292+
293+// compare(loader.item.text, data.label, "Label does not match data");
294+// compare(loader.item.checked, data.checked, "Checked does not match data");
295+// compare(loader.item.enabled, data.enabled, "Enabled does not match data");
296+// }
297+
298+ function test_create_switchMenu_data() {
299+ return [
300+ {label: "testLabel1", enabled: true, checked: false },
301+ {label: "testLabel2", enabled: false, checked: true },
302+ ];
303+ }
304+
305+ function test_create_switchMenu(data) {
306+ menuData.type = "com.canonical.indicator.switch";
307+ menuData.label = data.label;
308+ menuData.sensitive = data.enabled;
309+ menuData.icon = "file:///testIcon";
310+ menuData.isToggled = data.checked;
311+
312+ loader.data = menuData;
313+ loader.sourceComponent = factory.load(menuData);
314+ tryCompareFunction(function() { return loader.item != undefined; }, true);
315+ compare(loader.item.objectName, "switchMenu", "Should have created a standard menu");
316+
317+ compare(loader.item.text, data.label, "Label does not match data");
318+ compare(loader.item.icon, "file:///testIcon", "MaxIcon does not match data");
319+ compare(loader.item.checked, data.checked, "Checked does not match data");
320+ compare(loader.item.enabled, data.enabled, "Enabled does not match data");
321+ }
322+
323+ function test_create_wifiSection_data() {
324+ return [
325+ {label: "testLabel1", busy: false },
326+ {label: "testLabel2", busy: true },
327+ ];
328+ }
329+
330+ function test_create_wifiSection(data) {
331+ menuData.type = "unity.widgets.systemsettings.tablet.wifisection";
332+ menuData.label = data.label;
333+ menuData.ext = { 'xCanonicalBusyAction': data.busy }
334+
335+ loader.data = menuData;
336+ loader.sourceComponent = factory.load(menuData);
337+ tryCompareFunction(function() { return loader.item != undefined; }, true);
338+ compare(loader.item.objectName, "wifiSection", "Should have created a wifi section menu");
339+
340+ compare(loader.item.text, data.label, "Label does not match data");
341+ compare(loader.item.busy, data.busy, "Busy does not match data");
342+ }
343+
344+ function test_create_accessPoint_data() {
345+ return [
346+ {label: "testLabel1", enabled: true, checked: false, secure: true, adHoc: false },
347+ {label: "testLabel2", enabled: false, checked: true, secure: false, adHoc: true },
348+ ];
349+ }
350+
351+ function test_create_accessPoint(data) {
352+ menuData.type = "unity.widgets.systemsettings.tablet.accesspoint";
353+ menuData.label = data.label;
354+ menuData.sensitive = data.enabled;
355+ menuData.isToggled = data.checked;
356+ menuData.ext = {
357+ 'xCanonicalWifiApStrengthAction': "action::strength",
358+ 'xCanonicalWifiApIsSecure': data.secure,
359+ 'xCanonicalWifiApIsAdhoc': data.adHoc,
360+ };
361+
362+ loader.data = menuData;
363+ loader.sourceComponent = factory.load(menuData);
364+ tryCompareFunction(function() { return loader.item != undefined; }, true);
365+ compare(loader.item.objectName, "accessPoint", "Should have created a access point menu");
366+
367+ compare(loader.item.label, data.label, "Label does not match data");
368+ compare(loader.item.strengthAction.name, "action::strength", "Strength action incorrect");
369+ compare(loader.item.secure, data.secure, "Secure does not match data");
370+ compare(loader.item.adHoc, data.adHoc, "AdHoc does not match data");
371+ compare(loader.item.checked, data.checked, "Checked does not match data");
372+ compare(loader.item.enabled, data.enabled, "Enabled does not match data");
373+ }
374+
375+ function test_create_messageItem() {
376+ menuData.type = "com.canonical.indicator.messages.messageitem";
377+
378+ loader.data = menuData;
379+ loader.sourceComponent = factory.load(menuData);
380+ tryCompareFunction(function() { return loader.item != undefined; }, true);
381+ compare(loader.item.objectName, "messageItem", "Should have created a message menu");
382+ }
383+
384+ function test_create_groupedMessage_data() {
385+ return [
386+ {label: "testLabel1", enabled: true, count: "5", appIcon: "file:///testIcon" },
387+ {label: "testLabel2", enabled: false, count: "10", appIcon: "file:///testIcon2" },
388+ ];
389+ }
390+
391+ function test_create_groupedMessage(data) {
392+ menuData.type = "com.canonical.indicator.messages.sourceitem";
393+ menuData.label = data.label;
394+ menuData.sensitive = data.enabled;
395+ menuData.icon = data.appIcon;
396+ menuData.ext = { 'icon': data.appIcon };
397+ menuData.actionState = [data.count];
398+ menuData.isToggled = true;
399+
400+ loader.data = menuData;
401+ loader.sourceComponent = factory.load(menuData);
402+ tryCompareFunction(function() { return loader.item != undefined; }, true);
403+ compare(loader.item.objectName, "groupedMessage", "Should have created a group message menu");
404+
405+ compare(loader.item.title, data.label, "Label does not match data");
406+ compare(loader.item.count, data.count, "Count does not match data");
407+ compare(loader.item.appIcon, data.appIcon, "App Icon does not match data");
408+ compare(loader.item.enabled, data.enabled, "Enabled does not match data");
409+ }
410+
411+// function test_create_mediaPayerMenu_data() {
412+// return [{
413+// label: "player1",
414+// icon: "file:://icon1",
415+// albumArt: "file:://art1",
416+// song: "song1",
417+// artist: "artist1",
418+// album: "album1",
419+// running: true,
420+// state: "Playing",
421+// enabled: true
422+// },{
423+// label: "player2",
424+// icon: "file:://icon2",
425+// albumArt: "file:://art2",
426+// song: "song2",
427+// artist: "artist2",
428+// album: "album2",
429+// running: false,
430+// state: "Paused",
431+// enabled: false
432+// }
433+// ];
434+// }
435+
436+// function test_create_mediaPayerMenu(data) {
437+// var menuData = {
438+// 'label': data.label,
439+// 'sensitive': data.enabled,
440+// 'isSeparator': false,
441+// 'icon': data.icon,
442+// 'type': "com.canonical.unity.media-player",
443+// 'ext': {},
444+// 'action': "",
445+// 'actionState': {
446+// 'art-url': data.albumArt,
447+// 'title': data.song,
448+// 'artist': data.artist,
449+// 'album': data.album,
450+// 'running': data.running,
451+// 'state': data.state,
452+// },
453+// 'isCheck': false,
454+// 'isRadio': false,
455+// 'isToggled': false,
456+// };
457+
458+// loader.data = menuData;
459+// loader.sourceComponent = factory.load(menuData);
460+// tryCompareFunction(function() { return loader.item != undefined; }, true);
461+// compare(loader.item.objectName, "mediaPayerMenu", "Should have created a media player menu");
462+
463+// compare(loader.item.playerIcon, data.icon, "Album art does not match data");
464+// compare(loader.item.playerName, data.label, "Album art does not match data");
465+// compare(loader.item.albumArt, data.albumArt, "Album art does not match data");
466+// compare(loader.item.song, data.song, "Song does not match data");
467+// compare(loader.item.artist, data.artist, "Artist does not match data");
468+// compare(loader.item.album, data.album, "Album does not match data");
469+// compare(loader.item.running, data.running, "Running does not match data");
470+// compare(loader.item.state, data.state, "State does not match data");
471+// compare(loader.item.enabled, data.enabled, "Enabled does not match data");
472+// }
473+
474+// function test_create_playbackItemMenu_data() {
475+// return [{
476+// playAction: "action::play",
477+// nextAction: "action::next",
478+// previousAction: "action::previous",
479+// enabled: true
480+// },{
481+// playAction: "action::play2",
482+// nextAction: "action::next2",
483+// previousAction: "action::previous2",
484+// enabled: false
485+// }
486+// ];
487+// }
488+
489+// function test_create_playbackItemMenu(data) {
490+// var menuData = {
491+// 'label': "",
492+// 'sensitive': data.enabled,
493+// 'isSeparator': false,
494+// 'icon': "",
495+// 'type': "com.canonical.unity.playback-item",
496+// 'ext': {
497+// 'xCanonicalPlayAction': data.playAction,
498+// 'xCanonicalNextAction': data.nextAction,
499+// 'xCanonicalPreviousAction': data.previousAction
500+// },
501+// 'action': "",
502+// 'actionState': {},
503+// 'isCheck': false,
504+// 'isRadio': false,
505+// 'isToggled': false,
506+// };
507+
508+// loader.data = menuData;
509+// loader.sourceComponent = factory.load(menuData);
510+// tryCompareFunction(function() { return loader.item != undefined; }, true);
511+// compare(loader.item.objectName, "playbackItemMenu", "Should have created a playback menu");
512+
513+// compare(loader.item.playing, false, "Playing does not match data");
514+// compare(loader.item.playAction.name, data.playAction, "Play action incorrect");
515+// compare(loader.item.nextAction.name, data.nextAction, "Next action incorrect");
516+// compare(loader.item.previousAction.name, data.previousAction, "Previous action incorrect");
517+// compare(loader.item.canPlay, false, "CanPlay should be false");
518+// compare(loader.item.canGoNext, false, "CanGoNext should be false");
519+// compare(loader.item.canGoPrevious, false, "CanGoPrevious should be false");
520+// compare(loader.item.enabled, data.enabled, "Enabled does not match data");
521+// }
522+ }
523+}
tests/qmltests/Panel/Indicators/tst_MessageMenuItemFactory.qmlnew file+177
@@ -0,0 +1,177 @@
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 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.Messaging 0.1 as Indicators
22+
23+Item {
24+ id: testView
25+ width: units.gu(40)
26+ height: units.gu(70)
27+
28+ Indicators.MessageMenuItemFactory {
29+ id: factory
30+ menuModel: UnityMenuModel {}
31+ menuIndex: 0
32+ }
33+
34+ UT.UnityTestCase {
35+ name: "MessageMenuItemFactory"
36+
37+ property QtObject menuData: QtObject {
38+ property string label: "root"
39+ property bool sensitive: true
40+ property bool isSeparator: false
41+ property string icon: ""
42+ property string type: ""
43+ property var ext: undefined
44+ property string action: ""
45+ property var actionState: undefined
46+ property bool isCheck: false
47+ property bool isRadio: false
48+ property bool isToggled: false
49+ }
50+
51+ function init() {
52+ menuData.label = "";
53+ menuData.sensitive = true;
54+ menuData.isSeparator = false;
55+ menuData.icon = "";
56+ menuData.type = "";
57+ menuData.ext = undefined;
58+ menuData.action = "";
59+ menuData.actionState = undefined;
60+ menuData.isCheck = false;
61+ menuData.isRadio = false;
62+ menuData.isToggled = false;
63+
64+ factory.menuData = null;
65+ }
66+
67+ function test_create_simpleTextmessage_data() {
68+ return [
69+ { title: "Title1", time: new Date(2013, 10, 10).getTime()*1000, message: "This is a text message 1", avatar: "file:///avatar1", appIcon: "file:///appIcon1", enabled: true},
70+ { title: "Title2", time: new Date(2014, 12, 10).getTime()*1000, message: "This is a text message 2", avatar: "file:///avatar2", appIcon: "file:///appIcon2", enabled: false},
71+ ];
72+ }
73+
74+ function test_create_simpleTextmessage(data) {
75+ menuData.type = "com.canonical.indicator.messages.messageitem";
76+ menuData.label = data.title;
77+ menuData.sensitive = data.enabled;
78+ menuData.ext = {
79+ 'xCanonicalTime': data.time,
80+ 'xCanonicalText': data.message,
81+ 'icon': data.avatar,
82+ 'xCanonicalAppIcon': data.appIcon,
83+ };
84+ factory.menuData = menuData;
85+
86+ var loader = findChild(factory, "loader");
87+ verify(loader !== undefined);
88+
89+ tryCompare(loader.item, "objectName", "simpleTextMessage");
90+ compare(loader.item.title, data.title, "Title does not match data");
91+ compare(loader.item.time, data.time, "Time does not match data");
92+ compare(loader.item.message, data.message, "Message does not match data");
93+ compare(loader.item.avatar, data.avatar, "Avatar does not match data");
94+ compare(loader.item.appIcon, data.appIcon, "App icon does not match data");
95+ compare(loader.item.enabled, data.enabled, "Enabled does not match data");
96+ }
97+
98+ function test_create_textmessage_data() {
99+ return [
100+ { title: "Title1", time: new Date(2013, 10, 10).getTime()*1000, message: "This is a text message 1", avatar: "file:///avatar1", appIcon: "file:///appIcon1", enabled: true},
101+ { title: "Title2", time: new Date(2014, 12, 10).getTime()*1000, message: "This is a text message 2", avatar: "file:///avatar2", appIcon: "file:///appIcon2", enabled: false},
102+ ];
103+ }
104+
105+ function test_create_textmessage(data) {
106+ menuData.type = "com.canonical.indicator.messages.messageitem";
107+ menuData.label = data.title;
108+ menuData.sensitive = data.enabled;
109+ menuData.ext = {
110+ 'xCanonicalTime': data.time,
111+ 'xCanonicalText': data.message,
112+ 'icon': data.avatar,
113+ 'xCanonicalAppIcon': data.appIcon,
114+ 'xCanonicalMessageActions': [{
115+ 'parameter-type': "s",
116+ 'name': "action::reply",
117+ 'label': "Reply1"
118+ }
119+ ]
120+ };
121+ factory.menuData = menuData;
122+
123+ var loader = findChild(factory, "loader");
124+ verify(loader !== undefined);
125+
126+ tryCompare(loader.item, "objectName", "textMessage");
127+ compare(loader.item.title, data.title, "Title does not match data");
128+ compare(loader.item.time, data.time, "Time does not match data");
129+ compare(loader.item.message, data.message, "Message does not match data");
130+ compare(loader.item.avatar, data.avatar, "Avatar does not match data");
131+ compare(loader.item.appIcon, data.appIcon, "App icon does not match data");
132+ compare(loader.item.enabled, data.enabled, "Enabled does not match data");
133+ }
134+
135+
136+ function test_create_snapDecision_data() {
137+ return [
138+ { title: "Title1", time: new Date(2013, 10, 10).getTime()*1000, message: "This is a text message 1", avatar: "file:///avatar1", appIcon: "file:///appIcon1", enabled: true},
139+ { title: "Title2", time: new Date(2014, 12, 10).getTime()*1000, message: "This is a text message 2", avatar: "file:///avatar2", appIcon: "file:///appIcon2", enabled: false},
140+ ];
141+ }
142+
143+ function test_create_snapDecision(data) {
144+ menuData.type = "com.canonical.indicator.messages.messageitem";
145+ menuData.label = data.title;
146+ menuData.sensitive = data.enabled;
147+ menuData.ext = {
148+ 'xCanonicalTime': data.time,
149+ 'xCanonicalText': data.message,
150+ 'icon': data.avatar,
151+ 'xCanonicalAppIcon': data.appIcon,
152+ 'xCanonicalMessageActions': [{
153+ 'name': "action::callback",
154+ 'label': "Callback1"
155+ },{
156+ 'parameter-type': "s",
157+ 'name': "action::reply",
158+ 'label': "Reply1"
159+ }
160+ ]
161+ };
162+ factory.menuData = menuData;
163+
164+ var loader = findChild(factory, "loader");
165+ verify(loader !== undefined);
166+
167+ tryCompare(loader.item, "objectName", "snapDecision");
168+ compare(loader.item.title, data.title, "Title does not match data");
169+ compare(loader.item.time, data.time, "Time does not match data");
170+ compare(loader.item.message, data.message, "Message does not match data");
171+ compare(loader.item.avatar, data.avatar, "Avatar does not match data");
172+ compare(loader.item.appIcon, data.appIcon, "App icon does not match data");
173+ compare(loader.item.enabled, data.enabled, "Enabled does not match data");
174+ }
175+
176+ }
177+}