/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/


#include <QtTest/QtTest>

#include <QAbstractMessageHandler>
#include <QFileInfo>
#include <QNetworkReply>
#include <QtNetwork/QTcpServer>
#include <QtNetwork/QTcpSocket>
#include <QXmlFormatter>
#include <QXmlItem>
#include <QXmlName>
#include <QXmlQuery>
#include <QXmlResultItems>
#include <QXmlSerializer>

#include "MessageSilencer.h"
#include "MessageValidator.h"
#include "NetworkOverrider.h"
#include "PushBaseliner.h"
#include "../qabstracturiresolver/TestURIResolver.h"
#include "../qsimplexmlnodemodel/TestSimpleNodeModel.h"
#include "TestFundament.h"
#include "../network-settings.h"

/*!
 \class tst_QXmlQuery
 \internal
 \since 4.4
 \brief Tests class QXmlQuery.

 This test is not intended for testing the engine, but the functionality specific
 to the QXmlQuery class.

 In other words, if you have an engine bug; don't add it here because it won't be
 tested properly. Instead add it to the test suite.

 */
class tst_QXmlQuery : public QObject
                    , private TestFundament
{
    Q_OBJECT

public:
    inline tst_QXmlQuery() : m_generatedBaselines(0)
                           , m_pushTestsCount(0)
                           , m_testNetwork(true)
    {
    }

private Q_SLOTS:
    void initTestCase();
    void defaultConstructor() const;
    void copyConstructor() const;
    void constructorQXmlNamePool() const;
    void constructorQXmlNamePoolQueryLanguage() const;
    void constructorQXmlNamePoolWithinQSimpleXmlNodeModel() const;
    void assignmentOperator() const;
    void isValid() const;
    void sequentialExecution() const;
    void bindVariableQString() const;
    void bindVariableQStringNoExternalDeclaration() const;
    void bindVariableQXmlName() const;
    void bindVariableQXmlNameTriggerWarnings() const;
    void bindVariableQStringQIODevice() const;
    void bindVariableQStringQIODeviceWithByteArray() const;
    void bindVariableQStringQIODeviceWithString() const;
    void bindVariableQStringQIODeviceWithQFile() const;
    void bindVariableQXmlNameQIODevice() const;
    void bindVariableQXmlNameQIODeviceTriggerWarnings() const;
    void bindVariableXSLTSuccess() const;
    void bindVariableTemporaryNode() const;
    void setMessageHandler() const;
    void messageHandler() const;
    void evaluateToQAbstractXmlReceiverTriggerWarnings() const;
    void evaluateToQXmlResultItems() const;
    void evaluateToQXmlResultItemsTriggerWarnings() const;
    void evaluateToQXmlResultItemsErrorAtEnd() const;
    void evaluateToReceiver();
    void evaluateToReceiver_data() const;
    void evaluateToReceiverOnInvalidQuery() const;
    void evaluateToQStringTriggerError() const;
    void evaluateToQString() const;
    void evaluateToQString_data() const;
    void evaluateToQStringSignature() const;
    void checkGeneratedBaselines() const;
    void basicXQueryToQtTypeCheck() const;
    void basicQtToXQueryTypeCheck() const;
    void bindNode() const;
    void relativeBaseURI() const;
    void emptyBaseURI() const;
    void roundTripDateWithinQXmlItem() const;
    void bindingMissing() const;
    void bindDefaultConstructedItem() const;
    void bindDefaultConstructedItem_data() const;
    void bindEmptyNullString() const;
    void bindEmptyString() const;
    void rebindVariableSameType() const;
    void rebindVariableDifferentType() const;
    void rebindVariableWithNullItem() const;
    void eraseQXmlItemBinding() const;
    void eraseDeviceBinding() const;
    void constCorrectness() const;
    void objectSize() const;
    void setUriResolver() const;
    void uriResolver() const;
    void messageXML() const;
    void resultItemsDeallocatedQuery() const;
    void copyCheckMessageHandler() const;
    void shadowedVariables() const;
    void setFocusQXmlItem() const;
    void setFocusQUrl() const;
    void setFocusQIODevice() const;
    void setFocusQIODeviceAvoidVariableClash() const;
    void setFocusQIODeviceFailure() const;
    void setFocusQIODeviceTriggerWarnings() const;
    void setFocusQString() const;
    void setFocusQStringFailure() const;
    void setFocusQStringSignature() const;
    void recompilationWithEvaluateToResultFailing() const;
    void secondEvaluationWithEvaluateToResultFailing() const;
    void recompilationWithEvaluateToReceiver() const;
    void fnDocOnQIODeviceTimeout() const;
    void evaluateToQStringListOnInvalidQuery() const;
    void evaluateToQStringList() const;
    void evaluateToQStringListTriggerWarnings() const;
    void evaluateToQStringList_data() const;
    void evaluateToQStringListNoConversion() const;
    void evaluateToQIODevice() const;
    void evaluateToQIODeviceTriggerWarnings() const;
    void evaluateToQIODeviceSignature() const;
    void evaluateToQIODeviceOnInvalidQuery() const;
    void setQueryQIODeviceQUrl() const;
    void setQueryQIODeviceQUrlTriggerWarnings() const;
    void setQueryQString() const;
    void setQueryQUrlSuccess() const;
    void setQueryQUrlSuccess_data() const;
    void setQueryQUrlFailSucceed() const;
    void setQueryQUrlFailure() const;
    void setQueryQUrlFailure_data() const;
    void setQueryQUrlBaseURI() const;
    void setQueryQUrlBaseURI_data() const;
    void setQueryWithNonExistentQUrlOnValidQuery() const;
    void setQueryWithInvalidQueryFromQUrlOnValidQuery() const;
    void retrieveNameFromQuery() const;
    void retrieveNameFromQuery_data() const;
    void cleanupTestCase() const;
    void declareUnavailableExternal() const;
    void msvcCacheIssue() const;
    void unavailableExternalVariable() const;
    void useUriResolver() const;
    void queryWithFocusAndVariable() const;
    void undefinedFocus() const;
    void basicFocusUsage() const;

    void queryLanguage() const;
    void queryLanguageSignature() const;
    void enumQueryLanguage() const;

    void setNetworkAccessManager() const;
    void networkAccessManagerSignature() const;
    void networkAccessManagerDefaultValue() const;
    void networkAccessManager() const;

    void setInitialTemplateNameQXmlName() const;
    void setInitialTemplateNameQXmlNameSignature() const;
    void setInitialTemplateNameQString() const;
    void setInitialTemplateNameQStringSignature() const;
    void initialTemplateName() const;
    void initialTemplateNameSignature() const;

    void fnDocNetworkAccessSuccess() const;
    void fnDocNetworkAccessSuccess_data() const;
    void fnDocNetworkAccessFailure() const;
    void fnDocNetworkAccessFailure_data() const;
    void multipleDocsAndFocus() const;
    void multipleEvaluationsWithDifferentFocus() const;
    void bindVariableQXmlQuery() const;
    void bindVariableQXmlQuery_data() const;
    void bindVariableQStringQXmlQuerySignature() const;
    void bindVariableQXmlNameQXmlQuerySignature() const;
    void bindVariableQXmlNameQXmlQuery() const;
    void bindVariableQXmlQueryInvalidate() const;
    void unknownSourceLocation() const;

    void identityConstraintSuccess() const;
    void identityConstraintFailure() const;
    void identityConstraintFailure_data() const;

    // TODO call all URI resolving functions where 1) the URI resolver return a null QUrl(); 2) resolves into valid, existing URI, 3) invalid, non-existing URI.
    // TODO bind stringlists, variant lists, both ways.
    // TODO trigger serialization error, or any error in evaluateToushCallback().
    // TODO let items travle between two queries, as seen in the SDK
    // TODO what happens if the query declares local variable and external ones are provided?

private:
    enum
    {
        /**
         * One excluded, since we skip static-base-uri.xq.
         */
        ExpectedQueryCount = 30
    };

    static void checkBaseURI(const QUrl &baseURI, const QString &candidate);
    static QStringList queries();
    static const QString m_xmlPatternsDir;

    int m_generatedBaselines;
    int m_pushTestsCount;
    const bool m_testNetwork;
};

const QString tst_QXmlQuery::m_xmlPatternsDir = QFINDTESTDATA("../xmlpatterns");

void tst_QXmlQuery::initTestCase()
{
    QVERIFY2(!m_xmlPatternsDir.isEmpty(), qPrintable(QString::fromLatin1("Cannot locate '../xmlpatterns' starting from %1").arg(QDir::currentPath())));
}

void tst_QXmlQuery::checkBaseURI(const QUrl &baseURI, const QString &candidate)
{
    /* The use of QFileInfo::canonicalFilePath() takes into account that drive letters
     * on Windows may have different cases. */
    QVERIFY(QDir(baseURI.toLocalFile()).relativeFilePath(QFileInfo(candidate).canonicalFilePath()).startsWith("../"));
}

QStringList tst_QXmlQuery::queries()
{
    QDir dir;
    dir.cd(inputFile(m_xmlPatternsDir + QLatin1String("/queries/")));

    return dir.entryList(QStringList(QLatin1String("*.xq")));
}

void tst_QXmlQuery::defaultConstructor() const
{
    /* Allocate instance in different orders. */
    {
        QXmlQuery query;
    }

    {
        QXmlQuery query1;
        QXmlQuery query2;
    }

    {
        QXmlQuery query1;
        QXmlQuery query2;
        QXmlQuery query3;
    }
}

void tst_QXmlQuery::copyConstructor() const
{
    /* Verify that we can take a const reference, and simply do a copy of a default constructed object. */
    {
        const QXmlQuery query1;
        QXmlQuery query2(query1);
    }

    /* Copy twice. */
    {
        const QXmlQuery query1;
        QXmlQuery query2(query1);
        QXmlQuery query3(query2);
    }

    /* Verify that copying default values works. */
    {
        const QXmlQuery query1;
        const QXmlQuery query2(query1);
        QCOMPARE(query2.messageHandler(), query1.messageHandler());
        QCOMPARE(query2.uriResolver(), query1.uriResolver());
        QCOMPARE(query2.queryLanguage(), query1.queryLanguage());
        QCOMPARE(query2.initialTemplateName(), query1.initialTemplateName());
        QCOMPARE(query2.networkAccessManager(), query1.networkAccessManager());
    }

    /* Check that the
     *
     * - name pool
     * - URI resolver
     * - message handler
     * - query language
     * - initial template name
     *
     *   sticks with the copy. */
    {
        MessageSilencer silencer;
        TestURIResolver resolver;
        QNetworkAccessManager networkManager;
        QXmlQuery query1(QXmlQuery::XSLT20);
        QXmlNamePool np1(query1.namePool());

        query1.setMessageHandler(&silencer);
        query1.setUriResolver(&resolver);
        query1.setNetworkAccessManager(&networkManager);

        const QXmlName name(np1, QLatin1String("localName"),
                                 QLatin1String("http://example.com/"),
                                 QLatin1String("prefix"));
        query1.setInitialTemplateName(name);

        const QXmlQuery query2(query1);
        QCOMPARE(query2.messageHandler(), static_cast<QAbstractMessageHandler *>(&silencer));
        QCOMPARE(query2.uriResolver(), static_cast<const QAbstractUriResolver *>(&resolver));
        QCOMPARE(query2.queryLanguage(), QXmlQuery::XSLT20);
        QCOMPARE(query2.initialTemplateName(), name);
        QCOMPARE(query2.networkAccessManager(), &networkManager);

        QXmlNamePool np2(query2.namePool());

        QCOMPARE(name.namespaceUri(np2), QString::fromLatin1("http://example.com/"));
        QCOMPARE(name.localName(np2), QString::fromLatin1("localName"));
        QCOMPARE(name.prefix(np2), QString::fromLatin1("prefix"));
    }

    {
        QXmlQuery original;

        original.setFocus(QXmlItem(4));
        original.setQuery(QLatin1String("."));
        QVERIFY(original.isValid());

        const QXmlQuery copy(original);

        QXmlResultItems result;
        copy.evaluateTo(&result);
        QCOMPARE(result.next().toAtomicValue(), QVariant(4));
        QVERIFY(result.next().isNull());
        QVERIFY(!result.hasError());
    }

    /* Copy, set, compare. Check that copies are independent. */
    {
        // TODO all members except queryLanguage().
    }
}

void tst_QXmlQuery::constructorQXmlNamePool() const
{
    /* Check that the namepool we are passed, is actually used. */
    QXmlNamePool np;

    QXmlQuery query(np);
    const QXmlName name(np, QLatin1String("localName"),
                            QLatin1String("http://example.com/"),
                            QLatin1String("prefix"));

    QXmlNamePool np2(query.namePool());
    QCOMPARE(name.namespaceUri(np2), QString::fromLatin1("http://example.com/"));
    QCOMPARE(name.localName(np2), QString::fromLatin1("localName"));
    QCOMPARE(name.prefix(np2), QString::fromLatin1("prefix"));
}

/*!
  Ensure that the internal variable loading mechanisms uses the user-supplied
  name pool.

  If that is not the case, different name pools are used and the code crashes.

  \since 4.5
 */
void tst_QXmlQuery::constructorQXmlNamePoolQueryLanguage() const
{
    QXmlNamePool np;
    QXmlName name(np, QLatin1String("arbitraryName"));

    QXmlQuery query(QXmlQuery::XQuery10, np);

    QBuffer input;
    input.setData("<yall/>");

    QVERIFY(input.open(QIODevice::ReadOnly));
    query.bindVariable(name, &input);
    query.setQuery("string(doc($arbitraryName))");

    QStringList result;
    query.evaluateTo(&result);
}

void tst_QXmlQuery::constructorQXmlNamePoolWithinQSimpleXmlNodeModel() const
{
    class TestCTOR : public TestSimpleNodeModel
    {
    public:
        TestCTOR(const QXmlNamePool &np) : TestSimpleNodeModel(np)
        {
        }

        void checkCTOR() const
        {
            /* If this fails to compile, the constructor has trouble with taking
             * a mutable reference.
             *
             * The reason we use the this pointer explicitly, is to avoid a compiler
             * warnings with MSVC 2005. */
            QXmlQuery(this->namePool());
        }
    };

    QXmlNamePool np;
    TestCTOR ctor(np);
    ctor.checkCTOR();
}

