1
/****************************************************************************
2
**
3
** Copyright (C) 2012 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
** GNU Lesser General Public License Usage
11
** This file may be used under the terms of the GNU Lesser General Public
12
** License version 2.1 as published by the Free Software Foundation and
13
** appearing in the file LICENSE.LGPL included in the packaging of this
14
** file. Please review the following information to ensure the GNU Lesser
15
** General Public License version 2.1 requirements will be met:
16
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17
**
18
** In addition, as a special exception, Nokia gives you certain additional
19
** rights. These rights are described in the Nokia Qt LGPL Exception
20
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21
**
22
** GNU General Public License Usage
23
** Alternatively, this file may be used under the terms of the GNU General
24
** Public License version 3.0 as published by the Free Software Foundation
25
** and appearing in the file LICENSE.GPL included in the packaging of this
26
** file. Please review the following information to ensure the GNU General
27
** Public License version 3.0 requirements will be met:
28
** http://www.gnu.org/copyleft/gpl.html.
29
**
30
** Other Usage
31
** Alternatively, this file may be used in accordance with the terms and
32
** conditions contained in a signed written agreement between you and Nokia.
33
**
34
**
35
**
36
**
37
**
38
** $QT_END_LICENSE$
39
**
40
****************************************************************************/
41
42
43
#include <QtTest/QtTest>
44
45
#ifdef QTEST_XMLPATTERNS
46
47
#include <QtCore/QDir>
48
#include <QtXmlPatterns/QXmlQuery>
49
#include <QtXmlPatterns/QXmlSerializer>
50
#include <QtXmlPatterns/QXmlResultItems>
51
#include <QtXmlPatterns/QXmlFormatter>
52
53
#include "../qxmlquery/MessageSilencer.h"
54
#include "../qsimplexmlnodemodel/TestSimpleNodeModel.h"
55
56
/*!
57
 \class tst_PatternistExamples
58
 \internal
59
 \since 4.4
60
 \brief Verifies examples for Patternist.
61
 */
62
class tst_PatternistExamples : public QObject
63
{
64
    Q_OBJECT
65
66
private Q_SLOTS:
67
    void initTestCase();
68
    void checkQueries() const;
69
    void checkQueries_data() const;
70
    void checkXMLFiles() const;
71
    void checkXMLFiles_data() const;
72
    void buildSnippets() const;
73
74
private:
75
    QVector<QDir> m_dirs;
76
    QStringList listFiles(const QStringList &patterns) const;
77
    enum Constants
78
    {
79
        XMLFileCount = 12,
80
        XQueryFileCount = 52
81
    };
82
};
83
84
void tst_PatternistExamples::initTestCase()
85
{
86
#ifndef Q_OS_WINCE
87
    m_dirs.append(QDir(QLatin1String("../../../doc/src/snippets/patternist/")));
88
    m_dirs.append(QDir(QLatin1String("../../../examples/xmlpatterns/xquery/globalVariables/")));
89
    m_dirs.append(QDir(QLatin1String("../../../examples/xmlpatterns/filetree/")));
90
    m_dirs.append(QDir(QLatin1String("../../../examples/xmlpatterns/recipes/")));
91
    m_dirs.append(QDir(QLatin1String("../../../examples/xmlpatterns/recipes/files/")));
92
#else
93
    m_dirs.append(QDir(QLatin1String("patternist/")));
94
    m_dirs.append(QDir(QLatin1String("globalVariables/")));
95
    m_dirs.append(QDir(QLatin1String("filetree/")));
96
    m_dirs.append(QDir(QLatin1String("recipes/")));
97
    m_dirs.append(QDir(QLatin1String("recipes/files/")));
98
#endif
99
    for(int i = 0; i < m_dirs.size(); ++i)
100
        QVERIFY(m_dirs.at(i).exists());
101
}
102
103
/*!
104
  Returns a QStringList containing absolute filenames that were found in the predefined locations, when
105
  filtered through \a pattterns.
106
 */
107
QStringList tst_PatternistExamples::listFiles(const QStringList &patterns) const
108
{
109
    QStringList result;
110
111
    for(int i = 0; i < m_dirs.size(); ++i)
112
    {
113
        const QDir &dir = m_dirs.at(i);
114
115
        const QStringList files(dir.entryList(patterns));
116
        for(int s = 0; s < files.count(); ++s)
117
            result += dir.absoluteFilePath(files.at(s));
118
    }
119
120
    return result;
121
}
122
123
/*!
124
  Check that the queries contains no static errors such as
125
  syntax errors.
126
 */
