tests/auto/qtextlist/tst_qtextlist.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the test suite of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 
       
    43 #include <QtTest/QtTest>
       
    44 
       
    45 #include <qtextdocument.h>
       
    46 #include <qtextdocumentfragment.h>
       
    47 #include <qtextlist.h>
       
    48 #include <qabstracttextdocumentlayout.h>
       
    49 #include <qtextcursor.h>
       
    50 #include "../qtextdocument/common.h"
       
    51 
       
    52 //TESTED_CLASS=
       
    53 //TESTED_FILES=
       
    54 
       
    55 class tst_QTextList : public QObject
       
    56 {
       
    57     Q_OBJECT
       
    58 
       
    59 public:
       
    60     tst_QTextList();
       
    61 
       
    62 
       
    63 public slots:
       
    64     void init();
       
    65     void cleanup();
       
    66 private slots:
       
    67     void item();
       
    68     void autoNumbering();
       
    69     void autoNumberingRTL();
       
    70     void romanNumbering();
       
    71     void romanNumberingLimit();
       
    72     void formatChange();
       
    73     void cursorNavigation();
       
    74     void partialRemoval();
       
    75     void formatReferenceChange();
       
    76     void ensureItemOrder();
       
    77     void add();
       
    78     void defaultIndent();
       
    79     void blockUpdate();
       
    80     void numbering_data();
       
    81     void numbering();
       
    82 
       
    83 private:
       
    84     QTextDocument *doc;
       
    85     QTextCursor cursor;
       
    86     QTestDocumentLayout *layout;
       
    87 };
       
    88 
       
    89 tst_QTextList::tst_QTextList()
       
    90 {}
       
    91 
       
    92 void tst_QTextList::init()
       
    93 {
       
    94     doc = new QTextDocument();
       
    95     layout = new QTestDocumentLayout(doc);
       
    96     doc->setDocumentLayout(layout);
       
    97     cursor = QTextCursor(doc);
       
    98 }
       
    99 
       
   100 void tst_QTextList::cleanup()
       
   101 {
       
   102     cursor = QTextCursor();
       
   103     delete doc;
       
   104     doc = 0;
       
   105 }
       
   106 
       
   107 void tst_QTextList::item()
       
   108 {
       
   109     // this is basically a test for the key() + 1 in QTextList::item.
       
   110     QTextList *list = cursor.createList(QTextListFormat());
       
   111     QVERIFY(list->item(0).blockFormat().objectIndex() != -1);
       
   112 }
       
   113 
       
   114 void tst_QTextList::autoNumbering()
       
   115 {
       
   116     QTextListFormat fmt;
       
   117     fmt.setStyle(QTextListFormat::ListLowerAlpha);
       
   118     QTextList *list = cursor.createList(fmt);
       
   119     QVERIFY(list);
       
   120 
       
   121     for (int i = 0; i < 27; ++i)
       
   122 	cursor.insertBlock();
       
   123 
       
   124     QVERIFY(list->count() == 28);
       
   125 
       
   126     QVERIFY(cursor.currentList());
       
   127     QVERIFY(cursor.currentList()->itemNumber(cursor.block()) == 27);
       
   128     QVERIFY(cursor.currentList()->itemText(cursor.block()) == "ab.");
       
   129 }
       
   130 
       
   131 void tst_QTextList::autoNumberingRTL()
       
   132 {
       
   133     QTextBlockFormat bfmt;
       
   134     bfmt.setLayoutDirection(Qt::RightToLeft);
       
   135     cursor.setBlockFormat(bfmt);
       
   136 
       
   137     QTextListFormat fmt;
       
   138     fmt.setStyle(QTextListFormat::ListUpperAlpha);
       
   139     QTextList *list = cursor.createList(fmt);
       
   140     QVERIFY(list);
       
   141 
       
   142     cursor.insertBlock();
       
   143 
       
   144     QVERIFY(list->count() == 2);
       
   145 
       
   146     QVERIFY(cursor.currentList()->itemText(cursor.block()) == ".B");
       
   147 }
       
   148 
       
   149 void tst_QTextList::romanNumbering()
       
   150 {
       
   151     QTextListFormat fmt;
       
   152     fmt.setStyle(QTextListFormat::ListUpperRoman);
       
   153     QTextList *list = cursor.createList(fmt);
       
   154     QVERIFY(list);
       
   155 
       
   156     for (int i = 0; i < 4998; ++i)
       
   157       cursor.insertBlock();
       
   158 
       
   159     QVERIFY(list->count() == 4999);
       
   160 
       
   161     QVERIFY(cursor.currentList());
       
   162     QVERIFY(cursor.currentList()->itemNumber(cursor.block()) == 4998);
       
   163     QVERIFY(cursor.currentList()->itemText(cursor.block()) == "MMMMCMXCIX.");
       
   164 }
       
   165 
       
   166 void tst_QTextList::romanNumberingLimit()
       
   167 {
       
   168     QTextListFormat fmt;
       
   169     fmt.setStyle(QTextListFormat::ListLowerRoman);
       
   170     QTextList *list = cursor.createList(fmt);
       
   171     QVERIFY(list);
       
   172 
       
   173     for (int i = 0; i < 4999; ++i)
       
   174       cursor.insertBlock();
       
   175 
       
   176     QVERIFY(list->count() == 5000);
       
   177 
       
   178     QVERIFY(cursor.currentList());
       
   179     QVERIFY(cursor.currentList()->itemNumber(cursor.block()) == 4999);
       
   180     QVERIFY(cursor.currentList()->itemText(cursor.block()) == "?.");
       
   181 }
       
   182 
       
   183 void tst_QTextList::formatChange()
       
   184 {
       
   185     // testing the formatChanged slot in QTextListManager
       
   186 
       
   187     /* <initial block>
       
   188      * 1.
       
   189      * 2.
       
   190      */
       
   191     QTextList *list = cursor.insertList(QTextListFormat::ListDecimal);
       
   192     QTextList *firstList = list;
       
   193     cursor.insertBlock();
       
   194 
       
   195     QVERIFY(list && list->count() == 2);
       
   196 
       
   197     QTextBlockFormat bfmt = cursor.blockFormat();
       
   198 //     QVERIFY(bfmt.object() == list);
       
   199 
       
   200     bfmt.setObjectIndex(-1);
       
   201     cursor.setBlockFormat(bfmt);
       
   202 
       
   203     QVERIFY(firstList->count() == 1);
       
   204 }
       
   205 
       
   206 void tst_QTextList::cursorNavigation()
       
   207 {
       
   208     // testing some cursor list methods
       
   209 
       
   210     /* <initial block>
       
   211      * 1.
       
   212      * 2.
       
   213      */
       
   214     cursor.insertList(QTextListFormat::ListDecimal);
       
   215     cursor.insertBlock();
       
   216 
       
   217     cursor.movePosition(QTextCursor::Start);
       
   218     cursor.movePosition(QTextCursor::NextBlock);
       
   219     cursor.movePosition(QTextCursor::NextBlock);
       
   220     QVERIFY(cursor.currentList());
       
   221     cursor.movePosition(QTextCursor::PreviousBlock);
       
   222     QVERIFY(cursor.currentList());
       
   223     QVERIFY(cursor.currentList()->itemNumber(cursor.block()) == 0);
       
   224 }
       
   225 
       
   226 void tst_QTextList::partialRemoval()
       
   227 {
       
   228     /* this is essentially a test for PieceTable::removeBlock to not miss any
       
   229        blocks with the blockChanged signal emission that actually get removed.
       
   230 
       
   231        It creates two lists, like this:
       
   232 
       
   233        1. Hello World
       
   234        a. Foobar
       
   235 
       
   236        and then removes from within the 'Hello World' into the 'Foobar' .
       
   237        There used to be no emission for the removal of the second (a.) block,
       
   238        causing list inconsistencies.
       
   239 
       
   240        */
       
   241 
       
   242     QTextList *firstList = cursor.insertList(QTextListFormat::ListDecimal);
       
   243 
       
   244     QTextCursor selStart = cursor;
       
   245     selStart.movePosition(QTextCursor::PreviousCharacter);
       
   246 
       
   247     cursor.insertText("Hello World");
       
   248 
       
   249     // position it well into the 'hello world' text.
       
   250     selStart.movePosition(QTextCursor::NextCharacter);
       
   251     selStart.movePosition(QTextCursor::NextCharacter);
       
   252     selStart.clearSelection();
       
   253 
       
   254     QPointer<QTextList> secondList = cursor.insertList(QTextListFormat::ListCircle);
       
   255     cursor.insertText("Foobar");
       
   256 
       
   257     // position it into the 'foo bar' text.
       
   258     cursor.movePosition(QTextCursor::PreviousCharacter);
       
   259     QTextCursor selEnd = cursor;
       
   260 
       
   261     // this creates a selection that includes parts of both text-fragments and also the list item of the second list.
       
   262     QTextCursor selection = selStart;
       
   263     selection.setPosition(selEnd.position(),  QTextCursor::KeepAnchor);
       
   264 
       
   265     selection.deleteChar(); // deletes the second list
       
   266 
       
   267     QVERIFY(!secondList);
       
   268     QVERIFY(!firstList->isEmpty());
       
   269 
       
   270     doc->undo();
       
   271 }
       
   272 
       
   273 void tst_QTextList::formatReferenceChange()
       
   274 {
       
   275     QTextList *list = cursor.insertList(QTextListFormat::ListDecimal);
       
   276     cursor.insertText("Some Content...");
       
   277     cursor.insertBlock(QTextBlockFormat());
       
   278 
       
   279     cursor.setPosition(list->item(0).position());
       
   280     int listItemStartPos = cursor.position();
       
   281     cursor.movePosition(QTextCursor::NextBlock);
       
   282     int listItemLen = cursor.position() - listItemStartPos;
       
   283     layout->expect(listItemStartPos, listItemLen, listItemLen);
       
   284 
       
   285     QTextListFormat fmt = list->format();
       
   286     fmt.setStyle(QTextListFormat::ListCircle);
       
   287     list->setFormat(fmt);
       
   288 
       
   289     QVERIFY(layout->called);
       
   290     QVERIFY(!layout->error);
       
   291 }
       
   292 
       
   293 void tst_QTextList::ensureItemOrder()
       
   294 {
       
   295     /*
       
   296      * Insert a new list item before the first one and verify the blocks
       
   297      * are sorted after that.
       
   298      */
       
   299     QTextList *list = cursor.insertList(QTextListFormat::ListDecimal);
       
   300 
       
   301     QTextBlockFormat fmt = cursor.blockFormat();
       
   302     cursor.movePosition(QTextCursor::Start);
       
   303     cursor.insertBlock(fmt);
       
   304 
       
   305     QCOMPARE(list->item(0).position(), 1);
       
   306     QCOMPARE(list->item(1).position(), 2);
       
   307 }
       
   308 
       
   309 void tst_QTextList::add()
       
   310 {
       
   311     QTextList *list = cursor.insertList(QTextListFormat::ListDecimal);
       
   312     cursor.insertBlock(QTextBlockFormat());
       
   313     QCOMPARE(list->count(), 1);
       
   314     cursor.insertBlock(QTextBlockFormat());
       
   315     list->add(cursor.block());
       
   316     QCOMPARE(list->count(), 2);
       
   317 }
       
   318 
       
   319 // Task #72036
       
   320 void tst_QTextList::defaultIndent()
       
   321 {
       
   322     QTextListFormat fmt;
       
   323     QCOMPARE(fmt.indent(), 1);
       
   324 }
       
   325 
       
   326 void tst_QTextList::blockUpdate()
       
   327 {
       
   328     // three items
       
   329     QTextList *list = cursor.insertList(QTextListFormat::ListDecimal);
       
   330     cursor.insertBlock();
       
   331     cursor.insertBlock();
       
   332 
       
   333     // remove second, needs also update on the third
       
   334     // since the numbering might have changed
       
   335     const int len = cursor.position() + cursor.block().length() - 1;
       
   336     layout->expect(1, len, len);
       
   337     list->remove(list->item(1));
       
   338     QVERIFY(!layout->error);
       
   339 }
       
   340 
       
   341 void tst_QTextList::numbering_data()
       
   342 {
       
   343     QTest::addColumn<int>("format");
       
   344     QTest::addColumn<int>("number");
       
   345     QTest::addColumn<QString>("result");
       
   346 
       
   347     QTest::newRow("E.") << int(QTextListFormat::ListUpperAlpha) << 5 << "E.";
       
   348     QTest::newRow("abc.") << int(QTextListFormat::ListLowerAlpha) << (26 + 2) * 26 + 3 << "abc.";
       
   349     QTest::newRow("12.") << int(QTextListFormat::ListDecimal) << 12 << "12.";
       
   350     QTest::newRow("XXIV.") << int(QTextListFormat::ListUpperRoman) << 24 << "XXIV.";
       
   351     QTest::newRow("VIII.") << int(QTextListFormat::ListUpperRoman) << 8 << "VIII.";
       
   352     QTest::newRow("xxx.") << int(QTextListFormat::ListLowerRoman) << 30 << "xxx.";
       
   353     QTest::newRow("xxix.") << int(QTextListFormat::ListLowerRoman) << 29 << "xxix.";
       
   354 //    QTest::newRow("xxx. alpha") << int(QTextListFormat::ListLowerAlpha) << (24 * 26 + 24) * 26 + 24  << "xxx."; //Too slow
       
   355 }
       
   356 
       
   357 void tst_QTextList::numbering()
       
   358 {
       
   359     QFETCH(int, format);
       
   360     QFETCH(int, number);
       
   361     QFETCH(QString, result);
       
   362 
       
   363 
       
   364     QTextListFormat fmt;
       
   365     fmt.setStyle(QTextListFormat::Style(format));
       
   366     QTextList *list = cursor.createList(fmt);
       
   367     QVERIFY(list);
       
   368 
       
   369     for (int i = 1; i < number; ++i)
       
   370         cursor.insertBlock();
       
   371 
       
   372     QCOMPARE(list->count(), number);
       
   373 
       
   374     QVERIFY(cursor.currentList());
       
   375     QCOMPARE(cursor.currentList()->itemNumber(cursor.block()), number - 1);
       
   376     QCOMPARE(cursor.currentList()->itemText(cursor.block()), result);
       
   377 }
       
   378 
       
   379 QTEST_MAIN(tst_QTextList)
       
   380 #include "tst_qtextlist.moc"