| /**************************************************************************** | 
 | ** | 
 | ** 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 <QtDebug> | 
 |  | 
 | #include <private/qacceltreeresourceloader_p.h> | 
 | #include <private/qnetworkaccessdelegator_p.h> | 
 |  | 
 | #include "Global.h" | 
 | #include "TestBaseLine.h" | 
 | #include "TestGroup.h" | 
 |  | 
 | #include "XSLTTestSuiteHandler.h" | 
 |  | 
 | using namespace QPatternistSDK; | 
 |  | 
 | static QNetworkAccessManager *s_networkAccessManager = 0; | 
 |  | 
 | static void cleanupNetworkAccessManager() | 
 | { | 
 |     delete s_networkAccessManager; | 
 |     s_networkAccessManager = 0; | 
 |  | 
 | } | 
 | static QNetworkAccessManager *networkAccessManager() | 
 | { | 
 |     if (!s_networkAccessManager) { | 
 |         s_networkAccessManager = new QNetworkAccessManager; | 
 |         qAddPostRoutine(cleanupNetworkAccessManager); | 
 |     } | 
 |     return s_networkAccessManager; | 
 | } | 
 |  | 
 | XSLTTestSuiteHandler::XSLTTestSuiteHandler(const QUrl &catalogFile) : m_ts(0) | 
 |                                                                     , m_tc(0) | 
 |                                                                     , m_baseLine(0) | 
 |                                                                     , m_catalogFile(catalogFile) | 
 |                                                                     , m_removeTestcase(false) | 
 | { | 
 |     const QPatternist::NetworkAccessDelegator::Ptr networkDelegator(new QPatternist::NetworkAccessDelegator(networkAccessManager(), networkAccessManager())); | 
 |  | 
 |     m_resourceLoader = QPatternist::ResourceLoader::Ptr(new QPatternist::AccelTreeResourceLoader(Global::namePool(), | 
 |                                                                                                  networkDelegator)); | 
 |     Q_ASSERT(!m_catalogFile.isRelative()); | 
 | } | 
 |  | 
 | bool XSLTTestSuiteHandler::startElement(const QStringRef &namespaceURI, const QStringRef &localName, | 
 |                                         const QStringRef & /*qName*/, const QXmlStreamAttributes &atts) | 
 | { | 
 |     if(namespaceURI != Global::xsltsCatalogNS) | 
 |         return true; | 
 |  | 
 |     /* The elements are handled roughly in the order of highest occurrence in the catalog file. */ | 
 |     if(localName == QLatin1String("testcase")) | 
 |     { | 
 |         /* We pass m_ts temporarily, and change it later. */ | 
 |         m_tc = new XQTSTestCase(TestCase::Standard, 0, QXmlQuery::XSLT20); | 
 |  | 
 |         m_currentQueryPath = | 
 |                 m_queryOffset.resolved(QUrl(atts.value(QLatin1String("FilePath")).toString())); | 
 |         m_currentBaselinePath = | 
 |                 m_baselineOffset.resolved(QUrl(atts.value(QLatin1String("FilePath")).toString())); | 
 |     } | 
 |     else if(localName == QLatin1String("stylesheet")) | 
 |         m_tc->setQueryPath( | 
 |                 m_currentQueryPath.resolved(atts.value(QLatin1String("file")).toString())); | 
 |     else if(localName == QLatin1String("error")) | 
 |     { | 
 |         m_baseLine = new TestBaseLine(TestBaseLine::ExpectedError); | 
 |         m_baseLine->setDetails(atts.value(QLatin1String("error-id")).toString()); | 
 |         m_tc->addBaseLine(m_baseLine); | 
 |     } | 
 |     else if(localName == QLatin1String("testcases")) | 
 |     { | 
 |         m_ts = new TestSuite(); | 
 |         m_ts->setVersion(atts.value(QLatin1String("testSuiteVersion")).toString()); | 
 |  | 
 |         m_queryOffset = | 
 |                 m_catalogFile.resolved(atts.value(QLatin1String("InputOffsetPath")).toString()); | 
 |         m_baselineOffset = | 
 |                 m_catalogFile.resolved(atts.value(QLatin1String("ResultOffsetPath")).toString()); | 
 |         m_sourceOffset = | 
 |                 m_catalogFile.resolved(atts.value(QLatin1String("InputOffsetPath")).toString()); | 
 |     } | 
 |     else if(localName == QLatin1String("source-document")) | 
 |     { | 
 |         if(atts.value(QLatin1String("role")) == QLatin1String("principal")) | 
 |             m_tc->setContextItemSource( | 
 |                     m_sourceOffset.resolved(QUrl(atts.value(QLatin1String("file")).toString()))); | 
 |     } | 
 |     else if(localName == QLatin1String("result-document")) | 
 |     { | 
 |         m_baseLine = new TestBaseLine( | 
 |                 TestBaseLine::identifierFromString(atts.value(QLatin1String("type")).toString())); | 
 |         m_baseLine->setDetails( | 
 |                 m_currentBaselinePath.resolved(atts.value(QLatin1String("file")).toString()) | 
 |                         .toString()); | 
 |         m_tc->addBaseLine(m_baseLine); | 
 |     } | 
 |     else if(localName == QLatin1String("discretionary-feature")) | 
 |     { | 
 |         const QString feature(atts.value(QLatin1String("name")).toString()); | 
 |  | 
 |         m_removeTestcase = feature == QLatin1String("schema_aware") || | 
 |                            feature == QLatin1String("namespace_axis") || | 
 |                            feature == QLatin1String("disabling_output_escaping") || | 
 |                            feature == QLatin1String("XML_1.1"); | 
 |     } | 
 |     else if(localName == QLatin1String("discretionary-choice")) | 
 |     { | 
 |         m_baseLine = new TestBaseLine(TestBaseLine::ExpectedError); | 
 |         m_baseLine->setDetails(atts.value(QLatin1String("name")).toString()); | 
 |         m_tc->addBaseLine(m_baseLine); | 
 |         const QString feature(atts.value(QLatin1String("name")).toString()); | 
 |  | 
 |         m_removeTestcase = feature == QLatin1String("schema_aware") || | 
 |                            feature == QLatin1String("namespace_axis") || | 
 |                            feature == QLatin1String("disabling_output_escaping") || | 
 |                            feature == QLatin1String("XML_1.1"); | 
 |     } | 
 |     else if(localName == QLatin1String("entry-named-template")) | 
 |     { | 
 |         const QString name(atts.value(QLatin1String("qname")).toString()); | 
 |  | 
 |         if(!name.contains(QLatin1Char(':'))) | 
 |         { | 
 |             // TODO do namespace processing | 
 |             const QXmlName complete(Global::namePool()->allocateQName(QString(), name)); | 
 |  | 
 |             m_tc->setInitialTemplateName(complete); | 
 |         } | 
 |     } | 
 |  | 
 |     return true; | 
 | } | 
 |  | 
 | TestGroup *XSLTTestSuiteHandler::containerFor(const QString &name) | 
 | { | 
 |     TestGroup *& c = m_containers[name]; | 
 |  | 
 |     if(!c) | 
 |     { | 
 |         c = new TestGroup(m_ts); | 
 |         c->setTitle(name); | 
 |         Q_ASSERT(c); | 
 |         m_ts->appendChild(c); | 
 |     } | 
 |  | 
 |     return c; | 
 | } | 
 |  | 
 | bool XSLTTestSuiteHandler::endElement(const QStringRef &namespaceURI, | 
 |                                       const QStringRef &localName, | 
 |                                       const QStringRef &/*qName*/) | 
 | { | 
 |     if(namespaceURI != Global::xsltsCatalogNS) | 
 |         return true; | 
 |  | 
 |     /* The elements are handled roughly in the order of highest occurrence in the catalog file. */ | 
 |     if(localName == QLatin1String("description")) | 
 |     { | 
 |         if(m_tc) | 
 |         { | 
 |             /* We're inside a <testcase>, so the <description> belongs | 
 |              * to the testcase. */ | 
 |             m_tc->setDescription(m_ch.simplified()); | 
 |         } | 
 |     } | 
 |     else if(localName == QLatin1String("testcase")) | 
 |     { | 
 |         Q_ASSERT(m_tc->baseLines().count() >= 1); | 
 |         Q_ASSERT(m_resourceLoader); | 
 |         // TODO can this be removed? | 
 |         m_tc->setExternalVariableLoader(QPatternist::ExternalVariableLoader::Ptr | 
 |                                                 (new ExternalSourceLoader(m_tcSourceInputs, | 
 |                                                                           m_resourceLoader))); | 
 |         m_tcSourceInputs.clear(); | 
 |  | 
 |         if(!m_removeTestcase) | 
 |         { | 
 |             /* | 
 |             TestContainer *const container = containerFor(m_currentCategory); | 
 |             delete m_tc; | 
 |             container->removeLast(); | 
 |             */ | 
 |             TestContainer *const container = containerFor(m_currentCategory); | 
 |             m_tc->setParent(container); | 
 |             Q_ASSERT(m_tc); | 
 |             container->appendChild(m_tc); | 
 |         } | 
 |  | 
 |         m_tc = 0; | 
 |         m_removeTestcase = false; | 
 |     } | 
 |     else if(localName == QLatin1String("name")) | 
 |         m_tc->setName(m_ch); | 
 |     else if(localName == QLatin1String("creator")) | 
 |         m_tc->setCreator(m_ch); | 
 |     else if(localName == QLatin1String("contextItem")) | 
 |         m_contextItemSource = m_ch; | 
 |     else if(localName == QLatin1String("category")) | 
 |         m_currentCategory = m_ch; | 
 |  | 
 |     return true; | 
 | } | 
 |  | 
 | bool XSLTTestSuiteHandler::characters(const QStringRef &ch) | 
 | { | 
 |     m_ch = ch.toString(); | 
 |     return true; | 
 | } | 
 |  | 
 | TestSuite *XSLTTestSuiteHandler::testSuite() const | 
 | { | 
 |     return m_ts; | 
 | } | 
 |  | 
 | // vim: et:ts=4:sw=4:sts=4 | 
 |  |