/*
* Copyright (C) 2013 Canonical, Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Authors:
* Nick Dedekind
*/
#include "indicatorsmanager.h"
#include "unitymenumodelstack.h"
#include
#include
#include
#include
#include
class UnityMenuModelStackTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void init()
{
m_model = new UnityMenuModel();
m_headChanged = false;
m_tailChanged = false;
}
void cleanup()
{
delete m_model;
m_model = nullptr;
// send deleteLaters to avoid leaks.
QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
}
void testHeadOnSetHead()
{
UnityMenuModelStack stack;
connect(&stack, &UnityMenuModelStack::headChanged, this, &UnityMenuModelStackTest::onHeadChanged);
stack.setHead(m_model);
QCOMPARE(stack.head(), m_model);
QCOMPARE(m_headChanged, true);
}
void testTailOnSetHead()
{
UnityMenuModelStack stack;
connect(&stack, &UnityMenuModelStack::tailChanged, this, &UnityMenuModelStackTest::onTailChanged);
stack.setHead(m_model);
QCOMPARE(stack.tail(), m_model);
QCOMPARE(m_tailChanged, true);
}
void testPushPop_data() {
QTest::addColumn("menuDepth");
QTest::addColumn("subMenuCount");
QTest::addColumn("subMenuIndex");
QTest::newRow("depth=0") << 0 << 1 << 0;
QTest::newRow("depth=1") << 1 << 1 << 0;
QTest::newRow("depth=8") << 8 << 2 << 1;
}
void testPushPop()
{
QFETCH(int, menuDepth);
QFETCH(int, subMenuCount);
QFETCH(int, subMenuIndex);
m_model->setModelData(recuseAddMenu(subMenuCount, menuDepth));
UnityMenuModelStack stack;
connect(&stack, &UnityMenuModelStack::tailChanged, this, &UnityMenuModelStackTest::onTailChanged);
QList models;
int count = 0;
auto foreachChild = [&](UnityMenuModel* child, int childIndex) {
stack.push(child, childIndex);
QCOMPARE(stack.count(), count+1);
count++;
models << child;
};
recuseSubmenus(m_model, subMenuIndex, foreachChild);
QCOMPARE(stack.count(), models.count());
QCOMPARE(stack.count(), menuDepth+1);
while(stack.count() > 0) {
m_tailChanged = false;
QCOMPARE(stack.pop(), models.takeLast());
QCOMPARE(m_tailChanged, true);
if (stack.count()) {
QCOMPARE(stack.tail(), models.last());
}
}
QCOMPARE(m_tailChanged, true);
}
void testPopOnRemove_data() {
QTest::addColumn("menuDepth");
QTest::addColumn("subMenuCount");
QTest::addColumn("subMenuIndex");
QTest::addColumn("removeIndex");
QTest::addColumn("resultCount");
QTest::newRow("removeIndexBefore") << 4 << 2 << 1 << 0 << 5;
QTest::newRow("removeCurrentIndex") << 4 << 2 << 0 << 0 << 1;
QTest::newRow("removeIndexAfter") << 4 << 2 << 0 << 1 << 5;
}
void testPopOnRemove()
{
QFETCH(int, menuDepth);
QFETCH(int, subMenuCount);
QFETCH(int, subMenuIndex);
QFETCH(int, removeIndex);
QFETCH(int, resultCount);
m_model->setModelData(recuseAddMenu(subMenuCount, menuDepth));
UnityMenuModelStack stack;
auto foreachChild = [&](UnityMenuModel* child, int childIndex) {
stack.push(child, childIndex);
};
recuseSubmenus(m_model, subMenuIndex, foreachChild);
QCOMPARE(stack.count(), menuDepth+1);
m_model->removeRow(removeIndex);
QCOMPARE(stack.count(), resultCount);
}
private:
QVariant recuseAddMenu(int subMenuCount, int depth_remaining)
{
QVariantList rows;
for (int i = 0; i < subMenuCount; i ++) {
QVariantMap row;
QVariantMap rowData;
if (depth_remaining > 0) {
row["submenu"] = recuseAddMenu(subMenuCount, depth_remaining-1);
}
row["rowData"] = rowData;
rows << row;
}
return rows;
}
void recuseSubmenus(UnityMenuModel* model, int childIndex, std::function func) {
UnityMenuModel* parent = model;
UnityMenuModel* child = model;
while(child) {
if (func) {
func(child, childIndex);
}
parent = child;
child = qobject_cast(parent->submenu(childIndex));
}
}
private Q_SLOTS:
void onHeadChanged() { m_headChanged = true; }
void onTailChanged() { m_tailChanged = true; }
public:
UnityMenuModel* m_model;
bool m_headChanged;
bool m_tailChanged;
};
QTEST_GUILESS_MAIN(UnityMenuModelStackTest)
#include "UnityMenuModelStackTest.moc"