void tst_QXmlQuery::assignmentOperator() const
{
    class ReturnURI : public QAbstractUriResolver
    {
    public:
        ReturnURI() {}
        virtual QUrl resolve(const QUrl &relative,
                             const QUrl &baseURI) const
        {
            return baseURI.resolved(relative);
        }
    };

    /* Assign this to this. */
    {
        QXmlQuery query;
        query = query;
        query = query;
        query = query;

        /* Just call a couple of functions to give valgrind
         * something to check. */
        QVERIFY(!query.isValid());
        query.messageHandler();
    }

    /* Assign null instances a couple of times. */
    {
        QXmlQuery query1;
        QXmlQuery query2;
        query1 = query2;
        query1 = query2;
        query1 = query2;

        /* Just call a couple of functions to give valgrind
         * something to check. */
        QVERIFY(!query1.isValid());
        query1.messageHandler();

        /* Just call a couple of functions to give valgrind
         * something to check. */
        QVERIFY(!query2.isValid());
        query2.messageHandler();
    }

    /* Create a query, set all the things it stores, and ensure it
     * travels over to the new instance. */
    {
        MessageSilencer silencer;
        const ReturnURI returnURI;
        QXmlNamePool namePool;

        QBuffer documentDevice;
        documentDevice.setData(QByteArray("<e>a</e>"));
        QVERIFY(documentDevice.open(QIODevice::ReadOnly));

        QXmlQuery original(namePool);
        QXmlName testName(namePool, QLatin1String("somethingToCheck"));

        original.setMessageHandler(&silencer);
        original.bindVariable(QLatin1String("var"), QXmlItem(1));
        original.bindVariable(QLatin1String("device"), &documentDevice);
        original.setUriResolver(&returnURI);
        original.setFocus(QXmlItem(3));
        original.setQuery(QLatin1String("$var, 1 + 1, ., string(doc($device))"));

        /* Do a copy, and check that everything followed on into the copy. No modification
         * of the copy. */
        {
            QXmlQuery copy;

            /* We use assignment operator, not copy constructor. */
            copy = original;

            QVERIFY(copy.isValid());
            QCOMPARE(copy.uriResolver(), static_cast<const QAbstractUriResolver *>(&returnURI));
            QCOMPARE(copy.messageHandler(), static_cast<QAbstractMessageHandler *>(&silencer));
            QCOMPARE(testName.localName(copy.namePool()), QString::fromLatin1("somethingToCheck"));

            QXmlResultItems result;
            copy.evaluateTo(&result);
            QCOMPARE(result.next().toAtomicValue(), QVariant(1));
            QCOMPARE(result.next().toAtomicValue(), QVariant(2));
            QCOMPARE(result.next().toAtomicValue(), QVariant(3));
            QCOMPARE(result.next().toAtomicValue(), QVariant(QString::fromLatin1("a")));
            QVERIFY(result.next().isNull());
            QVERIFY(!result.hasError());
        }

        /* Copy, and change values. Things should detach. */
        {
            /* Evaluate the copy. */
            {
                MessageSilencer secondSilencer;
                const ReturnURI secondUriResolver;
                QBuffer documentDeviceCopy;
                documentDeviceCopy.setData(QByteArray("<e>b</e>"));
                QVERIFY(documentDeviceCopy.open(QIODevice::ReadOnly));

                QXmlQuery copy;
                copy = original;

                copy.setMessageHandler(&secondSilencer);
                /* Here we rebind variable values. */
                copy.bindVariable(QLatin1String("var"), QXmlItem(4));
                copy.bindVariable(QLatin1String("device"), &documentDeviceCopy);
                copy.setUriResolver(&secondUriResolver);
                copy.setFocus(QXmlItem(6));
                copy.setQuery(QLatin1String("$var, 1 + 1, ., string(doc($device))"));

                /* Check that the copy picked up the new things. */
                QVERIFY(copy.isValid());
                QCOMPARE(copy.uriResolver(), static_cast<const QAbstractUriResolver *>(&secondUriResolver));
                QCOMPARE(copy.messageHandler(), static_cast<QAbstractMessageHandler *>(&secondSilencer));

                QXmlResultItems resultCopy;
                copy.evaluateTo(&resultCopy);
                QCOMPARE(resultCopy.next().toAtomicValue(), QVariant(4));
                QCOMPARE(resultCopy.next().toAtomicValue(), QVariant(2));
                QCOMPARE(resultCopy.next().toAtomicValue(), QVariant(6));
                const QString stringedDevice(resultCopy.next().toAtomicValue().toString());
                QCOMPARE(stringedDevice, QString::fromLatin1("b"));
                QVERIFY(resultCopy.next().isNull());
                QVERIFY(!resultCopy.hasError());
            }

            /* Evaluate the original. */
            {
                /* Check that the original is unchanged. */
                QVERIFY(original.isValid());
                QCOMPARE(original.uriResolver(), static_cast<const QAbstractUriResolver *>(&returnURI));
                QCOMPARE(original.messageHandler(), static_cast<QAbstractMessageHandler *>(&silencer));

                QXmlResultItems resultOriginal;
                original.evaluateTo(&resultOriginal);
                QCOMPARE(resultOriginal.next().toAtomicValue(), QVariant(1));
                QCOMPARE(resultOriginal.next().toAtomicValue(), QVariant(2));
                QCOMPARE(resultOriginal.next().toAtomicValue(), QVariant(3));
                QCOMPARE(resultOriginal.next().toAtomicValue(), QVariant(QString::fromLatin1("a")));
                QVERIFY(resultOriginal.next().isNull());
                QVERIFY(!resultOriginal.hasError());
            }
        }
    }
}

/*!
  Since QXmlQuery doesn't seek devices to position 0, this code triggers a bug
  where document caching doesn't work. Since the document caching doesn't work,
  the device will be read twice, and the second time the device is at the end,
  hence premature end of document.
 */
void tst_QXmlQuery::sequentialExecution() const
{
    QBuffer inBuffer;
    inBuffer.setData(QByteArray("<input/>"));
    QVERIFY(inBuffer.open(QIODevice::ReadOnly));

    QXmlQuery query;
    query.bindVariable("inputDocument", &inBuffer);

    QByteArray outArray;
    QBuffer outBuffer(&outArray);
    outBuffer.open(QIODevice::WriteOnly);

    const QString queryString(QLatin1String("doc($inputDocument)"));
    query.setQuery(queryString);

    QXmlFormatter formatter(query, &outBuffer);

    QVERIFY(query.evaluateTo(&formatter));

    /* If this line is removed, the bug isn't triggered. */
    query.setQuery(queryString);

    QVERIFY(query.evaluateTo(&formatter));
}

void tst_QXmlQuery::isValid() const
{
    /* Check default value. */
    QXmlQuery query;
    QVERIFY(!query.isValid());
}

void tst_QXmlQuery::bindVariableQString() const
{
    {
        QXmlQuery query;
        /* Bind with a null QXmlItem. */
        query.bindVariable(QLatin1String("name"), QXmlItem());
    }

    {
        QXmlQuery query;
        /* Bind with a null QVariant. */
        query.bindVariable(QLatin1String("name"), QXmlItem(QVariant()));
    }

    {
        QXmlQuery query;
        /* Bind with a null QXmlNodeModelIndex. */
        query.bindVariable(QLatin1String("name"), QXmlItem(QXmlNodeModelIndex()));
    }
}

void tst_QXmlQuery::bindVariableQStringNoExternalDeclaration() const
{
    QXmlQuery query;
    query.bindVariable(QLatin1String("foo"), QXmlItem(QLatin1String("Variable Value")));
    query.setQuery(QLatin1String("$foo"));

    QVERIFY(query.isValid());

    QStringList result;
    QVERIFY(query.evaluateTo(&result));

    QCOMPARE(result, QStringList() << QLatin1String("Variable Value"));
}

void tst_QXmlQuery::bindVariableQXmlName() const
{
    // TODO
}

void tst_QXmlQuery::bindVariableQXmlNameTriggerWarnings() const
{
    QXmlQuery query;

    QTest::ignoreMessage(QtWarningMsg, "The variable name cannot be null.");
    query.bindVariable(QXmlName(), QVariant());
}

void tst_QXmlQuery::bindVariableQStringQIODeviceWithByteArray() const
{
    QXmlQuery query;

    QByteArray in("<e/>");
    QBuffer device(&in);
    QVERIFY(device.open(QIODevice::ReadOnly));

    query.bindVariable("doc", &device);

    query.setQuery(QLatin1String("declare variable $doc external; $doc"));

    QVERIFY(query.isValid());

    /* Check the URI corresponding to the variable. */
    {
        QXmlResultItems items;
        query.evaluateTo(&items);

        QCOMPARE(items.next().toAtomicValue().toString(), QString::fromLatin1("tag:trolltech.com,2007:QtXmlPatterns:QIODeviceVariable:doc"));
    }

    /* Now, actually load the document. We use the same QXmlQuery just to stress recompilation a bit. */
    {
        query.setQuery(QLatin1String("declare variable $doc external; doc($doc)"));

        QByteArray out;
        QBuffer outBuffer(&out);
        QVERIFY(outBuffer.open(QIODevice::WriteOnly));

        QXmlSerializer serializer(query, &outBuffer);

        QVERIFY(query.evaluateTo(&serializer));
        QCOMPARE(out, in);
    }
}

void tst_QXmlQuery::bindVariableQStringQIODeviceWithString() const
{
    QXmlQuery query;

    QString in("<qstring/>");
    QByteArray inUtf8(in.toUtf8());
    QBuffer inDevice(&inUtf8);

    QVERIFY(inDevice.open(QIODevice::ReadOnly));

    query.bindVariable("doc", &inDevice);

    query.setQuery(QLatin1String("declare variable $doc external; doc($doc)"));

    QByteArray out;
    QBuffer outBuffer(&out);
    QVERIFY(outBuffer.open(QIODevice::WriteOnly));

    QXmlSerializer serializer(query, &outBuffer);
    QVERIFY(query.evaluateTo(&serializer));

    QCOMPARE(out, inUtf8);
}

void tst_QXmlQuery::bindVariableQStringQIODeviceWithQFile() const
{
    QXmlQuery query;
    QFile inDevice(QFINDTESTDATA("input.xml"));

    QVERIFY(inDevice.open(QIODevice::ReadOnly));

    query.bindVariable("doc", &inDevice);

    query.setQuery(QLatin1String("declare variable $doc external; doc($doc)"));

    QByteArray out;
    QBuffer outBuffer(&out);
    QVERIFY(outBuffer.open(QIODevice::WriteOnly));

    QXmlSerializer serializer(query, &outBuffer);
    QVERIFY(query.evaluateTo(&serializer));
    outBuffer.close();

    QCOMPARE(out, QByteArray("<!-- This is just a file for testing. --><input/>"));
}

void tst_QXmlQuery::bindVariableQStringQIODevice() const
{
    QXmlQuery query;

    /* Rebind the variable. */
    {
        /* First evaluation. */
        {
            QByteArray in1("<e1/>");
            QBuffer inDevice1(&in1);
            QVERIFY(inDevice1.open(QIODevice::ReadOnly));

            query.bindVariable("in", &inDevice1);
            query.setQuery(QLatin1String("doc($in)"));

            QByteArray out1;
            QBuffer outDevice1(&out1);
            QVERIFY(outDevice1.open(QIODevice::WriteOnly));

            QXmlSerializer serializer(query, &outDevice1);
            query.evaluateTo(&serializer);
            QCOMPARE(out1, in1);
        }

        /* Second evaluation, rebind variable. */
        {
            QByteArray in2("<e2/>");
            QBuffer inDevice2(&in2);
            QVERIFY(inDevice2.open(QIODevice::ReadOnly));

            query.bindVariable(QLatin1String("in"), &inDevice2);

            QByteArray out2;
            QBuffer outDevice2(&out2);
            QVERIFY(outDevice2.open(QIODevice::WriteOnly));

            QXmlSerializer serializer(query, &outDevice2);
            QVERIFY(query.evaluateTo(&serializer));
            QCOMPARE(out2, in2);
        }
    }

    // TODO trigger recompilation when setting qiodevices., and qiodevice overwritten by other type, etc.
}

void tst_QXmlQuery::bindVariableQXmlNameQIODevice() const
{
    // TODO
}

void tst_QXmlQuery::bindVariableQXmlNameQIODeviceTriggerWarnings() const
{
    QXmlNamePool np;
    QXmlQuery query(np);

    QBuffer buffer;
    QTest::ignoreMessage(QtWarningMsg, "A null, or readable QIODevice must be passed.");
    query.bindVariable(QXmlName(np, QLatin1String("foo")), &buffer);

    QTest::ignoreMessage(QtWarningMsg, "The variable name cannot be null.");
    query.bindVariable(QXmlName(), 0);
}

void tst_QXmlQuery::bindVariableXSLTSuccess() const
{
    QXmlQuery stylesheet(QXmlQuery::XSLT20);
    stylesheet.setInitialTemplateName(QLatin1String("main"));

    stylesheet.bindVariable(QLatin1String("variableNoSelectNoBodyBoundWithBindVariable"),
                                          QVariant(QLatin1String("MUST NOT SHOW 1")));

    stylesheet.bindVariable(QLatin1String("variableSelectBoundWithBindVariable"),
                                          QVariant(QLatin1String("MUST NOT SHOW 2")));

    stylesheet.bindVariable(QLatin1String("variableSelectWithTypeIntBoundWithBindVariable"),
                                          QVariant(QLatin1String("MUST NOT SHOW 3")));

    stylesheet.bindVariable(QLatin1String("paramNoSelectNoBodyBoundWithBindVariable"),
                                          QVariant(QLatin1String("param1")));

    stylesheet.bindVariable(QLatin1String("paramNoSelectNoBodyBoundWithBindVariableRequired"),
                                          QVariant(QLatin1String("param1")));

    stylesheet.bindVariable(QLatin1String("paramSelectBoundWithBindVariable"),
                                          QVariant(QLatin1String("param2")));

    stylesheet.bindVariable(QLatin1String("paramSelectBoundWithBindVariableRequired"),
                                          QVariant(QLatin1String("param3")));

    stylesheet.bindVariable(QLatin1String("paramSelectWithTypeIntBoundWithBindVariable"),
                                          QVariant(4));

    stylesheet.bindVariable(QLatin1String("paramSelectWithTypeIntBoundWithBindVariableRequired"),
                                          QVariant(QLatin1String("param5")));

    stylesheet.setQuery(QUrl(inputFileAsURI(m_xmlPatternsDir + QLatin1String("/stylesheets/parameters.xsl"))));

    QVERIFY(stylesheet.isValid());

    QBuffer deviceOut;
    QVERIFY(deviceOut.open(QIODevice::ReadWrite));

    QVERIFY(stylesheet.evaluateTo(&deviceOut));

    const QString result(QString::fromUtf8(deviceOut.data().constData()));

    QCOMPARE(result,
             QString::fromLatin1("Variables:   variableSelectsDefaultValue variableSelectsDefaultValue2 3 4 "
                                 "Parameters: param1 param1 param2 param3 4 param5"));
}