127
void tst_PatternistExamples::checkQueries() const
128
{
129
    QFETCH(QString, queryFile);
130
131
    QFile file(queryFile);
132
    QVERIFY(file.open(QIODevice::ReadOnly));
133
134
    QXmlQuery query;
135
136
    /* Two queries relies on this binding, so provide it such that we don't get a compile error. */
137
    query.bindVariable(QLatin1String("fileToOpen"), QVariant(QString::fromLatin1("dummyString")));
138
139
    /* This is needed for the recipes example. */
140
    query.bindVariable(QLatin1String("inputDocument"), QVariant(QString::fromLatin1("dummString")));
141
142
    /* This is needed for literalsAndOperators.xq. */
143
    query.bindVariable(QLatin1String("date"), QVariant(QDate::currentDate()));
144
145
    /* These are needed for introExample2.xq. */
146
    query.bindVariable(QLatin1String("file"), QVariant(QLatin1String("dummy")));
147
    query.bindVariable(QLatin1String("publisher"), QVariant(QLatin1String("dummy")));
148
    query.bindVariable(QLatin1String("year"), QVariant(2000));
149
150
    /* and filetree/ needs this. */
151
    TestSimpleNodeModel nodeModel(query.namePool());
152
    query.bindVariable(QLatin1String("exampleDirectory"), nodeModel.root());
153
154
    query.setQuery(&file, queryFile);
155
156
    QVERIFY2(query.isValid(), QString::fromLatin1("%1 failed to compile").arg(queryFile).toLatin1().constData());
157
}
158
159
void tst_PatternistExamples::checkQueries_data() const
160
{
161
    QTest::addColumn<QString>("queryFile");
162
163
    const QStringList queryExamples(listFiles(QStringList(QLatin1String("*.xq"))));
164
165
    QCOMPARE(queryExamples.count(), int(XQueryFileCount));
166
167
    foreach(QString q, queryExamples)
168
        QTest::newRow(q.toLocal8Bit().constData()) << q;
169
}
170
171
void tst_PatternistExamples::checkXMLFiles() const
172
{
173
    QFETCH(QString, file);
174
175
    QXmlQuery query;
176
    /* Wrapping in QUrl ensures it gets formatted as a URI on all platforms. */
177
    query.setQuery(QLatin1String("doc('") + QUrl::fromLocalFile(file).toString() + QLatin1String("')"));
178
    QVERIFY(query.isValid());
179
180
    /* We don't care about the result, we only want to ensure the files can be parsed. */
181
    QByteArray dummy;
182
    QBuffer buffer(&dummy);
183
    QVERIFY(buffer.open(QIODevice::WriteOnly));
184
185
    QXmlSerializer serializer(query, &buffer);
186
187
    /* This is the important one. */
188
    QVERIFY(query.evaluateTo(&serializer));
189
}
190
191
void tst_PatternistExamples::checkXMLFiles_data() const
192
{
193
    QTest::addColumn<QString>("file");
194
    QStringList patterns;
195
    patterns.append(QLatin1String("*.xml"));
196
    patterns.append(QLatin1String("*.gccxml"));
197
    patterns.append(QLatin1String("*.svg"));
198
    patterns.append(QLatin1String("*.ui"));
199
    patterns.append(QLatin1String("*.html"));
200
201
    const QStringList xmlFiles(listFiles(patterns));
202
203
    if(xmlFiles.count() != XMLFileCount)
204
        qDebug() << "These files were encountered:" << xmlFiles;
205
206
    QCOMPARE(xmlFiles.count(), int(XMLFileCount));
207
208
    foreach(QString q, xmlFiles)
209
        QTest::newRow(q.toLocal8Bit().constData()) << q;
210
}
211
212
/*!
213
 Below, we include all the examples and ensure that they build, such that we rule
214
 out syntax error and that API changes has propagated into examples.
215
216
 An improvement could be to run them, to ensure that they behave as they intend
217
 to.
218
 */
