File indexing completed on 2024-04-28 15:25:13

0001 /**
0002  * This file is part of the KDE project
0003  *
0004  * Copyright (C) 2001,2003 Peter Kelly (pmk@post.com)
0005  *
0006  * This library is free software; you can redistribute it and/or
0007  * modify it under the terms of the GNU Library General Public
0008  * License as published by the Free Software Foundation; either
0009  * version 2 of the License, or (at your option) any later version.
0010  *
0011  * This library is distributed in the hope that it will be useful,
0012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014  * Library General Public License for more details.
0015  *
0016  * You should have received a copy of the GNU Library General Public License
0017  * along with this library; see the file COPYING.LIB.  If not, write to
0018  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0019  * Boston, MA 02110-1301, USA.
0020  *
0021  */
0022 
0023 #ifndef TEST_REGRESSION_H
0024 #define TEST_REGRESSION_H
0025 
0026 #include <khtml_part.h>
0027 #include <QObject>
0028 #include <QStack>
0029 #include <QUrl>
0030 #include <kjs/ustring.h>
0031 #include <kjs/object.h>
0032 #include <kjs/interpreter.h>
0033 #include "ecma/kjs_binding.h"
0034 
0035 class RegressionTest;
0036 class QTimer;
0037 class QEventLoop;
0038 
0039 /**
0040  * @internal
0041  */
0042 class PartMonitor : public QObject
0043 {
0044     Q_OBJECT
0045 public:
0046     PartMonitor(KHTMLPart *_part);
0047     ~PartMonitor();
0048     void waitForCompletion();
0049     void enterLoop();
0050     void exitLoop();
0051     static PartMonitor *sm_highestMonitor;
0052     QStack<QEventLoop *> m_eventLoopStack;
0053     bool m_completed;
0054     KHTMLPart *m_part;
0055     int m_timer_waits;
0056     QTimer *m_timeout_timer;
0057 public Q_SLOTS:
0058     void partCompleted();
0059     void timeout();
0060     void finishTimers();
0061 };
0062 
0063 /**
0064  * @internal
0065  */
0066 class RegTestObject : public KJS::JSObject
0067 {
0068 public:
0069     RegTestObject(KJS::ExecState *exec, RegressionTest *_regTest);
0070 
0071 private:
0072     RegressionTest *m_regTest;
0073 };
0074 
0075 /**
0076  * @internal
0077  */
0078 class RegTestFunction : public KJS::JSObject
0079 {
0080 public:
0081     RegTestFunction(KJS::ExecState *exec, RegressionTest *_regTest, int _id, int length);
0082 
0083     bool implementsCall() const;
0084     KJS::JSValue *callAsFunction(KJS::ExecState *exec, KJS::JSObject *thisObj, const KJS::List &args);
0085 
0086     enum { Print, ReportResult, CheckOutput, Quit };
0087 
0088 private:
0089     RegressionTest *m_regTest;
0090     int id;
0091 };
0092 
0093 /**
0094  * @internal
0095  */
0096 class KHTMLPartObject : public KJS::JSObject
0097 {
0098 public:
0099     KHTMLPartObject(KJS::ExecState *exec, KHTMLPart *_part);
0100 
0101     virtual bool getOwnPropertySlot(KJS::ExecState *exec, const KJS::Identifier &propertyName, KJS::PropertySlot &slot);
0102 private:
0103     static KJS::JSValue *winGetter(KJS::ExecState *, KJS::JSObject *, const KJS::Identifier &, const KJS::PropertySlot &);
0104     static KJS::JSValue *docGetter(KJS::ExecState *, KJS::JSObject *, const KJS::Identifier &, const KJS::PropertySlot &);
0105     KHTMLPart *m_part;
0106 };
0107 
0108 /**
0109  * @internal
0110  */
0111 class KHTMLPartFunction : public KJS::JSObject
0112 {
0113 public:
0114     KHTMLPartFunction(KJS::ExecState *exec, KHTMLPart *_part, int _id, int length);
0115 
0116     bool implementsCall() const;
0117     KJS::JSValue *callAsFunction(KJS::ExecState *exec, KJS::JSObject *thisObj, const KJS::List &args);
0118 
0119     enum { OpenPage, OpenPageAsUrl, Begin, Write, End, ExecuteScript, ProcessEvents };
0120 private:
0121     KHTMLPart *m_part;
0122     int id;
0123 };
0124 
0125 namespace KJS
0126 {
0127 class ScriptInterpreter;
0128 }
0129 
0130 /**
0131  * @internal
0132  */
0133 class RegressionTest : public QObject
0134 {
0135     Q_OBJECT
0136 public:
0137 
0138     RegressionTest(KHTMLPart *part, const QString &baseDir, const QString &outputDir, const QString &baselineDir,
0139                    bool _genOutput, bool runJS, bool runHTML);
0140     ~RegressionTest();
0141 
0142     enum OutputType { DOMTree, RenderTree };
0143     QString getPartOutput(OutputType type);
0144     void getPartDOMOutput(QTextStream &outputStream, KHTMLPart *part, uint indent);
0145     void dumpRenderTree(QTextStream &outputStream, KHTMLPart *part);
0146     void testStaticFile(const QString &filename);
0147     void testJSFile(const QString &filename);
0148     enum CheckResult { Failure = 0, Success = 1, Ignored = 2 };
0149     CheckResult checkOutput(const QString &againstFilename);
0150     CheckResult checkPaintdump(const QString &againstFilename);
0151     enum FailureType { NoFailure = 0, AllFailure = 1, RenderFailure = 2, DomFailure = 4, PaintFailure = 8, JSFailure = 16};
0152     bool runTests(QString relPath = QString(), bool mustExist = false, QStringList failureFileList = QStringList());
0153     bool reportResult(bool passed, const QString &description = QString());
0154     bool reportResult(CheckResult result, const QString &description = QString());
0155     void createMissingDirs(const QString &path);
0156 
0157     QImage renderToImage();
0158     bool imageEqual(const QImage &lhs, const QImage &rhs);
0159     void createLink(const QString &test, int failures);
0160     void doJavascriptReport(const QString &test);
0161     void doFailureReport(const QString &test, int failures);
0162 
0163     KHTMLPart *m_part;
0164     QString m_baseDir;
0165     QString m_outputDir;
0166     QString m_baselineDir;
0167     bool m_genOutput;
0168     QString m_currentBase;
0169 
0170     QString m_currentOutput;
0171     QString m_currentCategory;
0172     QString m_currentTest;
0173     QPixmap *m_paintBuffer;
0174 
0175     bool m_getOutput;
0176     bool m_runJS;
0177     bool m_runHTML;
0178     int m_passes_work;
0179     int m_passes_fail;
0180     int m_failures_work;
0181     int m_failures_fail;
0182     int m_errors;
0183     bool saw_failure;
0184     bool ignore_errors;
0185     int m_known_failures;
0186 
0187     static RegressionTest *curr;
0188 
0189 private:
0190     void printDescription(const QString &description);
0191 
0192     static bool svnIgnored(const QString &filename);
0193 
0194 private:
0195     void evalJS(KJS::ScriptInterpreter &interp, const QString &filename, bool report);   // used by testJS
0196 
0197 private Q_SLOTS:
0198     void slotOpenURL(const QUrl &url, const KParts::OpenUrlArguments &args, const KParts::BrowserArguments &browserArgs);
0199     void resizeTopLevelWidget(int, int);
0200 
0201 };
0202 
0203 #endif