void tst_QXmlQuery::bindVariableTemporaryNode() const
{
    /* First we do it with QXmlResultItems staying in scope. */;
    {
        QXmlQuery query1;
        query1.setQuery("<anElement/>");

        QXmlResultItems result1;
        query1.evaluateTo(&result1);

        QXmlQuery query2(query1);
        query2.bindVariable("fromQuery1", result1.next());
        query2.setQuery("$fromQuery1");

        QString output;
        QVERIFY(query2.evaluateTo(&output));

        QCOMPARE(output, QString::fromLatin1("<anElement/>\n"));
    }

    /* And now with it deallocating, so its internal DynamicContext pointer is
     * released. This doesn't work in Qt 4.5 and is ok. */
    {
        QXmlQuery query1;
        query1.setQuery("<anElement/>");

        QXmlQuery query2;

        {
            QXmlResultItems result1;
            query1.evaluateTo(&result1);

            query2.bindVariable("fromQuery1", result1.next());
            query2.setQuery("$fromQuery1");
        }

        QString output;
        return; // See comment above.
        QVERIFY(query2.evaluateTo(&output));

        QCOMPARE(output, QString::fromLatin1("<anElement/>\n"));
    }
}

void tst_QXmlQuery::messageHandler() const
{
    {
        /* Check default value. */
        QXmlQuery query;
        QCOMPARE(query.messageHandler(), static_cast<QAbstractMessageHandler *>(0));
    }
}

void tst_QXmlQuery::setMessageHandler() const
{
    QXmlQuery query;
    MessageSilencer silencer;
    query.setMessageHandler(&silencer);
    QCOMPARE(static_cast<QAbstractMessageHandler *>(&silencer), query.messageHandler());
}

void tst_QXmlQuery::evaluateToReceiver()
{
    QFETCH(QString, inputQuery);

    /* This query prints a URI specific to the local system. */
    if(inputQuery == QLatin1String("static-base-uri.xq"))
        return;

    ++m_pushTestsCount;
    const QString queryURI(inputFile(m_xmlPatternsDir + QLatin1String("/queries/") + inputQuery));
    QFile queryFile(queryURI);

    QVERIFY(queryFile.exists());
    QVERIFY(queryFile.open(QIODevice::ReadOnly));

    QXmlQuery query;

    MessageSilencer receiver;
    query.setMessageHandler(&receiver);
    query.setQuery(&queryFile, QUrl::fromLocalFile(queryURI));

    /* We read all the queries, and some of them are invalid. However, we
     * only want those that compile. */
    if(!query.isValid())
        return;

    QString produced;
    QTextStream stream(&produced, QIODevice::WriteOnly);
    PushBaseliner push(stream, query.namePool());
    QVERIFY(push.isValid());
    query.evaluateTo(&push);

    const QString baselineName(QFINDTESTDATA("pushBaselines/") + inputQuery.left(inputQuery.length() - 2) + QString::fromLatin1("ref"));
    QFile baseline(baselineName);

    if(baseline.exists())
    {
        QVERIFY(baseline.open(QIODevice::ReadOnly | QIODevice::Text));
        const QString stringedBaseline(QString::fromUtf8(baseline.readAll()));
        QCOMPARE(produced, stringedBaseline);
    }
    else
    {
        QVERIFY(baseline.open(QIODevice::WriteOnly));
        /* This is intentionally a warning, don't remove it. Update the baselines instead. */
        qWarning() << "Generated baseline for:" << baselineName;
        ++m_generatedBaselines;

        baseline.write(produced.toUtf8());
    }
}

void tst_QXmlQuery::evaluateToReceiver_data() const
{
    QTest::addColumn<QString>("inputQuery");

    const auto queries_ = queries();
    for (QString const& query : queries_) {
        /* This outputs a URI specific to the environment, so we can't use it for this
         * particular test. */
        if (query != QLatin1String("staticBaseURI.xq"))
            QTest::newRow(query.toUtf8().constData()) << query;
    }
}

void tst_QXmlQuery::evaluateToReceiverOnInvalidQuery() const
{
    /* Invoke on a default constructed object. */
    {
        QByteArray out;
        QBuffer buffer(&out);
        buffer.open(QIODevice::WriteOnly);

        QXmlQuery query;
        QXmlSerializer serializer(query, &buffer);
        QVERIFY(!query.evaluateTo(&serializer));
    }

    /* Invoke on an invalid query; compile time error. */
    {
        QByteArray out;
        QBuffer buffer(&out);
        buffer.open(QIODevice::WriteOnly);
        MessageSilencer silencer;

        QXmlQuery query;
        query.setMessageHandler(&silencer);
        query.setQuery(QLatin1String("1 + "));
        QXmlSerializer serializer(query, &buffer);
        QVERIFY(!query.evaluateTo(&serializer));
    }

    /* Invoke on an invalid query; runtime error. */
    {
        QByteArray out;
        QBuffer buffer(&out);
        buffer.open(QIODevice::WriteOnly);
        MessageSilencer silencer;

        QXmlQuery query;
        query.setMessageHandler(&silencer);
        query.setQuery(QLatin1String("error()"));
        QXmlSerializer serializer(query, &buffer);
        QVERIFY(!query.evaluateTo(&serializer));
    }
}

void tst_QXmlQuery::evaluateToQStringTriggerError() const
{
    /* Invoke on a default constructed object. */
    {
        QXmlQuery query;
        QString out;
        QVERIFY(!query.evaluateTo(&out));
    }

    /* Invoke on an invalid query; compile time error. */
    {
        QXmlQuery query;
        MessageSilencer silencer;
        query.setMessageHandler(&silencer);

        query.setQuery(QLatin1String("1 + "));

        QString out;
        QVERIFY(!query.evaluateTo(&out));
    }

    /* Invoke on an invalid query; runtime error. */
    {
        QXmlQuery query;
        MessageSilencer silencer;
        query.setMessageHandler(&silencer);

        query.setQuery(QLatin1String("error()"));

        QString out;
        QVERIFY(!query.evaluateTo(&out));
    }
}

void tst_QXmlQuery::evaluateToQString() const
{
    QFETCH(QString, query);
    QFETCH(QString, expectedOutput);

    QXmlQuery queryInstance;
    queryInstance.setQuery(query);
    QVERIFY(queryInstance.isValid());

    QString result;
    QVERIFY(queryInstance.evaluateTo(&result));

    QCOMPARE(result, expectedOutput);
}

void tst_QXmlQuery::evaluateToQString_data() const
{
    QTest::addColumn<QString>("query");
    QTest::addColumn<QString>("expectedOutput");

    QTest::newRow("Two atomics")
        << QString::fromLatin1("1, 'two'")
        << QString::fromLatin1("1 two\n");

    QTest::newRow("An element")
        << QString::fromLatin1("<e>{1}</e>")
        << QString::fromLatin1("<e>1</e>\n");
}

void tst_QXmlQuery::evaluateToQStringSignature() const
{
    const QXmlQuery query;

    QString output;

    /* evaluateTo(QString *) should be a const function. */
    query.evaluateTo(&output);
}

void tst_QXmlQuery::evaluateToQAbstractXmlReceiverTriggerWarnings() const
{
    QXmlQuery query;

    /* We check the return value as well as warning message here. */
    QTest::ignoreMessage(QtWarningMsg, "A non-null callback must be passed.");
    QCOMPARE(query.evaluateTo(static_cast<QAbstractXmlReceiver *>(0)),
             false);
}

void tst_QXmlQuery::evaluateToQXmlResultItems() const
{
    /* Invoke on a default constructed object. */
    {
        QXmlQuery query;
        QXmlResultItems result;
        query.evaluateTo(&result);
        QVERIFY(result.next().isNull());
    }
}

void tst_QXmlQuery::evaluateToQXmlResultItemsTriggerWarnings() const
{
    QTest::ignoreMessage(QtWarningMsg, "A null pointer cannot be passed.");
    QXmlQuery query;
    query.evaluateTo(static_cast<QXmlResultItems *>(0));
}

void tst_QXmlQuery::evaluateToQXmlResultItemsErrorAtEnd() const
{
    QXmlQuery query;
    MessageSilencer silencer;
    query.setMessageHandler(&silencer);
    query.setQuery(QLatin1String("1 to 100, fn:error()"));
    QVERIFY(query.isValid());

    QXmlResultItems it;
    query.evaluateTo(&it);

    while(!it.next().isNull())
    {
    }
}

/*!
  If baselines were generated, we flag it as a failure such that it gets
  attention, and that they are adjusted accordingly.
 */
void tst_QXmlQuery::checkGeneratedBaselines() const
{
    QCOMPARE(m_generatedBaselines, 0);

    /* If this check fails, the auto test setup is misconfigured, or files have
     * been added/removed without this number being updated. */
    QCOMPARE(m_pushTestsCount, int(ExpectedQueryCount));
}

void tst_QXmlQuery::basicXQueryToQtTypeCheck() const
{
    QFile queryFile(m_xmlPatternsDir + QLatin1String("/queries/") + QString::fromLatin1("allAtomics.xq"));
    QVERIFY(queryFile.open(QIODevice::ReadOnly));

    QXmlQuery query;
    query.setQuery(&queryFile);
    QVERIFY(query.isValid());

    QXmlResultItems it;
    query.evaluateTo(&it);

    QVariantList expectedValues;
    expectedValues.append(QString::fromLatin1("xs:untypedAtomic"));
    expectedValues.append(QDateTime(QDate(2002, 10, 10), QTime(23, 2, 11), Qt::UTC));
    expectedValues.append(QDate(2002, 10, 10));
    expectedValues.append(QVariant()); /* We currently doesn't support xs:time through the API. */

    expectedValues.append(QVariant()); /* xs:duration */
    expectedValues.append(QVariant()); /* xs:dayTimeDuration */
    expectedValues.append(QVariant()); /* xs:yearMonthDuration */

    if(sizeof(qreal) == sizeof(float)) {//ARM casts to Float not to double
        expectedValues.append(QVariant(float(3e3)));     /* xs:float */
        expectedValues.append(QVariant(float(4e4)));     /* xs:double */
        expectedValues.append(QVariant(float(2)));       /* xs:decimal */
    } else {
        expectedValues.append(QVariant(double(3e3)));     /* xs:float */
        expectedValues.append(QVariant(double(4e4)));     /* xs:double */
        expectedValues.append(QVariant(double(2)));       /* xs:decimal */
    }

    /* xs:integer and its sub-types. */
    expectedValues.append(QVariant(qlonglong(16)));
    expectedValues.append(QVariant(qlonglong(-6)));
    expectedValues.append(QVariant(qlonglong(-4)));
    expectedValues.append(QVariant(qlonglong(5)));
    expectedValues.append(QVariant(qlonglong(6)));
    expectedValues.append(QVariant(qlonglong(7)));
    expectedValues.append(QVariant(qlonglong(8)));
    expectedValues.append(QVariant(qlonglong(9)));
    expectedValues.append(QVariant(qulonglong(10)));
    expectedValues.append(QVariant(qlonglong(11)));
    expectedValues.append(QVariant(qlonglong(12)));
    expectedValues.append(QVariant(qlonglong(13)));
    expectedValues.append(QVariant(qlonglong(14)));

    expectedValues.append(QVariant());                                                          /* xs:gYearMonth("1976-02"), */
    expectedValues.append(QVariant());                                                          /* xs:gYear("2005-12:00"), */
    expectedValues.append(QVariant());                                                          /* xs:gMonthDay("--12-25-14:00"), */
    expectedValues.append(QVariant());                                                          /* xs:gDay("---25-14:00"), */
    expectedValues.append(QVariant());                                                          /* xs:gMonth("--12-14:00"), */
    expectedValues.append(true);                                                                /* xs:boolean("true"), */
    expectedValues.append(QVariant(QByteArray::fromBase64(QByteArray("aaaa"))));                /* xs:base64Binary("aaaa"), */
    expectedValues.append(QVariant(QByteArray::fromHex(QByteArray("FFFF"))));                   /* xs:hexBinary("FFFF"), */
    expectedValues.append(QVariant(QString::fromLatin1("http://example.com/")));                /* xs:anyURI("http://example.com/"), */
    QXmlNamePool np(query.namePool());
    expectedValues.append(QVariant::fromValue(QXmlName(np, QLatin1String("localName"),
                                                           QLatin1String("http://example.com/2"),
                                                           QLatin1String("prefix"))));

    expectedValues.append(QVariant(QString::fromLatin1("An xs:string")));
    expectedValues.append(QVariant(QString::fromLatin1("normalizedString")));
    expectedValues.append(QVariant(QString::fromLatin1("token")));
    expectedValues.append(QVariant(QString::fromLatin1("language")));
    expectedValues.append(QVariant(QString::fromLatin1("NMTOKEN")));
    expectedValues.append(QVariant(QString::fromLatin1("Name")));
    expectedValues.append(QVariant(QString::fromLatin1("NCName")));
    expectedValues.append(QVariant(QString::fromLatin1("ID")));
    expectedValues.append(QVariant(QString::fromLatin1("IDREF")));
    expectedValues.append(QVariant(QString::fromLatin1("ENTITY")));

    int i = 0;
    QXmlItem item(it.next());

    while(!item.isNull())
    {
        QVERIFY(item.isAtomicValue());
        const QVariant produced(item.toAtomicValue());

        const QVariant &expected = expectedValues.at(i);

        /* For the cases where we can't represent a value in the XDM with Qt,
         * we return an invalid QVariant. */
        QCOMPARE(expected.isValid(), produced.isValid());

        QCOMPARE(produced.type(), expected.type());

        if(expected.isValid())
        {
            /* This is only needed for xs:decimal though, for some reason. Probably
             * just artifacts created somewhere. */
            if(produced.type() == QVariant::Double)
                QVERIFY(qFuzzyCompare(produced.toDouble(), expected.toDouble()));
            else if (produced.canConvert<QXmlName>())
            {
                /* QVariant::operator==() does identity comparison, it doesn't delegate to operator==() of
                 * the contained type, unless it's hardcoded into QVariant. */
                const QXmlName n1 = qvariant_cast<QXmlName>(produced);
                const QXmlName n2 = qvariant_cast<QXmlName>(expected);
                QCOMPARE(n1, n2);
            }
            else
                QCOMPARE(produced, expected);
        }

        ++i;
        item = it.next();
    }

    QCOMPARE(i, expectedValues.count());
}

/*!
  Send values from Qt into XQuery.
 */
