on 2012c49 help sign in
unity8/tests/plugins/Unity/Indicators/unitymenumodelstacktest.cpp
205 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 "unitymenumodelstack.h"
23#include <QtTest>
24#include <QDebug>
25#include <unitymenumodel.h>
27class UnityMenuModelStackTest : public QObject
29 Q_OBJECT
30private Q_SLOTS:
32 void init()
33 {
34 m_model = new UnityMenuModel();
35 m_headChanged = false;
36 m_tailChanged = false;
37 }
39 void cleanup()
40 {
41 delete m_model;
42 m_model = NULL;
43 }
45 void testHeadOnSetHead()
46 {
47 UnityMenuModelStack stack;
48 connect(&stack, SIGNAL(headChanged(UnityMenuModel*)), this, SLOT(onHeadChanged()));
49 stack.setHead(m_model);
51 QCOMPARE(stack.head(), m_model);
52 QCOMPARE(m_headChanged, true);
53 }
55 void testTailOnSetHead()
56 {
57 UnityMenuModelStack stack;
58 connect(&stack, SIGNAL(tailChanged(UnityMenuModel*)), this, SLOT(onTailChanged()));
59 stack.setHead(m_model);
61 QCOMPARE(stack.tail(), m_model);
62 QCOMPARE(m_tailChanged, true);
63 }
65 void testPushPop_data() {
66 QTest::addColumn<int>("menuDepth");
67 QTest::addColumn<int>("subMenuCount");
68 QTest::addColumn<int>("subMenuIndex");
70 QTest::newRow("depth=0") << 0 << 1 << 0;
71 QTest::newRow("depth=1") << 1 << 1 << 0;
72 QTest::newRow("depth=8") << 8 << 2 << 1;
73 }
75 void testPushPop()
76 {
77 QFETCH(int, menuDepth);
78 QFETCH(int, subMenuCount);
79 QFETCH(int, subMenuIndex);
81 m_model->setModelData(recuseAddMenu(subMenuCount, menuDepth));
83 UnityMenuModelStack stack;
84 connect(&stack, SIGNAL(tailChanged(UnityMenuModel*)), this, SLOT(onTailChanged()));
86 QList<UnityMenuModel*> models;
88 int count = 0;
89 auto foreachChild = [&](UnityMenuModel* child, int childIndex) {
90 stack.push(child, childIndex);
91 QCOMPARE(stack.count(), count+1);
93 count++;
94 models << child;
95 };
96 recuseSubmenus(m_model, subMenuIndex, foreachChild);
98 QCOMPARE(stack.count(), models.count());
99 QCOMPARE(stack.count(), menuDepth+1);
100 while(stack.count() > 0) {
101 m_tailChanged = false;
103 QCOMPARE(stack.pop(), models.takeLast());
105 QCOMPARE(m_tailChanged, true);
106 if (stack.count()) {
107 QCOMPARE(stack.tail(), models.last());
108 }
109 }
110 QCOMPARE(m_tailChanged, true);
111 }
113 void testPopOnRemove_data() {
114 QTest::addColumn<int>("menuDepth");
115 QTest::addColumn<int>("subMenuCount");
116 QTest::addColumn<int>("subMenuIndex");
117 QTest::addColumn<int>("removeIndex");
118 QTest::addColumn<int>("resultCount");
120 QTest::newRow("removeIndexBefore") << 4 << 2 << 1 << 0 << 5;
121 QTest::newRow("removeCurrentIndex") << 4 << 2 << 0 << 0 << 1;
122 QTest::newRow("removeIndexAfter") << 4 << 2 << 0 << 1 << 5;
123 }
125 void testPopOnRemove()
126 {
127 QFETCH(int, menuDepth);
128 QFETCH(int, subMenuCount);
129 QFETCH(int, subMenuIndex);
130 QFETCH(int, removeIndex);
131 QFETCH(int, resultCount);
133 m_model->setModelData(recuseAddMenu(subMenuCount, menuDepth));
135 UnityMenuModelStack stack;
137 auto foreachChild = [&](UnityMenuModel* child, int childIndex) {
138 stack.push(child, childIndex);
139 };
140 recuseSubmenus(m_model, subMenuIndex, foreachChild);
142 QCOMPARE(stack.count(), menuDepth+1);
144 m_model->removeRow(removeIndex);
146 waitFor([&stack, resultCount]() { return stack.count() == resultCount; }, 1000);
147 QCOMPARE(stack.count(), resultCount);
148 }
150private:
151 bool waitFor(std::function<bool()> functor, int ms) {
153 QElapsedTimer timer;
154 timer.start();
155 while(!functor() && timer.elapsed() < ms) { QTest::qWait(10); }
156 return functor();
157 }
159 QVariant recuseAddMenu(int subMenuCount, int depth_remaining)
160 {
161 QVariantList rows;
163 for (int i = 0; i < subMenuCount; i ++) {
164 QVariantMap row;
165 QVariantMap rowData;
167 if (depth_remaining > 0) {
168 row["submenu"] = recuseAddMenu(subMenuCount, depth_remaining-1);
169 }
171 row["rowData"] = rowData;
173 rows << row;
174 }
176 return rows;
177 }
179 void recuseSubmenus(UnityMenuModel* model, int childIndex, std::function<void(UnityMenuModel*, int)> func) {
180 UnityMenuModel* parent = model;
181 UnityMenuModel* child = model;
183 while(child) {
184 if (func) {
185 func(child, childIndex);
186 }
188 parent = child;
189 child = qobject_cast<UnityMenuModel*>(parent->submenu(childIndex));
190 }
192 }
194private Q_SLOTS:
195 void onHeadChanged() { m_headChanged = true; }
196 void onTailChanged() { m_tailChanged = true; }
198public:
199 UnityMenuModel* m_model;
200 bool m_headChanged;
201 bool m_tailChanged;
202};
204QTEST_GUILESS_MAIN(UnityMenuModelStackTest)
205#include "unitymenumodelstacktest.moc"