<commit_before>/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <qdeclarativetester.h>
#include <QDebug>
#include <QApplication>
#include <qdeclarativeview.h>
#include <QFile>
#include <QDeclarativeComponent>
#include <QDir>
#include <QCryptographicHash>
#include <private/qabstractanimation_p.h>
#include <QGraphicsObject>
#include <private/qdeclarativeitem_p.h>

QT_BEGIN_NAMESPACE

extern Q_GUI_EXPORT bool qt_applefontsmoothing_enabled;

QDeclarativeTester::QDeclarativeTester(const QString &script, QDeclarativeViewer::ScriptOptions opts,
                     QDeclarativeView *parent)
: QAbstractAnimation(parent), m_script(script), m_view(parent), filterEvents(true), options(opts),
  testscript(0), hasCompleted(false), hasFailed(false)
{
    parent->viewport()->installEventFilter(this);
    parent->installEventFilter(this);
    QUnifiedTimer::instance()->setConsistentTiming(true);

    //Font antialiasing makes tests system-specific, so disable it
    QFont noAA = QApplication::font();
    noAA.setStyleStrategy(QFont::NoAntialias);
    QApplication::setFont(noAA);

    if (options & QDeclarativeViewer::Play)
        this->run();
    start();
}

QDeclarativeTester::~QDeclarativeTester()
{
    if (!hasFailed &&
        options & QDeclarativeViewer::Record &&
        options & QDeclarativeViewer::SaveOnExit)
        save();
}

int QDeclarativeTester::duration() const
{
    return -1;
}

void QDeclarativeTester::addMouseEvent(Destination dest, QMouseEvent *me)
{
    MouseEvent e(me);
    e.destination = dest;
    m_mouseEvents << e;
}

void QDeclarativeTester::addKeyEvent(Destination dest, QKeyEvent *ke)
{
    KeyEvent e(ke);
    e.destination = dest;
    m_keyEvents << e;
}

bool QDeclarativeTester::eventFilter(QObject *o, QEvent *e)
{
    if (!filterEvents)
        return false;

    Destination destination;
    if (o == m_view) {
        destination = View;
    } else if (o == m_view->viewport()) {
        destination = ViewPort;
    } else {
        return false;
    }

    switch (e->type()) {
        case QEvent::KeyPress:
        case QEvent::KeyRelease:
            addKeyEvent(destination, (QKeyEvent *)e);
            return true;
        case QEvent::MouseButtonPress:
        case QEvent::MouseButtonRelease:
        case QEvent::MouseMove:
        case QEvent::MouseButtonDblClick:
            addMouseEvent(destination, (QMouseEvent *)e);
            return true;
        default:
            break;
    }
    return false;
}

void QDeclarativeTester::executefailure()
{
    hasFailed = true;

    if (options & QDeclarativeViewer::ExitOnFailure)
        exit(-1);
}

void QDeclarativeTester::imagefailure()
{
    hasFailed = true;

    if (options & QDeclarativeViewer::ExitOnFailure){
        testSkip();
        exit(hasFailed?-1:0);
    }
}

void QDeclarativeTester::testSkip()
{
    if (options & QDeclarativeViewer::TestSkipProperty){
        QString e = m_view->rootObject()->property("skip").toString();
        if (!e.isEmpty()) {
            if(hasFailed){
                qWarning() << "Test failed, but skipping it: " << e;
            }else{
                qWarning() << "Test skipped: " << e;
            }
            hasFailed = 0;
        }
    }
}

void QDeclarativeTester::complete()
{
    if ((options & QDeclarativeViewer::TestErrorProperty) && !hasFailed) {
        QString e = m_view->rootObject()->property("error").toString();
        if (!e.isEmpty()) {
            qWarning() << "Test failed:" << e;
            hasFailed = true;
        }
    }


    testSkip();
    if (options & QDeclarativeViewer::ExitOnComplete)
        QApplication::exit(hasFailed?-1:0);

    if (hasCompleted)
        return;
    hasCompleted = true;

    if (options & QDeclarativeViewer::Play)
        qWarning("Script playback complete");
}

void QDeclarativeTester::run()
{
    QDeclarativeComponent c(m_view->engine(), m_script + QLatin1String(".qml"));

    testscript = qobject_cast<QDeclarativeVisualTest *>(c.create());
    if (testscript) testscript->setParent(this);
    else { executefailure(); exit(-1); }
    testscriptidx = 0;
}