void tst_QXmlQuery::basicQtToXQueryTypeCheck() const
{
    QFile queryFile(m_xmlPatternsDir + QLatin1String("/queries/") + QLatin1String("allAtomicsExternally.xq"));
    QVERIFY(queryFile.exists());
    QVERIFY(queryFile.open(QIODevice::ReadOnly));

    QCOMPARE(QVariant(QDate(1999, 9, 10)).type(), QVariant::Date);

    QXmlQuery query;

    QXmlNamePool np(query.namePool());

    const QXmlName name(np, QLatin1String("localname"),
                            QLatin1String("http://example.com"),
                            QLatin1String("prefix"));

    query.bindVariable(QLatin1String("fromQUrl"), QXmlItem(QUrl(QString::fromLatin1("http://example.com/"))));
    query.bindVariable(QLatin1String("fromQByteArray"), QXmlItem(QByteArray("AAAA")));
    query.bindVariable(QLatin1String("fromBool"), QXmlItem(bool(true)));
    query.bindVariable(QLatin1String("fromQDate"), QXmlItem(QDate(2000, 10, 11)));
    // TODO Do with different QDateTime time specs
    query.bindVariable(QLatin1String("fromQDateTime"), QXmlItem(QDateTime(QDate(2001, 9, 10), QTime(1, 2, 3))));
    query.bindVariable(QLatin1String("fromDouble"), QXmlItem(double(3)));
    query.bindVariable(QLatin1String("fromFloat"), QXmlItem(float(4)));
    query.bindVariable(QLatin1String("integer"), QXmlItem(5));
    query.bindVariable(QLatin1String("fromQString"), QXmlItem(QString::fromLatin1("A QString")));
    query.bindVariable(QLatin1String("fromQChar"), QXmlItem(QChar::fromLatin1('C')));

    query.bindVariable(QLatin1String("fromIntLiteral"), QXmlItem(QVariant(654)));

    {
        QVariant ui(uint(5));
        QCOMPARE(ui.type(), QVariant::UInt);
        query.bindVariable(QLatin1String("fromUInt"), ui);
    }

    {
        QVariant ulnglng(qulonglong(6));
        QCOMPARE(ulnglng.type(), QVariant::ULongLong);
        query.bindVariable(QLatin1String("fromULongLong"), ulnglng);
    }

    {
        QVariant qlnglng(qlonglong(7));
        QCOMPARE(qlnglng.type(), QVariant::LongLong);
        query.bindVariable(QLatin1String("fromLongLong"), qlnglng);
    }

    query.setQuery(&queryFile);

    // TODO do queries which declares external variables with types. Tons of combos here.
    // TODO ensure that binding with QXmlItem() doesn't make a binding available.
    // TODO test rebinding a variable.

    QVERIFY(query.isValid());

    QXmlResultItems it;
    query.evaluateTo(&it);
    QXmlItem item(it.next());
    QVERIFY(!item.isNull());
    QVERIFY(item.isAtomicValue());

    if(sizeof(qreal) == sizeof(float)) //ARM casts to Float not to double
        QCOMPARE(item.toAtomicValue().toString(),
                 QLatin1String("4 true 3 654 7 41414141 C 2000-10-11Z 2001-09-10T01:02:03 "
                               "A QString http://example.com/ 5 6 true false false true true true true true true true "
                               "true true true"));
    else
        QCOMPARE(item.toAtomicValue().toString(),
                 QLatin1String("4 true 3 654 7 41414141 C 2000-10-11Z 2001-09-10T01:02:03 "
                               "A QString http://example.com/ 5 6 true true true true true true true true true true "
                               "true true true"));

}

void tst_QXmlQuery::bindNode() const
{
    QXmlQuery query;
    TestSimpleNodeModel nodeModel(query.namePool());

    query.bindVariable(QLatin1String("node"), nodeModel.root());
    QByteArray out;
    QBuffer buff(&out);
    QVERIFY(buff.open(QIODevice::WriteOnly));

    query.setQuery(QLatin1String("declare variable $node external; $node"));
    QXmlSerializer serializer(query, &buff);

    QVERIFY(query.evaluateTo(&serializer));
    QCOMPARE(out, QByteArray("<nodeName/>"));
}

/*!
  Pass in a relative URI, and make sure it is resolved against the current application directory.
 */
void tst_QXmlQuery::relativeBaseURI() const
{
    QXmlQuery query;
    query.setQuery(QLatin1String("fn:static-base-uri()"), QUrl(QLatin1String("a/relative/uri.weirdExtension")));
    QVERIFY(query.isValid());

    QByteArray result;
    QBuffer buffer(&result);
    QVERIFY(buffer.open(QIODevice::ReadWrite));

    QXmlSerializer serializer(query, &buffer);
    QVERIFY(query.evaluateTo(&serializer));

    const QUrl loaded(QUrl::fromEncoded(result));
    QUrl appPath(QUrl::fromLocalFile(QCoreApplication::applicationFilePath()));

    QVERIFY(loaded.isValid());
    QVERIFY(appPath.isValid());
    QVERIFY(!loaded.isRelative());
    QVERIFY(!appPath.isRelative());

    QFileInfo dir(appPath.toLocalFile());

    /* We can't use QUrl::isParentOf() because it doesn't do what we want it to */
    if (!loaded.toLocalFile().startsWith(dir.absolutePath()))
        QTextStream(stderr) << "dir.absolutePath():" << dir.absolutePath() << "loaded.toLocalFile():" << loaded.toLocalFile();

    checkBaseURI(loaded, dir.absolutePath());
}

void tst_QXmlQuery::emptyBaseURI() const
{
    QXmlQuery query;
    query.setQuery(QLatin1String("fn:static-base-uri()"), QUrl());
    QVERIFY(query.isValid());

    QByteArray result;
    QBuffer buffer(&result);
    QVERIFY(buffer.open(QIODevice::ReadWrite));

    QXmlSerializer serializer(query, &buffer);
    QVERIFY(query.evaluateTo(&serializer));

    const QUrl loaded(QUrl::fromEncoded(result));
    QUrl appPath(QUrl::fromLocalFile(QCoreApplication::applicationFilePath()));

    QVERIFY(loaded.isValid());
    QVERIFY(appPath.isValid());
    QVERIFY(!loaded.isRelative());
    QVERIFY(!appPath.isRelative());

    QFileInfo dir(appPath.toLocalFile());
    dir.setFile(QString());

    QCOMPARE(loaded, appPath);
}

/*!
  Ensure that QDate comes out as QDateTime.
 */
void tst_QXmlQuery::roundTripDateWithinQXmlItem() const
{
    const QDate date(1999, 9, 10);
    QVERIFY(date.isValid());

    const QVariant variant(date);
    QVERIFY(variant.isValid());
    QCOMPARE(variant.type(), QVariant::Date);

    const QXmlItem item(variant);
    QVERIFY(!item.isNull());
    QVERIFY(item.isAtomicValue());

    const QVariant out(item.toAtomicValue());
    QVERIFY(out.isValid());
    QCOMPARE(out.type(), QVariant::Date);
    QCOMPARE(out.toDate(), date);
}

/*!
 Check whether a query is valid, which uses an unbound variable.
 */
void tst_QXmlQuery::bindingMissing() const
{
    QXmlQuery query;
    MessageSilencer messageHandler;
    query.setMessageHandler(&messageHandler);

    QFile queryFile(m_xmlPatternsDir + QLatin1String("/queries/") + QString::fromLatin1("externalVariable.xq"));
    QVERIFY(queryFile.open(QIODevice::ReadOnly));
    query.setQuery(&queryFile);

    QVERIFY(!query.isValid());
}

void tst_QXmlQuery::bindDefaultConstructedItem() const
{
    QFETCH(QXmlItem, item);

    QXmlQuery query;
    MessageSilencer messageHandler;
    query.setMessageHandler(&messageHandler);

    QFile queryFile(m_xmlPatternsDir + QLatin1String("/queries/") + QString::fromLatin1("externalVariable.xq"));
    QVERIFY(queryFile.open(QIODevice::ReadOnly));
    query.setQuery(&queryFile);
    query.bindVariable(QLatin1String("externalVariable"), item);

    QVERIFY(!query.isValid());
}

void tst_QXmlQuery::bindDefaultConstructedItem_data() const
{
    QTest::addColumn<QXmlItem>("item");

    QTest::newRow("QXmlItem()") << QXmlItem();
    QTest::newRow("QXmlItem(QVariant())") << QXmlItem(QVariant());
    QTest::newRow("QXmlItem(QXmlNodeModelIndex())") << QXmlItem(QXmlNodeModelIndex());
}

/*!
  Remove a binding by binding QXmlItem() with the same name.
 */
void tst_QXmlQuery::eraseQXmlItemBinding() const
{
    QXmlQuery query;
    MessageSilencer messageHandler;
    query.setMessageHandler(&messageHandler);

    QFile queryFile(m_xmlPatternsDir + QLatin1String("/queries/") + QString::fromLatin1("externalVariable.xq"));
    QVERIFY(queryFile.open(QIODevice::ReadOnly));
    query.bindVariable(QLatin1String("externalVariable"), QXmlItem(3));
    query.setQuery(&queryFile);
    QVERIFY(query.isValid());

    QByteArray result;
    QBuffer buffer(&result);
    QVERIFY(buffer.open(QIODevice::ReadWrite));

    QXmlSerializer serializer(query, &buffer);
    QVERIFY(query.evaluateTo(&serializer));

    QCOMPARE(result, QByteArray("3 6<e>3</e>false"));

    query.bindVariable(QLatin1String("externalVariable"), QXmlItem());
    QVERIFY(!query.isValid());
}

/*!
 Erase a variable binding
 */
void tst_QXmlQuery::eraseDeviceBinding() const
{
    /* Erase an existing QIODevice binding with another QIODevice binding. */
    {
        QXmlQuery query;

        QByteArray doc("<e/>");
        QBuffer buffer(&doc);
        QVERIFY(buffer.open(QIODevice::ReadOnly));

        query.bindVariable(QLatin1String("in"), &buffer);
        query.setQuery(QLatin1String("$in"));
        QVERIFY(query.isValid());

        query.bindVariable(QLatin1String("in"), 0);
        QVERIFY(!query.isValid());
    }

    /* Erase an existing QXmlItem binding with another QIODevice binding. */
    {
        QXmlQuery query;

        query.bindVariable(QLatin1String("in"), QXmlItem(5));
        query.setQuery(QLatin1String("$in"));
        QVERIFY(query.isValid());

        query.bindVariable(QLatin1String("in"), 0);
        QVERIFY(!query.isValid());
    }
}

/*!
 Bind a variable, evaluate, bind with a different value but same type, and evaluate again.
 */
void tst_QXmlQuery::rebindVariableSameType() const
{
    QXmlQuery query;
    MessageSilencer messageHandler;
    query.setMessageHandler(&messageHandler);

    query.bindVariable(QLatin1String("externalVariable"), QXmlItem(3));

    {
        QFile queryFile(m_xmlPatternsDir + QLatin1String("/queries/") + QString::fromLatin1("externalVariable.xq"));
        QVERIFY(queryFile.open(QIODevice::ReadOnly));
        query.setQuery(&queryFile);
    }

    QVERIFY(query.isValid());

    {
        QByteArray result;
        QBuffer buffer(&result);
        QVERIFY(buffer.open(QIODevice::ReadWrite));

        QXmlSerializer serializer(query, &buffer);
        QVERIFY(query.evaluateTo(&serializer));

        QCOMPARE(result, QByteArray("3 6<e>3</e>false"));
    }

    {
        query.bindVariable(QLatin1String("externalVariable"), QXmlItem(5));
        QByteArray result;
        QBuffer buffer(&result);
        QVERIFY(buffer.open(QIODevice::ReadWrite));

        QXmlSerializer serializer(query, &buffer);
        QVERIFY(query.evaluateTo(&serializer));

        QCOMPARE(result, QByteArray("5 8<e>5</e>false"));
    }

}

void tst_QXmlQuery::rebindVariableDifferentType() const
{
    /* Rebind QXmlItem variable with QXmlItem variable. */
    {
        QXmlQuery query;
        query.bindVariable(QLatin1String("in"), QXmlItem(3));
        query.setQuery(QLatin1String("$in"));
        QVERIFY(query.isValid());

        query.bindVariable(QLatin1String("in"), QXmlItem("A string"));
        QVERIFY(!query.isValid());
    }

    /* Rebind QIODevice variable with QXmlItem variable. */
    {
        QXmlQuery query;
        QBuffer buffer;
        buffer.setData(QByteArray("<e/>"));
        QVERIFY(buffer.open(QIODevice::ReadOnly));

        query.bindVariable(QLatin1String("in"), &buffer);
        query.setQuery(QLatin1String("$in"));
        QVERIFY(query.isValid());

        query.bindVariable(QLatin1String("in"), QXmlItem("A string"));
        QVERIFY(!query.isValid());
    }

    /* Rebind QXmlItem variable with QIODevice variable. The type of the
     * variable changes, so a recompile is necessary. */
    {
        QXmlQuery query;

        query.bindVariable(QLatin1String("in"), QXmlItem(QLatin1String("A string")));
        query.setQuery(QLatin1String("$in"));
        QVERIFY(query.isValid());

        QBuffer buffer;
        buffer.setData(QByteArray("<e/>"));
        QVERIFY(buffer.open(QIODevice::ReadOnly));
        query.bindVariable(QLatin1String("in"), &buffer);
        QVERIFY(!query.isValid());
    }
}

void tst_QXmlQuery::rebindVariableWithNullItem() const
{
    QXmlQuery query;

    query.bindVariable(QLatin1String("name"), QXmlItem(5));
    query.bindVariable(QLatin1String("name"), QXmlItem());
}

void tst_QXmlQuery::constCorrectness() const
{
    QXmlResultItems result;
    QXmlQuery tmp;
    tmp.setQuery(QLatin1String("1")); /* Just so we have a valid query. */
    const QXmlQuery query(tmp);

    /* These functions should be const. */
    query.isValid();
    query.evaluateTo(&result);
    query.namePool();
    query.uriResolver();
    query.messageHandler();

    {
        QString dummyString;
        QTextStream dummyStream(&dummyString);
        PushBaseliner dummy(dummyStream, query.namePool());
        QVERIFY(dummy.isValid());
        query.evaluateTo(&dummy);
    }
}

void tst_QXmlQuery::objectSize() const
{
    /* We have a d pointer. */
    QCOMPARE(sizeof(QXmlQuery), sizeof(void *));
}

void tst_QXmlQuery::setUriResolver() const
{
    /* Set a null resolver, and make sure it can take a const pointer. */
    {
        QXmlQuery query;
        query.setUriResolver(static_cast<const QAbstractUriResolver *>(0));
        QCOMPARE(query.uriResolver(), static_cast<const QAbstractUriResolver *>(0));
    }

    {
        TestURIResolver resolver;
        QXmlQuery query;
        query.setUriResolver(&resolver);
        QCOMPARE(query.uriResolver(), static_cast<const QAbstractUriResolver *>(&resolver));
    }
}

