tests/arthur/htmlgenerator/htmlgenerator.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 #include "htmlgenerator.h"
       
    42 
       
    43 #include "xmldata.h"
       
    44 
       
    45 #include <QtXml>
       
    46 
       
    47 #include <QFile>
       
    48 #include <QStringList>
       
    49 #include <QDateTime>
       
    50 #include <QtDebug>
       
    51 
       
    52 #include <iostream>
       
    53 
       
    54 static void generateIndex(QTextStream &out)
       
    55 {
       
    56     out <<"\
       
    57 <html>\n\
       
    58   <head><title>SVG rendering comparison</title></head>\n\
       
    59   <body bgcolor=\"white\">\n\
       
    60   <h1>QSvg testing framework</h1>\n\
       
    61   <table border=\"1\">\n\
       
    62   <tr><td>Testing suite</td><td>History</td></tr>\n\
       
    63   <tr>\n\
       
    64       <td><a href=\"test1.1-full.html\">1.1</a></td>\n\
       
    65       <td><a href=\"test1.1-history.html\">1.1 history</a></td>\n\
       
    66   </tr>\n\
       
    67   <tr>\n\
       
    68       <td><a href=\"test1.2-full.html\">1.2 testing suite</a></td>\n\
       
    69       <td><a href=\"test1.2-history.html\">1.2 QSvg history</a></td>\n\
       
    70   </tr>\n\
       
    71   <tr>\n\
       
    72       <td><a href=\"testrandom-full.html\">Random testing suite</a></td>\n\
       
    73       <td><a href=\"testrandom-history.html\">Random tests QSvg history</a></td>\n\
       
    74   </tr>\n\
       
    75   </body>\n\
       
    76 </html>\n";
       
    77 }
       
    78 
       
    79 
       
    80 static void usage(const char *progname)
       
    81 {
       
    82     std::cerr << "Couldn't find 'framework.ini' "
       
    83               << "file and no output has been specified."<<std::endl;
       
    84     std::cerr << "Usage: "<<progname
       
    85               << " -framework <framework.ini>"
       
    86               << " dirname\n"
       
    87               << std::endl;
       
    88 }
       
    89 
       
    90 
       
    91 HTMLGenerator::HTMLGenerator()
       
    92     : settings(0)
       
    93 {
       
    94     if (QFile::exists("framework.ini")) {
       
    95         settings = new QSettings("framework.ini", QSettings::IniFormat);
       
    96     }
       
    97 }
       
    98 
       
    99 void HTMLGenerator::generateIndex(const QString &)
       
   100 {
       
   101 
       
   102 }
       
   103 
       
   104 void HTMLGenerator::generatePages()
       
   105 {
       
   106     foreach(HTMLSuite *suite, suites) {
       
   107         generateSuite(*suite);
       
   108     }
       
   109 }
       
   110 
       
   111 struct HTMLPage
       
   112 {
       
   113     QString pageName;
       
   114     QStringList headings;
       
   115     QList<HTMLRow> rows;
       
   116 };
       
   117 void HTMLGenerator::generateSuite(const HTMLSuite &suite)
       
   118 {
       
   119     generateReferencePage(suite);
       
   120     generateHistoryPages(suite);
       
   121     generateQtComparisonPage(suite);
       
   122 }
       
   123 
       
   124 void HTMLGenerator::generateReferencePage(const HTMLSuite &suite)
       
   125 {
       
   126 
       
   127     bool generateReference = false;
       
   128     QStringList generators;
       
   129     foreach(HTMLRow *row, suite.rows) {
       
   130         foreach(HTMLImage refs, row->referenceImages) {
       
   131             generators += refs.generatorName;
       
   132             foreach(HTMLImage img, row->images) {
       
   133                 if ((img.flags & Default)) {
       
   134                     generators += img.generatorName;
       
   135                     break;
       
   136                 }
       
   137             }
       
   138             foreach(HTMLImage img, row->foreignImages) {
       
   139                 generators += img.generatorName;
       
   140             }
       
   141             generateReference = true;
       
   142             break;
       
   143         }
       
   144         if (generateReference)
       
   145             break;
       
   146     }
       
   147 
       
   148     if (!generateReference)
       
   149         return;
       
   150 
       
   151     QFile file(QString("test-%1-reference.html").arg(suite.name));
       
   152     if (!file.open(QFile::WriteOnly | QFile::Truncate)) {
       
   153         return;
       
   154     }
       
   155 
       
   156     QTextStream out(&file);
       
   157     generateHeader(out, "Reference Page", generators);
       
   158 
       
   159     foreach(HTMLRow *row, suite.rows) {
       
   160         bool referenceRow = false;
       
   161         QList<HTMLImage> images;
       
   162         foreach(HTMLImage refs, row->referenceImages) {
       
   163             startGenerateRow(out, row->testcase);
       
   164             referenceRow = true;
       
   165             images.append(refs);
       
   166             break;
       
   167         }
       
   168         if (referenceRow) {
       
   169             foreach(HTMLImage img, row->images) {
       
   170                 if ((img.flags & Default)) {
       
   171                     images.append(img);
       
   172                     break;
       
   173                 }
       
   174             }
       
   175             images << row->foreignImages;
       
   176 
       
   177             generateImages(out, images);
       
   178             finishGenerateRow(out, row->testcase);
       
   179         }
       
   180     }
       
   181 
       
   182     generateFooter(out);
       
   183 }
       
   184 
       
   185 void HTMLGenerator::generateHistoryPages(const HTMLSuite &suite)
       
   186 {
       
   187     QStringList lst;
       
   188     foreach(XMLEngine *engine, engines) {
       
   189         generateHistoryForEngine(suite, engine->name);
       
   190     }
       
   191 }
       
   192 
       
   193 void HTMLGenerator::generateHistoryForEngine(const HTMLSuite &suite, const QString &engine)
       
   194 {
       
   195     QFile file(QString("test-%1-%2-history.html").arg(suite.name).arg(engine));
       
   196     if (!file.open(QFile::WriteOnly | QFile::Truncate)) {
       
   197         return;
       
   198     }
       
   199 
       
   200     QTextStream out(&file);
       
   201 
       
   202     QStringList generators;
       
   203     foreach(HTMLRow *row, suite.rows) {
       
   204         foreach(HTMLImage refs, row->referenceImages) {
       
   205             generators += refs.generatorName;
       
   206             generators += "Today";
       
   207             generators += "Yesterday";
       
   208             generators += "Last Week";
       
   209             break;
       
   210         }
       
   211         if (!generators.isEmpty())
       
   212             break;
       
   213     }
       
   214     if (generators.isEmpty()) {
       
   215         generators += "Today";
       
   216         generators += "Yesterday";
       
   217         generators += "Last Week";
       
   218     }
       
   219     generateHeader(out, QString("History for %1 engine").arg(engine), generators);
       
   220 
       
   221     foreach(HTMLRow *row, suite.rows) {
       
   222         QList<HTMLImage> images;
       
   223         QStringList generators;
       
   224         foreach(HTMLImage refs, row->referenceImages) {
       
   225             generators += refs.generatorName;
       
   226             images.append(refs);
       
   227             break;
       
   228         }
       
   229 
       
   230         startGenerateRow(out, row->testcase);
       
   231         foreach(HTMLImage img, row->images) {
       
   232             if (img.generatorName == engine) {
       
   233                 images << img;
       
   234             }
       
   235         }
       
   236 
       
   237         generateHistoryImages(out, images);
       
   238         finishGenerateRow(out, row->testcase);
       
   239     }
       
   240 
       
   241     generateFooter(out);
       
   242 }
       
   243 
       
   244 
       
   245 void HTMLGenerator::generateQtComparisonPage(const HTMLSuite &suite)
       
   246 {
       
   247     QFile file(QString("test-%1-comparison.html").arg(suite.name));
       
   248     if (!file.open(QFile::WriteOnly | QFile::Truncate)) {
       
   249         return;
       
   250     }
       
   251 
       
   252     QTextStream out(&file);
       
   253 
       
   254     QStringList lst;
       
   255     foreach(XMLEngine *engine, engines) {
       
   256         if (!engine->foreignEngine && !engine->referenceEngine)
       
   257             lst += engine->name;
       
   258     }
       
   259 
       
   260     generateHeader(out, QString("Qt Engine Comparison"), lst);
       
   261     foreach(HTMLRow *row, suite.rows) {
       
   262         QList<HTMLImage> images;
       
   263 
       
   264         startGenerateRow(out, row->testcase);
       
   265         foreach(HTMLImage img, row->images) {
       
   266             images.append(img);
       
   267         }
       
   268         generateImages(out, images);
       
   269         finishGenerateRow(out, row->testcase);
       
   270     }
       
   271 
       
   272     generateFooter(out);
       
   273 }
       
   274 
       
   275 
       
   276 void HTMLGenerator::generateHeader(QTextStream &out, const QString &name,
       
   277                                    const QStringList &generators)
       
   278 {
       
   279     out << "<html>\n"
       
   280         << "<head><title>"<<name<<"</title></head>\n"
       
   281         << "<body bgcolor=\"white\">\n"
       
   282         << "<a href=\"index.html\">Click here to go back to main page</a>\n"
       
   283         << "<p><center><h2> Generated: "<<QDateTime::currentDateTime().toString()
       
   284         <<"</h2></center></p>\n"
       
   285         << "<table border=\"1\">\n";
       
   286 
       
   287     out << "<tr>";
       
   288     foreach(QString generator, generators) {
       
   289         out <<"<td><b>"<<generator<<"</b></td>\n";
       
   290     }
       
   291     out<<"</tr>\n";
       
   292 
       
   293 }
       
   294 
       
   295 void HTMLGenerator::startGenerateRow(QTextStream &out, const QString &name)
       
   296 {
       
   297     Q_UNUSED(name);
       
   298     out <<"  <tr>\n";
       
   299 }
       
   300 
       
   301 void HTMLGenerator::generateImages(QTextStream &out,
       
   302                                    const QList<HTMLImage> &images)
       
   303 {
       
   304     out <<"  <tr>\n";
       
   305     foreach(HTMLImage image, images) {
       
   306         out <<"     <td valign=top><img src=\""<< image.file <<"\"></td>\n";
       
   307     }
       
   308     out <<"  </tr>\n";
       
   309     out <<"  <tr>\n";
       
   310     foreach(HTMLImage image, images) {
       
   311         out <<"     <td><center>"
       
   312             << image.generatorName << ": "
       
   313             << image.details <<" ms </center></td>\n";
       
   314     }
       
   315 }
       
   316 
       
   317 void HTMLGenerator::generateHistoryImages(QTextStream &out,
       
   318                                           const QList<HTMLImage> &images)
       
   319 {
       
   320     foreach(HTMLImage image, images) {
       
   321         if ((image.flags & Reference)) {
       
   322             out <<"     <td><img src=\""<< image.file
       
   323                 <<"\"  width=480 height=360></td>\n";
       
   324         } else {
       
   325             QString genName = image.generatorName;
       
   326             QString file = image.file.replace(image.generatorName, "");
       
   327             out <<"     <td><img src=\""<<image.generatorName
       
   328                 << file <<"\"></td>\n"
       
   329                 <<"     <td><img src=\""<<image.generatorName
       
   330                 <<".yesterday"<< file <<"\"></td>\n"
       
   331                 <<"     <td><img src=\""<<image.generatorName
       
   332                 <<".lastweek"<< file <<"\"></td>\n";
       
   333         }
       
   334     }
       
   335 }
       
   336 
       
   337 
       
   338 void HTMLGenerator::finishGenerateRow(QTextStream &out, const QString &name)
       
   339 {
       
   340     out <<"  </tr>\n"
       
   341         <<"  <tr><td colspan=5 bgcolor=yellow><center>"
       
   342         <<name<<"</center></td>\n";
       
   343 }
       
   344 
       
   345 void HTMLGenerator::generateFooter(QTextStream &out)
       
   346 {
       
   347     out << "</table>\n"
       
   348         << "</body>\n"
       
   349         << "</html>\n";
       
   350 }
       
   351 
       
   352 void HTMLGenerator::run(int argc, char **argv)
       
   353 {
       
   354     processArguments(argc, argv);
       
   355 
       
   356     QDir dir;
       
   357     dir.setFilter(QDir::Dirs | QDir::NoSymLinks | QDir::NoDotAndDotDot);
       
   358     QFileInfoList list = dir.entryInfoList();
       
   359     for (int i = 0; i < list.size(); ++i) {
       
   360         QFileInfo fileInfo = list.at(i);
       
   361 
       
   362         QString dataFile = QString("%1/data.xml")
       
   363                            .arg(fileInfo.absoluteFilePath());
       
   364         if (QFile::exists(dataFile)) {
       
   365             XMLReader handler;
       
   366             QXmlSimpleReader reader;
       
   367             reader.setContentHandler(&handler);
       
   368             reader.setErrorHandler(&handler);
       
   369 
       
   370             QFile file(dataFile);
       
   371             if (!file.open(QFile::ReadOnly | QFile::Text)) {
       
   372                 qWarning("Cannot open file '%s', because: %s",
       
   373                          qPrintable(dataFile), qPrintable(file.errorString()));
       
   374                 continue;
       
   375             }
       
   376 
       
   377             QXmlInputSource xmlInputSource(&file);
       
   378             if (reader.parse(xmlInputSource)) {
       
   379                 XMLEngine *engine = handler.xmlEngine();
       
   380                 engines.insert(engine->name, engine);
       
   381             }
       
   382         }
       
   383     }
       
   384 
       
   385     if (engines.isEmpty()) {
       
   386         usage(argv[0]);
       
   387         return;
       
   388     }
       
   389 
       
   390     convertToHtml();
       
   391     generatePages();
       
   392 }
       
   393 
       
   394 void HTMLGenerator::processArguments(int argc, char **argv)
       
   395 {
       
   396     QString frameworkFile;
       
   397     for (int i=1; i < argc; ++i) {
       
   398         QString opt(argv[i]);
       
   399         if (opt == "-framework") {
       
   400             frameworkFile = QString(argv[++i]);
       
   401         } else {
       
   402             outputDirName = opt;
       
   403         }
       
   404     }
       
   405 
       
   406     if (!frameworkFile.isEmpty() && QFile::exists(frameworkFile)) {
       
   407         delete settings;
       
   408         baseDataDir = QFileInfo(frameworkFile).absoluteDir().absolutePath();
       
   409         settings = new QSettings(frameworkFile, QSettings::IniFormat);
       
   410     }
       
   411 
       
   412     if (!outputDirName.isEmpty()) {
       
   413         QDir::setCurrent(outputDirName);
       
   414     }
       
   415     htmlOutputDir = QString("html");
       
   416     QDir dir;
       
   417     dir.mkpath(htmlOutputDir);
       
   418 }
       
   419 
       
   420 void HTMLGenerator::convertToHtml()
       
   421 {
       
   422     foreach(XMLEngine *engine, engines) {
       
   423         foreach(XMLSuite *suite, engine->suites) {
       
   424             QString refUrl;
       
   425             QString refPrefix;
       
   426             if (settings) {
       
   427                 settings->beginGroup(suite->name);
       
   428                 refUrl = settings->value("reference").toString();
       
   429                 refPrefix = settings->value("referencePrefix").toString();
       
   430                 if (refUrl.endsWith('/'))
       
   431                     refUrl.chop(1);
       
   432                 settings->endGroup();
       
   433             }
       
   434 
       
   435             foreach(XMLFile *file, suite->files) {
       
   436                 HTMLImage image;
       
   437                 image.file = file->output;
       
   438                 image.generatorName = engine->name;
       
   439 
       
   440                 image.details = file->data.last().iterations == 0
       
   441                                 ? QString::number(-1)
       
   442                                 : QString::number(file->data.last().timeToRender
       
   443                                                   / file->data.last().iterations);
       
   444                 image.flags = Normal;
       
   445 
       
   446                 if (file->data.last().timeToRender == 0)
       
   447                     image.details = file->data.last().details;
       
   448 
       
   449                 if (engine->defaultEngine)
       
   450                     image.flags |= Default;
       
   451                 if (engine->foreignEngine) {
       
   452                     image.flags ^= Normal;
       
   453                     image.flags |= Foreign;
       
   454                 }
       
   455                 if (engine->referenceEngine) {
       
   456                     image.flags ^= Normal;
       
   457                     image.flags |= Reference;
       
   458                 }
       
   459 
       
   460                 if (!outputDirName.isEmpty() && image.file.startsWith(outputDirName))
       
   461                     image.file.remove(0, outputDirName.length() + 1); // + '/'
       
   462                 HTMLSuite *htmlSuite = suites[suite->name];
       
   463                 if (!htmlSuite) {
       
   464                     htmlSuite = new HTMLSuite;
       
   465                     htmlSuite->name = suite->name;
       
   466                     suites.insert(suite->name, htmlSuite);
       
   467                 }
       
   468                 HTMLRow *htmlRow = htmlSuite->rows[file->name];
       
   469                 if (!htmlRow) {
       
   470                     htmlRow = new HTMLRow;
       
   471                     htmlRow->testcase = file->name;
       
   472                     htmlSuite->rows.insert(file->name, htmlRow);
       
   473                 }
       
   474 
       
   475                 if ((image.flags & Foreign))
       
   476                     htmlRow->foreignImages.append(image);
       
   477                 else if ((image.flags & Reference))
       
   478                     htmlRow->referenceImages.append(image);
       
   479                 else {
       
   480                     htmlRow->images.append(image);
       
   481                 }
       
   482                 if (!refUrl.isEmpty()) {
       
   483                     QFileInfo fi(file->output);
       
   484                     HTMLImage image;
       
   485                     image.file = QString("%1/%2%3")
       
   486                                  .arg(refUrl)
       
   487                                  .arg(refPrefix)
       
   488                                  .arg(fi.fileName());
       
   489                     image.generatorName = QString("Reference");
       
   490                     image.details = QString("Reference");
       
   491                     image.flags = Reference;
       
   492                     if (htmlRow) {
       
   493                         htmlRow->referenceImages.append(image);
       
   494                     }
       
   495                 }
       
   496             }
       
   497         }
       
   498     }
       
   499 }
       
   500 
       
   501 void HTMLGenerator::createPerformance()
       
   502 {
       
   503 #if 0
       
   504     QFile file(QString("test-performance.html"));
       
   505     if (!file.open(QFile::WriteOnly | QFile::Truncate)) {
       
   506         return;
       
   507     }
       
   508 
       
   509     QTextStream out(&file);
       
   510     foreach(XMLEngine *engine, engines) {
       
   511         QImage img = createHistoryImage(engine);
       
   512         QImage ;
       
   513 
       
   514     }
       
   515 #endif
       
   516 }
       
   517 
       
   518