summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorAnselmo L. S. Melo <anselmo.melo@openbossa.org>2012-02-21 17:55:26 -0300
committerAnselmo L. S. Melo <anselmo.melo@openbossa.org>2012-03-15 00:02:57 +0100
commitf588e0500ce411d82382c8f2515fee96891b44a3 (patch)
treedae1db7b6a756fc5bc3678c8aacd58201c16248f /tests
parent33a889873be75a9fac2a87585496cbde0947c5c8 (diff)
Undo framework tests
Tests added to UiHelpers Change-Id: I891c992e0e4d26d46539e9e9ee324968c8ae59d5 Reviewed-by: Anselmo L. S. Melo <anselmo.melo@openbossa.org>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/auto.pro4
-rw-r--r--tests/auto/undo/qundogroup/.gitignore1
-rw-r--r--tests/auto/undo/qundogroup/qundogroup.pro6
-rw-r--r--tests/auto/undo/qundogroup/testdata/qundogroup.ts25
-rw-r--r--tests/auto/undo/qundogroup/tst_qundogroup.cpp618
-rw-r--r--tests/auto/undo/qundostack/.gitignore1
-rw-r--r--tests/auto/undo/qundostack/qundostack.pro6
-rw-r--r--tests/auto/undo/qundostack/testdata/qundostack.ts25
-rw-r--r--tests/auto/undo/qundostack/tst_qundostack.cpp2748
-rw-r--r--tests/auto/undo/undo.pro4
-rw-r--r--tests/tests.pro3
11 files changed, 3441 insertions, 0 deletions
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
new file mode 100644
index 0000000..efb24c1
--- /dev/null
+++ b/tests/auto/auto.pro
@@ -0,0 +1,4 @@
+TEMPLATE = subdirs
+
+SUBDIRS += \
+ undo
diff --git a/tests/auto/undo/qundogroup/.gitignore b/tests/auto/undo/qundogroup/.gitignore
new file mode 100644
index 0000000..bc3e8c4
--- /dev/null
+++ b/tests/auto/undo/qundogroup/.gitignore
@@ -0,0 +1 @@
+tst_qundogroup
diff --git a/tests/auto/undo/qundogroup/qundogroup.pro b/tests/auto/undo/qundogroup/qundogroup.pro
new file mode 100644
index 0000000..a2d5e4a
--- /dev/null
+++ b/tests/auto/undo/qundogroup/qundogroup.pro
@@ -0,0 +1,6 @@
+CONFIG += testcase
+TARGET = tst_qundogroup
+
+QT += uihelpers testlib
+
+SOURCES += tst_qundogroup.cpp
diff --git a/tests/auto/undo/qundogroup/testdata/qundogroup.ts b/tests/auto/undo/qundogroup/testdata/qundogroup.ts
new file mode 100644
index 0000000..a059bcb
--- /dev/null
+++ b/tests/auto/undo/qundogroup/testdata/qundogroup.ts
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="en">
+<context>
+ <name>QUndoGroup</name>
+ <message>
+ <source>Undo %1</source>
+ <translation>undo-prefix %1 undo-suffix</translation>
+ </message>
+ <message>
+ <source>Undo</source>
+ <comment>Default text for undo action</comment>
+ <translation>Undo-default-text</translation>
+ </message>
+ <message>
+ <source>Redo %1</source>
+ <translation>redo-prefix %1 redo-suffix</translation>
+ </message>
+ <message>
+ <source>Redo</source>
+ <comment>Default text for redo action</comment>
+ <translation>Redo-default-text</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/undo/qundogroup/tst_qundogroup.cpp b/tests/auto/undo/qundogroup/tst_qundogroup.cpp
new file mode 100644
index 0000000..dff2cfa
--- /dev/null
+++ b/tests/auto/undo/qundogroup/tst_qundogroup.cpp
@@ -0,0 +1,618 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the UiHelpers playground module 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 <UiHelpers/QUndoGroup>
+#include <UiHelpers/QUndoStack>
+
+QT_USE_NAMESPACE_UIHELPERS
+
+// 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_QUndoGroup
+*/
+
+class tst_QUndoGroup : public QObject
+{
+ Q_OBJECT
+public:
+ tst_QUndoGroup();
+
+private slots:
+ void setActive();
+ void addRemoveStack();
+ void deleteStack();
+ void checkSignals();
+ void addStackAndDie();
+};
+
+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(undoTextChangedSpy.count(), 1); \
+ QCOMPARE(undoTextChangedSpy.at(0).at(0).toString(), QString(_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(redoTextChangedSpy.count(), 1); \
+ QCOMPARE(redoTextChangedSpy.at(0).at(0).toString(), QString(_redoText)); \
+ canRedoChangedSpy.clear(); \
+ redoTextChangedSpy.clear(); \
+ } else { \
+ QCOMPARE(canRedoChangedSpy.count(), 0); \
+ QCOMPARE(redoTextChangedSpy.count(), 0); \
+ }
+
+void tst_QUndoGroup::checkSignals()
+{
+ QUndoGroup group;
+ 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
+}
+
+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;
+}
+
+#else
+class tst_QUndoGroup : public QObject
+{
+ Q_OBJECT
+public:
+ tst_QUndoGroup() {}
+
+private slots:
+ void setActive() { QSKIP( "Not tested on irix-g++"); }
+ void addRemoveStack() { QSKIP( "Not tested on irix-g++"); }
+ void deleteStack() { QSKIP( "Not tested on irix-g++"); }
+ void checkSignals() { QSKIP( "Not tested on irix-g++"); }
+ void addStackAndDie() { QSKIP( "Not tested on irix-g++"); }
+};
+#endif
+
+QTEST_MAIN(tst_QUndoGroup)
+
+#include "tst_qundogroup.moc"
+
diff --git a/tests/auto/undo/qundostack/.gitignore b/tests/auto/undo/qundostack/.gitignore
new file mode 100644
index 0000000..f8faf27
--- /dev/null
+++ b/tests/auto/undo/qundostack/.gitignore
@@ -0,0 +1 @@
+tst_qundostack
diff --git a/tests/auto/undo/qundostack/qundostack.pro b/tests/auto/undo/qundostack/qundostack.pro
new file mode 100644
index 0000000..a1096a3
--- /dev/null
+++ b/tests/auto/undo/qundostack/qundostack.pro
@@ -0,0 +1,6 @@
+CONFIG += testcase
+TARGET = tst_qundostack
+
+QT += testlib uihelpers
+
+SOURCES += tst_qundostack.cpp
diff --git a/tests/auto/undo/qundostack/testdata/qundostack.ts b/tests/auto/undo/qundostack/testdata/qundostack.ts
new file mode 100644
index 0000000..4584036
--- /dev/null
+++ b/tests/auto/undo/qundostack/testdata/qundostack.ts
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="en">
+<context>
+ <name>QUndoStack</name>
+ <message>
+ <source>Undo %1</source>
+ <translation>undo-prefix %1 undo-suffix</translation>
+ </message>
+ <message>
+ <source>Undo</source>
+ <comment>Default text for undo action</comment>
+ <translation>Undo-default-text</translation>
+ </message>
+ <message>
+ <source>Redo %1</source>
+ <translation>redo-prefix %1 redo-suffix</translation>
+ </message>
+ <message>
+ <source>Redo</source>
+ <comment>Default text for redo action</comment>
+ <translation>Redo-default-text</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/undo/qundostack/tst_qundostack.cpp b/tests/auto/undo/qundostack/tst_qundostack.cpp
new file mode 100644
index 0000000..b3d95fd
--- /dev/null
+++ b/tests/auto/undo/qundostack/tst_qundostack.cpp
@@ -0,0 +1,2748 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the UiHelpers playground module 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 <UiHelpers/QUndoStack>
+
+QT_USE_NAMESPACE_UIHELPERS
+
+/******************************************************************************
+** 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, bool _fail_merge = false,
+ QUndoCommand *parent = 0);
+ ~AppendCommand();
+
+ virtual void undo();
+ virtual void redo();
+ virtual int id() const;
+ virtual bool mergeWith(const QUndoCommand *other);
+
+ bool merged;
+ bool fail_merge;
+ static int delete_cnt;
+
+private:
+ QString *m_str;
+ QString m_text;
+};
+
+class IdleCommand : public QUndoCommand
+{
+public:
+ IdleCommand(QUndoCommand *parent = 0);
+ ~IdleCommand();
+
+ virtual void undo();
+ virtual void redo();
+};
+
+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);
+}
+
+int AppendCommand::delete_cnt = 0;
+
+AppendCommand::AppendCommand(QString *str, const QString &text, bool _fail_merge,
+ QUndoCommand *parent)
+ : QUndoCommand(parent)
+{
+ setText("append");
+
+ m_str = str;
+ m_text = text;
+ merged = false;
+ fail_merge = _fail_merge;
+}
+
+AppendCommand::~AppendCommand()
+{
+ ++delete_cnt;
+}
+
+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;
+ if (fail_merge)
+ return false;
+ m_text += static_cast<const AppendCommand*>(other)->m_text;
+ merged = true;
+ return true;
+}
+
+IdleCommand::IdleCommand(QUndoCommand *parent)
+ : QUndoCommand(parent)
+{
+ // "idle-item" goes to QUndoStack::{redo,undo}Text
+ // "idle-action" goes to all other places (e.g. QUndoView)
+ setText("idle-item\nidle-action");
+}
+
+IdleCommand::~IdleCommand()
+{
+}
+
+void IdleCommand::redo()
+{
+}
+
+void IdleCommand::undo()
+{
+}
+
+/******************************************************************************
+** tst_QUndoStack
+*/
+
+class tst_QUndoStack : public QObject
+{
+ Q_OBJECT
+public:
+ tst_QUndoStack();
+
+private slots:
+ void undoRedo();
+ void setIndex();
+ void setClean();
+ void clear();
+ void childCommand();
+ void macroBeginEnd();
+ void compression();
+ void undoLimit();
+ void separateUndoText();
+};
+
+tst_QUndoStack::tst_QUndoStack()
+{
+}
+
+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;
+}
+
+static void checkState(QSignalSpy &redoTextChangedSpy,
+ QSignalSpy &canRedoChangedSpy,
+ QSignalSpy &undoTextChangedSpy,
+ QSignalSpy &canUndoChangedSpy,
+ QSignalSpy &cleanChangedSpy,
+ QSignalSpy &indexChangedSpy,
+ QUndoStack &stack,
+ const bool _clean,
+ const int _count,
+ const int _index,
+ const bool _canUndo,
+ const QString &_undoText,
+ const bool _canRedo,
+ const QString &_redoText,
+ const bool _cleanChanged,
+ const bool _indexChanged,
+ const bool _undoChanged,
+ const bool _redoChanged)
+{
+ QCOMPARE(stack.count(), _count);
+ QCOMPARE(stack.isClean(), _clean);
+ QCOMPARE(stack.index(), _index);
+ QCOMPARE(stack.canUndo(), _canUndo);
+ QCOMPARE(stack.undoText(), QString(_undoText));
+ QCOMPARE(stack.canRedo(), _canRedo);
+ QCOMPARE(stack.redoText(), QString(_redoText));
+ if (_indexChanged) {
+ QCOMPARE(indexChangedSpy.count(), 1);
+ QCOMPARE(indexChangedSpy.at(0).at(0).toInt(), _index);
+ 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(undoTextChangedSpy.count(), 1);
+ QCOMPARE(undoTextChangedSpy.at(0).at(0).toString(), QString(_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(redoTextChangedSpy.count(), 1);
+ QCOMPARE(redoTextChangedSpy.at(0).at(0).toString(), QString(_redoText));
+ canRedoChangedSpy.clear();
+ redoTextChangedSpy.clear();
+ } else {
+ QCOMPARE(canRedoChangedSpy.count(), 0);
+ QCOMPARE(redoTextChangedSpy.count(), 0);
+ }
+}
+
+void tst_QUndoStack::undoRedo()
+{
+ QUndoStack stack;
+ QSignalSpy indexChangedSpy(&stack, SIGNAL(indexChanged(int)));
+ QSignalSpy cleanChangedSpy(&stack, SIGNAL(cleanChanged(bool)));
+ QSignalSpy canUndoChangedSpy(&stack, SIGNAL(canUndoChanged(bool)));
+ QSignalSpy undoTextChangedSpy(&stack, SIGNAL(undoTextChanged(QString)));
+ QSignalSpy canRedoChangedSpy(&stack, SIGNAL(canRedoChanged(bool)));
+ QSignalSpy redoTextChangedSpy(&stack, SIGNAL(redoTextChanged(QString)));
+ QString str;
+
+ // push, undo, redo
+
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ true, // clean
+ 0, // count
+ 0, // index
+ false, // canUndo
+ "", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ false, // indexChanged
+ false, // undoChanged
+ false); // redoChanged
+
+ stack.undo(); // nothing to undo
+ QCOMPARE(str, QString());
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ true, // clean
+ 0, // count
+ 0, // index
+ false, // canUndo
+ "", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ false, // indexChanged
+ false, // undoChanged
+ false); // redoChanged
+
+ stack.push(new InsertCommand(&str, 0, "hello"));
+ QCOMPARE(str, QString("hello"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 1, // count
+ 1, // index
+ true, // canUndo
+ "insert", // undoText
+ false, // canRedo
+ "", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.push(new InsertCommand(&str, 2, "123"));
+ QCOMPARE(str, QString("he123llo"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 2, // index
+ true, // canUndo
+ "insert", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+
+ stack.undo();
+ QCOMPARE(str, QString("hello"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 1, // index
+ true, // canUndo
+ "insert", // undoText
+ true, // canRedo
+ "insert", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.redo();
+ QCOMPARE(str, QString("he123llo"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 2, // index
+ true, // canUndo
+ "insert", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.redo(); // nothing to redo
+ QCOMPARE(str, QString("he123llo"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 2, // index
+ true, // canUndo
+ "insert", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ false, // indexChanged
+ false, // undoChanged
+ false); // redoChanged
+
+ stack.undo();
+ QCOMPARE(str, QString("hello"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 1, // index
+ true, // canUndo
+ "insert", // undoText
+ true, // canRedo
+ "insert", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.undo();
+ QCOMPARE(str, QString());
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ true, // clean
+ 2, // count
+ 0, // index
+ false, // canUndo
+ "", // undoText
+ true, // canRedo
+ "insert", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.undo(); // nothing to undo
+ QCOMPARE(str, QString());
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ true, // clean
+ 2, // count
+ 0, // index
+ false, // canUndo
+ "", // undoText
+ true, // canRedo
+ "insert", // redoText
+ false, // cleanChanged
+ false, // indexChanged
+ false, // undoChanged
+ false); // redoChanged
+
+ // push after undo - check that undone commands get deleted
+
+ stack.redo();
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 1, // index
+ true, // canUndo
+ "insert", // undoText
+ true, // canRedo
+ "insert", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.push(new RemoveCommand(&str, 2, 2));
+ QCOMPARE(str, QString("heo"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count - still 2, last command got deleted
+ 2, // index
+ true, // canUndo
+ "remove", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.undo();
+ QCOMPARE(str, QString("hello"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 1, // index
+ true, // canUndo
+ "insert", // undoText
+ true, // canRedo
+ "remove", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.undo();
+ QCOMPARE(str, QString());
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ true, // clean
+ 2, // count
+ 0, // index
+ false, // canUndo
+ "", // undoText
+ true, // canRedo
+ "insert", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.push(new InsertCommand(&str, 0, "goodbye"));
+ QCOMPARE(str, QString("goodbye"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 1, // count - two commands got deleted
+ 1, // index
+ true, // canUndo
+ "insert", // undoText
+ false, // canRedo
+ "", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+}
+
+void tst_QUndoStack::setIndex()
+{
+ QUndoStack stack;
+ QSignalSpy indexChangedSpy(&stack, SIGNAL(indexChanged(int)));
+ QSignalSpy cleanChangedSpy(&stack, SIGNAL(cleanChanged(bool)));
+ QSignalSpy canUndoChangedSpy(&stack, SIGNAL(canUndoChanged(bool)));
+ QSignalSpy undoTextChangedSpy(&stack, SIGNAL(undoTextChanged(QString)));
+ QSignalSpy canRedoChangedSpy(&stack, SIGNAL(canRedoChanged(bool)));
+ QSignalSpy redoTextChangedSpy(&stack, SIGNAL(redoTextChanged(QString)));
+ QString str;
+
+ stack.setIndex(10); // should do nothing
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ true, // clean
+ 0, // count
+ 0, // index
+ false, // canUndo
+ "", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ false, // indexChanged
+ false, // undoChanged
+ false); // redoChanged
+
+ stack.setIndex(0); // should do nothing
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ true, // clean
+ 0, // count
+ 0, // index
+ false, // canUndo
+ "", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ false, // indexChanged
+ false, // undoChanged
+ false); // redoChanged
+
+ stack.setIndex(-10); // should do nothing
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ true, // clean
+ 0, // count
+ 0, // index
+ false, // canUndo
+ "", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ false, // indexChanged
+ false, // undoChanged
+ false); // redoChanged
+
+ stack.push(new InsertCommand(&str, 0, "hello"));
+ QCOMPARE(str, QString("hello"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 1, // count
+ 1, // index
+ true, // canUndo
+ "insert", // undoText
+ false, // canRedo
+ "", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.push(new InsertCommand(&str, 2, "123"));
+ QCOMPARE(str, QString("he123llo"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 2, // index
+ true, // canUndo
+ "insert", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.setIndex(2);
+ QCOMPARE(str, QString("he123llo"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 2, // index
+ true, // canUndo
+ "insert", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ false, // indexChanged
+ false, // undoChanged
+ false); // redoChanged
+
+ stack.setIndex(0);
+ QCOMPARE(str, QString());
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ true, // clean
+ 2, // count
+ 0, // index
+ false, // canUndo
+ "", // undoText
+ true, // canRedo
+ "insert", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.setIndex(10); // should set index to 2
+ QCOMPARE(str, QString("he123llo"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 2, // index
+ true, // canUndo
+ "insert", // undoText
+ false, // canRedo
+ "", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.setIndex(-10); // should set index to 0
+ QCOMPARE(str, QString());
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ true, // clean
+ 2, // count
+ 0, // index
+ false, // canUndo
+ "", // undoText
+ true, // canRedo
+ "insert", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.setIndex(1);
+ QCOMPARE(str, QString("hello"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 1, // index
+ true, // canUndo
+ "insert", // undoText
+ true, // canRedo
+ "insert", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.setIndex(2);
+ QCOMPARE(str, QString("he123llo"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 2, // index
+ true, // canUndo
+ "insert", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+}
+
+void tst_QUndoStack::setClean()
+{
+ QUndoStack stack;
+ QSignalSpy indexChangedSpy(&stack, SIGNAL(indexChanged(int)));
+ QSignalSpy cleanChangedSpy(&stack, SIGNAL(cleanChanged(bool)));
+ QSignalSpy canUndoChangedSpy(&stack, SIGNAL(canUndoChanged(bool)));
+ QSignalSpy undoTextChangedSpy(&stack, SIGNAL(undoTextChanged(QString)));
+ QSignalSpy canRedoChangedSpy(&stack, SIGNAL(canRedoChanged(bool)));
+ QSignalSpy redoTextChangedSpy(&stack, SIGNAL(redoTextChanged(QString)));
+ QString str;
+
+ QCOMPARE(stack.cleanIndex(), 0);
+ stack.setClean();
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ true, // clean
+ 0, // count
+ 0, // index
+ false, // canUndo
+ "", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ false, // indexChanged
+ false, // undoChanged
+ false); // redoChanged
+ QCOMPARE(stack.cleanIndex(), 0);
+
+ stack.push(new InsertCommand(&str, 0, "goodbye"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 1, // count
+ 1, // index
+ true, // canUndo
+ "insert", // undoText
+ false, // canRedo
+ "", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+ QCOMPARE(stack.cleanIndex(), 0);
+
+ stack.setClean();
+ QCOMPARE(str, QString("goodbye"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ true, // clean
+ 1, // count
+ 1, // index
+ true, // canUndo
+ "insert", // undoText
+ false, // canRedo
+ "", // redoText
+ true, // cleanChanged
+ false, // indexChanged
+ false, // undoChanged
+ false); // redoChanged
+ QCOMPARE(stack.cleanIndex(), 1);
+
+ stack.push(new AppendCommand(&str, " cowboy"));
+ QCOMPARE(str, QString("goodbye cowboy"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 2, // index
+ true, // canUndo
+ "append", // undoText
+ false, // canRedo
+ "", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+ QCOMPARE(stack.cleanIndex(), 1);
+
+ stack.undo(); // reaching clean state from above
+ QCOMPARE(str, QString("goodbye"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ true, // clean
+ 2, // count
+ 1, // index
+ true, // canUndo
+ "insert", // undoText
+ true, // canRedo
+ "append", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+ QCOMPARE(stack.cleanIndex(), 1);
+
+ stack.undo();
+ QCOMPARE(str, QString());
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 0, // index
+ false, // canUndo
+ "", // undoText
+ true, // canRedo
+ "insert", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+ QCOMPARE(stack.cleanIndex(), 1);
+
+ stack.redo(); // reaching clean state from below
+ QCOMPARE(str, QString("goodbye"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ true, // clean
+ 2, // count
+ 1, // index
+ true, // canUndo
+ "insert", // undoText
+ true, // canRedo
+ "append", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+ QCOMPARE(stack.cleanIndex(), 1);
+
+ stack.undo();
+ QCOMPARE(str, QString());
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 0, // index
+ false, // canUndo
+ "", // undoText
+ true, // canRedo
+ "insert", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+ QCOMPARE(stack.cleanIndex(), 1);
+
+ stack.push(new InsertCommand(&str, 0, "foo")); // the clean state gets deleted!
+ QCOMPARE(str, QString("foo"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 1, // count
+ 1, // index
+ true, // canUndo
+ "insert", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+ QCOMPARE(stack.cleanIndex(), -1);
+
+ stack.undo();
+ QCOMPARE(str, QString());
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 1, // count
+ 0, // index
+ false, // canUndo
+ "", // undoText
+ true, // canRedo
+ "insert", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+ QCOMPARE(stack.cleanIndex(), -1);
+}
+
+void tst_QUndoStack::clear()
+{
+ QUndoStack stack;
+ QSignalSpy indexChangedSpy(&stack, SIGNAL(indexChanged(int)));
+ QSignalSpy cleanChangedSpy(&stack, SIGNAL(cleanChanged(bool)));
+ QSignalSpy canUndoChangedSpy(&stack, SIGNAL(canUndoChanged(bool)));
+ QSignalSpy undoTextChangedSpy(&stack, SIGNAL(undoTextChanged(QString)));
+ QSignalSpy canRedoChangedSpy(&stack, SIGNAL(canRedoChanged(bool)));
+ QSignalSpy redoTextChangedSpy(&stack, SIGNAL(redoTextChanged(QString)));
+ QString str;
+
+ stack.clear();
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ true, // clean
+ 0, // count
+ 0, // index
+ false, // canUndo
+ "", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ false, // indexChanged
+ false, // undoChanged
+ false); // redoChanged
+
+ stack.push(new InsertCommand(&str, 0, "hello"));
+ QCOMPARE(str, QString("hello"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 1, // count
+ 1, // index
+ true, // canUndo
+ "insert", // undoText
+ false, // canRedo
+ "", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.push(new InsertCommand(&str, 2, "123"));
+ QCOMPARE(str, QString("he123llo"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 2, // index
+ true, // canUndo
+ "insert", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.clear();
+ QCOMPARE(str, QString("he123llo"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ true, // clean
+ 0, // count
+ 0, // index
+ false, // canUndo
+ "", // undoText
+ false, // canRedo
+ "", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ str.clear();
+ stack.push(new InsertCommand(&str, 0, "hello"));
+ QCOMPARE(str, QString("hello"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 1, // count
+ 1, // index
+ true, // canUndo
+ "insert", // undoText
+ false, // canRedo
+ "", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.push(new InsertCommand(&str, 2, "123"));
+ QCOMPARE(str, QString("he123llo"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 2, // index
+ true, // canUndo
+ "insert", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.setIndex(0);
+ QCOMPARE(str, QString());
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ true, // clean
+ 2, // count
+ 0, // index
+ false, // canUndo
+ "", // undoText
+ true, // canRedo
+ "insert", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.clear();
+ QCOMPARE(str, QString());
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ true, // clean
+ 0, // count
+ 0, // index
+ false, // canUndo
+ "", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+}
+
+void tst_QUndoStack::childCommand()
+{
+ QUndoStack stack;
+ QSignalSpy indexChangedSpy(&stack, SIGNAL(indexChanged(int)));
+ QSignalSpy cleanChangedSpy(&stack, SIGNAL(cleanChanged(bool)));
+ QSignalSpy canUndoChangedSpy(&stack, SIGNAL(canUndoChanged(bool)));
+ QSignalSpy undoTextChangedSpy(&stack, SIGNAL(undoTextChanged(QString)));
+ QSignalSpy canRedoChangedSpy(&stack, SIGNAL(canRedoChanged(bool)));
+ QSignalSpy redoTextChangedSpy(&stack, SIGNAL(redoTextChanged(QString)));
+ QString str;
+
+ stack.push(new InsertCommand(&str, 0, "hello"));
+ QCOMPARE(str, QString("hello"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 1, // count
+ 1, // index
+ true, // canUndo
+ "insert", // undoText
+ false, // canRedo
+ "", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ QUndoCommand *cmd = new QUndoCommand();
+ cmd->setText("ding");
+ new InsertCommand(&str, 5, "world", cmd);
+ new RemoveCommand(&str, 4, 1, cmd);
+ stack.push(cmd);
+ QCOMPARE(str, QString("hellworld"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 2, // index
+ true, // canUndo
+ "ding", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.undo();
+ QCOMPARE(str, QString("hello"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 1, // index
+ true, // canUndo
+ "insert", // undoText
+ true, // canRedo
+ "ding", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.redo();
+ QCOMPARE(str, QString("hellworld"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 2, // index
+ true, // canUndo
+ "ding", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+}
+
+void tst_QUndoStack::macroBeginEnd()
+{
+ QUndoStack stack;
+ QSignalSpy indexChangedSpy(&stack, SIGNAL(indexChanged(int)));
+ QSignalSpy cleanChangedSpy(&stack, SIGNAL(cleanChanged(bool)));
+ QSignalSpy canUndoChangedSpy(&stack, SIGNAL(canUndoChanged(bool)));
+ QSignalSpy undoTextChangedSpy(&stack, SIGNAL(undoTextChanged(QString)));
+ QSignalSpy canRedoChangedSpy(&stack, SIGNAL(canRedoChanged(bool)));
+ QSignalSpy redoTextChangedSpy(&stack, SIGNAL(redoTextChanged(QString)));
+ QString str;
+
+ stack.beginMacro("ding");
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 1, // count
+ 0, // index
+ false, // canUndo
+ "", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ false, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.setClean(); // should do nothing
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 1, // count
+ 0, // index
+ false, // canUndo
+ "", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ false, // indexChanged
+ false, // undoChanged
+ false); // redoChanged
+
+ stack.undo(); // should do nothing
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 1, // count
+ 0, // index
+ false, // canUndo
+ "", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ false, // indexChanged
+ false, // undoChanged
+ false); // redoChanged
+
+ stack.redo(); // should do nothing
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 1, // count
+ 0, // index
+ false, // canUndo
+ "", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ false, // indexChanged
+ false, // undoChanged
+ false); // redoChanged
+
+ stack.setIndex(0); // should do nothing
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 1, // count
+ 0, // index
+ false, // canUndo
+ "", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ false, // indexChanged
+ false, // undoChanged
+ false); // redoChanged
+
+ stack.endMacro();
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 1, // count
+ 1, // index - endMacro() increments index
+ true, // canUndo
+ "ding", // undoText
+ false, // canRedo
+ "", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.push(new InsertCommand(&str, 0, "h"));
+ QCOMPARE(str, QString("h"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 2, // index
+ true, // canUndo
+ "insert", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.push(new InsertCommand(&str, 1, "owdy"));
+ QCOMPARE(str, QString("howdy"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 3, // count
+ 3, // index
+ true, // canUndo
+ "insert", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.setIndex(2);
+ QCOMPARE(str, QString("h"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 3, // count
+ 2, // index
+ true, // canUndo
+ "insert", // undoText
+ true, // canRedo
+ "insert", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.beginMacro("dong"); // the "owdy" command gets deleted
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 3, // count
+ 2, // index
+ false, // canUndo
+ "", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ false, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.push(new InsertCommand(&str, 1, "ello"));
+ QCOMPARE(str, QString("hello"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 3, // count
+ 2, // index
+ false, // canUndo
+ "", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ false, // indexChanged
+ false, // undoChanged
+ false); // redoChanged
+
+ stack.push(new RemoveCommand(&str, 1, 2));
+ QCOMPARE(str, QString("hlo"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 3, // count
+ 2, // index
+ false, // canUndo
+ "", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ false, // indexChanged
+ false, // undoChanged
+ false); // redoChanged
+
+ stack.beginMacro("dong2");
+ QCOMPARE(str, QString("hlo"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 3, // count
+ 2, // index
+ false, // canUndo
+ "", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ false, // indexChanged
+ false, // undoChanged
+ false); // redoChanged
+
+ stack.push(new RemoveCommand(&str, 1, 1));
+ QCOMPARE(str, QString("ho"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 3, // count
+ 2, // index
+ false, // canUndo
+ "", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ false, // indexChanged
+ false, // undoChanged
+ false); // redoChanged
+
+ stack.endMacro();
+ QCOMPARE(str, QString("ho"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 3, // count
+ 2, // index
+ false, // canUndo
+ "", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ false, // indexChanged
+ false, // undoChanged
+ false); // redoChanged
+
+ stack.endMacro();
+ QCOMPARE(str, QString("ho"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 3, // count
+ 3, // index
+ true, // canUndo
+ "dong", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.undo();
+ QCOMPARE(str, QString("h"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 3, // count
+ 2, // index
+ true, // canUndo
+ "insert", // undoText
+ true, // canRedo
+ "dong", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.undo();
+ QCOMPARE(str, QString(""));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 3, // count
+ 1, // index
+ true, // canUndo
+ "ding", // undoText
+ true, // canRedo
+ "insert", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.setIndex(3);
+ QCOMPARE(str, QString("ho"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 3, // count
+ 3, // index
+ true, // canUndo
+ "dong", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.setIndex(1);
+ QCOMPARE(str, QString());
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 3, // count
+ 1, // index
+ true, // canUndo
+ "ding", // undoText
+ true, // canRedo
+ "insert", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+}
+
+void tst_QUndoStack::compression()
+{
+ QUndoStack stack;
+ QSignalSpy indexChangedSpy(&stack, SIGNAL(indexChanged(int)));
+ QSignalSpy cleanChangedSpy(&stack, SIGNAL(cleanChanged(bool)));
+ QSignalSpy canUndoChangedSpy(&stack, SIGNAL(canUndoChanged(bool)));
+ QSignalSpy undoTextChangedSpy(&stack, SIGNAL(undoTextChanged(QString)));
+ QSignalSpy canRedoChangedSpy(&stack, SIGNAL(canRedoChanged(bool)));
+ QSignalSpy redoTextChangedSpy(&stack, SIGNAL(redoTextChanged(QString)));
+ QString str;
+
+ AppendCommand::delete_cnt = 0;
+
+ stack.push(new InsertCommand(&str, 0, "ene"));
+ QCOMPARE(str, QString("ene"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 1, // count
+ 1, // index
+ true, // canUndo
+ "insert", // undoText
+ false, // canRedo
+ "", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.push(new AppendCommand(&str, " due")); // #1
+ QCOMPARE(str, QString("ene due"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 2, // index
+ true, // canUndo
+ "append", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.push(new AppendCommand(&str, " rike")); // #2 should merge
+ QCOMPARE(str, QString("ene due rike"));
+ QCOMPARE(AppendCommand::delete_cnt, 1); // #2 should be deleted
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 2, // index
+ true, // canUndo
+ "append", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.setClean();
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ true, // clean
+ 2, // count
+ 2, // index
+ true, // canUndo
+ "append", // undoText
+ false, // canRedo
+ "", // redoText
+ true, // cleanChanged
+ false, // indexChanged
+ false, // undoChanged
+ false); // redoChanged
+
+ stack.push(new AppendCommand(&str, " fake")); // #3 should NOT merge, since the stack was clean
+ QCOMPARE(str, QString("ene due rike fake")); // and we want to be able to return to this state
+ QCOMPARE(AppendCommand::delete_cnt, 1); // #3 should not be deleted
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 3, // count
+ 3, // index
+ true, // canUndo
+ "append", // undoText
+ false, // canRedo
+ "", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.undo();
+ QCOMPARE(str, QString("ene due rike"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ true, // clean
+ 3, // count
+ 2, // index
+ true, // canUndo
+ "append", // undoText
+ true, // canRedo
+ "append", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.undo();
+ QCOMPARE(str, QString("ene"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 3, // count
+ 1, // index
+ true, // canUndo
+ "insert", // undoText
+ true, // canRedo
+ "append", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.push(new AppendCommand(&str, "ma", true)); // #4 clean state gets deleted!
+ QCOMPARE(str, QString("enema"));
+ QCOMPARE(AppendCommand::delete_cnt, 3); // #1 got deleted
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 2, // index
+ true, // canUndo
+ "append", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.push(new AppendCommand(&str, "trix")); // #5 should NOT merge
+ QCOMPARE(str, QString("enematrix"));
+ QCOMPARE(AppendCommand::delete_cnt, 3);
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 3, // count
+ 3, // index
+ true, // canUndo
+ "append", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.undo();
+ QCOMPARE(str, QString("enema"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 3, // count
+ 2, // index
+ true, // canUndo
+ "append", // undoText
+ true, // canRedo
+ "append", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ // and now for command compression inside macros
+
+ stack.setClean();
+ QCOMPARE(str, QString("enema"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ true, // clean
+ 3, // count
+ 2, // index
+ true, // canUndo
+ "append", // undoText
+ true, // canRedo
+ "append", // redoText
+ true, // cleanChanged
+ false, // indexChanged
+ false, // undoChanged
+ false); // redoChanged
+
+ stack.beginMacro("ding");
+ QCOMPARE(str, QString("enema"));
+ QCOMPARE(AppendCommand::delete_cnt, 4); // #5 gets deleted
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 3, // count
+ 2, // index
+ false, // canUndo
+ "", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ false, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ AppendCommand *merge_cmd = new AppendCommand(&str, "top");
+ stack.push(merge_cmd); // #6
+ QCOMPARE(merge_cmd->merged, false);
+ QCOMPARE(str, QString("enematop"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 3, // count
+ 2, // index
+ false, // canUndo
+ "", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ false, // indexChanged
+ false, // undoChanged
+ false); // redoChanged
+
+ stack.push(new AppendCommand(&str, "eja")); // #7 should merge
+ QCOMPARE(str, QString("enematopeja"));
+ QCOMPARE(merge_cmd->merged, true);
+ QCOMPARE(AppendCommand::delete_cnt, 5); // #7 gets deleted
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 3, // count
+ 2, // index
+ false, // canUndo
+ "", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ false, // indexChanged
+ false, // undoChanged
+ false); // redoChanged
+ merge_cmd->merged = false;
+
+ stack.push(new InsertCommand(&str, 2, "123")); // should not merge
+ QCOMPARE(str, QString("en123ematopeja"));
+ QCOMPARE(merge_cmd->merged, false);
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 3, // count
+ 2, // index
+ false, // canUndo
+ "", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ false, // indexChanged
+ false, // undoChanged
+ false); // redoChanged
+
+ stack.endMacro();
+ QCOMPARE(str, QString("en123ematopeja"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 3, // count
+ 3, // index
+ true, // canUndo
+ "ding", // undoText
+ false, // canRedo
+ "", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.undo();
+ QCOMPARE(str, QString("enema"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ true, // clean
+ 3, // count
+ 2, // index
+ true, // canUndo
+ "append", // undoText
+ true, // canRedo
+ "ding", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.redo();
+ QCOMPARE(str, QString("en123ematopeja"));
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 3, // count
+ 3, // index
+ true, // canUndo
+ "ding", // undoText
+ false, // canRedo
+ "", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+}
+
+void tst_QUndoStack::undoLimit()
+{
+ QUndoStack stack;
+ QSignalSpy indexChangedSpy(&stack, SIGNAL(indexChanged(int)));
+ QSignalSpy cleanChangedSpy(&stack, SIGNAL(cleanChanged(bool)));
+ QSignalSpy canUndoChangedSpy(&stack, SIGNAL(canUndoChanged(bool)));
+ QSignalSpy undoTextChangedSpy(&stack, SIGNAL(undoTextChanged(QString)));
+ QSignalSpy canRedoChangedSpy(&stack, SIGNAL(canRedoChanged(bool)));
+ QSignalSpy redoTextChangedSpy(&stack, SIGNAL(redoTextChanged(QString)));
+ AppendCommand::delete_cnt = 0;
+ QString str;
+
+ QCOMPARE(stack.undoLimit(), 0);
+ stack.setUndoLimit(2);
+ QCOMPARE(stack.undoLimit(), 2);
+
+ stack.push(new AppendCommand(&str, "1", true));
+ QCOMPARE(str, QString("1"));
+ QCOMPARE(AppendCommand::delete_cnt, 0);
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 1, // count
+ 1, // index
+ true, // canUndo
+ "append", // undoText
+ false, // canRedo
+ "", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.push(new AppendCommand(&str, "2", true));
+ QCOMPARE(str, QString("12"));
+ QCOMPARE(AppendCommand::delete_cnt, 0);
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 2, // index
+ true, // canUndo
+ "append", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.setClean();
+ QCOMPARE(str, QString("12"));
+ QCOMPARE(AppendCommand::delete_cnt, 0);
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ true, // clean
+ 2, // count
+ 2, // index
+ true, // canUndo
+ "append", // undoText
+ false, // canRedo
+ "", // redoText
+ true, // cleanChanged
+ false, // indexChanged
+ false, // undoChanged
+ false); // redoChanged
+
+ stack.push(new AppendCommand(&str, "3", true));
+ QCOMPARE(str, QString("123"));
+ QCOMPARE(AppendCommand::delete_cnt, 1);
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 2, // index
+ true, // canUndo
+ "append", // undoText
+ false, // canRedo
+ "", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.push(new AppendCommand(&str, "4", true));
+ QCOMPARE(str, QString("1234"));
+ QCOMPARE(AppendCommand::delete_cnt, 2);
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 2, // index
+ true, // canUndo
+ "append", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.undo();
+ QCOMPARE(str, QString("123"));
+ QCOMPARE(AppendCommand::delete_cnt, 2);
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 1, // index
+ true, // canUndo
+ "append", // undoText
+ true, // canRedo
+ "append", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.undo();
+ QCOMPARE(str, QString("12"));
+ QCOMPARE(AppendCommand::delete_cnt, 2);
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ true, // clean
+ 2, // count
+ 0, // index
+ false, // canUndo
+ "", // undoText
+ true, // canRedo
+ "append", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.push(new AppendCommand(&str, "3", true));
+ QCOMPARE(str, QString("123"));
+ QCOMPARE(AppendCommand::delete_cnt, 4);
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 1, // count
+ 1, // index
+ true, // canUndo
+ "append", // undoText
+ false, // canRedo
+ "", // redoText
+ true, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.push(new AppendCommand(&str, "4", true));
+ QCOMPARE(str, QString("1234"));
+ QCOMPARE(AppendCommand::delete_cnt, 4);
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 2, // index
+ true, // canUndo
+ "append", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.push(new AppendCommand(&str, "5", true));
+ QCOMPARE(str, QString("12345"));
+ QCOMPARE(AppendCommand::delete_cnt, 5);
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 2, // index
+ true, // canUndo
+ "append", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.undo();
+ QCOMPARE(str, QString("1234"));
+ QCOMPARE(AppendCommand::delete_cnt, 5);
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 1, // index
+ true, // canUndo
+ "append", // undoText
+ true, // canRedo
+ "append", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.undo();
+ QCOMPARE(str, QString("123"));
+ QCOMPARE(AppendCommand::delete_cnt, 5);
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 0, // index
+ false, // canUndo
+ "", // undoText
+ true, // canRedo
+ "append", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.push(new AppendCommand(&str, "4", true));
+ QCOMPARE(str, QString("1234"));
+ QCOMPARE(AppendCommand::delete_cnt, 7);
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 1, // count
+ 1, // index
+ true, // canUndo
+ "append", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.push(new AppendCommand(&str, "5"));
+ QCOMPARE(str, QString("12345"));
+ QCOMPARE(AppendCommand::delete_cnt, 7);
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 2, // index
+ true, // canUndo
+ "append", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.push(new AppendCommand(&str, "6", true)); // should be merged
+ QCOMPARE(str, QString("123456"));
+ QCOMPARE(AppendCommand::delete_cnt, 8);
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 2, // index
+ true, // canUndo
+ "append", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.beginMacro("foo");
+ QCOMPARE(str, QString("123456"));
+ QCOMPARE(AppendCommand::delete_cnt, 8);
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 3, // count
+ 2, // index
+ false, // canUndo
+ "", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ false, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.push(new AppendCommand(&str, "7", true));
+ QCOMPARE(str, QString("1234567"));
+ QCOMPARE(AppendCommand::delete_cnt, 8);
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 3, // count
+ 2, // index
+ false, // canUndo
+ "", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ false, // indexChanged
+ false, // undoChanged
+ false); // redoChanged
+
+ stack.push(new AppendCommand(&str, "8"));
+ QCOMPARE(str, QString("12345678"));
+ QCOMPARE(AppendCommand::delete_cnt, 8);
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 3, // count
+ 2, // index
+ false, // canUndo
+ "", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ false, // indexChanged
+ false, // undoChanged
+ false); // redoChanged
+
+ stack.endMacro();
+ QCOMPARE(str, QString("12345678"));
+ QCOMPARE(AppendCommand::delete_cnt, 9);
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 2, // index
+ true, // canUndo
+ "foo", // undoText
+ false, // canRedo
+ "", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.undo();
+ QCOMPARE(str, QString("123456"));
+ QCOMPARE(AppendCommand::delete_cnt, 9);
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 1, // index
+ true, // canUndo
+ "append", // undoText
+ true, // canRedo
+ "foo", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+
+ stack.undo();
+ QCOMPARE(str, QString("1234"));
+ QCOMPARE(AppendCommand::delete_cnt, 9);
+ checkState(redoTextChangedSpy,
+ canRedoChangedSpy,
+ undoTextChangedSpy,
+ canUndoChangedSpy,
+ cleanChangedSpy,
+ indexChangedSpy,
+ stack,
+ false, // clean
+ 2, // count
+ 0, // index
+ false, // canUndo
+ "", // undoText
+ true, // canRedo
+ "append", // redoText
+ false, // cleanChanged
+ true, // indexChanged
+ true, // undoChanged
+ true); // redoChanged
+}
+
+void tst_QUndoStack::separateUndoText()
+{
+ QUndoStack stack;
+
+ QUndoCommand *command1 = new IdleCommand();
+ QUndoCommand *command2 = new IdleCommand();
+ stack.push(command1);
+ stack.push(command2);
+ stack.undo();
+
+ QCOMPARE(command1->actionText(), QString("idle-action"));
+
+ QCOMPARE(command1->text(), QString("idle-item"));
+ QCOMPARE(stack.text(0), QString("idle-item"));
+
+ command1->setText("idle");
+ QCOMPARE(command1->actionText(), QString("idle"));
+ QCOMPARE(command1->text(), QString("idle"));
+
+ command1->setText("idle-item\nidle-action");
+ QCOMPARE(command1->actionText(), QString("idle-action"));
+ QCOMPARE(command1->text(), QString("idle-item"));
+}
+
+QTEST_MAIN(tst_QUndoStack)
+
+#include "tst_qundostack.moc"
diff --git a/tests/auto/undo/undo.pro b/tests/auto/undo/undo.pro
new file mode 100644
index 0000000..2a70804
--- /dev/null
+++ b/tests/auto/undo/undo.pro
@@ -0,0 +1,4 @@
+TEMPLATE=subdirs
+SUBDIRS=\
+ qundogroup \
+ qundostack \
diff --git a/tests/tests.pro b/tests/tests.pro
new file mode 100644
index 0000000..b8445a7
--- /dev/null
+++ b/tests/tests.pro
@@ -0,0 +1,3 @@
+TEMPLATE = subdirs
+SUBDIRS = \
+ auto