void tst_QXmlQuery::uriResolver() const
{
    /* Check default value. */
    {
        QXmlQuery query;
        QCOMPARE(query.uriResolver(), static_cast<const QAbstractUriResolver *>(0));
    }
}

void tst_QXmlQuery::messageXML() const
{
    QXmlQuery query;

    MessageValidator messageValidator;
    query.setMessageHandler(&messageValidator);

    query.setQuery(QLatin1String("1basicSyntaxError"));

    QRegExp removeFilename(QLatin1String("Location: file:.*\\#"));
    QVERIFY(removeFilename.isValid());

    QVERIFY(messageValidator.success());
    QCOMPARE(messageValidator.received().remove(removeFilename),
             QString::fromLatin1("Type:3\n"
                                 "Description: <html xmlns='http://www.w3.org/1999/xhtml/'><body><p>syntax error, unexpected unknown keyword</p></body></html>\n"
                                 "Identifier: http://www.w3.org/2005/xqt-errors#XPST0003\n"
                                 "1,1"));
}

/*!
  1. Allocate QXmlResultItems
  2. Allocate QXmlQuery
  3. evaluate to the QXmlResultItems instance
  4. Dellocate the QXmlQuery instance
  5. Ensure QXmlResultItems works
 */
void tst_QXmlQuery::resultItemsDeallocatedQuery() const
{
    QXmlResultItems result;

    {
        QXmlQuery query;
        query.setQuery(QLatin1String("1, 2, xs:integer(<e>3</e>)"));
        query.evaluateTo(&result);
    }

    QCOMPARE(result.next().toAtomicValue(), QVariant(1));
    QCOMPARE(result.next().toAtomicValue(), QVariant(2));
    QCOMPARE(result.next().toAtomicValue(), QVariant(3));
    QVERIFY(result.next().isNull());
    QVERIFY(!result.hasError());
}

/*!
  1. Bind variable with bindVariable()
  2. setQuery that has 'declare variable' with same name.
  3. Ensure the value inside the query is used. We don't guarantee this behavior
     but that's what we lock.
 */
void tst_QXmlQuery::shadowedVariables() const
{
    QXmlQuery query;
    query.bindVariable("varName", QXmlItem(3));
    query.setQuery(QLatin1String("declare variable $varName := 5; $varName"));

    QXmlResultItems result;
    query.evaluateTo(&result);

    QCOMPARE(result.next().toAtomicValue(), QVariant(5));
}

void tst_QXmlQuery::setFocusQXmlItem() const
{
    /* Make sure we can take a const reference. */
    {
        QXmlQuery query;
        const QXmlItem item;
        query.setFocus(item);
    }

    // TODO evaluate with atomic value, check type
    // TODO evaluate with node, check type
    // TODO ensure that setFocus() triggers query recompilation, as appropriate.
    // TODO let the focus be undefined, call isvalid, call evaluate anyway
    // TODO let the focus be undefined, call evaluate directly
}

void tst_QXmlQuery::setFocusQUrl() const
{
    /* Load a focus which isn't well-formed. */
    {
        QXmlQuery query;
        MessageSilencer silencer;

        query.setMessageHandler(&silencer);

        QVERIFY(!query.setFocus(QUrl(QLatin1String("data/notWellformed.xml"))));
    }

    /* Ensure the same URI resolver is used. */
    {
        QXmlQuery query(QXmlQuery::XSLT20);

        const TestURIResolver resolver(QUrl(inputFileAsURI(m_xmlPatternsDir + QLatin1String("/stylesheets/documentElement.xml"))));
        query.setUriResolver(&resolver);

        QVERIFY(query.setFocus(QUrl(QLatin1String("arbitraryURI"))));
        query.setQuery(QUrl(inputFileAsURI(m_xmlPatternsDir + QLatin1String("/stylesheets/copyWholeDocument.xsl"))));
        QVERIFY(query.isValid());

        QBuffer result;
        QVERIFY(result.open(QIODevice::ReadWrite));
        QXmlSerializer serializer(query, &result);
        query.evaluateTo(&serializer);

        QCOMPARE(result.data(), QByteArray("<doc/>"));
    }

    // TODO ensure that the focus type doesn't change from XSLT20 on the main instance.
}

/*!
  This code poses a challenge wrt. to internal caching.
 */
void tst_QXmlQuery::setFocusQIODevice() const
{
    QXmlQuery query;

    {
        QBuffer focus;
        focus.setData(QByteArray("<e>abc</e>"));
        QVERIFY(focus.open(QIODevice::ReadOnly));
        query.setFocus(&focus);
        query.setQuery(QLatin1String("string()"));
        QVERIFY(query.isValid());

        QString output;
        query.evaluateTo(&output);

        QCOMPARE(output, QString::fromLatin1("abc\n"));
    }

    /* Set a new focus, make sure it changes & works. */
    {
        QBuffer focus2;
        focus2.setData(QByteArray("<e>abc2</e>"));
        QVERIFY(focus2.open(QIODevice::ReadOnly));
        query.setFocus(&focus2);
        QVERIFY(query.isValid());

        QString output;
        query.evaluateTo(&output);

        QCOMPARE(output, QString::fromLatin1("abc2\n"));
    }
}

/*!
 Since we internally use variable bindings for implementing the focus, we need
 to make sure we don't clash in this area.
*/
void tst_QXmlQuery::setFocusQIODeviceAvoidVariableClash() const
{
    QBuffer buffer;
    buffer.setData("<e>focus</e>");
    QVERIFY(buffer.open(QIODevice::ReadOnly));

    /* First we bind the variable name, then the focus. */
    {
        QXmlQuery query;
        query.bindVariable(QString(QLatin1Char('u')), QVariant(1));
        query.setFocus(&buffer);
        query.setQuery(QLatin1String("string()"));

        QString out;
        query.evaluateTo(&out);

        QCOMPARE(out, QString::fromLatin1("focus\n"));
    }

    /* First we bind the focus, then the variable name. */
    {
        QXmlQuery query;
        QVERIFY(buffer.open(QIODevice::ReadOnly));
        query.setFocus(&buffer);
        query.bindVariable(QString(QLatin1Char('u')), QVariant(1));
        query.setQuery(QLatin1String("string()"));

        QString out;
        query.evaluateTo(&out);

        QCOMPARE(out, QString::fromLatin1("focus\n"));
    }
}

void tst_QXmlQuery::setFocusQIODeviceFailure() const
{
    /* A not well-formed input document. */
    {
        QXmlQuery query;

        MessageSilencer silencer;
        query.setMessageHandler(&silencer);

        QBuffer input;
        input.setData("<e");
        QVERIFY(input.open(QIODevice::ReadOnly));

        QCOMPARE(query.setFocus(&input), false);
    }
}

void tst_QXmlQuery::setFocusQString() const
{
    QXmlQuery query;

    /* Basic use of focus. */
    {
        QVERIFY(query.setFocus(QLatin1String("<e>textNode</e>")));
        query.setQuery(QLatin1String("string()"));
        QVERIFY(query.isValid());
        QString out;
        query.evaluateTo(&out);
        QCOMPARE(out, QString::fromLatin1("textNode\n"));
    }

    /* Set to a new focus, make sure it changes and works. */
    {
        QVERIFY(query.setFocus(QLatin1String("<e>newFocus</e>")));
        QString out;
        query.evaluateTo(&out);
        QCOMPARE(out, QString::fromLatin1("newFocus\n"));
    }
}

void tst_QXmlQuery::setFocusQStringFailure() const
{
    QXmlQuery query;
    MessageSilencer silencer;

    query.setMessageHandler(&silencer);
    QVERIFY(!query.setFocus(QLatin1String("<notWellformed")));

    /* Let's try the slight special case of a null string. */
    QVERIFY(!query.setFocus(QString()));
}

void tst_QXmlQuery::setFocusQStringSignature() const
{
    QXmlQuery query;
    MessageSilencer silencer;
    query.setMessageHandler(&silencer);

    const QString argument;
    /* We should take a const ref. */
    query.setFocus(argument);

    /* We should return a bool. */
    static_cast<bool>(query.setFocus(QString()));
}

void tst_QXmlQuery::setFocusQIODeviceTriggerWarnings() const
{
    /* A null pointer. */
    {
        QXmlQuery query;

        QTest::ignoreMessage(QtWarningMsg, "A null QIODevice pointer cannot be passed.");
        QCOMPARE(query.setFocus(static_cast<QIODevice *>(0)), false);
    }

    /* A non opened-device. */
    {
        QXmlQuery query;

        QBuffer notReadable;
        QVERIFY(!notReadable.isReadable());

        QTest::ignoreMessage(QtWarningMsg, "The device must be readable.");
        QCOMPARE(query.setFocus(&notReadable), false);
    }
}

void tst_QXmlQuery::fnDocNetworkAccessSuccess() const
{
    if (QTest::currentDataTag() == QByteArray("http scheme")
            || QTest::currentDataTag() == QByteArray("ftp scheme"))
        QVERIFY(QtNetworkSettings::verifyTestNetworkSettings());

    QFETCH(QUrl, uriToOpen);
    QFETCH(QByteArray, expectedOutput);

    if(!uriToOpen.isValid())
        qDebug() << "uriToOpen:" << uriToOpen;

    QVERIFY(uriToOpen.isValid());

    QXmlQuery query;
    query.bindVariable(QLatin1String("uri"), QVariant(uriToOpen));
    query.setQuery(QLatin1String("declare variable $uri external;\ndoc($uri)"));
    QVERIFY(query.isValid());

    QByteArray result;
    QBuffer buffer(&result);
    QVERIFY(buffer.open(QIODevice::WriteOnly));

    QXmlSerializer serializer(query, &buffer);
    QVERIFY(query.evaluateTo(&serializer));

    QCOMPARE(result, expectedOutput);
}

void tst_QXmlQuery::fnDocNetworkAccessSuccess_data() const
{
    QTest::addColumn<QUrl>("uriToOpen");
    QTest::addColumn<QByteArray>("expectedOutput");

    QTest::newRow("file scheme")
        << inputFileAsURI(QFINDTESTDATA("input.xml"))
        << QByteArray("<!-- This is just a file for testing. --><input/>");

    QTest::newRow("data scheme with ASCII")
        /* QUrl::toPercentEncoding(QLatin1String("<e/>")) yields "%3Ce%2F%3E". */
        << QUrl::fromEncoded("data:application/xml,%3Ce%2F%3E")
        << QByteArray("<e/>");

    QTest::newRow("data scheme with ASCII no MIME type")
        << QUrl::fromEncoded("data:,%3Ce%2F%3E")
        << QByteArray("<e/>");

    QTest::newRow("data scheme with base 64")
        << QUrl::fromEncoded("data:application/xml;base64,PGUvPg==")
        << QByteArray("<e/>");

    QTest::newRow("qrc scheme")
        << QUrl::fromEncoded("qrc:/QXmlQueryTestData/data/oneElement.xml")
        << QByteArray("<oneElement/>");

    if(!m_testNetwork)
        return;

    QTest::newRow("http scheme")
        << QUrl(QString("http://" + QtNetworkSettings::serverName() + "/qtest/qxmlquery/wellFormed.xml"))
        << QByteArray("<!-- a comment --><e from=\"http\">Some Text</e>");

    QTest::newRow("ftp scheme")
        << QUrl(QString("ftp://" + QtNetworkSettings::serverName() + "/pub/qxmlquery/wellFormed.xml"))
        << QByteArray("<!-- a comment --><e from=\"ftp\">Some Text</e>");

}

void tst_QXmlQuery::fnDocNetworkAccessFailure() const
{
    if (QTest::currentDataTag() == QByteArray("http scheme, not well-formed")
            || QTest::currentDataTag() == QByteArray("https scheme, not well-formed")
            || QTest::currentDataTag() == QByteArray("ftp scheme, not well-formed"))
        QVERIFY(QtNetworkSettings::verifyTestNetworkSettings());

    QFETCH(QUrl, uriToOpen);

    QVERIFY(uriToOpen.isValid());

    QXmlQuery query;
    MessageSilencer silencer;
    query.setMessageHandler(&silencer);
    query.bindVariable(QLatin1String("uri"), QVariant(uriToOpen));
    query.setQuery(QLatin1String("declare variable $uri external;\ndoc($uri)"));
    QVERIFY(query.isValid());

    QXmlResultItems result;
    query.evaluateTo(&result);

    while(!result.next().isNull())
    {
        /* Just loop until the end. */
    }

    // TODO do something that triggers a /timeout/.
    QVERIFY(result.hasError());
}

void tst_QXmlQuery::fnDocNetworkAccessFailure_data() const
{
    QTest::addColumn<QUrl>("uriToOpen");

    QTest::newRow("data scheme, not-well-formed")
        << QUrl(QLatin1String("data:application/xml;base64,PGUvg==="));

    QTest::newRow("file scheme, non-existent file")
        << QUrl(QLatin1String("file:///example.com/does/notExist.xml"));

    QTest::newRow("http scheme, file not found")
        << QUrl(QLatin1String("http://www.example.com/does/not/exist.xml"));

    QTest::newRow("http scheme, nonexistent host")
        << QUrl(QLatin1String("http://this.host.does.not.exist.I.SWear"));

    QTest::newRow("qrc scheme, not well-formed")
        << QUrl(QLatin1String("qrc:/QXmlQueryTestData/notWellformed.xml"));

    QTest::newRow("'qrc:/', non-existing file")
        << QUrl(QLatin1String("qrc:/QXmlQueryTestData/data/thisFileDoesNotExist.xml"));

    if(!m_testNetwork)
        return;

    QTest::newRow("http scheme, not well-formed")
        << QUrl(QString("http://" + QtNetworkSettings::serverName() + "/qtest/qxmlquery/notWellformed.xml"));

    QTest::newRow("https scheme, not well-formed")
        << QUrl(QString("https://" + QtNetworkSettings::serverName() + "/qtest/qxmlquery/notWellformedViaHttps.xml"));

    QTest::newRow("https scheme, nonexistent host")
        << QUrl(QLatin1String("https://this.host.does.not.exist.I.SWear"));

    QTest::newRow("ftp scheme, nonexistent host")
        << QUrl(QLatin1String("ftp://this.host.does.not.exist.I.SWear"));

    QTest::newRow("ftp scheme, not well-formed")
        << QUrl(QString("ftp://" + QtNetworkSettings::serverName() + "/pub/qxmlquery/notWellFormed.xml"));
}

/*!
  Create a network timeout from a QIODevice binding such
  that we ensure we don't hang infinitely.
 */