void QDeclarativeTester::save()
{
    QString filename = m_script + QLatin1String(".qml");
    QFileInfo filenameInfo(filename);
    QDir saveDir = filenameInfo.absoluteDir();
    saveDir.mkpath(QLatin1String("."));

    QFile file(filename);
    file.open(QIODevice::WriteOnly);
    QTextStream ts(&file);
<commit_msg>QmlViewer: Fix test script exits.<commit_after>/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <qdeclarativetester.h>
#include <QDebug>
#include <QApplication>
#include <qdeclarativeview.h>
#include <QFile>
#include <QDeclarativeComponent>
#include <QDir>
#include <QCryptographicHash>
#include <private/qabstractanimation_p.h>
#include <QGraphicsObject>
#include <private/qdeclarativeitem_p.h>

QT_BEGIN_NAMESPACE

enum {
    TestSuccessExitCode = 0,
#ifdef Q_OS_WIN
    TestFailureExitCode = 1 // QProcess on Windows reports crash for exit codes < 0, QTBUG-28735
#else
    TestFailureExitCode = -1
#endif
};

extern Q_GUI_EXPORT bool qt_applefontsmoothing_enabled;

QDeclarativeTester::QDeclarativeTester(const QString &script, QDeclarativeViewer::ScriptOptions opts,
                     QDeclarativeView *parent)
: QAbstractAnimation(parent), m_script(script), m_view(parent), filterEvents(true), options(opts),
  testscript(0), hasCompleted(false), hasFailed(false)
{
    parent->viewport()->installEventFilter(this);
    parent->installEventFilter(this);
    QUnifiedTimer::instance()->setConsistentTiming(true);

    //Font antialiasing makes tests system-specific, so disable it
    QFont noAA = QApplication::font();
    noAA.setStyleStrategy(QFont::NoAntialias);
    QApplication::setFont(noAA);

    if (options & QDeclarativeViewer::Play)
        this->run();
    start();
}

QDeclarativeTester::~QDeclarativeTester()
{
    if (!hasFailed &&
        options & QDeclarativeViewer::Record &&
        options & QDeclarativeViewer::SaveOnExit)
        save();
}

int QDeclarativeTester::duration() const
{
    return -1;
}

void QDeclarativeTester::addMouseEvent(Destination dest, QMouseEvent *me)
{
    MouseEvent e(me);
    e.destination = dest;
    m_mouseEvents << e;
}

void QDeclarativeTester::addKeyEvent(Destination dest, QKeyEvent *ke)
{
    KeyEvent e(ke);
    e.destination = dest;
    m_keyEvents << e;
}

bool QDeclarativeTester::eventFilter(QObject *o, QEvent *e)
{
    if (!filterEvents)
        return false;

    Destination destination;
    if (o == m_view) {
        destination = View;
    } else if (o == m_view->viewport()) {
        destination = ViewPort;
    } else {
        return false;
    }

    switch (e->type()) {
        case QEvent::KeyPress:
        case QEvent::KeyRelease:
            addKeyEvent(destination, (QKeyEvent *)e);
            return true;
        case QEvent::MouseButtonPress:
        case QEvent::MouseButtonRelease:
        case QEvent::MouseMove:
        case QEvent::MouseButtonDblClick:
            addMouseEvent(destination, (QMouseEvent *)e);
            return true;
        default:
            break;
    }
    return false;
}

void QDeclarativeTester::executefailure()
{
    hasFailed = true;

    if (options & QDeclarativeViewer::ExitOnFailure)
        QCoreApplication::exit(TestFailureExitCode);
}

void QDeclarativeTester::imagefailure()
{
    hasFailed = true;

    if (options & QDeclarativeViewer::ExitOnFailure){
        testSkip();
        QCoreApplication::exit(hasFailed ? TestFailureExitCode : TestSuccessExitCode);
    }
}

void QDeclarativeTester::testSkip()
{
    if (options & QDeclarativeViewer::TestSkipProperty){
        QString e = m_view->rootObject()->property("skip").toString();
        if (!e.isEmpty()) {
            if(hasFailed){
                qWarning() << "Test failed, but skipping it: " << e;
            }else{
                qWarning() << "Test skipped: " << e;
            }
            hasFailed = 0;
        }
    }
}

void QDeclarativeTester::complete()
{
    if ((options & QDeclarativeViewer::TestErrorProperty) && !hasFailed) {
        QString e = m_view->rootObject()->property("error").toString();
        if (!e.isEmpty()) {
            qWarning() << "Test failed:" << e;
            hasFailed = true;
        }
    }


    testSkip();
    if (options & QDeclarativeViewer::ExitOnComplete)
        QCoreApplication::exit(hasFailed? TestFailureExitCode : TestSuccessExitCode);

    if (hasCompleted)
        return;
    hasCompleted = true;

    if (options & QDeclarativeViewer::Play)
        qWarning("Script playback complete");
}

void QDeclarativeTester::run()
{
    QDeclarativeComponent c(m_view->engine(), m_script + QLatin1String(".qml"));

    testscript = qobject_cast<QDeclarativeVisualTest *>(c.create());
    if (testscript) {
        testscript->setParent(this);
    } else {
        executefailure();
        if (!(options & QDeclarativeViewer::ExitOnFailure))
            QCoreApplication::exit(TestFailureExitCode);
    }
    testscriptidx = 0;
}

void QDeclarativeTester::save()
{
    QString filename = m_script + QLatin1String(".qml");
    QFileInfo filenameInfo(filename);
    QDir saveDir = filenameInfo.absoluteDir();
    saveDir.mkpath(QLatin1String("."));

    QFile file(filename);
    file.open(QIODevice::WriteOnly);
    QTextStream ts(&file);

{'fraction_non_alphanumeric': 0.13498329790464622, 'fraction_numerical': 0.004631035529911934, 'mean_word_length': 3.658062234794908, 'pattern_counts': {'":': 0, '<': 60, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 6, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7037188', 'n_tokens_mistral': 3921, 'n_tokens_neox': 3805, 'n_words': 1028}