📄 test_regression.cpp
字号:
/** * This file is part of the KDE project * * Copyright (C) 2001,2003 Peter Kelly (pmk@post.com) * Copyright (C) 2003,2004 Stephan Kulow (coolo@kde.org) * Copyright (C) 2004 Dirk Mueller ( mueller@kde.org ) * * 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 <stdlib.h>#include <sys/time.h>#include <sys/resource.h>#include <sys/types.h>#include <unistd.h>#include <pwd.h>#include <signal.h>#include <kapplication.h>#include <qimage.h>#include <qfile.h>#include "test_regression.h"#include <unistd.h>#include <stdio.h>#include "css/cssstyleselector.h"#include <dom_string.h>#include "rendering/render_style.h"#include "rendering/render_layer.h"#include "khtmldefaults.h"//We don't use the default fonts, though, but traditional testregression ones#undef HTML_DEFAULT_VIEW_FONT#undef HTML_DEFAULT_VIEW_FIXED_FONT#undef HTML_DEFAULT_VIEW_SERIF_FONT#undef HTML_DEFAULT_VIEW_SANSSERIF_FONT#undef HTML_DEFAULT_VIEW_CURSIVE_FONT#undef HTML_DEFAULT_VIEW_FANTASY_FONT#define HTML_DEFAULT_VIEW_FONT "helvetica"#define HTML_DEFAULT_VIEW_FIXED_FONT "courier"#define HTML_DEFAULT_VIEW_SERIF_FONT "times"#define HTML_DEFAULT_VIEW_SANSSERIF_FONT "helvetica"#define HTML_DEFAULT_VIEW_CURSIVE_FONT "helvetica"#define HTML_DEFAULT_VIEW_FANTASY_FONT "helvetica"#include <kaction.h>#include <kcmdlineargs.h>#include "khtml_factory.h"#include <kio/job.h>#include <kmainwindow.h>#include <ksimpleconfig.h>#include <kglobalsettings.h>#include <qcolor.h>#include <qcursor.h>#include <qdir.h>#include <qobject.h>#include <qpushbutton.h>#include <qscrollview.h>#include <qstring.h>#include <qtextstream.h>#include <qvaluelist.h>#include <qwidget.h>#include <qfileinfo.h>#include <qtimer.h>#include <kstatusbar.h>#include <qfileinfo.h>#include "misc/decoder.h"#include "dom/dom2_range.h"#include "dom/dom_exception.h"#include "dom/html_document.h"#include "html/htmltokenizer.h"#include "khtml_part.h"#include "khtmlpart_p.h"#include <kparts/browserextension.h>#include "khtmlview.h"#include "rendering/render_replaced.h"#include "xml/dom_docimpl.h"#include "html/html_baseimpl.h"#include "dom/dom_doc.h"#include "misc/loader.h"#include "ecma/kjs_binding.h"#include "ecma/kjs_dom.h"#include "ecma/kjs_window.h"#include "ecma/kjs_binding.h"#include "ecma/kjs_proxy.h"using namespace khtml;using namespace DOM;using namespace KJS;bool visual = false;pid_t xvfb;// -------------------------------------------------------------------------PartMonitor *PartMonitor::sm_highestMonitor = NULL;PartMonitor::PartMonitor(KHTMLPart *_part){ m_part = _part; m_completed = false; connect(m_part,SIGNAL(completed()),this,SLOT(partCompleted())); m_timer_waits = 200; m_timeout_timer = new QTimer(this);}PartMonitor::~PartMonitor(){ if (this == sm_highestMonitor) sm_highestMonitor = 0;}void PartMonitor::waitForCompletion(){ if (!m_completed) { if (sm_highestMonitor) return; sm_highestMonitor = this; kapp->enter_loop(); //connect(m_timeout_timer, SIGNAL(timeout()), this, SLOT( timeout() ) ); //m_timeout_timer->stop(); //m_timeout_timer->start( visual ? 100 : 2, true ); } QTimer::singleShot( 0, this, SLOT( finishTimers() ) ); kapp->enter_loop();}void PartMonitor::timeout(){ kapp->exit_loop();}void PartMonitor::finishTimers(){ KJS::Window *w = KJS::Window::retrieveWindow( m_part ); --m_timer_waits; if ( m_timer_waits && (w && w->winq->hasTimers()) || m_part->inProgress()) { // wait a bit QTimer::singleShot( 10, this, SLOT(finishTimers() ) ); return; } kapp->exit_loop();}void PartMonitor::partCompleted(){ m_completed = true; RenderWidget::flushWidgetResizes(); m_timeout_timer->stop(); connect(m_timeout_timer, SIGNAL(timeout()),this, SLOT( timeout() ) ); m_timeout_timer->start( visual ? 100 : 2, true ); disconnect(m_part,SIGNAL(completed()),this,SLOT(partCompleted()));}void signal_handler( int ){ printf( "timeout\n" ); abort();}// -------------------------------------------------------------------------RegTestObject::RegTestObject(ExecState *exec, RegressionTest *_regTest){ m_regTest = _regTest; putDirect("print",new RegTestFunction(exec,m_regTest,RegTestFunction::Print,1), DontEnum); putDirect("reportResult",new RegTestFunction(exec,m_regTest,RegTestFunction::ReportResult,3), DontEnum); putDirect("checkOutput",new RegTestFunction(exec,m_regTest,RegTestFunction::CheckOutput,1), DontEnum); // add "quit" for compatibility with the mozilla js shell putDirect("quit", new RegTestFunction(exec,m_regTest,RegTestFunction::Quit,1), DontEnum );}RegTestFunction::RegTestFunction(ExecState* /*exec*/, RegressionTest *_regTest, int _id, int length){ m_regTest = _regTest; id = _id; putDirect("length",length);}bool RegTestFunction::implementsCall() const{ return true;}Value RegTestFunction::call(ExecState *exec, Object &/*thisObj*/, const List &args){ Value result = Undefined(); if ( m_regTest->ignore_errors ) return result; switch (id) { case Print: { UString str = args[0].toString(exec); if ( str.qstring().lower().find( "failed!" ) >= 0 ) m_regTest->saw_failure = true; QString res = str.qstring().replace('\007', ""); m_regTest->m_currentOutput += res + "\n"; break; } case ReportResult: { bool passed = args[0].toBoolean(exec); QString description = args[1].toString(exec).qstring(); if (args[1].isA(UndefinedType) || args[1].isA(NullType)) description = QString::null; m_regTest->reportResult(passed,description); if ( !passed ) m_regTest->saw_failure = true; break; } case CheckOutput: { DOM::DocumentImpl* docimpl = static_cast<DOM::DocumentImpl*>( m_regTest->m_part->document().handle() ); if ( docimpl && docimpl->view() && docimpl->renderer() ) { docimpl->updateRendering(); docimpl->view()->layout(); } QString filename = args[0].toString(exec).qstring(); filename = RegressionTest::curr->m_currentCategory+"/"+filename; int failures = RegressionTest::NoFailure; if ( m_regTest->m_genOutput ) { if ( !m_regTest->reportResult( m_regTest->checkOutput(filename+"-dom"), "Script-generated " + filename + "-dom") ) failures |= RegressionTest::DomFailure; if ( !m_regTest->reportResult( m_regTest->checkOutput(filename+"-render"), "Script-generated " + filename + "-render") ) failures |= RegressionTest::RenderFailure; } else { // compare with output file if ( !m_regTest->reportResult( m_regTest->checkOutput(filename+"-dom"), "DOM") ) failures |= RegressionTest::DomFailure; if ( !m_regTest->reportResult( m_regTest->checkOutput(filename+"-render"), "RENDER") ) failures |= RegressionTest::RenderFailure; } RegressionTest::curr->doFailureReport( filename, failures ); break; } case Quit: m_regTest->reportResult(true, "Called quit" ); if ( !m_regTest->saw_failure ) m_regTest->ignore_errors = true; break; } return result;}// -------------------------------------------------------------------------KHTMLPartObject::KHTMLPartObject(ExecState *exec, KHTMLPart *_part){ m_part = _part; putDirect("openPage", new KHTMLPartFunction(exec,m_part,KHTMLPartFunction::OpenPage,1), DontEnum); putDirect("openPageAsUrl", new KHTMLPartFunction(exec,m_part,KHTMLPartFunction::OpenPageAsUrl,1), DontEnum); putDirect("begin", new KHTMLPartFunction(exec,m_part,KHTMLPartFunction::Begin,1), DontEnum); putDirect("write", new KHTMLPartFunction(exec,m_part,KHTMLPartFunction::Write,1), DontEnum); putDirect("end", new KHTMLPartFunction(exec,m_part,KHTMLPartFunction::End,0), DontEnum); putDirect("executeScript", new KHTMLPartFunction(exec,m_part,KHTMLPartFunction::ExecuteScript,0), DontEnum); putDirect("processEvents", new KHTMLPartFunction(exec,m_part,KHTMLPartFunction::ProcessEvents,0), DontEnum);}Value KHTMLPartObject::get(ExecState *exec, const Identifier &propertyName) const{ if (propertyName == "document") return getDOMNode(exec,m_part->document()); else if (propertyName == "window") return Object(KJS::Window::retrieveWindow(m_part)); else return ObjectImp::get(exec,propertyName);}KHTMLPartFunction::KHTMLPartFunction(ExecState */*exec*/, KHTMLPart *_part, int _id, int length){ m_part = _part; id = _id; putDirect("length",length);}bool KHTMLPartFunction::implementsCall() const{ return true;}Value KHTMLPartFunction::call(ExecState *exec, Object &/*thisObj*/, const List &args){ Value result = Undefined(); switch (id) { case OpenPage: { if (args[0].type() == NullType || args[0].type() == NullType) { exec->setException(Error::create(exec, GeneralError,"No filename specified")); return Undefined(); } QString filename = args[0].toString(exec).qstring(); QString fullFilename = QFileInfo(RegressionTest::curr->m_currentBase+"/"+filename).absFilePath(); KURL url; url.setProtocol("file"); url.setPath(fullFilename); PartMonitor pm(m_part); m_part->openURL(url); pm.waitForCompletion(); kapp->processEvents(60000); break; } case OpenPageAsUrl: { if (args[0].type() == NullType || args[0].type() == UndefinedType) { exec->setException(Error::create(exec, GeneralError,"No filename specified")); return Undefined(); } if (args[1].type() == NullType || args[1].type() == UndefinedType) { exec->setException(Error::create(exec, GeneralError,"No url specified")); return Undefined(); } QString filename = args[0].toString(exec).qstring(); QString url = args[1].toString(exec).qstring(); QFile file(RegressionTest::curr->m_currentBase+"/"+filename); if (!file.open(IO_ReadOnly)) { exec->setException(Error::create(exec, GeneralError, QString("Error reading " + filename).latin1())); } else { QByteArray fileData; QDataStream stream(fileData,IO_WriteOnly); char buf[1024]; int bytesread; while (!file.atEnd()) { bytesread = file.readBlock(buf,1024); stream.writeRawBytes(buf,bytesread); } file.close(); QString contents(fileData); PartMonitor pm(m_part); m_part->begin(KURL( url )); m_part->write(contents); m_part->end(); pm.waitForCompletion(); } kapp->processEvents(60000); break; } case Begin: { QString url = args[0].toString(exec).qstring(); m_part->begin(KURL( url )); break; } case Write: { QString str = args[0].toString(exec).qstring(); m_part->write(str); break; } case End: { m_part->end(); kapp->processEvents(60000); break; } case ExecuteScript: { QString code = args[0].toString(exec).qstring(); Completion comp; KJSProxy *proxy = m_part->jScript(); proxy->evaluate("",0,code,0,&comp); if (comp.complType() == Throw) exec->setException(comp.value()); kapp->processEvents(60000); break; } case ProcessEvents: { kapp->processEvents(60000); break; } } return result;}// -------------------------------------------------------------------------static KCmdLineOptions options[] ={
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -