on 11ff4cc help sign in
unity8/tests/plugins/Unity/Indicators/unitymenumodelstacktest.cpp
206 lines 5.7 kB history raw
1/*
2 * Copyright (C) 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 * Authors:
17 * Nick Dedekind <nick.dedekind@canonical.com>
18 */
20#include "indicatorsmanager.h"
21#include "paths.h"
22#include "unitymenumodelstack.h"
24#include <QtTest>
25#include <QDebug>
26#include <unitymenumodel.h>
28class UnityMenuModelStackTest : public QObject
30 Q_OBJECT
31private Q_SLOTS:
33 void init()
34 {
35 m_model = new UnityMenuModel();
36 m_headChanged = false;
37 m_tailChanged = false;
38 }
40 void cleanup()
41 {
42 delete m_model;
43 m_model = NULL;
44 }
46 void testHeadOnSetHead()
47 {
48 UnityMenuModelStack stack;
49 connect(&stack, SIGNAL(headChanged(UnityMenuModel*)), this, SLOT(onHeadChanged()));
50 stack.setHead(m_model);
52 QCOMPARE(stack.head(), m_model);
53 QCOMPARE(m_headChanged, true);
54 }
56 void testTailOnSetHead()
57 {
58 UnityMenuModelStack stack;
59 connect(&stack, SIGNAL(tailChanged(UnityMenuModel*)), this, SLOT(onTailChanged()));
60 stack.setHead(m_model);
62 QCOMPARE(stack.tail(), m_model);
63 QCOMPARE(m_tailChanged, true);
64 }
66 void testPushPop_data() {
67 QTest::addColumn<int>("menuDepth");
68 QTest::addColumn<int>("subMenuCount");
69 QTest::addColumn<int>("subMenuIndex");
71 QTest::newRow("depth=0") << 0 << 1 << 0;
72 QTest::newRow("depth=1") << 1 << 1 << 0;
73 QTest::newRow("depth=8") << 8 << 2 << 1;
74 }
76 void testPushPop()
77 {
78 QFETCH(int, menuDepth);
79 QFETCH(int, subMenuCount);
80 QFETCH(int, subMenuIndex);
82 m_model->setModelData(recuseAddMenu(subMenuCount, menuDepth));
84 UnityMenuModelStack stack;
85 connect(&stack, SIGNAL(tailChanged(UnityMenuModel*)), this, SLOT(onTailChanged()));
87 QList<UnityMenuModel*> models;
89 int count = 0;
90 auto foreachChild = [&](UnityMenuModel* child, int childIndex) {
91 stack.push(child, childIndex);
92 QCOMPARE(stack.count(), count+1);
94 count++;
95 models << child;
96 };
97 recuseSubmenus(m_model, subMenuIndex, foreachChild);
99 QCOMPARE(stack.count(), models.count());
100 QCOMPARE(stack.count(), menuDepth+1);
101 while(stack.count() > 0) {
102 m_tailChanged = false;
104 QCOMPARE(stack.pop(), models.takeLast());
106 QCOMPARE(m_tailChanged, true);
107 if (stack.count()) {
108 QCOMPARE(stack.tail(), models.last());
109 }
110 }
111 QCOMPARE(m_tailChanged, true);
112 }
114 void testPopOnRemove_data() {
115 QTest::addColumn<int>("menuDepth");
116 QTest::addColumn<int>("subMenuCount");
117 QTest::addColumn<int>("subMenuIndex");
118 QTest::addColumn<int>("removeIndex");
119 QTest::addColumn<int>("resultCount");
121 QTest::newRow("removeIndexBefore") << 4 << 2 << 1 << 0 << 5;
122 QTest::newRow("removeCurrentIndex") << 4 << 2 << 0 << 0 << 1;
123 QTest::newRow("removeIndexAfter") << 4 << 2 << 0 << 1 << 5;
124 }
126 void testPopOnRemove()
127 {
128 QFETCH(int, menuDepth);
129 QFETCH(int, subMenuCount);
130 QFETCH(int, subMenuIndex);
131 QFETCH(int, removeIndex);
132 QFETCH(int, resultCount);
134 m_model->setModelData(recuseAddMenu(subMenuCount, menuDepth));
136 UnityMenuModelStack stack;
138 auto foreachChild = [&](UnityMenuModel* child, int childIndex) {
139 stack.push(child, childIndex);
140 };
141 recuseSubmenus(m_model, subMenuIndex, foreachChild);
143 QCOMPARE(stack.count(), menuDepth+1);
145 m_model->removeRow(removeIndex);
147 waitFor([&stack, resultCount]() { return stack.count() == resultCount; }, 1000);
148 QCOMPARE(stack.count(), resultCount);
149 }
151private:
152 bool waitFor(std::function<bool()> functor, int ms) {
154 QElapsedTimer timer;
155 timer.start();
156 while(!functor() && timer.elapsed() < ms) { QTest::qWait(10); }
157 return functor();
158 }
160 QVariant recuseAddMenu(int subMenuCount, int depth_remaining)
161 {
162 QVariantList rows;
164 for (int i = 0; i < subMenuCount; i ++) {
165 QVariantMap row;
166 QVariantMap rowData;
168 if (depth_remaining > 0) {
169 row["submenu"] = recuseAddMenu(subMenuCount, depth_remaining-1);
170 }
172 row["rowData"] = rowData;
174 rows << row;
175 }
177 return rows;
178 }
180 void recuseSubmenus(UnityMenuModel* model, int childIndex, std::function<void(UnityMenuModel*, int)> func) {
181 UnityMenuModel* parent = model;
182 UnityMenuModel* child = model;
184 while(child) {
185 if (func) {
186 func(child, childIndex);
187 }
189 parent = child;
190 child = qobject_cast<UnityMenuModel*>(parent->submenu(childIndex));
191 }
193 }
195private Q_SLOTS:
196 void onHeadChanged() { m_headChanged = true; }
197 void onTailChanged() { m_tailChanged = true; }
199public:
200 UnityMenuModel* m_model;
201 bool m_headChanged;
202 bool m_tailChanged;
203};
205QTEST_GUILESS_MAIN(UnityMenuModelStackTest)
206#include "unitymenumodelstacktest.moc"