on db4d374 help sign in
unity8/tests/plugins/Unity/Indicators/unitymenumodelstacktest.cpp
207 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>
27#include <functional>
29class UnityMenuModelStackTest : public QObject
31 Q_OBJECT
32private Q_SLOTS:
34 void init()
35 {
36 m_model = new UnityMenuModel();
37 m_headChanged = false;
38 m_tailChanged = false;
39 }
41 void cleanup()
42 {
43 delete m_model;
44 m_model = NULL;
45 }
47 void testHeadOnSetHead()
48 {
49 UnityMenuModelStack stack;
50 connect(&stack, SIGNAL(headChanged(UnityMenuModel*)), this, SLOT(onHeadChanged()));
51 stack.setHead(m_model);
53 QCOMPARE(stack.head(), m_model);
54 QCOMPARE(m_headChanged, true);
55 }
57 void testTailOnSetHead()
58 {
59 UnityMenuModelStack stack;
60 connect(&stack, SIGNAL(tailChanged(UnityMenuModel*)), this, SLOT(onTailChanged()));
61 stack.setHead(m_model);
63 QCOMPARE(stack.tail(), m_model);
64 QCOMPARE(m_tailChanged, true);
65 }
67 void testPushPop_data() {
68 QTest::addColumn<int>("menuDepth");
69 QTest::addColumn<int>("subMenuCount");
70 QTest::addColumn<int>("subMenuIndex");
72 QTest::newRow("depth=0") << 0 << 1 << 0;
73 QTest::newRow("depth=1") << 1 << 1 << 0;
74 QTest::newRow("depth=8") << 8 << 2 << 1;
75 }
77 void testPushPop()
78 {
79 QFETCH(int, menuDepth);
80 QFETCH(int, subMenuCount);
81 QFETCH(int, subMenuIndex);
83 m_model->setModelData(recuseAddMenu(subMenuCount, menuDepth));
85 UnityMenuModelStack stack;
86 connect(&stack, SIGNAL(tailChanged(UnityMenuModel*)), this, SLOT(onTailChanged()));
88 QList<UnityMenuModel*> models;
90 int count = 0;
91 auto foreachChild = [&](UnityMenuModel* child, int childIndex) {
92 stack.push(child, childIndex);
93 QCOMPARE(stack.count(), count+1);
95 count++;
96 models << child;
97 };
98 recuseSubmenus(m_model, subMenuIndex, foreachChild);
100 QCOMPARE(stack.count(), models.count());
101 QCOMPARE(stack.count(), menuDepth+1);
102 while(stack.count() > 0) {
103 m_tailChanged = false;
105 QCOMPARE(stack.pop(), models.takeLast());
107 QCOMPARE(m_tailChanged, true);
108 if (stack.count()) {
109 QCOMPARE(stack.tail(), models.last());
110 }
111 }
112 QCOMPARE(m_tailChanged, true);
113 }
115 void testPopOnRemove_data() {
116 QTest::addColumn<int>("menuDepth");
117 QTest::addColumn<int>("subMenuCount");
118 QTest::addColumn<int>("subMenuIndex");
119 QTest::addColumn<int>("removeIndex");
120 QTest::addColumn<int>("resultCount");
122 QTest::newRow("removeIndexBefore") << 4 << 2 << 1 << 0 << 5;
123 QTest::newRow("removeCurrentIndex") << 4 << 2 << 0 << 0 << 1;
124 QTest::newRow("removeIndexAfter") << 4 << 2 << 0 << 1 << 5;
125 }
127 void testPopOnRemove()
128 {
129 QFETCH(int, menuDepth);
130 QFETCH(int, subMenuCount);
131 QFETCH(int, subMenuIndex);
132 QFETCH(int, removeIndex);
133 QFETCH(int, resultCount);
135 m_model->setModelData(recuseAddMenu(subMenuCount, menuDepth));
137 UnityMenuModelStack stack;
139 auto foreachChild = [&](UnityMenuModel* child, int childIndex) {
140 stack.push(child, childIndex);
141 };
142 recuseSubmenus(m_model, subMenuIndex, foreachChild);
144 QCOMPARE(stack.count(), menuDepth+1);
146 m_model->removeRow(removeIndex);
148 waitFor([&stack, resultCount]() { return stack.count() == resultCount; }, 1000);
149 QCOMPARE(stack.count(), resultCount);
150 }
152private:
153 bool waitFor(std::function<bool()> functor, int ms) {
155 QElapsedTimer timer;
156 timer.start();
157 while(!functor() && timer.elapsed() < ms) { QTest::qWait(10); }
158 return functor();
159 }
161 QVariant recuseAddMenu(int subMenuCount, int depth_remaining)
162 {
163 QVariantList rows;
165 for (int i = 0; i < subMenuCount; i ++) {
166 QVariantMap row;
167 QVariantMap rowData;
169 if (depth_remaining > 0) {
170 row["submenu"] = recuseAddMenu(subMenuCount, depth_remaining-1);
171 }
173 row["rowData"] = rowData;
175 rows << row;
176 }
178 return rows;
179 }
181 void recuseSubmenus(UnityMenuModel* model, int childIndex, std::function<void(UnityMenuModel*, int)> func) {
182 UnityMenuModel* parent = model;
183 UnityMenuModel* child = model;
185 while(child) {
186 if (func) {
187 func(child, childIndex);
188 }
190 parent = child;
191 child = qobject_cast<UnityMenuModel*>(parent->submenu(childIndex));
192 }
194 }
196private Q_SLOTS:
197 void onHeadChanged() { m_headChanged = true; }
198 void onTailChanged() { m_tailChanged = true; }
200public:
201 UnityMenuModel* m_model;
202 bool m_headChanged;
203 bool m_tailChanged;
204};
206QTEST_GUILESS_MAIN(UnityMenuModelStackTest)
207#include "unitymenumodelstacktest.moc"