void tst_QXmlQuery::fnDocOnQIODeviceTimeout() const
{
    if(!m_testNetwork)
        return;

    QTcpServer server;
    server.listen(QHostAddress::LocalHost, 1088);

    QTcpSocket client;
    client.connectToHost("localhost", 1088);
    QVERIFY(client.isReadable());

    QXmlQuery query;

    MessageSilencer silencer;
    query.setMessageHandler(&silencer);

    query.bindVariable(QLatin1String("inDevice"), &client);
    query.setQuery(QLatin1String("declare variable $inDevice external;\ndoc($inDevice)"));
    QVERIFY(query.isValid());

    QXmlResultItems result;
    query.evaluateTo(&result);
    QXmlItem next(result.next());

    while(!next.isNull())
    {
        next = result.next();
    }

    QVERIFY(result.hasError());
}

/*!
 When changing query, the static context must change too, such that
 the source locations are updated.
 */
void tst_QXmlQuery::recompilationWithEvaluateToResultFailing() const
{
    QXmlQuery query;
    MessageSilencer silencer;
    query.setMessageHandler(&silencer);

    query.setQuery(QLatin1String("1 + 1")); /* An arbitrary valid query. */
    QVERIFY(query.isValid()); /* Trigger query compilation. */

    query.setQuery(QLatin1String("fn:doc('doesNotExist.example.com.xml')")); /* An arbitrary invalid query that make use of a source location. */
    QVERIFY(query.isValid()); /* Trigger second compilation. */

    QXmlResultItems items;
    query.evaluateTo(&items);
    items.next();
    QVERIFY(items.hasError());
}

void tst_QXmlQuery::secondEvaluationWithEvaluateToResultFailing() const
{
    QXmlQuery query;
    MessageSilencer silencer;
    query.setMessageHandler(&silencer);

    query.setQuery(QLatin1String("1 + 1")); /* An arbitrary valid query. */
    QVERIFY(query.isValid()); /* Trigger query compilation. */

    query.setQuery(QLatin1String("fn:doc('doesNotExist.example.com.xml')")); /* An arbitrary invalid query that make use of a source location. */
    /* We don't call isValid(). */
QXmlResultItems items;
    query.evaluateTo(&items);
    items.next();
    QVERIFY(items.hasError());
}

/*!
 Compilation is triggered in the evaluation function due to no call to QXmlQuery::isValid().
 */
void tst_QXmlQuery::recompilationWithEvaluateToReceiver() const
{
    QXmlQuery query;
    MessageSilencer silencer;
    query.setMessageHandler(&silencer);

    query.setQuery(QLatin1String("1 + 1")); /* An arbitrary valid query. */
    QVERIFY(query.isValid()); /* Trigger query compilation. */

    query.setQuery(QLatin1String("fn:doc('doesNotExist.example.com.xml')")); /* An arbitrary invalid query that make use of a source location. */
    /* We don't call isValid(). */

    QByteArray dummy;
    QBuffer buffer(&dummy);
    buffer.open(QIODevice::WriteOnly);

    QXmlSerializer serializer(query, &buffer);

    QVERIFY(!query.evaluateTo(&serializer));
}

void tst_QXmlQuery::evaluateToQStringListOnInvalidQuery() const
{
    MessageSilencer silencer;

    /* Invoke on a default constructed object. */
    {
        QXmlQuery query;
        QStringList out;
        QVERIFY(!query.evaluateTo(&out));
    }

    /* Invoke on a syntactically invalid query. */
    {
        QXmlQuery query;
        QStringList out;
        MessageSilencer silencer;

        query.setMessageHandler(&silencer);
        query.setQuery(QLatin1String("1 + "));

        QVERIFY(!query.evaluateTo(&out));
    }

    /* Invoke on a query with the wrong type, one atomic. */
    {
        QXmlQuery query;
        QStringList out;

        query.setQuery(QLatin1String("1"));
        query.setMessageHandler(&silencer);
        QVERIFY(!query.evaluateTo(&out));
    }

    /* Invoke on a query with the wrong type, one element. */
    {
        QXmlQuery query;
        QStringList out;

        query.setQuery(QLatin1String("<e/>"));
        QVERIFY(!query.evaluateTo(&out));
    }

    /* Invoke on a query with the wrong type, mixed nodes & atomics. */
    {
        QXmlQuery query;
        QStringList out;

        query.setQuery(QLatin1String("<e/>, 1, 'a string'"));
        query.setMessageHandler(&silencer);
        QVERIFY(!query.evaluateTo(&out));
    }

    /* Evaluate the empty sequence. */
    {
        QXmlQuery query;
        QStringList out;

        query.setQuery(QLatin1String("()"));
        QVERIFY(!query.evaluateTo(&out));
        QVERIFY(out.isEmpty());
    }
}

void tst_QXmlQuery::evaluateToQStringList() const
{
    QFETCH(QString, queryString);
    QFETCH(QStringList, expectedOutput);

    QXmlQuery query;
    query.setQuery(queryString);
    QStringList out;
    QVERIFY(query.isValid());

    QVERIFY(query.evaluateTo(&out));

    QCOMPARE(out, expectedOutput);
}

void tst_QXmlQuery::evaluateToQStringListTriggerWarnings() const
{
    QXmlQuery query;

    QTest::ignoreMessage(QtWarningMsg, "A non-null callback must be passed.");
    QCOMPARE(query.evaluateTo(static_cast<QStringList *>(0)),
             false);
}

void tst_QXmlQuery::evaluateToQStringList_data() const
{
    QTest::addColumn<QString>("queryString");
    QTest::addColumn<QStringList>("expectedOutput");

    QTest::newRow("One atomic")
        << QString::fromLatin1("(1 + 1) cast as xs:string")
        << QStringList(QString::fromLatin1("2"));

    {
        QStringList expected;
        expected << QLatin1String("2");
        expected << QLatin1String("a string");

        QTest::newRow("Two atomics")
            << QString::fromLatin1("(1 + 1) cast as xs:string, 'a string'")
            << expected;
    }

    QTest::newRow("A query which evaluates to sub-types of xs:string.")
        << QString::fromLatin1("xs:NCName('NCName'), xs:normalizedString('  a b c   ')")
        << (QStringList() << QString::fromLatin1("NCName")
                          << QString::fromLatin1("  a b c   "));

    QTest::newRow("A query which evaluates to two elements.")
        << QString::fromLatin1("string(<e>theString1</e>), string(<e>theString2</e>)")
        << (QStringList() << QString::fromLatin1("theString1")
                          << QString::fromLatin1("theString2"));
}

/*!
  Ensure that we don't automatically convert non-xs:string values.
 */
void tst_QXmlQuery::evaluateToQStringListNoConversion() const
{
    QXmlQuery query;
    query.setQuery(QString::fromLatin1("<e/>"));
    QVERIFY(query.isValid());
    QStringList result;
    QVERIFY(!query.evaluateTo(&result));
}

void tst_QXmlQuery::evaluateToQIODevice() const
{
    /* an XQuery, check that no indentation is performed. */
    {
        QBuffer out;
        QVERIFY(out.open(QIODevice::ReadWrite));

        QXmlQuery query;
        query.setQuery(QLatin1String("<a><b/></a>"));
        QVERIFY(query.isValid());
        QVERIFY(query.evaluateTo(&out));
        QCOMPARE(out.data(), QByteArray("<a><b/></a>"));
    }
}

void tst_QXmlQuery::evaluateToQIODeviceTriggerWarnings() const
{
    QXmlQuery query;

    QTest::ignoreMessage(QtWarningMsg, "The pointer to the device cannot be null.");
    QCOMPARE(query.evaluateTo(static_cast<QIODevice *>(0)),
             false);

    QBuffer buffer;

    QTest::ignoreMessage(QtWarningMsg, "The device must be writable.");
    QCOMPARE(query.evaluateTo(&buffer),
             false);
}

void tst_QXmlQuery::evaluateToQIODeviceSignature() const
{
    /* The function should be const. */
    {
        QBuffer out;
        QVERIFY(out.open(QIODevice::ReadWrite));

        const QXmlQuery query;

        query.evaluateTo(&out);
    }
}

void tst_QXmlQuery::evaluateToQIODeviceOnInvalidQuery() const
{
    QBuffer out;
    QVERIFY(out.open(QIODevice::WriteOnly));

    /* On syntactically invalid query. */
    {
        QXmlQuery query;
        MessageSilencer silencer;
        query.setMessageHandler(&silencer);
        query.setQuery(QLatin1String("1 +"));
        QVERIFY(!query.isValid());
        QVERIFY(!query.evaluateTo(&out));
    }

    /* On null QXmlQuery instance. */
    {
        QXmlQuery query;
        QVERIFY(!query.evaluateTo(&out));
    }

}

void tst_QXmlQuery::setQueryQIODeviceQUrl() const
{
    /* Basic test. */
    {
        QBuffer buffer;
        buffer.setData("1, 2, 2 + 1");
        QVERIFY(buffer.open(QIODevice::ReadOnly));

        QXmlQuery query;
        query.setQuery(&buffer);
        QVERIFY(query.isValid());

        QXmlResultItems result;
        query.evaluateTo(&result);
        QCOMPARE(result.next().toAtomicValue(), QVariant(1));
        QCOMPARE(result.next().toAtomicValue(), QVariant(2));
        QCOMPARE(result.next().toAtomicValue(), QVariant(3));
        QVERIFY(result.next().isNull());
        QVERIFY(!result.hasError());
    }

    /* Set query that is invalid. */
    {
        QBuffer buffer;
        buffer.setData("1, ");
        QVERIFY(buffer.open(QIODevice::ReadOnly));

        QXmlQuery query;
        MessageSilencer silencer;
        query.setMessageHandler(&silencer);
        query.setQuery(&buffer);
        QVERIFY(!query.isValid());
    }

    /* Check that the base URI passes through. */
    {
        QBuffer buffer;
        buffer.setData("string(static-base-uri())");
        QVERIFY(buffer.open(QIODevice::ReadOnly));

        QXmlQuery query;
        query.setQuery(&buffer, QUrl::fromEncoded("http://www.example.com/QIODeviceQUrl"));
        QVERIFY(query.isValid());

        QStringList result;
        query.evaluateTo(&result);
        QCOMPARE(result, QStringList(QLatin1String("http://www.example.com/QIODeviceQUrl")));
    }
}

void tst_QXmlQuery::setQueryQIODeviceQUrlTriggerWarnings() const
{
    QXmlQuery query;
    QTest::ignoreMessage(QtWarningMsg, "A null QIODevice pointer cannot be passed.");
    query.setQuery(0);

    QBuffer buffer;
    QTest::ignoreMessage(QtWarningMsg, "The device must be readable.");
    query.setQuery(&buffer);
}

void tst_QXmlQuery::setQueryQString() const
{
    /* Basic test. */
    {
        QXmlQuery query;
        query.setQuery(QLatin1String("1, 2, 2 + 1"));
        QVERIFY(query.isValid());

        QXmlResultItems result;
        query.evaluateTo(&result);
        QCOMPARE(result.next().toAtomicValue(), QVariant(1));
        QCOMPARE(result.next().toAtomicValue(), QVariant(2));
        QCOMPARE(result.next().toAtomicValue(), QVariant(3));
        QVERIFY(result.next().isNull());
        QVERIFY(!result.hasError());
    }

    /* Set query that is invalid. */
    {
        MessageSilencer silencer;
        QXmlQuery query;
        query.setMessageHandler(&silencer);
        query.setQuery(QLatin1String("1, "));
        QVERIFY(!query.isValid());
    }

    /* Check that the base URI passes through. */
    {
        QXmlQuery query;
        query.setQuery(QLatin1String("string(static-base-uri())"), QUrl::fromEncoded("http://www.example.com/QIODeviceQUrl"));
        QVERIFY(query.isValid());

        QStringList result;
        query.evaluateTo(&result);
        QCOMPARE(result, QStringList(QLatin1String("http://www.example.com/QIODeviceQUrl")));
    }
}

void tst_QXmlQuery::setQueryQUrlSuccess() const
{
    if (QTest::currentDataTag() == QByteArray("A valid query via the ftp scheme")
            || QTest::currentDataTag() == QByteArray("A valid query via the http scheme"))
        QVERIFY(QtNetworkSettings::verifyTestNetworkSettings());

    QFETCH(QUrl, queryURI);
    QFETCH(QByteArray, expectedOutput);

    QVERIFY(queryURI.isValid());

    QXmlQuery query;

    MessageSilencer silencer;
    query.setMessageHandler(&silencer);

    query.setQuery(queryURI);
    QVERIFY(query.isValid());

    QByteArray out;
    QBuffer buffer(&out);
    QVERIFY(buffer.open(QIODevice::WriteOnly));
    QXmlSerializer serializer(query, &buffer);

    query.evaluateTo(&serializer);
    QCOMPARE(out, expectedOutput);
}

void tst_QXmlQuery::setQueryQUrlSuccess_data() const
{
    QTest::addColumn<QUrl>("queryURI");
    QTest::addColumn<QByteArray>("expectedOutput");

    QTest::newRow("A valid query via the data scheme")
        << QUrl::fromEncoded("data:application/xml,1%20%2B%201") /* "1 + 1" */
        << QByteArray("2");

    QTest::newRow("A valid query via the file scheme")
        << QUrl::fromLocalFile(inputFile(m_xmlPatternsDir + QLatin1String("/queries/") + QLatin1String("onePlusOne.xq")))
        << QByteArray("2");

    if(!m_testNetwork)
        return;

    QTest::newRow("A valid query via the ftp scheme")
        << QUrl::fromEncoded(QString("ftp://" + QtNetworkSettings::serverName() + "/pub/qxmlquery/viaFtp.xq").toLatin1())
        << QByteArray("This was received via FTP");

    QTest::newRow("A valid query via the http scheme")
        << QUrl::fromEncoded(QString("http://" + QtNetworkSettings::serverName() + "/qtest/qxmlquery/viaHttp.xq").toLatin1())
        << QByteArray("This was received via HTTP.");
}

void tst_QXmlQuery::setQueryQUrlFailSucceed() const
{
    QXmlQuery query;
    MessageSilencer silencer;

    query.setMessageHandler(&silencer);

    query.setQuery(QLatin1String("1 + 1"));
    QVERIFY(query.isValid());

    query.setQuery(QUrl::fromEncoded("file://example.com/does/not/exist"));
    QVERIFY(!query.isValid());
}

void tst_QXmlQuery::setQueryQUrlFailure() const
{
    if (QTest::currentDataTag() == QByteArray("A query via http:// that is completely empty, but readable.")
            || QTest::currentDataTag() == QByteArray("A query via ftp:// that is completely empty, but readable."))
        QVERIFY(QtNetworkSettings::verifyTestNetworkSettings());

    QFETCH(QUrl, queryURI);

    MessageSilencer silencer;

    QXmlQuery query;
    query.setMessageHandler(&silencer);
    query.setQuery(queryURI);
    QVERIFY(!query.isValid());
}

