tests/auto/qabstractxmlnodemodel/tst_qabstractxmlnodemodel.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the test suite of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 
       
    43 #include <QFile>
       
    44 #include <QtTest/QtTest>
       
    45 
       
    46 #ifdef QTEST_XMLPATTERNS
       
    47 
       
    48 #include <QSourceLocation>
       
    49 #include <QXmlFormatter>
       
    50 #include <QXmlNamePool>
       
    51 #include <QXmlQuery>
       
    52 #include <QXmlResultItems>
       
    53 #include <QXmlSerializer>
       
    54 
       
    55 #include "TestNodeModel.h"
       
    56 #include "LoadingModel.h"
       
    57 #include "../qxmlquery/TestFundament.h"
       
    58 
       
    59 /*!
       
    60  \class tst_QAbstractXmlNodeModel
       
    61  \internal
       
    62  \since 4.4
       
    63  \brief Tests the QAbstractXmlNodeModel class.
       
    64  */
       
    65 class tst_QAbstractXmlNodeModel : public QObject
       
    66                                 , private TestFundament
       
    67 {
       
    68     Q_OBJECT
       
    69 
       
    70 private Q_SLOTS:
       
    71     // TODO lots of tests missing
       
    72     void initTestCase();
       
    73     void constructor() const;
       
    74     void objectSize() const;
       
    75     void nextFromSimpleAxis();
       
    76     void nextFromSimpleAxis_data() const;
       
    77     void constCorrectness() const;
       
    78     void createData() const;
       
    79     void createPointerAdditionalData() const;
       
    80     void createDataAdditionalData() const;
       
    81     void id() const;
       
    82     void idref() const;
       
    83     void typedValue() const;
       
    84     void sourceLocation() const;
       
    85 
       
    86 private:
       
    87     QAbstractXmlNodeModel::Ptr  m_nodeModel;
       
    88     QXmlNamePool                m_namePool;
       
    89     QXmlNodeModelIndex          m_rootNode;
       
    90 };
       
    91 
       
    92 void tst_QAbstractXmlNodeModel::initTestCase()
       
    93 {
       
    94     m_nodeModel = LoadingModel::create(m_namePool);
       
    95     QVERIFY(m_nodeModel);
       
    96     m_rootNode = m_nodeModel->root(QXmlNodeModelIndex());
       
    97     QVERIFY(!m_rootNode.isNull());
       
    98 }
       
    99 
       
   100 void tst_QAbstractXmlNodeModel::constructor() const
       
   101 {
       
   102     /* Allocate instance. */
       
   103     {
       
   104         TestNodeModel instance;
       
   105     }
       
   106 
       
   107     {
       
   108         TestNodeModel instance1;
       
   109         TestNodeModel instance2;
       
   110     }
       
   111 
       
   112     {
       
   113         TestNodeModel instance1;
       
   114         TestNodeModel instance2;
       
   115         TestNodeModel instance3;
       
   116     }
       
   117 }
       
   118 
       
   119 void tst_QAbstractXmlNodeModel::objectSize() const
       
   120 {
       
   121     /* We can't currently test this in portable way,
       
   122      * so disable it. */
       
   123     return;
       
   124 
       
   125     const int pointerSize = sizeof(void *);
       
   126     // adjust for pointer alignment
       
   127     const int sharedDataSize = ((sizeof(QSharedData) + pointerSize) / pointerSize) * pointerSize;
       
   128     const int modelSize = sizeof(QAbstractXmlNodeModel);
       
   129 
       
   130     /* A d pointer plus a vtable pointer. */
       
   131     QCOMPARE(modelSize, sharedDataSize + pointerSize * 2);
       
   132 }
       
   133 
       
   134 /*!
       
   135  Tests nextFromSimpleAxis(). More exactly that all the logic in
       
   136  QAbstractXmlNodeModel::iterate() is as we expect to. Subsequently, a lot
       
   137  of testing code is in LoadingModel(.cpp).
       
   138 
       
   139  Approach:
       
   140 
       
   141   1. In initTestCase() we loaded tree.xml into LoadingModel and
       
   142      stored the root node in m_rootNode.
       
   143   2. We execute a query that navigates from m_rootNode and write out
       
   144      the result using QXmlFormatter.
       
   145   3. We execute the exact same query, but this time use the built in node backend,
       
   146      and write out the result in the same way. This is our baseline.
       
   147   4. Compare the two.
       
   148 
       
   149   Hence we check QAbstractXmlNodeModel::iterate() and friends against our XQuery
       
   150   code, which in turn is (mainly) checked by the XQTS. This means safer testing
       
   151   since we don't create baselines manually, and it also means that we can modify
       
   152   the input file, tree.xml, without having to update static baselines.
       
   153  */
       
   154 void tst_QAbstractXmlNodeModel::nextFromSimpleAxis()
       
   155 {
       
   156     QFETCH(QString, queryString);
       
   157 
       
   158     QBuffer out;
       
   159 
       
   160     /* Fill out, using LoadingModel. */
       
   161     {
       
   162         QXmlQuery query(m_namePool);
       
   163         query.bindVariable(QLatin1String("node"), m_rootNode);
       
   164         query.setQuery(queryString);
       
   165         QVERIFY(query.isValid());
       
   166 
       
   167         QVERIFY(out.open(QIODevice::WriteOnly));
       
   168         QXmlFormatter formatter(query, &out);
       
   169 
       
   170         QVERIFY(query.evaluateTo(&formatter));
       
   171     }
       
   172 
       
   173     QBuffer baseline;
       
   174 
       
   175     /* Create the baseline. */
       
   176     {
       
   177         QXmlQuery openDoc(m_namePool);
       
   178         openDoc.bindVariable(QLatin1String("docURI"), QVariant(inputFile(QLatin1String("tree.xml"))));
       
   179         openDoc.setQuery(QLatin1String("doc($docURI)"));
       
   180         QXmlResultItems doc;
       
   181         QVERIFY(openDoc.isValid());
       
   182         openDoc.evaluateTo(&doc);
       
   183 
       
   184         QXmlQuery produceBaseline(m_namePool);
       
   185         produceBaseline.bindVariable(QLatin1String("node"), doc.next());
       
   186         produceBaseline.setQuery(queryString);
       
   187         QVERIFY(produceBaseline.isValid());
       
   188         QVERIFY(baseline.open(QIODevice::WriteOnly));
       
   189 
       
   190         QXmlFormatter baselineFormatter(produceBaseline, &baseline);
       
   191         QVERIFY(produceBaseline.evaluateTo(&baselineFormatter));
       
   192     }
       
   193 
       
   194     if(out.data() != baseline.data())
       
   195     {
       
   196         QTextStream(stderr) << "ACTUAL:" << QString::fromUtf8(out.data().constData())
       
   197                             << "EXPECTED:" << QString::fromUtf8(baseline.data().constData());
       
   198     }
       
   199 
       
   200     QCOMPARE(out.data(), baseline.data());
       
   201 }
       
   202 
       
   203 void tst_QAbstractXmlNodeModel::nextFromSimpleAxis_data() const
       
   204 {
       
   205      QTest::addColumn<QString>("queryString");
       
   206 
       
   207      QTest::newRow("The whole tree")
       
   208          << "$node";
       
   209 
       
   210      QTest::newRow("::descendant-or-self from $node, all nodes.")
       
   211          << "$node/descendant-or-self::node()";
       
   212 
       
   213      QTest::newRow("::descendant from $node, all nodes.")
       
   214          << "$node/descendant::node()";
       
   215 
       
   216      QTest::newRow("::descendant from node with no descendants.")
       
   217          << "$node/descendant::node()";
       
   218 
       
   219      QTest::newRow("following-sibling on $root.")
       
   220          << "$node/text()[1]/following-sibling::node()";
       
   221 
       
   222      QTest::newRow("following-sibling from section1.")
       
   223          << "$node//section1/following-sibling::node()";
       
   224 
       
   225      QTest::newRow("preceding-sibling-sibling from section1.")
       
   226          << "$node//section1/preceding-sibling::node()";
       
   227 
       
   228      QTest::newRow("following-sibling from oneTextChild.")
       
   229          << "$node//oneTextChild/following-sibling::node()";
       
   230 
       
   231      QTest::newRow("preceding-sibling-sibling from oneTextChild.")
       
   232          << "$node//oneTextChild/preceding-sibling::node()";
       
   233 
       
   234      QTest::newRow("preceding-sibling on $root.")
       
   235          << "$node/preceding-sibling::node()";
       
   236 
       
   237      QTest::newRow("::ancestor from node at the end")
       
   238          << "$node//node()/ancestor::node()";
       
   239 
       
   240      QTest::newRow("::ancestor-or-self from node at the end")
       
   241          << "$node//node()/ancestor-or-self::node()";
       
   242 
       
   243      QTest::newRow("Copy attributes from all nodes.")
       
   244          << "<e>{for $i in $node//node()/@* order by $i return $i}</e>";
       
   245 
       
   246      QTest::newRow("::preceding from node at the end")
       
   247          << "($node//node())[last()]/preceding::node()";
       
   248 
       
   249      QTest::newRow("::preceding from $node")
       
   250          << "$node/preceding::node()";
       
   251 
       
   252      QTest::newRow("::following from node at the end")
       
   253          << "($node//node())[last()]/following::node()";
       
   254 
       
   255      QTest::newRow("::following from $node")
       
   256          << "$node//following::node()";
       
   257 
       
   258      QTest::newRow("::following from $node")
       
   259          << "$node/following::node()";
       
   260 
       
   261      QTest::newRow("::descendant from text() nodes.")
       
   262          << "$node/descendant-or-self::text()/descendant::node()";
       
   263 
       
   264      QTest::newRow("::descendant-or-self from text() nodes.")
       
   265          << "$node/descendant-or-self::text()/descendant-or-self::node()";
       
   266 
       
   267      QTest::newRow("descendant-or-self::node() from section1.")
       
   268          << "$node//section1/descendant-or-self::node()";
       
   269 
       
   270      QTest::newRow("descendant::node() from section1.")
       
   271          << "$node//section1/descendant::node()";
       
   272 
       
   273      /* Checks for axis order. */
       
   274 
       
   275      QTest::newRow("::descendant from text() nodes with last(), checking axis order.")
       
   276          << "$node/descendant-or-self::text()/(descendant::node()[last()])";
       
   277 
       
   278      QTest::newRow("::descendant-or-self from text() nodes with last(), checking axis order.")
       
   279          << "$node/descendant-or-self::text()/(descendant-or-self::node()[last()])";
       
   280 
       
   281      QTest::newRow("::descendant from text() nodes with predicate, checking axis order.")
       
   282          << "$node/descendant-or-self::text()/(descendant::node()[2])";
       
   283 
       
   284      QTest::newRow("::descendant-or-self from text() nodes with predicate, checking axis order.")
       
   285          << "$node/descendant-or-self::text()/(descendant-or-self::node()[2])";
       
   286 
       
   287      QTest::newRow("::following from node at the end with predicate, checking axis order.")
       
   288          << "($node//node())[last()]/(following::node()[2])";
       
   289 
       
   290      QTest::newRow("::following from node at the end with last(), checking axis order.")
       
   291          << "($node//node())[last()]/(following::node()[last()])";
       
   292 
       
   293      QTest::newRow("ancestor:: from node at the end with predicate, checking axis order.")
       
   294          << "($node//node())[last()]/(ancestor::node()[2])";
       
   295 
       
   296      QTest::newRow("ancestor:: from node at the end with last(), checking axis order.")
       
   297          << "($node//node())[last()]/(ancestor::node()[last()])";
       
   298 
       
   299      QTest::newRow("ancestor-or-self:: from node at the end with predicate, checking axis order.")
       
   300          << "($node//node())[last()]/(ancestor::node()[2])";
       
   301 
       
   302      QTest::newRow("ancestor-or-self:: from node at the end with last(), checking axis order.")
       
   303          << "($node//node())[last()]/(ancestor::node()[last()])";
       
   304 
       
   305      QTest::newRow("::preceding from node at the end with predicate, checking axis order.")
       
   306          << "($node//node())[last()]/(preceding::node()[2])";
       
   307 
       
   308      QTest::newRow("descendant-or-self in two levels, with last()")
       
   309          << "$node/descendant-or-self::text()/(descendant-or-self::node()[last()])";
       
   310 
       
   311      QTest::newRow("descendant-or-self with last()")
       
   312          << "$node/descendant-or-self::node()[last()]";
       
   313 
       
   314      QTest::newRow("::preceding from node at the end with last(), checking axis order.")
       
   315          << "$node/preceding::node()[last()]";
       
   316 
       
   317      QTest::newRow("::preceding combined with descendant-or-self, from node at the end with last(), checking axis order.")
       
   318          << "$node//preceding::node()[last()]";
       
   319 
       
   320      QTest::newRow("::preceding combined with descendant-or-self, from node at the end with last(), checking axis order.")
       
   321          << "($node//node())[last()]/(preceding::node()[last()])";
       
   322 }
       
   323 
       
   324 void tst_QAbstractXmlNodeModel::constCorrectness() const
       
   325 {
       
   326     // TODO
       
   327 }
       
   328 
       
   329 void tst_QAbstractXmlNodeModel::createData() const
       
   330 {
       
   331     // TODO
       
   332     // Verify that the argument is qint64
       
   333 }
       
   334 
       
   335 void tst_QAbstractXmlNodeModel::createPointerAdditionalData() const
       
   336 {
       
   337     // TODO
       
   338     // Verify that the second argument is qint64
       
   339 }
       
   340 
       
   341 void tst_QAbstractXmlNodeModel::createDataAdditionalData() const
       
   342 {
       
   343     // TODO
       
   344 }
       
   345 
       
   346 void tst_QAbstractXmlNodeModel::id() const
       
   347 {
       
   348     // TODO verify that invalid NCNames are not sent to the model.
       
   349 }
       
   350 
       
   351 void tst_QAbstractXmlNodeModel::idref() const
       
   352 {
       
   353     // TODO verify that invalid NCNames are not sent to the model.
       
   354 }
       
   355 
       
   356 /*!
       
   357  Verify that if QAbstractXmlNodeModel::typedValue() return a null
       
   358  QVariant, it is treated as that the node has no typed value.
       
   359  */
       
   360 void tst_QAbstractXmlNodeModel::typedValue() const
       
   361 {
       
   362     class TypedModel : public TestNodeModel
       
   363     {
       
   364     public:
       
   365         virtual QVariant typedValue(const QXmlNodeModelIndex &) const
       
   366         {
       
   367             return QVariant();
       
   368         }
       
   369 
       
   370         QXmlNodeModelIndex root() const
       
   371         {
       
   372             return createIndex(qint64(1));
       
   373         }
       
   374     };
       
   375 
       
   376     TypedModel model;
       
   377 
       
   378     QXmlQuery query;
       
   379     query.bindVariable(QLatin1String("node"), model.root());
       
   380     query.setQuery(QLatin1String("declare variable $node external;"
       
   381                                  "string($node), data($node)"));
       
   382 
       
   383     QByteArray output;
       
   384     QBuffer buffer(&output);
       
   385     QVERIFY(buffer.open(QIODevice::WriteOnly));
       
   386     QVERIFY(query.isValid());
       
   387 
       
   388     QXmlSerializer serializer(query, &buffer);
       
   389     QVERIFY(query.evaluateTo(&serializer));
       
   390 
       
   391     QVERIFY(output.isEmpty());
       
   392 }
       
   393 
       
   394 void tst_QAbstractXmlNodeModel::sourceLocation() const
       
   395 {
       
   396     const QAbstractXmlNodeModel* const constModel = m_nodeModel.data();
       
   397     const QSourceLocation location = constModel->sourceLocation(m_rootNode);
       
   398 }
       
   399 
       
   400 QTEST_MAIN(tst_QAbstractXmlNodeModel)
       
   401 
       
   402 #include "tst_qabstractxmlnodemodel.moc"
       
   403 #else
       
   404 QTEST_NOOP_MAIN
       
   405 #endif
       
   406 
       
   407 // vim: et:ts=4:sw=4:sts=4