Merge remote-tracking branch 'origin/master' into api_changes
[profile/ivi/qtdeclarative.git] / tests / auto / qml / qqmlparser / tst_qqmlparser.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include <private/qqmljsengine_p.h>
43 #include <private/qqmljsparser_p.h>
44 #include <private/qqmljslexer_p.h>
45 #include <private/qqmljsastvisitor_p.h>
46 #include <private/qqmljsast_p.h>
47
48 #include <qtest.h>
49 #include <QDir>
50 #include <QDebug>
51 #include <cstdlib>
52
53 class tst_qqmlparser : public QObject
54 {
55     Q_OBJECT
56 public:
57     tst_qqmlparser();
58
59 private slots:
60     void initTestCase();
61     void qmlParser_data();
62     void qmlParser();
63
64 private:
65     QStringList excludedDirs;
66
67     QStringList findFiles(const QDir &);
68 };
69
70 namespace check {
71
72 using namespace QQmlJS;
73
74 class Check: public AST::Visitor
75 {
76     Engine *engine;
77     QList<AST::Node *> nodeStack;
78
79 public:
80     Check(Engine *engine)
81         : engine(engine)
82     {
83     }
84
85     void operator()(AST::Node *node)
86     {
87         AST::Node::accept(node, this);
88     }
89
90     void checkNode(AST::Node *node)
91     {
92         if (! nodeStack.isEmpty()) {
93             AST::Node *parent = nodeStack.last();
94             const quint32 parentBegin = parent->firstSourceLocation().begin();
95             const quint32 parentEnd = parent->lastSourceLocation().end();
96
97             QVERIFY(node->firstSourceLocation().begin() >= parentBegin);
98             QVERIFY(node->lastSourceLocation().end() <= parentEnd);
99         }
100     }
101
102     virtual bool preVisit(AST::Node *node)
103     {
104         checkNode(node);
105         nodeStack.append(node);
106         return true;
107     }
108
109     virtual void postVisit(AST::Node *)
110     {
111         nodeStack.removeLast();
112     }
113 };
114
115 }
116
117 tst_qqmlparser::tst_qqmlparser()
118 {
119 }
120
121 void tst_qqmlparser::initTestCase()
122 {
123     // Add directories you want excluded here
124
125     // These snippets are not expected to run on their own.
126     excludedDirs << "doc/src/snippets/qml/visualdatamodel_rootindex";
127     excludedDirs << "doc/src/snippets/qml/qtbinding";
128     excludedDirs << "doc/src/snippets/qml/imports";
129     excludedDirs << "doc/src/snippets/qtquick1/visualdatamodel_rootindex";
130     excludedDirs << "doc/src/snippets/qtquick1/qtbinding";
131     excludedDirs << "doc/src/snippets/qtquick1/imports";
132 }
133
134 QStringList tst_qqmlparser::findFiles(const QDir &d)
135 {
136     for (int ii = 0; ii < excludedDirs.count(); ++ii) {
137         QString s = excludedDirs.at(ii);
138         if (d.absolutePath().endsWith(s))
139             return QStringList();
140     }
141
142     QStringList rv;
143
144     QStringList files = d.entryList(QStringList() << QLatin1String("*.qml") << QLatin1String("*.js"),
145                                     QDir::Files);
146     foreach (const QString &file, files) {
147         rv << d.absoluteFilePath(file);
148     }
149
150     QStringList dirs = d.entryList(QDir::Dirs | QDir::NoDotAndDotDot |
151                                    QDir::NoSymLinks);
152     foreach (const QString &dir, dirs) {
153         QDir sub = d;
154         sub.cd(dir);
155         rv << findFiles(sub);
156     }
157
158     return rv;
159 }
160
161 /*
162 This test checks all the qml and js files in the QtQml UI source tree
163 and ensures that the subnode's source locations are inside parent node's source locations
164 */
165
166 void tst_qqmlparser::qmlParser_data()
167 {
168     QTest::addColumn<QString>("file");
169
170     QString examples = QLatin1String(SRCDIR) + "/../../../../examples/";
171     QString tests = QLatin1String(SRCDIR) + "/../../../../tests/";
172
173     QStringList files;
174     files << findFiles(QDir(examples));
175     files << findFiles(QDir(tests));
176
177     foreach (const QString &file, files)
178         QTest::newRow(qPrintable(file)) << file;
179 }
180
181 void tst_qqmlparser::qmlParser()
182 {
183     QFETCH(QString, file);
184
185 #if defined(QTEST_CROSS_COMPILED)
186     QSKIP("sources not available when cross compiled");
187 #endif
188
189     using namespace QQmlJS;
190
191     QString code;
192
193     QFile f(file);
194     if (f.open(QFile::ReadOnly))
195         code = QString::fromUtf8(f.readAll());
196
197     const bool qmlMode = file.endsWith(QLatin1String(".qml"));
198
199     Engine engine;
200     Lexer lexer(&engine);
201     lexer.setCode(code, 1, qmlMode);
202     Parser parser(&engine);
203     if (qmlMode)
204         parser.parse();
205     else
206         parser.parseProgram();
207
208     check::Check chk(&engine);
209     chk(parser.rootNode());
210 }
211
212 QTEST_MAIN(tst_qqmlparser)
213
214 #include "tst_qqmlparser.moc"