void tst_QXmlQuery::setQueryQUrlFailure_data() const
{
    const auto localFileUrl = [](const QString &relPath) {
        return QUrl::fromLocalFile(QCoreApplication::applicationFilePath()).resolved(QUrl(relPath));
    };
    QTest::addColumn<QUrl>("queryURI");

    QTest::newRow("Query via file:// that does not exist.")
        << QUrl::fromEncoded("file://example.com/does/not/exist");

    QTest::newRow("A query via file:// that is completely empty, but readable.")
        << localFileUrl(QStringLiteral("../xmlpatterns/queries/completelyEmptyQuery.xq"));

    {
        const QString name(QLatin1String("nonReadableFile.xq"));
        QFile outFile(name);
        QVERIFY(outFile.open(QIODevice::WriteOnly));
        outFile.write(QByteArray("1"));
        outFile.close();
        /* On some windows versions, this fails, so we don't check that this works with QVERIFY. */
        if (outFile.setPermissions(QFile::Permissions())) {
            QTest::newRow("Query via file:/ that does not have read permissions.")
                << localFileUrl(name);
        }
    }

    if(!m_testNetwork)
        return;

    QTest::newRow("Query via HTTP that does not exist.")
        << QUrl::fromEncoded("http://example.com/NoQuery/ISWear");

    /*
    QTest::newRow("Query via FTP that does not exist.")
        << QUrl::fromEncoded("ftp://example.com/NoQuery/ISWear");
        */

    QTest::newRow("A query via http:// that is completely empty, but readable.")
        << QUrl::fromEncoded(QString(
                "http://" + QtNetworkSettings::serverName() + "/qtest/qxmlquery/completelyEmptyQuery.xq").toLatin1());

    QTest::newRow("A query via ftp:// that is completely empty, but readable.")
        << QUrl::fromEncoded(QString(
                "ftp://" + QtNetworkSettings::serverName() + "/pub/qxmlquery/completelyEmptyQuery.xq").toLatin1());

}

void tst_QXmlQuery::setQueryQUrlBaseURI() const
{
    QFETCH(QUrl, inputBaseURI);
    QFETCH(QUrl, expectedBaseURI);

    QXmlQuery query;

    query.setQuery(QUrl(QLatin1String("qrc:/QXmlQueryTestData/queries/staticBaseURI.xq")), inputBaseURI);
    QVERIFY(query.isValid());

    QStringList result;
    QVERIFY(query.evaluateTo(&result));
    QCOMPARE(result.count(), 1);

    if(qstrcmp(QTest::currentDataTag(), "Relative base URI") == 0)
        checkBaseURI(QUrl(result.first()), QCoreApplication::applicationFilePath());
    else
        QCOMPARE(result.first(), expectedBaseURI.toString());
}

void tst_QXmlQuery::setQueryQUrlBaseURI_data() const
{
    QTest::addColumn<QUrl>("inputBaseURI");
    QTest::addColumn<QUrl>("expectedBaseURI");

    QTest::newRow("absolute HTTP")
        << QUrl(QLatin1String("http://www.example.com/"))
        << QUrl(QLatin1String("http://www.example.com/"));

    QTest::newRow("None, so the query URI is used")
        << QUrl()
        << QUrl(QLatin1String("qrc:/QXmlQueryTestData/queries/staticBaseURI.xq"));

    QTest::newRow("Relative base URI")
        << QUrl(QLatin1String("../data/relative.uri"))
        << QUrl();
}

/*!
  1. Create a valid query.
  2. Call setQuery(QUrl), with a query file that doesn't exist.
  3. Verify that the query has changed state into invalid.
 */
void tst_QXmlQuery::setQueryWithNonExistentQUrlOnValidQuery() const
{
    QXmlQuery query;

    MessageSilencer messageSilencer;
    query.setMessageHandler(&messageSilencer);

    query.setQuery(QLatin1String("1 + 1"));
    QVERIFY(query.isValid());

    query.setQuery(QUrl::fromEncoded("qrc:/QXmlQueryTestData/DOESNOTEXIST.xq"));
    QVERIFY(!query.isValid());
}

/*!
  1. Create a valid query.
  2. Call setQuery(QUrl), with a query file that is invalid.
  3. Verify that the query has changed state into invalid.
 */
void tst_QXmlQuery::setQueryWithInvalidQueryFromQUrlOnValidQuery() const
{
    QXmlQuery query;

    MessageSilencer messageSilencer;
    query.setMessageHandler(&messageSilencer);

    query.setQuery(QLatin1String("1 + 1"));
    QVERIFY(query.isValid());

    query.setQuery(QUrl::fromEncoded("qrc:/QXmlQueryTestData/queries/syntaxError.xq"));
    QVERIFY(!query.isValid());
}

/*!
  This triggered two bugs:

  - First, the DynamicContext wasn't assigned to QXmlResultItems, meaning it went out of
    scope and therefore deallocated the document pool, and calls
    to QXmlResultItems::next() would use dangling pointers.

  - Conversion between QPatternist::Item and QXmlItem was incorrectly done, leading to nodes
    being treated as atomic values, and subsequent crashes.

 */
void tst_QXmlQuery::retrieveNameFromQuery() const
{
    QFETCH(QString, queryString);
    QFETCH(QString, expectedName);

    QXmlQuery query;
    query.setQuery(queryString);
    QVERIFY(query.isValid());
    QXmlResultItems result;
    query.evaluateTo(&result);

    QVERIFY(!result.hasError());

    const QXmlItem item(result.next());
    QVERIFY(!result.hasError());
    QVERIFY(!item.isNull());
    QVERIFY(item.isNode());

    const QXmlNodeModelIndex node(item.toNodeModelIndex());
    QVERIFY(!node.isNull());

    QCOMPARE(node.model()->name(node).localName(query.namePool()), expectedName);
}

void tst_QXmlQuery::retrieveNameFromQuery_data() const
{
    QTest::addColumn<QString>("queryString");
    QTest::addColumn<QString>("expectedName");

    QTest::newRow("Document-node")
        << QString::fromLatin1("document{<elementName/>}")
        << QString();

    QTest::newRow("Element")
        << QString::fromLatin1("document{<elementName/>}/*")
        << QString::fromLatin1("elementName");
}

/*!
 Binding a null QString leads to no variable binding, but an
 empty non-null QString is possible.
 */
void tst_QXmlQuery::bindEmptyNullString() const
{
    MessageSilencer messageHandler;
    QXmlQuery query;
    query.setMessageHandler(&messageHandler);
    query.setQuery(QLatin1String("declare variable $v external; $v"));
    /* Here, we effectively pass an invalid QVariant. */
    query.bindVariable(QLatin1String("v"), QVariant(QString()));
    QVERIFY(!query.isValid());

    QStringList result;
    QVERIFY(!query.evaluateTo(&result));
}

void tst_QXmlQuery::bindEmptyString() const
{
    QXmlQuery query;
    query.bindVariable(QLatin1String("v"), QVariant(QString(QLatin1String(""))));
    query.setQuery(QLatin1String("declare variable $v external; $v"));
    QVERIFY(query.isValid());

    QStringList result;
    QVERIFY(query.evaluateTo(&result));
    QStringList expected((QString()));
    QCOMPARE(result, expected);
}

void tst_QXmlQuery::cleanupTestCase() const
{
    /* Remove a weird file we created. */
    const QString name(QLatin1String("nonReadableFile.xq"));

    if(QFile::exists(name))
    {
        QFile file(name);
        QVERIFY(file.setPermissions(QFile::WriteOwner));
        QVERIFY(file.remove());
    }
}

void tst_QXmlQuery::declareUnavailableExternal() const
{
    QXmlQuery query;
    MessageSilencer silencer;
    query.setMessageHandler(&silencer);
    query.setQuery(QLatin1String("declare variable $var external;"
                                 "1 + 1"));
    /* We do not bind $var with QXmlQuery::bindVariable(). */
    QVERIFY(!query.isValid());
}

/*!
 This test triggers an assert in one of the cache iterator
 with MSVC 2005 when compiled in debug mode.
 */
void tst_QXmlQuery::msvcCacheIssue() const
{
    QXmlQuery query;
    query.bindVariable(QLatin1String("externalVariable"), QXmlItem("Variable Value"));
    query.setQuery(QUrl::fromLocalFile(m_xmlPatternsDir + QLatin1String("/queries/") + QString::fromLatin1("externalVariableUsedTwice.xq")));
    QStringList result;
    QVERIFY(query.evaluateTo(&result));

    QCOMPARE(result,
             QStringList() << QString::fromLatin1("Variable Value") << QString::fromLatin1("Variable Value"));
}

void tst_QXmlQuery::unavailableExternalVariable() const
{
    QXmlQuery query;

    MessageSilencer silencer;
    query.setMessageHandler(&silencer);

    query.setQuery(QLatin1String("declare variable $foo external; 1"));

    QVERIFY(!query.isValid());
}

/*!
 Ensure that setUriResolver() affects \c fn:doc() and \c fn:doc-available().
 */
void tst_QXmlQuery::useUriResolver() const
{
    class TestUriResolver : public QAbstractUriResolver
                          , private TestFundament
    {
    public:
        TestUriResolver() {}
        virtual QUrl resolve(const QUrl &relative,
                             const QUrl &baseURI) const
        {
            Q_UNUSED(relative);
            QString fixedInputFile = inputFile(m_xmlPatternsDir + QLatin1String("/queries/") + QLatin1String("simpleDocument.xml"));
#ifdef Q_OS_WIN
            // A file path with drive letter is not a valid relative URI, so remove the drive letter.
            // Note that can't just use inputFileAsURI() instead of inputFile() as that doesn't
            // produce a relative URI either.
            if (fixedInputFile.size() > 1 && fixedInputFile.at(1) == QLatin1Char(':'))
                fixedInputFile.remove(0, 2);
#endif
            return baseURI.resolved(fixedInputFile);
        }
    };

    const TestUriResolver uriResolver;
    QXmlQuery query;

    query.setUriResolver(&uriResolver);
    query.setQuery(QLatin1String("let $i := 'http://www.example.com/DoesNotExist'"
                                 "return (string(doc($i)), doc-available($i))"));


    QXmlResultItems result;
    query.evaluateTo(&result);

    QVERIFY(!result.hasError());
    QCOMPARE(result.next().toAtomicValue().toString(), QString::fromLatin1("text text node"));
    QCOMPARE(result.next().toAtomicValue().toBool(), true);
    QVERIFY(result.next().isNull());
    QVERIFY(!result.hasError());
}

void tst_QXmlQuery::queryWithFocusAndVariable() const
{
    QXmlQuery query;
    query.setFocus(QXmlItem(5));
    query.bindVariable(QLatin1String("var"), QXmlItem(2));

    query.setQuery(QLatin1String("string(. * $var)"));

    QStringList result;

    QVERIFY(query.evaluateTo(&result));

    QCOMPARE(result, QStringList(QLatin1String("10")));
}

void tst_QXmlQuery::undefinedFocus() const
{
    QXmlQuery query;

    MessageSilencer silencer;
    query.setMessageHandler(&silencer);

    query.setQuery(QLatin1String("."));
    QVERIFY(!query.isValid());
}

void tst_QXmlQuery::basicFocusUsage() const
{
    QXmlQuery query;

    MessageSilencer silencer;
    query.setMessageHandler(&silencer);

    query.setFocus(QXmlItem(5));
    query.setQuery(QLatin1String("string(. * .)"));
    QVERIFY(query.isValid());

    QStringList result;
    QVERIFY(query.evaluateTo(&result));

    QCOMPARE(result, QStringList(QLatin1String("25")));
}

/*!
  Triggers an ownership related crash.
 */
void tst_QXmlQuery::copyCheckMessageHandler() const
{
    QXmlQuery query;
    QCOMPARE(query.messageHandler(), static_cast<QAbstractMessageHandler *>(0));

    query.setQuery(QLatin1String("doc('qrc:/QXmlQueryTestData/data/oneElement.xml')"));
    /* By now, we should have set the builtin message handler. */
    const QAbstractMessageHandler *const messageHandler = query.messageHandler();
    QVERIFY(messageHandler);

    {
        /* This copies QXmlQueryPrivate::m_ownerObject, and its destructor
         * will delete it, and hence the builtin message handler attached to it. */
        QXmlQuery copy(query);
    }

    QXmlResultItems result;
    query.evaluateTo(&result);

    while(!result.next().isNull())
    {
    }
    QVERIFY(!result.hasError());
}

void tst_QXmlQuery::queryLanguage() const
{
    /* Check default value. */
    {
        const QXmlQuery query;
        QCOMPARE(query.queryLanguage(), QXmlQuery::XQuery10);
    }

    /* Check default value of copies default instance. */
    {
        const QXmlQuery query1;
        const QXmlQuery query2(query1);

        QCOMPARE(query1.queryLanguage(), QXmlQuery::XQuery10);
        QCOMPARE(query2.queryLanguage(), QXmlQuery::XQuery10);
    }
}

void tst_QXmlQuery::queryLanguageSignature() const
{
    /* This getter should be const. */
    QXmlQuery query;
    query.queryLanguage();
}

void tst_QXmlQuery::enumQueryLanguage() const
{
    /* These enum values should be possible to OR for future plans. */
    QCOMPARE(int(QXmlQuery::XQuery10), 1);
    QCOMPARE(int(QXmlQuery::XSLT20), 2);
    QCOMPARE(int(QXmlQuery::XmlSchema11IdentityConstraintSelector), 1024);
    QCOMPARE(int(QXmlQuery::XmlSchema11IdentityConstraintField), 2048);
    QCOMPARE(int(QXmlQuery::XPath20), 4096);
}

void tst_QXmlQuery::setInitialTemplateNameQXmlName() const
{
    QXmlQuery query(QXmlQuery::XSLT20);
    QXmlNamePool np(query.namePool());
    const QXmlName name(np, QLatin1String("main"));

    query.setInitialTemplateName(name);

    QCOMPARE(query.initialTemplateName(), name);

    query.setQuery(QUrl(inputFileAsURI(m_xmlPatternsDir + QLatin1String("/stylesheets/namedTemplate.xsl"))));
    QVERIFY(query.isValid());

    QBuffer result;
    QVERIFY(result.open(QIODevice::ReadWrite));
    QXmlSerializer serializer(query, &result);
    query.evaluateTo(&serializer);

    QCOMPARE(result.data(), QByteArray("1 2 3 4 5"));

    // TODO invoke a template which has required params.
}

