1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#include <qtest.h>
30#include <QtQml/qqmlengine.h>
31#include <QtQml/qqmlfile.h>
32#include <QtQml/qqmlcomponent.h>
33#include <QtQml/qqmlexpression.h>
34#include <QtQml/qqmlscriptstring.h>
35#include "../../shared/util.h"
36
37class tst_qqmlexpression : public QQmlDataTest
38{
39 Q_OBJECT
40public:
41 tst_qqmlexpression() {}
42
43private slots:
44 void scriptString();
45 void syntaxError();
46 void exception();
47 void expressionFromDataComponent();
48};
49
50class TestObject : public QObject
51{
52 Q_OBJECT
53 Q_PROPERTY(QQmlScriptString scriptString READ scriptString WRITE setScriptString)
54 Q_PROPERTY(QQmlScriptString scriptStringError READ scriptStringError WRITE setScriptStringError)
55public:
56 TestObject(QObject *parent = nullptr) : QObject(parent) {}
57
58 QQmlScriptString scriptString() const { return m_scriptString; }
59 void setScriptString(QQmlScriptString scriptString) { m_scriptString = scriptString; }
60
61 QQmlScriptString scriptStringError() const { return m_scriptStringError; }
62 void setScriptStringError(QQmlScriptString scriptString) { m_scriptStringError = scriptString; }
63
64private:
65 QQmlScriptString m_scriptString;
66 QQmlScriptString m_scriptStringError;
67};
68
69QML_DECLARE_TYPE(TestObject)
70
71void tst_qqmlexpression::scriptString()
72{
73 qmlRegisterType<TestObject>(uri: "Test", versionMajor: 1, versionMinor: 0, qmlName: "TestObject");
74
75 QQmlEngine engine;
76 QQmlComponent c(&engine, testFileUrl(fileName: "scriptString.qml"));
77 TestObject *testObj = qobject_cast<TestObject*>(object: c.create());
78 QVERIFY(testObj != nullptr);
79
80 QQmlScriptString script = testObj->scriptString();
81 QVERIFY(!script.isEmpty());
82
83 QQmlExpression expression(script);
84 QVariant value = expression.evaluate();
85 QCOMPARE(value.toInt(), 15);
86
87 QQmlScriptString scriptError = testObj->scriptStringError();
88 QVERIFY(!scriptError.isEmpty());
89
90 //verify that the expression has the correct error location information
91 QQmlExpression expressionError(scriptError);
92 QVariant valueError = expressionError.evaluate();
93 QVERIFY(!valueError.isValid());
94 QVERIFY(expressionError.hasError());
95 QQmlError error = expressionError.error();
96 QCOMPARE(error.url(), c.url());
97 QCOMPARE(error.line(), 8);
98}
99
100// QTBUG-21310 - crash test
101void tst_qqmlexpression::syntaxError()
102{
103 QQmlEngine engine;
104 QQmlExpression expression(engine.rootContext(), nullptr, "asd asd");
105 bool isUndefined = false;
106 QVariant v = expression.evaluate(valueIsUndefined: &isUndefined);
107 QCOMPARE(v, QVariant());
108 QVERIFY(expression.hasError());
109 QCOMPARE(expression.error().description(), "SyntaxError: Expected token `;'");
110 QVERIFY(isUndefined);
111}
112
113void tst_qqmlexpression::exception()
114{
115 QQmlEngine engine;
116 QQmlExpression expression(engine.rootContext(), nullptr, "abc=123");
117 QVariant v = expression.evaluate();
118 QCOMPARE(v, QVariant());
119 QVERIFY(expression.hasError());
120}
121
122void tst_qqmlexpression::expressionFromDataComponent()
123{
124 qmlRegisterType<TestObject>(uri: "Test", versionMajor: 1, versionMinor: 0, qmlName: "TestObject");
125
126 QQmlEngine engine;
127 QQmlComponent c(&engine);
128
129 const QString fn(QLatin1String("expressionFromDataComponent.qml"));
130 QUrl url = testFileUrl(fileName: fn);
131 QString path = testFile(fileName: fn);
132
133 {
134 QFile f(path);
135 QVERIFY(f.open(QIODevice::ReadOnly));
136 c.setData(f.readAll(), baseUrl: url);
137 }
138
139 QScopedPointer<TestObject> object;
140 object.reset(other: qobject_cast<TestObject*>(object: c.create()));
141 Q_ASSERT(!object.isNull());
142
143 QQmlExpression expression(object->scriptString());
144 QVariant result = expression.evaluate();
145 QCOMPARE(result.type(), QVariant::String);
146 QCOMPARE(result.toString(), QStringLiteral("success"));
147}
148
149QTEST_MAIN(tst_qqmlexpression)
150
151#include "tst_qqmlexpression.moc"
152

source code of qtdeclarative/tests/auto/qml/qqmlexpression/tst_qqmlexpression.cpp