diff options
author | Lars Knoll <lars.knoll@nokia.com> | 2009-03-23 09:34:13 (GMT) |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2009-03-23 09:34:13 (GMT) |
commit | 67ad0519fd165acee4a4d2a94fa502e9e4847bd0 (patch) | |
tree | 1dbf50b3dff8d5ca7e9344733968c72704eb15ff /tests/auto/qabstractxmlnodemodel | |
download | Qt-67ad0519fd165acee4a4d2a94fa502e9e4847bd0.zip Qt-67ad0519fd165acee4a4d2a94fa502e9e4847bd0.tar.gz Qt-67ad0519fd165acee4a4d2a94fa502e9e4847bd0.tar.bz2 |
Long live Qt!
Diffstat (limited to 'tests/auto/qabstractxmlnodemodel')
-rw-r--r-- | tests/auto/qabstractxmlnodemodel/.gitignore | 1 | ||||
-rw-r--r-- | tests/auto/qabstractxmlnodemodel/LoadingModel.cpp | 360 | ||||
-rw-r--r-- | tests/auto/qabstractxmlnodemodel/LoadingModel.h | 99 | ||||
-rw-r--r-- | tests/auto/qabstractxmlnodemodel/TestNodeModel.h | 139 | ||||
-rw-r--r-- | tests/auto/qabstractxmlnodemodel/qabstractxmlnodemodel.pro | 14 | ||||
-rw-r--r-- | tests/auto/qabstractxmlnodemodel/tree.xml | 15 | ||||
-rw-r--r-- | tests/auto/qabstractxmlnodemodel/tst_qabstractxmlnodemodel.cpp | 399 |
7 files changed, 1027 insertions, 0 deletions
diff --git a/tests/auto/qabstractxmlnodemodel/.gitignore b/tests/auto/qabstractxmlnodemodel/.gitignore new file mode 100644 index 0000000..6b025af --- /dev/null +++ b/tests/auto/qabstractxmlnodemodel/.gitignore @@ -0,0 +1 @@ +tst_qabstractxmlnodemodel diff --git a/tests/auto/qabstractxmlnodemodel/LoadingModel.cpp b/tests/auto/qabstractxmlnodemodel/LoadingModel.cpp new file mode 100644 index 0000000..5cc33d6 --- /dev/null +++ b/tests/auto/qabstractxmlnodemodel/LoadingModel.cpp @@ -0,0 +1,360 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QFile> +#include <QStack> + +#ifdef QTEST_XMLPATTERNS +#include <QXmlNamePool> +#include <QXmlStreamReader> +#include <QtDebug> +#include <QTest> + +#include "LoadingModel.h" +LoadingModel::LoadingModel(const Node::Vector &content, + const QXmlNamePool &np) : QSimpleXmlNodeModel(np) + , m_nodes(content) +{ + Q_ASSERT(!content.isEmpty()); + /* + foreach(const Node *n, content) + qDebug() << "this:" << n + << "kind:" << n->kind + << "parent: " << n->parent + << "preceding: " << n->precedingSibling + << "following: " << n->followingSibling + << "firstChild: " << n->firstChild + << "value: " << n->value; + */ +} + +LoadingModel::~LoadingModel() +{ + qDeleteAll(m_nodes); +} + +const LoadingModel::Node *LoadingModel::toInternal(const QXmlNodeModelIndex &ni) const +{ + return static_cast<const Node *>(ni.internalPointer()); +} + +QXmlNodeModelIndex LoadingModel::createIndex(const Node *const internal) const +{ + Q_ASSERT_X(internal, Q_FUNC_INFO, + "We shouldn't construct from null pointers."); + return QAbstractXmlNodeModel::createIndex(const_cast<Node *>(internal)); +} + +QUrl LoadingModel::documentUri(const QXmlNodeModelIndex &) const +{ + Q_ASSERT(false); + return QUrl(); +} + +QXmlNodeModelIndex::NodeKind LoadingModel::kind(const QXmlNodeModelIndex &ni) const +{ + Q_ASSERT(!ni.isNull()); + return toInternal(ni)->kind; +} + +QXmlNodeModelIndex::DocumentOrder LoadingModel::compareOrder(const QXmlNodeModelIndex &n1, const QXmlNodeModelIndex &n2) const +{ + const Node *const in1 = toInternal(n1); + const Node *const in2 = toInternal(n2); + Q_ASSERT(m_nodes.indexOf(in1) != -1); + Q_ASSERT(m_nodes.indexOf(in2) != -1); + + if(in1 == in2) + return QXmlNodeModelIndex::Is; + else if(m_nodes.indexOf(in1) < m_nodes.indexOf(in2)) + return QXmlNodeModelIndex::Precedes; + else + return QXmlNodeModelIndex::Follows; +} + +QXmlNodeModelIndex LoadingModel::root(const QXmlNodeModelIndex &) const +{ + Q_ASSERT(kind(createIndex(m_nodes.first())) == QXmlNodeModelIndex::Document); + return createIndex(m_nodes.first()); +} + +QXmlName LoadingModel::name(const QXmlNodeModelIndex &ni) const +{ + return toInternal(ni)->name; +} + +QVariant LoadingModel::typedValue(const QXmlNodeModelIndex &ni) const +{ + const Node *const internal = toInternal(ni); + + Q_ASSERT(internal->kind == QXmlNodeModelIndex::Attribute + || internal->kind == QXmlNodeModelIndex::Element); + + return internal->value; +} + +QString LoadingModel::stringValue(const QXmlNodeModelIndex &ni) const +{ + const Node *const internal = toInternal(ni); + + switch(internal->kind) + { + case QXmlNodeModelIndex::Text: + /* Fallthrough. */ + case QXmlNodeModelIndex::ProcessingInstruction: + /* Fallthrough. */ + case QXmlNodeModelIndex::Comment: + /* Fallthrough. */ + case QXmlNodeModelIndex::Attribute: + return internal->value; + default: + return QString(); + } +} + +QXmlNodeModelIndex LoadingModel::nextFromSimpleAxis(QAbstractXmlNodeModel::SimpleAxis axis, + const QXmlNodeModelIndex &ni) const +{ + const Node *const internal = toInternal(ni); + + /* Note that a QXmlNodeModelIndex containing a null pointer is not a null node. */ + switch(axis) + { + case Parent: + return internal->parent ? createIndex(internal->parent) : QXmlNodeModelIndex(); + case FirstChild: + return internal->firstChild ? createIndex(internal->firstChild) : QXmlNodeModelIndex(); + case PreviousSibling: + return internal->precedingSibling ? createIndex(internal->precedingSibling) : QXmlNodeModelIndex(); + case NextSibling: + return internal->followingSibling ? createIndex(internal->followingSibling) : QXmlNodeModelIndex(); + } + + Q_ASSERT(false); + return QXmlNodeModelIndex(); +} + +QVector<QXmlNodeModelIndex> LoadingModel::attributes(const QXmlNodeModelIndex &ni) const +{ + QVector<QXmlNodeModelIndex> retval; + foreach(const Node *n, toInternal(ni)->attributes) + retval.append(createIndex(n)); + + return retval; +} + +class Loader +{ +public: + inline Loader(const QXmlNamePool &namePool) : m_namePool(namePool) + , m_currentNode(0) + { + m_parentStack.push(0); + } + +private: + inline void adjustSiblings(LoadingModel::Node *const justBorn); + friend class LoadingModel; + Q_DISABLE_COPY(Loader); + + void load(); + + QXmlNamePool m_namePool; + QXmlStreamReader m_reader; + LoadingModel::Node::Vector m_result; + LoadingModel::Node * m_currentNode; + QStack<LoadingModel::Node *> m_parentStack; +}; + +inline void Loader::adjustSiblings(LoadingModel::Node *const justBorn) +{ + if(m_currentNode) + { + if(m_currentNode->parent == justBorn->parent) + justBorn->precedingSibling = m_currentNode; + + m_currentNode->followingSibling = justBorn; + } + + m_currentNode = justBorn; + + /* Otherwise we're the first child, and our precedingSibling should remain null. */ + + if(m_parentStack.top() && !m_parentStack.top()->firstChild) + m_parentStack.top()->firstChild = justBorn; +} + +void Loader::load() +{ + QFile in(QLatin1String("tree.xml")); + + /* LoadingModel::m_result will be null, signalling failure. */ + if(!in.open(QIODevice::ReadOnly)) + return; + + QXmlStreamReader reader(&in); + while(!reader.atEnd()) + { + reader.readNext(); + + switch(reader.tokenType()) + { + case QXmlStreamReader::StartDocument: + /* Fallthrough. */ + case QXmlStreamReader::StartElement: + { + QXmlName name; + if(reader.tokenType() == QXmlStreamReader::StartElement) + { + name = QXmlName(m_namePool, + reader.name().toString(), + reader.namespaceUri().toString(), + reader.prefix().toString()); + } + /* Else, the name is null. */ + + LoadingModel::Node *const tmp = new LoadingModel::Node(reader.tokenType() == QXmlStreamReader::StartElement + ? QXmlNodeModelIndex::Element + : QXmlNodeModelIndex::Document, + m_parentStack.top(), + QString(), + name); + m_result.append(tmp); + + if(m_currentNode) + { + if(m_currentNode->parent == m_parentStack.top()) + m_currentNode->followingSibling = tmp; + } + + const QXmlStreamAttributes attributes(reader.attributes()); + const int len = attributes.count(); + + for(int i = 0; i < len; ++i) + { + const QXmlStreamAttribute &attr = attributes.at(i); + const LoadingModel::Node *const a = new LoadingModel::Node(QXmlNodeModelIndex::Attribute, + m_parentStack.top(), + attr.value().toString(), + QXmlName(m_namePool, + attr.name().toString(), + attr.namespaceUri().toString(), + attr.prefix().toString())); + /* We add it also to m_result such that compareOrder() is correct + * for attributes. m_result owns a. */ + tmp->attributes.append(a); + m_result.append(a); + } + + adjustSiblings(tmp); + m_parentStack.push(m_currentNode); + break; + } + case QXmlStreamReader::EndDocument: + /* Fallthrough. */ + case QXmlStreamReader::EndElement: + { + m_currentNode->followingSibling = 0; + m_currentNode = m_parentStack.pop(); + + if(reader.tokenType() == QXmlStreamReader::EndDocument) + const_cast<LoadingModel::Node *>(m_result.first())->followingSibling = 0; + + break; + } + case QXmlStreamReader::Characters: + { + LoadingModel::Node *const tmp = new LoadingModel::Node(QXmlNodeModelIndex::Text, m_parentStack.top(), reader.text().toString()); + m_result.append(tmp); + adjustSiblings(tmp); + break; + } + case QXmlStreamReader::ProcessingInstruction: + { + LoadingModel::Node *const tmp = new LoadingModel::Node(QXmlNodeModelIndex::ProcessingInstruction, + m_parentStack.top(), + reader.processingInstructionData().toString(), + QXmlName(m_namePool, reader.processingInstructionTarget().toString())); + m_result.append(tmp); + adjustSiblings(tmp); + break; + } + case QXmlStreamReader::Comment: + { + LoadingModel::Node *const tmp = new LoadingModel::Node(QXmlNodeModelIndex::Comment, m_parentStack.top(), reader.text().toString()); + m_result.append(tmp); + adjustSiblings(tmp); + break; + } + case QXmlStreamReader::DTD: + /* Fallthrough. */ + case QXmlStreamReader::EntityReference: + { + Q_ASSERT_X(false, Q_FUNC_INFO, + "We don't support this."); + /* Fallthrough. */ + } + case QXmlStreamReader::NoToken: + /* Fallthrough. */ + case QXmlStreamReader::Invalid: + { + qWarning(qPrintable(reader.errorString())); + m_result.clear(); + return; + } + } + } + + if(reader.hasError()) + { + qWarning(qPrintable(reader.errorString())); + m_result.clear(); + } +} + +QAbstractXmlNodeModel::Ptr LoadingModel::create(const QXmlNamePool &np) +{ + Loader loader(np); + loader.load(); + return Ptr(new LoadingModel(loader.m_result, np)); +} +#endif //QTEST_XMLPATTERNS diff --git a/tests/auto/qabstractxmlnodemodel/LoadingModel.h b/tests/auto/qabstractxmlnodemodel/LoadingModel.h new file mode 100644 index 0000000..1b4967b --- /dev/null +++ b/tests/auto/qabstractxmlnodemodel/LoadingModel.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QSimpleXmlNodeModel> +#include <QVector> + +class LoadingModel : public QSimpleXmlNodeModel +{ +public: + virtual ~LoadingModel(); + static QAbstractXmlNodeModel::Ptr create(const QXmlNamePool &np); + + virtual QUrl documentUri(const QXmlNodeModelIndex &) const; + virtual QXmlNodeModelIndex::NodeKind kind(const QXmlNodeModelIndex &) const; + virtual QXmlNodeModelIndex::DocumentOrder compareOrder(const QXmlNodeModelIndex &, const QXmlNodeModelIndex&) const; + virtual QXmlNodeModelIndex root(const QXmlNodeModelIndex &) const; + virtual QXmlName name(const QXmlNodeModelIndex &) const; + virtual QVariant typedValue(const QXmlNodeModelIndex &) const; + virtual QString stringValue(const QXmlNodeModelIndex &) const; + virtual QXmlNodeModelIndex nextFromSimpleAxis(QAbstractXmlNodeModel::SimpleAxis, const QXmlNodeModelIndex &) const; + virtual QVector<QXmlNodeModelIndex> attributes(const QXmlNodeModelIndex &) const; + +private: + friend class Loader; + class Node + { + public: + inline Node(const QXmlNodeModelIndex::NodeKind k, + const Node *const p, + const QString &v = QString(), + const QXmlName &n = QXmlName()) : kind(k) + , value(v) + , parent(p) + , precedingSibling(0) + , followingSibling(0) + , firstChild(0) + , name(n) + { + } + + typedef QVector<const Node *> Vector; + QXmlNodeModelIndex::NodeKind kind; + QString value; + const Node * parent; + const Node * precedingSibling; + const Node * followingSibling; + const Node * firstChild; + Node::Vector attributes; + QXmlName name; + }; + + inline const Node *toInternal(const QXmlNodeModelIndex &ni) const; + inline QXmlNodeModelIndex createIndex(const Node *const internal) const; + + LoadingModel(const Node::Vector &content, + const QXmlNamePool &np); + + Node::Vector m_nodes; +}; + diff --git a/tests/auto/qabstractxmlnodemodel/TestNodeModel.h b/tests/auto/qabstractxmlnodemodel/TestNodeModel.h new file mode 100644 index 0000000..d4532d7 --- /dev/null +++ b/tests/auto/qabstractxmlnodemodel/TestNodeModel.h @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtXmlPatterns/QAbstractXmlNodeModel> + +/*! + \class TestNodeModel + \since 4.4 + \internal + \brief Subclass of QAbstractXmlNodeModel, used by tst_QAbstractXmlNodeModel, for testing only. + */ +class TestNodeModel : public QAbstractXmlNodeModel +{ +public: + virtual QUrl baseUri(const QXmlNodeModelIndex&) const; + virtual QUrl documentUri(const QXmlNodeModelIndex&) const; + virtual QXmlNodeModelIndex::NodeKind kind(const QXmlNodeModelIndex&) const; + virtual QXmlNodeModelIndex::DocumentOrder compareOrder(const QXmlNodeModelIndex&, const QXmlNodeModelIndex&) const; + virtual QXmlNodeModelIndex root(const QXmlNodeModelIndex&) const; + virtual QXmlName name(const QXmlNodeModelIndex&) const; + virtual QString stringValue(const QXmlNodeModelIndex&) const; + virtual QVariant typedValue(const QXmlNodeModelIndex&) const; + virtual QVector<QXmlName> namespaceBindings(const QXmlNodeModelIndex&) const; + virtual QXmlNodeModelIndex elementById(const QXmlName &ncname) const; + virtual QVector<QXmlNodeModelIndex> nodesByIdref(const QXmlName &ncname) const; + +protected: + virtual QXmlNodeModelIndex nextFromSimpleAxis(SimpleAxis axis, + const QXmlNodeModelIndex &origin) const; + virtual QVector<QXmlNodeModelIndex> attributes(const QXmlNodeModelIndex&) const; + +}; + +QUrl TestNodeModel::baseUri(const QXmlNodeModelIndex&) const +{ + return QUrl(); +} + +QUrl TestNodeModel::documentUri(const QXmlNodeModelIndex&) const +{ + return QUrl(); +} + +QXmlNodeModelIndex::NodeKind TestNodeModel::kind(const QXmlNodeModelIndex&) const +{ + return QXmlNodeModelIndex::Element; +} + +QXmlNodeModelIndex::DocumentOrder TestNodeModel::compareOrder(const QXmlNodeModelIndex&, const QXmlNodeModelIndex&) const +{ + return QXmlNodeModelIndex::Precedes; +} + +QXmlNodeModelIndex TestNodeModel::root(const QXmlNodeModelIndex&) const +{ + return QXmlNodeModelIndex(); +} + +QXmlName TestNodeModel::name(const QXmlNodeModelIndex&) const +{ + return QXmlName(); +} + +QString TestNodeModel::stringValue(const QXmlNodeModelIndex&) const +{ + return QString(); +} + +QVariant TestNodeModel::typedValue(const QXmlNodeModelIndex&) const +{ + return QVariant(); +} + +QVector<QXmlName> TestNodeModel::namespaceBindings(const QXmlNodeModelIndex&) const +{ + return QVector<QXmlName>(); +} + +QXmlNodeModelIndex TestNodeModel::elementById(const QXmlName &ncname) const +{ + Q_UNUSED(ncname); + return QXmlNodeModelIndex(); +} + +QVector<QXmlNodeModelIndex> TestNodeModel::nodesByIdref(const QXmlName &ncname) const +{ + Q_UNUSED(ncname); + return QVector<QXmlNodeModelIndex>(); +} + +QXmlNodeModelIndex TestNodeModel::nextFromSimpleAxis(SimpleAxis, const QXmlNodeModelIndex &) const +{ + return QXmlNodeModelIndex(); +} + +QVector<QXmlNodeModelIndex> TestNodeModel::attributes(const QXmlNodeModelIndex&) const +{ + return QVector<QXmlNodeModelIndex>(); +} + diff --git a/tests/auto/qabstractxmlnodemodel/qabstractxmlnodemodel.pro b/tests/auto/qabstractxmlnodemodel/qabstractxmlnodemodel.pro new file mode 100644 index 0000000..a18f4ca --- /dev/null +++ b/tests/auto/qabstractxmlnodemodel/qabstractxmlnodemodel.pro @@ -0,0 +1,14 @@ +load(qttest_p4) +SOURCES += tst_qabstractxmlnodemodel.cpp \ + LoadingModel.cpp \ + ../qxmlquery/TestFundament.cpp +HEADERS += TestNodeModel.h LoadingModel.h + +include (../xmlpatterns.pri) + +wince*: { + addFiles.sources = tree.xml + addFiles.path = . + + DEPLOYMENT += addFiles +} diff --git a/tests/auto/qabstractxmlnodemodel/tree.xml b/tests/auto/qabstractxmlnodemodel/tree.xml new file mode 100644 index 0000000..cba262a --- /dev/null +++ b/tests/auto/qabstractxmlnodemodel/tree.xml @@ -0,0 +1,15 @@ +<documentElement xml:lang="en"> + <section1 noValue=""> + text1 + <?target1 data1?> + <?target2 data2?> + <?target3 data3?> + </section1> + <section2 attr1="1" attr2="2"/> + <!-- comment1 --> + <section3/> + <!-- comment2 --> + <!-- comment3 --> + <noChildren/> + <oneTextChild>theTextChild2</oneTextChild> +</documentElement> diff --git a/tests/auto/qabstractxmlnodemodel/tst_qabstractxmlnodemodel.cpp b/tests/auto/qabstractxmlnodemodel/tst_qabstractxmlnodemodel.cpp new file mode 100644 index 0000000..72b43ee --- /dev/null +++ b/tests/auto/qabstractxmlnodemodel/tst_qabstractxmlnodemodel.cpp @@ -0,0 +1,399 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QFile> +#include <QtTest/QtTest> + +#ifdef QTEST_XMLPATTERNS + +#include <QXmlFormatter> +#include <QXmlNamePool> +#include <QXmlQuery> +#include <QXmlResultItems> +#include <QXmlSerializer> + +#include "TestNodeModel.h" +#include "LoadingModel.h" +#include "../qxmlquery/TestFundament.h" + +/*! + \class tst_QAbstractXmlNodeModel + \internal + \since 4.4 + \brief Tests the QAbstractXmlNodeModel class. + */ +class tst_QAbstractXmlNodeModel : public QObject + , private TestFundament +{ + Q_OBJECT + +private Q_SLOTS: + // TODO lots of tests missing + void initTestCase(); + void constructor() const; + void objectSize() const; + void nextFromSimpleAxis(); + void nextFromSimpleAxis_data() const; + void constCorrectness() const; + void createData() const; + void createPointerAdditionalData() const; + void createDataAdditionalData() const; + void id() const; + void idref() const; + void typedValue() const; + +private: + QAbstractXmlNodeModel::Ptr m_nodeModel; + QXmlNamePool m_namePool; + QXmlNodeModelIndex m_rootNode; +}; + +void tst_QAbstractXmlNodeModel::initTestCase() +{ + m_nodeModel = LoadingModel::create(m_namePool); + QVERIFY(m_nodeModel); + m_rootNode = m_nodeModel->root(QXmlNodeModelIndex()); + QVERIFY(!m_rootNode.isNull()); +} + +void tst_QAbstractXmlNodeModel::constructor() const +{ + /* Allocate instance. */ + { + TestNodeModel instance; + } + + { + TestNodeModel instance1; + TestNodeModel instance2; + } + + { + TestNodeModel instance1; + TestNodeModel instance2; + TestNodeModel instance3; + } +} + +void tst_QAbstractXmlNodeModel::objectSize() const +{ + /* We can't currently test this in portable way, + * so disable it. */ + return; + + const int pointerSize = sizeof(void *); + // adjust for pointer alignment + const int sharedDataSize = ((sizeof(QSharedData) + pointerSize) / pointerSize) * pointerSize; + const int modelSize = sizeof(QAbstractXmlNodeModel); + + /* A d pointer plus a vtable pointer. */ + QCOMPARE(modelSize, sharedDataSize + pointerSize * 2); +} + +/*! + Tests nextFromSimpleAxis(). More exactly that all the logic in + QAbstractXmlNodeModel::iterate() is as we expect to. Subsequently, a lot + of testing code is in LoadingModel(.cpp). + + Approach: + + 1. In initTestCase() we loaded tree.xml into LoadingModel and + stored the root node in m_rootNode. + 2. We execute a query that navigates from m_rootNode and write out + the result using QXmlFormatter. + 3. We execute the exact same query, but this time use the built in node backend, + and write out the result in the same way. This is our baseline. + 4. Compare the two. + + Hence we check QAbstractXmlNodeModel::iterate() and friends against our XQuery + code, which in turn is (mainly) checked by the XQTS. This means safer testing + since we don't create baselines manually, and it also means that we can modify + the input file, tree.xml, without having to update static baselines. + */ +void tst_QAbstractXmlNodeModel::nextFromSimpleAxis() +{ + QFETCH(QString, queryString); + + QBuffer out; + + /* Fill out, using LoadingModel. */ + { + QXmlQuery query(m_namePool); + query.bindVariable(QLatin1String("node"), m_rootNode); + query.setQuery(queryString); + QVERIFY(query.isValid()); + + QVERIFY(out.open(QIODevice::WriteOnly)); + QXmlFormatter formatter(query, &out); + + QVERIFY(query.evaluateTo(&formatter)); + } + + QBuffer baseline; + + /* Create the baseline. */ + { + QXmlQuery openDoc(m_namePool); + openDoc.bindVariable(QLatin1String("docURI"), QVariant(inputFile(QLatin1String("tree.xml")))); + openDoc.setQuery(QLatin1String("doc($docURI)")); + QXmlResultItems doc; + QVERIFY(openDoc.isValid()); + openDoc.evaluateTo(&doc); + + QXmlQuery produceBaseline(m_namePool); + produceBaseline.bindVariable(QLatin1String("node"), doc.next()); + produceBaseline.setQuery(queryString); + QVERIFY(produceBaseline.isValid()); + QVERIFY(baseline.open(QIODevice::WriteOnly)); + + QXmlFormatter baselineFormatter(produceBaseline, &baseline); + QVERIFY(produceBaseline.evaluateTo(&baselineFormatter)); + } + + if(out.data() != baseline.data()) + { + QTextStream(stderr) << "ACTUAL:" << QString::fromUtf8(out.data().constData()) + << "EXPECTED:" << QString::fromUtf8(baseline.data().constData()); + } + + QCOMPARE(out.data(), baseline.data()); +} + +void tst_QAbstractXmlNodeModel::nextFromSimpleAxis_data() const +{ + QTest::addColumn<QString>("queryString"); + + QTest::newRow("The whole tree") + << "$node"; + + QTest::newRow("::descendant-or-self from $node, all nodes.") + << "$node/descendant-or-self::node()"; + + QTest::newRow("::descendant from $node, all nodes.") + << "$node/descendant::node()"; + + QTest::newRow("::descendant from node with no descendants.") + << "$node/descendant::node()"; + + QTest::newRow("following-sibling on $root.") + << "$node/text()[1]/following-sibling::node()"; + + QTest::newRow("following-sibling from section1.") + << "$node//section1/following-sibling::node()"; + + QTest::newRow("preceding-sibling-sibling from section1.") + << "$node//section1/preceding-sibling::node()"; + + QTest::newRow("following-sibling from oneTextChild.") + << "$node//oneTextChild/following-sibling::node()"; + + QTest::newRow("preceding-sibling-sibling from oneTextChild.") + << "$node//oneTextChild/preceding-sibling::node()"; + + QTest::newRow("preceding-sibling on $root.") + << "$node/preceding-sibling::node()"; + + QTest::newRow("::ancestor from node at the end") + << "$node//node()/ancestor::node()"; + + QTest::newRow("::ancestor-or-self from node at the end") + << "$node//node()/ancestor-or-self::node()"; + + QTest::newRow("Copy attributes from all nodes.") + << "<e>{for $i in $node//node()/@* order by $i return $i}</e>"; + + QTest::newRow("::preceding from node at the end") + << "($node//node())[last()]/preceding::node()"; + + QTest::newRow("::preceding from $node") + << "$node/preceding::node()"; + + QTest::newRow("::following from node at the end") + << "($node//node())[last()]/following::node()"; + + QTest::newRow("::following from $node") + << "$node//following::node()"; + + QTest::newRow("::following from $node") + << "$node/following::node()"; + + QTest::newRow("::descendant from text() nodes.") + << "$node/descendant-or-self::text()/descendant::node()"; + + QTest::newRow("::descendant-or-self from text() nodes.") + << "$node/descendant-or-self::text()/descendant-or-self::node()"; + + QTest::newRow("descendant-or-self::node() from section1.") + << "$node//section1/descendant-or-self::node()"; + + QTest::newRow("descendant::node() from section1.") + << "$node//section1/descendant::node()"; + + /* Checks for axis order. */ + + QTest::newRow("::descendant from text() nodes with last(), checking axis order.") + << "$node/descendant-or-self::text()/(descendant::node()[last()])"; + + QTest::newRow("::descendant-or-self from text() nodes with last(), checking axis order.") + << "$node/descendant-or-self::text()/(descendant-or-self::node()[last()])"; + + QTest::newRow("::descendant from text() nodes with predicate, checking axis order.") + << "$node/descendant-or-self::text()/(descendant::node()[2])"; + + QTest::newRow("::descendant-or-self from text() nodes with predicate, checking axis order.") + << "$node/descendant-or-self::text()/(descendant-or-self::node()[2])"; + + QTest::newRow("::following from node at the end with predicate, checking axis order.") + << "($node//node())[last()]/(following::node()[2])"; + + QTest::newRow("::following from node at the end with last(), checking axis order.") + << "($node//node())[last()]/(following::node()[last()])"; + + QTest::newRow("ancestor:: from node at the end with predicate, checking axis order.") + << "($node//node())[last()]/(ancestor::node()[2])"; + + QTest::newRow("ancestor:: from node at the end with last(), checking axis order.") + << "($node//node())[last()]/(ancestor::node()[last()])"; + + QTest::newRow("ancestor-or-self:: from node at the end with predicate, checking axis order.") + << "($node//node())[last()]/(ancestor::node()[2])"; + + QTest::newRow("ancestor-or-self:: from node at the end with last(), checking axis order.") + << "($node//node())[last()]/(ancestor::node()[last()])"; + + QTest::newRow("::preceding from node at the end with predicate, checking axis order.") + << "($node//node())[last()]/(preceding::node()[2])"; + + QTest::newRow("descendant-or-self in two levels, with last()") + << "$node/descendant-or-self::text()/(descendant-or-self::node()[last()])"; + + QTest::newRow("descendant-or-self with last()") + << "$node/descendant-or-self::node()[last()]"; + + QTest::newRow("::preceding from node at the end with last(), checking axis order.") + << "$node/preceding::node()[last()]"; + + QTest::newRow("::preceding combined with descendant-or-self, from node at the end with last(), checking axis order.") + << "$node//preceding::node()[last()]"; + + QTest::newRow("::preceding combined with descendant-or-self, from node at the end with last(), checking axis order.") + << "($node//node())[last()]/(preceding::node()[last()])"; +} + +void tst_QAbstractXmlNodeModel::constCorrectness() const +{ + // TODO +} + +void tst_QAbstractXmlNodeModel::createData() const +{ + // TODO + // Verify that the argument is qint64 +} + +void tst_QAbstractXmlNodeModel::createPointerAdditionalData() const +{ + // TODO + // Verify that the second argument is qint64 +} + +void tst_QAbstractXmlNodeModel::createDataAdditionalData() const +{ + // TODO +} + +void tst_QAbstractXmlNodeModel::id() const +{ + // TODO verify that invalid NCNames are not sent to the model. +} + +void tst_QAbstractXmlNodeModel::idref() const +{ + // TODO verify that invalid NCNames are not sent to the model. +} + +/*! + Verify that if QAbstractXmlNodeModel::typedValue() return a null + QVariant, it is treated as that the node has no typed value. + */ +void tst_QAbstractXmlNodeModel::typedValue() const +{ + class TypedModel : public TestNodeModel + { + public: + virtual QVariant typedValue(const QXmlNodeModelIndex &) const + { + return QVariant(); + } + + QXmlNodeModelIndex root() const + { + return createIndex(qint64(1)); + } + }; + + TypedModel model; + + QXmlQuery query; + query.bindVariable(QLatin1String("node"), model.root()); + query.setQuery(QLatin1String("declare variable $node external;" + "string($node), data($node)")); + + QByteArray output; + QBuffer buffer(&output); + QVERIFY(buffer.open(QIODevice::WriteOnly)); + QVERIFY(query.isValid()); + + QXmlSerializer serializer(query, &buffer); + QVERIFY(query.evaluateTo(&serializer)); + + QVERIFY(output.isEmpty()); +} + +QTEST_MAIN(tst_QAbstractXmlNodeModel) + +#include "tst_qabstractxmlnodemodel.moc" +#else +QTEST_NOOP_MAIN +#endif + +// vim: et:ts=4:sw=4:sts=4 |