diff options
Diffstat (limited to 'tests/auto/widgets/util/qundogroup/tst_qundogroup.cpp')
-rw-r--r-- | tests/auto/widgets/util/qundogroup/tst_qundogroup.cpp | 668 |
1 files changed, 668 insertions, 0 deletions
diff --git a/tests/auto/widgets/util/qundogroup/tst_qundogroup.cpp b/tests/auto/widgets/util/qundogroup/tst_qundogroup.cpp new file mode 100644 index 0000000000..6d51252e22 --- /dev/null +++ b/tests/auto/widgets/util/qundogroup/tst_qundogroup.cpp @@ -0,0 +1,668 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QtTest/QtTest> +#include <QUndoGroup> +#include <QUndoStack> +#include <QAction> + +// Temporarily disabling IRIX due to build issuues with GCC +#if !defined(__sgi) || defined(__sgi) && !defined(__GNUC__) + +/****************************************************************************** +** Commands +*/ + +class InsertCommand : public QUndoCommand +{ +public: + InsertCommand(QString *str, int idx, const QString &text, + QUndoCommand *parent = 0); + + virtual void undo(); + virtual void redo(); + +private: + QString *m_str; + int m_idx; + QString m_text; +}; + +class RemoveCommand : public QUndoCommand +{ +public: + RemoveCommand(QString *str, int idx, int len, QUndoCommand *parent = 0); + + virtual void undo(); + virtual void redo(); + +private: + QString *m_str; + int m_idx; + QString m_text; +}; + +class AppendCommand : public QUndoCommand +{ +public: + AppendCommand(QString *str, const QString &text, QUndoCommand *parent = 0); + + virtual void undo(); + virtual void redo(); + virtual int id() const; + virtual bool mergeWith(const QUndoCommand *other); + + bool merged; + +private: + QString *m_str; + QString m_text; +}; + +InsertCommand::InsertCommand(QString *str, int idx, const QString &text, + QUndoCommand *parent) + : QUndoCommand(parent) +{ + QVERIFY(str->length() >= idx); + + setText("insert"); + + m_str = str; + m_idx = idx; + m_text = text; +} + +void InsertCommand::redo() +{ + QVERIFY(m_str->length() >= m_idx); + + m_str->insert(m_idx, m_text); +} + +void InsertCommand::undo() +{ + QCOMPARE(m_str->mid(m_idx, m_text.length()), m_text); + + m_str->remove(m_idx, m_text.length()); +} + +RemoveCommand::RemoveCommand(QString *str, int idx, int len, QUndoCommand *parent) + : QUndoCommand(parent) +{ + QVERIFY(str->length() >= idx + len); + + setText("remove"); + + m_str = str; + m_idx = idx; + m_text = m_str->mid(m_idx, len); +} + +void RemoveCommand::redo() +{ + QCOMPARE(m_str->mid(m_idx, m_text.length()), m_text); + + m_str->remove(m_idx, m_text.length()); +} + +void RemoveCommand::undo() +{ + QVERIFY(m_str->length() >= m_idx); + + m_str->insert(m_idx, m_text); +} + +AppendCommand::AppendCommand(QString *str, const QString &text, QUndoCommand *parent) + : QUndoCommand(parent) +{ + setText("append"); + + m_str = str; + m_text = text; + merged = false; +} + +void AppendCommand::redo() +{ + m_str->append(m_text); +} + +void AppendCommand::undo() +{ + QCOMPARE(m_str->mid(m_str->length() - m_text.length()), m_text); + + m_str->truncate(m_str->length() - m_text.length()); +} + +int AppendCommand::id() const +{ + return 1; +} + +bool AppendCommand::mergeWith(const QUndoCommand *other) +{ + if (other->id() != id()) + return false; + m_text += static_cast<const AppendCommand*>(other)->m_text; + merged = true; + return true; +} + +/****************************************************************************** +** tst_QUndoStack +*/ + +class tst_QUndoGroup : public QObject +{ + Q_OBJECT +public: + tst_QUndoGroup(); + +private slots: + void setActive(); + void addRemoveStack(); + void deleteStack(); + void checkSignals(); + void addStackAndDie(); + void commandTextFormat(); +}; + +tst_QUndoGroup::tst_QUndoGroup() +{ +} + +void tst_QUndoGroup::setActive() +{ + QUndoGroup group; + QUndoStack stack1(&group), stack2(&group); + + QCOMPARE(group.activeStack(), (QUndoStack*)0); + QCOMPARE(stack1.isActive(), false); + QCOMPARE(stack2.isActive(), false); + + QUndoStack stack3; + QCOMPARE(stack3.isActive(), true); + + group.addStack(&stack3); + QCOMPARE(stack3.isActive(), false); + + stack1.setActive(); + QCOMPARE(group.activeStack(), &stack1); + QCOMPARE(stack1.isActive(), true); + QCOMPARE(stack2.isActive(), false); + QCOMPARE(stack3.isActive(), false); + + group.setActiveStack(&stack2); + QCOMPARE(group.activeStack(), &stack2); + QCOMPARE(stack1.isActive(), false); + QCOMPARE(stack2.isActive(), true); + QCOMPARE(stack3.isActive(), false); + + group.removeStack(&stack2); + QCOMPARE(group.activeStack(), (QUndoStack*)0); + QCOMPARE(stack1.isActive(), false); + QCOMPARE(stack2.isActive(), true); + QCOMPARE(stack3.isActive(), false); + + group.removeStack(&stack2); + QCOMPARE(group.activeStack(), (QUndoStack*)0); + QCOMPARE(stack1.isActive(), false); + QCOMPARE(stack2.isActive(), true); + QCOMPARE(stack3.isActive(), false); +} + +void tst_QUndoGroup::addRemoveStack() +{ + QUndoGroup group; + + QUndoStack stack1(&group); + QCOMPARE(group.stacks(), QList<QUndoStack*>() << &stack1); + + QUndoStack stack2; + group.addStack(&stack2); + QCOMPARE(group.stacks(), QList<QUndoStack*>() << &stack1 << &stack2); + + group.addStack(&stack1); + QCOMPARE(group.stacks(), QList<QUndoStack*>() << &stack1 << &stack2); + + group.removeStack(&stack1); + QCOMPARE(group.stacks(), QList<QUndoStack*>() << &stack2); + + group.removeStack(&stack1); + QCOMPARE(group.stacks(), QList<QUndoStack*>() << &stack2); + + group.removeStack(&stack2); + QCOMPARE(group.stacks(), QList<QUndoStack*>()); +} + +void tst_QUndoGroup::deleteStack() +{ + QUndoGroup group; + + QUndoStack *stack1 = new QUndoStack(&group); + QCOMPARE(group.stacks(), QList<QUndoStack*>() << stack1); + QCOMPARE(group.activeStack(), (QUndoStack*)0); + + stack1->setActive(); + QCOMPARE(group.activeStack(), stack1); + + QUndoStack *stack2 = new QUndoStack(&group); + QCOMPARE(group.stacks(), QList<QUndoStack*>() << stack1 << stack2); + QCOMPARE(group.activeStack(), stack1); + + QUndoStack *stack3 = new QUndoStack(&group); + QCOMPARE(group.stacks(), QList<QUndoStack*>() << stack1 << stack2 << stack3); + QCOMPARE(group.activeStack(), stack1); + + delete stack2; + QCOMPARE(group.stacks(), QList<QUndoStack*>() << stack1 << stack3); + QCOMPARE(group.activeStack(), stack1); + + delete stack1; + QCOMPARE(group.stacks(), QList<QUndoStack*>() << stack3); + QCOMPARE(group.activeStack(), (QUndoStack*)0); + + stack3->setActive(false); + QCOMPARE(group.activeStack(), (QUndoStack*)0); + + stack3->setActive(true); + QCOMPARE(group.activeStack(), stack3); + + group.removeStack(stack3); + QCOMPARE(group.stacks(), QList<QUndoStack*>()); + QCOMPARE(group.activeStack(), (QUndoStack*)0); + + delete stack3; +} + +static QString glue(const QString &s1, const QString &s2) +{ + QString result; + + result.append(s1); + if (!s1.isEmpty() && !s2.isEmpty()) + result.append(' '); + result.append(s2); + + return result; +} + +#define CHECK_STATE(_activeStack, _clean, _canUndo, _undoText, _canRedo, _redoText, \ + _cleanChanged, _indexChanged, _undoChanged, _redoChanged) \ + QCOMPARE(group.activeStack(), (QUndoStack*)_activeStack); \ + QCOMPARE(group.isClean(), _clean); \ + QCOMPARE(group.canUndo(), _canUndo); \ + QCOMPARE(group.undoText(), QString(_undoText)); \ + QCOMPARE(group.canRedo(), _canRedo); \ + QCOMPARE(group.redoText(), QString(_redoText)); \ + if (_indexChanged) { \ + QCOMPARE(indexChangedSpy.count(), 1); \ + indexChangedSpy.clear(); \ + } else { \ + QCOMPARE(indexChangedSpy.count(), 0); \ + } \ + if (_cleanChanged) { \ + QCOMPARE(cleanChangedSpy.count(), 1); \ + QCOMPARE(cleanChangedSpy.at(0).at(0).toBool(), _clean); \ + cleanChangedSpy.clear(); \ + } else { \ + QCOMPARE(cleanChangedSpy.count(), 0); \ + } \ + if (_undoChanged) { \ + QCOMPARE(canUndoChangedSpy.count(), 1); \ + QCOMPARE(canUndoChangedSpy.at(0).at(0).toBool(), _canUndo); \ + QCOMPARE(undo_action->isEnabled(), _canUndo); \ + QCOMPARE(undoTextChangedSpy.count(), 1); \ + QCOMPARE(undoTextChangedSpy.at(0).at(0).toString(), QString(_undoText)); \ + QCOMPARE(undo_action->text(), glue("foo", _undoText)); \ + canUndoChangedSpy.clear(); \ + undoTextChangedSpy.clear(); \ + } else { \ + QCOMPARE(canUndoChangedSpy.count(), 0); \ + QCOMPARE(undoTextChangedSpy.count(), 0); \ + } \ + if (_redoChanged) { \ + QCOMPARE(canRedoChangedSpy.count(), 1); \ + QCOMPARE(canRedoChangedSpy.at(0).at(0).toBool(), _canRedo); \ + QCOMPARE(redo_action->isEnabled(), _canRedo); \ + QCOMPARE(redoTextChangedSpy.count(), 1); \ + QCOMPARE(redoTextChangedSpy.at(0).at(0).toString(), QString(_redoText)); \ + QCOMPARE(redo_action->text(), glue("bar", _redoText)); \ + canRedoChangedSpy.clear(); \ + redoTextChangedSpy.clear(); \ + } else { \ + QCOMPARE(canRedoChangedSpy.count(), 0); \ + QCOMPARE(redoTextChangedSpy.count(), 0); \ + } + +void tst_QUndoGroup::checkSignals() +{ + QUndoGroup group; + QAction *undo_action = group.createUndoAction(0, QString("foo")); + QAction *redo_action = group.createRedoAction(0, QString("bar")); + QSignalSpy indexChangedSpy(&group, SIGNAL(indexChanged(int))); + QSignalSpy cleanChangedSpy(&group, SIGNAL(cleanChanged(bool))); + QSignalSpy canUndoChangedSpy(&group, SIGNAL(canUndoChanged(bool))); + QSignalSpy undoTextChangedSpy(&group, SIGNAL(undoTextChanged(QString))); + QSignalSpy canRedoChangedSpy(&group, SIGNAL(canRedoChanged(bool))); + QSignalSpy redoTextChangedSpy(&group, SIGNAL(redoTextChanged(QString))); + + QString str; + + CHECK_STATE(0, // activeStack + true, // clean + false, // canUndo + "", // undoText + false, // canRedo + "", // redoText + false, // cleanChanged + false, // indexChanged + false, // undoChanged + false) // redoChanged + + group.undo(); + CHECK_STATE(0, // activeStack + true, // clean + false, // canUndo + "", // undoText + false, // canRedo + "", // redoText + false, // cleanChanged + false, // indexChanged + false, // undoChanged + false) // redoChanged + + group.redo(); + CHECK_STATE(0, // activeStack + true, // clean + false, // canUndo + "", // undoText + false, // canRedo + "", // redoText + false, // cleanChanged + false, // indexChanged + false, // undoChanged + false) // redoChanged + + QUndoStack *stack1 = new QUndoStack(&group); + CHECK_STATE(0, // activeStack + true, // clean + false, // canUndo + "", // undoText + false, // canRedo + "", // redoText + false, // cleanChanged + false, // indexChanged + false, // undoChanged + false) // redoChanged + + stack1->push(new AppendCommand(&str, "foo")); + CHECK_STATE(0, // activeStack + true, // clean + false, // canUndo + "", // undoText + false, // canRedo + "", // redoText + false, // cleanChanged + false, // indexChanged + false, // undoChanged + false) // redoChanged + + stack1->setActive(); + CHECK_STATE(stack1, // activeStack + false, // clean + true, // canUndo + "append", // undoText + false, // canRedo + "", // redoText + true, // cleanChanged + true, // indexChanged + true, // undoChanged + true) // redoChanged + + stack1->push(new InsertCommand(&str, 0, "bar")); + CHECK_STATE(stack1, // activeStack + false, // clean + true, // canUndo + "insert", // undoText + false, // canRedo + "", // redoText + false, // cleanChanged + true, // indexChanged + true, // undoChanged + true) // redoChanged + + stack1->undo(); + CHECK_STATE(stack1, // activeStack + false, // clean + true, // canUndo + "append", // undoText + true, // canRedo + "insert", // redoText + false, // cleanChanged + true, // indexChanged + true, // undoChanged + true) // redoChanged + + stack1->undo(); + CHECK_STATE(stack1, // activeStack + true, // clean + false, // canUndo + "", // undoText + true, // canRedo + "append", // redoText + true, // cleanChanged + true, // indexChanged + true, // undoChanged + true) // redoChanged + + stack1->undo(); + CHECK_STATE(stack1, // activeStack + true, // clean + false, // canUndo + "", // undoText + true, // canRedo + "append", // redoText + false, // cleanChanged + false, // indexChanged + false, // undoChanged + false) // redoChanged + + group.undo(); + CHECK_STATE(stack1, // activeStack + true, // clean + false, // canUndo + "", // undoText + true, // canRedo + "append", // redoText + false, // cleanChanged + false, // indexChanged + false, // undoChanged + false) // redoChanged + + group.redo(); + CHECK_STATE(stack1, // activeStack + false, // clean + true, // canUndo + "append", // undoText + true, // canRedo + "insert", // redoText + true, // cleanChanged + true, // indexChanged + true, // undoChanged + true) // redoChanged + + stack1->setActive(false); + CHECK_STATE(0, // activeStack + true, // clean + false, // canUndo + "", // undoText + false, // canRedo + "", // redoText + true, // cleanChanged + true, // indexChanged + true, // undoChanged + true) // redoChanged + + QUndoStack *stack2 = new QUndoStack(&group); + CHECK_STATE(0, // activeStack + true, // clean + false, // canUndo + "", // undoText + false, // canRedo + "", // redoText + false, // cleanChanged + false, // indexChanged + false, // undoChanged + false) // redoChanged + + stack2->setActive(); + CHECK_STATE(stack2, // activeStack + true, // clean + false, // canUndo + "", // undoText + false, // canRedo + "", // redoText + true, // cleanChanged + true, // indexChanged + true, // undoChanged + true) // redoChanged + + stack1->setActive(); + CHECK_STATE(stack1, // activeStack + false, // clean + true, // canUndo + "append", // undoText + true, // canRedo + "insert", // redoText + true, // cleanChanged + true, // indexChanged + true, // undoChanged + true) // redoChanged + + delete stack1; + CHECK_STATE(0, // activeStack + true, // clean + false, // canUndo + "", // undoText + false, // canRedo + "", // redoText + true, // cleanChanged + true, // indexChanged + true, // undoChanged + true) // redoChanged + + delete undo_action; + delete redo_action; +} + +void tst_QUndoGroup::addStackAndDie() +{ + // Test that QUndoStack doesn't keep a reference to QUndoGroup after the + // group is deleted. + QUndoStack *stack = new QUndoStack; + QUndoGroup *group = new QUndoGroup; + group->addStack(stack); + delete group; + stack->setActive(true); + delete stack; +} + +void tst_QUndoGroup::commandTextFormat() +{ + QString binDir = QLibraryInfo::location(QLibraryInfo::BinariesPath); + + if (QProcess::execute(binDir + "/lrelease -version") != 0) { + QSKIP("lrelease is missing or broken", SkipAll); + } + + QVERIFY(!QProcess::execute(binDir + "/lrelease testdata/qundogroup.ts")); + + QTranslator translator; + QVERIFY(translator.load("testdata/qundogroup.qm")); + qApp->installTranslator(&translator); + + QUndoGroup group; + QAction *undo_action = group.createUndoAction(0); + QAction *redo_action = group.createRedoAction(0); + + QCOMPARE(undo_action->text(), QString("Undo-default-text")); + QCOMPARE(redo_action->text(), QString("Redo-default-text")); + + QUndoStack stack(&group); + stack.setActive(); + QString str; + + stack.push(new AppendCommand(&str, "foo")); + QCOMPARE(undo_action->text(), QString("undo-prefix append undo-suffix")); + QCOMPARE(redo_action->text(), QString("Redo-default-text")); + + stack.push(new InsertCommand(&str, 0, "bar")); + stack.undo(); + QCOMPARE(undo_action->text(), QString("undo-prefix append undo-suffix")); + QCOMPARE(redo_action->text(), QString("redo-prefix insert redo-suffix")); + + stack.undo(); + QCOMPARE(undo_action->text(), QString("Undo-default-text")); + QCOMPARE(redo_action->text(), QString("redo-prefix append redo-suffix")); + + qApp->removeTranslator(&translator); +} + +#else +class tst_QUndoGroup : public QObject +{ + Q_OBJECT +public: + tst_QUndoGroup() {} + +private slots: + void setActive() { QSKIP( "Not tested on irix-g++", SkipAll); } + void addRemoveStack() { QSKIP( "Not tested on irix-g++", SkipAll); } + void deleteStack() { QSKIP( "Not tested on irix-g++", SkipAll); } + void checkSignals() { QSKIP( "Not tested on irix-g++", SkipAll); } + void addStackAndDie() { QSKIP( "Not tested on irix-g++", SkipAll); } +}; +#endif + +QTEST_MAIN(tst_QUndoGroup) + +#include "tst_qundogroup.moc" + |