void tst_QXmlQuery::setInitialTemplateNameQXmlNameSignature() const
{
    QXmlQuery query;
    QXmlNamePool np(query.namePool());
    const QXmlName name(np, QLatin1String("foo"));

    /* The signature should take a const reference. */
    query.setInitialTemplateName(name);
}

void tst_QXmlQuery::setInitialTemplateNameQString() const
{
    QXmlQuery query;
    QXmlNamePool np(query.namePool());
    query.setInitialTemplateName(QLatin1String("foo"));

    QCOMPARE(query.initialTemplateName(), QXmlName(np, QLatin1String("foo")));
}

void tst_QXmlQuery::setInitialTemplateNameQStringSignature() const
{
    const QString name(QLatin1String("name"));
    QXmlQuery query;

    /* We should take a const reference. */
    query.setInitialTemplateName(name);
}

void tst_QXmlQuery::initialTemplateName() const
{
    /* Check our default value. */
    QXmlQuery query;
    QCOMPARE(query.initialTemplateName(), QXmlName());
    QVERIFY(query.initialTemplateName().isNull());
}

void tst_QXmlQuery::initialTemplateNameSignature() const
{
    const QXmlQuery query;
    /* This should be a const member. */
    query.initialTemplateName();
}

void tst_QXmlQuery::setNetworkAccessManager() const
{

    /* Ensure fn:doc() picks up the right QNetworkAccessManager. */
    {
        NetworkOverrider networkOverrider(QUrl(QLatin1String("tag:example.com:DOESNOTEXIST")),
                                          QUrl(inputFileAsURI(m_xmlPatternsDir + QLatin1String("/queries/simpleDocument.xml"))));
        QVERIFY(networkOverrider.isValid());

        QXmlQuery query;
        query.setNetworkAccessManager(&networkOverrider);
        query.setQuery(QLatin1String("string(doc('tag:example.com:DOESNOTEXIST'))"));
        QVERIFY(query.isValid());

        QStringList result;
        QVERIFY(query.evaluateTo(&result));

        QCOMPARE(result, QStringList(QLatin1String("text text node")));
    }

    /* Ensure setQuery() is using the right network manager. */
    {
        NetworkOverrider networkOverrider(QUrl(QLatin1String("tag:example.com:DOESNOTEXIST")),
                                          QUrl(inputFileAsURI(m_xmlPatternsDir + QLatin1String("/queries/concat.xq"))));
        QVERIFY(networkOverrider.isValid());

        QXmlQuery query;
        query.setNetworkAccessManager(&networkOverrider);
        query.setQuery(QUrl("tag:example.com:DOESNOTEXIST"));
        QVERIFY(query.isValid());

        QStringList result;
        QVERIFY(query.evaluateTo(&result));

        QCOMPARE(result, QStringList(QLatin1String("abcdef")));
    }
}
void tst_QXmlQuery::networkAccessManagerSignature() const
{
    /* Const object. */
    const QXmlQuery query;

    /* The function should be const. */
    query.networkAccessManager();
}

void tst_QXmlQuery::networkAccessManagerDefaultValue() const
{
    const QXmlQuery query;

    QCOMPARE(query.networkAccessManager(), static_cast<QNetworkAccessManager *>(0));
}

void tst_QXmlQuery::networkAccessManager() const
{
    /* Test that we return the network manager that was set. */
    {
        QNetworkAccessManager manager;
        QXmlQuery query;
        query.setNetworkAccessManager(&manager);
        QCOMPARE(query.networkAccessManager(), &manager);
    }
}

/*!
 \internal
 \since 4.5

  1. Load a document into QXmlQuery's document cache, by executing a query which does it.
  2. Set a focus
  3. Change query, to one which uses the focus
  4. Evaluate

 Used to crash.
 */
void tst_QXmlQuery::multipleDocsAndFocus() const
{
    QXmlQuery query;

    /* We use string concatenation, since variable bindings might disturb what
     * we're testing. */
    query.setQuery(QLatin1String("string(doc('") +
                   inputFile(m_xmlPatternsDir + QLatin1String("/queries/simpleDocument.xml")) +
                   QLatin1String("'))"));
    query.setFocus(QUrl(inputFileAsURI(m_xmlPatternsDir + QLatin1String("/stylesheets/documentElement.xml"))));
    query.setQuery(QLatin1String("string(.)"));

    QStringList result;
    QVERIFY(query.evaluateTo(&result));
}

/*!
 \internal
 \since 4.5

 1. Set a focus
 2. Set a query
 3. Evaluate
 4. Change focus
 5. Evaluate

 Used to crash.
 */
void tst_QXmlQuery::multipleEvaluationsWithDifferentFocus() const
{
    QXmlQuery query;
    QStringList result;

    query.setFocus(QUrl(inputFileAsURI(m_xmlPatternsDir + QLatin1String("/stylesheets/documentElement.xml"))));
    query.setQuery(QLatin1String("string(.)"));
    QVERIFY(query.evaluateTo(&result));

    query.setFocus(QUrl(inputFileAsURI(m_xmlPatternsDir + QLatin1String("/stylesheets/documentElement.xml"))));
    QVERIFY(query.evaluateTo(&result));
}

void tst_QXmlQuery::bindVariableQXmlQuery() const
{
    QFETCH(QString, query1);
    QFETCH(QString, query2);
    QFETCH(QString, expectedOutput);
    QFETCH(bool, expectedSuccess);

    MessageSilencer silencer;
    QXmlQuery xmlQuery1;
    xmlQuery1.setMessageHandler(&silencer);
    xmlQuery1.setQuery(query1);

    QXmlQuery xmlQuery2(xmlQuery1);
    xmlQuery2.bindVariable("query1", xmlQuery1);
    xmlQuery2.setQuery(query2);

    QString output;
    const bool querySuccess = xmlQuery2.evaluateTo(&output);

    QCOMPARE(querySuccess, expectedSuccess);

    if(querySuccess)
        QCOMPARE(output, expectedOutput);
}

void tst_QXmlQuery::bindVariableQXmlQuery_data() const
{
    QTest::addColumn<QString>("query1");
    QTest::addColumn<QString>("query2");
    QTest::addColumn<QString>("expectedOutput");
    QTest::addColumn<bool>("expectedSuccess");

    QTest::newRow("First query has one atomic value.")
            << "2"
            << "1, $query1, 3"
            << "1 2 3\n"
            << true;

    QTest::newRow("First query has two atomic values.")
            << "2, 3"
            << "1, $query1, 4"
            << "1 2 3 4\n"
            << true;

    QTest::newRow("First query is a node.")
            << "<e/>"
            << "1, $query1, 3"
            << "1<e/>3\n"
            << true;

    /* This is a good test, because it triggers the exception in the
     * bindVariable() call, as supposed to when the actual evaluation is done.
     */
    QTest::newRow("First query has a dynamic error.")
            << "error()"
            << "1, $query1"
            << QString() /* We don't care. */
            << false;
}

void tst_QXmlQuery::bindVariableQStringQXmlQuerySignature() const
{
    QXmlQuery query1;
    query1.setQuery("'dummy'");

    QXmlQuery query2;
    const QString name(QLatin1String("name"));

    /* We should be able to take a const QXmlQuery reference. Evaluation never mutate
     * QXmlQuery, and evaluation is what we do here. */
    query2.bindVariable(name, const_cast<const QXmlQuery &>(query1));
}

void tst_QXmlQuery::bindVariableQXmlNameQXmlQuerySignature() const
{
    QXmlNamePool np;
    QXmlQuery query1(np);
    query1.setQuery("'dummy'");

    QXmlQuery query2;
    const QXmlName name(np, QLatin1String("name"));

    /* We should be able to take a const QXmlQuery reference. Evaluation never mutate
     * QXmlQuery, and evaluation is what we do here. */
    query2.bindVariable(name, const_cast<const QXmlQuery &>(query1));
}

/*!
  Check that the QXmlName is handled correctly.
 */
void tst_QXmlQuery::bindVariableQXmlNameQXmlQuery() const
{
    QXmlNamePool np;
    QXmlQuery query1;
    query1.setQuery(QLatin1String("1"));

    QXmlQuery query2(np);
    query2.bindVariable(QXmlName(np, QLatin1String("theName")), query1);
    query2.setQuery("$theName");

    QString result;
    query2.evaluateTo(&result);

    QCOMPARE(result, QString::fromLatin1("1\n"));
}

void tst_QXmlQuery::bindVariableQXmlQueryInvalidate() const
{
    QXmlQuery query;
    query.bindVariable(QLatin1String("name"), QVariant(1));
    query.setQuery("$name");
    QVERIFY(query.isValid());

    QXmlQuery query2;
    query2.setQuery("'query2'");

    query.bindVariable(QLatin1String("name"), query2);
    QVERIFY(!query.isValid());
}

void tst_QXmlQuery::unknownSourceLocation() const
{
    QBuffer b;
    b.setData("<a><b/><b/></a>");
    b.open(QIODevice::ReadOnly);

    MessageSilencer silencer;
    QXmlQuery query;
    query.bindVariable(QLatin1String("inputDocument"), &b);
    query.setMessageHandler(&silencer);

    query.setQuery(QLatin1String("doc($inputDocument)/a/(let $v := b/string() return if ($v) then $v else ())"));

    QString output;
    query.evaluateTo(&output);
}

void tst_QXmlQuery::identityConstraintSuccess() const
{
    QXmlQuery::QueryLanguage queryLanguage = QXmlQuery::XmlSchema11IdentityConstraintSelector;

    /* We run this code for Selector and Field. */
    for(int i = 0; i < 3; ++i)
    {
        QXmlNamePool namePool;
        QXmlResultItems result;
        QXmlItem node;

        {
            QXmlQuery nodeSource(namePool);
            nodeSource.setQuery(QLatin1String("<e/>"));

            nodeSource.evaluateTo(&result);
            node = result.next();
        }

        /* Basic use:
         * 1. The focus is undefined, but it's still valid.
         * 2. We never evaluate. */
        {
            QXmlQuery query(queryLanguage);
            query.setQuery(QLatin1String("a"));
            QVERIFY(query.isValid());
        }

        /* Basic use:
         * 1. The focus is undefined, but it's still valid.
         * 2. We afterwards set the focus. */
        {
            QXmlQuery query(queryLanguage, namePool);
            query.setQuery(QLatin1String("a"));
            query.setFocus(node);
            QVERIFY(query.isValid());
        }

        /* Basic use:
         * 1. The focus is undefined, but it's still valid.
         * 2. We afterwards set the focus.
         * 3. We evaluate. */
        {
            QXmlQuery query(queryLanguage, namePool);
            query.setQuery(QString(QLatin1Char('.')));
            query.setFocus(node);
            QVERIFY(query.isValid());

            QString result;
            QVERIFY(query.evaluateTo(&result));
            QCOMPARE(result, QString::fromLatin1("<e/>\n"));
        }

        /* A slightly more complex Field. */
        {
            QXmlQuery query(queryLanguage);
            query.setQuery(QLatin1String("* | .//xml:*/."));
            QVERIFY(query.isValid());
        }

        /* @ is only allowed in Field. */
        if(queryLanguage == QXmlQuery::XmlSchema11IdentityConstraintField)
        {
            QXmlQuery query(QXmlQuery::XmlSchema11IdentityConstraintField);
            query.setQuery(QLatin1String("@abc"));
            QVERIFY(query.isValid());
        }

        /* Field allows attribute:: and child:: .*/
        if(queryLanguage == QXmlQuery::XmlSchema11IdentityConstraintField)
        {
            QXmlQuery query(QXmlQuery::XmlSchema11IdentityConstraintField);
            query.setQuery(QLatin1String("attribute::name | child::name"));
            QVERIFY(query.isValid());
        }

        /* Selector allows only child:: .*/
        {
            QXmlQuery query(QXmlQuery::XmlSchema11IdentityConstraintSelector);
            query.setQuery(QLatin1String("child::name"));
            QVERIFY(query.isValid());
        }

        if(i == 0)
            queryLanguage = QXmlQuery::XmlSchema11IdentityConstraintField;
        else if(i == 1)
            queryLanguage = QXmlQuery::XPath20;
    }
}

Q_DECLARE_METATYPE(QXmlQuery::QueryLanguage);

/*!
 We just do some basic tests for boot strapping and sanity checking. The actual regression
 testing is in the Schema suite.
 */
void tst_QXmlQuery::identityConstraintFailure() const
{
    QFETCH(QXmlQuery::QueryLanguage, queryLanguage);
    QFETCH(QString, inputQuery);

    QXmlQuery query(queryLanguage);
    MessageSilencer silencer;
    query.setMessageHandler(&silencer);

    query.setQuery(inputQuery);
    QVERIFY(!query.isValid());
}

void tst_QXmlQuery::identityConstraintFailure_data() const
{
    QTest::addColumn<QXmlQuery::QueryLanguage>("queryLanguage");
    QTest::addColumn<QString>("inputQuery");

    QTest::newRow("We don't have element constructors in identity constraint pattern, "
                  "it's an XQuery feature(Selector).")
        << QXmlQuery::XmlSchema11IdentityConstraintSelector
        << QString::fromLatin1("<e/>");

    QTest::newRow("We don't have functions in identity constraint pattern, "
                  "it's an XPath feature(Selector).")
        << QXmlQuery::XmlSchema11IdentityConstraintSelector
        << QString::fromLatin1("current-time()");

    QTest::newRow("We don't have element constructors in identity constraint pattern, "
                  "it's an XQuery feature(Field).")
        << QXmlQuery::XmlSchema11IdentityConstraintSelector
        << QString::fromLatin1("<e/>");

    QTest::newRow("We don't have functions in identity constraint pattern, "
                  "it's an XPath feature(Field).")
        << QXmlQuery::XmlSchema11IdentityConstraintSelector
        << QString::fromLatin1("current-time()");

    QTest::newRow("@attributeName is disallowed for the selector.")
        << QXmlQuery::XmlSchema11IdentityConstraintSelector
        << QString::fromLatin1("@abc");

    QTest::newRow("attribute:: is disallowed for the selector.")
        << QXmlQuery::XmlSchema11IdentityConstraintSelector
        << QString::fromLatin1("attribute::name");

    QTest::newRow("ancestor::name is disallowed for the selector.")
        << QXmlQuery::XmlSchema11IdentityConstraintSelector
        << QString::fromLatin1("ancestor::name");

    QTest::newRow("ancestor::name is disallowed for the field.")
        << QXmlQuery::XmlSchema11IdentityConstraintField
        << QString::fromLatin1("ancestor::name");
}

QTEST_MAIN(tst_QXmlQuery)

#include "tst_qxmlquery.moc"
