/* Copyright (C) 2008 Holger Hans Peter Freyther This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include <QtTest/QtTest> #include <QAction> #include "qwebpage.h" #include "qwebview.h" #include "qwebframe.h" #include "qwebhistory.h" #include "qdebug.h" class tst_QWebHistory : public QObject { Q_OBJECT public: tst_QWebHistory(); virtual ~tst_QWebHistory(); protected : void loadPage(int nr) { frame->load(QUrl("qrc:/resources/page" + QString::number(nr) + ".html")); waitForLoadFinished.exec(); } public slots: void init(); void cleanup(); private slots: void title(); void count(); void back(); void forward(); void itemAt(); void goToItem(); void items(); void serialize_1(); //QWebHistory countity void serialize_2(); //QWebHistory index void serialize_3(); //QWebHistoryItem void saveAndRestore_crash_1(); void saveAndRestore_crash_2(); void saveAndRestore_crash_3(); void clear(); private: QWebPage* page; QWebFrame* frame; QWebHistory* hist; QEventLoop waitForLoadFinished; //operation on history are asynchronous! int histsize; }; tst_QWebHistory::tst_QWebHistory() { } tst_QWebHistory::~tst_QWebHistory() { } void tst_QWebHistory::init() { page = new QWebPage(this); frame = page->mainFrame(); connect(page, SIGNAL(loadFinished(bool)), &waitForLoadFinished, SLOT(quit())); for (int i = 1;i < 6;i++) { loadPage(i); } hist = page->history(); histsize = 5; } void tst_QWebHistory::cleanup() { delete page; } /** * Check QWebHistoryItem::title() method */ void tst_QWebHistory::title() { QCOMPARE(hist->currentItem().title(), QString("page5")); } /** * Check QWebHistory::count() method */ void tst_QWebHistory::count() { QCOMPARE(hist->count(), histsize); } /** * Check QWebHistory::back() method */ void tst_QWebHistory::back() { for (int i = histsize;i > 1;i--) { QCOMPARE(page->mainFrame()->toPlainText(), QString("page") + QString::number(i)); hist->back(); waitForLoadFinished.exec(); } //try one more time (too many). crash test hist->back(); } /** * Check QWebHistory::forward() method */ void tst_QWebHistory::forward() { //rewind history :-) while (hist->canGoBack()) { hist->back(); waitForLoadFinished.exec(); } for (int i = 1;i < histsize;i++) { QCOMPARE(page->mainFrame()->toPlainText(), QString("page") + QString::number(i)); hist->forward(); waitForLoadFinished.exec(); } //try one more time (too many). crash test hist->forward(); } /** * Check QWebHistory::itemAt() method */ void tst_QWebHistory::itemAt() { for (int i = 1;i < histsize;i++) { QCOMPARE(hist->itemAt(i - 1).title(), QString("page") + QString::number(i)); QVERIFY(hist->itemAt(i - 1).isValid()); } //check out of range values QVERIFY(!hist->itemAt(-1).isValid()); QVERIFY(!hist->itemAt(histsize).isValid()); } /** * Check QWebHistory::goToItem() method */ void tst_QWebHistory::goToItem() { QWebHistoryItem current = hist->currentItem(); hist->back(); waitForLoadFinished.exec(); hist->back(); waitForLoadFinished.exec(); QVERIFY(hist->currentItem().title() != current.title()); hist->goToItem(current); waitForLoadFinished.exec(); QCOMPARE(hist->currentItem().title(), current.title()); } /** * Check QWebHistory::items() method */ void tst_QWebHistory::items() { QList<QWebHistoryItem> items = hist->items(); //check count QCOMPARE(histsize, items.count()); //check order for (int i = 1;i <= histsize;i++) { QCOMPARE(items.at(i - 1).title(), QString("page") + QString::number(i)); } } /** * Check history state after serialization (pickle, persistent..) method * Checks history size, history order */ void tst_QWebHistory::serialize_1() { QByteArray tmp; //buffer QDataStream save(&tmp, QIODevice::WriteOnly); //here data will be saved QDataStream load(&tmp, QIODevice::ReadOnly); //from here data will be loaded save << *hist; QVERIFY(save.status() == QDataStream::Ok); QCOMPARE(hist->count(), histsize); //check size of history //load next page to find differences loadPage(6); QCOMPARE(hist->count(), histsize + 1); load >> *hist; QVERIFY(load.status() == QDataStream::Ok); QCOMPARE(hist->count(), histsize); //check order of historyItems QList<QWebHistoryItem> items = hist->items(); for (int i = 1;i <= histsize;i++) { QCOMPARE(items.at(i - 1).title(), QString("page") + QString::number(i)); } } /** * Check history state after serialization (pickle, persistent..) method * Checks history currentIndex value */ void tst_QWebHistory::serialize_2() { QByteArray tmp; //buffer QDataStream save(&tmp, QIODevice::WriteOnly); //here data will be saved QDataStream load(&tmp, QIODevice::ReadOnly); //from here data will be loaded int oldCurrentIndex = hist->currentItemIndex(); hist->back(); waitForLoadFinished.exec(); hist->back(); waitForLoadFinished.exec(); //check if current index was changed (make sure that it is not last item) QVERIFY(hist->currentItemIndex() != oldCurrentIndex); //save current index oldCurrentIndex = hist->currentItemIndex(); save << *hist; QVERIFY(save.status() == QDataStream::Ok); load >> *hist; QVERIFY(load.status() == QDataStream::Ok); //check current index QCOMPARE(hist->currentItemIndex(), oldCurrentIndex); } /** * Check history state after serialization (pickle, persistent..) method * Checks QWebHistoryItem public property after serialization */ void tst_QWebHistory::serialize_3() { QByteArray tmp; //buffer QDataStream save(&tmp, QIODevice::WriteOnly); //here data will be saved QDataStream load(&tmp, QIODevice::ReadOnly); //from here data will be loaded //prepare two different history items QWebHistoryItem a = hist->currentItem(); a.setUserData("A - user data"); //check properties BEFORE serialization QString title(a.title()); QDateTime lastVisited(a.lastVisited()); QUrl originalUrl(a.originalUrl()); QUrl url(a.url()); QVariant userData(a.userData()); save << *hist; QVERIFY(save.status() == QDataStream::Ok); QVERIFY(!load.atEnd()); hist->clear(); QVERIFY(hist->count() == 1); load >> *hist; QVERIFY(load.status() == QDataStream::Ok); QWebHistoryItem b = hist->currentItem(); //check properties AFTER serialization QCOMPARE(b.title(), title); QCOMPARE(b.lastVisited(), lastVisited); QCOMPARE(b.originalUrl(), originalUrl); QCOMPARE(b.url(), url); QCOMPARE(b.userData(), userData); //Check if all data was read QVERIFY(load.atEnd()); } static void saveHistory(QWebHistory* history, QByteArray* in) { in->clear(); QDataStream save(in, QIODevice::WriteOnly); save << *history; } static void restoreHistory(QWebHistory* history, QByteArray* out) { QDataStream load(out, QIODevice::ReadOnly); load >> *history; } /** The test shouldn't crash */ void tst_QWebHistory::saveAndRestore_crash_1() { QByteArray buffer; saveHistory(hist, &buffer); for (unsigned i = 0; i < 5; i++) { restoreHistory(hist, &buffer); saveHistory(hist, &buffer); } } /** The test shouldn't crash */ void tst_QWebHistory::saveAndRestore_crash_2() { QByteArray buffer; saveHistory(hist, &buffer); QWebPage* page2 = new QWebPage(this); QWebHistory* hist2 = page2->history(); for (unsigned i = 0; i < 5; i++) { restoreHistory(hist2, &buffer); saveHistory(hist2, &buffer); } delete page2; } /** The test shouldn't crash */ void tst_QWebHistory::saveAndRestore_crash_3() { QByteArray buffer; saveHistory(hist, &buffer); QWebPage* page2 = new QWebPage(this); QWebHistory* hist1 = hist; QWebHistory* hist2 = page2->history(); for (unsigned i = 0; i < 5; i++) { restoreHistory(hist1, &buffer); restoreHistory(hist2, &buffer); QVERIFY(hist1->count() == hist2->count()); QVERIFY(hist1->count() == histsize); hist2->back(); saveHistory(hist2, &buffer); hist2->clear(); } delete page2; } /** ::clear */ void tst_QWebHistory::clear() { QByteArray buffer; QAction* actionBack = page->action(QWebPage::Back); QVERIFY(actionBack->isEnabled()); saveHistory(hist, &buffer); QVERIFY(hist->count() > 1); hist->clear(); QVERIFY(hist->count() == 1); // Leave current item. QVERIFY(!actionBack->isEnabled()); QWebPage* page2 = new QWebPage(this); QWebHistory* hist2 = page2->history(); QVERIFY(hist2->count() == 0); hist2->clear(); QVERIFY(hist2->count() == 0); // Do not change anything. delete page2; } QTEST_MAIN(tst_QWebHistory) #include "tst_qwebhistory.moc"