diff options
author | Rohan McGovern <rohan.mcgovern@nokia.com> | 2010-02-16 05:34:50 (GMT) |
---|---|---|
committer | Rohan McGovern <rohan.mcgovern@nokia.com> | 2010-02-17 06:12:08 (GMT) |
commit | 2d67f6efc47986e8f6d69943f0986d18ae2ced96 (patch) | |
tree | 42b8e16e73c021ffabba0b82b12f0f533ce8aa11 /tests/auto/xmlpatternssdk | |
parent | 0cdf33e9acb00b8f3654e8268253a3fb7c5db92c (diff) | |
download | Qt-2d67f6efc47986e8f6d69943f0986d18ae2ced96.zip Qt-2d67f6efc47986e8f6d69943f0986d18ae2ced96.tar.gz Qt-2d67f6efc47986e8f6d69943f0986d18ae2ced96.tar.bz2 |
Fixed compile of xmlpatterns tests with vcproj generator.
These tests were adding the same SUBDIR multiple times from different
projects. Don't do that.
Diffstat (limited to 'tests/auto/xmlpatternssdk')
61 files changed, 11293 insertions, 0 deletions
diff --git a/tests/auto/xmlpatternssdk/ASTItem.cpp b/tests/auto/xmlpatternssdk/ASTItem.cpp new file mode 100644 index 0000000..3b4fbdc --- /dev/null +++ b/tests/auto/xmlpatternssdk/ASTItem.cpp @@ -0,0 +1,161 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QList> +#include <QPointer> +#include <QVariant> + +#include "ASTItem.h" + +using namespace QPatternistSDK; + +/** + * This is what the AST rendering is indented with. + */ +static const QLatin1String astIndent(" "); +// STATIC DATA + +ASTItem::ASTItem(ASTItem *p, + const QString &name, + const QString &details, + const QString &staticType, + const QString &reqType) : m_name(name), + m_details(details), + m_reqType(reqType), + m_staticType(staticType), + m_parent(p) +{ +} + +ASTItem::~ASTItem() +{ + qDeleteAll(m_children); +} + +QString ASTItem::toString() const +{ + /* The first ASTItem* is a virtual root node, so skip "this". */ + Q_ASSERT(m_children.count() == 1); + TreeItem *treeChild = m_children.first(); + Q_ASSERT(treeChild); + + ASTItem *astChild = static_cast<ASTItem *>(treeChild); + + return astChild->toString(QString()); +} + +QString ASTItem::toString(const QString &indent) const +{ + QString retval; + + retval += indent; + retval += m_name; + retval += QLatin1Char('('); + retval += m_details; + retval += QLatin1String(")\n"); + + const TreeItem::List::const_iterator end(m_children.constEnd()); + + for(TreeItem::List::const_iterator it(m_children.constBegin()); it != end; ++it) + { + TreeItem *treeChild = *it; /* Cast away the QPointer with its casting operator. */ + ASTItem *astChild = static_cast<ASTItem *>(treeChild); + + retval += astChild->toString(indent + astIndent); + } + + return retval; +} + +QVariant ASTItem::data(const Qt::ItemDataRole role, int column) const +{ + if(role != Qt::DisplayRole) + return QVariant(); + + switch(column) + { + case 0: + return m_name; + case 1: + return m_details; + case 2: + return m_staticType; + case 3: + return m_reqType; + default: + { + Q_ASSERT(false); + return QVariant(); + } + } +} + +int ASTItem::columnCount() const +{ + return 4; +} + +TreeItem::List ASTItem::children() const +{ + return m_children; +} + +void ASTItem::appendChild(TreeItem *item) +{ + m_children.append(item); +} + +TreeItem *ASTItem::child(const unsigned int rowP) const +{ + return m_children.value(rowP); +} + +unsigned int ASTItem::childCount() const +{ + return m_children.count(); +} + +TreeItem *ASTItem::parent() const +{ + return m_parent; +} + +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/ASTItem.h b/tests/auto/xmlpatternssdk/ASTItem.h new file mode 100644 index 0000000..ca3ac8f --- /dev/null +++ b/tests/auto/xmlpatternssdk/ASTItem.h @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PatternistSDK_ASTItem_H +#define PatternistSDK_ASTItem_H + +#include <QList> +#include <QString> + +#include "TreeItem.h" +#include "Global.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternistSDK +{ + /** + * @short Is a node in a ASTItem tree; each ASTItem contains + * debug information about an QPatternist::Expression. + * + * ASTItem, by implementing TreeItem, leverages debug data about QPatternist::Expression + * instances into Qt's model/view framework. + * + * @ingroup PatternistSDK + * @author Frans Englich <frans.englich@nokia.com> + */ + class Q_PATTERNISTSDK_EXPORT ASTItem : public TreeItem + { + public: + virtual ~ASTItem(); + ASTItem(ASTItem *parent, + const QString &name, + const QString &details = QString(), + const QString &staticType = QString(), + const QString &reqType = QString()); + + virtual void appendChild(TreeItem *item); + virtual TreeItem *child(const unsigned int row) const; + virtual unsigned int childCount() const; + virtual QVariant data(const Qt::ItemDataRole role, int column) const; + virtual TreeItem::List children() const; + virtual TreeItem *parent() const; + int columnCount() const; + + /** + * Returns a string representation of this AST node, recursively including + * children. For example, the query <tt>1 eq number()</tt> would result in the string: + * +@verbatim +ValueComparison(eq) + xs:integer(0) + FunctionCall(fn:number) + ContextItem +@endverbatim + */ + QString toString() const; + + private: + QString toString(const QString &indent) const; + + const QString m_name; + const QString m_details; + const QString m_reqType; + const QString m_staticType; + TreeItem::List m_children; + TreeItem *m_parent; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/DebugExpressionFactory.cpp b/tests/auto/xmlpatternssdk/DebugExpressionFactory.cpp new file mode 100644 index 0000000..1b5121e --- /dev/null +++ b/tests/auto/xmlpatternssdk/DebugExpressionFactory.cpp @@ -0,0 +1,264 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QStringList> +#include <QVariant> +#include <QtDebug> +#include <QXmlNamePool> + +#include "qfunctionfactorycollection_p.h" + +#include "ASTItem.h" +#include "ExpressionInfo.h" +#include "ExpressionNamer.h" +#include "Global.h" + +#include "DebugExpressionFactory.h" + +using namespace QPatternistSDK; +using namespace QPatternist; + +static const QPatternist::ExpressionVisitor::Ptr namer(new ExpressionNamer()); + +QStringList DebugExpressionFactory::availableFunctionSignatures() +{ + const QPatternist::FunctionFactory::Ptr factory(QPatternist::FunctionFactoryCollection::xpath20Factory(Global::namePool())); + const QPatternist::FunctionSignature::Hash signs(factory->functionSignatures()); + const QPatternist::FunctionSignature::Hash::const_iterator end(signs.constEnd()); + QPatternist::FunctionSignature::Hash::const_iterator it(signs.constBegin()); + QStringList retval; + + while(it != end) + { + retval << it.value()->displayName(Global::namePool()); + ++it; + } + + return retval; +} + +ASTItem *DebugExpressionFactory::buildASTTree(const QPatternist::Expression::Ptr &expr, + ASTItem *parent, + const QPatternist::SequenceType::Ptr &reqType) +{ + Q_ASSERT(expr); + const QPatternist::ExpressionVisitorResult::Ptr exprInfo(expr->accept(namer)); + Q_ASSERT(exprInfo); + const ExpressionInfo *const constExprInfo = static_cast<const ExpressionInfo *>(exprInfo.data()); + const QString name(constExprInfo->first); + const QString details(constExprInfo->second); + const QString rType(reqType ? reqType->displayName(Global::namePool()) : QLatin1String("Not specified")); + + /* ---------- Handle its staticType() -------- */ + const QPatternist::SequenceType::Ptr type(expr->staticType()); + QString seqType; + + if(type) + seqType = type->displayName(Global::namePool()); + else + seqType = QLatin1String("no type, null pointer returned"); + /* ------------------------------------------- */ + + ASTItem *const node = new ASTItem(parent, name, details, seqType, rType); + + /* ------------ Handle child nodes ----------- */ + const QPatternist::Expression::List children(expr->operands()); + QPatternist::Expression::List::const_iterator it(children.constBegin()); + const QPatternist::Expression::List::const_iterator end(children.constEnd()); + + const QPatternist::SequenceType::List reqTypes(expr->expectedOperandTypes()); + const QPatternist::SequenceType::List::const_iterator typeEnd(reqTypes.constEnd()); + QPatternist::SequenceType::List::const_iterator typeIt(reqTypes.constBegin()); + QPatternist::SequenceType::Ptr t; + + for(; it != end; ++it) + { + if(typeIt != typeEnd) + { + t = *typeIt; + ++typeIt; + } + + node->appendChild(buildASTTree(*it, node, t)); + } + /* ------------------------------------------- */ + + return node; +} + +QPatternist::Expression::Ptr +DebugExpressionFactory::createExpression(QIODevice *const expr, + const QPatternist::StaticContext::Ptr &context, + const QXmlQuery::QueryLanguage lang, + const QPatternist::SequenceType::Ptr &requiredType, + const QUrl &baseURI, + const QXmlName &initialTemplateName) +{ + /* Create the root node. */ + m_ast = new ASTItem(0, QString()); + + return ExpressionFactory::createExpression(expr, context, lang, requiredType, baseURI, initialTemplateName); +} + +void DebugExpressionFactory::processTreePass(const QPatternist::Expression::Ptr &expr, + const CompilationStage stage) +{ + ASTItem *newChild = 0; + + switch(stage) + { + case QueryBodyInitial: + { + newChild = new ASTItem(m_ast, QLatin1String("Initial Build")); + break; + } + case QueryBodyTypeCheck: + { + newChild = new ASTItem(m_ast, QLatin1String("Type Check")); + break; + } + case QueryBodyCompression: + { + newChild = new ASTItem(m_ast, QLatin1String("Compression")); + break; + } + case UserFunctionTypeCheck: + { + newChild = new ASTItem(m_ast, QLatin1String("User Function Type Check")); + break; + } + case UserFunctionCompression: + { + newChild = new ASTItem(m_ast, QLatin1String("User Function Compression")); + break; + } + case GlobalVariableTypeCheck: + { + newChild = new ASTItem(m_ast, QLatin1String("Global Variable Type Check")); + break; + } + } + + Q_ASSERT(newChild); + m_ast->appendChild(newChild); + newChild->appendChild(buildASTTree(expr, newChild, QPatternist::SequenceType::Ptr())); +} + +void DebugExpressionFactory::processTemplateRule(const Expression::Ptr &body, + const TemplatePattern::Ptr &pattern, + const QXmlName &mode, + const TemplateCompilationStage stage) +{ + const char * title; + + switch(stage) + { + case TemplateInitial: + { + title = "Initial Build"; + break; + } + case TemplateTypeCheck: + { + title = "Type Check"; + break; + } + case TemplateCompress: + { + title = "Compression"; + break; + } + } + + const QString modeName(Global::namePool()->displayName(mode)); + Q_ASSERT(title); + ASTItem *const newChild = new ASTItem(m_ast, QLatin1String("T-Rule ") + + QLatin1String(title) + + QLatin1String(" mode: ") + + modeName + + QLatin1String(" priority: ") + + QString::number(pattern->priority())); + m_ast->appendChild(newChild); + + newChild->appendChild(buildASTTree(pattern->matchPattern(), newChild, QPatternist::SequenceType::Ptr())); + newChild->appendChild(buildASTTree(body, newChild, QPatternist::SequenceType::Ptr())); +} + +void DebugExpressionFactory::processNamedTemplate(const QXmlName &name, + const Expression::Ptr &body, + const TemplateCompilationStage stage) +{ + const char * title; + + switch(stage) + { + case TemplateInitial: + { + title = "Named Template Initial Build"; + break; + } + case TemplateTypeCheck: + { + title = "Named Template Type Check"; + break; + } + case TemplateCompress: + { + title = "Named Template Compression"; + break; + } + } + + Q_ASSERT(title); + ASTItem *const newChild = new ASTItem(m_ast, QLatin1String(title) + + QLatin1String(": ") + + Global::namePool()->displayName(name)); + + m_ast->appendChild(newChild); + newChild->appendChild(buildASTTree(body, newChild, QPatternist::SequenceType::Ptr())); +} + +ASTItem *DebugExpressionFactory::astTree() const +{ + return m_ast; +} + +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/DebugExpressionFactory.h b/tests/auto/xmlpatternssdk/DebugExpressionFactory.h new file mode 100644 index 0000000..d5e676d --- /dev/null +++ b/tests/auto/xmlpatternssdk/DebugExpressionFactory.h @@ -0,0 +1,128 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PatternistSDK_DebugExpressionFactory_H +#define PatternistSDK_DebugExpressionFactory_H + +#include "Global.h" +#include "qexpressionfactory_p.h" +#include "qfunctionfactory_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternistSDK +{ + class ASTItem; + + /** + * @short Is a QPatternist::ExpressionFactory, with the + * difference that it provides the hooks for building from a tree of + * debug data from the compiled expression. + * + * This tree can be retrieved via astTree(). The astTree() function + * returns the AST built the last time createExpression() was called. + * + * @ingroup PatternistSDK + * @author Frans Englich <frans.englich@nokia.com> + */ + class Q_PATTERNISTSDK_EXPORT DebugExpressionFactory : public QPatternist::ExpressionFactory + { + public: + DebugExpressionFactory() : m_ast(0) + { + } + + typedef QExplicitlySharedDataPointer<DebugExpressionFactory> Ptr; + /** + * Identical to ExpressionFactory::createExpression() with the difference + * that it builds an ASTItem tree which can be accessed via astTree(). + */ + virtual QPatternist::Expression::Ptr createExpression(QIODevice *const expr, + const QPatternist::StaticContext::Ptr &context, + const QXmlQuery::QueryLanguage lang, + const QPatternist::SequenceType::Ptr &requiredType, + const QUrl &queryURI, + const QXmlName &initialTemplateName); + + /** + * @returns an ASTItem tree built for the last created expression, + * via createExpression(). + */ + virtual ASTItem *astTree() const; + + /** + * @returns a list containing string representations of all available + * functions in Patternist. Each QString in the returned QStringList + * is a function synopsis for human consumption. + */ + static QStringList availableFunctionSignatures(); + + protected: + /** + * Performs the ASTItem tree building. + */ + virtual void processTreePass(const QPatternist::Expression::Ptr &tree, + const CompilationStage stage); + + void processTemplateRule(const QPatternist::Expression::Ptr &body, + const QPatternist::TemplatePattern::Ptr &pattern, + const QXmlName &mode, + const TemplateCompilationStage stage); + + void processNamedTemplate(const QXmlName &name, + const QPatternist::Expression::Ptr &body, + const TemplateCompilationStage stage); + private: + static ASTItem *buildASTTree(const QPatternist::Expression::Ptr &expr, + ASTItem *const parent, + const QPatternist::SequenceType::Ptr &reqType); + ASTItem *m_ast; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/ErrorHandler.cpp b/tests/auto/xmlpatternssdk/ErrorHandler.cpp new file mode 100644 index 0000000..3f07737 --- /dev/null +++ b/tests/auto/xmlpatternssdk/ErrorHandler.cpp @@ -0,0 +1,166 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <cstdio> + +#include <QBuffer> +#include <QStringList> +#include <QtDebug> +#include <QtTest> +#include <QtGlobal> +#include <QXmlQuery> +#include <QXmlResultItems> + +#include "ErrorHandler.h" + +using namespace QPatternistSDK; + +ErrorHandler *ErrorHandler::handler = 0; + +void qMessageHandler(QtMsgType type, const char *description) +{ + if(type == QtDebugMsg) + { + std::fprintf(stderr, "%s\n", description); + return; + } + + QtMsgType t; + + switch(type) + { + case QtWarningMsg: + { + t = QtWarningMsg; + break; + } + case QtCriticalMsg: + { + t = QtFatalMsg; + break; + } + case QtFatalMsg: + { + /* We can't swallow Q_ASSERTs, we need to fail the hard way here. + * But maybe not: when run from "patternistrunsingle" it could be an idea + * to actually try to record it(but nevertheless fail somehow) such + * that it gets reported. */ + std::fprintf(stderr, "Fatal error: %s\n", description); + t = QtFatalMsg; /* Dummy, to silence a bogus compiler warning. */ + return; + } + case QtDebugMsg: /* This enum is handled above in the if-clause. */ + /* Fallthrough. */ + default: + { + Q_ASSERT(false); + return; + } + } + + Q_ASSERT(ErrorHandler::handler); + /* This message is hacky. Ideally, we should do it the same way + * ReportContext::error() constructs messages, but this is just testing + * code. */ + ErrorHandler::handler->message(t, QLatin1String("<p>") + QPatternist::escape(QLatin1String(description)) + QLatin1String("</p>")); +} + +void ErrorHandler::installQtMessageHandler(ErrorHandler *const h) +{ + handler = h; + + if(h) + qInstallMsgHandler(qMessageHandler); + else + qInstallMsgHandler(0); +} + +void ErrorHandler::handleMessage(QtMsgType type, + const QString &description, + const QUrl &identifier, + const QSourceLocation &) +{ + /* Don't use pDebug() in this function, it results in infinite + * recursion. Talking from experience.. */ + + Message msg; + msg.setType(type); + msg.setIdentifier(identifier); + + /* Let's remove all the XHTML markup. */ + QBuffer buffer; + buffer.setData(description.toLatin1()); + buffer.open(QIODevice::ReadOnly); + + QXmlQuery query; + query.bindVariable(QLatin1String("desc"), &buffer); + query.setQuery(QLatin1String("string(doc($desc))")); + + QStringList result; + const bool success = query.evaluateTo(&result); + + if(!description.startsWith(QLatin1String("\"Test-suite harness error:"))) + { + const QString msg(QString::fromLatin1("Invalid description: %1").arg(description)); + QVERIFY2(success, qPrintable(msg)); + + if(!success) + QTextStream(stderr) << msg; + } + + + if(!result.isEmpty()) + msg.setDescription(result.first()); + + m_messages.append(msg); +} + +ErrorHandler::Message::List ErrorHandler::messages() const +{ + return m_messages; +} + +void ErrorHandler::reset() +{ + m_messages.clear(); +} + +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/ErrorHandler.h b/tests/auto/xmlpatternssdk/ErrorHandler.h new file mode 100644 index 0000000..25447a9 --- /dev/null +++ b/tests/auto/xmlpatternssdk/ErrorHandler.h @@ -0,0 +1,149 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PatternistSDK_ErrorHandler_H +#define PatternistSDK_ErrorHandler_H + +#include "Global.h" +#include "qabstractmessagehandler.h" + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +template<typename T> class QList; + +namespace QPatternistSDK +{ + /** + * @short A MessageHandler which + * accumulates all its received ErrorHandler::Message instances + * in a list, retrievable via messages(). + * + * Thus, ErrorHandler does not report errors, but collects them + * and allows easy access to them. + * + * @ingroup PatternistSDK + * @author Frans Englich <frans.englich@nokia.com> + */ + class Q_PATTERNISTSDK_EXPORT ErrorHandler : public QAbstractMessageHandler + { + public: + class Message + { + public: + typedef QList<Message> List; + + QString description() const + { + return m_description; + } + + void setDescription(const QString &desc) + { + m_description = desc; + } + + void setIdentifier(const QUrl &newId) + { + m_identifier = newId; + } + + QUrl identifier() const + { + return m_identifier; + } + + QtMsgType type() const + { + return m_type; + } + + void setType(const QtMsgType t) + { + m_type = t; + } + + private: + QUrl m_identifier; + QtMsgType m_type; + QString m_description; + }; + + /** + * Clears all accumulated errors. + */ + void reset(); + + Message::List messages() const; + + /** + * Calling this function causes all Qt's internal debug messages to be + * sent to @p handler. If @p handler is @c null, Qt's default message + * handler is re-installed. In other words, via an internal proxy function, + * it installs @p handler as Qt's message handler. + * + * If @p handler is heap allocated, it will be leaked. + * + * @see qInstallMsgHandler() + */ + static void installQtMessageHandler(ErrorHandler *const handler); + + static ErrorHandler *handler; + + protected: + virtual void handleMessage(QtMsgType type, + const QString &description, + const QUrl &identifier = QUrl(), + const QSourceLocation &sourceLocation = QSourceLocation()); + + private: + ErrorHandler::Message::List m_messages; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/ErrorItem.cpp b/tests/auto/xmlpatternssdk/ErrorItem.cpp new file mode 100644 index 0000000..57edc1f --- /dev/null +++ b/tests/auto/xmlpatternssdk/ErrorItem.cpp @@ -0,0 +1,142 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QList> +#include <QPointer> +#include <QVariant> + +#include "qreportcontext_p.h" +#include "qcommonnamespaces_p.h" + +#include "ErrorItem.h" + +using namespace QPatternistSDK; + +QString ErrorItem::toString(const QtMsgType type) +{ + switch(type) + { + case QtWarningMsg: + return QLatin1String("Warning"); + case QtFatalMsg: + return QLatin1String("Error"); + default: + { + Q_ASSERT(false); + return QString(); + } + } +} + +ErrorItem::ErrorItem(const ErrorHandler::Message &error, + ErrorItem *p) : m_message(error), + m_parent(p) +{ +} + +ErrorItem::~ErrorItem() +{ + qDeleteAll(m_children); +} + +int ErrorItem::columnCount() const +{ + return 3; +} + +QVariant ErrorItem::data(const Qt::ItemDataRole role, int column) const +{ + if(role != Qt::DisplayRole) + return QVariant(); + + switch(column) + { + case 0: + return toString(m_message.type()); + case 1: + { + if(!m_message.type()) /* It's a warning, likely. */ + return QString(); + + QString ns; + const QString code(QPatternist::ReportContext::codeFromURI(m_message.identifier().toString(), ns)); + + if(ns == QPatternist::CommonNamespaces::XPERR) + return code; + else /* Do the full version. */ + return m_message.type(); + } + case 2: + return m_message.description(); + default: + { + Q_ASSERT(false); + return QVariant(); + } + } +} + +TreeItem::List ErrorItem::children() const +{ + return m_children; +} + +void ErrorItem::appendChild(TreeItem *item) +{ + m_children.append(item); +} + +TreeItem *ErrorItem::child(const unsigned int rowP) const +{ + return m_children.value(rowP); +} + +unsigned int ErrorItem::childCount() const +{ + return m_children.count(); +} + +TreeItem *ErrorItem::parent() const +{ + return m_parent; +} + +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/ErrorItem.h b/tests/auto/xmlpatternssdk/ErrorItem.h new file mode 100644 index 0000000..1d05872 --- /dev/null +++ b/tests/auto/xmlpatternssdk/ErrorItem.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PatternistSDK_ErrorItem_H +#define PatternistSDK_ErrorItem_H + +#include <QList> + +#include "ErrorHandler.h" +#include "Global.h" +#include "TreeItem.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternistSDK +{ + /** + * @short Delegates a ErrorHandler::Message through the interface + * exposed by TreeItem, such that errors from DOM related code + * can be displayed/used in Qt's model/view framework. + * + * @ingroup PatternistSDK + * @author Frans Englich <frans.englich@nokia.com> + */ + class Q_PATTERNISTSDK_EXPORT ErrorItem : public TreeItem + { + public: + ErrorItem(const ErrorHandler::Message &error, ErrorItem *parent); + virtual ~ErrorItem(); + + virtual QVariant data(const Qt::ItemDataRole role, int column) const; + + virtual void appendChild(TreeItem *item); + virtual TreeItem *child(const unsigned int row) const; + virtual unsigned int childCount() const; + virtual TreeItem::List children() const; + virtual TreeItem *parent() const; + int columnCount() const; + + private: + static QString toString(const QtMsgType sev); + + const ErrorHandler::Message m_message; + ErrorItem * m_parent; + TreeItem::List m_children; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/ExitCode.h b/tests/auto/xmlpatternssdk/ExitCode.h new file mode 100644 index 0000000..e1810b1 --- /dev/null +++ b/tests/auto/xmlpatternssdk/ExitCode.h @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PatternistSDK_ExitCode_H +#define PatternistSDK_ExitCode_H + +#include "Global.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternistSDK +{ + /** + * @short Houses program exit codes for PatternistSDK utilities. + * + * @ingroup PatternistSDK + * @author Frans Englich <frans.englich@nokia.com> + */ + class Q_PATTERNISTSDK_EXPORT ExitCode + { + public: + /** + * Exit codes for programs part of PatternistSDK. The values for the enums are specified + * to make it easily understandable what number a symbol corresponds to. + */ + enum Code + { + Success = 0, + InvalidArgCount = 1, + InvalidArgs = 2, + + /** + * Used in @c patternistrunsuite + */ + InvalidCatalogFile = 3, + FileNotExists = 4, + OpenError = 5, + WriteError = 6, + + /** + * Used in the test program used for comparing files on the byte level. + */ + NotEqual = 7, + UnevenTestCount = 8, + InternalError = 9, + Regression = 10 + }; + + private: + /** + * This constructor is private and has no implementation, because this + * class is not supposed to be instantiated. + */ + inline ExitCode(); + + Q_DISABLE_COPY(ExitCode) + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/ExpressionInfo.cpp b/tests/auto/xmlpatternssdk/ExpressionInfo.cpp new file mode 100644 index 0000000..abbc8b3 --- /dev/null +++ b/tests/auto/xmlpatternssdk/ExpressionInfo.cpp @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtDebug> + +#include "ExpressionInfo.h" + +using namespace QPatternistSDK; + +ExpressionInfo::ExpressionInfo(const QString &name, + const QString &details) : QPair<QString, QString>(name, details) +{ +} + +// vim: et:ts=4:sw=4:sts=4 + diff --git a/tests/auto/xmlpatternssdk/ExpressionInfo.h b/tests/auto/xmlpatternssdk/ExpressionInfo.h new file mode 100644 index 0000000..2d9d398 --- /dev/null +++ b/tests/auto/xmlpatternssdk/ExpressionInfo.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PatternistSDK_ExpressionInfo_H +#define PatternistSDK_ExpressionInfo_H + +#include "Global.h" +#include "qexpressiondispatch_p.h" + +#include <QPair> +#include <QString> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternistSDK +{ + /** + * @short Houses debug information about an QPatternist::Expression instance. + * + * An Expression's name, typically its class name, can be retrieved + * via the member variable first, and additional data, for example its string + * value or operator, can be retrieved via the member variable second. + * + * @ingroup PatternistSDK + * @author Frans Englich <frans.englich@nokia.com> + */ + class Q_PATTERNISTSDK_EXPORT ExpressionInfo : public QPatternist::ExpressionVisitorResult + , public QPair<QString, QString> + { + public: + ExpressionInfo(const QString &name, const QString &details); + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/ExpressionNamer.cpp b/tests/auto/xmlpatternssdk/ExpressionNamer.cpp new file mode 100644 index 0000000..605c754 --- /dev/null +++ b/tests/auto/xmlpatternssdk/ExpressionNamer.cpp @@ -0,0 +1,316 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtDebug> + +#include "qabstractfloat_p.h" +#include "qandexpression_p.h" +#include "qanyuri_p.h" +#include "qapplytemplate_p.h" +#include "qargumentreference_p.h" +#include "qarithmeticexpression_p.h" +#include "qatomicstring_p.h" +#include "qatomizer_p.h" +#include "qattributeconstructor_p.h" +#include "qattributenamevalidator_p.h" +#include "qaxisstep_p.h" +#include "qbase64binary_p.h" +#include "qboolean_p.h" +#include "qcardinalityverifier_p.h" +#include "qcastableas_p.h" +#include "qcastas_p.h" +#include "qcombinenodes_p.h" +#include "qcontextitem_p.h" +#include "qdate_p.h" +#include "qdecimal_p.h" +#include "qdynamiccontextstore_p.h" +#include "qelementconstructor_p.h" +#include "qemptysequence_p.h" +#include "qevaluationcache_p.h" +#include "qexpressionsequence_p.h" +#include "qexpressionvariablereference_p.h" +#include "qfirstitempredicate_p.h" +#include "qforclause_p.h" +#include "qfunctioncall_p.h" +#include "qgday_p.h" +#include "qgeneralcomparison_p.h" +#include "qgenericpredicate_p.h" +#include "qgmonthday_p.h" +#include "qgmonth_p.h" +#include "qgyearmonth_p.h" +#include "qgyear_p.h" +#include "qhexbinary_p.h" +#include "qifthenclause_p.h" +#include "qinstanceof_p.h" +#include "qinteger_p.h" +#include "qitem_p.h" +#include "qitemverifier_p.h" +#include "qliteral_p.h" +#include "qnamespaceconstructor_p.h" +#include "qncnameconstructor_p.h" +#include "qnodecomparison_p.h" +#include "qorexpression_p.h" +#include "qpath_p.h" +#include "qpositionalvariablereference_p.h" +#include "qqnameconstructor_p.h" +#include "qqnamevalue_p.h" +#include "qquantifiedexpression_p.h" +#include "qrangeexpression_p.h" +#include "qrangevariablereference_p.h" +#include "qschemadatetime_p.h" +#include "qschematime_p.h" +#include "qsimplecontentconstructor_p.h" +#include "qtreatas_p.h" +#include "qtruthpredicate_p.h" +#include "quntypedatomicconverter_p.h" +#include "quntypedatomic_p.h" +#include "quserfunctioncallsite_p.h" +#include "qvalidationerror_p.h" +#include "qvaluecomparison_p.h" + +#include "ExpressionInfo.h" +#include "Global.h" + +#include "ExpressionNamer.h" + +using namespace QPatternistSDK; + +/* Simple ones, they have no additional data. */ +#define implClass(cls) \ +QPatternist::ExpressionVisitorResult::Ptr ExpressionNamer::visit(const QPatternist::cls *) const \ +{ \ + return QPatternist::ExpressionVisitorResult::Ptr \ + (new ExpressionInfo(QLatin1String(#cls), QString())); \ +} + +implClass(AndExpression) +implClass(ArgumentConverter) +implClass(Atomizer) +implClass(AttributeConstructor) +implClass(AttributeNameValidator) +implClass(CallTemplate) +implClass(CardinalityVerifier) +implClass(CollationChecker) +implClass(CommentConstructor) +implClass(ComputedNamespaceConstructor) +implClass(ContextItem) +implClass(CopyOf) +implClass(CurrentItemStore) +implClass(DocumentConstructor) +implClass(DynamicContextStore) +implClass(EBVExtractor) +implClass(ElementConstructor) +implClass(EmptySequence) +implClass(ExpressionSequence) +implClass(ExternalVariableReference) +implClass(FirstItemPredicate) +implClass(ForClause) +implClass(GenericPredicate) +implClass(IfThenClause) +implClass(ItemVerifier) +implClass(LetClause) +implClass(LiteralSequence) +implClass(NCNameConstructor) +implClass(NodeSortExpression) +implClass(OrderBy) +implClass(OrExpression) +implClass(ParentNodeAxis) +implClass(ProcessingInstructionConstructor) +implClass(QNameConstructor) +implClass(RangeExpression) +implClass(ReturnOrderBy) +implClass(SimpleContentConstructor) +implClass(StaticBaseURIStore) +implClass(StaticCompatibilityStore) +implClass(TemplateParameterReference) +implClass(TextNodeConstructor) +implClass(TreatAs) +implClass(TruthPredicate) +implClass(UnresolvedVariableReference) +implClass(UntypedAtomicConverter) +implClass(UserFunctionCallsite) +implClass(ValidationError) +#undef implClass + +/** Variable references. */ +#define implVarRef(name) \ +QPatternist::ExpressionVisitorResult::Ptr ExpressionNamer::visit(const QPatternist::name *i) const \ +{ \ + return QPatternist::ExpressionVisitorResult::Ptr \ + (new ExpressionInfo(QLatin1String(#name), \ + QString(QLatin1String("Slot: %1")).arg(i->slot()))); \ +} +implVarRef(RangeVariableReference) +implVarRef(ArgumentReference) +implVarRef(ExpressionVariableReference) +implVarRef(PositionalVariableReference) +#undef implVarRef + +/* Type related classes which have a targetType() function. */ +#define implTypeClass(cls) \ +QPatternist::ExpressionVisitorResult::Ptr ExpressionNamer::visit(const QPatternist::cls *i) const \ +{ \ + return QPatternist::ExpressionVisitorResult::Ptr(new ExpressionInfo(QLatin1String(#cls), \ + i->targetType()->displayName(Global::namePool()))); \ +} + +implTypeClass(InstanceOf) +implTypeClass(CastableAs) +#undef implTypeClass + +/* Type related classes which have a targetType() function. */ +QPatternist::ExpressionVisitorResult::Ptr ExpressionNamer::visit(const QPatternist::CastAs *i) const +{ + return QPatternist::ExpressionVisitorResult::Ptr(new ExpressionInfo(QLatin1String("CastAs"), + i->targetSequenceType()->displayName(Global::namePool()))); +} + +/* Classes which represent operators. */ +#define implOPClass(cls, compClass) \ +QPatternist::ExpressionVisitorResult::Ptr ExpressionNamer::visit(const QPatternist::cls *i) const \ +{ \ + return QPatternist::ExpressionVisitorResult::Ptr(new ExpressionInfo(QLatin1String(#cls), \ + QPatternist::compClass::displayName(i->operatorID()))); \ +} + +implOPClass(ArithmeticExpression, AtomicMathematician) +implOPClass(NodeComparison, NodeComparison) +implOPClass(QuantifiedExpression, QuantifiedExpression) +implOPClass(CombineNodes, CombineNodes) +#undef implOPClass + +/* Classes which represent operators. */ +#define implCompClass(cls, type) \ +QPatternist::ExpressionVisitorResult::Ptr ExpressionNamer::visit(const QPatternist::cls *i) const \ +{ \ + return QPatternist::ExpressionVisitorResult::Ptr(new ExpressionInfo(QLatin1String(#cls), \ + QPatternist::AtomicComparator::displayName(i->operatorID(), \ + QPatternist::AtomicComparator::type))); \ +} + +implCompClass(GeneralComparison, AsGeneralComparison) +implCompClass(ValueComparison, AsValueComparison) +#undef implCompClass + +QPatternist::ExpressionVisitorResult::Ptr ExpressionNamer::visit(const QPatternist::FunctionCall *i) const +{ + return QPatternist::ExpressionVisitorResult::Ptr + (new ExpressionInfo(QLatin1String("FunctionCall"), + Global::namePool()->displayName(i->signature()->name()))); +} + +QPatternist::ExpressionVisitorResult::Ptr ExpressionNamer::visit(const QPatternist::Literal *i) const +{ + return QPatternist::ExpressionVisitorResult::Ptr(new ExpressionInfo( + i->item().type()->displayName(Global::namePool()), + i->item().stringValue())); +} + +QPatternist::ExpressionVisitorResult::Ptr ExpressionNamer::visit(const QPatternist::AxisStep *i) const +{ + return QPatternist::ExpressionVisitorResult::Ptr(new ExpressionInfo(QLatin1String("AxisStep"), + QPatternist::AxisStep::axisName(i->axis()) + + QLatin1String("::") + + i->nodeTest()->displayName(Global::namePool()))); + +} + + +QPatternist::ExpressionVisitorResult::Ptr ExpressionNamer::visit(const QPatternist::EvaluationCache<true> *i) const +{ + return QPatternist::ExpressionVisitorResult::Ptr(new ExpressionInfo(QLatin1String("EvaluationCache<IsForGlobal=true>"), + QLatin1String("Slot: ") + QString::number(i->slot()))); + +} + +QPatternist::ExpressionVisitorResult::Ptr ExpressionNamer::visit(const QPatternist::EvaluationCache<false> *i) const +{ + return QPatternist::ExpressionVisitorResult::Ptr(new ExpressionInfo(QLatin1String("EvaluationCache<IsForGlobal=false>"), + QLatin1String("Slot: ") + QString::number(i->slot()))); + +} + +QPatternist::ExpressionVisitorResult::Ptr ExpressionNamer::visit(const QPatternist::NamespaceConstructor *i) const +{ + return QPatternist::ExpressionVisitorResult::Ptr(new ExpressionInfo(QLatin1String("NamespaceConstructor"), + Global::namePool()->stringForPrefix(i->namespaceBinding().prefix()) + + QLatin1Char('=') + + Global::namePool()->stringForNamespace(i->namespaceBinding().namespaceURI()))); + +} + +QPatternist::ExpressionVisitorResult::Ptr ExpressionNamer::visit(const QPatternist::Path *path) const +{ + + QPatternist::Path::Kind k = path->kind(); + QString type; + + switch(k) + { + case QPatternist::Path::XSLTForEach: + { + type = QLatin1String("XSLTForEach"); + break; + } + case QPatternist::Path::RegularPath: + { + type = QLatin1String("RegularPath"); + break; + } + case QPatternist::Path::ForApplyTemplate: + { + type = QLatin1String("ForApplyTemplate"); + break; + } + } + + return QPatternist::ExpressionVisitorResult::Ptr(new ExpressionInfo(QLatin1String("Path"), type)); +} + +QPatternist::ExpressionVisitorResult::Ptr ExpressionNamer::visit(const QPatternist::ApplyTemplate *path) const +{ + const QPatternist::TemplateMode::Ptr mode(path->mode()); + return QPatternist::ExpressionVisitorResult::Ptr + (new ExpressionInfo(QLatin1String("ApplyTemplate"), mode ? Global::namePool()->displayName(mode->name()) : QString::fromLatin1("#current"))); +} + +// vim: et:ts=4:sw=4:sts=4 + diff --git a/tests/auto/xmlpatternssdk/ExpressionNamer.h b/tests/auto/xmlpatternssdk/ExpressionNamer.h new file mode 100644 index 0000000..129d8d7 --- /dev/null +++ b/tests/auto/xmlpatternssdk/ExpressionNamer.h @@ -0,0 +1,281 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PatternistSDK_ExpressionNamer_H +#define PatternistSDK_ExpressionNamer_H + +#include "Global.h" +#include "qexpressiondispatch_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternistSDK +{ + /** + * @short Extracts debug information from a QPatternist::Expression tree. + * + * This data is the name of the AST node(typically the class name), + * and additional data such as the value, type of operator, and so forth. The result + * is returned(from visit()), is an ExpressionInfo instance. + * + * @see ExpressionInfo + * @see ASTItem + * @ingroup PatternistSDK + * @author Frans Englich <frans.englich@nokia.com> + */ + class Q_PATTERNISTSDK_EXPORT ExpressionNamer : public QPatternist::ExpressionVisitor + { + public: + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::AndExpression *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::ApplyTemplate *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::ArgumentReference *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::ArithmeticExpression *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::Atomizer *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::AttributeConstructor *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::AttributeNameValidator *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::CallTemplate *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::CardinalityVerifier *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::CastAs *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::CastableAs *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::CollationChecker *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::CombineNodes *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::ComputedNamespaceConstructor *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::CommentConstructor *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::ContextItem *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::CopyOf *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::CurrentItemStore *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::DocumentConstructor *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::DynamicContextStore *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::EBVExtractor *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::ElementConstructor *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::EmptySequence *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::ExpressionSequence *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::ExpressionVariableReference *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::ExternalVariableReference *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::EvaluationCache<true> *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::EvaluationCache<false> *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::FirstItemPredicate *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::ForClause *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::FunctionCall *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::GeneralComparison *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::GenericPredicate *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::IfThenClause *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::InstanceOf *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::ItemVerifier *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::LetClause *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::Literal *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::LiteralSequence *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::NCNameConstructor *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::NodeComparison *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::NodeSortExpression *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::OrderBy *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::OrExpression *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::ParentNodeAxis *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::Path *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::PositionalVariableReference *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::ProcessingInstructionConstructor *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::QNameConstructor *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::QuantifiedExpression *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::RangeExpression *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::RangeVariableReference *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::ReturnOrderBy *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::SimpleContentConstructor *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::StaticBaseURIStore *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::StaticCompatibilityStore *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::AxisStep *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::TemplateParameterReference *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::TextNodeConstructor *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::TreatAs *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::TruthPredicate *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::UntypedAtomicConverter *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::UnresolvedVariableReference *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::ArgumentConverter *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::UserFunctionCallsite *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::ValidationError *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::ValueComparison *) const; + + virtual QPatternist::ExpressionVisitorResult::Ptr + visit(const QPatternist::NamespaceConstructor *) const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/ExternalSourceLoader.cpp b/tests/auto/xmlpatternssdk/ExternalSourceLoader.cpp new file mode 100644 index 0000000..a83a100 --- /dev/null +++ b/tests/auto/xmlpatternssdk/ExternalSourceLoader.cpp @@ -0,0 +1,140 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QCoreApplication> +#include <QFile> +#include <QtDebug> +#include <QXmlResultItems> +#include <QXmlNamePool> + +#include "Global.h" + +#include "qcommonsequencetypes_p.h" +#include "qdebug_p.h" +#include "qatomicstring_p.h" + +#include "ExternalSourceLoader.h" + +using namespace QPatternistSDK; +using namespace QPatternist; + +ExternalSourceLoader::ExternalSourceLoader(const VariableMap &varMap, + const QPatternist::ResourceLoader::Ptr &r) : m_variableMap(varMap) + , m_resourceLoader(r) + , m_query(Global::namePoolAsPublic()) +{ + Q_ASSERT(m_resourceLoader); +} + +QPatternist::SequenceType::Ptr +ExternalSourceLoader::announceExternalVariable(const QXmlName name, + const QPatternist::SequenceType::Ptr &declaredType) +{ + pDebug() << "ExternalSourceLoader::announceExternalVariable()"; + Q_ASSERT(!name.isNull()); + Q_ASSERT(declaredType); + Q_UNUSED(declaredType); /* Needed when bulding in release mode. */ + + if(name.namespaceURI() == QPatternist::StandardNamespaces::empty) + { + const VariableValue variable(m_variableMap.value(Global::namePool()->stringForLocalName(name.localName()))); + + if(variable.first.isEmpty()) + return QPatternist::SequenceType::Ptr(); + else + { + /* If announceDocument() can't load a document for uriForVar, it will return + * null, which we will too, which is fine, since we can't supply a value for + * this variable then. */ + if(variable.second == Document) + return m_resourceLoader->announceDocument(variable.first, QPatternist::ResourceLoader::WillUse); + else if(variable.second == URI) + { + return QPatternist::CommonSequenceTypes::ExactlyOneString; + } + else + { + /* The type is Query, and we don't pre-load + * them. No particular reason, just not worth it. */ + return QPatternist::CommonSequenceTypes::ZeroOrMoreItems; + } + } + } + else + return QPatternist::SequenceType::Ptr(); +} + +QPatternist::Item +ExternalSourceLoader::evaluateSingleton(const QXmlName name, + const QPatternist::DynamicContext::Ptr &context) +{ + Q_ASSERT(!name.isNull()); + const VariableValue variable(m_variableMap.value(Global::namePool()->stringForLocalName(name.localName()))); + + if(variable.second == Document) + { + Q_ASSERT_X(QFile::exists(variable.first.toLocalFile()), Q_FUNC_INFO, + qPrintable(QString::fromLatin1("The file %1 doesn't exist").arg(variable.first.toLocalFile()))); + Q_ASSERT_X(m_resourceLoader->openDocument(variable.first, context), Q_FUNC_INFO, + "We're supposed to have the value. If not, an error should have been issued at query compile time."); + + return m_resourceLoader->openDocument(variable.first, context); + } + else if(variable.second == Query) + { + /* Well, here we open the file and execute it. */ + m_query.setQuery(QUrl::fromLocalFile(variable.first.toLocalFile())); + Q_ASSERT(m_query.isValid()); + + QXmlResultItems result; + m_query.evaluateTo(&result); + + return QPatternist::Item::fromPublic(result.next()); + } + else + { + Q_ASSERT(variable.second == URI); + return QPatternist::AtomicString::fromValue(variable.first.toString()); + } +} + +// vim: et:ts=4:sw=4:sts=4 + diff --git a/tests/auto/xmlpatternssdk/ExternalSourceLoader.h b/tests/auto/xmlpatternssdk/ExternalSourceLoader.h new file mode 100644 index 0000000..2d88222 --- /dev/null +++ b/tests/auto/xmlpatternssdk/ExternalSourceLoader.h @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PatternistSDK_ExternalSourceLoader_H +#define PatternistSDK_ExternalSourceLoader_H + +#include <QHash> +#include <QUrl> +#include <QXmlQuery> + +#include "qdynamiccontext_p.h" +#include "qresourceloader_p.h" +#include "qexternalvariableloader_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternistSDK +{ + /** + * @short Handles external variables in XQTS queries, such as <tt>$input-context</tt>, + * by loading appropriate XML source files. + * + * @ingroup PatternistSDK + * @author Frans Englich <frans.englich@nokia.com> + */ + class Q_PATTERNISTSDK_EXPORT ExternalSourceLoader : public QPatternist::ExternalVariableLoader + { + public: + enum TargetOfURI + { + /** + * Identifies @c input-file. + */ + Document, + + /** + * Identifies @c input-URI. + */ + URI, + + /** + * Identifies @c input-query. + */ + Query + }; + + /** + * The first is the complete, absolute, final URI to the file to be loaded, + * and the second is the type of source found at that URI. + */ + typedef QPair<QUrl, TargetOfURI> VariableValue; + + /** + * In the XQTSCatalog.xml each source file in each test is referred to + * by a key, which can be fully looked up in the @c sources element. This QHash + * maps the keys to absolute URIs pointing to the source file. + */ + typedef QHash<QString, QUrl> SourceMap; + + /** + * The first value is the variable name, and the second is the URI identifying + * the XML source file that's supposed to be loaded as a document. + * + * This is one for every test case, except for @c rdb-queries-results-q5, + * @c rdb-queries-results-q17 and @c rdb-queries-results-q18(at least in XQTS 1.0). + */ + typedef QHash<QString, VariableValue> VariableMap; + + ExternalSourceLoader(const VariableMap &varMap, + const QPatternist::ResourceLoader::Ptr &resourceLoader); + + virtual QPatternist::SequenceType::Ptr + announceExternalVariable(const QXmlName name, + const QPatternist::SequenceType::Ptr &declaredType); + + virtual QPatternist::Item + evaluateSingleton(const QXmlName name, + const QPatternist::DynamicContext::Ptr &context); + + VariableMap variableMap() const + { + return m_variableMap; + } + + private: + const VariableMap m_variableMap; + const QPatternist::ResourceLoader::Ptr m_resourceLoader; + QXmlQuery m_query; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/Global.cpp b/tests/auto/xmlpatternssdk/Global.cpp new file mode 100644 index 0000000..f78e421 --- /dev/null +++ b/tests/auto/xmlpatternssdk/Global.cpp @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QXmlNamePool> + +#include "Global.h" + +using namespace QPatternistSDK; + +const QString Global::xqtsCatalogNS (QLatin1String("http://www.w3.org/2005/02/query-test-XQTSCatalog")); +const QString Global::xqtsResultNS (QLatin1String("http://www.w3.org/2005/02/query-test-XQTSResult")); +const QString Global::xsltsCatalogNS (QLatin1String("http://www.w3.org/2005/05/xslt20-test-catalog")); +const QString Global::organizationName (QLatin1String("Patternist Team")); +const qint16 Global::versionNumber (0x01); + +static QXmlNamePool s_namePool; + +QPatternist::NamePool::Ptr Global::namePool() +{ + return s_namePool.d; +} + +QXmlNamePool Global::namePoolAsPublic() +{ + return s_namePool; +} + +bool Global::readBoolean(const QString &value) +{ + const QString normd(value.simplified()); + + if(normd == QLatin1String("true") || + normd == QLatin1String("1")) + return true; + else if(normd.isEmpty() || + normd == QLatin1String("false") || + normd == QLatin1String("0")) + return false; + + Q_ASSERT_X(false, Q_FUNC_INFO, + "The lexical representation of xs:boolean was invalid"); + return false; +} + +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/Global.h b/tests/auto/xmlpatternssdk/Global.h new file mode 100644 index 0000000..53c32cb --- /dev/null +++ b/tests/auto/xmlpatternssdk/Global.h @@ -0,0 +1,128 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PatternistSDK_Global_H +#define PatternistSDK_Global_H + +#include <QString> + +#include "private/qitem_p.h" +#include "private/qnamepool_p.h" + +#if defined(Q_WS_WIN) || defined(Q_OS_SYMBIAN) +# ifdef Q_PATTERNISTSDK_BUILDING + #define Q_PATTERNISTSDK_EXPORT __declspec(dllexport) + #else + #define Q_PATTERNISTSDK_EXPORT __declspec(dllimport) + #endif +#else + #define Q_PATTERNISTSDK_EXPORT +#endif + +/** + * @short Contains testing utilities for Patternist, interfacing W3C's XQuery Test Suite. + * + * @see <a href="http://www.w3.org/XML/Query/test-suite/">XML Query Test Suite</a> + * @author Frans Englich <frans.englich@nokia.com> + */ +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternistSDK +{ + /** + * @short Contains global constants. + * + * @ingroup PatternistSDK + * @author Frans Englich <frans.englich@nokia.com> + */ + class Q_PATTERNISTSDK_EXPORT Global + { + public: + + /** + * The namespace which the XQTS test case catalog(specified by Catalog.xsd) + * is in. The namespace is: <tt>http://www.w3.org/2005/02/query-test-XQTSCatalog</tt> + */ + static const QString xqtsCatalogNS; + + /** + * The namespace which the XQTS test results collection(specified by XQTSResult.xsd) + * is in. The namespace is: <tt>http://www.w3.org/2005/02/query-test-XQTSResult</tt> + */ + static const QString xqtsResultNS; + + /** + * The organization which created PatternistSDK. It say something + * in the direction of "Patternist Team", and is used for QSettings and the like. + */ + static const QString organizationName; + + /** + * The namespace which W3C's XSL-T test suite resides in. + */ + static const QString xsltsCatalogNS; + + /** + * The version of PatternistSDK. The value has currently no other + * meaning than that larger means older. This version information is supplied to + * QMainWindow::restoreState() and QMainWindow::saveState(). + */ + static const qint16 versionNumber; + + /** + * Parses the lexical space of @c xs:boolean, + * with the exception that the empty string is considered @c false. + */ + static bool readBoolean(const QString &lexicalSpace); + + static QPatternist::NamePool::Ptr namePool(); + static QXmlNamePool namePoolAsPublic(); + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/ResultThreader.cpp b/tests/auto/xmlpatternssdk/ResultThreader.cpp new file mode 100644 index 0000000..3296854 --- /dev/null +++ b/tests/auto/xmlpatternssdk/ResultThreader.cpp @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QEventLoop> + +#include "ResultThreader.h" + +using namespace QPatternistSDK; + +ResultThreader::ResultThreader(QEventLoop &ev, + QFile *file, + const Type t, + QObject *p) : QThread(p) + , m_file(file) + , m_type(t) + , m_eventLoop(ev) +{ + Q_ASSERT_X(p, Q_FUNC_INFO, "Should have a parent"); + Q_ASSERT_X(file, Q_FUNC_INFO, "Should have a valid file"); + Q_ASSERT(m_type == Baseline || m_type == Result); +} + +void ResultThreader::run() +{ + QXmlSimpleReader reader; + reader.setContentHandler(this); + + QXmlInputSource source(m_file); + reader.parse(source); + m_file->close(); +} + +ResultThreader::Type ResultThreader::type() const +{ + return m_type; +} + +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/ResultThreader.h b/tests/auto/xmlpatternssdk/ResultThreader.h new file mode 100644 index 0000000..19749f0 --- /dev/null +++ b/tests/auto/xmlpatternssdk/ResultThreader.h @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PatternistSDK_ResultThreader_H +#define PatternistSDK_ResultThreader_H + +#include <QFile> +#include <QFileInfo> +#include <QThread> + +#include "TestResultHandler.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QEventLoop; + +namespace QPatternistSDK +{ + /** + * @short Reads XML in the @c XQTSResult.xsd format, as a thread, allowing + * multiple parses to be done simultaneously. + * + * @author Frans Englich <frans.englich@nokia.com> + * @ingroup PatternistSDK + */ + class Q_PATTERNISTSDK_EXPORT ResultThreader : public QThread + , public TestResultHandler + { + public: + enum Type + { + Baseline = 1, + Result + }; + + /** + * Creates a ResultThreader that will read @p file when run() is called. + */ + ResultThreader(QEventLoop &ev, + QFile *file, + const Type type, + QObject *parent); + + /** + * Parses the file passed in this class's constructor with this ResultHandlerTH::Item::LisT + * as the QXmlContentHandler, and returns. + */ + virtual void run(); + + /** + * @note Do not reimplement this function. + * @returns whether this ResultThreader handles the baseline or the result. + */ + Type type() const; + + private: + Q_DISABLE_COPY(ResultThreader) + + QFile *const m_file; + const Type m_type; + QEventLoop & m_eventLoop; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/TestBaseLine.cpp b/tests/auto/xmlpatternssdk/TestBaseLine.cpp new file mode 100644 index 0000000..6a46bcc --- /dev/null +++ b/tests/auto/xmlpatternssdk/TestBaseLine.cpp @@ -0,0 +1,511 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QDomDocument> +#include <QFile> +#include <QFileInfo> +#include <QRegExp> +#include <QtDebug> +#include <QUrl> +#include <QXmlAttributes> +#include <QXmlSimpleReader> + +#include "qdebug_p.h" +#include "XMLWriter.h" + +#include "TestBaseLine.h" + +using namespace QPatternistSDK; +using namespace QPatternist; + +Q_GLOBAL_STATIC_WITH_ARGS(QRegExp, errorRegExp, (QLatin1String("[A-Z]{4}[0-9]{4}"))) + +TestBaseLine::TestBaseLine(const Type t) : m_type(t) +{ + Q_ASSERT(errorRegExp()->isValid()); +} + +TestResult::Status TestBaseLine::scan(const QString &serialized, + const TestBaseLine::List &lines) +{ + Q_ASSERT_X(lines.count() >= 1, Q_FUNC_INFO, + "At least one base line must be passed, otherwise there's nothing " + "to compare to."); + + const TestBaseLine::List::const_iterator end(lines.constEnd()); + TestBaseLine::List::const_iterator it(lines.constBegin()); + for(; it != end; ++it) + { + const TestResult::Status retval((*it)->verify(serialized)); + + if(retval == TestResult::Pass || retval == TestResult::NotTested) + return retval; + } + + return TestResult::Fail; +} + +TestResult::Status TestBaseLine::scanErrors(const ErrorHandler::Message::List &errors, + const TestBaseLine::List &lines) +{ + pDebug() << "TestBaseLine::scanErrors()"; + + /* 1. Find the first error in @p errors that's a Patternist + * error(not warning and not from Qt) and extract the error code. */ + QString errorCode; + + const ErrorHandler::Message::List::const_iterator end(errors.constEnd()); + ErrorHandler::Message::List::const_iterator it(errors.constBegin()); + for(; it != end; ++it) + { + if((*it).type() != QtFatalMsg) + continue; + + errorCode = QUrl((*it).identifier()).fragment(); + + pDebug() << "ERR:" << (*it).description(); + /* This is hackish. We have no way of determining whether a Message + * is actually issued from Patternist, so we try to narrow it down like this. */ + if(errorRegExp()->exactMatch(errorCode)) + break; /* It's an error code. */ + else + errorCode.clear(); + } + + pDebug() << "Got error code: " << errorCode; + /* 2. Loop through @p lines, and for the first base line + * which is of type ExpectedError and which matches @p errorCode + * return Pass, otherwise Fail. */ + const TestBaseLine::List::const_iterator blend(lines.constEnd()); + TestBaseLine::List::const_iterator blit(lines.constBegin()); + for(; blit != blend; ++blit) + { + const Type t = (*blit)->type(); + + if(t == TestBaseLine::ExpectedError) + { + const QString d((*blit)->details()); + if(d == errorCode || d == QChar::fromLatin1('*')) + return TestResult::Pass; + } + } + + return TestResult::Fail; +} + +void TestBaseLine::toXML(XMLWriter &receiver) const +{ + switch(m_type) + { + case XML: /* Fallthrough. */ + case Fragment: /* Fallthrough. */ + case SchemaIsValid: /* Fallthrough. */ + case Text: + { + QXmlAttributes inspectAtts; + inspectAtts.append(QLatin1String("role"), QString(), + QLatin1String("role"), QLatin1String("principal")); + inspectAtts.append(QLatin1String("compare"), QString(), + QLatin1String("compare"), displayName(m_type)); + receiver.startElement(QLatin1String("output-file"), inspectAtts); + receiver.characters(m_details); + receiver.endElement(QLatin1String("output-file")); + return; + } + case Ignore: + { + Q_ASSERT_X(false, Q_FUNC_INFO, "Serializing 'Ignore' is not implemented."); + return; + } + case Inspect: + { + QXmlAttributes inspectAtts; + inspectAtts.append(QLatin1String("role"), QString(), + QLatin1String("role"), QLatin1String("principal")); + inspectAtts.append(QLatin1String("compare"), QString(), + QLatin1String("compare"), QLatin1String("Inspect")); + receiver.startElement(QLatin1String("output-file"), inspectAtts); + receiver.characters(m_details); + receiver.endElement(QLatin1String("output-file")); + return; + } + case ExpectedError: + { + receiver.startElement(QLatin1String("expected-error")); + receiver.characters(m_details); + receiver.endElement(QLatin1String("expected-error")); + return; + } + } +} + +bool TestBaseLine::isChildrenDeepEqual(const QDomNodeList &cl1, const QDomNodeList &cl2) +{ + const unsigned int len = cl1.length(); + + if(len == cl2.length()) + { + for(unsigned int i = 0; i < len; ++i) + { + if(!isDeepEqual(cl1.at(i), cl2.at(i))) + return false; + } + + return true; + } + else + return false; +} + +bool TestBaseLine::isAttributesEqual(const QDomNamedNodeMap &cl1, const QDomNamedNodeMap &cl2) +{ + const unsigned int len = cl1.length(); + pDebug() << "LEN:" << len; + + if(len == cl2.length()) + { + for(unsigned int i1 = 0; i1 < len; ++i1) + { + const QDomNode attr1(cl1.item(i1)); + Q_ASSERT(!attr1.isNull()); + + /* This is set if attr1 cannot be found at all in cl2. */ + bool earlyExit = false; + + for(unsigned int i2 = 0; i2 < len; ++i2) + { + const QDomNode attr2(cl2.item(i2)); + Q_ASSERT(!attr2.isNull()); + pDebug() << "ATTR1:" << attr1.localName() << attr1.namespaceURI() << attr1.prefix() << attr1.nodeName(); + pDebug() << "ATTR2:" << attr2.localName() << attr2.namespaceURI() << attr2.prefix() << attr2.nodeName(); + + if(attr1.localName() == attr2.localName() && + attr1.namespaceURI() == attr2.namespaceURI() && + attr1.prefix() == attr2.prefix() && + attr1.nodeName() == attr2.nodeName() && /* Yes, needed in addition to all the other. */ + attr1.nodeValue() == attr2.nodeValue()) + { + earlyExit = true; + break; + } + } + + if(!earlyExit) + { + /* An attribute was found that doesn't exist in the other list so exit. */ + return false; + } + } + + return true; + } + else + return false; +} + +bool TestBaseLine::isDeepEqual(const QDomNode &n1, const QDomNode &n2) +{ + if(n1.nodeType() != n2.nodeType()) + return false; + + switch(n1.nodeType()) + { + case QDomNode::CommentNode: + /* Fallthrough. */ + case QDomNode::TextNode: + { + return static_cast<const QDomCharacterData &>(n1).data() == + static_cast<const QDomCharacterData &>(n2).data(); + } + case QDomNode::ProcessingInstructionNode: + { + return n1.nodeName() == n2.nodeName() && + n1.nodeValue() == n2.nodeValue(); + } + case QDomNode::DocumentNode: + return isChildrenDeepEqual(n1.childNodes(), n2.childNodes()); + case QDomNode::ElementNode: + { + return n1.localName() == n2.localName() && + n1.namespaceURI() == n2.namespaceURI() && + n1.nodeName() == n2.nodeName() && /* Yes, this one is needed in addition to localName(). */ + isAttributesEqual(n1.attributes(), n2.attributes()) && + isChildrenDeepEqual(n1.childNodes(), n2.childNodes()); + } + /* Fallthrough all these. */ + case QDomNode::EntityReferenceNode: + case QDomNode::CDATASectionNode: + case QDomNode::EntityNode: + case QDomNode::DocumentTypeNode: + case QDomNode::DocumentFragmentNode: + case QDomNode::NotationNode: + case QDomNode::BaseNode: + case QDomNode::CharacterDataNode: + { + Q_ASSERT_X(false, Q_FUNC_INFO, + "An unsupported node type was encountered."); + return false; + } + case QDomNode::AttributeNode: + { + Q_ASSERT_X(false, Q_FUNC_INFO, + "This should never happen. QDom doesn't allow us to compare DOM attributes " + "properly."); + return false; + } + default: + { + Q_ASSERT_X(false, Q_FUNC_INFO, "Unhandled QDom::NodeType value."); + return false; + } + } +} + +TestResult::Status TestBaseLine::verify(const QString &serializedInput) const +{ + switch(m_type) + { + case SchemaIsValid: + /* Fall through. */ + case Text: + { + if(serializedInput == details()) + return TestResult::Pass; + else + return TestResult::Fail; + } + case Fragment: + /* Fall through. */ + case XML: + { + /* Read the baseline and the serialized input into two QDomDocuments, and compare + * them deeply. We wrap fragments in a root node such that it is well-formed XML. + */ + + QDomDocument output; + { + /* The reason we put things into a QByteArray and then parse it through QXmlSimpleReader, is that + * QDomDocument does whitespace stripping when calling setContent(QString). In other words, + * this workarounds a bug. */ + + QXmlInputSource source; + source.setData((m_type == XML ? serializedInput : QLatin1String("<r>") + + serializedInput + + QLatin1String("</r>")).toUtf8()); + + QString outputReadingError; + + QXmlSimpleReader reader; + reader.setFeature(QLatin1String("http://xml.org/sax/features/namespace-prefixes"), true); + + const bool success = output.setContent(&source, + &reader, + &outputReadingError); + + if(!success) + return TestResult::Fail; + + Q_ASSERT(success); + } + + QDomDocument baseline; + { + QXmlInputSource source; + source.setData((m_type == XML ? details() : QLatin1String("<r>") + + details() + + QLatin1String("</r>")).toUtf8()); + QString baselineReadingError; + + QXmlSimpleReader reader; + reader.setFeature(QLatin1String("http://xml.org/sax/features/namespace-prefixes"), true); + + const bool success = baseline.setContent(&source, + &reader, + &baselineReadingError); + + if(!success) + return TestResult::Fail; + + /* This piece of code workaround a bug in QDom, which treats XML prologs as processing + * instructions and make them available in the tree as so. */ + if(m_type == XML) + { + /* $doc/r/node() */ + const QDomNodeList children(baseline.childNodes()); + const int len = children.length(); + + for(int i = 0; i < len; ++i) + { + const QDomNode &child = children.at(i); + if(child.isProcessingInstruction() && child.nodeName() == QLatin1String("xml")) + { + baseline.removeChild(child); + break; + } + } + } + + Q_ASSERT_X(baselineReadingError.isNull(), Q_FUNC_INFO, + qPrintable((QLatin1String("Reading the baseline failed: ") + baselineReadingError))); + } + + if(isDeepEqual(output, baseline)) + return TestResult::Pass; + else + { + pDebug() << "FAILURE:" << output.toString() << "is NOT IDENTICAL to(baseline):" << baseline.toString(); + return TestResult::Fail; + } + } + case Ignore: + return TestResult::Pass; + case Inspect: + return TestResult::NotTested; + case ExpectedError: + { + /* This function is only called for Text/XML/Fragment tests. */ + return TestResult::Fail; + } + } + Q_ASSERT(false); + return TestResult::Fail; +} + +TestBaseLine::Type TestBaseLine::identifierFromString(const QString &string) +{ + /* "html-output: Using an ad hoc tool, it must assert that the document obeys the HTML + * Output Method as defined in the Serialization specification and section + * 20 of the XSLT 2.0 specification." We treat it as XML for now, same with + * xhtml-output. */ + if(string.compare(QLatin1String("XML"), Qt::CaseInsensitive) == 0 || + string == QLatin1String("html-output") || + string == QLatin1String("xml-output") || + string == QLatin1String("xhtml-output")) + return XML; + else if(string == QLatin1String("Fragment") || string == QLatin1String("xml-frag")) + return Fragment; + else if(string.compare(QLatin1String("Text"), Qt::CaseInsensitive) == 0) + return Text; + else if(string == QLatin1String("Ignore")) + return Ignore; + else if(string.compare(QLatin1String("Inspect"), Qt::CaseInsensitive) == 0) + return Inspect; + else + { + Q_ASSERT_X(false, Q_FUNC_INFO, + qPrintable(QString::fromLatin1("Invalid string representation for a comparation type: %1").arg(string))); + + return Ignore; /* Silence GCC. */ + } +} + +QString TestBaseLine::displayName(const Type id) +{ + switch(id) + { + case XML: + return QLatin1String("XML"); + case Fragment: + return QLatin1String("Fragment"); + case Text: + return QLatin1String("Text"); + case Ignore: + return QLatin1String("Ignore"); + case Inspect: + return QLatin1String("Inspect"); + case ExpectedError: + return QLatin1String("ExpectedError"); + case SchemaIsValid: + return QLatin1String("SchemaIsValid"); + } + + Q_ASSERT(false); + return QString(); +} + +QString TestBaseLine::details() const +{ + if(m_type == Ignore) /* We're an error code. */ + return QString(); + if(m_type == ExpectedError) /* We're an error code. */ + return m_details; + if(m_type == SchemaIsValid) /* We're a schema validation information . */ + return m_details; + + if(m_details.isEmpty()) + return m_details; + + /* m_details is a file name, we open it and return the result. */ + QFile file(QUrl(m_details).toLocalFile()); + + QString retval; + if(!file.exists()) + retval = QString::fromLatin1("%1 does not exist.").arg(file.fileName()); + else if(!QFileInfo(file.fileName()).isFile()) + retval = QString::fromLatin1("%1 is not a file, cannot display it.").arg(file.fileName()); + else if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) + retval = QString::fromLatin1("Could not open %1. Likely a permission error.").arg(file.fileName()); + + if(retval.isNull()) + { + /* Scary, we assume the query/baseline is in UTF-8. */ + return QString::fromUtf8(file.readAll()); + } + else + { + /* We had a file error. */ + retval.prepend(QLatin1String("Test-suite harness error: ")); + qCritical() << retval; + return retval; + } +} + +TestBaseLine::Type TestBaseLine::type() const +{ + return m_type; +} + +void TestBaseLine::setDetails(const QString &detailsP) +{ + m_details = detailsP; +} + +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/TestBaseLine.h b/tests/auto/xmlpatternssdk/TestBaseLine.h new file mode 100644 index 0000000..e297128 --- /dev/null +++ b/tests/auto/xmlpatternssdk/TestBaseLine.h @@ -0,0 +1,212 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PatternistSDK_TestBaseLine_H +#define PatternistSDK_TestBaseLine_H + +#include <QString> + +#include "Global.h" +#include "TestResult.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QDomNamedNodeMap; +class QDomNode; +class QDomNodeList; +template<typename T> class QList; + +namespace QPatternistSDK +{ + /** + * @short Represents an expected test result for a test case. + * + * TestBaseLine represents a valid outcome for a test case, + * the "base line". A XQTS test case can have many different valid + * base lines, and one TestBaseLine instance represents on of them. + * + * Of highest interest, TestBaseLine have the function scan() and + * scanErrors(), which allows serialized output to be + * compared to the base line. + * + * @ingroup PatternistSDK + * @author Frans Englich <frans.englich@nokia.com> + */ + class Q_PATTERNISTSDK_EXPORT TestBaseLine + { + public: + typedef QList<TestBaseLine *> List; + + /** + * Identifies what kind of comparator to use. The documentation + * for each enumerator is copied from + * <a href="http://www.w3.org/XML/Query/test-suite/Guidelines + * for Running the XML Query Test Suite.html">Guidelines + * for Running the XML Query Test Suite</a> + */ + enum Type + { + /** + * The test harness must canonicalize both, the actual result + * and the expected result according to the "Canonical XML" recommendation [2], + * which refers to a number of open-source implementations. Byte-comparison can + * then be applied to the resulting XML documents. If the test harness does + * this process in a different manner, it must be documented. + */ + XML, + + /** + * For XML fragments, the same root node must be created for both, + * implementation result and test suite result. The resulting XML + * can be compared using XML comparison. + */ + Fragment, + + /** + * Text (that has been produced by XML serialization) is compared + * using byte-comparison. + */ + Text, + + /** + * No comparison needs to be applied; the result is always @c true if + * the implementation successfully executes the test case. + */ + Ignore, + + /** + * A human is required to make the call about correctness of the result + * according to the description in the test case. + */ + Inspect, + + /** + * The expected result of the test case is an error, identified as an + * eight-character error code (e.g., XPST0003). The result of a test is + * @c true, if the implementation raises an error. However, raising an error + * because an implementation does not support the feature is not + * considered a correct result. + */ + ExpectedError, + + /** + * A special comparison for the schema validation tests. The details + * can only be 'true' or 'false' depending on whether it is a valid + * schema or not. + */ + SchemaIsValid + }; + + /** + * Takes a string identifying a comparator either in the XSL-T or the + * XQuery test suite, and returns an enum value for it. + * + * If the value is unknown, the code asserts. + */ + static Type identifierFromString(const QString &string); + + /** + * @returns a display name for @p id. For example, if Inspect was passed, "Inspect" + * would be returned. + */ + static QString displayName(const Type id); + + /** + * Compares @p items(typically the result of an evaluation) against + * the base lines @p lines. + * + * @returns the status of the first base line which passes, + * otherwise TestResult::Fail. + */ + static TestResult::Status scan(const QString &serialized, + const TestBaseLine::List &lines); + + static TestResult::Status scanErrors(const ErrorHandler::Message::List &errors, + const TestBaseLine::List &lines); + + /** + * Constructs a TestBaseLine of type @p type. + */ + TestBaseLine(const Type type); + + /** + * What @p details contains depends on the type(). If the type() is ExpectedError, + * @p details contains the relevant error code. If the type() is one which compares + * result against a base line, it is a filename locating the baseline. + */ + void setDetails(const QString &details); + + Type type() const; + + QString details() const; + + void toXML(XMLWriter &receiver) const; + + protected: + TestResult::Status verify(const QString &serializedInput) const; + + private: + static bool isDeepEqual(const QDomNode &n1, const QDomNode &n2); + + /** + * @returns @c true if the nodes in @p cl1 are equal to @p cl2, by calling isDeepEqual() + * for each pair. + */ + static bool isChildrenDeepEqual(const QDomNodeList &cl1, const QDomNodeList &cl2); + + /** + * Considers @p cl1 and @p cl2 to be lists containing attributes. The list are equal + * if they contain attributes by same value and name, but regardless of order. + */ + static bool isAttributesEqual(const QDomNamedNodeMap &cl1, const QDomNamedNodeMap &cl2); + const Type m_type; + QString m_details; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/TestCase.cpp b/tests/auto/xmlpatternssdk/TestCase.cpp new file mode 100644 index 0000000..7b424d2 --- /dev/null +++ b/tests/auto/xmlpatternssdk/TestCase.cpp @@ -0,0 +1,439 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QBuffer> +#include <QUrl> +#include <QXmlAttributes> +#include <QXmlQuery> +#include <QXmlResultItems> +#include <QXmlSerializer> +#include <qxmlquery_p.h> + +#include "DebugExpressionFactory.h" +#include "ExternalSourceLoader.h" +#include "Global.h" +#include "TestSuite.h" +#include "XMLWriter.h" + +#include "TestCase.h" + +using namespace QPatternistSDK; +using namespace QPatternist; + +// STATIC DATA +static const DebugExpressionFactory::Ptr s_exprFact(new DebugExpressionFactory()); + +TestCase::TestCase() : m_result(0) +{ +} + +TestCase::~TestCase() +{ + delete m_result; +} + +TestResult::List TestCase::execute(const ExecutionStage stage, + TestSuite *) +{ + if(name() == QLatin1String("Constr-cont-document-3")) + { + TestResult::List result; + result.append(createTestResult(TestResult::Fail, QLatin1String("Skipped this test, because we loop infinitely on it."))); + return result; + } + else if(name() == QLatin1String("Axes089")) + { + TestResult::List result; + result.append(createTestResult(TestResult::Fail, QLatin1String("Skipped this test, we crash on it."))); + return result; + } + + qDebug() << "Running test case: " << name(); + + return execute(stage); + + Q_ASSERT(false); + return TestResult::List(); +} + +TestResult *TestCase::createTestResult(const TestResult::Status status, + const QString &comment) const +{ + TestResult *const result = new TestResult(name(), + status, + 0 /* We don't have an AST. */, + ErrorHandler::Message::List(), + QPatternist::Item::List(), + QString()); + result->setComment(comment); + return result; +} + +TestResult::List TestCase::execute(const ExecutionStage stage) +{ + ErrorHandler errHandler; + ErrorHandler::installQtMessageHandler(&errHandler); + + pDebug() << "TestCase::execute()"; + delete m_result; + + QXmlQuery query(language(), Global::namePoolAsPublic()); + + query.d->setExpressionFactory(s_exprFact); + query.setInitialTemplateName(initialTemplateName()); + + QXmlQuery openDoc(query.namePool()); + + if(contextItemSource().isValid()) + { + openDoc.setQuery(QString::fromLatin1("doc('") + contextItemSource().toString() + QLatin1String("')")); + Q_ASSERT(openDoc.isValid()); + QXmlResultItems result; + + openDoc.evaluateTo(&result); + const QXmlItem item(result.next()); + Q_ASSERT(!item.isNull()); + query.setFocus(item); + } + + TestResult::List retval; + + const Scenario scen(scenario()); + TestResult::Status resultStatus = TestResult::Unknown; + + bool ok = false; + const QString queryString(sourceCode(ok)); + + if(!ok) + { + /* Loading the query file failed, or similar. */ + resultStatus = TestResult::Fail; + + m_result = new TestResult(name(), resultStatus, s_exprFact->astTree(), + errHandler.messages(), QPatternist::Item::List(), QString()); + retval.append(m_result); + ErrorHandler::installQtMessageHandler(0); + changed(this); + return retval; + } + + query.setMessageHandler(&errHandler); + QXmlNamePool namePool(query.namePool()); + + /* Bind variables. */ + QPatternist::ExternalVariableLoader::Ptr loader(externalVariableLoader()); + if(loader) + { + Q_ASSERT(loader); + const ExternalSourceLoader::VariableMap vMap(static_cast<const ExternalSourceLoader *>(loader.data())->variableMap()); + const QStringList variables(vMap.keys()); + + for(int i = 0; i < variables.count(); ++i) + { + const QXmlName name(namePool, variables.at(i)); + const QXmlItem val(QPatternist::Item::toPublic(loader->evaluateSingleton(name, QPatternist::DynamicContext::Ptr()))); + query.bindVariable(name, val); + } + } + + /* We pass in the testCasePath(), such that the base URI is correct fort + * XSL-T stylesheets. */ + query.setQuery(queryString, testCasePath()); + + if(!query.isValid()) + { + pDebug() << "Got compilation exception."; + resultStatus = TestBaseLine::scanErrors(errHandler.messages(), baseLines()); + + Q_ASSERT(resultStatus != TestResult::Unknown); + m_result = new TestResult(name(), resultStatus, s_exprFact->astTree(), + errHandler.messages(), QPatternist::Item::List(), QString()); + retval.append(m_result); + ErrorHandler::installQtMessageHandler(0); + changed(this); + return retval; + } + + if(stage == CompileOnly) + { + m_result = new TestResult(name(), TestResult::Fail, s_exprFact->astTree(), + errHandler.messages(), QPatternist::Item::List(), QString()); + retval.append(m_result); + return retval; + } + + Q_ASSERT(stage == CompileAndRun); + + if(scen == ParseError) /* We're supposed to have received an error + at this point. */ + { + m_result = new TestResult(name(), TestResult::Fail, s_exprFact->astTree(), + errHandler.messages(), QPatternist::Item::List(), QString()); + ErrorHandler::installQtMessageHandler(0); + retval.append(m_result); + changed(this); + return retval; + } + + QPatternist::Item::List itemList; + + QByteArray output; + QBuffer buffer(&output); + buffer.open(QIODevice::WriteOnly); + + QXmlSerializer serializer(query, &buffer); + + pDebug() << "-------------------------- evaluateToPushCallback() ---------------------------- "; + const bool success = query.evaluateTo(&serializer); + pDebug() << "------------------------------------------------------------------------------------ "; + + buffer.close(); + + const QString serialized(QString::fromUtf8(output.constData(), output.size())); + + if(!success) + { + resultStatus = TestBaseLine::scanErrors(errHandler.messages(), baseLines()); + + Q_ASSERT(resultStatus != TestResult::Unknown); + m_result = new TestResult(name(), resultStatus, s_exprFact->astTree(), + errHandler.messages(), QPatternist::Item::List(), serialized); + retval.append(m_result); + ErrorHandler::installQtMessageHandler(0); + changed(this); + return retval; + } + + /* It's a regular test. */ + Q_ASSERT(scen == Standard || scen == RuntimeError); + + resultStatus = TestBaseLine::scan(serialized, baseLines()); + Q_ASSERT(resultStatus != TestResult::Unknown); + + /* Check that errHandler()->messages() at most only contains + * warnings, since it shouldn't have errors at this point. */ + const ErrorHandler::Message::List errors (errHandler.messages()); + const ErrorHandler::Message::List::const_iterator end(errors.constEnd()); + ErrorHandler::Message::List::const_iterator it(errors.constBegin()); + + for(; it != end; ++it) + { + const QtMsgType type = (*it).type(); + if(type == QtFatalMsg) + { + m_result = new TestResult(name(), TestResult::Fail, s_exprFact->astTree(), + errHandler.messages(), itemList, serialized); + retval.append(m_result); + ErrorHandler::installQtMessageHandler(0); + changed(this); + return retval; + } + } + + m_result = new TestResult(name(), resultStatus, s_exprFact->astTree(), + errHandler.messages(), itemList, serialized); + retval.append(m_result); + ErrorHandler::installQtMessageHandler(0); + changed(this); + return retval; +} + +TestCase::Scenario TestCase::scenarioFromString(const QString &string) +{ + if(string == QLatin1String("standard")) + return Standard; + else if(string == QLatin1String("parse-error")) + return ParseError; + else if(string == QLatin1String("runtime-error")) + return RuntimeError; + else if(string == QLatin1String("trivial")) + return Trivial; + else + { + Q_ASSERT_X(false, Q_FUNC_INFO, + qPrintable(QString::fromLatin1("Invalid string representation for the scenario-enum: %1").arg(string))); + return ParseError; /* Silence GCC. */ + } +} + +void TestCase::toXML(XMLWriter &receiver) const +{ + /* <test-case> */ + QXmlAttributes test_caseAtts; + test_caseAtts.append(QLatin1String("is-XPath2"), QString(), + QLatin1String("is-XPath2"), isXPath() ? QLatin1String("true") + : QLatin1String("false")); + test_caseAtts.append(QLatin1String("name"), QString(), QLatin1String("name"), name()); + test_caseAtts.append(QLatin1String("creator"), QString(), QLatin1String("creator"), creator()); + QString scen; + switch(scenario()) + { + case Standard: + { + scen = QLatin1String("standard"); + break; + } + case ParseError: + { + scen = QLatin1String("parse-error"); + break; + } + case RuntimeError: + { + scen = QLatin1String("runtime-error"); + break; + } + case Trivial: + { + scen = QLatin1String("trivial"); + break; + } + default: /* includes 'AnyError' */ + Q_ASSERT(false); + } + test_caseAtts.append(QLatin1String("scenario"), QString(), QLatin1String("scenario"), scen); + test_caseAtts.append(QLatin1String(QLatin1String("FilePath")), QString(), + QLatin1String("FilePath"), QString()); + receiver.startElement(QLatin1String("test-case"), test_caseAtts); + + /* <description> */ + receiver.startElement(QLatin1String("description"), test_caseAtts); + receiver.characters(description()); + + /* </description> */ + receiver.endElement(QLatin1String("description")); + + /* <query> */ + QXmlAttributes queryAtts; + queryAtts.append(QLatin1String("date"), QString(), QLatin1String("date"), /* This date is a dummy. */ + QDate::currentDate().toString(Qt::ISODate)); + queryAtts.append(QLatin1String("name"), QString(), QLatin1String("name"), testCasePath().toString()); + receiver.startElement(QLatin1String("query"), queryAtts); + + /* </query> */ + receiver.endElement(QLatin1String("query")); + + /* Note: this is invalid, we don't add spec-citation. */ + TestBaseLine::List bls(baseLines()); + const TestBaseLine::List::const_iterator end(bls.constEnd()); + TestBaseLine::List::const_iterator it(bls.constBegin()); + + for(; it != end; ++it) + (*it)->toXML(receiver); + + /* </test-case> */ + receiver.endElement(QLatin1String("test-case")); +} + +QString TestCase::displayName(const Scenario scen) +{ + switch(scen) + { + case Standard: + return QLatin1String("Standard"); + case ParseError: + return QLatin1String("Parse Error"); + case RuntimeError: + return QLatin1String("Runtime Error"); + case Trivial: + return QLatin1String("Trivial"); + case AnyError: + { + Q_ASSERT(false); + return QString(); + } + } + + Q_ASSERT(false); + return QString(); +} + +TestItem::ResultSummary TestCase::resultSummary() const +{ + if(m_result) + return ResultSummary(m_result->status() == TestResult::Pass ? 1 : 0, + 1); + + return ResultSummary(0, 1); +} + +void TestCase::appendChild(TreeItem *) +{ + Q_ASSERT_X(false, Q_FUNC_INFO, "Makes no sense to call appendChild() for TestCase."); +} + +TreeItem *TestCase::child(const unsigned int) const +{ + return 0; /* Silence GCC */ +} + +TreeItem::List TestCase::children() const +{ + return TreeItem::List(); +} + +unsigned int TestCase::childCount() const +{ + return 0; +} + +TestResult *TestCase::testResult() const +{ + return m_result; +} + +bool TestCase::isFinalNode() const +{ + return true; +} + +QXmlQuery::QueryLanguage TestCase::language() const +{ + return QXmlQuery::XQuery10; +} + +QXmlName TestCase::initialTemplateName() const +{ + return QXmlName(); +} + +// vim: et:ts=4:sw=4:sts=4 + diff --git a/tests/auto/xmlpatternssdk/TestCase.h b/tests/auto/xmlpatternssdk/TestCase.h new file mode 100644 index 0000000..28df5f1 --- /dev/null +++ b/tests/auto/xmlpatternssdk/TestCase.h @@ -0,0 +1,256 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PatternistSDK_TestCase_H +#define PatternistSDK_TestCase_H + +#include <QtXmlPatterns/QXmlQuery> + +#include "qexternalvariableloader_p.h" + +#include "ErrorHandler.h" +#include "TestBaseLine.h" +#include "Global.h" + +#include "TestItem.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QDate; +class QString; +class QUrl; + +namespace QPatternistSDK +{ + class XMLWriter; + + /** + * @short A generic abstract base class for test cases. + * + * @ingroup PatternistSDK + * @author Frans Englich <frans.englich@nokia.com> + */ + class Q_PATTERNISTSDK_EXPORT TestCase : public TestItem + { + public: + /** + * Corresponds to the simpleType test:scenarios-enum + */ + enum Scenario + { + /** + * The test case should evaluate normally and that the output + * should match the supplied base line. + */ + Standard = 1, + + /** + * The test case should result in a static error, a parser error. + */ + ParseError = 2, + + /** + * The test case should result in a dynamic error, a runtime error. + */ + RuntimeError = 4, + + Trivial = 8, + + /** + * ParseError and RuntimeError OR'd. + */ + AnyError = RuntimeError | ParseError + + }; + + TestCase(); + virtual ~TestCase(); + + /** + * Executes the test, and returns the result. The returned list + * will always contain exactly one TestResult. + * + * @p stage is ignored when running out-of-process. + */ + virtual TestResult::List execute(const ExecutionStage stage, + TestSuite *ts); + + /** + * Determines the corresponding Scenario enumerator from the string + * representation @p string. + * + * The following mappings are in effect: + * @arg @c Standard "standard" + * @arg @c ParseError "parse-error" + * @arg @c RuntimeError "runtime-error" + */ + static Scenario scenarioFromString(const QString &string); + + /** + * @return always @c true + */ + virtual bool isFinalNode() const; + + /** + * Calling this function makes no sense, so it always + * performs an Q_ASSERT check. + */ + virtual void appendChild(TreeItem *); + + /** + * Calling this function makes no sense, so it always + * performs an Q_ASSERT check. + */ + virtual TreeItem *child(const unsigned int) const; + + /** + * @return always zero + */ + virtual unsigned int childCount() const; + + /** + * @return always an empty list. + */ + virtual TreeItem::List children() const; + + /** + * A description of the test case for human consumption. + */ + virtual QString description() const = 0; + + /** + * The title of the test. This can be the identifier of the test, for example. + */ + virtual QString title() const = 0; + + /** + * Whether this test case only make use of XPath features. + * + * @returns @c false if the test case exercises any XQuery feature + * which is not available in XPath 2.0. + */ + virtual bool isXPath() const = 0; + + /** + * The full name of the creator of the test case. For example, "Frans Englich". + */ + virtual QString creator() const = 0; + + /** + * The date of when the test case was created or last modified. + */ + virtual QDate lastModified() const = 0; + + /** + * The test's source code. That is, the XPath/XQuery code for the test. + * + * @param ok the function sets this value to @c false if loading the query + * failed, and returns a description of the error for human consumption. If + * everything went ok, @p ok is set to @c true, and the query is returned. + */ + virtual QString sourceCode(bool &ok) const = 0; + + /** + * The path to the file containing the code of the test case. + */ + virtual QUrl testCasePath() const = 0; + + /** + * The test case's identifier. For example, "Literals001". + */ + virtual QString name() const = 0; + + /** + * What kind of test this is. For example, whether the test case + * should result in a parser error or should evaluate without errors. + * + * The vast common case is that one Scenario is returned; the bit signifiance + * is for the TestCase sub-class UserTestCase. + */ + virtual Scenario scenario() const = 0; + + static QString displayName(const Scenario scen); + + /** + * @returns the valid test baselines for this test case. If only + * one outcome is valid, the returned list only contains + * that baseline. + */ + virtual TestBaseLine::List baseLines() const = 0; + + virtual TestResult *testResult() const; + + virtual ResultSummary resultSummary() const; + + void toXML(XMLWriter &receiver) const; + + virtual QPatternist::ExternalVariableLoader::Ptr externalVariableLoader() const = 0; + + /** + * @short The XML document that should be used as focus. If none should + * be used, and hence the focus be undefined, a default constructed + * QUrl is returned. + */ + virtual QUrl contextItemSource() const = 0; + + /** + * Returns by default QXmlQuery::XQuery10. + */ + virtual QXmlQuery::QueryLanguage language() const; + + virtual QXmlName initialTemplateName() const; + private: + TestResult::List execute(const ExecutionStage stage); + TestResult *createTestResult(const TestResult::Status status, + const QString &comment) const; + + QPointer<TestResult> m_result; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/TestContainer.cpp b/tests/auto/xmlpatternssdk/TestContainer.cpp new file mode 100644 index 0000000..ec6196c --- /dev/null +++ b/tests/auto/xmlpatternssdk/TestContainer.cpp @@ -0,0 +1,151 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QPair> +#include <QtDebug> + +#include "TestContainer.h" + +using namespace QPatternistSDK; + +TestContainer::TestContainer() : m_deleteChildren(true) +{ +} + +TestContainer::~TestContainer() +{ + if(m_deleteChildren) + qDeleteAll(m_children); +} + +TestResult::List TestContainer::execute(const ExecutionStage stage, + TestSuite *ts) +{ + Q_ASSERT(ts); + const unsigned int c = m_children.count(); + TestResult::List result; + + for(unsigned int i = 0; i != c; ++i) + result += static_cast<TestItem *>(child(i))->execute(stage, ts); + + return result; +} + +TestItem::ResultSummary TestContainer::resultSummary() const +{ + const int c = childCount(); + int total = 0; + int pass = 0; + + for(int i = 0; i != c; ++i) + { + TestItem *t = static_cast<TestItem *>(child(i)); + const ResultSummary sum(t->resultSummary()); + pass += sum.first; + total += sum.second; + } + + return ResultSummary(pass, total); +} + +TreeItem::List TestContainer::children() const +{ + return m_children; +} + +void TestContainer::appendChild(TreeItem *item) +{ + /* When one of our children changes, we changes. */ + connect(item, SIGNAL(changed(TreeItem *)), SIGNAL(changed(TreeItem *))); + m_children.append(item); +} + +TreeItem *TestContainer::child(const unsigned int rowP) const +{ + return m_children.value(rowP); +} + +unsigned int TestContainer::childCount() const +{ + return m_children.count(); +} + +void TestContainer::setTitle(const QString &titleP) +{ + m_title = titleP; +} + +QString TestContainer::title() const +{ + return m_title; +} + +bool TestContainer::isFinalNode() const +{ + return false; +} + +int TestContainer::columnCount() const +{ + return 4; +} + +QString TestContainer::description() const +{ + return m_description; +} + +void TestContainer::setDescription(const QString &desc) +{ + m_description = desc; +} + +void TestContainer::setDeleteChildren(const bool val) +{ + m_deleteChildren = val; +} + +void TestContainer::removeLast() +{ + m_children.removeLast(); +} + +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/TestContainer.h b/tests/auto/xmlpatternssdk/TestContainer.h new file mode 100644 index 0000000..5b93491 --- /dev/null +++ b/tests/auto/xmlpatternssdk/TestContainer.h @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PatternistSDK_TestContainer_H +#define PatternistSDK_TestContainer_H + +#include "Global.h" +#include "TestItem.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternistSDK +{ + /** + * @short an abstract base class, containing + * an appropriate implementation of TestItem for sub-classes + * which can contain other TestItem instances. + * + * @ingroup PatternistSDK + * @author Frans Englich <frans.englich@nokia.com> + */ + class Q_PATTERNISTSDK_EXPORT TestContainer : public TestItem + { + public: + virtual ~TestContainer(); + virtual void appendChild(TreeItem *item); + virtual TreeItem *child(const unsigned int row) const; + virtual unsigned int childCount() const; + + /** + * @returns the TestResults of this TestContainer's children. + */ + virtual TestResult::List execute(const ExecutionStage stage, + TestSuite *ts); + + QString title() const; + void setTitle(const QString &title); + + virtual TreeItem::List children() const; + + /** + * @return always 2 + */ + virtual int columnCount() const; + + virtual bool isFinalNode() const; + + virtual ResultSummary resultSummary() const; + virtual QString description() const; + virtual void setDescription(const QString &desc); + + /** + * Determines whether TestContainer will delete its children upon + * destruction. By default, it will. + */ + void setDeleteChildren(const bool val); + + /** + * Removes the last appended child. + */ + void removeLast(); + + protected: + /** + * Constructor, protected. TestContainer is an abstract class, + * and is not ment to be instantiated, but sub classed. + */ + TestContainer(); + + private: + TreeItem::List m_children; + QString m_title; + QString m_description; + bool m_deleteChildren; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/TestGroup.cpp b/tests/auto/xmlpatternssdk/TestGroup.cpp new file mode 100644 index 0000000..f2cd2bd --- /dev/null +++ b/tests/auto/xmlpatternssdk/TestGroup.cpp @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QColor> +#include <QPair> +#include <QVariant> + +#include "TestGroup.h" + +using namespace QPatternistSDK; + +TestGroup::TestGroup(TreeItem *p) : m_parent(p) +{ +} + +QVariant TestGroup::data(const Qt::ItemDataRole role, int column) const +{ + if(role != Qt::DisplayRole && role != Qt::BackgroundRole && role != Qt::ToolTipRole) + return QVariant(); + + /* In ResultSummary, the first is the amount of passes and the second is the total. */ + const ResultSummary sum(resultSummary()); + const int failures = sum.second - sum.first; + + switch(role) + { + case Qt::DisplayRole: + { + + switch(column) + { + case 0: + return title(); + case 1: + /* Passes. */ + return QString::number(sum.first); + case 2: + /* Failures. */ + return QString::number(failures); + case 3: + /* Total. */ + return QString::number(sum.second); + default: + { + Q_ASSERT(false); + return QString(); + } + } + } + case Qt::BackgroundRole: + { + switch(column) + { + case 1: + { + if(sum.first) + { + /* Pass. */ + return Qt::green; + } + else + return QVariant(); + } + case 2: + { + if(failures) + { + /* Failure. */ + return Qt::red; + } + else + return QVariant(); + } + default: + return QVariant(); + } + } + case Qt::ToolTipRole: + { + return description(); + } + default: + { + Q_ASSERT_X(false, Q_FUNC_INFO, "This shouldn't be reached"); + return QVariant(); + } + } +} + +void TestGroup::setNote(const QString &n) +{ + m_note = n; +} + +QString TestGroup::note() const +{ + return m_note; +} + +TreeItem *TestGroup::parent() const +{ + return m_parent; +} + +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/TestGroup.h b/tests/auto/xmlpatternssdk/TestGroup.h new file mode 100644 index 0000000..5f4798f --- /dev/null +++ b/tests/auto/xmlpatternssdk/TestGroup.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PatternistSDK_TestGroup_H +#define PatternistSDK_TestGroup_H + +#include <QString> + +#include "TestContainer.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternistSDK +{ + /** + * @short Groups test groups and test cases into a group. + * + * TestGroup corresponds to the @c test-group element in XQTSCatalog.xsd. + * + * @ingroup PatternistSDK + * @author Frans Englich <frans.englich@nokia.com> + */ + class Q_PATTERNISTSDK_EXPORT TestGroup : public TestContainer + { + public: + TestGroup(TreeItem *parent); + + /** + * @returns the parent of this group. Is either another group, or + * the TestSuite instance governing this tree. + */ + virtual TreeItem *parent() const; + + virtual QVariant data(const Qt::ItemDataRole role, int column) const; + + QString note() const; + + void setName(const QString &name); + void setNote(const QString ¬e); + + private: + QString m_name; + QString m_note; + TreeItem *m_parent; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/TestItem.h b/tests/auto/xmlpatternssdk/TestItem.h new file mode 100644 index 0000000..0b3c606 --- /dev/null +++ b/tests/auto/xmlpatternssdk/TestItem.h @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PatternistSDK_TestItem_H +#define PatternistSDK_TestItem_H + +#include "TestResult.h" +#include "TreeItem.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +template<typename A, typename B> struct QPair; + +namespace QPatternistSDK +{ + class XMLWriter; + class TestSuite; + + /** + * @short base class for all classes which + * represent an element in an XQuery Test Suite catalog. + * + * @ingroup PatternistSDK + * @author Frans Englich <frans.englich@nokia.com> + */ + class Q_PATTERNISTSDK_EXPORT TestItem : public TreeItem + { + public: + + /** + * Determines how far an test case execution should go. + */ + enum ExecutionStage + { + /** + * The query will not be run. It will only go through the (whole) compilation stage. + */ + CompileOnly = 1, + + /** + * The query will be compiled and run, as ordinary. + */ + CompileAndRun + }; + + /** + * Represents a summary of test results for a collection + * of tests. QPair::first contains the amount of + * passed tests; QPair::second contains the count of + * all tests. For example TestCase::summary() returns + * ResultSummary(0, 1) or ResultSummary(1, 1) depending + * on whether the TestCase have succeeded or not. + */ + typedef QPair<int, int> ResultSummary; + + /** + * Executes the test case(s) this TestItem represents, + * and return the TestResult. For example, the TestGroup + * returns the result of its children concatenated, while + * TestCase always returns a list containing one + * TestResult(what it evaluated to). + */ + virtual TestResult::List execute(const ExecutionStage stage, + TestSuite *ts) = 0; + + /** + * @todo Rename this function. Perhaps create a type() hierarchy + * instead. + */ + virtual bool isFinalNode() const = 0; + + /** + * @returns a ResultSummary for this TestItem. + */ + virtual ResultSummary resultSummary() const = 0; + + /** + * Serializes into the corresponding elements attributes + * specified in XQTSCatalog.xsd. + * + * @note Sub-classes must assume the XQTSCatalog namespace + * is the default namespace, and not add any namespace declarations. + */ + //virtual void toXML(XMLWriter &receiver) const = 0; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/TestResult.cpp b/tests/auto/xmlpatternssdk/TestResult.cpp new file mode 100644 index 0000000..2374bc0 --- /dev/null +++ b/tests/auto/xmlpatternssdk/TestResult.cpp @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QXmlAttributes> +#include <QtDebug> + +#include "qdebug_p.h" +#include "Global.h" +#include "XMLWriter.h" + +#include "TestResult.h" + +using namespace QPatternistSDK; +using namespace QPatternist; + +QString TestResult::displayName(const TestResult::Status stat) +{ + switch(stat) + { + case Pass: + return QLatin1String("pass"); + case Fail: + return QLatin1String("fail"); + case NotTested: + return QLatin1String("not tested"); + case Unknown: + Q_ASSERT(false); + } + + Q_ASSERT(false); + return QString(); +} + +TestResult::Status TestResult::statusFromString(const QString &string) +{ + if(string == QLatin1String("pass")) + return Pass; + else if(string == QLatin1String("fail")) + return Fail; + else if(string == QLatin1String("not tested")) + return NotTested; + else + { + Q_ASSERT(false); + return Fail; + } +} + +TestResult::TestResult(const QString &n, + const Status s, + ASTItem *tree, + const ErrorHandler::Message::List &ers, + const QPatternist::Item::List &itemsP, + const QString &serialized) : m_status(s), + m_messages(ers), + m_astTree(tree), + m_testName(n), + m_items(itemsP), + m_asSerialized(serialized) +{ + Q_ASSERT(!n.isEmpty()); + Q_ASSERT(s != 0); +} + +TestResult::~TestResult() +{ + delete m_astTree; +} + +void TestResult::toXML(XMLWriter &receiver) const +{ + QXmlAttributes atts; + atts.append(QLatin1String("name"), QString(), QLatin1String("name"), m_testName); + atts.append(QLatin1String("result"), QString(), QLatin1String("result"), displayName(m_status)); + + if(!m_comment.isEmpty()) + atts.append(QLatin1String("comment"), QString(), QLatin1String("comment"), m_comment); + + receiver.startElement(QLatin1String("test-case"), atts); + receiver.endElement(QLatin1String("test-case")); +} + +void TestResult::setComment(const QString &comm) +{ + m_comment = comm; +} + +TestResult::Status TestResult::status() const +{ + return m_status; +} + +QString TestResult::comment() const +{ + return m_comment; +} + +ASTItem *TestResult::astTree() const +{ + return m_astTree; +} + +ErrorHandler::Message::List TestResult::messages() const +{ + return m_messages; +} + +QPatternist::Item::List TestResult::items() const +{ + return m_items; +} + +QString TestResult::asSerialized() const +{ + pDebug() << "asSerialized: " << m_asSerialized; + return m_asSerialized; +} + +// vim: et:ts=4:sw=4:sts=4 + diff --git a/tests/auto/xmlpatternssdk/TestResult.h b/tests/auto/xmlpatternssdk/TestResult.h new file mode 100644 index 0000000..6951f90 --- /dev/null +++ b/tests/auto/xmlpatternssdk/TestResult.h @@ -0,0 +1,179 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PatternistSDK_TestResult_H +#define PatternistSDK_TestResult_H + +#include <QList> +#include <QObject> +#include <QPointer> +#include <QString> + +#include <QtXmlPatterns/private/qitem_p.h> +#include "ErrorHandler.h" + +#include "ASTItem.h" + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternistSDK +{ + class ASTItem; + class XMLWriter; + + /** + * @short represents the result produced by running a test case. + * + * This information TestResult houses is: + * + * - The result status() of the run. Whether the test case succeeded or not, for example. + * - The astTree() which reflects the compiled test case + * - The messages issued when compiling and running the test case, retrievable via messages() + * - The data -- XPath Data Model items() -- the test case evaluated to, if any. + * + * @ingroup PatternistSDK + * @author Frans Englich <frans.englich@nokia.com> + */ + class Q_PATTERNISTSDK_EXPORT TestResult : public QObject + { + Q_OBJECT + + public: + enum Status + { + /** + * Used when the status is unknown. + */ + Unknown = 0, + + /** + * The test case passed. + */ + Pass, + + /** + * The test case failed. + */ + Fail, + + /** + * The test was not run. Similar to "SKIP". + */ + NotTested + }; + + /** + * A list of TestResult instances. + */ + typedef QList<QPointer<TestResult> > List; + + /** + * Constructs a TestResult. + * + * @param testName the name of the test. For example, @c Literal-001. + * @param astTree may be @c null, signalling no AST being available, or point to one. + * @param status the result status of running the test-case. Whether the test-case + * passed or failed, and so forth. + * @param errors the errors and warnings that were reported while running the test-case + * @param items the XDM items that were outputted, if any + * @param serialized the output when serialized + */ + TestResult(const QString &testName, + const Status status, + ASTItem *astTree, + const ErrorHandler::Message::List &errors, + const QPatternist::Item::List &items, + const QString &serialized); + + virtual ~TestResult(); + + Status status() const; + + QString comment() const; + void setComment(const QString &comment); + + QPatternist::Item::List items() const; + + ErrorHandler::Message::List messages() const; + + /** + * Serializes itself to @p receiver, into a test-case element, + * as per @c XQTSResult.xsd. + */ + void toXML(XMLWriter &receiver) const; + + ASTItem *astTree() const; + + /** + * @returns a string representation for @p status, as per the anonymous + * type inside the type test-case, in @c XQTSResult.xsd. For example, if @p status + * is NotTested, is "not tested" returned. + */ + static QString displayName(const TestResult::Status status); + + static Status statusFromString(const QString &string); + + /** + * @returns the output of this test result(if any) as when + * being serialized. + */ + QString asSerialized() const; + + private: + const Status m_status; + QString m_comment; + const ErrorHandler::Message::List m_messages; + QPointer<ASTItem> m_astTree; + QString m_testName; + const QPatternist::Item::List m_items; + const QString m_asSerialized; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/TestResultHandler.cpp b/tests/auto/xmlpatternssdk/TestResultHandler.cpp new file mode 100644 index 0000000..b87d481 --- /dev/null +++ b/tests/auto/xmlpatternssdk/TestResultHandler.cpp @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtDebug> + +#include "Global.h" + +#include "TestResultHandler.h" + +using namespace QPatternistSDK; + +TestResultHandler::TestResultHandler() +{ + /* Fifteen thousand. When finished, we squeeze them. */ + m_result.reserve(15000); + m_comments.reserve(1000); /* Comments are only used for stuff that crash, more or less. */ +} + +bool TestResultHandler::startElement(const QString &namespaceURI, + const QString &localName, + const QString &, + const QXmlAttributes &atts) +{ + /* We only care about 'test-case', ignore everything else. */ + if(localName != QLatin1String("test-case") || + namespaceURI != Global::xqtsResultNS) + return true; + + /* The 'comments' attribute is optional. */ + Q_ASSERT_X(atts.count() == 2 || atts.count() == 3, Q_FUNC_INFO, + "The input appears to not conform to XQTSResult.xsd"); + + Q_ASSERT_X(!m_result.contains(atts.value(QLatin1String("name"))), + Q_FUNC_INFO, + qPrintable(QString::fromLatin1("A test result for test case %1 has " + "already been read(duplicate entry it seems).").arg(atts.value(QLatin1String("name"))))); + + m_result.insert(atts.value(0), TestResult::statusFromString(atts.value(QLatin1String("result")))); + + return true; +} + +bool TestResultHandler::endDocument() +{ + m_result.squeeze(); + m_comments.squeeze(); + return true; +} + +TestResultHandler::Hash TestResultHandler::result() const +{ + return m_result; +} + +TestResultHandler::CommentHash TestResultHandler::comments() const +{ + return m_comments; +} + +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/TestResultHandler.h b/tests/auto/xmlpatternssdk/TestResultHandler.h new file mode 100644 index 0000000..a786ac4 --- /dev/null +++ b/tests/auto/xmlpatternssdk/TestResultHandler.h @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PatternistSDK_TestResultHandler_H +#define PatternistSDK_TestResultHandler_H + +#include <QHash> +#include <QString> +#include <QtXml/QXmlDefaultHandler> + +#include "TestResult.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternistSDK +{ + /** + * @short Reads XML in the @c XQTSResult.xsd format, and provides access to + * the reported results. + * + * @author Frans Englich <frans.englich@nokia.com> + * @ingroup PatternistSDK + */ + class Q_PATTERNISTSDK_EXPORT TestResultHandler : public QXmlDefaultHandler + { + public: + /** + * A hash where the key is the class's name, that is <tt>test-case/@@name</tt>, + * and the value the test's result status. + */ + typedef QHash<QString, TestResult::Status> Hash; + + /** + * A hash mapping test-case names to their' comments. + */ + typedef QHash<QString, QString> CommentHash; + + /** + * Creates a TestResultHandler that will read @p file when run() is called. + */ + TestResultHandler(); + + /** + * Performs finalization. + */ + virtual bool endDocument(); + + /** + * Reads the <tt>test-case</tt> element and its attributes, everything else is ignored. + */ + virtual bool startElement(const QString &namespaceURI, + const QString &localName, + const QString &qName, + const QXmlAttributes &atts); + /** + * @note Do not reimplement this function. + * @returns the result obtained from reading the XML file. + */ + Hash result() const; + + CommentHash comments() const; + + private: + Q_DISABLE_COPY(TestResultHandler) + Hash m_result; + CommentHash m_comments; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/TestSuite.cpp b/tests/auto/xmlpatternssdk/TestSuite.cpp new file mode 100644 index 0000000..2c3e49c --- /dev/null +++ b/tests/auto/xmlpatternssdk/TestSuite.cpp @@ -0,0 +1,269 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QFileInfo> +#include <QVariant> +#include <QXmlInputSource> +#include <QXmlSimpleReader> +#include <QtDebug> + +#include "Global.h" +#include "TestSuiteHandler.h" +#include "TestSuiteResult.h" +#include "XMLWriter.h" +#include "XSLTTestSuiteHandler.h" +#include "XSDTestSuiteHandler.h" +#include "qdebug_p.h" + +#include "TestSuite.h" + +using namespace QPatternistSDK; +using namespace QPatternist; + +TestSuite::TestSuite() +{ +} + +QVariant TestSuite::data(const Qt::ItemDataRole role, int column) const +{ + if(role != Qt::DisplayRole) + return QVariant(); + + switch(column) + { + case 0: + return title(); + case 1: + return QString(); + default: + { + Q_ASSERT(false); + return QString(); + } + } +} + +TestSuiteResult *TestSuite::runSuite() +{ + const QDate date(QDate::currentDate()); + TestResult::List result(execute(CompileAndRun, this)); + + return new TestSuiteResult(version(), date, result); +} + +TestSuite *TestSuite::openCatalog(const QUrl &catalogURI, + QString &errorMsg, + const bool useExclusionList, + SuiteType suiteType) +{ + pDebug() << "Opening catalog:" << catalogURI.toString(); + QFile ts(catalogURI.toLocalFile()); + Q_ASSERT(catalogURI.isValid()); + + if(!ts.exists()) + { + errorMsg = QString::fromLatin1("The test suite catalog \"%1\" could not be found.\n") + .arg(ts.fileName()); + return 0; + } + + const QFileInfo info(ts); + + if(!info.isReadable()) + { + errorMsg = QString::fromLatin1("Cannot read the test suite catalog.\n"); + return 0; + } + else if(!info.isFile()) + { + errorMsg = QString::fromLatin1("The specified test suite catalog \"%1\" is not a file. " + "The test suite catalog must be a file, it cannot be " + "a directory, for example.\n") + .arg(ts.fileName()); + return 0; + } + else if(!ts.open(QIODevice::ReadOnly | QIODevice::Text)) + { + errorMsg = QString::fromLatin1("Failed to open the test suite catalog, \"%1\".\n") + .arg(ts.fileName()); + return 0; + } + + return openCatalog(&ts, errorMsg, catalogURI, useExclusionList, suiteType); +} + +TestSuite *TestSuite::openCatalog(QIODevice *input, + QString &errorMsg, + const QUrl &fileName, + const bool useExclusionList, + SuiteType suiteType) +{ + Q_ASSERT(input); + + QXmlSimpleReader reader; + typedef QPatternist::AutoPtr<QXmlDefaultHandler> HandlerPtr; + + HandlerPtr loader; + + switch (suiteType) { + case XQuerySuite: loader = HandlerPtr(new TestSuiteHandler(fileName, useExclusionList)); break; + case XsltSuite: loader = HandlerPtr(new XSLTTestSuiteHandler(fileName)); break; + case XsdSuite: loader = HandlerPtr(new XSDTestSuiteHandler(fileName)); break; + default: Q_ASSERT(false); break; + } + + reader.setContentHandler(loader.data()); + + QXmlInputSource source(input); + + if(!reader.parse(source)) + { + errorMsg = QString::fromLatin1("Couldn't parse %1").arg(fileName.toString()); + return 0; + } + + TestSuite *suite = 0; + switch (suiteType) { + case XQuerySuite: suite = static_cast<TestSuiteHandler *>(loader.data())->testSuite(); break; + case XsltSuite: suite = static_cast<XSLTTestSuiteHandler *>(loader.data())->testSuite(); break; + case XsdSuite: suite = static_cast<XSDTestSuiteHandler *>(loader.data())->testSuite(); break; + default: Q_ASSERT(false); break; + } + + if(suite) + return suite; + + errorMsg = QString::fromLatin1("Failed to load \"%1\". " + "It appears to have no test-suite element.\n").arg(fileName.toString()); + return 0; +} + +void TestSuite::toXML(XMLWriter &receiver, TestCase *const tc) const +{ + // TODO startElement() endElement() calls can be simplified. + + Q_ASSERT(tc); + + receiver.startDocument(); + /* <test-suite> */ + QXmlAttributes test_suiteAtts; + test_suiteAtts.append(QLatin1String("CatalogDesignDate"), QString(), + QLatin1String("CatalogDesignDate"), m_designDate.toString(Qt::ISODate)); + test_suiteAtts.append(QLatin1String("version"), QString(), + QLatin1String("version"), m_version); + test_suiteAtts.append(QLatin1String("SourceOffsetPath"), QString(), + QLatin1String("SourceOffsetPath"), QString()); + test_suiteAtts.append(QLatin1String("ResultOffsetPath"), QString(), + QLatin1String("ResultOffsetPath"), QString()); + test_suiteAtts.append(QLatin1String("XQueryQueryOffsetPath"), QString(), + QLatin1String("XQueryQueryOffsetPath"), QString()); + test_suiteAtts.append(QLatin1String("QueryXQueryOffsetPath"), QString(), + QLatin1String("QueryXQueryOffsetPath"), QString()); + test_suiteAtts.append(QLatin1String("XQueryFileExtension"), QString(), + QLatin1String("XQueryFileExtension"), QString()); + test_suiteAtts.append(QLatin1String("XQueryXFileExtension"), QString(), + QLatin1String("XQueryXFileExtension"), QString()); + + receiver.startPrefixMapping(QString(), Global::xqtsCatalogNS); + receiver.startElement(QLatin1String("test-suite"), test_suiteAtts); + receiver.endPrefixMapping(QString()); + + /* <test-group> */ + QXmlAttributes test_groupAtts; + test_groupAtts.append(QLatin1String("GeneratedGroupByPatternistSDKRunSuite"), QString(), + QLatin1String("GeneratedGroupByPatternistSDKRunSuite"), QString()); + receiver.startElement(QLatin1String("test-group"), test_groupAtts); + + /* <GroupInfo> */ + receiver.startElement(QLatin1String("GroupInfo"), test_groupAtts); + + /* <title> */ + receiver.startElement(QLatin1String("title"), test_groupAtts); + receiver.characters(QLatin1String("Contains the test case generated by PatternistSDKRunSuite.")); + + /* </title> */ + receiver.endElement(QLatin1String("title")); + + /* <description> */ + receiver.startElement(QLatin1String("description"), test_groupAtts); + /* </description> */ + receiver.endElement(QLatin1String("description")); + + /* </GroupInfo> */ + receiver.endElement(QLatin1String("GroupInfo")); + + /* <test-case> */ + tc->toXML(receiver); + /* </test-case> */ + + /* </test-group> */ + receiver.endElement(QLatin1String("test-group")); + + /* </test-suite> */ + receiver.endElement(QLatin1String("test-suite")); +} + +QString TestSuite::version() const +{ + return m_version; +} + +QDate TestSuite::designDate() const +{ + return m_designDate; +} + +void TestSuite::setVersion(const QString &ver) +{ + m_version = ver; +} + +void TestSuite::setDesignDate(const QDate &date) +{ + m_designDate = date; +} + +TestContainer *TestSuite::parent() const +{ + return 0; +} + +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/TestSuite.h b/tests/auto/xmlpatternssdk/TestSuite.h new file mode 100644 index 0000000..d14dc62 --- /dev/null +++ b/tests/auto/xmlpatternssdk/TestSuite.h @@ -0,0 +1,160 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PatternistSDK_TestSuite_H +#define PatternistSDK_TestSuite_H + +#include <QDate> +#include <QString> + +#include "TestContainer.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QIODevice; +class QUrl; +class QVariant; + +namespace QPatternistSDK +{ + class TestCase; + class TestSuiteResult; + + /** + * @short Represents a test suite in the W3C XML Query Test Suite format. + * + * TestSuite contains the test suite's test cases and meta data. + * + * @ingroup PatternistSDK + * @author Frans Englich <frans.englich@nokia.com> + */ + class Q_PATTERNISTSDK_EXPORT TestSuite : public TestContainer + { + public: + /** + * Describes the type of test suite. + */ + enum SuiteType + { + XQuerySuite, ///< The test suite for XQuery + XsltSuite, ///< The test suite for XSLT + XsdSuite ///< The test suite for XML Schema + }; + + TestSuite(); + + virtual QVariant data(const Qt::ItemDataRole role, int column) const; + + /** + * The version of the catalog test suite. For example, "0.8.0". + */ + QString version() const; + + /** + * When the catalog was designed, last modified. + */ + QDate designDate() const; + + void setVersion(const QString &version); + void setDesignDate(const QDate &version); + + /** + * @return always @c null + */ + virtual TestContainer *parent() const; + + /** + * Creates and returns a pointer to a TestSuite instance, which + * was instantiated from the XQuery Test Suite catalog file @p catalogFile. + * + * If loading went wrong, @c null is returned and @p errorMsg is set with a + * human readable message string. However, @p catalogFile is not validated; + * if the XML file is not valid against the XQTS task force's W3C XML Schema, the + * behavior and result for this function is undefined. + * + * This function blocks. Currently is only local files supported. + */ + static TestSuite *openCatalog(const QUrl &catalogFile, + QString &errorMsg, + const bool useExclusionList, + SuiteType type); + + void toXML(XMLWriter &receiver, TestCase *const tc) const; + + /** + * Evaluates all the test cases in this TestSuite, and returns + * it all in a TestSuiteResult. + */ + TestSuiteResult *runSuite(); + + private: + /** + * Essentially similar to open(const QUrl &, QString &errorMsg), + * with the difference that it takes directly a QIODevice as input, + * as opposed to a file name locating the catalog file to read. + * + * @param input the test suite catalog + * @param fileName this URI is used for resolving relative paths inside + * the catalog file into absolute. + * @param errorMsg if an error occurs, this QString is set to contain the message. + * Whether an error occurred can therefore be determined by checking if this variable + * still is @c null after the call + * @param useExclusionList whether the excludeTestGroups.txt file should be used + * to exclude test groups for this catalog + */ + static TestSuite *openCatalog(QIODevice *input, + QString &errorMsg, + const QUrl &fileName, + const bool useExclusionList, + SuiteType type); + QString m_version; + QDate m_designDate; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/TestSuiteHandler.cpp b/tests/auto/xmlpatternssdk/TestSuiteHandler.cpp new file mode 100644 index 0000000..7c687f3 --- /dev/null +++ b/tests/auto/xmlpatternssdk/TestSuiteHandler.cpp @@ -0,0 +1,312 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtDebug> + +#include "qacceltreeresourceloader_p.h" +#include "qnetworkaccessdelegator_p.h" + +#include "Global.h" +#include "TestBaseLine.h" +#include "TestGroup.h" + +#include "TestSuiteHandler.h" + +using namespace QPatternistSDK; + +QNetworkAccessManager s_networkManager; + +TestSuiteHandler::TestSuiteHandler(const QUrl &catalogFile, + const bool useEList) : m_ts(0) + , m_container(0) + , m_tc(0) + , m_baseLine(0) + , m_catalogFile(catalogFile) + , m_exclusionList(readExclusionList(useEList)) + , m_isExcluding(false) +{ + Q_ASSERT(!m_catalogFile.isRelative()); +} + +QStringList TestSuiteHandler::readExclusionList(const bool useExclusionList) const +{ + if(!useExclusionList) + return QStringList(); + + QStringList avoid; + + /* These test groups are for features we don't support. + * + * Originally these were stored in a text file pulled in with Qt resources, but + * it was not possible to get it to link on some HP-UX and Intel-icc platforms. */ + + avoid << "SchemaImport"; // The schema import feature + avoid << "SchemaValidation"; // The validate expression(requires schema import) + avoid << "StaticTyping"; // Pessimistic static typing checking + avoid << "TrivialEmbedding"; // XQueryX inside XQuery + avoid << "XMark"; // We're currently too buggy for running these tests. + + return avoid; +} + +bool TestSuiteHandler::startElement(const QString &namespaceURI, + const QString &localName, + const QString &/*qName*/, + const QXmlAttributes &atts) +{ + if(namespaceURI != Global::xqtsCatalogNS) + return true; + else if(m_isExcluding) + { + if(localName == QLatin1String("test-group")) + { + m_testGroupName.push(atts.value(QLatin1String("name"))); + return true; + } + else + return true; + } + + /* The elements are handled roughly in the order of highest occurrence in the catalog file. */ + if(localName == QLatin1String("test-case")) + { + XQTSTestCase *const c = new XQTSTestCase( + TestCase::scenarioFromString(atts.value(QLatin1String("scenario"))), m_container); + + c->setName(atts.value(QLatin1String("name"))); + c->setCreator(atts.value(QLatin1String("Creator"))); + c->setIsXPath(Global::readBoolean(atts.value(QLatin1String("is-XPath2")))); + c->setLastModified(QDate::fromString(atts.value(QLatin1String("version-drop")), Qt::ISODate)); + Q_ASSERT(c->lastModified().isNull() || c->lastModified().isValid()); + + m_currentQueryPath = m_queryOffset.resolved(QUrl(atts.value(QLatin1String("FilePath")))); + m_currentBaselinePath = m_baselineOffset.resolved(QUrl(atts.value(QLatin1String("FilePath")))); + + m_container->appendChild(c); + m_tc = c; + } + else if(localName == QLatin1String("query")) + { + m_tc->setQueryPath(m_currentQueryPath.resolved(atts.value(QLatin1String("name")) + + m_xqueryFileExtension)); + } + else if(localName == QLatin1String("input-file") || + localName == QLatin1String("input-URI")) + { + m_currentInputVariable = atts.value(QLatin1String("variable")); + } + else if(localName == QLatin1String("output-file")) + { + m_baseLine = new TestBaseLine(TestBaseLine::identifierFromString(atts.value(QLatin1String("compare")))); + } + else if(localName == QLatin1String("expected-error")) + { + m_baseLine = new TestBaseLine(TestBaseLine::ExpectedError); + } + else if(localName == QLatin1String("test-group")) + { + m_testGroupName.push(atts.value(QLatin1String("name"))); + + if(m_exclusionList.contains(m_testGroupName.top())) + { + /* Ok, this group is supposed to be excluded, we don't + * insert it into the tree. */ + m_isExcluding = true; + return true; + } + else + { + Q_ASSERT(m_container); + TestGroup *const newGroup = new TestGroup(m_container); + m_container->appendChild(newGroup); + m_container = newGroup; + } + } + else if(localName == QLatin1String("source")) + { + m_sourceMap.insert(atts.value(QLatin1String("ID")), + m_sourceOffset.resolved(QUrl(atts.value(QLatin1String("FileName"))))); + } + else if(localName == QLatin1String("test-suite")) + { + m_ts = new TestSuite(); + m_ts->setVersion(atts.value(QLatin1String("version"))); + m_ts->setDesignDate(QDate::fromString(atts.value(QLatin1String("CatalogDesignDate")), Qt::ISODate)); + Q_ASSERT(m_ts->designDate().isValid()); + m_container = m_ts; + + m_xqueryFileExtension = atts.value(QLatin1String("XQueryFileExtension")); + m_queryOffset = m_catalogFile.resolved(atts.value(QLatin1String("XQueryQueryOffsetPath"))); + m_baselineOffset = m_catalogFile.resolved(atts.value(QLatin1String("ResultOffsetPath"))); + m_sourceOffset = m_catalogFile.resolved(atts.value(QLatin1String("SourceOffsetPath"))); + } + else if(localName == QLatin1String("input-query")) + { + m_tcSourceInputs.insert(atts.value(QLatin1String("variable")), + ExternalSourceLoader::VariableValue(m_currentQueryPath.resolved(atts.value(QLatin1String("name")) + m_xqueryFileExtension), + ExternalSourceLoader::Query)); + } + + return true; +} + +bool TestSuiteHandler::endElement(const QString &namespaceURI, + const QString &localName, + const QString &/*qName*/) +{ + if(namespaceURI != Global::xqtsCatalogNS) + return true; + + if(m_isExcluding) + { + if(localName == QLatin1String("test-group")) + { + const QString myName(m_testGroupName.pop()); + + if(m_exclusionList.contains(myName)) + { + /* This test-group is being excluded and now we're exiting from it. */ + m_isExcluding = false; + } + } + + 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 <test-case>, so the <description> belongs + * to the test-case. */ + m_tc->setDescription(m_ch.simplified()); + } + else + m_container->setDescription(m_ch.simplified()); + } + else if(localName == QLatin1String("test-case")) + { + Q_ASSERT(m_tc->baseLines().count() >= 1); + Q_ASSERT(m_resourceLoader); + m_tc->setExternalVariableLoader(QPatternist::ExternalVariableLoader::Ptr + (new ExternalSourceLoader(m_tcSourceInputs, + m_resourceLoader))); + m_tcSourceInputs.clear(); + + if(!m_contextItemSource.isEmpty()) + { + m_tc->setContextItemSource(QUrl(m_sourceMap.value(m_contextItemSource))); + m_contextItemSource.clear(); + } + + m_tc = 0; + } + else if(localName == QLatin1String("output-file")) + { + m_baseLine->setDetails(m_currentBaselinePath.resolved(m_ch).toString()); + m_tc->addBaseLine(m_baseLine); + } + else if(localName == QLatin1String("input-file")) + { + m_tcSourceInputs.insert(m_currentInputVariable, ExternalSourceLoader::VariableValue(m_sourceMap.value(m_ch), + ExternalSourceLoader::Document)); + } + else if(localName == QLatin1String("expected-error")) + { + m_baseLine->setDetails(m_ch); + m_tc->addBaseLine(m_baseLine); + } + else if(localName == QLatin1String("title")) + { + /* A bit dangerous, the only element with name title in the vocabulary + * is the the child of GroupInfo */ + m_container->setTitle(m_ch.simplified()); + } + else if(localName == QLatin1String("test-group")) + { + m_testGroupName.pop(); + Q_ASSERT(m_container); + m_container = static_cast<TestContainer *>(m_container->parent()); + Q_ASSERT(m_container); + } + else if(localName == QLatin1String("test-suite")) + { + Q_ASSERT(m_container); + m_container = static_cast<TestContainer *>(m_container->parent()); + } + else if(localName == QLatin1String("sources")) + { + const QPatternist::NetworkAccessDelegator::Ptr networkDelegator(new QPatternist::NetworkAccessDelegator(&s_networkManager, &s_networkManager)); + + m_resourceLoader = QPatternist::ResourceLoader::Ptr(new QPatternist::AccelTreeResourceLoader(Global::namePool(), + networkDelegator)); + + const ExternalSourceLoader::SourceMap::const_iterator end(m_sourceMap.constEnd()); + ExternalSourceLoader::SourceMap::const_iterator it(m_sourceMap.constBegin()); + + for(; it != end; ++it) + m_resourceLoader->announceDocument(it.value(), QPatternist::ResourceLoader::WillUse); + } + else if(localName == QLatin1String("input-URI")) + { + m_tcSourceInputs.insert(m_currentInputVariable, ExternalSourceLoader::VariableValue(m_sourceMap.value(m_ch), + ExternalSourceLoader::URI)); + } + else if(localName == QLatin1String("contextItem")) + m_contextItemSource = m_ch; + + return true; +} + +bool TestSuiteHandler::characters(const QString &ch) +{ + m_ch = ch; + return true; +} + +TestSuite *TestSuiteHandler::testSuite() const +{ + return m_ts; +} + +// vim: et:ts=4:sw=4:sts=4 + diff --git a/tests/auto/xmlpatternssdk/TestSuiteHandler.h b/tests/auto/xmlpatternssdk/TestSuiteHandler.h new file mode 100644 index 0000000..76156c0 --- /dev/null +++ b/tests/auto/xmlpatternssdk/TestSuiteHandler.h @@ -0,0 +1,169 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PatternistSDK_TestSuiteHandler_H +#define PatternistSDK_TestSuiteHandler_H + +#include <QStack> +#include <QUrl> +#include <QXmlDefaultHandler> + +#include "ExternalSourceLoader.h" +#include "TestSuite.h" +#include "XQTSTestCase.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternistSDK +{ + class TestBaseLine; + + /** + * @short Creates a TestSuite from the XQuery Test Suite catalog, + * represented as a SAX stream. + * + * The created TestSuite can be retrieved via testSuite(). + * + * @note TestSuiteHandler assumes the XML is valid by having been validated + * against the W3C XML Schema. It have no safety checks for that the XML format + * is correct but is hard coded for it. Thus, the behavior is undefined if + * the XML is invalid. + * + * @ingroup PatternistSDK + * @author Frans Englich <frans.englich@nokia.com> + */ + class Q_PATTERNISTSDK_EXPORT TestSuiteHandler : public QXmlDefaultHandler + { + public: + /** + * @param catalogFile the URI for the catalog file being parsed. This + * URI is used for creating absolute URIs for files mentioned in + * the catalog with relative URIs. + * @param useExclusionList whether excludeTestGroups.txt should be used to ignore + * test groups when loading + */ + TestSuiteHandler(const QUrl &catalogFile, + const bool useExclusionList); + virtual bool characters(const QString &ch); + + virtual bool endElement(const QString &namespaceURI, + const QString &localName, + const QString &qName); + virtual bool startElement(const QString &namespaceURI, + const QString &localName, + const QString &qName, + const QXmlAttributes &atts); + + virtual TestSuite *testSuite() const; + + private: + QStringList readExclusionList(const bool useExclusionList) const; + + TestSuite * m_ts; + TestContainer * m_container; + XQTSTestCase * m_tc; + TestBaseLine * m_baseLine; + QString m_ch; + const QUrl m_catalogFile; + + /** + * The extension of XQuery files. For example, ".xq" + */ + QString m_xqueryFileExtension; + + /** + * The base URI for where the XQuery query files are found. + * It is absolute, resolved against catalogFile. + */ + QUrl m_queryOffset; + + QUrl m_baselineOffset; + QUrl m_sourceOffset; + QUrl m_currentQueryPath; + QUrl m_currentBaselinePath; + + /** + * In the XQTSCatalog.xml, each source file in each test is referred to + * by a key, which can be fully looked up in the @c sources element. This QHash + * maps the keys to absolute URIs pointing to the source files. + */ + ExternalSourceLoader::SourceMap m_sourceMap; + + ExternalSourceLoader::VariableMap m_tcSourceInputs; + + QPatternist::ResourceLoader::Ptr m_resourceLoader; + + /** + * The current value of <tt>input-file/\@variable/</tt>. + */ + QString m_currentInputVariable; + + /** + * The names of the test groups we're excluding. + */ + const QStringList m_exclusionList; + + /** + * This is set when we're inside a test-group that we're excluding. + */ + bool m_isExcluding; + + /** + * The names of the test groups. + */ + QStack<QString> m_testGroupName; + + /** + * Holds the content of the current <tt>input-URI</tt> element. + */ + QString m_inputURI; + QString m_contextItemSource; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/TestSuiteResult.cpp b/tests/auto/xmlpatternssdk/TestSuiteResult.cpp new file mode 100644 index 0000000..4e81859 --- /dev/null +++ b/tests/auto/xmlpatternssdk/TestSuiteResult.cpp @@ -0,0 +1,173 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QXmlContentHandler> + +#include "Global.h" +#include "XMLWriter.h" + +#include "TestSuiteResult.h" + +using namespace QPatternistSDK; + +TestSuiteResult::TestSuiteResult(const QString &testSuiteVersion, + const QDate &runDate, + const TestResult::List &results) : m_testSuiteVersion(testSuiteVersion), + m_runDate(runDate), + m_results(results) +{ +} + +TestSuiteResult::~TestSuiteResult() +{ + qDeleteAll(m_results); +} + +void TestSuiteResult::toXML(XMLWriter &receiver) const +{ + /* If this data needs to be configurable in someway(say, another + * XML format is supported), then break out the info into getters(alternatively, combined + * with setters, or that the class is subclassed), and access the getters instead. + */ + const QString organizationName (QLatin1String("K Desktop Environment(KDE)")); + const QString organizationWebsite (QLatin1String("http://www.kde.org/")); + const QString submittorName (QLatin1String("Frans Englich")); + const QString submittorEmail (QLatin1String("frans.englich@nokia.com")); + const QString implementationVersion (QLatin1String("0.1")); + const QString implementationName (QLatin1String("Patternist")); + const QString implementationDescription (QLatin1String( + "Patternist is an implementation written in C++ " + "and with the Qt/KDE libraries. " + "It is licensed under GNU LGPL and part of KDE, " + "the K Desktop Environment.")); + + /* Not currently serialized: + * - <implementation-defined-items> + * - <features> + * - <context-properties> + */ + + receiver.startDocument(); + /* <test-suite-result> */ + receiver.startPrefixMapping(QString(), Global::xqtsResultNS); + receiver.startElement(QLatin1String("test-suite-result")); + receiver.endPrefixMapping(QString()); + + /* <implementation> */ + QXmlAttributes implementationAtts; + implementationAtts.append(QLatin1String("name"), QString(), + QLatin1String("name"), implementationName); + implementationAtts.append(QLatin1String("version"), QString(), + QLatin1String("version"), implementationVersion); + receiver.startElement(QLatin1String("implementation"), implementationAtts); + + /* <organization> */ + QXmlAttributes organizationAtts; + organizationAtts.append(QLatin1String("name"), QString(), + QLatin1String("name"), organizationName); + organizationAtts.append(QLatin1String("website"), QString(), + QLatin1String("website"), organizationWebsite); + receiver.startElement(QLatin1String("organization"), organizationAtts); + + /* </organization> */ + receiver.endElement(QLatin1String("organization")); + + /* <submittor> */ + QXmlAttributes submittorAtts; + submittorAtts.append(QLatin1String("name"), QString(), QLatin1String("name"), submittorName); + submittorAtts.append(QLatin1String("email"), QString(), QLatin1String("email"), submittorEmail); + receiver.startElement(QLatin1String("submittor"), submittorAtts); + + /* </submittor> */ + receiver.endElement(QLatin1String("submittor")); + + /* <description> */ + receiver.startElement(QLatin1String("description")); + + /* <p> */ + receiver.startElement(QLatin1String("p")); + receiver.characters(implementationDescription); + + /* </p> */ + receiver.endElement(QLatin1String("p")); + /* </description> */ + receiver.endElement(QLatin1String("description")); + + /* </implementation> */ + receiver.endElement(QLatin1String("implementation")); + + /* <syntax> */ + receiver.startElement(QLatin1String("syntax")); + receiver.characters(QLatin1String(QLatin1String("XQuery"))); + + /* </syntax> */ + receiver.endElement(QLatin1String("syntax")); + + /* <test-run> */ + QXmlAttributes test_runAtts; + test_runAtts.append(QLatin1String("dateRun"), QString(), QLatin1String("dateRun"), m_runDate.toString(QLatin1String("yyyy-MM-dd"))); + receiver.startElement(QLatin1String("test-run"), test_runAtts); + + /* <test-suite> */ + QXmlAttributes test_suiteAtts; + test_suiteAtts.append(QLatin1String("version"), QString(), QLatin1String("version"), m_testSuiteVersion); + receiver.startElement(QLatin1String("test-suite"), test_suiteAtts); + + /* </test-suite> */ + receiver.endElement(QLatin1String("test-suite")); + + /* </test-run> */ + receiver.endElement(QLatin1String("test-run")); + + /* Serialize the TestResults: tons of test-case elements. */ + const TestResult::List::const_iterator end(m_results.constEnd()); + TestResult::List::const_iterator it(m_results.constBegin()); + + for(; it != end; ++it) + (*it)->toXML(receiver); + + /* </test-suite-result> */ + receiver.endElement(QLatin1String("test-suite-result")); + receiver.endDocument(); +} + +// vim: et:ts=4:sw=4:sts=4 + diff --git a/tests/auto/xmlpatternssdk/TestSuiteResult.h b/tests/auto/xmlpatternssdk/TestSuiteResult.h new file mode 100644 index 0000000..491c2b2 --- /dev/null +++ b/tests/auto/xmlpatternssdk/TestSuiteResult.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PatternistSDK_TestSuiteResult_H +#define PatternistSDK_TestSuiteResult_H + +#include <QDate> +#include <QString> + +#include "TestResult.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternistSDK +{ + /** + * @short A collection of TestResult instances. + * + * A TestSuiteResult gathers all TestResult instances, and provides + * the toXML() function which serializes it all into a XQuery Test Suite + * result file, conforming to XQTSResult.xsd. + * + * @ingroup PatternistSDK + * @author Frans Englich <frans.englich@nokia.com> + */ + class Q_PATTERNISTSDK_EXPORT TestSuiteResult + { + public: + ~TestSuiteResult(); + + TestSuiteResult(const QString &testSuiteVersion, + const QDate &runDate, + const TestResult::List &results); + + /** + * Serializes the test results this TestSuiteResult represents, + * into XQTS test-suite-result document, conformant to XQTSCatalog.xsd. + */ + void toXML(XMLWriter &receiver) const; + + private: + const QString m_testSuiteVersion; + const QDate m_runDate; + const TestResult::List m_results; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/TreeItem.cpp b/tests/auto/xmlpatternssdk/TreeItem.cpp new file mode 100644 index 0000000..b34262d --- /dev/null +++ b/tests/auto/xmlpatternssdk/TreeItem.cpp @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "TestContainer.h" + +#include "TreeItem.h" + +using namespace QPatternistSDK; + +int TreeItem::row() const +{ + const TreeItem *const p = parent(); + + if(p) + { + /* The const_cast makes it possible for QPointer's constructor + * to implicitly kick in. */ + return p->children().indexOf(const_cast<TreeItem *>(this)); + } + else + return -1; +} + +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/TreeItem.h b/tests/auto/xmlpatternssdk/TreeItem.h new file mode 100644 index 0000000..f5e051f --- /dev/null +++ b/tests/auto/xmlpatternssdk/TreeItem.h @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PatternistSDK_TreeItem_H +#define PatternistSDK_TreeItem_H + +#include <QObject> + +#include "Global.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QVariant; +template<typename T> class QList; +template<typename T> class QPointer; + +namespace QPatternistSDK +{ + /** + * @short TreeItem is a node in a hierachial structure and is used together + * with TreeModel. + * + * TreeItem is abstract base class. Instances of sub-classes of TreeItem + * can be used with TreeModel in order to use hierarchial data in Qt's + * model/view framework. + * + * TreeItem is a QObject in order to be able to be used with QPointer. + * + * @author Frans Englich <frans.englich@nokia.com> + * @see TreeModel + * @ingroup PatternistSDK + */ + class Q_PATTERNISTSDK_EXPORT TreeItem : public QObject + { + Q_OBJECT + public: + typedef QList<QPointer<TreeItem> > List; + + virtual ~TreeItem() {} + virtual void appendChild(TreeItem *item) = 0; + virtual TreeItem *child(const unsigned int row) const = 0; + virtual unsigned int childCount() const = 0; + virtual TreeItem *parent() const = 0; + + virtual TreeItem::List children() const = 0; + virtual int columnCount() const = 0; + + /** + * Determines the position among the children of + * this TreeItem's parent. This is done by introspecting the result + * of children(). + */ + int row() const; + + virtual QVariant data(const Qt::ItemDataRole role, int column) const = 0; + + Q_SIGNALS: + /** + * Emitted whenever this item changed. This is used for keeping + * views in synchronization with the item model which houses + * this item. + * + * @param item the item which changed. That is, this TreeItem. + */ + void changed(TreeItem *item); + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/TreeModel.cpp b/tests/auto/xmlpatternssdk/TreeModel.cpp new file mode 100644 index 0000000..e27f8e0 --- /dev/null +++ b/tests/auto/xmlpatternssdk/TreeModel.cpp @@ -0,0 +1,184 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtDebug> + +#include "TestContainer.h" + +#include "TreeModel.h" + +using namespace QPatternistSDK; + +TreeModel::TreeModel(const QStringList columnData, + QObject *p) : QAbstractItemModel(p), + m_root(0), + m_columnData(columnData) +{ +} + +TreeModel::~TreeModel() +{ +} + +QVariant TreeModel::data(const QModelIndex &idx, int role) const +{ + if(!idx.isValid()) + return QVariant(); + + TreeItem *item = static_cast<TreeItem *>(idx.internalPointer()); + Q_ASSERT(item); + + return item->data(static_cast<Qt::ItemDataRole>(role), idx.column()); +} + +QVariant TreeModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(orientation == Qt::Horizontal && role == Qt::DisplayRole) + return m_columnData.value(section); + + return QVariant(); +} + +void TreeModel::childChanged(TreeItem *item) +{ + if (item) { + const QModelIndex index = createIndex(item->row(), 0, item); + dataChanged(index, index); + } else { + layoutChanged(); + } +} + +QModelIndex TreeModel::index(int row, int column, const QModelIndex &p) const +{ + const int c = columnCount(p); + + if(row < 0 || column < 0 || column >= c) + return QModelIndex(); + + TreeItem *parentItem; + + if(p.isValid()) + parentItem = static_cast<TreeItem *>(p.internalPointer()); + else + parentItem = m_root; + + if(!parentItem) + return QModelIndex(); + + TreeItem *childItem = parentItem->child(row); + + if(childItem) + return createIndex(row, column, childItem); + else + return QModelIndex(); +} + +QModelIndex TreeModel::parent(const QModelIndex &idx) const +{ + if(!idx.isValid()) + return QModelIndex(); + + TreeItem *childItem = static_cast<TreeItem *>(idx.internalPointer()); + Q_ASSERT(childItem); + TreeItem *parentItem = childItem->parent(); + + if(!parentItem || parentItem == m_root) + return QModelIndex(); + + Q_ASSERT(parentItem); + return createIndex(parentItem->row(), 0, parentItem); +} + +Qt::ItemFlags TreeModel::flags(const QModelIndex &idx) const +{ + /* Not sure about this code. */ + if(!idx.isValid()) + return Qt::ItemFlags(); + + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; +} + +int TreeModel::rowCount(const QModelIndex &p) const +{ + if(p.column() > 0) + return 0; + + const TreeItem *parentItem; + + if(p.isValid()) + parentItem = static_cast<TreeItem *>(p.internalPointer()); + else + { + if(m_root) + parentItem = m_root; + else + return 0; + } + + return parentItem->childCount(); +} + +int TreeModel::columnCount(const QModelIndex &p) const +{ + if(p.isValid()) + return static_cast<TreeItem *>(p.internalPointer())->columnCount(); + else + return m_columnData.count(); +} + +TreeItem *TreeModel::root() const +{ + return m_root; +} + +void TreeModel::setRoot(TreeItem *r) +{ + TreeItem *const oldRoot = m_root; + m_root = r; + + if(m_root) + connect(r, SIGNAL(changed(TreeItem *)), SLOT(childChanged(TreeItem *))); + reset(); /* Notify views that we have radically changed. */ + delete oldRoot; +} + +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/TreeModel.h b/tests/auto/xmlpatternssdk/TreeModel.h new file mode 100644 index 0000000..1d8ea72 --- /dev/null +++ b/tests/auto/xmlpatternssdk/TreeModel.h @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PatternistSDK_TreeModel_H +#define PatternistSDK_TreeModel_H + +#include <QAbstractItemModel> +#include <QObject> +#include <QPointer> +#include <QStringList> + +#include "Global.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternistSDK +{ + class TreeItem; + + /** + * @short TreeItem is a generic QAbstractItemModel tailored for + * representing hierarchial data. + * + * TreeModel is an item model in Qt's model/view framework. Its + * data consists of TreeItem instances. + * + * @see TreeItem + * @ingroup PatternistSDK + * @author Frans Englich <frans.englich@nokia.com> + */ + class Q_PATTERNISTSDK_EXPORT TreeModel : public QAbstractItemModel + { + Q_OBJECT + public: + TreeModel(const QStringList columnData, QObject *parent); + virtual ~TreeModel(); + + virtual QVariant data(const QModelIndex &index, int role) const; + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + virtual QVariant headerData(int section, + Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + virtual QModelIndex index(int row, + int column, + const QModelIndex &parent = QModelIndex()) const; + virtual QModelIndex parent(const QModelIndex &index) const; + virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; + virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; + + TreeItem *root() const; + /** + * Sets @p root to the new root, and deletes the old. + */ + void setRoot(TreeItem *root); + + protected Q_SLOTS: + void childChanged(TreeItem *child); + + private: + QPointer<TreeItem> m_root; + const QStringList m_columnData; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/Worker.cpp b/tests/auto/xmlpatternssdk/Worker.cpp new file mode 100644 index 0000000..0121099 --- /dev/null +++ b/tests/auto/xmlpatternssdk/Worker.cpp @@ -0,0 +1,258 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QDir> +#include <QEventLoop> +#include <QPair> +#include <QtDebug> + +#include "ExitCode.h" + +#include "Worker.h" + +using namespace QPatternistSDK; + +const char *const Worker::m_indent = " "; + +Worker::Worker(QEventLoop &ev, + const QFileInfo &baseline, + const QFileInfo &result) : m_finishedCount(0) + , m_baselineFile(baseline) + , m_resultFile(result) + , m_eventLoop(ev) +{ +} + +void Worker::list(QTextStream &out, const QString &msg, QStringList &list) +{ + Q_ASSERT(!msg.isEmpty()); + + if(list.isEmpty()) + return; + + list.sort(); /* Make it pretty, and easy to read. */ + + out << msg << ":\n"; + + const QStringList::const_iterator end(list.constEnd()); + QStringList::const_iterator it(list.constBegin()); + + for(; it != end; ++it) + out << m_indent << qPrintable(*it) << '\n'; +} + +static inline int count(const ResultThreader::Hash &list, const TestResult::Status stat) +{ + const ResultThreader::Hash::const_iterator end(list.constEnd()); + ResultThreader::Hash::const_iterator it(list.constBegin()); + int result = 0; + + for(; it != end; ++it) + { + if(it.value() == stat) + ++result; + } + + return result; +} + +void Worker::threadFinished() +{ + ++m_finishedCount; + Q_ASSERT(m_finishedCount == 1 || m_finishedCount == 2); + + const ResultThreader *const handler = static_cast<ResultThreader *>(sender()); + Q_ASSERT(handler); + + switch(handler->type()) + { + case ResultThreader::Baseline: + { + m_baseline = handler->result(); + break; + } + case ResultThreader::Result: + m_result = handler->result(); + } + + if(m_finishedCount == 1) /* One thread's missing. */ + return; + + /* Ok, both threads have now finished, and we got their results in m_result and m_baseline. */ + + /* No matter how this function exits, we want to delete this Worker. */ + deleteLater(); + + ResultThreader::Hash::const_iterator itA(m_result.constBegin()); + ResultThreader::Hash::const_iterator itB(m_baseline.constBegin()); + const ResultThreader::Hash::const_iterator endA(m_result.constEnd()); + const ResultThreader::Hash::const_iterator endB(m_baseline.constEnd()); + const int baselineCount = m_baseline.count(); + const int resultCount = m_result.count(); + + /* If you want useful output, change the QTextStream to use stderr. */ + //QTextStream err(stderr); + QByteArray out; + QTextStream err(&out); + + if(resultCount < baselineCount) + { + err << qPrintable(QString(QLatin1String("WARNING: Test result contains %1 reports, " + "but the baseline contains %2, a DECREASE " + "of %3 tests.\n")) + .arg(resultCount) + .arg(baselineCount) + .arg(resultCount - baselineCount)); + } + else if(resultCount > baselineCount) + { + err << qPrintable(QString(QLatin1String("NOTE: The number of tests run is more than what " + "the baseline specifies. Run was %1 test cases, the " + "baseline specifies %2; an increase of %3 tests.\n")) + .arg(resultCount) + .arg(baselineCount) + .arg(resultCount - baselineCount)); + } + + for(; itA != endA; ++itA) + { + const TestResult::Status result = itA.value(); + const TestResult::Status baseline = m_baseline.value(itA.key()); + + if(result == baseline) /* We have no change. */ + { + if(result == TestResult::NotTested) + m_notTested.append(itA.key()); + else + continue; + } + else if(baseline == TestResult::Pass && result == TestResult::Fail) + m_unexpectedFailures.append(itA.key()); + else if(baseline == TestResult::Fail && result == TestResult::Pass) + m_unexpectedPasses.append(itA.key()); + } + + list(err, QLatin1String("Not tested"), m_notTested); + list(err, QLatin1String("Unexpected failures"), m_unexpectedFailures); + list(err, QLatin1String("Unexpected passes"), m_unexpectedPasses); + + err << "SUMMARY:\n"; + typedef QPair<QString, int> Info; + typedef QList<Info> InfoList; + InfoList info; + + const int totFail = count(m_result, TestResult::Fail); + const int totPass = count(m_result, TestResult::Pass); + const int total = resultCount; + const int notTested = m_notTested.count(); + const int percentage = int((static_cast<double>(totPass) / total) * 100); + + Q_ASSERT_X(percentage >= 0 && percentage <= 100, Q_FUNC_INFO, + qPrintable(QString(QLatin1String("Percentage was: %1")).arg(percentage))); + + info.append(Info(QLatin1String("Total"), total)); + info.append(Info(QLatin1String("Failures"), totFail)); + info.append(Info(QLatin1String("Passes"), totPass)); + info.append(Info(QLatin1String("Not tested"), notTested)); + info.append(Info(QLatin1String("Pass percentage(%)"), percentage)); + info.append(Info(QLatin1String("Unexpected failures"), m_unexpectedFailures.count())); + info.append(Info(QLatin1String("Unexpected passes"), m_unexpectedPasses.count())); + + const InfoList::const_iterator end(info.constEnd()); + InfoList::const_iterator it(info.constBegin()); + + /* List the statistics nicely in a row with padded columns. */ + for(; it != end; ++it) + { + const QString result((((*it).first) + QLatin1Char(':')).leftJustified(22, QLatin1Char(' '))); + err << m_indent << qPrintable(result) << (*it).second << '\n'; + } + + if(!m_unexpectedFailures.isEmpty()) + { + err << "FAILURE: Regressions discovered, baseline was not updated.\n"; + err.flush(); + QTextStream(stderr) << out; + m_eventLoop.exit(ExitCode::Regression); + return; + } + else if(m_unexpectedPasses.isEmpty() && baselineCount == resultCount) + { + err << "Result was identical to the baseline, baseline was not updated.\n"; + m_eventLoop.exit(ExitCode::Success); + return; + } + + /* Ok, we got unexpected successes and no regressions: let's update the baseline. */ + + QFile resultFile(m_resultFile.absoluteFilePath()); + + /* Remove the old file, otherwise QFile::copy() will fail. */ + QDir baselineDir(m_baselineFile.absolutePath()); + baselineDir.remove(m_baselineFile.fileName()); + + if(resultFile.copy(m_baselineFile.absoluteFilePath())) + { + /* Give a detailed message of what's going on. */ + if(resultCount > baselineCount) + err << "More tests was run than specified in the baseline, updating the baseline.\n"; + else + err << "Improvement, the baseline was updated.\n"; + + /* We actually flag this as an error, because the new baseline must be submitted. */ + err.flush(); + QTextStream(stderr) << out; + m_eventLoop.exit(ExitCode::Regression); + return; + } + else + { + err << qPrintable(QString(QLatin1String("Encountered error when updating " + "the baseline: %1\n")) + .arg(resultFile.errorString())); + err.flush(); + QTextStream(stderr) << out; + m_eventLoop.exit(ExitCode::WriteError); + return; + } +} + +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/Worker.h b/tests/auto/xmlpatternssdk/Worker.h new file mode 100644 index 0000000..b3d7ae2 --- /dev/null +++ b/tests/auto/xmlpatternssdk/Worker.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PatternistSDK_Worker_H +#define PatternistSDK_Worker_H + +#include <QFileInfo> +#include <QList> +#include <QObject> +#include <QStringList> + +#include "ResultThreader.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QEventLoop; + +namespace QPatternistSDK +{ + /** + * @short Gets notified when the ResultThreader threads are + * finished, and output summaries and adjusts a baseline. + * + * @author Frans Englich <frans.englich@nokia.com> + * @ingroup PatternistSDK + */ + class Q_PATTERNISTSDK_EXPORT Worker : public QObject + { + Q_OBJECT + public: + Worker(QEventLoop &e, + const QFileInfo &baseline, + const QFileInfo &result); + + public Q_SLOTS: + void threadFinished(); + + private: + static inline void list(QTextStream &out, const QString &msg, QStringList &list); + + qint8 m_finishedCount; + const QFileInfo m_baselineFile; + const QFileInfo m_resultFile; + ResultThreader::Hash m_result; + ResultThreader::Hash m_baseline; + ResultThreader::Hash m_summary; + QStringList m_unexpectedPasses; + QStringList m_unexpectedFailures; + QStringList m_notTested; + QEventLoop & m_eventLoop; + static const char *const m_indent; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/XMLWriter.cpp b/tests/auto/xmlpatternssdk/XMLWriter.cpp new file mode 100644 index 0000000..60a5344 --- /dev/null +++ b/tests/auto/xmlpatternssdk/XMLWriter.cpp @@ -0,0 +1,669 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QCoreApplication> +#include <QDateTime> +#include <QIODevice> +#include <QList> +#include <QPair> +#include <QStack> +#include <QtDebug> + +#include "XMLWriter.h" + +/* Issues: + * - Switch to Qt's d-pointer semantics, if in Qt. + * - Remove namespace(PatternistSDK), and change name, if in Qt. + * - Is it really necessary to pass the tag name to endElement()? + * - Could it be of interest to let the user control the encoding? Are those cases common + * enough to justify support in Qt? Using anything but UTF-8 or UTF-16 + * means asking for trouble, from an interoperability perspective. + */ + +/* Design rationalis, comments: + * + * - The class is called XMLWriter to harvest familarity by being consistent with + * Java's XMLWriter class. If XMLWriter is moved to Qt, the name QXmlWriter is perhaps suitable. + * - The class does not handle indentation because the "do one thing well"-principle is + * in use. XMLWriter should be fast and not assume a certain idea of indentation. Indentation + * should be implemented in a standalone QXmlContentHandler that performs the indentation and + * "has a" QXmlContentHandler which it in addition calls, and by that proxying/piping another + * QXmlContentHandler(which most likely is an XMLWriter). Thus, achieving a modularized, + * flexibly approach to indentation. A reason is also that indentation is very subjective. + * The indenter class should probably be called XMLIndenter/QXmlIndenter. + * - It could be of interest to implement QXmlDTDHandler such that it would be possible to serialize + * DTDs. Must be done before BC becomes significant. + * - I think the most valuable of this class is its Q_ASSERT tests. Many programmers have severe problems + * producing XML, and the tests helps them catching their mistakes. They therefore promote + * interoperability. Do not remove them. If any are wrong, fix them instead. + */ + +using namespace QPatternistSDK; + +/** + * A namespace binding, prefix/namespace URI. + */ +typedef QPair<QString, QString> NSBinding; +typedef QList<NSBinding> NSBindingList; + +#ifdef QT_NO_DEBUG +# define DEBUG_CODE(code) +#else +# define DEBUG_CODE(code) code +#endif + +class XMLWriter::Private +{ +public: + inline Private(QIODevice *devP) : insideCDATA(false), + addModificationNote(false), + dev(devP) + { + hasContentStack.push(true); + } + +#ifdef QT_NO_DEBUG + inline void validateQName(const QString &) const + { + } + + inline void verifyNS(const QString &) const + { + } +#else + /** + * Simple test of that @p name is an acceptable QName. + */ + inline void validateQName(const QString &name) + { + Q_ASSERT_X(!name.isEmpty(), Q_FUNC_INFO, + "An XML name cannot be empty."); + Q_ASSERT_X(!name.endsWith(QLatin1Char(':')), Q_FUNC_INFO, + "An XML name cannot end with a colon(QLatin1Char(':'))."); + Q_ASSERT_X(!name.contains(QRegExp(QLatin1String("[ \t\n]"))), Q_FUNC_INFO, + "An XML name cannot contain whitespace."); + } + + /** + * Ensures that the prefix of @p qName is declared. + */ + inline void verifyNS(const QString &qName) const + { + const QString prefix(qName.left(qName.indexOf(QLatin1Char(':')))); + + if(qName.contains(QLatin1Char(':')) && prefix != QLatin1String("xml")) + { + bool foundPrefix = false; + const QStack<NSBindingList>::const_iterator end(namespaceTracker.constEnd()); + QStack<NSBindingList>::const_iterator it(namespaceTracker.constBegin()); + + for(; it != end; ++it) + { + const NSBindingList::const_iterator lend((*it).constEnd()); + NSBindingList::const_iterator lit((*it).constBegin()); + + for(; lit != lend; ++it) + { + if((*lit).first == prefix) + { + foundPrefix = true; + break; + } + } + if(foundPrefix) + break; + } + + Q_ASSERT_X(foundPrefix, "XMLWriter::startElement()", + qPrintable(QString::fromLatin1("The prefix %1 is not declared. All prefixes " + "except 'xml' must be declared.").arg(prefix))); + } + } +#endif + + inline QString escapeElementContent(const QString &ch) + { + const int l = ch.length(); + QString retval; + + for(int i = 0; i != l; ++i) + { + const QChar c(ch.at(i)); + + if(c == QLatin1Char(QLatin1Char('&'))) + retval += QLatin1String("&"); + else if(c == QLatin1Char(QLatin1Char('<'))) + retval += QLatin1String("<"); + else + retval += c; + } + + return retval; + } + + inline QString escapeAttributeContent(const QString &ch) + { + const int l = ch.length(); + QString retval; + + for(int i = 0; i != l; ++i) + { + const QChar c(ch.at(i)); + + /* We don't have to escape '\'' because we use '\"' as attribute delimiter. */ + if(c == QLatin1Char('&')) + retval += QLatin1String("&"); + else if(c == QLatin1Char('<')) + retval += QLatin1String("<"); + else if(c == QLatin1Char('"')) + retval += QLatin1String("""); + else + retval += c; + } + + return retval; + } + + inline QString escapeCDATAContent(const QString &ch) + { + const int l = ch.length(); + QString retval; + qint8 atEnd = 0; + + for(int i = 0; i != l; ++i) + { + const QChar c(ch.at(i)); + + /* Escape '>' if in "]]>" */ + if(c == QLatin1Char(']')) + { + if(atEnd == 0 || atEnd == 1) + ++atEnd; + else + atEnd = 0; + + retval += QLatin1Char(']'); + } + else if(c == QLatin1Char('>')) + { + if(atEnd == 2) + retval += QLatin1String(">"); + else + { + atEnd = 0; + retval += QLatin1Char('>'); + } + } + else + retval += c; + } + + return retval; + } + + /** + * We wrap dev in this function such that we can deploy the Q_ASSERT_X + * macro in each place it's used. + */ + inline QIODevice *device() const + { + Q_ASSERT_X(dev, Q_FUNC_INFO, + "No device specified for XMLWriter; one must be specified with " + "setDevice() or via the constructor before XMLWriter can be used."); + return dev; + } + + /** + * @returns true on success, otherwise false + */ + inline bool serialize(const QString &data) + { + const QByteArray utf8(data.toUtf8()); + + return device()->write(utf8) == utf8.size(); + } + + /** + * @returns true on success, otherwise false + */ + inline bool serialize(const char data) + { + return device()->putChar(data); + } + + /** + * @returns true on success, otherwise false + */ + inline bool serialize(const char *data) + { + return device()->write(data) == qstrlen(data); + } + + inline bool hasElementContent() const + { + return hasContentStack.top(); + } + + inline void handleElement() + { + if(!hasElementContent()) + serialize('>'); + + /* This element is content for the parent. */ + hasContentStack.top() = true; + } + + NSBindingList namespaces; + bool insideCDATA; + bool addModificationNote; + QString msg; + QIODevice *dev; + QStack<bool> hasContentStack; + QString errorString; + DEBUG_CODE(QStack<QString> tags;) + DEBUG_CODE(QStack<NSBindingList> namespaceTracker;) +}; + +/** + * Reduces complexity. The empty else clause is for avoiding mess when macro + * is used in the 'then' branch of an if clause, which is followed by an else clause. + */ +#define serialize(string) if(!d->serialize(string)) \ + { \ + d->errorString = d->device()->errorString(); \ + return false; \ + } \ + else do {} while (false) + +XMLWriter::XMLWriter(QIODevice *outStream) : d(new Private(outStream)) +{ +} + +XMLWriter::~XMLWriter() +{ + delete d; +} + +bool XMLWriter::startDocument() +{ + if(!device()->isOpen() && !device()->open(QIODevice::WriteOnly)) + return false; + + if(d->addModificationNote) + { + if(d->msg.isNull()) + { + d->msg = QString::fromLatin1("NOTE: This file was automatically generated " + "by %1 at %2. All changes to this file will be lost.") + .arg(QCoreApplication::instance()->applicationName(), + QDateTime::currentDateTime().toString()); + } + if(!comment(d->msg)) + return false; + + serialize('\n'); + } + + serialize(QLatin1String("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")); + + return true; +} + +bool XMLWriter::startElement(const QString &/*namespaceURI*/, + const QString &/*localName*/, + const QString &qName, + const QXmlAttributes &atts) +{ + return startElement(qName, atts); +} + +bool XMLWriter::startElement(const QString &qName, + const QXmlAttributes &atts) +{ + Q_ASSERT_X(!d->insideCDATA, Q_FUNC_INFO, + "Only characters() can be received when inside CDATA."); + Q_ASSERT_X(!qName.startsWith(QLatin1String("xmlns")), Q_FUNC_INFO, + "startElement should not be used for declaring prefixes, " + "use startPrefixMapping() for that."); + + d->validateQName(qName); + d->verifyNS(qName); + + d->handleElement(); + + serialize('<'); + serialize(qName); + + DEBUG_CODE(d->tags.push(qName)); + DEBUG_CODE(d->namespaceTracker.push(d->namespaces)); + + /* Add namespace declarations. */ + const NSBindingList::const_iterator end(d->namespaces.constEnd()); + NSBindingList::const_iterator it(d->namespaces.constBegin()); + + for(; it != end; ++it) + { + if((*it).first.isEmpty()) + serialize(" xmlns="); + else + { + serialize(" xmlns:"); + serialize((*it).first); + serialize('='); + } + + serialize('"'); + serialize(d->escapeElementContent((*it).second)); + serialize('"'); + } + d->namespaces.clear(); + + const int c = atts.count(); + + /* Serialize attributes. */ + for(int i = 0; i != c; ++i) + { + d->validateQName(atts.qName(i)); + d->verifyNS(atts.qName(i)); + + serialize(' '); + serialize(atts.qName(i)); + serialize("=\""); + serialize(d->escapeAttributeContent(atts.value(i))); + serialize('"'); + } + + d->hasContentStack.push(false); + return true; +} + +bool XMLWriter::endElement(const QString &/*namespaceURI*/, + const QString &/*localName*/, + const QString &qName) +{ + return endElement(qName); +} + +bool XMLWriter::endElement(const QString &qName) +{ + Q_ASSERT_X(!d->insideCDATA, Q_FUNC_INFO, + "Only characters() can be received when inside CDATA."); + Q_ASSERT_X(d->tags.pop() == qName, Q_FUNC_INFO, + "The element tags are not balanced, the produced XML is invalid."); + + DEBUG_CODE(d->namespaceTracker.pop()); + + /* "this" element is content for our parent, so ensure hasElementContent is true. */ + + if(d->hasElementContent()) + { + serialize(QLatin1String("</")); + serialize(qName); + serialize('>'); + } + else + serialize(QLatin1String("/>")); + + d->hasContentStack.pop(); + + return true; +} + +bool XMLWriter::startPrefixMapping(const QString &prefix, const QString &uri) +{ + Q_ASSERT_X(!d->insideCDATA, Q_FUNC_INFO, + "Only characters() can be received when inside CDATA."); + Q_ASSERT_X(prefix.toLower() != QLatin1String("xml") || + (prefix.toLower() == QLatin1String("xml") && + (uri == QLatin1String("http://www.w3.org/TR/REC-xml-names/") || + uri.isEmpty())), + Q_FUNC_INFO, + "The prefix 'xml' can only be bound to the namespace " + "\"http://www.w3.org/TR/REC-xml-names/\"."); + Q_ASSERT_X(prefix.toLower() != QLatin1String("xml") && + uri != QLatin1String("http://www.w3.org/TR/REC-xml-names/"), + Q_FUNC_INFO, + "The namespace \"http://www.w3.org/TR/REC-xml-names/\" can only be bound to the " + "\"xml\" prefix."); + + d->namespaces.append(qMakePair(prefix, uri)); + return true; +} + +bool XMLWriter::processingInstruction(const QString &target, + const QString &data) +{ + Q_ASSERT_X(target.toLower() != QLatin1String("xml"), Q_FUNC_INFO, + "A processing instruction cannot have the name xml in any " + "capitalization, because it is reserved."); + Q_ASSERT_X(!data.contains(QLatin1String("?>")), Q_FUNC_INFO, + "The content of a processing instruction cannot contain the string \"?>\"."); + Q_ASSERT_X(!d->insideCDATA, "XMLWriter::processingInstruction()", + "Only characters() can be received when inside CDATA."); + + d->handleElement(); + + serialize(QLatin1String("<?")); + serialize(target); + serialize(' '); + serialize(data); + serialize(QLatin1String("?>")); + return true; +} + +bool XMLWriter::characters(const QString &ch) +{ + Q_ASSERT_X(d->tags.count() >= 1, Q_FUNC_INFO, + "Text nodes can only appear inside elements(no elements sent)."); + d->handleElement(); + + if(d->insideCDATA) + serialize(d->escapeCDATAContent(ch)); + else + serialize(d->escapeElementContent(ch)); + + return true; +} + +bool XMLWriter::comment(const QString &ch) +{ + Q_ASSERT_X(!d->insideCDATA, Q_FUNC_INFO, + "Only characters() can be received when inside CDATA."); + Q_ASSERT_X(!ch.contains(QLatin1String("--")), Q_FUNC_INFO, + "XML comments may not contain double-hyphens(\"--\")."); + Q_ASSERT_X(!ch.endsWith(QLatin1Char('-')), Q_FUNC_INFO, + "XML comments cannot end with a hyphen, \"-\"(add a space, for example)."); + /* A comment starting with "<!---" is ok. */ + + d->handleElement(); + + serialize(QLatin1String("<!--")); + serialize(ch); + serialize(QLatin1String("-->")); + + return true; +} + +bool XMLWriter::startCDATA() +{ + Q_ASSERT_X(d->insideCDATA, Q_FUNC_INFO, + "startCDATA() has already been called."); + Q_ASSERT_X(d->tags.count() >= 1, Q_FUNC_INFO, + "CDATA sections can only appear inside elements(no elements sent)."); + d->insideCDATA = true; + serialize(QLatin1String("<![CDATA[")); + return true; +} + +bool XMLWriter::endCDATA() +{ + d->insideCDATA = false; + serialize("]]>"); + return true; +} + +bool XMLWriter::startDTD(const QString &name, + const QString &publicId, + const QString &systemId) +{ + Q_ASSERT_X(!d->insideCDATA, Q_FUNC_INFO, + "Only characters() can be received when inside CDATA."); + Q_ASSERT_X(!name.isEmpty(), Q_FUNC_INFO, + "The DOCTYPE name cannot be empty."); + Q_ASSERT_X(d->tags.isEmpty() && d->namespaces.isEmpty(), Q_FUNC_INFO, + "No content such as namespace declarations or elements can be serialized " + "before the DOCTYPE declaration, the XML is invalid."); + Q_ASSERT_X(!publicId.contains(QLatin1Char('"')), Q_FUNC_INFO, + "The PUBLIC ID cannot contain quotes('\"')."); + Q_ASSERT_X(!systemId.contains(QLatin1Char('"')), Q_FUNC_INFO, + "The SYSTEM ID cannot contain quotes('\"')."); + + serialize(QLatin1String("<!DOCTYPE ")); + serialize(name); + + if(!publicId.isEmpty()) + { + Q_ASSERT_X(!systemId.isEmpty(), Q_FUNC_INFO, + "When a public identifier is specified, a system identifier " + "must also be specified in order to produce valid XML."); + serialize(" PUBLIC \""); + serialize(publicId); + serialize('"'); + } + + if(!systemId.isEmpty()) + { + if(publicId.isEmpty()) + serialize(" SYSTEM"); + + serialize(" \""); + serialize(systemId); + serialize('"'); + } + + return true; +} + +bool XMLWriter::endDTD() +{ + Q_ASSERT_X(d->tags.isEmpty() && d->namespaces.isEmpty(), Q_FUNC_INFO, + "Content such as namespace declarations or elements cannot occur inside " + "the DOCTYPE declaration, the XML is invalid."); + serialize(QLatin1String(">\n")); + return true; +} + +bool XMLWriter::startEntity(const QString &) +{ + return true; +} + +bool XMLWriter::endEntity(const QString &) +{ + return true; +} + +void XMLWriter::setMessage(const QString &msg) +{ + d->msg = msg; +} + +QString XMLWriter::modificationMessage() const +{ + return d->msg; +} + +bool XMLWriter::endDocument() +{ + Q_ASSERT_X(d->tags.isEmpty(), Q_FUNC_INFO, + "endDocument() called before all elements were closed with endElement()."); + d->device()->close(); + return true; +} + +QString XMLWriter::errorString() const +{ + return d->errorString; +} + +bool XMLWriter::ignorableWhitespace(const QString &ch) +{ + return characters(ch); +} + +bool XMLWriter::endPrefixMapping(const QString &) +{ + /* Again, should we do something with this? */ + return true; +} + +bool XMLWriter::skippedEntity(const QString &) +{ + return true; +} + +void XMLWriter::setDocumentLocator(QXmlLocator *) +{ +} + +QIODevice *XMLWriter::device() const +{ + return d->dev; +} + +void XMLWriter::setDevice(QIODevice *dev) +{ + d->dev = dev; +} + +void XMLWriter::setAddMessage(const bool toggle) +{ + d->addModificationNote = toggle; +} + +bool XMLWriter::addModificationMessage() const +{ + return d->addModificationNote; +} + +#undef serialize +// vim: et:ts=4:sw=4:sts=4 + diff --git a/tests/auto/xmlpatternssdk/XMLWriter.h b/tests/auto/xmlpatternssdk/XMLWriter.h new file mode 100644 index 0000000..2b629bb --- /dev/null +++ b/tests/auto/xmlpatternssdk/XMLWriter.h @@ -0,0 +1,403 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PatternistSDK_XMLWriter_H +#define PatternistSDK_XMLWriter_H + +#include "Global.h" + +#include <QtXml/QXmlContentHandler> +#include <QtXml/QXmlLexicalHandler> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QIODevice; + +namespace QPatternistSDK +{ + /** + * @short Serializes a stream of SAX events into XML, sent to a QIODevice. + * + * XMLWriter is a fast and simple XML serializer which takes care of + * all the low level details of well-formedness and character escaping, allowing + * the user to focus on higher level issues and increasing the chances of producing + * valid, interoperable XML. + * + * The content XMLWriter produces is sent to a QIODevice, which is either + * specified in XMLWriter's constructor or via setDevice(). If writing to + * the device fails, the content functions such as startElement() returns @c false. + * + * XMLWriter sub-classes QXmlContentHandler meaning it can serialize content + * from any code that produces SAX events. The class can also be used manually, + * by calling startElement(), endCDATA(), and so forth. + * + * XMLWriter cannot be used to serialize multiple documents. One instance per + * document must be used. + * + * XMLWriter takes care of escaping content into character references as necessary. Thus, + * it should not be done manually. In fact, it would most likely + * result in invalid XML or an unintended result. XMLWriter always serializes into UTF-8. + * + * When compiled in debug mode, XMLWriter contains several tests that helps + * ensuring that XMLWriter produces valid XML. Some of these tests ensures that: + * + * - The @c xmlns and @c xml prefixes are used properly + * - Content of comments and processing instructions is valid + * - Element, attribute and DOCTYPE names are sensible + * - Elements are properly nested and balanced + * - To some extent that things occur in the proper order. For example, that + * the document type definition isn't added inside an element + * - That namespaces prefixes are declared + * + * Not triggering XMLWriter's tests does not guarantee valid XML is produced, + * but they do help catching common mistakes and some of the corner cases in the + * specifications. When XMLWriter is compiled in release mode, these tests are not enabled + * and the error handling in effect is concerning writing to the QIODevice. + * + * Often it is of interest to add a note at the beginning of the file communicating + * it is auto-generated. setMessage() and setAddMessage() provides + * a convenient way of doing that. + * + * Namespace declarations are added with startPrefixMapping(), not by sending attributes + * with name <tt>xmlns:*</tt> to startElement(). + * + * @see <a href="http://hsivonen.iki.fi/producing-xml/">HOWTO Avoid Being + * Called a Bozo When Producing XML</a> + * @see <a href="http://www.w3.org/TR/REC-xml/">Extensible Markup + * Language (XML) 1.0 (Third Edition)</a> + * @see <a href="http://www.w3.org/TR/REC-xml-names/">Namespaces in XML</a> + * @todo Replace this class with QXmlStreamWriter + * @author Frans Englich <frans.englich@nokia.com> + * @ingroup PatternistSDK + */ + class Q_PATTERNISTSDK_EXPORT XMLWriter : public QXmlContentHandler + , public QXmlLexicalHandler + { + public: + /** + * Creates a XMLWriter which serializes its received events + * to @p outStream. + * + * @note XMLWriter does not claim ownership of @p outStream. Thus, + * @p outStream may not be destroyed as long as + * this XMLWriter instance uses it. + */ + XMLWriter(QIODevice *outStream = 0); + + virtual ~XMLWriter(); + + /** + * @returns @c true if opening the output device succeeds, otherwise @c false + */ + virtual bool startDocument(); + + /** + * @returns @c false if failure occurs in writing to the QIODevice, otherwise + * @c true + */ + virtual bool characters(const QString &ch); + + /** + * Starts an element with name @p qName and attributes @p atts. The prefix + * in @p qName must first be declared with startPrefixMapping(), if it has one. + * + * A call to startElement() must always at some point be balanced with a call + * to endElement(). + * + * To declare namespaces, don't put attributes with name <tt>xmlns:*</tt> in @p atts, + * but use startPrefixMapping(). + */ + virtual bool startElement(const QString &qName, const QXmlAttributes &atts = QXmlAttributes()); + + /** + * + * Behaves essentially as startElement(const QString &qName, const QXmlAttributes &atts). This + * function is used in conjunction with other SAX classes. + * + * The call: + * + * @code + * startElement(QString(), QString(), qName, atts); + * @endcode + * + * is equivalent to: + * + * @code + * startElement(qName, atts); + * @endcode + * + * @p namespaceURI and @p localName are not used. This function is + * used in conjunction with other SAX classes. + * + * @returns @c false if failure occurs in writing to the QIODevice, otherwise + * @c true + */ + virtual bool startElement(const QString &namespaceURI, + const QString &localName, + const QString &qName, + const QXmlAttributes &atts); + + /** + * Signals the end of an element with name @p qName. @p qName must + * be supplied. + * + * Calls to startElement() and endElement() must always be balanced. + * + * @returns @c false if failure occurs in writing to the QIODevice, otherwise + * @c true + */ + virtual bool endElement(const QString &qName); + + /** + * Behaves essentially as endElement(const QString &qName). This function + * is used when XMLWriter is used in SAX code. + * + * @p namespaceURI and @p localName are not used. + * + * The call: + * + * @code + * endElement(QString(), QString(), qName); + * @endcode + * + * is equivalent to: + * + * @code + * endElement(qName); + * @endcode + * + * @returns @c false if failure occurs in writing to the QIODevice, otherwise + * @c true + */ + virtual bool endElement(const QString &namespaceURI, + const QString &localName, + const QString &qName); + + /** + * A description of an error if it occurred. This is typically + * QIODevice::errorString(). If no error has occurred, an empty + * string is returned. + */ + virtual QString errorString() const; + + /** + * Starts a CDATA section. Content sent with characters() will not be escaped + * except for ">" if occurring in "]]>". + * + * @returns @c false if failure occurs in writing to the QIODevice, otherwise + * @c true + */ + virtual bool startCDATA(); + + /** + * @returns @c false if failure occurs in writing to the QIODevice, otherwise + * @c true + */ + virtual bool endCDATA(); + + /** + * Creates a document type definition. + * + * For example, the code snippet: + * + * @code + * writer.startDTD("html", "-//W3C//DTD XHTML 1.0 Strict//EN", + * "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"); + * writer.endDTD(); + * @endcode + * + * would create: + * @verbatim + <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +@endverbatim + * + * @note A system identifier must always be specified, but a public identifier may + * be left out. + * + * A call to startDTD() must be followed by a call to endDTD(). + */ + virtual bool startDTD(const QString &name, + const QString &publicId, + const QString &systemId); + + /** + * Apart from closing the DTD, an new line is also added at end. + */ + virtual bool endDTD(); + + /** + * Creates a processing instruction by name @p target, and content + * @p data. + * + * @returns @c false if failure occurs in writing to the QIODevice, otherwise + * @c true + */ + virtual bool processingInstruction(const QString &target, + const QString &data); + + /** + * Declares a namespace which maps @p prefix to @p namespaceURI. For example, the call: + * + * @code + * startPrefixMapping("xhtml", "http://www.w3.org/1999/xhtml"); + * @endcode + * + * would result in: + * + * @code + * xmlns="http://www.w3.org/1999/xhtml" + * @endcode + */ + virtual bool startPrefixMapping(const QString &prefix, + const QString &namespaceURI); + + /** + * Creates a comment with content @p ch. @p ch is escaped, there's + * no need to do it manually. For example, calling comment() with @p ch + * set to "my comment", results in "<!--my comment-->" in the output. + * + * @note if @p ch contains double hyphen("--"), the produced XML will + * not be well formed. + * + * @returns @c false if failure occurs in writing to the QIODevice, otherwise + * @c true + */ + virtual bool comment(const QString &ch); + + virtual bool startEntity(const QString &name); + virtual bool endEntity(const QString &name); + + /** + * Sets the message which is added as a comment if addModificationMessage() + * is set to @c true. If no message is specified and addModificationMessage() + * is set to @c true, a default message is used. + * + * @see modificationMessage(), setAddMessage() + */ + virtual void setMessage(const QString &msg); + + /** + * The message that is added at the beginning of the XML events + * in a comment node. If no modificationMessage is set via modificationMessage(), + * and addModificationMessage is set to @c true, this message will be used: + * "NOTE: This file was automatically generated by [the application name] at + * [the current date time]. All changes to this file will be lost." + * + * @see setMessage() + */ + virtual QString modificationMessage() const; + + /** + * Closes the QIODevice XMLWriter writes to. + */ + virtual bool endDocument(); + + /** + * Serializes @p ch as if it was sent to characters(). + * + * @returns @c false if failure occurs in writing to the QIODevice, otherwise + * @c true + */ + virtual bool ignorableWhitespace(const QString &ch); + + /** + * This function is not used by XMLWriter, but is implemented + * in order to satisfy QXmlContentHandler's interface. + */ + virtual bool endPrefixMapping(const QString &prefix); + + /** + * This function is not used by XMLWriter, but is implemented + * in order to satisfy QXmlContentHandler's interface. + */ + virtual bool skippedEntity(const QString &name); + + /** + * This function is not used by XMLWriter, but is implemented + * in order to satisfy QXmlContentHandler's interface. + */ + virtual void setDocumentLocator(QXmlLocator *); + + /** + * @returns the device XMLWriter writes its output to. + * XMLWriter does not own the device. + */ + virtual QIODevice *device() const; + + /** + * Sets the QIODevice XMLWriter writes to, to @p device. A device must be specified + * either via this function or in the constructor before XMLWriter is used. + * + * XMLWriter does not claim ownership of @p device. + */ + virtual void setDevice(QIODevice *device); + + /** + * Determines whether the modification message should be inserted as a comment + * before the document element. The message returned by modificationMessage() is used. + * + * If @p toggle is @c true, the message will be added, otherwise not. + */ + virtual void setAddMessage(const bool toggle); + + /** + * Tells whether a modification message will be added. + * + * @see setAddMessage(), modificationMessage() + */ + virtual bool addModificationMessage() const; + + private: + Q_DISABLE_COPY(XMLWriter) + + class Private; + Private *d; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/XQTSTestCase.cpp b/tests/auto/xmlpatternssdk/XQTSTestCase.cpp new file mode 100644 index 0000000..6a8645b --- /dev/null +++ b/tests/auto/xmlpatternssdk/XQTSTestCase.cpp @@ -0,0 +1,286 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QColor> +#include <QFile> +#include <QFileInfo> +#include <QVariant> +#include <QtDebug> + +#include "XQTSTestCase.h" + +using namespace QPatternistSDK; +using namespace QPatternist; + +XQTSTestCase::XQTSTestCase(const Scenario scen, + TreeItem *p, + const QXmlQuery::QueryLanguage lang) : m_isXPath(false) + , m_scenario(scen) + , m_parent(p) + , m_lang(lang) +{ +} + +XQTSTestCase::~XQTSTestCase() +{ + qDeleteAll(m_baseLines); +} + +QVariant XQTSTestCase::data(const Qt::ItemDataRole role, int column) const +{ + if(role == Qt::DisplayRole) + { + if(column == 0) + return title(); + + const TestResult *const tr = testResult(); + if(!tr) + { + if(column == 1) + return TestResult::displayName(TestResult::NotTested); + else + return QString(); + } + const TestResult::Status status = tr->status(); + + switch(column) + { + case 1: + return status == TestResult::Pass ? QString(QChar::fromLatin1('1')) + : QString(QChar::fromLatin1('0')); + case 2: + return status == TestResult::Fail ? QString(QChar::fromLatin1('1')) + : QString(QChar::fromLatin1('0')); + default: + return QString(); + } + } + + if(role != Qt::BackgroundRole) + return QVariant(); + + const TestResult *const tr = testResult(); + + if(!tr) + { + if(column == 0) + return Qt::yellow; + else + return QVariant(); + } + + const TestResult::Status status = tr->status(); + + if(status == TestResult::NotTested || status == TestResult::Unknown) + return Qt::yellow; + + switch(column) + { + case 1: + return status == TestResult::Pass ? Qt::green : QVariant(); + case 2: + return status == TestResult::Fail ? Qt::red : QVariant(); + default: + return QVariant(); + } +} + +QString XQTSTestCase::sourceCode(bool &ok) const +{ + QFile file(m_queryPath.toLocalFile()); + + QString err; + + if(!file.exists()) + err = QString::fromLatin1("Error: %1 does not exist.").arg(file.fileName()); + else if(!QFileInfo(file.fileName()).isFile()) + err = QString::fromLatin1("Error: %1 is not a file, cannot display it.").arg(file.fileName()); + else if(!file.open(QIODevice::ReadOnly)) + err = QString::fromLatin1("Error: Could not open %1. Likely a permission error.") + .arg(file.fileName()); + + if(err.isNull()) /* No errors. */ + { + ok = true; + /* Scary, we assume the query is stored in UTF-8. */ + return QString::fromUtf8(file.readAll()); + } + else + { + ok = false; + return err; + } +} + +int XQTSTestCase::columnCount() const +{ + return 2; +} + +void XQTSTestCase::addBaseLine(TestBaseLine *line) +{ + m_baseLines.append(line); +} + +QString XQTSTestCase::name() const +{ + return m_name; +} + +QString XQTSTestCase::creator() const +{ + return m_creator; +} + +QString XQTSTestCase::description() const +{ + return m_description; +} + +QDate XQTSTestCase::lastModified() const +{ + return m_lastModified; +} + +bool XQTSTestCase::isXPath() const +{ + return m_isXPath; +} + +TestCase::Scenario XQTSTestCase::scenario() const +{ + return m_scenario; +} + +void XQTSTestCase::setName(const QString &n) +{ + m_name = n; +} + +void XQTSTestCase::setCreator(const QString &ctor) +{ + m_creator = ctor; +} + +void XQTSTestCase::setDescription(const QString &descriptionP) +{ + m_description = descriptionP; +} + +void XQTSTestCase::setLastModified(const QDate &date) +{ + m_lastModified = date; +} + +void XQTSTestCase::setIsXPath(const bool isXPathP) +{ + m_isXPath = isXPathP; +} + +void XQTSTestCase::setQueryPath(const QUrl &uri) +{ + m_queryPath = uri; +} + +TreeItem *XQTSTestCase::parent() const +{ + return m_parent; +} + +QString XQTSTestCase::title() const +{ + return m_name; +} + +TestBaseLine::List XQTSTestCase::baseLines() const +{ + Q_ASSERT_X(!m_baseLines.isEmpty(), Q_FUNC_INFO, + qPrintable(QString::fromLatin1("The test %1 has no base lines, it should have at least one.").arg(name()))); + return m_baseLines; +} + +QUrl XQTSTestCase::testCasePath() const +{ + return m_queryPath; +} + +void XQTSTestCase::setExternalVariableLoader(const QPatternist::ExternalVariableLoader::Ptr &loader) +{ + m_externalVariableLoader = loader; +} + +QPatternist::ExternalVariableLoader::Ptr XQTSTestCase::externalVariableLoader() const +{ + return m_externalVariableLoader; +} + +void XQTSTestCase::setContextItemSource(const QUrl &uri) +{ + m_contextItemSource = uri; +} + +QUrl XQTSTestCase::contextItemSource() const +{ + return m_contextItemSource; +} + +QXmlQuery::QueryLanguage XQTSTestCase::language() const +{ + return m_lang; +} + +void XQTSTestCase::setParent(TreeItem *const p) +{ + m_parent = p; +} + +void XQTSTestCase::setInitialTemplateName(const QXmlName &name) +{ + m_initialTemplateName = name; +} + +QXmlName XQTSTestCase::initialTemplateName() const +{ + return m_initialTemplateName; +} + +// vim: et:ts=4:sw=4:sts=4 + diff --git a/tests/auto/xmlpatternssdk/XQTSTestCase.h b/tests/auto/xmlpatternssdk/XQTSTestCase.h new file mode 100644 index 0000000..8872b32 --- /dev/null +++ b/tests/auto/xmlpatternssdk/XQTSTestCase.h @@ -0,0 +1,149 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PatternistSDK_XQTSTestCase_H +#define PatternistSDK_XQTSTestCase_H + +#include <QDate> +#include <QString> +#include <QUrl> + +#include "qexternalvariableloader_p.h" + +#include "TestBaseLine.h" +#include "TestCase.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternistSDK +{ + /** + * @short Represents a test case in a test suite in the XML Query Test Suite. + * + * TestCase is a memory representation of a test case, and maps + * to the @c test-case element in the XQuery Test Suite test + * case catalog. + * + * @ingroup PatternistSDK + * @author Frans Englich <frans.englich@nokia.com> + */ + class Q_PATTERNISTSDK_EXPORT XQTSTestCase : public TestCase + { + public: + XQTSTestCase(const Scenario scen, TreeItem *parent, + const QXmlQuery::QueryLanguage lang = QXmlQuery::XQuery10); + virtual ~XQTSTestCase(); + + /** + * The identifier, the name of the test. For example, "Literals034". + * The name of a test case must be unique. + */ + virtual QString name() const; + virtual QString creator() const; + virtual QString description() const; + /** + * @returns the query inside the file, specified by testCasePath(). Loading + * of the file is not cached in order to avoid complications. + * @param ok is set to @c false if loading the query file fails + */ + virtual QString sourceCode(bool &ok) const; + virtual QUrl testCasePath() const; + virtual QDate lastModified() const; + + bool isXPath() const; + + /** + * What kind of test case this is, what kind of scenario it takes part + * of. For example, whether the test case should evaluate normally or fail. + */ + Scenario scenario() const; + + void setCreator(const QString &creator); + void setLastModified(const QDate &date); + void setDescription(const QString &description); + void setIsXPath(const bool isXPath); + void setName(const QString &name); + void setQueryPath(const QUrl &uri); + void setContextItemSource(const QUrl &uri); + void addBaseLine(TestBaseLine *lines); + void setInitialTemplateName(const QXmlName &name); + + virtual TreeItem *parent() const; + + virtual QVariant data(const Qt::ItemDataRole role, int column) const; + + virtual QString title() const; + virtual TestBaseLine::List baseLines() const; + + virtual int columnCount() const; + + void setExternalVariableLoader(const QPatternist::ExternalVariableLoader::Ptr &loader); + virtual QPatternist::ExternalVariableLoader::Ptr externalVariableLoader() const; + virtual QUrl contextItemSource() const; + virtual QXmlQuery::QueryLanguage language() const; + void setParent(TreeItem *const parent); + virtual QXmlName initialTemplateName() const; + + private: + QString m_name; + QString m_creator; + QString m_description; + QUrl m_queryPath; + bool m_isXPath; + QDate m_lastModified; + const Scenario m_scenario; + TreeItem * m_parent; + TestBaseLine::List m_baseLines; + QPatternist::ExternalVariableLoader::Ptr m_externalVariableLoader; + QUrl m_contextItemSource; + QXmlQuery::QueryLanguage m_lang; + QXmlName m_initialTemplateName; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/XSDTSTestCase.cpp b/tests/auto/xmlpatternssdk/XSDTSTestCase.cpp new file mode 100644 index 0000000..3cbb681 --- /dev/null +++ b/tests/auto/xmlpatternssdk/XSDTSTestCase.cpp @@ -0,0 +1,375 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the autotests of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QColor> +#include <QFile> +#include <QFileInfo> +#include <QVariant> +#include <QtDebug> + +#include "XSDTSTestCase.h" + +#include "qxmlschema.h" +#include "qxmlschemavalidator.h" + +using namespace QPatternistSDK; +using namespace QPatternist; + +XSDTSTestCase::XSDTSTestCase(const Scenario scen, TreeItem *p, TestType testType) + : m_scenario(scen) + , m_parent(p) + , m_testType(testType) +{ +} + +XSDTSTestCase::~XSDTSTestCase() +{ + qDeleteAll(m_baseLines); +} + +TestResult::List XSDTSTestCase::execute(const ExecutionStage, TestSuite*) +{ + ErrorHandler errHandler; + ErrorHandler::installQtMessageHandler(&errHandler); + + TestResult::List retval; + TestResult::Status resultStatus = TestResult::Unknown; + QString serialized; + + if (m_testType == SchemaTest) { + executeSchemaTest(resultStatus, serialized, &errHandler); + } else { + executeInstanceTest(resultStatus, serialized, &errHandler); + } + + resultStatus = TestBaseLine::scan(serialized, baseLines()); + Q_ASSERT(resultStatus != TestResult::Unknown); + + m_result = new TestResult(name(), resultStatus, 0, errHandler.messages(), + QPatternist::Item::List(), serialized); + retval.append(m_result); + ErrorHandler::installQtMessageHandler(0); + changed(this); + return retval; +} + +void XSDTSTestCase::executeSchemaTest(TestResult::Status &resultStatus, QString &serialized, QAbstractMessageHandler *handler) +{ + QFile file(m_schemaUri.path()); + if (!file.open(QIODevice::ReadOnly)) { + resultStatus = TestResult::Fail; + serialized = QString(); + return; + } + + QXmlSchema schema; + schema.setMessageHandler(handler); + schema.load(&file, m_schemaUri); + + if (schema.isValid()) { + resultStatus = TestResult::Pass; + serialized = QString::fromLatin1("true"); + } else { + resultStatus = TestResult::Pass; + serialized = QString::fromLatin1("false"); + } +} + +void XSDTSTestCase::executeInstanceTest(TestResult::Status &resultStatus, QString &serialized, QAbstractMessageHandler *handler) +{ + QFile instanceFile(m_instanceUri.path()); + if (!instanceFile.open(QIODevice::ReadOnly)) { + resultStatus = TestResult::Fail; + serialized = QString(); + return; + } + + QXmlSchema schema; + if (m_schemaUri.isValid()) { + QFile file(m_schemaUri.path()); + if (!file.open(QIODevice::ReadOnly)) { + resultStatus = TestResult::Fail; + serialized = QString(); + return; + } + + schema.setMessageHandler(handler); + schema.load(&file, m_schemaUri); + + if (!schema.isValid()) { + resultStatus = TestResult::Pass; + serialized = QString::fromLatin1("false"); + return; + } + } + + QXmlSchemaValidator validator(schema); + validator.setMessageHandler(handler); + + qDebug("check %s", qPrintable(m_instanceUri.path())); + if (validator.validate(&instanceFile, m_instanceUri)) { + resultStatus = TestResult::Pass; + serialized = QString::fromLatin1("true"); + } else { + resultStatus = TestResult::Pass; + serialized = QString::fromLatin1("false"); + } +} + +QVariant XSDTSTestCase::data(const Qt::ItemDataRole role, int column) const +{ + if(role == Qt::DisplayRole) + { + if(column == 0) + return title(); + + const TestResult *const tr = testResult(); + if(!tr) + { + if(column == 1) + return TestResult::displayName(TestResult::NotTested); + else + return QString(); + } + const TestResult::Status status = tr->status(); + + switch(column) + { + case 1: + return status == TestResult::Pass ? QString(QChar::fromLatin1('1')) + : QString(QChar::fromLatin1('0')); + case 2: + return status == TestResult::Fail ? QString(QChar::fromLatin1('1')) + : QString(QChar::fromLatin1('0')); + default: + return QString(); + } + } + + if(role != Qt::BackgroundRole) + return QVariant(); + + const TestResult *const tr = testResult(); + + if(!tr) + { + if(column == 0) + return Qt::yellow; + else + return QVariant(); + } + + const TestResult::Status status = tr->status(); + + if(status == TestResult::NotTested || status == TestResult::Unknown) + return Qt::yellow; + + switch(column) + { + case 1: + return status == TestResult::Pass ? Qt::green : QVariant(); + case 2: + return status == TestResult::Fail ? Qt::red : QVariant(); + default: + return QVariant(); + } +} + +QString XSDTSTestCase::sourceCode(bool &ok) const +{ + QFile file((m_testType == SchemaTest ? m_schemaUri : m_instanceUri).toLocalFile()); + + QString err; + + if(!file.exists()) + err = QString::fromLatin1("Error: %1 does not exist.").arg(file.fileName()); + else if(!QFileInfo(file.fileName()).isFile()) + err = QString::fromLatin1("Error: %1 is not a file, cannot display it.").arg(file.fileName()); + else if(!file.open(QIODevice::ReadOnly)) + err = QString::fromLatin1("Error: Could not open %1. Likely a permission error.") + .arg(file.fileName()); + + if(err.isNull()) /* No errors. */ + { + ok = true; + /* Scary, we assume the query is stored in UTF-8. */ + return QString::fromUtf8(file.readAll()); + } + else + { + ok = false; + return err; + } +} + +int XSDTSTestCase::columnCount() const +{ + return 2; +} + +void XSDTSTestCase::addBaseLine(TestBaseLine *line) +{ + m_baseLines.append(line); +} + +QString XSDTSTestCase::name() const +{ + return m_name; +} + +QString XSDTSTestCase::creator() const +{ + return m_creator; +} + +QString XSDTSTestCase::description() const +{ + return m_description; +} + +QDate XSDTSTestCase::lastModified() const +{ + return m_lastModified; +} + +bool XSDTSTestCase::isXPath() const +{ + return false; +} + +TestCase::Scenario XSDTSTestCase::scenario() const +{ + return m_scenario; +} + +void XSDTSTestCase::setName(const QString &n) +{ + m_name = n; +} + +void XSDTSTestCase::setCreator(const QString &ctor) +{ + m_creator = ctor; +} + +void XSDTSTestCase::setDescription(const QString &descriptionP) +{ + m_description = descriptionP; +} + +void XSDTSTestCase::setLastModified(const QDate &date) +{ + m_lastModified = date; +} + +void XSDTSTestCase::setSchemaUri(const QUrl &uri) +{ + m_schemaUri = uri; +} + +void XSDTSTestCase::setInstanceUri(const QUrl &uri) +{ + m_instanceUri = uri; +} + +TreeItem *XSDTSTestCase::parent() const +{ + return m_parent; +} + +QString XSDTSTestCase::title() const +{ + return m_name; +} + +TestBaseLine::List XSDTSTestCase::baseLines() const +{ + Q_ASSERT_X(!m_baseLines.isEmpty(), Q_FUNC_INFO, + qPrintable(QString::fromLatin1("The test %1 has no base lines, it should have at least one.").arg(name()))); + return m_baseLines; +} + +QUrl XSDTSTestCase::schemaUri() const +{ + return m_schemaUri; +} + +QUrl XSDTSTestCase::instanceUri() const +{ + return m_instanceUri; +} + +void XSDTSTestCase::setContextItemSource(const QUrl &uri) +{ + m_contextItemSource = uri; +} + +QUrl XSDTSTestCase::contextItemSource() const +{ + return m_contextItemSource; +} + +void XSDTSTestCase::setParent(TreeItem *const p) +{ + m_parent = p; +} + +QPatternist::ExternalVariableLoader::Ptr XSDTSTestCase::externalVariableLoader() const +{ + return QPatternist::ExternalVariableLoader::Ptr(); +} + +TestResult *XSDTSTestCase::testResult() const +{ + return m_result; +} + +TestItem::ResultSummary XSDTSTestCase::resultSummary() const +{ + if(m_result) + return ResultSummary(m_result->status() == TestResult::Pass ? 1 : 0, + 1); + + return ResultSummary(0, 1); +} + +// vim: et:ts=4:sw=4:sts=4 + diff --git a/tests/auto/xmlpatternssdk/XSDTSTestCase.h b/tests/auto/xmlpatternssdk/XSDTSTestCase.h new file mode 100644 index 0000000..947687a --- /dev/null +++ b/tests/auto/xmlpatternssdk/XSDTSTestCase.h @@ -0,0 +1,161 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the autotests of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PatternistSDK_XSDTSTestCase_H +#define PatternistSDK_XSDTSTestCase_H + +#include <QDate> +#include <QString> +#include <QUrl> + +#include "TestBaseLine.h" +#include "TestCase.h" + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +namespace QPatternistSDK +{ + /** + * @short Represents a test case in a test suite in the XML Query Test Suite. + * + * TestCase is a memory representation of a test case, and maps + * to the @c test-case element in the XQuery Test Suite test + * case catalog. + * + * @ingroup PatternistSDK + * @author Frans Englich <frans.englich@nokia.com> + */ + class Q_PATTERNISTSDK_EXPORT XSDTSTestCase : public TestCase + { + public: + enum TestType + { + SchemaTest, + InstanceTest + }; + + XSDTSTestCase(const Scenario scen, TreeItem *parent, TestType testType); + virtual ~XSDTSTestCase(); + + /** + * Executes the test, and returns the result. The returned list + * will always contain exactly one TestResult. + * + * @p stage is ignored when running out-of-process. + */ + virtual TestResult::List execute(const ExecutionStage stage, + TestSuite *ts); + /** + * The identifier, the name of the test. For example, "Literals034". + * The name of a test case must be unique. + */ + virtual QString name() const; + virtual QString creator() const; + virtual QString description() const; + /** + * @returns the query inside the file, specified by testCasePath(). Loading + * of the file is not cached in order to avoid complications. + * @param ok is set to @c false if loading the query file fails + */ + virtual QString sourceCode(bool &ok) const; + virtual QUrl schemaUri() const; + virtual QUrl instanceUri() const; + virtual QUrl testCasePath() const {return QUrl();} + virtual QDate lastModified() const; + + bool isXPath() const; + + /** + * What kind of test case this is, what kind of scenario it takes part + * of. For example, whether the test case should evaluate normally or fail. + */ + Scenario scenario() const; + + void setCreator(const QString &creator); + void setLastModified(const QDate &date); + void setDescription(const QString &description); + void setName(const QString &name); + void setSchemaUri(const QUrl &uri); + void setInstanceUri(const QUrl &uri); + void setTestCasePath(const QUrl & /* uri */) {} + void setContextItemSource(const QUrl &uri); + void addBaseLine(TestBaseLine *lines); + + virtual TreeItem *parent() const; + + virtual QVariant data(const Qt::ItemDataRole role, int column) const; + + virtual QString title() const; + virtual TestBaseLine::List baseLines() const; + + virtual int columnCount() const; + + virtual QUrl contextItemSource() const; + void setParent(TreeItem *const parent); + virtual QPatternist::ExternalVariableLoader::Ptr externalVariableLoader() const; + virtual TestResult *testResult() const; + virtual ResultSummary resultSummary() const; + + private: + void executeSchemaTest(TestResult::Status &resultStatus, QString &serialized, QAbstractMessageHandler *handler); + void executeInstanceTest(TestResult::Status &resultStatus, QString &serialized, QAbstractMessageHandler *handler); + + QString m_name; + QString m_creator; + QString m_description; + QUrl m_schemaUri; + QUrl m_instanceUri; + QDate m_lastModified; + const Scenario m_scenario; + TreeItem * m_parent; + TestBaseLine::List m_baseLines; + QUrl m_contextItemSource; + TestType m_testType; + QPointer<TestResult> m_result; + }; +} + +QT_END_NAMESPACE +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/XSDTestSuiteHandler.cpp b/tests/auto/xmlpatternssdk/XSDTestSuiteHandler.cpp new file mode 100644 index 0000000..a868d19 --- /dev/null +++ b/tests/auto/xmlpatternssdk/XSDTestSuiteHandler.cpp @@ -0,0 +1,910 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the autotests of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtDebug> + +#include "qacceltreeresourceloader_p.h" +#include "qnetworkaccessdelegator_p.h" + +#include "Global.h" +#include "TestBaseLine.h" +#include "TestGroup.h" + +#include "XSDTestSuiteHandler.h" +#include "XSDTSTestCase.h" + +using namespace QPatternistSDK; + +extern QNetworkAccessManager s_networkManager; + +XSDTestSuiteHandler::XSDTestSuiteHandler(const QUrl &catalogFile) : m_ts(0) + , m_catalogFile(catalogFile) + , m_inSchemaTest(false) + , m_inInstanceTest(false) + , m_inTestGroup(false) + , m_inDescription(false) + , m_schemaBlacklisted(false) + , m_counter(0) +{ + Q_ASSERT(!m_catalogFile.isRelative()); + m_ts = new TestSuite(); + m_topLevelGroup = new TestGroup(m_ts); + m_topLevelGroup->setTitle("XML Schema Test Suite"); + m_ts->appendChild(m_topLevelGroup); + + // exclude these test cases, as they break our current state machine + m_blackList << QLatin1String("addB099") + << QLatin1String("addB118") + << QLatin1String("elemJ003") + << QLatin1String("elemJ011") + << QLatin1String("elemZ004") + << QLatin1String("elemZ020") + << QLatin1String("groupH021v") + << QLatin1String("groupJ009v") + << QLatin1String("name00101m2") + << QLatin1String("schL5") + << QLatin1String("ste110") + << QLatin1String("stZ007") + << QLatin1String("stZ047") + << QLatin1String("stZ055") + << QLatin1String("addB049") + << QLatin1String("addB068") + << QLatin1String("addB078") + << QLatin1String("addB078A") + << QLatin1String("addB078B") + << QLatin1String("addB167") + << QLatin1String("addB191") + << QLatin1String("isDefault060_2") + << QLatin1String("isDefault069") + << QLatin1String("annotB025") + << QLatin1String("base64Binary_enumeration003_1321") + << QLatin1String("anyURI_a001_1336") + << QLatin1String("anyURI_a001_1336") + << QLatin1String("anyURI_a003_1338") + << QLatin1String("anyURI_a004_1339") + << QLatin1String("anyURI_b004_1354") + << QLatin1String("anyURI_b004_1354") + << QLatin1String("anyURI_b006_1356") + << QLatin1String("QName_length001_1357") + << QLatin1String("QName_length003_1359") + << QLatin1String("QName_minLength003_1362") + << QLatin1String("QName_maxLength001_1364") + << QLatin1String("NOTATION_length001_1372") + << QLatin1String("NOTATION_length003_1374") + << QLatin1String("NOTATION_minLength003_1377") + << QLatin1String("NOTATION_maxLength001_1379") + << QLatin1String("hexBinary003_2069") + << QLatin1String("QName009_2092") + << QLatin1String("dtZ107447_a_2245") + << QLatin1String("elemE001") + << QLatin1String("elemE002") + << QLatin1String("elemE003") + << QLatin1String("elemE004") + << QLatin1String("elemE005") + << QLatin1String("elemT026") + << QLatin1String("elemT027") + << QLatin1String("elemT028") + << QLatin1String("elemT029") + << QLatin1String("elemT054") + << QLatin1String("elemT055") + << QLatin1String("elemT056") + << QLatin1String("elemT057") + << QLatin1String("elemZ006") + << QLatin1String("elemZ007") + << QLatin1String("elemZ026") + << QLatin1String("elemZ027_c") + << QLatin1String("elemZ028c") + << QLatin1String("elemZ028d") + << QLatin1String("elemZ028f1") + << QLatin1String("elemZ028f1") + << QLatin1String("elemZ028f2") + << QLatin1String("elemZ028f2") + << QLatin1String("elemZ028f3") + << QLatin1String("elemZ028f3") + << QLatin1String("elemZ031") + << QLatin1String("errF001") + << QLatin1String("idC019") + << QLatin1String("idL100") + << QLatin1String("idZ011") + << QLatin1String("idZ015") + << QLatin1String("mgO013") + << QLatin1String("particlesA012") + << QLatin1String("particlesA013") + << QLatin1String("particlesA014") + << QLatin1String("particlesA015") + << QLatin1String("particlesHa161") + << QLatin1String("particlesHb008") + << QLatin1String("particlesHb011") + << QLatin1String("particlesIe003") + << QLatin1String("particlesIg003") + << QLatin1String("particlesIg004") + << QLatin1String("particlesJb003") + << QLatin1String("particlesJd003") + << QLatin1String("particlesJf003") + << QLatin1String("particlesJk003") + << QLatin1String("particlesOb001") + << QLatin1String("particlesOb002") + << QLatin1String("particlesOb004") + << QLatin1String("particlesOb008") + << QLatin1String("particlesOb009") + << QLatin1String("particlesOb013") + << QLatin1String("particlesOb018") + << QLatin1String("particlesQ005") + << QLatin1String("particlesS002") + << QLatin1String("particlesT002") + << QLatin1String("particlesT009") + << QLatin1String("particlesT014") + << QLatin1String("particlesV001") + << QLatin1String("particlesV002") + << QLatin1String("particlesV020") + << QLatin1String("particlesZ001") + << QLatin1String("particlesZ005") + << QLatin1String("particlesZ007") + << QLatin1String("particlesZ023") + << QLatin1String("particlesZ024") + << QLatin1String("particlesZ026") + << QLatin1String("particlesZ028") + << QLatin1String("particlesZ033_c") + << QLatin1String("particlesZ033_d") + << QLatin1String("particlesZ033_e") + << QLatin1String("particlesZ033_f") + << QLatin1String("particlesZ033_g") + << QLatin1String("particlesZ034_a1") + << QLatin1String("particlesZ034_a2") + << QLatin1String("particlesZ034_a3") + << QLatin1String("particlesZ034_b") + << QLatin1String("particlesZ035_a") + << QLatin1String("particlesZ035_b") + << QLatin1String("particlesZ036_a") + << QLatin1String("particlesZ036_b1") + << QLatin1String("particlesZ036_b2") + << QLatin1String("particlesZ036_c") +/* + << QLatin1String("reC65") + << QLatin1String("reC66") + << QLatin1String("reC67") + << QLatin1String("reC68") + << QLatin1String("reF58") + << QLatin1String("reG50") + << QLatin1String("reJ11") + << QLatin1String("reJ13") + << QLatin1String("reJ19") + << QLatin1String("reJ21") + << QLatin1String("reJ23") + << QLatin1String("reJ25") + << QLatin1String("reJ29") + << QLatin1String("reJ31") + << QLatin1String("reJ33") + << QLatin1String("reJ35") + << QLatin1String("reJ61") + << QLatin1String("reJ69") + << QLatin1String("reJ75") + << QLatin1String("reJ77") + << QLatin1String("reL98") + << QLatin1String("reL99") + << QLatin1String("reM98") + << QLatin1String("reN99") + << QLatin1String("reS21") + << QLatin1String("reS42") + << QLatin1String("reT63") + << QLatin1String("reT84") + << QLatin1String("reDG2") + << QLatin1String("RegexTest_9") + << QLatin1String("RegexTest_11") + << QLatin1String("RegexTest_14") + << QLatin1String("RegexTest_15") + << QLatin1String("RegexTest_16") + << QLatin1String("RegexTest_17") + << QLatin1String("RegexTest_23") + << QLatin1String("RegexTest_24") + << QLatin1String("RegexTest_25") + << QLatin1String("RegexTest_26") + << QLatin1String("RegexTest_27") + << QLatin1String("RegexTest_28") + << QLatin1String("RegexTest_30") + << QLatin1String("RegexTest_30") + << QLatin1String("RegexTest_33") + << QLatin1String("RegexTest_34") + << QLatin1String("RegexTest_34") + << QLatin1String("RegexTest_43") + << QLatin1String("RegexTest_44") + << QLatin1String("RegexTest_45") + << QLatin1String("RegexTest_46") + << QLatin1String("RegexTest_47") + << QLatin1String("RegexTest_48") + << QLatin1String("RegexTest_49") + << QLatin1String("RegexTest_50") + << QLatin1String("RegexTest_51") + << QLatin1String("RegexTest_52") + << QLatin1String("RegexTest_53") + << QLatin1String("RegexTest_54") + << QLatin1String("RegexTest_55") + << QLatin1String("RegexTest_56") + << QLatin1String("RegexTest_57") + << QLatin1String("RegexTest_57") + << QLatin1String("RegexTest_58") + << QLatin1String("RegexTest_58") + << QLatin1String("RegexTest_65") + << QLatin1String("RegexTest_113") + << QLatin1String("RegexTest_116") + << QLatin1String("RegexTest_119") + << QLatin1String("RegexTest_120") + << QLatin1String("RegexTest_121") + << QLatin1String("RegexTest_141") + << QLatin1String("RegexTest_142") + << QLatin1String("RegexTest_143") + << QLatin1String("RegexTest_145") + << QLatin1String("RegexTest_146") + << QLatin1String("RegexTest_147") + << QLatin1String("RegexTest_148") + << QLatin1String("RegexTest_149") + << QLatin1String("RegexTest_150") + << QLatin1String("RegexTest_151") + << QLatin1String("RegexTest_152") + << QLatin1String("RegexTest_154") + << QLatin1String("RegexTest_155") + << QLatin1String("RegexTest_156") + << QLatin1String("RegexTest_157") + << QLatin1String("RegexTest_158") + << QLatin1String("RegexTest_163") + << QLatin1String("RegexTest_164") + << QLatin1String("RegexTest_165") + << QLatin1String("RegexTest_166") + << QLatin1String("RegexTest_167") + << QLatin1String("RegexTest_168") + << QLatin1String("RegexTest_169") + << QLatin1String("RegexTest_170") + << QLatin1String("RegexTest_171") + << QLatin1String("RegexTest_172") + << QLatin1String("RegexTest_173") + << QLatin1String("RegexTest_174") + << QLatin1String("RegexTest_178") + << QLatin1String("RegexTest_194") + << QLatin1String("RegexTest_194") + << QLatin1String("RegexTest_195") + << QLatin1String("RegexTest_195") + << QLatin1String("RegexTest_196") + << QLatin1String("RegexTest_196") + << QLatin1String("RegexTest_197") + << QLatin1String("RegexTest_198") + << QLatin1String("RegexTest_199") + << QLatin1String("RegexTest_200") + << QLatin1String("RegexTest_200") + << QLatin1String("RegexTest_201") + << QLatin1String("RegexTest_201") + << QLatin1String("RegexTest_202") + << QLatin1String("RegexTest_202") + << QLatin1String("RegexTest_203") + << QLatin1String("RegexTest_204") + << QLatin1String("RegexTest_205") + << QLatin1String("RegexTest_206") + << QLatin1String("RegexTest_207") + << QLatin1String("RegexTest_208") + << QLatin1String("RegexTest_209") + << QLatin1String("RegexTest_209") + << QLatin1String("RegexTest_210") + << QLatin1String("RegexTest_210") + << QLatin1String("RegexTest_211") + << QLatin1String("RegexTest_211") + << QLatin1String("RegexTest_212") + << QLatin1String("RegexTest_213") + << QLatin1String("RegexTest_214") + << QLatin1String("RegexTest_215") + << QLatin1String("RegexTest_216") + << QLatin1String("RegexTest_217") + << QLatin1String("RegexTest_218") + << QLatin1String("RegexTest_220") + << QLatin1String("RegexTest_221") + << QLatin1String("RegexTest_222") + << QLatin1String("RegexTest_226") + << QLatin1String("RegexTest_230") + << QLatin1String("RegexTest_232") + << QLatin1String("RegexTest_233") + << QLatin1String("RegexTest_294") + << QLatin1String("RegexTest_294") + << QLatin1String("RegexTest_295") + << QLatin1String("RegexTest_295") + << QLatin1String("RegexTest_299") + << QLatin1String("RegexTest_300") + << QLatin1String("RegexTest_301") + << QLatin1String("RegexTest_302") + << QLatin1String("RegexTest_303") + << QLatin1String("RegexTest_304") + << QLatin1String("RegexTest_305") + << QLatin1String("RegexTest_306") + << QLatin1String("RegexTest_307") + << QLatin1String("RegexTest_308") + << QLatin1String("RegexTest_309") + << QLatin1String("RegexTest_310") + << QLatin1String("RegexTest_311") + << QLatin1String("RegexTest_312") + << QLatin1String("RegexTest_313") + << QLatin1String("RegexTest_314") + << QLatin1String("RegexTest_315") + << QLatin1String("RegexTest_315") + << QLatin1String("RegexTest_316") + << QLatin1String("RegexTest_316") + << QLatin1String("RegexTest_317") + << QLatin1String("RegexTest_317") + << QLatin1String("RegexTest_440") + << QLatin1String("RegexTest_441") + << QLatin1String("RegexTest_442") + << QLatin1String("RegexTest_443") + << QLatin1String("RegexTest_448") + << QLatin1String("RegexTest_449") + << QLatin1String("RegexTest_450") + << QLatin1String("RegexTest_451") + << QLatin1String("RegexTest_458") + << QLatin1String("RegexTest_464") + << QLatin1String("RegexTest_464") + << QLatin1String("RegexTest_465") + << QLatin1String("RegexTest_469") + << QLatin1String("RegexTest_470") + << QLatin1String("RegexTest_471") + << QLatin1String("RegexTest_472") + << QLatin1String("RegexTest_473") + << QLatin1String("RegexTest_477") + << QLatin1String("RegexTest_478") + << QLatin1String("RegexTest_478") + << QLatin1String("RegexTest_479") + << QLatin1String("RegexTest_480") + << QLatin1String("RegexTest_481") + << QLatin1String("RegexTest_482") + << QLatin1String("RegexTest_482") + << QLatin1String("RegexTest_483") + << QLatin1String("RegexTest_483") + << QLatin1String("RegexTest_484") + << QLatin1String("RegexTest_487") + << QLatin1String("RegexTest_516") + << QLatin1String("RegexTest_516") + << QLatin1String("RegexTest_517") + << QLatin1String("RegexTest_517") + << QLatin1String("RegexTest_518") + << QLatin1String("RegexTest_518") + << QLatin1String("RegexTest_519") + << QLatin1String("RegexTest_519") + << QLatin1String("RegexTest_521") + << QLatin1String("RegexTest_523") + << QLatin1String("RegexTest_524") + << QLatin1String("RegexTest_524") + << QLatin1String("RegexTest_586") + << QLatin1String("RegexTest_587") + << QLatin1String("RegexTest_592") + << QLatin1String("RegexTest_593") + << QLatin1String("RegexTest_594") + << QLatin1String("RegexTest_595") + << QLatin1String("RegexTest_596") + << QLatin1String("RegexTest_597") + << QLatin1String("RegexTest_598") + << QLatin1String("RegexTest_599") + << QLatin1String("RegexTest_600") + << QLatin1String("RegexTest_601") + << QLatin1String("RegexTest_602") + << QLatin1String("RegexTest_603") + << QLatin1String("RegexTest_604") + << QLatin1String("RegexTest_605") + << QLatin1String("RegexTest_648") + << QLatin1String("RegexTest_655") + << QLatin1String("RegexTest_688") + << QLatin1String("RegexTest_696") + << QLatin1String("RegexTest_697") + << QLatin1String("RegexTest_698") + << QLatin1String("RegexTest_700") + << QLatin1String("RegexTest_701") + << QLatin1String("RegexTest_702") + << QLatin1String("RegexTest_703") + << QLatin1String("RegexTest_704") + << QLatin1String("RegexTest_705") + << QLatin1String("RegexTest_706") + << QLatin1String("RegexTest_707") + << QLatin1String("RegexTest_717") + << QLatin1String("RegexTest_718") + << QLatin1String("RegexTest_719") + << QLatin1String("RegexTest_724") + << QLatin1String("RegexTest_725") + << QLatin1String("RegexTest_726") + << QLatin1String("RegexTest_727") + << QLatin1String("RegexTest_728") + << QLatin1String("RegexTest_729") + << QLatin1String("RegexTest_730") + << QLatin1String("RegexTest_731") + << QLatin1String("RegexTest_732") + << QLatin1String("RegexTest_733") + << QLatin1String("RegexTest_743") + << QLatin1String("RegexTest_755") + << QLatin1String("RegexTest_756") + << QLatin1String("RegexTest_761") + << QLatin1String("RegexTest_762") + << QLatin1String("RegexTest_781") + << QLatin1String("RegexTest_782") + << QLatin1String("RegexTest_783") + << QLatin1String("RegexTest_790") + << QLatin1String("RegexTest_791") + << QLatin1String("RegexTest_824") + << QLatin1String("RegexTest_826") + << QLatin1String("RegexTest_827") + << QLatin1String("RegexTest_836") + << QLatin1String("RegexTest_837") + << QLatin1String("RegexTest_841") + << QLatin1String("RegexTest_842") + << QLatin1String("RegexTest_843") + << QLatin1String("RegexTest_844") + << QLatin1String("RegexTest_845") + << QLatin1String("RegexTest_846") + << QLatin1String("RegexTest_847") + << QLatin1String("RegexTest_848") + << QLatin1String("RegexTest_851") + << QLatin1String("RegexTest_852") + << QLatin1String("RegexTest_853") + << QLatin1String("RegexTest_854") + << QLatin1String("RegexTest_855") + << QLatin1String("RegexTest_856") + << QLatin1String("RegexTest_857") + << QLatin1String("RegexTest_861") + << QLatin1String("RegexTest_862") + << QLatin1String("RegexTest_863") + << QLatin1String("RegexTest_864") + << QLatin1String("RegexTest_865") + << QLatin1String("RegexTest_866") + << QLatin1String("RegexTest_870") + << QLatin1String("RegexTest_879") + << QLatin1String("RegexTest_880") + << QLatin1String("RegexTest_888") + << QLatin1String("RegexTest_889") + << QLatin1String("RegexTest_890") + << QLatin1String("RegexTest_891") + << QLatin1String("RegexTest_892") + << QLatin1String("RegexTest_893") + << QLatin1String("RegexTest_894") + << QLatin1String("RegexTest_895") + << QLatin1String("RegexTest_896") + << QLatin1String("RegexTest_897") + << QLatin1String("RegexTest_898") + << QLatin1String("RegexTest_899") + << QLatin1String("RegexTest_900") + << QLatin1String("RegexTest_901") + << QLatin1String("RegexTest_902") + << QLatin1String("RegexTest_903") + << QLatin1String("RegexTest_904") + << QLatin1String("RegexTest_905") + << QLatin1String("RegexTest_906") + << QLatin1String("RegexTest_907") + << QLatin1String("RegexTest_908") + << QLatin1String("RegexTest_909") + << QLatin1String("RegexTest_910") + << QLatin1String("RegexTest_911") + << QLatin1String("RegexTest_912") + << QLatin1String("RegexTest_913") + << QLatin1String("RegexTest_914") + << QLatin1String("RegexTest_915") + << QLatin1String("RegexTest_916") + << QLatin1String("RegexTest_917") + << QLatin1String("RegexTest_918") + << QLatin1String("RegexTest_919") + << QLatin1String("RegexTest_920") + << QLatin1String("RegexTest_921") + << QLatin1String("RegexTest_922") + << QLatin1String("RegexTest_923") + << QLatin1String("RegexTest_924") + << QLatin1String("RegexTest_925") + << QLatin1String("RegexTest_926") + << QLatin1String("RegexTest_928") + << QLatin1String("RegexTest_929") + << QLatin1String("RegexTest_930") + << QLatin1String("RegexTest_936") + << QLatin1String("RegexTest_937") + << QLatin1String("RegexTest_938") + << QLatin1String("RegexTest_939") + << QLatin1String("RegexTest_940") + << QLatin1String("RegexTest_941") + << QLatin1String("RegexTest_942") + << QLatin1String("RegexTest_943") + << QLatin1String("RegexTest_944") + << QLatin1String("RegexTest_945") + << QLatin1String("RegexTest_946") + << QLatin1String("RegexTest_949") + << QLatin1String("RegexTest_950") + << QLatin1String("RegexTest_951") + << QLatin1String("RegexTest_952") + << QLatin1String("RegexTest_953") + << QLatin1String("RegexTest_954") + << QLatin1String("RegexTest_955") + << QLatin1String("RegexTest_956") + << QLatin1String("RegexTest_957") + << QLatin1String("RegexTest_958") + << QLatin1String("RegexTest_959") + << QLatin1String("RegexTest_960") + << QLatin1String("RegexTest_961") + << QLatin1String("RegexTest_962") + << QLatin1String("RegexTest_963") + << QLatin1String("RegexTest_964") + << QLatin1String("RegexTest_976") + << QLatin1String("RegexTest_977") + << QLatin1String("RegexTest_988") + << QLatin1String("RegexTest_989") + << QLatin1String("RegexTest_990") + << QLatin1String("RegexTest_991") + << QLatin1String("RegexTest_994") + << QLatin1String("RegexTest_995") + << QLatin1String("RegexTest_996") + << QLatin1String("RegexTest_997") + << QLatin1String("RegexTest_1000") + << QLatin1String("RegexTest_1001") + << QLatin1String("RegexTest_1002") + << QLatin1String("RegexTest_1003") + << QLatin1String("RegexTest_1004") + << QLatin1String("RegexTest_1007") + << QLatin1String("RegexTest_1008") + << QLatin1String("RegexTest_1009") + << QLatin1String("RegexTest_1010") + << QLatin1String("RegexTest_1011") + << QLatin1String("RegexTest_1012") + << QLatin1String("RegexTest_1013") + << QLatin1String("RegexTest_1014") + << QLatin1String("RegexTest_1015") + << QLatin1String("RegexTest_1016") + << QLatin1String("RegexTest_1017") + << QLatin1String("RegexTest_1018") + << QLatin1String("RegexTest_1019") + << QLatin1String("RegexTest_1070") + << QLatin1String("RegexTest_1071") + << QLatin1String("RegexTest_1076") + << QLatin1String("RegexTest_1077") + << QLatin1String("RegexTest_1078") + << QLatin1String("RegexTest_1079") + << QLatin1String("RegexTest_1080") + << QLatin1String("RegexTest_1081") + << QLatin1String("RegexTest_1082") + << QLatin1String("RegexTest_1083") + << QLatin1String("RegexTest_1084") + << QLatin1String("RegexTest_1085") + << QLatin1String("RegexTest_1086") + << QLatin1String("RegexTest_1087") + << QLatin1String("RegexTest_1088") + << QLatin1String("RegexTest_1089") + << QLatin1String("RegexTest_1132") + << QLatin1String("RegexTest_1139") + << QLatin1String("RegexTest_1172") + << QLatin1String("RegexTest_1180") + << QLatin1String("RegexTest_1181") + << QLatin1String("RegexTest_1182") + << QLatin1String("RegexTest_1184") + << QLatin1String("RegexTest_1185") + << QLatin1String("RegexTest_1186") + << QLatin1String("RegexTest_1187") + << QLatin1String("RegexTest_1188") + << QLatin1String("RegexTest_1189") + << QLatin1String("RegexTest_1190") + << QLatin1String("RegexTest_1191") + << QLatin1String("RegexTest_1201") + << QLatin1String("RegexTest_1202") + << QLatin1String("RegexTest_1203") + << QLatin1String("RegexTest_1208") + << QLatin1String("RegexTest_1209") + << QLatin1String("RegexTest_1210") + << QLatin1String("RegexTest_1211") + << QLatin1String("RegexTest_1212") + << QLatin1String("RegexTest_1213") + << QLatin1String("RegexTest_1214") + << QLatin1String("RegexTest_1215") + << QLatin1String("RegexTest_1216") + << QLatin1String("RegexTest_1217") + << QLatin1String("RegexTest_1227") + << QLatin1String("RegexTest_1239") + << QLatin1String("RegexTest_1240") + << QLatin1String("RegexTest_1245") + << QLatin1String("RegexTest_1246") + << QLatin1String("RegexTest_1265") + << QLatin1String("RegexTest_1266") + << QLatin1String("RegexTest_1267") + << QLatin1String("RegexTest_1274") + << QLatin1String("RegexTest_1275") + << QLatin1String("RegexTest_1308") + << QLatin1String("RegexTest_1310") + << QLatin1String("RegexTest_1311") + << QLatin1String("RegexTest_1320") + << QLatin1String("RegexTest_1321") + << QLatin1String("RegexTest_1322") + << QLatin1String("RegexTest_1323") + << QLatin1String("RegexTest_1324") + << QLatin1String("RegexTest_1325") + << QLatin1String("RegexTest_1326") + << QLatin1String("RegexTest_1327") + << QLatin1String("RegexTest_1328") + << QLatin1String("RegexTest_1329") + << QLatin1String("RegexTest_1330") + << QLatin1String("RegexTest_1331") + << QLatin1String("RegexTest_1332") + << QLatin1String("RegexTest_1335") + << QLatin1String("RegexTest_1336") + << QLatin1String("RegexTest_1337") + << QLatin1String("RegexTest_1338") + << QLatin1String("RegexTest_1339") + << QLatin1String("RegexTest_1340") + << QLatin1String("RegexTest_1341") + << QLatin1String("RegexTest_1345") + << QLatin1String("RegexTest_1346") + << QLatin1String("RegexTest_1347") + << QLatin1String("RegexTest_1348") + << QLatin1String("RegexTest_1349") + << QLatin1String("RegexTest_1350") + << QLatin1String("RegexTest_1354") + << QLatin1String("RegexTest_1363") + << QLatin1String("RegexTest_1364") + << QLatin1String("RegexTest_1365") + << QLatin1String("RegexTest_1372") + << QLatin1String("RegexTest_1373") + << QLatin1String("RegexTest_1374") + << QLatin1String("RegexTest_1375") + << QLatin1String("RegexTest_1376") + << QLatin1String("RegexTest_1377") + << QLatin1String("RegexTest_1378") + << QLatin1String("RegexTest_1379") + << QLatin1String("RegexTest_1380") + << QLatin1String("RegexTest_1381") + << QLatin1String("RegexTest_1382") + << QLatin1String("RegexTest_1383") + << QLatin1String("RegexTest_1384") + << QLatin1String("RegexTest_1385") + << QLatin1String("RegexTest_1386") + << QLatin1String("RegexTest_1387") + << QLatin1String("RegexTest_1388") + << QLatin1String("RegexTest_1389") + << QLatin1String("RegexTest_1390") + << QLatin1String("RegexTest_1391") + << QLatin1String("RegexTest_1392") + << QLatin1String("RegexTest_1393") + << QLatin1String("RegexTest_1394") + << QLatin1String("RegexTest_1395") + << QLatin1String("RegexTest_1396") + << QLatin1String("RegexTest_1397") + << QLatin1String("RegexTest_1398") + << QLatin1String("RegexTest_1399") + << QLatin1String("RegexTest_1400") + << QLatin1String("RegexTest_1401") + << QLatin1String("RegexTest_1402") + << QLatin1String("RegexTest_1403") + << QLatin1String("RegexTest_1404") + << QLatin1String("RegexTest_1405") + << QLatin1String("RegexTest_1406") + << QLatin1String("RegexTest_1407") + << QLatin1String("RegexTest_1408") + << QLatin1String("RegexTest_1409") + << QLatin1String("RegexTest_1410") + << QLatin1String("RegexTest_1412") + << QLatin1String("RegexTest_1413") + << QLatin1String("RegexTest_1414") + << QLatin1String("RegexTest_1420") + << QLatin1String("RegexTest_1421") + << QLatin1String("RegexTest_1422") + << QLatin1String("RegexTest_1423") + << QLatin1String("RegexTest_1424") + << QLatin1String("RegexTest_1425") + << QLatin1String("RegexTest_1426") + << QLatin1String("RegexTest_1427") + << QLatin1String("RegexTest_1428") + << QLatin1String("RegexTest_1429") + << QLatin1String("RegexTest_1430") + << QLatin1String("RegexTest_1433") + << QLatin1String("RegexTest_1434") + << QLatin1String("RegexTest_1435") + << QLatin1String("RegexTest_1436") + << QLatin1String("RegexTest_1437") + << QLatin1String("RegexTest_1438") + << QLatin1String("RegexTest_1439") + << QLatin1String("RegexTest_1440") + << QLatin1String("RegexTest_1441") + << QLatin1String("RegexTest_1442") + << QLatin1String("RegexTest_1443") + << QLatin1String("RegexTest_1444") + << QLatin1String("RegexTest_1445") + << QLatin1String("RegexTest_1446") + << QLatin1String("RegexTest_1447") + << QLatin1String("RegexTest_1448") + << QLatin1String("RegexTest_1451") + << QLatin1String("RegexTest_1452") + << QLatin1String("RegexTest_1453") + << QLatin1String("RegexTest_1454") + << QLatin1String("RegexTest_1455") + << QLatin1String("RegexTest_1456") + << QLatin1String("RegexTest_1472") + << QLatin1String("RegexTest_1473") + << QLatin1String("RegexTest_1474") + << QLatin1String("RegexTest_1475") + << QLatin1String("RegexTest_1478") + << QLatin1String("RegexTest_1479") + << QLatin1String("RegexTest_1480") + << QLatin1String("RegexTest_1481") + << QLatin1String("RegexTest_1484") + << QLatin1String("RegexTest_1485") + << QLatin1String("RegexTest_1486") + << QLatin1String("RegexTest_1487") + << QLatin1String("RegexTest_1488") + << QLatin1String("RegexTest_1491") + << QLatin1String("RegexTest_1492") + << QLatin1String("RegexTest_1493") + << QLatin1String("RegexTest_1494") + << QLatin1String("RegexTest_1495") + << QLatin1String("RegexTest_1496") + << QLatin1String("RegexTest_1497") + << QLatin1String("RegexTest_1498") + << QLatin1String("RegexTest_1499") + << QLatin1String("RegexTest_1500") + << QLatin1String("RegexTest_1501") + << QLatin1String("RegexTest_1502") + << QLatin1String("RegexTest_1503") + << QLatin1String("RegexTest_1543") + << QLatin1String("RegexTest_1544") + << QLatin1String("reZ001") +*/ + << QLatin1String("schA2") + << QLatin1String("schA5") + << QLatin1String("schA7") + << QLatin1String("schD8") + << QLatin1String("schG3") + << QLatin1String("schG6") + << QLatin1String("schG9") + << QLatin1String("schG11") + << QLatin1String("schG12") + << QLatin1String("schU1") + << QLatin1String("schU3") + << QLatin1String("schU4") + << QLatin1String("schU5") + << QLatin1String("schZ004") + << QLatin1String("schZ005") + << QLatin1String("schZ012_a") + << QLatin1String("stZ041") + << QLatin1String("wildZ010"); +} + +bool XSDTestSuiteHandler::startElement(const QString &namespaceURI, + const QString &localName, + const QString &/*qName*/, + const QXmlAttributes &atts) +{ + if(namespaceURI != QString::fromLatin1("http://www.w3.org/XML/2004/xml-schema-test-suite/")) + return true; + + if (localName == QLatin1String("testSet")) { + m_currentTestSet = new TestGroup(m_topLevelGroup); + Q_ASSERT(m_currentTestSet); + m_currentTestSet->setTitle(atts.value("name")); + m_topLevelGroup->appendChild(m_currentTestSet); + } else if (localName == QLatin1String("testGroup")) { + m_currentTestGroup = new TestGroup(m_currentTestSet); + Q_ASSERT(m_currentTestGroup); + m_currentTestGroup->setTitle(atts.value("name")); + m_currentTestSet->appendChild(m_currentTestGroup); + m_inTestGroup = true; + } else if (localName == QLatin1String("schemaTest")) { + if (m_blackList.contains(atts.value("name"))) { + m_currentTestCase = 0; + m_schemaBlacklisted = true; + return true; + } + m_schemaBlacklisted = false; + + m_currentTestCase = new XSDTSTestCase(TestCase::Standard, m_currentTestGroup, XSDTSTestCase::SchemaTest); + Q_ASSERT(m_currentTestCase); + m_counter++; + m_currentTestCase->setName(QString::number(m_counter) + atts.value("name")); + m_currentTestGroup->appendChild(m_currentTestCase); + m_currentTestCase->setParent(m_currentTestGroup); + + m_inSchemaTest = true; + } else if (localName == QLatin1String("instanceTest")) { + if (m_schemaBlacklisted) { + m_currentTestCase = 0; + return true; + } + + m_currentTestCase = new XSDTSTestCase(TestCase::Standard, m_currentTestGroup, XSDTSTestCase::InstanceTest); + Q_ASSERT(m_currentTestCase); + m_counter++; + m_currentTestCase->setName(QString::number(m_counter) + atts.value("name")); + m_currentTestGroup->appendChild(m_currentTestCase); + + m_inInstanceTest = true; + } else if (localName == QLatin1String("schemaDocument") || localName == QLatin1String("instanceDocument")) { + if (m_inSchemaTest) { + m_currentTestCase->setSchemaUri(QUrl(atts.value("xlink:href"))); + if (m_currentSchemaLink.isEmpty()) // we only use the first schema document for validation + m_currentSchemaLink = atts.value("xlink:href"); + } + if (m_inInstanceTest) { + m_currentTestCase->setInstanceUri(QUrl(atts.value("xlink:href"))); + m_currentTestCase->setSchemaUri(QUrl(m_currentSchemaLink)); + } + } else if (localName == QLatin1String("expected") && (m_inSchemaTest || m_inInstanceTest)) { + TestBaseLine *baseLine = new TestBaseLine(TestBaseLine::SchemaIsValid); + if (atts.value("validity") == QLatin1String("valid")) { + baseLine->setDetails(QLatin1String("true")); + m_currentTestCase->setName(m_currentTestCase->name() + QLatin1String(" tokoe:valid")); + } else { + baseLine->setDetails(QLatin1String("false")); + m_currentTestCase->setName(m_currentTestCase->name() + QLatin1String(" tokoe:invalid")); + } + + m_currentTestCase->addBaseLine(baseLine); + } else if (localName == QLatin1String("documentation") && m_inTestGroup) { + m_inDescription = true; + } + + return true; +} + +bool XSDTestSuiteHandler::endElement(const QString &/*namespaceURI*/, + const QString &localName, + const QString &/*qName*/) +{ + if (localName == QLatin1String("testGroup")) { + m_inTestGroup = false; + m_currentTestGroup->setDescription(m_documentation); + m_documentation.clear(); + m_currentSchemaLink.clear(); + + if (m_currentTestGroup->childCount() == 0) + m_currentTestSet->removeLast(); + } else if (localName == QLatin1String("schemaTest")) + m_inSchemaTest = false; + else if (localName == QLatin1String("instanceTest")) + m_inInstanceTest = false; + else if (localName == QLatin1String("documentation")) + m_inDescription = false; + + return true; +} + +bool XSDTestSuiteHandler::characters(const QString &ch) +{ + if (m_inDescription) + m_documentation += ch; + + return true; +} + +TestSuite *XSDTestSuiteHandler::testSuite() const +{ + return m_ts; +} + +// vim: et:ts=4:sw=4:sts=4 + diff --git a/tests/auto/xmlpatternssdk/XSDTestSuiteHandler.h b/tests/auto/xmlpatternssdk/XSDTestSuiteHandler.h new file mode 100644 index 0000000..5493c7d --- /dev/null +++ b/tests/auto/xmlpatternssdk/XSDTestSuiteHandler.h @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the autotests of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PatternistSDK_XSDTestSuiteHandler_H +#define PatternistSDK_XSDTestSuiteHandler_H + +#include <QUrl> +#include <QXmlDefaultHandler> + +#include "ExternalSourceLoader.h" +#include "TestSuite.h" +#include "XQTSTestCase.h" + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +namespace QPatternistSDK +{ + class TestBaseLine; + class TestGroup; + class XSDTSTestCase; + + /** + * @short Creates a TestSuite from the XSD Test Suite. + * + * The created TestSuite can be retrieved via testSuite(). + * + * @note XSDTestSuiteHandler assumes the XML is valid by having been validated + * against the W3C XML Schema. It has no safety checks for that the XML format + * is correct but is hard coded for it. Thus, the behavior is undefined if + * the XML is invalid. + * + * @ingroup PatternistSDK + * @author Tobias Koenig <tobias.koenig@nokia.com> + */ + class Q_PATTERNISTSDK_EXPORT XSDTestSuiteHandler : public QXmlDefaultHandler + { + public: + /** + * @param catalogFile the URI for the catalog file being parsed. This + * URI is used for creating absolute URIs for files mentioned in + * the catalog with relative URIs. + * @param useExclusionList whether excludeTestGroups.txt should be used to ignore + * test groups when loading + */ + XSDTestSuiteHandler(const QUrl &catalogFile); + virtual bool characters(const QString &ch); + + virtual bool endElement(const QString &namespaceURI, + const QString &localName, + const QString &qName); + virtual bool startElement(const QString &namespaceURI, + const QString &localName, + const QString &qName, + const QXmlAttributes &atts); + + virtual TestSuite *testSuite() const; + + private: + TestSuite* m_ts; + const QUrl m_catalogFile; + + TestGroup* m_topLevelGroup; + TestGroup* m_currentTestSet; + TestGroup* m_currentTestGroup; + XSDTSTestCase* m_currentTestCase; + bool m_inSchemaTest; + bool m_inInstanceTest; + bool m_inTestGroup; + bool m_inDescription; + bool m_schemaBlacklisted; + QString m_documentation; + QString m_currentSchemaLink; + int m_counter; + QSet<QString> m_blackList; + }; +} + +QT_END_NAMESPACE +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/XSLTTestSuiteHandler.cpp b/tests/auto/xmlpatternssdk/XSLTTestSuiteHandler.cpp new file mode 100644 index 0000000..cfc3b2b --- /dev/null +++ b/tests/auto/xmlpatternssdk/XSLTTestSuiteHandler.cpp @@ -0,0 +1,234 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtDebug> + +#include "qacceltreeresourceloader_p.h" +#include "qnetworkaccessdelegator_p.h" + +#include "Global.h" +#include "TestBaseLine.h" +#include "TestGroup.h" + +#include "XSLTTestSuiteHandler.h" + +using namespace QPatternistSDK; + +extern QNetworkAccessManager s_networkManager; + +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(&s_networkManager, &s_networkManager)); + + m_resourceLoader = QPatternist::ResourceLoader::Ptr(new QPatternist::AccelTreeResourceLoader(Global::namePool(), + networkDelegator)); + Q_ASSERT(!m_catalogFile.isRelative()); +} + +bool XSLTTestSuiteHandler::startElement(const QString &namespaceURI, + const QString &localName, + const QString &/*qName*/, + const QXmlAttributes &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")))); + m_currentBaselinePath = m_baselineOffset.resolved(QUrl(atts.value(QLatin1String("FilePath")))); + } + else if(localName == QLatin1String("stylesheet")) + m_tc->setQueryPath(m_currentQueryPath.resolved(atts.value(QLatin1String("file")))); + else if(localName == QLatin1String("error")) + { + m_baseLine = new TestBaseLine(TestBaseLine::ExpectedError); + m_baseLine->setDetails(atts.value(QLatin1String("error-id"))); + m_tc->addBaseLine(m_baseLine); + } + else if(localName == QLatin1String("testcases")) + { + m_ts = new TestSuite(); + m_ts->setVersion(atts.value(QLatin1String("testSuiteVersion"))); + + m_queryOffset = m_catalogFile.resolved(atts.value(QLatin1String("InputOffsetPath"))); + m_baselineOffset = m_catalogFile.resolved(atts.value(QLatin1String("ResultOffsetPath"))); + m_sourceOffset = m_catalogFile.resolved(atts.value(QLatin1String("InputOffsetPath"))); + } + else if(localName == QLatin1String("source-document")) + { + if(atts.value(QLatin1String("role")) == QLatin1String("principal")) + m_tc->setContextItemSource(m_sourceOffset.resolved(QUrl(atts.value(QLatin1String("file"))))); + } + else if(localName == QLatin1String("result-document")) + { + m_baseLine = new TestBaseLine(TestBaseLine::identifierFromString(atts.value(QLatin1String("type")))); + m_baseLine->setDetails(m_currentBaselinePath.resolved(atts.value(QLatin1String("file"))).toString()); + m_tc->addBaseLine(m_baseLine); + } + else if(localName == QLatin1String("discretionary-feature")) + { + const QString feature(atts.value(QLatin1String("name"))); + + 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"))); + m_tc->addBaseLine(m_baseLine); + const QString feature(atts.value(QLatin1String("name"))); + + 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"))); + + 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 QString &namespaceURI, + const QString &localName, + const QString &/*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 QString &ch) +{ + m_ch = ch; + return true; +} + +TestSuite *XSLTTestSuiteHandler::testSuite() const +{ + return m_ts; +} + +// vim: et:ts=4:sw=4:sts=4 + diff --git a/tests/auto/xmlpatternssdk/XSLTTestSuiteHandler.h b/tests/auto/xmlpatternssdk/XSLTTestSuiteHandler.h new file mode 100644 index 0000000..8614789 --- /dev/null +++ b/tests/auto/xmlpatternssdk/XSLTTestSuiteHandler.h @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PatternistSDK_XSLTTestSuiteHandler_H +#define PatternistSDK_XSLTTestSuiteHandler_H + +#include <QStack> +#include <QUrl> +#include <QXmlDefaultHandler> + +#include "ExternalSourceLoader.h" +#include "TestSuite.h" +#include "XQTSTestCase.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternistSDK +{ + class TestBaseLine; + class TestGroup; + + /** + * @short Creates a TestSuite from the XQuery Test Suite catalog. + * + * The created TestSuite can be retrieved via testSuite(). + * + * @note XSLTTestSuiteHandler assumes the XML is valid by having been validated + * against the W3C XML Schema. It has no safety checks for that the XML format + * is correct but is hard coded for it. Thus, the behavior is undefined if + * the XML is invalid. + * + * @see http://www.w3.org/XML/Group/xslt20-test/TestSuiteStagingArea/catalog.html + * @see http://www.w3.org/XML/Group/xslt20-test/Documentation/XSLT2Test.htm + * @ingroup PatternistSDK + * @author Frans Englich <frans.englich@nokia.com> + */ + class Q_PATTERNISTSDK_EXPORT XSLTTestSuiteHandler : public QXmlDefaultHandler + { + public: + /** + * @param catalogFile the URI for the catalog file being parsed. This + * URI is used for creating absolute URIs for files mentioned in + * the catalog with relative URIs. + * @param useExclusionList whether excludeTestGroups.txt should be used to ignore + * test groups when loading + */ + XSLTTestSuiteHandler(const QUrl &catalogFile); + virtual bool characters(const QString &ch); + + virtual bool endElement(const QString &namespaceURI, + const QString &localName, + const QString &qName); + virtual bool startElement(const QString &namespaceURI, + const QString &localName, + const QString &qName, + const QXmlAttributes &atts); + + virtual TestSuite *testSuite() const; + + private: + TestGroup *containerFor(const QString &name); + + QHash<QString, TestGroup *> m_containers; + + TestSuite * m_ts; + XQTSTestCase * m_tc; + TestBaseLine * m_baseLine; + QString m_ch; + const QUrl m_catalogFile; + + /** + * The base URI for where the XQuery query files are found. + * It is absolute, resolved against catalogFile. + */ + QUrl m_queryOffset; + + QUrl m_baselineOffset; + QUrl m_sourceOffset; + QUrl m_currentQueryPath; + QUrl m_currentBaselinePath; + + /** + * In the XQTSCatalog.xml, each source file in each test is referred to + * by a key, which can be fully looked up in the @c sources element. This QHash + * maps the keys to absolute URIs pointing to the source files. + */ + ExternalSourceLoader::SourceMap m_sourceMap; + + ExternalSourceLoader::VariableMap m_tcSourceInputs; + + QPatternist::ResourceLoader::Ptr m_resourceLoader; + + /** + * The current value of <tt>input-file/\@variable</tt>. + */ + QString m_currentInputVariable; + + /** + * The names of the test groups. + */ + QStack<QString> m_testGroupName; + + /** + * Holds the content of the current <tt>input-URI</tt> element. + */ + QString m_inputURI; + QString m_contextItemSource; + QString m_currentCategory; + bool m_removeTestcase; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/docs/XMLIndenterExample.cpp b/tests/auto/xmlpatternssdk/docs/XMLIndenterExample.cpp new file mode 100644 index 0000000..24ee158 --- /dev/null +++ b/tests/auto/xmlpatternssdk/docs/XMLIndenterExample.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +QByteArray result; +QBuffer returnBuffer(&result); +XMLWriter writer(&returnBuffer); + +writer.startDocument(); + +writer.startDTD(QLatin1String("html"), QLatin1String("-//W3C//DTD XHTML 1.0 Strict//EN"), + QLatin1String("http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd")); +writer.endDTD(); + +writer.startPrefixMapping(QString(), QLatin1String("http://www.w3.org/1999/xhtml")); + +writer.startElement(QLatin1String("html"), QXmlAttributes()); +writer.startElement(QLatin1String("body"), QXmlAttributes()); +writer.startElement(QLatin1String("p"), QXmlAttributes()); + +writer.characters(QLatin1String("Hello World!")); + +writer.endElement(QLatin1String("p")); +writer.endElement(QLatin1String("body")); +writer.endElement(QLatin1String("html")); + +writer.endDocument(); diff --git a/tests/auto/xmlpatternssdk/docs/XMLIndenterExampleResult.xml b/tests/auto/xmlpatternssdk/docs/XMLIndenterExampleResult.xml new file mode 100644 index 0000000..c5e7312 --- /dev/null +++ b/tests/auto/xmlpatternssdk/docs/XMLIndenterExampleResult.xml @@ -0,0 +1,3 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"><body><p>Hello World!</p></body></html> diff --git a/tests/auto/xmlpatternssdk/docs/XMLWriterExample.cpp b/tests/auto/xmlpatternssdk/docs/XMLWriterExample.cpp new file mode 100644 index 0000000..24ee158 --- /dev/null +++ b/tests/auto/xmlpatternssdk/docs/XMLWriterExample.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +QByteArray result; +QBuffer returnBuffer(&result); +XMLWriter writer(&returnBuffer); + +writer.startDocument(); + +writer.startDTD(QLatin1String("html"), QLatin1String("-//W3C//DTD XHTML 1.0 Strict//EN"), + QLatin1String("http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd")); +writer.endDTD(); + +writer.startPrefixMapping(QString(), QLatin1String("http://www.w3.org/1999/xhtml")); + +writer.startElement(QLatin1String("html"), QXmlAttributes()); +writer.startElement(QLatin1String("body"), QXmlAttributes()); +writer.startElement(QLatin1String("p"), QXmlAttributes()); + +writer.characters(QLatin1String("Hello World!")); + +writer.endElement(QLatin1String("p")); +writer.endElement(QLatin1String("body")); +writer.endElement(QLatin1String("html")); + +writer.endDocument(); diff --git a/tests/auto/xmlpatternssdk/docs/XMLWriterExampleResult.xml b/tests/auto/xmlpatternssdk/docs/XMLWriterExampleResult.xml new file mode 100644 index 0000000..c5e7312 --- /dev/null +++ b/tests/auto/xmlpatternssdk/docs/XMLWriterExampleResult.xml @@ -0,0 +1,3 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"><body><p>Hello World!</p></body></html> diff --git a/tests/auto/xmlpatternssdk/tests/XMLWriterTest.cpp b/tests/auto/xmlpatternssdk/tests/XMLWriterTest.cpp new file mode 100644 index 0000000..a10c01a --- /dev/null +++ b/tests/auto/xmlpatternssdk/tests/XMLWriterTest.cpp @@ -0,0 +1,186 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> + +#include "XMLWriter.h" + +#include "XMLWriterTest.h" +#include "XMLWriterTest.moc" + +using namespace QPatternistSDK; + +QTEST_MAIN(XMLWriterTest) + +void XMLWriterTest::serialize() +{ + QFETCH(QString, input); + QFETCH(QString, expectedResult); + + QByteArray result; + QBuffer returnBuffer(&result); + + XMLWriter writer(&returnBuffer); + + QXmlInputSource inputSource; + inputSource.setData(input); + + QXmlSimpleReader reader; + reader.setContentHandler(&writer); + + const bool parseSuccess = reader.parse(inputSource); + Q_ASSERT_X(parseSuccess, Q_FUNC_INFO, + "XMLWriter reported an error while serializing the input."); + + QCOMPARE(QString::fromLatin1(result), expectedResult); +} + +void XMLWriterTest::serialize_data() +{ + QTest::addColumn<QString>("input"); + QTest::addColumn<QString>("expectedResult"); + + /* ------------------- Elements ------------------- */ + QTest::newRow("Only an document element") + << "<doc></doc>" + << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<doc/>"; + + QTest::newRow("Document element containing a short closed element") + << "<doc><f/></doc>" + << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<doc><f/></doc>"; + QTest::newRow("Complex nested elements") + << "<doc><a/><b/><c><d/><e><f><x/></f></e></c></doc>" + << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<doc><a/><b/><c><d/><e><f><x/></f></e></c></doc>"; + /* ------------------------------------------------- */ + + /* ---------------- Element Content ---------------- */ + QTest::newRow("Element content with simple content") + << "<doc>content</doc>" + << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<doc>content</doc>"; + + QTest::newRow("Element content with tricky to escape content") + << "<doc>>>&'\"''/></doc>" + << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<doc>>>&'\"''/></doc>"; + /* ------------------------------------------------- */ + + /* ----------- Processing Instructions ------------- */ + QTest::newRow("Simple processing instruction.") + << "<doc><?php content?></doc>" + << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<doc><?php content?></doc>"; + /* ------------------------------------------------- */ + + /* --------------- 'xml' attributes ---------------- */ + QTest::newRow("Simple xml:space attribute.") + << "<doc xml:space='preserve'>content</doc>" + << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<doc xml:space=\"preserve\">content</doc>"; + + QTest::newRow("Many 'xml' attributes.") + << "<doc xml:space='preserve' xml:foo='3' xml:s2='3'>content</doc>" + << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<doc xml:space=\"preserve\" xml:foo=\"3\" xml:s2=\"3\">content</doc>"; + /* ------------------------------------------------- */ + + /* ------------ namespace declarations ------------- */ + QTest::newRow("One simple namespace declaration.") + << "<doc xmlns:f='example.org/'/>" + << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<doc xmlns:f=\"example.org/\"/>"; + + QTest::newRow("Two simple namespace declarations.") + << "<doc xmlns:f='example.org/' xmlns:e='example.org/'/>" + << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<doc xmlns:f=\"example.org/\" xmlns:e=\"example.org/\"/>"; + + QTest::newRow("A simple default namespace.") + << "<doc xmlns='example.org/'/>" + << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<doc xmlns=\"example.org/\"/>"; + /* ------------------------------------------------- */ + + /* -------- namespace declarations in use ---------- */ + QTest::newRow("Simple use of a namespace declaration.") + << "<doc xmlns:f='example.org/' f:attr='chars'><n/><f:name f:attr='chars'/></doc>" + << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<doc xmlns:f=\"example.org/\" f:attr=\"chars\"><n/><f:name f:attr=\"chars\"/></doc>"; + /* ------------------------------------------------- */ +} + +void XMLWriterTest::cdata() +{ + /* + QTest::newRow("Simple CDATA") + << "<doc><![CDATA[content]]></doc>" + << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<doc><![CDATA[content]]></doc>"; + + QTest::newRow("Complex CDATA") + << "<doc><![CDATA[<<>>&'\";&987;]]></doc>" + << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<doc><![CDATA[<<>>&'\";&123;]]></doc>"; + */ +} + +void XMLWriterTest::comments() +{ + /* + QTest::newRow("Simple comment") + << "<doc><!-- comment --></doc>" + << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<doc><!-- comment --></doc>"; + QTest::newRow("Comment") + << "<doc><!--- comment --></doc>" + << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<doc><!--- comment --></doc>"; + */ +} + +void XMLWriterTest::doxygenExample() +{ +#include "../docs/XMLWriterExample.cpp" + + /* When changing, remember to update the Doxygen in XMLWriter.h */ + const QByteArray expectedResult( + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" " + "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n" + "<html xmlns=\"http://www.w3.org/1999/xhtml\"><body><p>Hello World!</p></body></html>" + ); + + QCOMPARE(QString::fromLatin1(result), QString::fromLatin1(expectedResult)); +} + +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/tests/XMLWriterTest.h b/tests/auto/xmlpatternssdk/tests/XMLWriterTest.h new file mode 100644 index 0000000..f90aea2 --- /dev/null +++ b/tests/auto/xmlpatternssdk/tests/XMLWriterTest.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PatternistSDK_XMLWriterTest_H +#define PatternistSDK_XMLWriterTest_H + +#include <QObject> + +QT_BEGIN_HEADER + +namespace QPatternistSDK +{ + /** + * @short QTestLib test for XMLWriter. + * + * @ingroup PatternistSDK + * @author Frans Englich <frans.englich@nokia.com> + */ + class XMLWriterTest : public QObject + { + Q_OBJECT + private Q_SLOTS: + void serialize(); + void serialize_data(); + void comments(); + void cdata(); + + /** + * Ensure the example compiles, and that it does + * what it claims to. + */ + void doxygenExample(); + }; +} + +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternssdk/xmlpatternssdk.pro b/tests/auto/xmlpatternssdk/xmlpatternssdk.pro new file mode 100644 index 0000000..6204f01 --- /dev/null +++ b/tests/auto/xmlpatternssdk/xmlpatternssdk.pro @@ -0,0 +1,88 @@ +include (../xmlpatterns.pri) + +TARGET = $$XMLPATTERNS_SDK +TEMPLATE = lib +DEFINES += Q_PATTERNISTSDK_BUILDING + +# lib_bundle ensures we get a framework on OS X, a library bundle. +CONFIG += resources + +mac { + CONFIG += absolute_library_soname + target.path=$$[QT_INSTALL_LIBS] + INSTALLS += target +} + +symbian { + TARGET.EPOCALLOWDLLDATA=1 + TARGET.CAPABILITY = All -Tcb + MMP_RULES += EXPORTUNFROZEN +} + +# We add gui, because xmlpatterns.pri pull it out. +QT += xmlpatterns xml network testlib gui + +DESTDIR = $$QT_BUILD_TREE/lib +!wince*:DLLDESTDIR = $$QT_BUILD_TREE/bin + +# syncqt doesn't copy headers in tools/ so let's manually ensure +# it works with shadow builds and source builds. +INCLUDEPATH += $$QT_BUILD_TREE/include/QtXmlPatterns/private \ + $$QT_SOURCE_TREE/include/QtXmlPatterns/private \ + $$QT_SOURCE_TREE/tools/xmlpatterns + +HEADERS = ASTItem.h \ + DebugExpressionFactory.h \ + ErrorHandler.h \ + ErrorItem.h \ + ExitCode.h \ + ExpressionInfo.h \ + ExpressionNamer.h \ + ExternalSourceLoader.h \ + Global.h \ + ResultThreader.h \ + TestBaseLine.h \ + TestCase.h \ + TestContainer.h \ + TestGroup.h \ + TestItem.h \ + TestResult.h \ + TestResultHandler.h \ + TestSuite.h \ + TestSuiteHandler.h \ + TestSuiteResult.h \ + TreeItem.h \ + TreeModel.h \ + Worker.h \ + XMLWriter.h \ + XQTSTestCase.h \ + XSDTestSuiteHandler.h \ + XSDTSTestCase.h \ + XSLTTestSuiteHandler.h + +SOURCES = ASTItem.cpp \ + DebugExpressionFactory.cpp \ + ErrorHandler.cpp \ + ErrorItem.cpp \ + ExpressionInfo.cpp \ + ExpressionNamer.cpp \ + ExternalSourceLoader.cpp \ + Global.cpp \ + ResultThreader.cpp \ + TestBaseLine.cpp \ + TestCase.cpp \ + TestContainer.cpp \ + TestGroup.cpp \ + TestResult.cpp \ + TestResultHandler.cpp \ + TestSuite.cpp \ + TestSuiteHandler.cpp \ + TestSuiteResult.cpp \ + TreeItem.cpp \ + TreeModel.cpp \ + Worker.cpp \ + XMLWriter.cpp \ + XQTSTestCase.cpp \ + XSDTestSuiteHandler.cpp \ + XSDTSTestCase.cpp \ + XSLTTestSuiteHandler.cpp |