1 /* 2 Copyright (C) 2008 Holger Hans Peter Freyther 3 4 This library is free software; you can redistribute it and/or 5 modify it under the terms of the GNU Library General Public 6 License as published by the Free Software Foundation; either 7 version 2 of the License, or (at your option) any later version. 8 9 This library is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Library General Public License for more details. 13 14 You should have received a copy of the GNU Library General Public License 15 along with this library; see the file COPYING.LIB. If not, write to 16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 Boston, MA 02110-1301, USA. 18 */ 19 20 #include <QtTest/QtTest> 21 #include <QAction> 22 23 #include "qwebpage.h" 24 #include "qwebview.h" 25 #include "qwebframe.h" 26 #include "qwebhistory.h" 27 #include "qdebug.h" 28 29 class tst_QWebHistory : public QObject 30 { 31 Q_OBJECT 32 33 public: 34 tst_QWebHistory(); 35 virtual ~tst_QWebHistory(); 36 37 protected : 38 void loadPage(int nr) 39 { 40 frame->load(QUrl("qrc:/resources/page" + QString::number(nr) + ".html")); 41 waitForLoadFinished.exec(); 42 } 43 44 public slots: 45 void init(); 46 void cleanup(); 47 48 private slots: 49 void title(); 50 void count(); 51 void back(); 52 void forward(); 53 void itemAt(); 54 void goToItem(); 55 void items(); 56 void serialize_1(); //QWebHistory countity 57 void serialize_2(); //QWebHistory index 58 void serialize_3(); //QWebHistoryItem 59 void saveAndRestore_crash_1(); 60 void saveAndRestore_crash_2(); 61 void saveAndRestore_crash_3(); 62 void clear(); 63 64 65 private: 66 QWebPage* page; 67 QWebFrame* frame; 68 QWebHistory* hist; 69 QEventLoop waitForLoadFinished; //operation on history are asynchronous! 70 int histsize; 71 }; 72 73 tst_QWebHistory::tst_QWebHistory() 74 { 75 } 76 77 tst_QWebHistory::~tst_QWebHistory() 78 { 79 } 80 81 void tst_QWebHistory::init() 82 { 83 page = new QWebPage(this); 84 frame = page->mainFrame(); 85 connect(page, SIGNAL(loadFinished(bool)), &waitForLoadFinished, SLOT(quit())); 86 87 for (int i = 1;i < 6;i++) { 88 loadPage(i); 89 } 90 hist = page->history(); 91 histsize = 5; 92 } 93 94 void tst_QWebHistory::cleanup() 95 { 96 delete page; 97 } 98 99 /** 100 * Check QWebHistoryItem::title() method 101 */ 102 void tst_QWebHistory::title() 103 { 104 QCOMPARE(hist->currentItem().title(), QString("page5")); 105 } 106 107 /** 108 * Check QWebHistory::count() method 109 */ 110 void tst_QWebHistory::count() 111 { 112 QCOMPARE(hist->count(), histsize); 113 } 114 115 /** 116 * Check QWebHistory::back() method 117 */ 118 void tst_QWebHistory::back() 119 { 120 for (int i = histsize;i > 1;i--) { 121 QCOMPARE(page->mainFrame()->toPlainText(), QString("page") + QString::number(i)); 122 hist->back(); 123 waitForLoadFinished.exec(); 124 } 125 //try one more time (too many). crash test 126 hist->back(); 127 } 128 129 /** 130 * Check QWebHistory::forward() method 131 */ 132 void tst_QWebHistory::forward() 133 { 134 //rewind history :-) 135 while (hist->canGoBack()) { 136 hist->back(); 137 waitForLoadFinished.exec(); 138 } 139 140 for (int i = 1;i < histsize;i++) { 141 QCOMPARE(page->mainFrame()->toPlainText(), QString("page") + QString::number(i)); 142 hist->forward(); 143 waitForLoadFinished.exec(); 144 } 145 //try one more time (too many). crash test 146 hist->forward(); 147 } 148 149 /** 150 * Check QWebHistory::itemAt() method 151 */ 152 void tst_QWebHistory::itemAt() 153 { 154 for (int i = 1;i < histsize;i++) { 155 QCOMPARE(hist->itemAt(i - 1).title(), QString("page") + QString::number(i)); 156 QVERIFY(hist->itemAt(i - 1).isValid()); 157 } 158 //check out of range values 159 QVERIFY(!hist->itemAt(-1).isValid()); 160 QVERIFY(!hist->itemAt(histsize).isValid()); 161 } 162 163 /** 164 * Check QWebHistory::goToItem() method 165 */ 166 void tst_QWebHistory::goToItem() 167 { 168 QWebHistoryItem current = hist->currentItem(); 169 hist->back(); 170 waitForLoadFinished.exec(); 171 hist->back(); 172 waitForLoadFinished.exec(); 173 QVERIFY(hist->currentItem().title() != current.title()); 174 hist->goToItem(current); 175 waitForLoadFinished.exec(); 176 QCOMPARE(hist->currentItem().title(), current.title()); 177 } 178 179 /** 180 * Check QWebHistory::items() method 181 */ 182 void tst_QWebHistory::items() 183 { 184 QList<QWebHistoryItem> items = hist->items(); 185 //check count 186 QCOMPARE(histsize, items.count()); 187 188 //check order 189 for (int i = 1;i <= histsize;i++) { 190 QCOMPARE(items.at(i - 1).title(), QString("page") + QString::number(i)); 191 } 192 } 193 194 /** 195 * Check history state after serialization (pickle, persistent..) method 196 * Checks history size, history order 197 */ 198 void tst_QWebHistory::serialize_1() 199 { 200 QByteArray tmp; //buffer 201 QDataStream save(&tmp, QIODevice::WriteOnly); //here data will be saved 202 QDataStream load(&tmp, QIODevice::ReadOnly); //from here data will be loaded 203 204 save << *hist; 205 QVERIFY(save.status() == QDataStream::Ok); 206 QCOMPARE(hist->count(), histsize); 207 208 //check size of history 209 //load next page to find differences 210 loadPage(6); 211 QCOMPARE(hist->count(), histsize + 1); 212 load >> *hist; 213 QVERIFY(load.status() == QDataStream::Ok); 214 QCOMPARE(hist->count(), histsize); 215 216 //check order of historyItems 217 QList<QWebHistoryItem> items = hist->items(); 218 for (int i = 1;i <= histsize;i++) { 219 QCOMPARE(items.at(i - 1).title(), QString("page") + QString::number(i)); 220 } 221 } 222 223 /** 224 * Check history state after serialization (pickle, persistent..) method 225 * Checks history currentIndex value 226 */ 227 void tst_QWebHistory::serialize_2() 228 { 229 QByteArray tmp; //buffer 230 QDataStream save(&tmp, QIODevice::WriteOnly); //here data will be saved 231 QDataStream load(&tmp, QIODevice::ReadOnly); //from here data will be loaded 232 233 int oldCurrentIndex = hist->currentItemIndex(); 234 235 hist->back(); 236 waitForLoadFinished.exec(); 237 hist->back(); 238 waitForLoadFinished.exec(); 239 //check if current index was changed (make sure that it is not last item) 240 QVERIFY(hist->currentItemIndex() != oldCurrentIndex); 241 //save current index 242 oldCurrentIndex = hist->currentItemIndex(); 243 244 save << *hist; 245 QVERIFY(save.status() == QDataStream::Ok); 246 load >> *hist; 247 QVERIFY(load.status() == QDataStream::Ok); 248 249 //check current index 250 QCOMPARE(hist->currentItemIndex(), oldCurrentIndex); 251 } 252 253 /** 254 * Check history state after serialization (pickle, persistent..) method 255 * Checks QWebHistoryItem public property after serialization 256 */ 257 void tst_QWebHistory::serialize_3() 258 { 259 QByteArray tmp; //buffer 260 QDataStream save(&tmp, QIODevice::WriteOnly); //here data will be saved 261 QDataStream load(&tmp, QIODevice::ReadOnly); //from here data will be loaded 262 263 //prepare two different history items 264 QWebHistoryItem a = hist->currentItem(); 265 a.setUserData("A - user data"); 266 267 //check properties BEFORE serialization 268 QString title(a.title()); 269 QDateTime lastVisited(a.lastVisited()); 270 QUrl originalUrl(a.originalUrl()); 271 QUrl url(a.url()); 272 QVariant userData(a.userData()); 273 274 save << *hist; 275 QVERIFY(save.status() == QDataStream::Ok); 276 QVERIFY(!load.atEnd()); 277 hist->clear(); 278 QVERIFY(hist->count() == 1); 279 load >> *hist; 280 QVERIFY(load.status() == QDataStream::Ok); 281 QWebHistoryItem b = hist->currentItem(); 282 283 //check properties AFTER serialization 284 QCOMPARE(b.title(), title); 285 QCOMPARE(b.lastVisited(), lastVisited); 286 QCOMPARE(b.originalUrl(), originalUrl); 287 QCOMPARE(b.url(), url); 288 QCOMPARE(b.userData(), userData); 289 290 //Check if all data was read 291 QVERIFY(load.atEnd()); 292 } 293 294 static void saveHistory(QWebHistory* history, QByteArray* in) 295 { 296 in->clear(); 297 QDataStream save(in, QIODevice::WriteOnly); 298 save << *history; 299 } 300 301 static void restoreHistory(QWebHistory* history, QByteArray* out) 302 { 303 QDataStream load(out, QIODevice::ReadOnly); 304 load >> *history; 305 } 306 307 /** The test shouldn't crash */ 308 void tst_QWebHistory::saveAndRestore_crash_1() 309 { 310 QByteArray buffer; 311 saveHistory(hist, &buffer); 312 for (unsigned i = 0; i < 5; i++) { 313 restoreHistory(hist, &buffer); 314 saveHistory(hist, &buffer); 315 } 316 } 317 318 /** The test shouldn't crash */ 319 void tst_QWebHistory::saveAndRestore_crash_2() 320 { 321 QByteArray buffer; 322 saveHistory(hist, &buffer); 323 QWebPage* page2 = new QWebPage(this); 324 QWebHistory* hist2 = page2->history(); 325 for (unsigned i = 0; i < 5; i++) { 326 restoreHistory(hist2, &buffer); 327 saveHistory(hist2, &buffer); 328 } 329 delete page2; 330 } 331 332 /** The test shouldn't crash */ 333 void tst_QWebHistory::saveAndRestore_crash_3() 334 { 335 QByteArray buffer; 336 saveHistory(hist, &buffer); 337 QWebPage* page2 = new QWebPage(this); 338 QWebHistory* hist1 = hist; 339 QWebHistory* hist2 = page2->history(); 340 for (unsigned i = 0; i < 5; i++) { 341 restoreHistory(hist1, &buffer); 342 restoreHistory(hist2, &buffer); 343 QVERIFY(hist1->count() == hist2->count()); 344 QVERIFY(hist1->count() == histsize); 345 hist2->back(); 346 saveHistory(hist2, &buffer); 347 hist2->clear(); 348 } 349 delete page2; 350 } 351 352 /** ::clear */ 353 void tst_QWebHistory::clear() 354 { 355 QByteArray buffer; 356 357 QAction* actionBack = page->action(QWebPage::Back); 358 QVERIFY(actionBack->isEnabled()); 359 saveHistory(hist, &buffer); 360 QVERIFY(hist->count() > 1); 361 hist->clear(); 362 QVERIFY(hist->count() == 1); // Leave current item. 363 QVERIFY(!actionBack->isEnabled()); 364 365 QWebPage* page2 = new QWebPage(this); 366 QWebHistory* hist2 = page2->history(); 367 QVERIFY(hist2->count() == 0); 368 hist2->clear(); 369 QVERIFY(hist2->count() == 0); // Do not change anything. 370 delete page2; 371 } 372 373 QTEST_MAIN(tst_QWebHistory) 374 #include "tst_qwebhistory.moc" 375