219
220
static QUrl abstractURI()
221
{
222
    QUrl baseURI;
223
    QUrl relative;
224
#include "../../doc/src/snippets/code/src_xmlpatterns_api_qabstracturiresolver.cpp"
225
}
226
227
class MyValue
228
{
229
public:
230
    MyValue parent() const
231
    {
232
        return MyValue();
233
    }
234
};
235
236
static MyValue toMyValue(const QXmlNodeModelIndex &)
237
{
238
    return MyValue();
239
}
240
241
static QXmlNodeModelIndex toNodeIndex(const MyValue &)
242
{
243
    return QXmlNodeModelIndex();
244
}
245
246
class MyTreeModel : public QSimpleXmlNodeModel
247
{
248
public:
249
    MyTreeModel(const QXmlNamePool &np, const QFile &f);
250
251
    virtual QUrl documentUri(const QXmlNodeModelIndex&) const
252
    {
253
        return QUrl();
254
    }
255
256
    virtual QXmlNodeModelIndex::NodeKind kind(const QXmlNodeModelIndex&) const
257
    {
258
        return QXmlNodeModelIndex::Element;
259
    }
260
261
    virtual QXmlNodeModelIndex::DocumentOrder compareOrder(const QXmlNodeModelIndex&, const QXmlNodeModelIndex&) const
262
    {
263
        return QXmlNodeModelIndex::Is;
264
    }
265
266
    virtual QXmlNodeModelIndex root(const QXmlNodeModelIndex&) const
267
    {
268
        return QXmlNodeModelIndex();
269
    }
270
271
    virtual QXmlName name(const QXmlNodeModelIndex&) const
272
    {
273
        return QXmlName();
274
    }
275
276
    virtual QVariant typedValue(const QXmlNodeModelIndex&) const
277
    {
278
        return QVariant();
279
    }
280
281
    virtual QVector<QXmlNodeModelIndex> attributes(const QXmlNodeModelIndex&) const
282
    {
283
        return QVector<QXmlNodeModelIndex>();
284
    }
285
286
    QXmlNodeModelIndex nodeFor(const QString &) const
287
    {
288
        return QXmlNodeModelIndex();
289
    }
290
291
    virtual QXmlNodeModelIndex nextFromSimpleAxis(SimpleAxis axis, const QXmlNodeModelIndex &origin) const;
292
};
293
294
/*
295
 Exists for linking with at least msvc-2005.
296
*/
297
MyTreeModel::MyTreeModel(const QXmlNamePool &np, const QFile &) : QSimpleXmlNodeModel(np)
298
{
299
}
300
301
#include "../../doc/src/snippets/code/src_xmlpatterns_api_qsimplexmlnodemodel.cpp"
302
303
class MyMapper
304
{
305
public:
306
    class InputType;
307
    enum OutputType
308
    {
309
    };
310
#include "../../doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlforwarditerator.cpp"
311
};
312
313
#include "../../doc/src/snippets/code/src_xmlpatterns_api_qxmlname.cpp"
314
315
void tst_PatternistExamples::buildSnippets() const
316
{
317
    /* We don't run this code, see comment above. */
318
    return;
319
320
    /* We place a call to this function, such that GCC doesn't emit a warning. */
321
    abstractURI();
322
323
    {
324
    }
325
326
    {
327
#include "../../doc/src/snippets/code/src_xmlpatterns_api_qxmlresultitems.cpp"
328
    }
329
330
    {
331
    }
332
333
    {
334
        QIODevice *myOutputDevice = 0;
335
#include "../../doc/src/snippets/code/src_xmlpatterns_api_qxmlformatter.cpp"
336
    }
337
338
    {
339
        QIODevice *myOutputDevice = 0;
340
#include "../../doc/src/snippets/code/src_xmlpatterns_api_qxmlserializer.cpp"
341
    }
342
343
    {
344
        QXmlNodeModelIndex myInstance;
345
        const char **argv = 0;
346
        typedef MyTreeModel ChemistryNodeModel;
347
#include "../../doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlnodemodel.cpp"
348
    }
349
350
    {
351
    }
352
353
    {
354
        QIODevice *myOutputDevice = 0;
355
#include "../../doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlreceiver.cpp"
356
    }
357
358
    {
359
        QXmlQuery query;
360
        QString localName;
361
        QVariant value;
362
#include "../../doc/src/snippets/code/src_xmlpatterns_api_qxmlquery.cpp"
363
    }
364
}
365
366
QTEST_MAIN(tst_PatternistExamples)
367
368
#include "tst_patternistexamples.moc"
369
#else
370
QTEST_NOOP_MAIN
371
#endif
372
373
// vim: et:ts=4:sw=4:sts=4