tests/auto/qtextcursor/tst_qtextcursor.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/auto/qtextcursor/tst_qtextcursor.cpp	Mon Jan 11 14:00:40 2010 +0000
@@ -0,0 +1,1756 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+
+
+#include <qtextdocument.h>
+#include <qtexttable.h>
+#include <qvariant.h>
+#include <qtextdocumentfragment.h>
+#include <qabstracttextdocumentlayout.h>
+#include <qtextlayout.h>
+#include <qtextcursor.h>
+#include <qdebug.h>
+
+//TESTED_FILES=gui/text/qtextcursor.cpp gui/text/qtextcursor_p.h
+
+QT_FORWARD_DECLARE_CLASS(QTextDocument)
+
+class tst_QTextCursor : public QObject
+{
+    Q_OBJECT
+
+public:
+    tst_QTextCursor();
+
+
+public slots:
+    void init();
+    void cleanup();
+private slots:
+    void navigation1();
+    void navigation2_data();
+    void navigation2();
+    void navigation3();
+    void navigation4();
+    void navigation5();
+    void navigation6();
+    void navigation7();
+    void navigation8();
+    void navigation9();
+    void navigation10();
+    void movePositionEndOfLine();
+    void insertBlock();
+    void insertWithBlockSeparator1();
+    void insertWithBlockSeparator2();
+    void insertWithBlockSeparator3();
+    void insertWithBlockSeparator4();
+    void clearObjectType1();
+    void clearObjectType2();
+    void clearObjectType3();
+    void comparisonOperators1();
+    void comparisonOperators2();
+    void selection1();
+    void dontCopyTableAttributes();
+
+    void checkFrame1();
+    void checkFrame2();
+
+    void tableMovement();
+    void selectionsInTable();
+
+    void insertBlockToUseCharFormat();
+
+    void selectedText();
+
+    void insertBlockShouldRemoveSelection();
+    void insertBlockShouldRemoveSelection2();
+    void mergeCellShouldUpdateSelection();
+
+    void joinPreviousEditBlock();
+
+    void setBlockFormatInTable();
+
+    void blockCharFormat();
+    void blockCharFormat2();
+    void blockCharFormat3();
+    void blockCharFormatOnSelection();
+
+    void anchorInitialized1();
+    void anchorInitialized2();
+    void anchorInitialized3();
+
+    void selectWord();
+    void selectWordWithSeparators_data();
+    void selectWordWithSeparators();
+    void startOfWord();
+    void selectBlock();
+    void selectVisually();
+
+    void insertText();
+
+    void insertFragmentShouldUseCurrentCharFormat();
+
+    void endOfLine();
+
+    void editBlocksDuringRemove();
+
+    void update_data();
+    void update();
+
+    void disallowSettingObjectIndicesOnCharFormats();
+
+    void blockAndColumnNumber();
+
+    void clearCells();
+
+    void task244408_wordUnderCursor_data();
+    void task244408_wordUnderCursor();
+
+    void adjustCursorsOnInsert();
+
+private:
+    int blockCount();
+
+    QTextDocument *doc;
+    QTextCursor cursor;
+};
+
+Q_DECLARE_METATYPE(QList<QVariant>)
+
+tst_QTextCursor::tst_QTextCursor()
+{}
+
+void tst_QTextCursor::init()
+{
+    doc = new QTextDocument;
+    cursor = QTextCursor(doc);
+}
+
+void tst_QTextCursor::cleanup()
+{
+    cursor = QTextCursor();
+    delete doc;
+    doc = 0;
+}
+
+void tst_QTextCursor::navigation1()
+{
+
+    cursor.insertText("Hello World");
+    QVERIFY(doc->toPlainText() == "Hello World");
+
+    cursor.movePosition(QTextCursor::End);
+    QVERIFY(cursor.position() == 11);
+    cursor.deletePreviousChar();
+    QVERIFY(cursor.position() == 10);
+    cursor.deletePreviousChar();
+    cursor.deletePreviousChar();
+    cursor.deletePreviousChar();
+    cursor.deletePreviousChar();
+    cursor.deletePreviousChar();
+    QVERIFY(doc->toPlainText() == "Hello");
+
+    QTextCursor otherCursor(doc);
+    otherCursor.movePosition(QTextCursor::Start);
+    otherCursor.movePosition(QTextCursor::Right);
+    cursor = otherCursor;
+    cursor.movePosition(QTextCursor::Right);
+    QVERIFY(cursor != otherCursor);
+    otherCursor.insertText("Hey");
+    QVERIFY(cursor.position() == 5);
+
+    doc->undo();
+    QVERIFY(cursor.position() == 2);
+    doc->redo();
+    QVERIFY(cursor.position() == 5);
+
+    doc->undo();
+
+    doc->undo();
+    QVERIFY(doc->toPlainText() == "Hello World");
+
+    cursor.movePosition(QTextCursor::Start);
+    cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 6);
+    QVERIFY(cursor.position() == 6);
+    otherCursor = cursor;
+    otherCursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 2);
+    otherCursor.deletePreviousChar();
+    otherCursor.deletePreviousChar();
+    otherCursor.deletePreviousChar();
+    QVERIFY(cursor.position() == 5);
+
+    cursor.movePosition(QTextCursor::End);
+    cursor.insertBlock();
+    {
+	int oldPos = cursor.position();
+	cursor.movePosition(QTextCursor::End);
+	QVERIFY(cursor.position() == oldPos);
+    }
+    QVERIFY(cursor.atBlockStart());
+    QVERIFY(cursor.position() == 9);
+
+    QTextCharFormat fmt;
+    fmt.setForeground(Qt::blue);
+    cursor.insertText("Test", fmt);
+    QVERIFY(fmt == cursor.charFormat());
+    QVERIFY(cursor.position() == 13);
+}
+
+void tst_QTextCursor::navigation2_data()
+{
+    QTest::addColumn<QStringList>("sl");
+    QTest::addColumn<QList<QVariant> >("movement");
+    QTest::addColumn<int>("finalPos");
+
+    QTest::newRow("startBlock1") << QStringList("Happy happy happy joy joy joy")
+                              << (QList<QVariant>() << QVariant(QTextCursor::StartOfBlock)) << 0;
+    QTest::newRow("endBlock1") << QStringList("Happy happy happy joy joy joy")
+                            << (QList<QVariant>() << QVariant(QTextCursor::StartOfBlock)
+                                     << QVariant(QTextCursor::EndOfBlock)) << 29;
+    QTest::newRow("startBlock2") << QStringList("Happy happy happy joy joy joy")
+                              << (QList<QVariant>() << QVariant(QTextCursor::StartOfBlock)
+                                     << QVariant(QTextCursor::EndOfBlock)
+                                     << QVariant(QTextCursor::StartOfBlock)) << 0;
+    QTest::newRow("endBlock2") << QStringList("Happy happy happy joy joy joy")
+                            << (QList<QVariant>() << QVariant(QTextCursor::StartOfBlock)
+                                     << QVariant(QTextCursor::EndOfBlock)
+                                     << QVariant(QTextCursor::StartOfBlock)
+                                     << QVariant(QTextCursor::EndOfBlock)
+                                     ) << 29;
+    QTest::newRow("multiBlock1") << (QStringList() << QString("Happy happy happy")
+                                                << QString("Joy Joy Joy"))
+                             << (QList<QVariant>() << QVariant(QTextCursor::StartOfBlock))
+                             << 18;
+    QTest::newRow("multiBlock2") << (QStringList() << QString("Happy happy happy")
+                                                << QString("Joy Joy Joy"))
+                             << (QList<QVariant>() << QVariant(QTextCursor::StartOfBlock)
+                                                   << QVariant(QTextCursor::EndOfBlock))
+                             << 29;
+    QTest::newRow("multiBlock3") << (QStringList() << QString("Happy happy happy")
+                                                << QString("Joy Joy Joy"))
+                             << (QList<QVariant>() << QVariant(QTextCursor::StartOfBlock)
+                                                   << QVariant(QTextCursor::StartOfBlock))
+                             << 18;
+    QTest::newRow("multiBlock4") << (QStringList() << QString("Happy happy happy")
+                                                << QString("Joy Joy Joy"))
+                             << (QList<QVariant>() << QVariant(QTextCursor::Start)
+                                                   << QVariant(QTextCursor::EndOfBlock))
+                             << 17;
+    QTest::newRow("multiBlock5") << (QStringList() << QString("Happy happy happy")
+                                                << QString("Joy Joy Joy"))
+                             << (QList<QVariant>() << QVariant(QTextCursor::Start)
+                                                   << QVariant(QTextCursor::EndOfBlock)
+                                                   << QVariant(QTextCursor::EndOfBlock))
+                             << 17;
+    QTest::newRow("multiBlock6") << (QStringList() << QString("Happy happy happy")
+                                                << QString("Joy Joy Joy"))
+                             << (QList<QVariant>() << QVariant(QTextCursor::End)
+                                                   << QVariant(QTextCursor::StartOfBlock))
+                             << 18;
+    QTest::newRow("multiBlock7") << (QStringList() << QString("Happy happy happy")
+                                                << QString("Joy Joy Joy"))
+                             << (QList<QVariant>() << QVariant(QTextCursor::PreviousBlock))
+                             << 0;
+    QTest::newRow("multiBlock8") << (QStringList() << QString("Happy happy happy")
+                                                << QString("Joy Joy Joy"))
+                             << (QList<QVariant>() << QVariant(QTextCursor::PreviousBlock)
+                                                   << QVariant(QTextCursor::EndOfBlock))
+                             << 17;
+    QTest::newRow("multiBlock9") << (QStringList() << QString("Happy happy happy")
+                                                << QString("Joy Joy Joy"))
+                             << (QList<QVariant>() << QVariant(QTextCursor::PreviousBlock)
+                                                   << QVariant(QTextCursor::NextBlock))
+                             << 18;
+    QTest::newRow("multiBlock10") << (QStringList() << QString("Happy happy happy")
+                                                << QString("Joy Joy Joy"))
+                               << (QList<QVariant>() << QVariant(QTextCursor::PreviousBlock)
+                                                     << QVariant(QTextCursor::NextBlock)
+                                                     << QVariant(QTextCursor::NextBlock))
+                               << 18;
+    QTest::newRow("multiBlock11") << (QStringList() << QString("Happy happy happy")
+                                                << QString("Joy Joy Joy"))
+                               << (QList<QVariant>() << QVariant(QTextCursor::PreviousBlock)
+                                                     << QVariant(QTextCursor::NextBlock)
+                                                     << QVariant(QTextCursor::EndOfBlock))
+                               << 29;
+    QTest::newRow("PreviousWord1") << (QStringList() << QString("Happy happy happy Joy Joy Joy"))
+                                << (QList<QVariant>() << QVariant(QTextCursor::PreviousWord))
+                                << 26;
+    QTest::newRow("PreviousWord2") << (QStringList() << QString("Happy happy happy Joy Joy Joy"))
+                                << (QList<QVariant>() << QVariant(QTextCursor::PreviousWord)
+                                                      << QVariant(QTextCursor::PreviousWord))
+                                << 22;
+    QTest::newRow("EndWord1") << (QStringList() << QString("Happy happy happy Joy Joy Joy"))
+                                << (QList<QVariant>() << QVariant(QTextCursor::PreviousWord)
+                                                      << QVariant(QTextCursor::PreviousWord)
+                                                      << QVariant(QTextCursor::EndOfWord))
+                                << 25;
+    QTest::newRow("NextWord1") << (QStringList() << QString("Happy happy happy Joy Joy Joy"))
+                                << (QList<QVariant>() << QVariant(QTextCursor::PreviousWord)
+                                                      << QVariant(QTextCursor::PreviousWord)
+                                                      << QVariant(QTextCursor::NextWord))
+                                << 26;
+    QTest::newRow("NextWord2") << (QStringList() << QString("Happy happy happy Joy Joy Joy"))
+                                << (QList<QVariant>() << QVariant(QTextCursor::Start)
+                                                      << QVariant(QTextCursor::NextWord)
+                                                      << QVariant(QTextCursor::EndOfWord))
+                                << 11;
+    QTest::newRow("StartWord1") << (QStringList() << QString("Happy happy happy Joy Joy Joy"))
+                             << (QList<QVariant>() << QVariant(QTextCursor::PreviousWord)
+                                                   << QVariant(QTextCursor::PreviousWord)
+                                                   << QVariant(QTextCursor::StartOfWord))
+                             << 22;
+    QTest::newRow("StartWord3") << (QStringList() << QString("Happy happy happy Joy Joy Joy"))
+                             << (QList<QVariant>() << QVariant(QTextCursor::Start)
+                                                   << QVariant(QTextCursor::NextWord)
+                                                   << QVariant(QTextCursor::EndOfWord)
+                                                   << QVariant(QTextCursor::StartOfWord))
+                             << 6;
+
+    QTest::newRow("PreviousCharacter") << (QStringList() << QString("Happy happy Joy Joy"))
+                             << (QList<QVariant>() << QVariant(QTextCursor::PreviousCharacter)
+                                                   << QVariant(QTextCursor::PreviousCharacter))
+                             << 17;
+}
+
+void tst_QTextCursor::navigation2()
+{
+    QFETCH(QStringList, sl);
+    QFETCH(QList<QVariant>, movement);
+    int i;
+    for (i = 0; i < sl.size(); ++i) {
+        cursor.insertText(sl.at(i));
+        if (i < sl.size() - 1)
+            cursor.insertBlock();
+    }
+
+    for (i = 0; i < movement.size(); ++i)
+        cursor.movePosition(QTextCursor::MoveOperation(movement.at(i).toInt()));
+    QTEST(cursor.position(), "finalPos");
+}
+
+void tst_QTextCursor::navigation3()
+{
+    cursor.insertText("a");
+    cursor.deletePreviousChar();
+    QCOMPARE(cursor.position(), 0);
+    QVERIFY(doc->toPlainText().isEmpty());
+}
+
+void tst_QTextCursor::navigation4()
+{
+    cursor.insertText("  Test  ");
+
+    cursor.setPosition(4);
+    cursor.movePosition(QTextCursor::EndOfWord);
+    QCOMPARE(cursor.position(), 6);
+}
+
+void tst_QTextCursor::navigation5()
+{
+    cursor.insertText("Test");
+    cursor.insertBlock();
+    cursor.insertText("Test");
+
+    cursor.setPosition(0);
+    cursor.movePosition(QTextCursor::EndOfBlock);
+    QCOMPARE(cursor.position(), 4);
+}
+
+void tst_QTextCursor::navigation6()
+{
+    // triger creation of document layout, so that QTextLines are there
+    doc->documentLayout();
+    doc->setTextWidth(1000);
+
+    cursor.insertText("Test    ");
+
+    cursor.movePosition(QTextCursor::Start);
+    cursor.movePosition(QTextCursor::EndOfLine);
+    QCOMPARE(cursor.position(), 8);
+}
+
+void tst_QTextCursor::navigation7()
+{
+    QVERIFY(doc->isEmpty());
+    for (int i = QTextCursor::Start; i <= QTextCursor::WordRight; ++i)
+        QVERIFY(!cursor.movePosition(QTextCursor::MoveOperation(i)));
+
+    doc->setPlainText("Hello World");
+    cursor.movePosition(QTextCursor::Start);
+    do {
+    } while (cursor.movePosition(QTextCursor::NextCharacter));
+    QVERIFY(true /*reached*/);
+}
+
+void tst_QTextCursor::navigation8()
+{
+    cursor.insertList(QTextListFormat::ListDecimal);
+    QCOMPARE(cursor.position(), 1);
+    cursor.insertText("foo");
+    QCOMPARE(cursor.position(), 4);
+
+    cursor.insertList(QTextListFormat::ListCircle);
+    QCOMPARE(cursor.position(), 5);
+    cursor.insertText("something");
+    QCOMPARE(cursor.position(), 14);
+
+    cursor.movePosition(QTextCursor::PreviousCharacter);
+    QCOMPARE(cursor.position(), 13);
+
+    cursor.setPosition(2);
+    cursor.movePosition(QTextCursor::NextCharacter);
+    QCOMPARE(cursor.position(), 3);
+}
+
+void tst_QTextCursor::navigation9()
+{
+    cursor.insertText("Hello  &-=+\t   World");
+    cursor.movePosition(QTextCursor::PreviousWord);
+    QCOMPARE(cursor.position(), 15);
+    cursor.movePosition(QTextCursor::PreviousWord);
+    QCOMPARE(cursor.position(), 7);
+    cursor.movePosition(QTextCursor::PreviousWord);
+    QCOMPARE(cursor.position(), 0);
+    cursor.movePosition(QTextCursor::NextWord);
+    QCOMPARE(cursor.position(), 7);
+    cursor.movePosition(QTextCursor::NextWord);
+    QCOMPARE(cursor.position(), 15);
+}
+
+void tst_QTextCursor::navigation10()
+{
+    doc->setHtml("<html><p>just a simple paragraph.</p>"
+        "<table>"
+          "<tr><td>Cell number 1</td><td>another cell</td><td></td><td>previous</br>is</br>empty</td></tr>"
+          "<tr><td>row 2</td><td colspan=\"2\">foo bar</td><td>last cell</td></tr>"
+          "<tr><td colspan=\"3\">row 3</td><td>a</td></tr>"
+        "</table></html");
+    QCOMPARE(cursor.position(), 101); // end of document
+    cursor.setPosition(0);
+    QCOMPARE(cursor.position(), 0);
+    bool ok = cursor.movePosition(QTextCursor::EndOfLine);
+    QVERIFY(ok);
+    QCOMPARE(cursor.position(), 24);
+    ok = cursor.movePosition(QTextCursor::NextBlock);
+    QCOMPARE(cursor.position(), 25); // cell 1
+    ok = cursor.movePosition(QTextCursor::NextCell);
+    QVERIFY(ok);
+    QCOMPARE(cursor.position(), 39); // another..
+    ok = cursor.movePosition(QTextCursor::NextCell);
+    QVERIFY(ok);
+    QCOMPARE(cursor.position(), 52); // empty
+    ok = cursor.movePosition(QTextCursor::NextCell);
+    QVERIFY(ok);
+    QCOMPARE(cursor.position(), 53); // last on row 1
+    ok = cursor.movePosition(QTextCursor::NextCell);
+    QVERIFY(ok);
+    QCOMPARE(cursor.position(), 69); // row 2
+    ok = cursor.movePosition(QTextCursor::NextCell);
+    QVERIFY(ok);
+    QCOMPARE(cursor.position(), 75);
+    ok = cursor.movePosition(QTextCursor::NextCell);
+    QVERIFY(ok);
+    QCOMPARE(cursor.position(), 83);
+    ok = cursor.movePosition(QTextCursor::NextCell);
+    QVERIFY(ok);
+    QCOMPARE(cursor.position(), 93); // row 3
+    ok = cursor.movePosition(QTextCursor::NextCell);
+    QVERIFY(ok);
+    QCOMPARE(cursor.position(), 99);
+    ok = cursor.movePosition(QTextCursor::NextCell);
+    QVERIFY(ok == false);
+    QCOMPARE(cursor.position(), 99); // didn't move.
+    QVERIFY(cursor.currentTable());
+
+    // same thing in reverse...
+    ok = cursor.movePosition(QTextCursor::PreviousCell);
+    QVERIFY(ok);
+    QCOMPARE(cursor.position(), 93);
+    ok = cursor.movePosition(QTextCursor::PreviousCell);
+    QVERIFY(ok);
+    QCOMPARE(cursor.position(), 83);
+    ok = cursor.movePosition(QTextCursor::PreviousCell);
+    QVERIFY(ok);
+    QCOMPARE(cursor.position(), 75);
+    ok = cursor.movePosition(QTextCursor::PreviousCell);
+    QVERIFY(ok);
+    QCOMPARE(cursor.position(), 69);
+    ok = cursor.movePosition(QTextCursor::PreviousCell);
+    QVERIFY(ok);
+    QCOMPARE(cursor.position(), 53);
+    ok = cursor.movePosition(QTextCursor::PreviousCell);
+    QVERIFY(ok);
+    QCOMPARE(cursor.position(), 52);
+    ok = cursor.movePosition(QTextCursor::PreviousCell);
+    QVERIFY(ok);
+    QCOMPARE(cursor.position(), 39);
+    ok = cursor.movePosition(QTextCursor::PreviousCell);
+    QVERIFY(ok);
+    QCOMPARE(cursor.position(), 25);
+    ok = cursor.movePosition(QTextCursor::PreviousCell);
+    QVERIFY(!ok);
+    QCOMPARE(cursor.position(), 25); // can't leave the table
+
+    ok = cursor.movePosition(QTextCursor::NextRow);
+    QVERIFY(ok);
+    QCOMPARE(cursor.position(), 69);
+    ok = cursor.movePosition(QTextCursor::NextRow);
+    QVERIFY(ok);
+    QCOMPARE(cursor.position(), 93);
+    ok = cursor.movePosition(QTextCursor::NextRow);
+    QVERIFY(!ok);
+    QCOMPARE(cursor.position(), 93); // didn't move
+
+    ok = cursor.movePosition(QTextCursor::PreviousRow);
+    QVERIFY(ok);
+    QCOMPARE(cursor.position(), 83); // last col in row 2
+    ok = cursor.movePosition(QTextCursor::PreviousRow);
+    QVERIFY(ok);
+    QCOMPARE(cursor.position(), 53); // last col in row 1
+    ok = cursor.movePosition(QTextCursor::PreviousRow);
+    QVERIFY(!ok);
+    QCOMPARE(cursor.position(), 53);
+
+    // test usecase of jumping over a cell
+    doc->clear();
+    doc->setHtml("<html><table>tr><td rowspan=\"2\">a</td><td>b</td></tr><tr><td>c</td></tr></table></html>");
+    cursor.setPosition(1); // a
+    ok = cursor.movePosition(QTextCursor::NextCell);
+    QVERIFY(ok);
+    QCOMPARE(cursor.position(), 3); // b
+    ok = cursor.movePosition(QTextCursor::NextCell);
+    QVERIFY(ok);
+    QCOMPARE(cursor.position(), 5); // c
+    ok = cursor.movePosition(QTextCursor::PreviousCell);
+    QVERIFY(ok);
+    QCOMPARE(cursor.position(), 3); // b
+    ok = cursor.movePosition(QTextCursor::PreviousCell);
+    QVERIFY(ok);
+    QCOMPARE(cursor.position(), 1); // a
+}
+
+void tst_QTextCursor::insertBlock()
+{
+    QTextBlockFormat fmt;
+    fmt.setTopMargin(100);
+    cursor.insertBlock(fmt);
+    QVERIFY(cursor.position() == 1);
+    QVERIFY(cursor.blockFormat() == fmt);
+}
+
+void tst_QTextCursor::insertWithBlockSeparator1()
+{
+    QString text = "Hello" + QString(QChar::ParagraphSeparator) + "World";
+
+    cursor.insertText(text);
+
+    cursor.movePosition(QTextCursor::PreviousBlock);
+    QVERIFY(cursor.position() == 0);
+
+    cursor.movePosition(QTextCursor::NextBlock);
+    QVERIFY(cursor.position() == 6);
+}
+
+void tst_QTextCursor::insertWithBlockSeparator2()
+{
+    cursor.insertText(QString(QChar::ParagraphSeparator));
+    QVERIFY(cursor.position() == 1);
+}
+
+void tst_QTextCursor::insertWithBlockSeparator3()
+{
+    cursor.insertText(QString(QChar::ParagraphSeparator) + "Hi" + QString(QChar::ParagraphSeparator));
+    QVERIFY(cursor.position() == 4);
+}
+
+void tst_QTextCursor::insertWithBlockSeparator4()
+{
+    cursor.insertText(QString(QChar::ParagraphSeparator) + QString(QChar::ParagraphSeparator));
+    QVERIFY(cursor.position() == 2);
+}
+
+void tst_QTextCursor::clearObjectType1()
+{
+    cursor.insertImage("test.png");
+    QVERIFY(cursor.charFormat().isValid());
+    QVERIFY(cursor.charFormat().isImageFormat());
+    cursor.insertText("Hey");
+    QVERIFY(cursor.charFormat().isValid());
+    QVERIFY(!cursor.charFormat().isImageFormat());
+}
+
+void tst_QTextCursor::clearObjectType2()
+{
+    cursor.insertImage("test.png");
+    QVERIFY(cursor.charFormat().isValid());
+    QVERIFY(cursor.charFormat().isImageFormat());
+    cursor.insertBlock();
+    QVERIFY(cursor.charFormat().isValid());
+    QVERIFY(!cursor.charFormat().isImageFormat());
+}
+
+void tst_QTextCursor::clearObjectType3()
+{
+    // like clearObjectType2 but tests different insertBlock overload
+    cursor.insertImage("test.png");
+    QVERIFY(cursor.charFormat().isValid());
+    QVERIFY(cursor.charFormat().isImageFormat());
+    QTextBlockFormat bfmt;
+    bfmt.setAlignment(Qt::AlignRight);
+    cursor.insertBlock(bfmt);
+    QVERIFY(cursor.charFormat().isValid());
+    QVERIFY(!cursor.charFormat().isImageFormat());
+}
+
+void tst_QTextCursor::comparisonOperators1()
+{
+    cursor.insertText("Hello World");
+
+    cursor.movePosition(QTextCursor::PreviousWord);
+
+    QTextCursor startCursor = cursor;
+    startCursor.movePosition(QTextCursor::Start);
+
+    QVERIFY(startCursor < cursor);
+
+    QTextCursor midCursor = startCursor;
+    midCursor.movePosition(QTextCursor::NextWord);
+
+    QVERIFY(midCursor <= cursor);
+    QVERIFY(midCursor == cursor);
+    QVERIFY(midCursor >= cursor);
+
+    QVERIFY(midCursor > startCursor);
+
+    QVERIFY(midCursor != startCursor);
+    QVERIFY(!(midCursor == startCursor));
+
+    QTextCursor nullCursor;
+
+    QVERIFY(!(startCursor < nullCursor));
+    QVERIFY(!(nullCursor < nullCursor));
+    QVERIFY(nullCursor < startCursor);
+
+    QVERIFY(nullCursor <= startCursor);
+    QVERIFY(!(startCursor <= nullCursor));
+
+    QVERIFY(!(nullCursor >= startCursor));
+    QVERIFY(startCursor >= nullCursor);
+
+    QVERIFY(!(nullCursor > startCursor));
+    QVERIFY(!(nullCursor > nullCursor));
+    QVERIFY(startCursor > nullCursor);
+}
+
+void tst_QTextCursor::comparisonOperators2()
+{
+    QTextDocument doc1;
+    QTextDocument doc2;
+
+    QTextCursor cursor1(&doc1);
+    QTextCursor cursor2(&doc2);
+
+    QVERIFY(cursor1 != cursor2);
+    QVERIFY(cursor1 == QTextCursor(&doc1));
+}
+
+void tst_QTextCursor::selection1()
+{
+    cursor.insertText("Hello World");
+
+    cursor.setPosition(0);
+    cursor.clearSelection();
+    cursor.setPosition(4, QTextCursor::KeepAnchor);
+
+    QCOMPARE(cursor.selectionStart(), 0);
+    QCOMPARE(cursor.selectionEnd(), 4);
+}
+
+void tst_QTextCursor::dontCopyTableAttributes()
+{
+    /* when pressing 'enter' inside a cell it shouldn't
+     * enlarge the table by adding another cell but just
+     * extend the cell */
+    QTextTable *table = cursor.insertTable(2, 2);
+    QVERIFY(cursor == table->cellAt(0, 0).firstCursorPosition());
+    cursor.insertBlock();
+    QCOMPARE(table->columns(), 2);
+}
+
+void tst_QTextCursor::checkFrame1()
+{
+    QVERIFY(cursor.position() == 0);
+    QPointer<QTextFrame> frame = cursor.insertFrame(QTextFrameFormat());
+    QVERIFY(frame != 0);
+
+    QTextFrame *root = frame->parentFrame();
+    QVERIFY(root != 0);
+
+    QVERIFY(frame->firstPosition() == 1);
+    QVERIFY(frame->lastPosition() == 1);
+    QVERIFY(frame->parentFrame() != 0);
+    QVERIFY(root->childFrames().size() == 1);
+
+    QVERIFY(cursor.position() == 1);
+    QVERIFY(cursor.selectionStart() == 1);
+    QVERIFY(cursor.selectionEnd() == 1);
+
+    doc->undo();
+
+    QVERIFY(!frame);
+    QVERIFY(root->childFrames().size() == 0);
+
+    QVERIFY(cursor.position() == 0);
+    QVERIFY(cursor.selectionStart() == 0);
+    QVERIFY(cursor.selectionEnd() == 0);
+
+    doc->redo();
+
+    frame = doc->frameAt(1);
+
+    QVERIFY(frame);
+    QVERIFY(frame->firstPosition() == 1);
+    QVERIFY(frame->lastPosition() == 1);
+    QVERIFY(frame->parentFrame() != 0);
+    QVERIFY(root->childFrames().size() == 1);
+
+    QVERIFY(cursor.position() == 1);
+    QVERIFY(cursor.selectionStart() == 1);
+    QVERIFY(cursor.selectionEnd() == 1);
+
+//     cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor);
+//     QVERIFY(cursor.position() == 2);
+//     QVERIFY(cursor.selectionStart() == 0);
+//     QVERIFY(cursor.selectionEnd() == 2);
+}
+
+void tst_QTextCursor::checkFrame2()
+{
+    QVERIFY(cursor.position() == 0);
+    cursor.insertText("A");
+    QVERIFY(cursor.position() == 1);
+    cursor.movePosition(QTextCursor::Start, QTextCursor::KeepAnchor);
+
+    QPointer<QTextFrame> frame = cursor.insertFrame(QTextFrameFormat());
+    QTextFrame *root = frame->parentFrame();
+
+    QVERIFY(frame->firstPosition() == 1);
+    QVERIFY(frame->lastPosition() == 2);
+    QVERIFY(frame->parentFrame() != 0);
+    QVERIFY(root->childFrames().size() == 1);
+
+    QVERIFY(cursor.position() == 1);
+    QVERIFY(cursor.selectionStart() == 1);
+    QVERIFY(cursor.selectionEnd() == 2);
+
+    doc->undo();
+
+    QVERIFY(!frame);
+    QVERIFY(root->childFrames().size() == 0);
+
+    QVERIFY(cursor.position() == 0);
+    QVERIFY(cursor.selectionStart() == 0);
+    QVERIFY(cursor.selectionEnd() == 1);
+
+    doc->redo();
+
+    frame = doc->frameAt(1);
+
+    QVERIFY(frame);
+    QVERIFY(frame->firstPosition() == 1);
+    QVERIFY(frame->lastPosition() == 2);
+    QVERIFY(frame->parentFrame() != 0);
+    QVERIFY(root->childFrames().size() == 1);
+
+    QVERIFY(cursor.position() == 1);
+    QVERIFY(cursor.selectionStart() == 1);
+    QVERIFY(cursor.selectionEnd() == 2);
+
+    cursor.movePosition(QTextCursor::Left, QTextCursor::KeepAnchor);
+    QVERIFY(cursor.position() == 0);
+    QVERIFY(cursor.selectionStart() == 0);
+    QVERIFY(cursor.selectionEnd() == 3);
+}
+
+void tst_QTextCursor::insertBlockToUseCharFormat()
+{
+    QTextCharFormat fmt;
+    fmt.setForeground(Qt::blue);
+    cursor.insertText("Hello", fmt);
+    QCOMPARE(cursor.charFormat().foreground().color(), QColor(Qt::blue));
+
+    cursor.insertBlock();
+    QCOMPARE(cursor.charFormat().foreground().color(), QColor(Qt::blue));
+
+    fmt.setForeground(Qt::red);
+    cursor.insertText("Hello\nWorld", fmt);
+    cursor.insertText("Blah");
+    QCOMPARE(cursor.charFormat().foreground().color(), QColor(Qt::red));
+
+    // ### we might want a testcase for createTable, too, as it calls insertBlock, too,
+    // and we might want to have the char format copied (the one that gets inserted
+    // as table separators, that are undeletable)
+}
+
+void tst_QTextCursor::tableMovement()
+{
+    QVERIFY(cursor.position() == 0);
+    cursor.insertText("AA");
+    QVERIFY(cursor.position() == 2);
+    cursor.movePosition(QTextCursor::Left);
+
+    cursor.insertTable(3, 3);
+    QCOMPARE(cursor.position(), 2);
+
+    cursor.movePosition(QTextCursor::Down);
+    QCOMPARE(cursor.position(), 5);
+
+    cursor.movePosition(QTextCursor::Right);
+    QCOMPARE(cursor.position(), 6);
+
+    cursor.movePosition(QTextCursor::Up);
+    QCOMPARE(cursor.position(), 3);
+
+    cursor.movePosition(QTextCursor::Right);
+    QCOMPARE(cursor.position(), 4);
+
+    cursor.movePosition(QTextCursor::Right);
+    QCOMPARE(cursor.position(), 5);
+
+    cursor.movePosition(QTextCursor::Up);
+    QCOMPARE(cursor.position(), 2);
+
+    cursor.movePosition(QTextCursor::Up);
+    QCOMPARE(cursor.position(), 0);
+
+}
+
+void tst_QTextCursor::selectionsInTable()
+{
+    QTextTable *table = cursor.insertTable(2, 2);
+    table->cellAt(0, 0).firstCursorPosition().insertText("First");
+    table->cellAt(0, 1).firstCursorPosition().insertText("Second");
+    table->cellAt(1, 0).firstCursorPosition().insertText("Third");
+    table->cellAt(1, 1).firstCursorPosition().insertText("Fourth");
+
+    cursor = table->cellAt(0, 0).lastCursorPosition();
+    QVERIFY(cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor));
+    QVERIFY(cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor) == false);
+
+    cursor = table->cellAt(1, 0).lastCursorPosition();
+    QVERIFY(cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor));
+    QVERIFY(cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor) == false);
+
+    cursor = table->cellAt(0, 1).firstCursorPosition();
+    QVERIFY(cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor));
+    QVERIFY(cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor) == false);
+
+    cursor = table->cellAt(1, 1).firstCursorPosition();
+    QVERIFY(cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor));
+    QVERIFY(cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor) == false);
+}
+
+void tst_QTextCursor::selectedText()
+{
+    cursor.insertText("Hello World");
+    cursor.movePosition(QTextCursor::Start);
+    cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
+
+    QCOMPARE(cursor.selectedText(), QString("Hello World"));
+}
+
+void tst_QTextCursor::insertBlockShouldRemoveSelection()
+{
+    cursor.insertText("Hello World");
+    cursor.movePosition(QTextCursor::Start);
+    cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
+
+    QVERIFY(cursor.hasSelection());
+    QCOMPARE(cursor.selectedText(), QString("Hello"));
+
+    cursor.insertBlock();
+
+    QVERIFY(!cursor.hasSelection());
+    QVERIFY(doc->toPlainText().indexOf("Hello") == -1);
+}
+
+void tst_QTextCursor::insertBlockShouldRemoveSelection2()
+{
+    cursor.insertText("Hello World");
+    cursor.movePosition(QTextCursor::Start);
+    cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
+
+    QVERIFY(cursor.hasSelection());
+    QCOMPARE(cursor.selectedText(), QString("Hello"));
+
+    QTextBlockFormat fmt = cursor.blockFormat();
+    cursor.insertBlock(fmt);
+
+    QVERIFY(!cursor.hasSelection());
+    QVERIFY(doc->toPlainText().indexOf("Hello") == -1);
+}
+
+void tst_QTextCursor::mergeCellShouldUpdateSelection()
+{
+    QTextTable *table = cursor.insertTable(4, 4);
+    cursor.setPosition(table->cellAt(0, 0).firstPosition());
+    cursor.setPosition(table->cellAt(3, 0).firstPosition(), QTextCursor::KeepAnchor); // aka bottom left
+    int firstRow, numRows, firstColumn, numColumns;
+    cursor.selectedTableCells(&firstRow, &numRows, &firstColumn, &numColumns);
+    QCOMPARE(firstRow, 0);
+    QCOMPARE(numRows, 4);
+    QCOMPARE(firstColumn, 0);
+    QCOMPARE(numColumns, 1);
+
+    table->removeColumns(firstColumn, numColumns);
+
+    QCOMPARE(cursor.anchor(), table->cellAt(0, 0).firstPosition());
+    QCOMPARE(cursor.position(), table->cellAt(0, 0).firstPosition());
+    QCOMPARE(cursor.position(), cursor.anchor()); // empty. I don't really care where it ends up.
+
+    // prepare for another test with multiple cursors.
+    // note we have a 4 rows, 3 cols table now.
+    cursor.setPosition(table->cellAt(0, 0).firstPosition());
+    cursor.setPosition(table->cellAt(0, 2).firstPosition(), QTextCursor::KeepAnchor);
+
+    // now create a selection of a whole row.
+    QTextCursor c2 = table->cellAt(2, 0).firstCursorPosition();
+    c2.setPosition(table->cellAt(2, 2).firstPosition(), QTextCursor::KeepAnchor);
+
+    // just for good measure, another one for a block of cells.
+    QTextCursor c3 = table->cellAt(2, 1).firstCursorPosition();
+    c3.setPosition(table->cellAt(3, 2).firstPosition(), QTextCursor::KeepAnchor);
+
+    table->removeRows(2, 1);
+
+    QCOMPARE(cursor.anchor(), table->cellAt(0, 0).firstPosition());
+    QCOMPARE(cursor.position(), table->cellAt(0, 2).firstPosition());
+
+    QCOMPARE(c2.position(), c2.anchor()); // empty. I don't really care where it ends up.
+
+    QCOMPARE(c3.anchor(), table->cellAt(2, 1).firstPosition());
+    QCOMPARE(c3.position(), table->cellAt(2, 2).firstPosition());
+
+
+    // prepare for another test where we remove a column
+    // note we have a 3 rows, 3 cols table now.
+    cursor.setPosition(table->cellAt(0, 0).firstPosition());
+    cursor.setPosition(table->cellAt(2, 1).firstPosition(), QTextCursor::KeepAnchor);
+
+    c2.setPosition(table->cellAt(0, 1).firstPosition());
+    c2.setPosition(table->cellAt(2, 2).firstPosition(), QTextCursor::KeepAnchor);
+
+    table->removeColumns(1, 1);
+
+    QCOMPARE(cursor.anchor(), table->cellAt(0, 0).firstPosition());
+    QCOMPARE(cursor.position(), table->cellAt(2, 0).firstPosition());
+
+    QCOMPARE(c2.anchor(), table->cellAt(0, 1).firstPosition());
+    QCOMPARE(c2.position(), table->cellAt(2, 1).firstPosition());
+
+    // test for illegal cursor positions.
+    // note we have a 3 rows, 2 cols table now.
+    cursor.setPosition(table->cellAt(2, 0).firstPosition());
+    cursor.setPosition(table->cellAt(2, 1).firstPosition(), QTextCursor::KeepAnchor);
+
+    c2.setPosition(table->cellAt(0, 0).firstPosition());
+    c2.setPosition(table->cellAt(2, 1).firstPosition(), QTextCursor::KeepAnchor);
+
+    c3.setPosition(table->cellAt(2, 1).firstPosition());
+
+    table->removeRows(2, 1);
+
+    QCOMPARE(cursor.anchor(), table->cellAt(1, 1).lastPosition()+1);
+    QCOMPARE(cursor.position(), cursor.anchor());
+
+    QCOMPARE(c2.anchor(), table->cellAt(0, 0).firstPosition());
+    QCOMPARE(c2.position(), table->cellAt(1, 1).firstPosition());
+
+    QCOMPARE(c3.anchor(), table->cellAt(1, 1).firstPosition());
+    QCOMPARE(c3.position(), table->cellAt(1, 1).firstPosition());
+}
+
+void tst_QTextCursor::joinPreviousEditBlock()
+{
+    cursor.beginEditBlock();
+    cursor.insertText("Hello");
+    cursor.insertText("World");
+    cursor.endEditBlock();
+    QVERIFY(doc->toPlainText().startsWith("HelloWorld"));
+
+    cursor.joinPreviousEditBlock();
+    cursor.insertText("Hey");
+    cursor.endEditBlock();
+    QVERIFY(doc->toPlainText().startsWith("HelloWorldHey"));
+
+    doc->undo();
+    QVERIFY(!doc->toPlainText().contains("HelloWorldHey"));
+}
+
+void tst_QTextCursor::setBlockFormatInTable()
+{
+    // someone reported this on qt4-preview-feedback
+    QTextBlockFormat fmt;
+    fmt.setBackground(Qt::blue);
+    cursor.setBlockFormat(fmt);
+
+    QTextTable *table = cursor.insertTable(2, 2);
+    cursor = table->cellAt(0, 0).firstCursorPosition();
+    fmt.setBackground(Qt::red);
+    cursor.setBlockFormat(fmt);
+
+    cursor.movePosition(QTextCursor::Start);
+    QVERIFY(cursor.blockFormat().background().color() == Qt::blue);
+}
+
+void tst_QTextCursor::blockCharFormat2()
+{
+    QTextCharFormat fmt;
+    fmt.setForeground(Qt::green);
+    cursor.mergeBlockCharFormat(fmt);
+
+    fmt.setForeground(Qt::red);
+
+    cursor.insertText("Test", fmt);
+    cursor.movePosition(QTextCursor::Start);
+    cursor.insertText("Red");
+    cursor.movePosition(QTextCursor::PreviousCharacter);
+    QVERIFY(cursor.charFormat().foreground().color() == Qt::red);
+}
+
+void tst_QTextCursor::blockCharFormat3()
+{
+    QVERIFY(cursor.atBlockStart());
+    QVERIFY(cursor.atBlockEnd());
+    QVERIFY(cursor.atStart());
+
+    QTextCharFormat fmt;
+    fmt.setForeground(Qt::green);
+    cursor.setBlockCharFormat(fmt);
+    cursor.insertText("Test");
+    cursor.movePosition(QTextCursor::Start);
+    cursor.movePosition(QTextCursor::NextCharacter);
+    QVERIFY(cursor.charFormat().foreground().color() == Qt::green);
+
+    cursor.movePosition(QTextCursor::Start);
+    QVERIFY(cursor.charFormat().foreground().color() == Qt::green);
+
+    fmt.setForeground(Qt::red);
+    cursor.setBlockCharFormat(fmt);
+    QVERIFY(cursor.blockCharFormat().foreground().color() == Qt::red);
+
+    cursor.movePosition(QTextCursor::End);
+    cursor.movePosition(QTextCursor::Start);
+    QVERIFY(cursor.charFormat().foreground().color() == Qt::green);
+
+    cursor.insertText("Test");
+    QVERIFY(cursor.charFormat().foreground().color() == Qt::green);
+
+    cursor.select(QTextCursor::Document);
+    cursor.removeSelectedText();
+    QVERIFY(cursor.atBlockStart());
+    QVERIFY(cursor.atBlockEnd());
+    QVERIFY(cursor.atStart());
+
+    cursor.insertText("Test");
+    QVERIFY(cursor.charFormat().foreground().color() == Qt::red);
+}
+
+void tst_QTextCursor::blockCharFormat()
+{
+    QTextCharFormat fmt;
+    fmt.setForeground(Qt::blue);
+    cursor.insertBlock(QTextBlockFormat(), fmt);
+    cursor.insertText("Hm");
+
+    QVERIFY(cursor.blockCharFormat().foreground().color() == Qt::blue);
+
+    fmt.setForeground(Qt::red);
+
+    cursor.setBlockCharFormat(fmt);
+    QVERIFY(cursor.blockCharFormat().foreground().color() == Qt::red);
+}
+
+void tst_QTextCursor::blockCharFormatOnSelection()
+{
+    QTextCharFormat fmt;
+    fmt.setForeground(Qt::blue);
+    cursor.insertBlock(QTextBlockFormat(), fmt);
+
+    fmt.setForeground(Qt::green);
+    cursor.insertText("Hm", fmt);
+
+    fmt.setForeground(Qt::red);
+    cursor.insertBlock(QTextBlockFormat(), fmt);
+    cursor.insertText("Ah");
+
+    fmt.setForeground(Qt::white);
+    cursor.insertBlock(QTextBlockFormat(), fmt);
+    cursor.insertText("bleh");
+
+    cursor.movePosition(QTextCursor::Start);
+    cursor.movePosition(QTextCursor::NextBlock);
+    QVERIFY(cursor.blockCharFormat().foreground().color() == Qt::blue);
+    cursor.movePosition(QTextCursor::NextBlock);
+    QVERIFY(cursor.blockCharFormat().foreground().color() == Qt::red);
+    cursor.movePosition(QTextCursor::NextBlock);
+    QVERIFY(cursor.blockCharFormat().foreground().color() == Qt::white);
+
+    cursor.movePosition(QTextCursor::Start);
+    cursor.movePosition(QTextCursor::NextBlock);
+    cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor);
+
+    fmt.setForeground(Qt::cyan);
+    cursor.setBlockCharFormat(fmt);
+
+    cursor.movePosition(QTextCursor::Start);
+    cursor.movePosition(QTextCursor::NextBlock);
+    QVERIFY(cursor.blockCharFormat().foreground().color() == Qt::cyan);
+
+    cursor.movePosition(QTextCursor::Right);
+    cursor.movePosition(QTextCursor::Right);
+    QVERIFY(cursor.charFormat().foreground().color() == Qt::green);
+
+    cursor.movePosition(QTextCursor::NextBlock);
+    QVERIFY(cursor.blockCharFormat().foreground().color() == Qt::cyan);
+
+    cursor.movePosition(QTextCursor::NextBlock);
+    QVERIFY(cursor.blockCharFormat().foreground().color() == Qt::white);
+}
+
+void tst_QTextCursor::anchorInitialized1()
+{
+    cursor.insertBlock();
+    cursor = QTextCursor(cursor.block());
+    QCOMPARE(cursor.position(), 1);
+    QCOMPARE(cursor.anchor(), 1);
+    QCOMPARE(cursor.selectionStart(), 1);
+    QCOMPARE(cursor.selectionEnd(), 1);
+}
+
+void tst_QTextCursor::anchorInitialized2()
+{
+    cursor.insertBlock();
+    cursor = QTextCursor(cursor.block().docHandle(), 1);
+    QCOMPARE(cursor.position(), 1);
+    QCOMPARE(cursor.anchor(), 1);
+    QCOMPARE(cursor.selectionStart(), 1);
+    QCOMPARE(cursor.selectionEnd(), 1);
+}
+
+void tst_QTextCursor::anchorInitialized3()
+{
+    QTextFrame *frame = cursor.insertFrame(QTextFrameFormat());
+    cursor = QTextCursor(frame);
+    QCOMPARE(cursor.position(), 1);
+    QCOMPARE(cursor.anchor(), 1);
+    QCOMPARE(cursor.selectionStart(), 1);
+    QCOMPARE(cursor.selectionEnd(), 1);
+}
+
+void tst_QTextCursor::selectWord()
+{
+    cursor.insertText("first second     third");
+    cursor.insertBlock();
+    cursor.insertText("words in second paragraph");
+
+    cursor.setPosition(9);
+    cursor.select(QTextCursor::WordUnderCursor);
+    QVERIFY(cursor.hasSelection());
+    QCOMPARE(cursor.selectionStart(), 6);
+    QCOMPARE(cursor.selectionEnd(), 12);
+
+    cursor.setPosition(5);
+    cursor.select(QTextCursor::WordUnderCursor);
+    QVERIFY(cursor.hasSelection());
+    QCOMPARE(cursor.selectionStart(), 0);
+    QCOMPARE(cursor.selectionEnd(), 5);
+
+    cursor.setPosition(6);
+    cursor.select(QTextCursor::WordUnderCursor);
+    QVERIFY(cursor.hasSelection());
+    QCOMPARE(cursor.selectionStart(), 6);
+    QCOMPARE(cursor.selectionEnd(), 12);
+
+    cursor.setPosition(14);
+    cursor.select(QTextCursor::WordUnderCursor);
+    QVERIFY(cursor.hasSelection());
+    QCOMPARE(cursor.selectionStart(), 6);
+    QCOMPARE(cursor.selectionEnd(), 12);
+
+    cursor.movePosition(QTextCursor::Start);
+    cursor.select(QTextCursor::WordUnderCursor);
+    QVERIFY(cursor.hasSelection());
+    QCOMPARE(cursor.selectionStart(), 0);
+    QCOMPARE(cursor.selectionEnd(), 5);
+
+    cursor.movePosition(QTextCursor::EndOfBlock);
+    cursor.select(QTextCursor::WordUnderCursor);
+    QVERIFY(cursor.hasSelection());
+    QCOMPARE(cursor.selectionStart(), 17);
+    QCOMPARE(cursor.selectionEnd(), 22);
+}
+
+void tst_QTextCursor::selectWordWithSeparators_data()
+{
+    QTest::addColumn<QString>("text");
+    QTest::addColumn<int>("initialPosition");
+    QTest::addColumn<QString>("expectedSelectedText");
+
+    QTest::newRow("dereference") << QString::fromLatin1("foo->bar()") << 1 << QString::fromLatin1("foo");
+    QTest::newRow("funcsignature") << QString::fromLatin1("bar(int x);") << 1 << QString::fromLatin1("bar");
+    QTest::newRow("def") << QString::fromLatin1("foo *f;") << 1 << QString::fromLatin1("foo");
+}
+
+void tst_QTextCursor::selectWordWithSeparators()
+{
+    QFETCH(QString, text);
+    QFETCH(int, initialPosition);
+    QFETCH(QString, expectedSelectedText);
+
+    cursor.insertText(text);
+    cursor.setPosition(initialPosition);
+    cursor.select(QTextCursor::WordUnderCursor);
+
+    QCOMPARE(cursor.selectedText(), expectedSelectedText);
+}
+
+void tst_QTextCursor::startOfWord()
+{
+    cursor.insertText("first     second");
+    cursor.setPosition(7);
+    cursor.movePosition(QTextCursor::StartOfWord);
+    QCOMPARE(cursor.position(), 0);
+}
+
+void tst_QTextCursor::selectBlock()
+{
+    cursor.insertText("foobar");
+    QTextBlockFormat blockFmt;
+    blockFmt.setAlignment(Qt::AlignHCenter);
+    cursor.insertBlock(blockFmt);
+    cursor.insertText("blah");
+    cursor.insertBlock(QTextBlockFormat());
+
+    cursor.movePosition(QTextCursor::PreviousBlock);
+    QCOMPARE(cursor.block().text(), QString("blah"));
+
+    cursor.select(QTextCursor::BlockUnderCursor);
+    QVERIFY(cursor.hasSelection());
+
+    QTextDocumentFragment fragment(cursor);
+    doc->clear();
+    cursor.insertFragment(fragment);
+    QCOMPARE(blockCount(), 2);
+
+    cursor.movePosition(QTextCursor::Start);
+    cursor.movePosition(QTextCursor::NextBlock);
+    QVERIFY(cursor.blockFormat().alignment() == Qt::AlignHCenter);
+    QCOMPARE(cursor.block().text(), QString("blah"));
+}
+
+void tst_QTextCursor::selectVisually()
+{
+    cursor.insertText("Foo\nlong line which is probably going to be cut in two when shown in a widget\nparagraph 3\n");
+
+    cursor.setPosition(6); // somewhere in the long paragraph.
+    cursor.select(QTextCursor::LineUnderCursor);
+    // since we are not yet layed-out, we expect the whole paragraph to be selected.
+    QCOMPARE(cursor.position(), 77);
+    QCOMPARE(cursor.anchor(), 4);
+}
+
+void tst_QTextCursor::insertText()
+{
+    QString txt = "Foo\nBar\r\nMeep";
+    txt += QChar::LineSeparator;
+    txt += "Baz";
+    txt += QChar::ParagraphSeparator;
+    txt += "yoyodyne";
+    cursor.insertText(txt);
+    QCOMPARE(blockCount(), 4);
+    cursor.movePosition(QTextCursor::Start);
+    QCOMPARE(cursor.block().text(), QString("Foo"));
+    cursor.movePosition(QTextCursor::NextBlock);
+    QCOMPARE(cursor.block().text(), QString("Bar"));
+    cursor.movePosition(QTextCursor::NextBlock);
+    QCOMPARE(cursor.block().text(), QString(QString("Meep") + QChar(QChar::LineSeparator) + QString("Baz")));
+    cursor.movePosition(QTextCursor::NextBlock);
+    QCOMPARE(cursor.block().text(), QString("yoyodyne"));
+}
+
+void tst_QTextCursor::insertFragmentShouldUseCurrentCharFormat()
+{
+    QTextDocumentFragment fragment = QTextDocumentFragment::fromPlainText("Hello World");
+    QTextCharFormat fmt;
+    fmt.setFontUnderline(true);
+
+    cursor.clearSelection();
+    cursor.setCharFormat(fmt);
+    cursor.insertFragment(fragment);
+    cursor.movePosition(QTextCursor::Start);
+    cursor.movePosition(QTextCursor::NextCharacter);
+    QVERIFY(cursor.charFormat() == fmt);
+}
+
+int tst_QTextCursor::blockCount()
+{
+    int cnt = 0;
+    for (QTextBlock blk = doc->begin(); blk.isValid(); blk = blk.next())
+        ++cnt;
+    return cnt;
+}
+
+void tst_QTextCursor::endOfLine()
+{
+    doc->setPageSize(QSizeF(100000, INT_MAX));
+
+    QString text("First Line    \nSecond Line  ");
+    text.replace(QLatin1Char('\n'), QChar(QChar::LineSeparator));
+    cursor.insertText(text);
+
+    // ensure layouted
+    doc->documentLayout()->documentSize();
+
+    cursor.movePosition(QTextCursor::Start);
+
+    QCOMPARE(cursor.block().layout()->lineCount(), 2);
+
+    cursor.movePosition(QTextCursor::EndOfLine);
+    QCOMPARE(cursor.position(), 14);
+    cursor.movePosition(QTextCursor::NextCharacter);
+    QCOMPARE(cursor.position(), 15);
+    cursor.movePosition(QTextCursor::EndOfLine);
+    QCOMPARE(cursor.position(), 28);
+}
+
+class CursorListener : public QObject
+{
+    Q_OBJECT
+public:
+    CursorListener(QTextCursor *_cursor) : lastRecordedPosition(-1), lastRecordedAnchor(-1), recordingCount(0), cursor(_cursor) {}
+
+    int lastRecordedPosition;
+    int lastRecordedAnchor;
+    int recordingCount;
+
+public slots:
+    void recordCursorPosition()
+    {
+        lastRecordedPosition = cursor->position();
+        lastRecordedAnchor = cursor->anchor();
+        ++recordingCount;
+    }
+
+private:
+    QTextCursor *cursor;
+};
+
+void tst_QTextCursor::editBlocksDuringRemove()
+{
+    CursorListener listener(&cursor);
+
+    cursor.insertText("Hello World");
+    cursor.movePosition(QTextCursor::Start, QTextCursor::KeepAnchor);
+    QCOMPARE(cursor.selectedText(), QString("Hello World"));
+
+    connect(doc, SIGNAL(contentsChanged()), &listener, SLOT(recordCursorPosition()));
+    listener.recordingCount = 0;
+    cursor.deleteChar();
+
+    QCOMPARE(listener.recordingCount, 1);
+    QCOMPARE(listener.lastRecordedPosition, 0);
+    QCOMPARE(listener.lastRecordedAnchor, 0);
+
+    QVERIFY(doc->toPlainText().isEmpty());
+}
+
+void tst_QTextCursor::update_data()
+{
+    QTest::addColumn<QString>("text");
+    QTest::addColumn<int>("position");
+    QTest::addColumn<int>("anchor");
+    QTest::addColumn<int>("modifyPosition");
+    QTest::addColumn<int>("modifyAnchor");
+    QTest::addColumn<QString>("insertText");
+    QTest::addColumn<int>("expectedPosition");
+    QTest::addColumn<int>("expectedAnchor");
+
+    QString text("Hello big world");
+    int charsToDelete = 3;
+    QTest::newRow("removeInsideSelection")
+        << text
+        << /*position*/ 0
+        << /*anchor*/ text.length()
+        // delete 'big'
+        << 6
+        << 6 + charsToDelete
+        << QString() // don't insert anything, just remove
+        << /*expectedPosition*/ 0
+        << /*expectedAnchor*/ text.length() - charsToDelete
+        ;
+
+    text = "Hello big world";
+    charsToDelete = 3;
+    QTest::newRow("removeInsideSelectionWithSwappedAnchorAndPosition")
+        << text
+        << /*position*/ text.length()
+        << /*anchor*/ 0
+        // delete 'big'
+        << 6
+        << 6 + charsToDelete
+        << QString() // don't insert anything, just remove
+        << /*expectedPosition*/ text.length() - charsToDelete
+        << /*expectedAnchor*/ 0
+        ;
+
+
+    text = "Hello big world";
+    charsToDelete = 3;
+    QString textToInsert("small");
+    QTest::newRow("replaceInsideSelection")
+        << text
+        << /*position*/ 0
+        << /*anchor*/ text.length()
+        // delete 'big' ...
+        << 6
+        << 6 + charsToDelete
+        << textToInsert // ... and replace 'big' with 'small'
+        << /*expectedPosition*/ 0
+        << /*expectedAnchor*/ text.length() - charsToDelete + textToInsert.length()
+        ;
+
+    text = "Hello big world";
+    charsToDelete = 3;
+    textToInsert = "small";
+    QTest::newRow("replaceInsideSelectionWithSwappedAnchorAndPosition")
+        << text
+        << /*position*/ text.length()
+        << /*anchor*/ 0
+        // delete 'big' ...
+        << 6
+        << 6 + charsToDelete
+        << textToInsert // ... and replace 'big' with 'small'
+        << /*expectedPosition*/ text.length() - charsToDelete + textToInsert.length()
+        << /*expectedAnchor*/ 0
+        ;
+
+
+    text = "Hello big world";
+    charsToDelete = 3;
+    QTest::newRow("removeBeforeSelection")
+        << text
+        << /*position*/ text.length() - 5
+        << /*anchor*/ text.length()
+        // delete 'big'
+        << 6
+        << 6 + charsToDelete
+        << QString() // don't insert anything, just remove
+        << /*expectedPosition*/ text.length() - 5 - charsToDelete
+        << /*expectedAnchor*/ text.length() - charsToDelete
+        ;
+
+    text = "Hello big world";
+    charsToDelete = 3;
+    QTest::newRow("removeAfterSelection")
+        << text
+        << /*position*/ 0
+        << /*anchor*/ 4
+        // delete 'big'
+        << 6
+        << 6 + charsToDelete
+        << QString() // don't insert anything, just remove
+        << /*expectedPosition*/ 0
+        << /*expectedAnchor*/ 4
+        ;
+
+}
+
+void tst_QTextCursor::update()
+{
+    QFETCH(QString, text);
+
+    doc->setPlainText(text);
+
+    QFETCH(int, position);
+    QFETCH(int, anchor);
+
+    cursor.setPosition(anchor);
+    cursor.setPosition(position, QTextCursor::KeepAnchor);
+
+    QCOMPARE(cursor.position(), position);
+    QCOMPARE(cursor.anchor(), anchor);
+
+    QFETCH(int, modifyPosition);
+    QFETCH(int, modifyAnchor);
+
+    QTextCursor modifyCursor = cursor;
+    modifyCursor.setPosition(modifyAnchor);
+    modifyCursor.setPosition(modifyPosition, QTextCursor::KeepAnchor);
+
+    QCOMPARE(modifyCursor.position(), modifyPosition);
+    QCOMPARE(modifyCursor.anchor(), modifyAnchor);
+
+    QFETCH(QString, insertText);
+    modifyCursor.insertText(insertText);
+
+    QFETCH(int, expectedPosition);
+    QFETCH(int, expectedAnchor);
+
+    QCOMPARE(cursor.position(), expectedPosition);
+    QCOMPARE(cursor.anchor(), expectedAnchor);
+}
+
+void tst_QTextCursor::disallowSettingObjectIndicesOnCharFormats()
+{
+    QTextCharFormat fmt;
+    fmt.setObjectIndex(42);
+    cursor.insertText("Hey", fmt);
+    QCOMPARE(cursor.charFormat().objectIndex(), -1);
+
+    cursor.select(QTextCursor::Document);
+    cursor.mergeCharFormat(fmt);
+    QCOMPARE(doc->begin().begin().fragment().charFormat().objectIndex(), -1);
+
+    cursor.select(QTextCursor::Document);
+    cursor.setCharFormat(fmt);
+    QCOMPARE(doc->begin().begin().fragment().charFormat().objectIndex(), -1);
+
+    cursor.setBlockCharFormat(fmt);
+    QCOMPARE(cursor.blockCharFormat().objectIndex(), -1);
+
+    cursor.movePosition(QTextCursor::End);
+    cursor.insertBlock(QTextBlockFormat(), fmt);
+    QCOMPARE(cursor.blockCharFormat().objectIndex(), -1);
+
+    doc->clear();
+
+    QTextTable *table = cursor.insertTable(1, 1);
+    cursor.select(QTextCursor::Document);
+    cursor.setCharFormat(fmt);
+
+    cursor = table->cellAt(0, 0).firstCursorPosition();
+    QVERIFY(!cursor.isNull());
+    QCOMPARE(cursor.blockCharFormat().objectIndex(), table->objectIndex());
+}
+
+void tst_QTextCursor::blockAndColumnNumber()
+{
+    QCOMPARE(QTextCursor().columnNumber(), 0);
+    QCOMPARE(QTextCursor().blockNumber(), 0);
+
+    QCOMPARE(cursor.columnNumber(), 0);
+    QCOMPARE(cursor.blockNumber(), 0);
+    cursor.insertText("Hello");
+    QCOMPARE(cursor.columnNumber(), 5);
+    QCOMPARE(cursor.blockNumber(), 0);
+
+    cursor.insertBlock();
+    QCOMPARE(cursor.columnNumber(), 0);
+    QCOMPARE(cursor.blockNumber(), 1);
+    cursor.insertText("Blah");
+    QCOMPARE(cursor.blockNumber(), 1);
+
+    // trigger a layout
+    doc->documentLayout();
+
+    cursor.insertBlock();
+    QCOMPARE(cursor.columnNumber(), 0);
+    QCOMPARE(cursor.blockNumber(), 2);
+    cursor.insertText("Test");
+    QCOMPARE(cursor.columnNumber(), 4);
+    QCOMPARE(cursor.blockNumber(), 2);
+    cursor.insertText(QString(QChar(QChar::LineSeparator)));
+    QCOMPARE(cursor.columnNumber(), 0);
+    QCOMPARE(cursor.blockNumber(), 2);
+    cursor.insertText("A");
+    QCOMPARE(cursor.columnNumber(), 1);
+    QCOMPARE(cursor.blockNumber(), 2);
+}
+
+void tst_QTextCursor::movePositionEndOfLine()
+{
+    cursor.insertText("blah\nblah\n");
+    // Select part of the second line ("la")
+    cursor.setPosition(6);
+    cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 2);
+    QCOMPARE(cursor.selectedText(), QLatin1String("la"));
+
+    // trigger a layout
+    doc->documentLayout();
+
+    // Remove "la" and append "something" to the end in one undo operation
+    cursor.beginEditBlock();
+    cursor.removeSelectedText();
+    QTextCursor c2(doc);
+    c2.setPosition(7);
+    c2.insertText("foo"); // append to doc without touching the cursor.
+
+    QCOMPARE(cursor.position(), 6);
+    cursor.movePosition(QTextCursor::EndOfLine); // in an edit block visual movement is moved to the end of the paragraph
+    QCOMPARE(cursor.position(), 10);
+    cursor.endEditBlock();
+}
+
+void tst_QTextCursor::clearCells()
+{
+    QTextTable *table = cursor.insertTable(3, 5);
+    cursor.setPosition(table->cellAt(0,0).firstPosition()); // select cell 1 and cell 2
+    cursor.setPosition(table->cellAt(0,1).firstPosition(), QTextCursor::KeepAnchor);
+    cursor.deleteChar(); // should clear the cells, and not crash ;)
+}
+
+void tst_QTextCursor::task244408_wordUnderCursor_data()
+{
+    QTest::addColumn<QString>("input");
+    QTest::addColumn<QString>("expected");
+    QTest::newRow("trailingSpace") << QString::fromLatin1("foo ") << QString::fromLatin1("");
+    QTest::newRow("noTrailingSpace") << QString::fromLatin1("foo") << QString::fromLatin1("foo");
+}
+
+void tst_QTextCursor::task244408_wordUnderCursor()
+{
+    QFETCH(QString, input);
+    QFETCH(QString, expected);
+    cursor.insertText(input);
+    cursor.movePosition(QTextCursor::End);
+    cursor.select(QTextCursor::WordUnderCursor);
+    QCOMPARE(cursor.selectedText(), expected);
+}
+
+void tst_QTextCursor::adjustCursorsOnInsert()
+{
+    cursor.insertText("Some text before ");
+    int posBefore = cursor.position();
+    cursor.insertText("selected text");
+    int posAfter = cursor.position();
+    cursor.insertText(" some text afterwards");
+
+    QTextCursor selection = cursor;
+    selection.setPosition(posBefore);
+    selection.setPosition(posAfter, QTextCursor::KeepAnchor);
+
+    cursor.setPosition(posBefore-1);
+    cursor.insertText(QLatin1String("x"));
+    QCOMPARE(selection.anchor(), posBefore+1);
+    QCOMPARE(selection.position(), posAfter+1);
+    doc->undo();
+
+    cursor.setPosition(posBefore);
+    cursor.insertText(QLatin1String("x"));
+    QCOMPARE(selection.anchor(), posBefore+1);
+    QCOMPARE(selection.position(), posAfter+1);
+    doc->undo();
+
+    cursor.setPosition(posBefore+1);
+    cursor.insertText(QLatin1String("x"));
+    QCOMPARE(selection.anchor(), posBefore);
+    QCOMPARE(selection.position(), posAfter+1);
+    doc->undo();
+
+    cursor.setPosition(posAfter-1);
+    cursor.insertText(QLatin1String("x"));
+    QCOMPARE(selection.anchor(), posBefore);
+    QCOMPARE(selection.position(), posAfter+1);
+    doc->undo();
+
+    cursor.setPosition(posAfter);
+    cursor.insertText(QLatin1String("x"));
+    QCOMPARE(selection.anchor(), posBefore);
+    QCOMPARE(selection.position(), posAfter);
+    doc->undo();
+
+    cursor.setPosition(posAfter+1);
+    cursor.insertText(QLatin1String("x"));
+    QCOMPARE(selection.anchor(), posBefore);
+    QCOMPARE(selection.position(), posAfter);
+    doc->undo();
+
+    selection.setPosition(posAfter);
+    selection.setPosition(posBefore, QTextCursor::KeepAnchor);
+
+    cursor.setPosition(posBefore-1);
+    cursor.insertText(QLatin1String("x"));
+    QCOMPARE(selection.position(), posBefore+1);
+    QCOMPARE(selection.anchor(), posAfter+1);
+    doc->undo();
+
+    cursor.setPosition(posBefore);
+    cursor.insertText(QLatin1String("x"));
+    QCOMPARE(selection.position(), posBefore+1);
+    QCOMPARE(selection.anchor(), posAfter+1);
+    doc->undo();
+
+    cursor.setPosition(posBefore+1);
+    cursor.insertText(QLatin1String("x"));
+    QCOMPARE(selection.position(), posBefore);
+    QCOMPARE(selection.anchor(), posAfter+1);
+    doc->undo();
+
+    cursor.setPosition(posAfter-1);
+    cursor.insertText(QLatin1String("x"));
+    QCOMPARE(selection.position(), posBefore);
+    QCOMPARE(selection.anchor(), posAfter+1);
+    doc->undo();
+
+    cursor.setPosition(posAfter);
+    cursor.insertText(QLatin1String("x"));
+    QCOMPARE(selection.position(), posBefore);
+    QCOMPARE(selection.anchor(), posAfter+1);
+    doc->undo();
+
+    cursor.setPosition(posAfter+1);
+    cursor.insertText(QLatin1String("x"));
+    QCOMPARE(selection.position(), posBefore);
+    QCOMPARE(selection.anchor(), posAfter);
+    doc->undo();
+
+
+
+
+}
+
+QTEST_MAIN(tst_QTextCursor)
+#include "tst_qtextcursor.moc"