on aa42683 help sign in
unity8/tests/plugins/Unity/Indicators/UnityMenuModelStackTest.cpp
208 lines 5.8 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>
28#include <chrono>
30class UnityMenuModelStackTest : public QObject
32 Q_OBJECT
33private Q_SLOTS:
35 void init()
36 {
37 m_model = new UnityMenuModel();
38 m_headChanged = false;
39 m_tailChanged = false;
40 }
42 void cleanup()
43 {
44 delete m_model;
45 m_model = nullptr;
46 }
48 void testHeadOnSetHead()
49 {
50 UnityMenuModelStack stack;
51 connect(&stack, &UnityMenuModelStack::headChanged, this, &UnityMenuModelStackTest::onHeadChanged);
52 stack.setHead(m_model);
54 QCOMPARE(stack.head(), m_model);
55 QCOMPARE(m_headChanged, true);
56 }
58 void testTailOnSetHead()
59 {
60 UnityMenuModelStack stack;
61 connect(&stack, &UnityMenuModelStack::tailChanged, this, &UnityMenuModelStackTest::onTailChanged);
62 stack.setHead(m_model);
64 QCOMPARE(stack.tail(), m_model);
65 QCOMPARE(m_tailChanged, true);
66 }
68 void testPushPop_data() {
69 QTest::addColumn<int>("menuDepth");
70 QTest::addColumn<int>("subMenuCount");
71 QTest::addColumn<int>("subMenuIndex");
73 QTest::newRow("depth=0") << 0 << 1 << 0;
74 QTest::newRow("depth=1") << 1 << 1 << 0;
75 QTest::newRow("depth=8") << 8 << 2 << 1;
76 }
78 void testPushPop()
79 {
80 QFETCH(int, menuDepth);
81 QFETCH(int, subMenuCount);
82 QFETCH(int, subMenuIndex);
84 m_model->setModelData(recuseAddMenu(subMenuCount, menuDepth));
86 UnityMenuModelStack stack;
87 connect(&stack, &UnityMenuModelStack::tailChanged, this, &UnityMenuModelStackTest::onTailChanged);
89 QList<UnityMenuModel*> models;
91 int count = 0;
92 auto foreachChild = [&](UnityMenuModel* child, int childIndex) {
93 stack.push(child, childIndex);
94 QCOMPARE(stack.count(), count+1);
96 count++;
97 models << child;
98 };
99 recuseSubmenus(m_model, subMenuIndex, foreachChild);
101 QCOMPARE(stack.count(), models.count());
102 QCOMPARE(stack.count(), menuDepth+1);
103 while(stack.count() > 0) {
104 m_tailChanged = false;
106 QCOMPARE(stack.pop(), models.takeLast());
108 QCOMPARE(m_tailChanged, true);
109 if (stack.count()) {
110 QCOMPARE(stack.tail(), models.last());
111 }
112 }
113 QCOMPARE(m_tailChanged, true);
114 }
116 void testPopOnRemove_data() {
117 QTest::addColumn<int>("menuDepth");
118 QTest::addColumn<int>("subMenuCount");
119 QTest::addColumn<int>("subMenuIndex");
120 QTest::addColumn<int>("removeIndex");
121 QTest::addColumn<int>("resultCount");
123 QTest::newRow("removeIndexBefore") << 4 << 2 << 1 << 0 << 5;
124 QTest::newRow("removeCurrentIndex") << 4 << 2 << 0 << 0 << 1;
125 QTest::newRow("removeIndexAfter") << 4 << 2 << 0 << 1 << 5;
126 }
128 void testPopOnRemove()
129 {
130 QFETCH(int, menuDepth);
131 QFETCH(int, subMenuCount);
132 QFETCH(int, subMenuIndex);
133 QFETCH(int, removeIndex);
134 QFETCH(int, resultCount);
136 m_model->setModelData(recuseAddMenu(subMenuCount, menuDepth));
138 UnityMenuModelStack stack;
140 auto foreachChild = [&](UnityMenuModel* child, int childIndex) {
141 stack.push(child, childIndex);
142 };
143 recuseSubmenus(m_model, subMenuIndex, foreachChild);
145 QCOMPARE(stack.count(), menuDepth+1);
147 m_model->removeRow(removeIndex);
149 waitFor([&stack, resultCount]() { return stack.count() == resultCount; }, 1000);
150 QCOMPARE(stack.count(), resultCount);
151 }
153private:
154 bool waitFor(std::function<bool()> functor, int ms) {
156 QElapsedTimer timer;
157 timer.start();
158 while(!functor() && timer.elapsed() < ms) { QTest::qWait(10); }
159 return functor();
160 }
162 QVariant recuseAddMenu(int subMenuCount, int depth_remaining)
163 {
164 QVariantList rows;
166 for (int i = 0; i < subMenuCount; i ++) {
167 QVariantMap row;
168 QVariantMap rowData;
170 if (depth_remaining > 0) {
171 row["submenu"] = recuseAddMenu(subMenuCount, depth_remaining-1);
172 }
174 row["rowData"] = rowData;
176 rows << row;
177 }
179 return rows;
180 }
182 void recuseSubmenus(UnityMenuModel* model, int childIndex, std::function<void(UnityMenuModel*, int)> func) {
183 UnityMenuModel* parent = model;
184 UnityMenuModel* child = model;
186 while(child) {
187 if (func) {
188 func(child, childIndex);
189 }
191 parent = child;
192 child = qobject_cast<UnityMenuModel*>(parent->submenu(childIndex));
193 }
195 }
197private Q_SLOTS:
198 void onHeadChanged() { m_headChanged = true; }
199 void onTailChanged() { m_tailChanged = true; }
201public:
202 UnityMenuModel* m_model;
203 bool m_headChanged;
204 bool m_tailChanged;
205};
207QTEST_GUILESS_MAIN(UnityMenuModelStackTest)
208#include "UnityMenuModelStackTest.moc"