aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2018-03-21 11:43:47 +0100
committerLiang Qi <liang.qi@qt.io>2018-03-21 11:43:47 +0100
commit089e5f7822e6d64e8e5864806929d29fd735fb0d (patch)
treebb0c4f173067e8a498c70e218f0b8c0c82a5525f /tests
parentbc4455cda2ae395f2943cd9f18b6ae51a676399a (diff)
parent1a816cd8dcc3499351ce6dfb6ad3bdfb34c31ede (diff)
Merge remote-tracking branch 'origin/5.11' into dev
Conflicts: tests/auto/qml/qjsengine/tst_qjsengine.cpp Change-Id: I25e264df273c01832f64dbd31923d8529f1d1900
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp24
-rw-r--r--tests/auto/qml/qjsengine/tst_qjsengine.cpp82
-rw-r--r--tests/auto/qml/qmlcachegen/qmlcachegen.pro2
-rw-r--r--tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp110
-rw-r--r--tests/auto/qml/qmlcachegen/versionchecks.qml4
-rw-r--r--tests/auto/qml/qqmlecmascript/data/include_callback.js2
-rw-r--r--tests/auto/qml/qqmllanguage/data/assignLiteralToJSValue.qml1
-rw-r--r--tests/auto/qml/qqmllanguage/data/empty.errors.txt3
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp5
-rw-r--r--tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp22
-rw-r--r--tests/auto/quick/qquickitem/BLACKLIST2
11 files changed, 252 insertions, 5 deletions
diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp
index d01d9a6791..89217e7556 100644
--- a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp
+++ b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp
@@ -141,6 +141,7 @@ private slots:
void queryObjectWithNonStreamableTypes();
void asynchronousCreate();
void invalidContexts();
+ void createObjectOnDestruction();
};
QmlDebugObjectReference tst_QQmlEngineDebugService::findRootObject(
@@ -1345,6 +1346,29 @@ void tst_QQmlEngineDebugService::invalidContexts()
QCOMPARE(m_dbg->rootContext().contexts.count(), 0);
}
+void tst_QQmlEngineDebugService::createObjectOnDestruction()
+{
+ QSignalSpy spy(m_dbg, SIGNAL(newObject(int)));
+ {
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData(
+ "import QtQml 2.0;"
+ "QtObject {"
+ "property Component x:"
+ "Qt.createQmlObject('import QtQml 2.0; Component { QtObject { } }',"
+ "this, 'x.qml');"
+ "Component.onDestruction: x.createObject(this, {});"
+ "}", QUrl::fromLocalFile("x.qml"));
+ QVERIFY(component.isReady());
+ QVERIFY(component.create());
+ QTRY_COMPARE(spy.count(), 2);
+ }
+ // Doesn't crash and doesn't give us another signal for the object created on destruction.
+ QTest::qWait(500);
+ QCOMPARE(spy.count(), 2);
+}
+
int main(int argc, char *argv[])
{
int _argc = argc + 1;
diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
index 9dc088486b..1eff5739b8 100644
--- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
@@ -128,6 +128,7 @@ private slots:
void JSONparse();
void arraySort();
void lookupOnDisappearingProperty();
+ void arrayConcat();
void qRegExpInport_data();
void qRegExpInport();
@@ -202,6 +203,7 @@ private slots:
void malformedExpression();
void scriptScopes();
+ void perfMapFile();
void binaryNumbers();
void octalNumbers();
@@ -3011,6 +3013,19 @@ void tst_QJSEngine::lookupOnDisappearingProperty()
QVERIFY(func.call(QJSValueList()<< o).isUndefined());
}
+void tst_QJSEngine::arrayConcat()
+{
+ QJSEngine eng;
+ QJSValue v = eng.evaluate("var x = [1, 2, 3, 4, 5, 6];"
+ "var y = [];"
+ "for (var i = 0; i < 5; ++i)"
+ " x.shift();"
+ "for (var i = 10; i < 13; ++i)"
+ " x.push(i);"
+ "x.toString();");
+ QCOMPARE(v.toString(), QString::fromLatin1("6,10,11,12"));
+}
+
static QRegExp minimal(QRegExp r) { r.setMinimal(true); return r; }
void tst_QJSEngine::qRegExpInport_data()
@@ -4165,6 +4180,73 @@ void tst_QJSEngine::octalNumbers()
QVERIFY(result.isError());
}
+static const char *perfMapKey = "QV4_PROFILE_WRITE_PERF_MAP";
+static const char *jitCallKey = "QV4_JIT_CALL_THRESHOLD";
+
+struct EnvironmentModifier {
+ const bool hasPerfMap = false;
+ const bool hasJitCall = false;
+ const QByteArray perfMap;
+ const QByteArray jitCall;
+
+ EnvironmentModifier() :
+ hasPerfMap(qEnvironmentVariableIsSet(perfMapKey)),
+ hasJitCall(qEnvironmentVariableIsSet(jitCallKey)),
+ perfMap(qgetenv(perfMapKey)),
+ jitCall(qgetenv(jitCallKey))
+ {
+ qputenv(perfMapKey, "1");
+ qputenv(jitCallKey, "0");
+ }
+
+ ~EnvironmentModifier()
+ {
+ if (hasPerfMap)
+ qputenv(perfMapKey, perfMap);
+ else
+ qunsetenv(perfMapKey);
+
+ if (hasJitCall)
+ qputenv(jitCallKey, jitCall);
+ else
+ qunsetenv(jitCallKey);
+ }
+};
+
+void tst_QJSEngine::perfMapFile()
+{
+#if !defined(Q_OS_LINUX)
+ QSKIP("perf map files are only generated on linux");
+#else
+ EnvironmentModifier modifier;
+ Q_UNUSED(modifier);
+ QJSEngine engine;
+ QJSValue def = engine.evaluate("'use strict'; function foo() { return 42 }");
+ QVERIFY(!def.isError());
+ QJSValue use = engine.evaluate("'use strict'; foo()");
+ QVERIFY(use.isNumber());
+ QFile file(QString::fromLatin1("/tmp/perf-%1.map").arg(QCoreApplication::applicationPid()));
+ QVERIFY(file.exists());
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ QList<QByteArray> functions;
+ while (!file.atEnd()) {
+ const QByteArray contents = file.readLine();
+ QVERIFY(contents.endsWith('\n'));
+ QList<QByteArray> fields = contents.split(' ');
+ QCOMPARE(fields.length(), 3);
+ bool ok = false;
+ const qulonglong address = fields[0].toULongLong(&ok, 16);
+ QVERIFY(ok);
+ QVERIFY(address > 0);
+ const ulong size = fields[1].toULong(&ok, 16);
+ QVERIFY(ok);
+ QVERIFY(size > 0);
+ functions.append(fields[2]);
+ }
+ QVERIFY(functions.contains("foo\n"));
+#endif
+}
+
QTEST_MAIN(tst_QJSEngine)
#include "tst_qjsengine.moc"
diff --git a/tests/auto/qml/qmlcachegen/qmlcachegen.pro b/tests/auto/qml/qmlcachegen/qmlcachegen.pro
index a8b72224ba..bad912c781 100644
--- a/tests/auto/qml/qmlcachegen/qmlcachegen.pro
+++ b/tests/auto/qml/qmlcachegen/qmlcachegen.pro
@@ -8,4 +8,6 @@ workerscripts_test.files = worker.js worker.qml
workerscripts_test.prefix = /workerscripts
RESOURCES += workerscripts_test
+RESOURCES += versionchecks.qml
+
QT += core-private qml-private testlib
diff --git a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
index 2f5ff0022e..1c05005c90 100644
--- a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
+++ b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
@@ -33,6 +33,7 @@
#include <QProcess>
#include <QLibraryInfo>
#include <QSysInfo>
+#include <QLoggingCategory>
#include <private/qqmlcomponent_p.h>
class tst_qmlcachegen: public QObject
@@ -47,6 +48,8 @@ private slots:
void signalHandlerParameters();
void errorOnArgumentsInSignalHandler();
void aheadOfTimeCompilation();
+ void functionExpressions();
+ void versionChecksForAheadOfTimeUnits();
void workerScripts();
};
@@ -279,6 +282,50 @@ void tst_qmlcachegen::aheadOfTimeCompilation()
QCOMPARE(result.toInt(), 42);
}
+static QQmlPrivate::CachedQmlUnit *temporaryModifiedCachedUnit = nullptr;
+
+void tst_qmlcachegen::versionChecksForAheadOfTimeUnits()
+{
+ QVERIFY(QFile::exists(":/versionchecks.qml"));
+ QCOMPARE(QFileInfo(":/versionchecks.qml").size(), 0);
+
+ Q_ASSERT(!temporaryModifiedCachedUnit);
+ QQmlMetaType::CachedUnitLookupError error = QQmlMetaType::CachedUnitLookupError::NoError;
+ const QV4::CompiledData::Unit *originalUnit = QQmlMetaType::findCachedCompilationUnit(QUrl("qrc:/versionchecks.qml"), &error);
+ QVERIFY(originalUnit);
+ QV4::CompiledData::Unit *tweakedUnit = (QV4::CompiledData::Unit *)malloc(originalUnit->unitSize);
+ memcpy(reinterpret_cast<void *>(tweakedUnit), reinterpret_cast<const void *>(originalUnit), originalUnit->unitSize);
+ tweakedUnit->version = QV4_DATA_STRUCTURE_VERSION - 1;
+ temporaryModifiedCachedUnit = new QQmlPrivate::CachedQmlUnit{tweakedUnit, nullptr, nullptr};
+
+ auto testHandler = [](const QUrl &url) -> const QQmlPrivate::CachedQmlUnit * {
+ if (url == QUrl("qrc:/versionchecks.qml"))
+ return temporaryModifiedCachedUnit;
+ return nullptr;
+ };
+ QQmlMetaType::prependCachedUnitLookupFunction(testHandler);
+
+ {
+ QQmlMetaType::CachedUnitLookupError error = QQmlMetaType::CachedUnitLookupError::NoError;
+ QVERIFY(!QQmlMetaType::findCachedCompilationUnit(QUrl("qrc:/versionchecks.qml"), &error));
+ QCOMPARE(error, QQmlMetaType::CachedUnitLookupError::VersionMismatch);
+ }
+
+ {
+ QQmlEngine engine;
+ QQmlComponent component(&engine, QUrl("qrc:/versionchecks.qml"));
+ QCOMPARE(component.status(), QQmlComponent::Error);
+ QCOMPARE(component.errorString(), QString("qrc:/versionchecks.qml:-1 File was compiled ahead of time with an incompatible version of Qt and the original file cannot be found. Please recompile\n"));
+ }
+
+ Q_ASSERT(temporaryModifiedCachedUnit);
+ free(const_cast<QV4::CompiledData::Unit *>(temporaryModifiedCachedUnit->qmlData));
+ delete temporaryModifiedCachedUnit;
+ temporaryModifiedCachedUnit = nullptr;
+
+ QQmlMetaType::removeCachedUnitLookupFunction(testHandler);
+}
+
void tst_qmlcachegen::workerScripts()
{
QVERIFY(QFile::exists(":/workerscripts/worker.js"));
@@ -292,6 +339,69 @@ void tst_qmlcachegen::workerScripts()
QTRY_VERIFY(obj->property("success").toBool());
}
+void tst_qmlcachegen::functionExpressions()
+{
+ QTemporaryDir tempDir;
+ QVERIFY(tempDir.isValid());
+
+ const auto writeTempFile = [&tempDir](const QString &fileName, const char *contents) {
+ QFile f(tempDir.path() + '/' + fileName);
+ const bool ok = f.open(QIODevice::WriteOnly | QIODevice::Truncate);
+ Q_ASSERT(ok);
+ f.write(contents);
+ return f.fileName();
+ };
+
+ const QString testFilePath = writeTempFile(
+ "test.qml",
+ "import QtQuick 2.0\n"
+ "Item {\n"
+ " id: di\n"
+ " \n"
+ " property var f\n"
+ " property bool f_called: false\n"
+ " f : function() { f_called = true }\n"
+ " \n"
+ " signal g\n"
+ " property bool g_handler_called: false\n"
+ " onG: function() { g_handler_called = true }\n"
+ " \n"
+ " signal h(int i)\n"
+ " property bool h_connections_handler_called: false\n"
+ " Connections {\n"
+ " target: di\n"
+ " onH: function(magic) { h_connections_handler_called = (magic == 42)\n }\n"
+ " }\n"
+ " \n"
+ " function runTest() { \n"
+ " f()\n"
+ " g()\n"
+ " h(42)\n"
+ " }\n"
+ "}");
+
+ QVERIFY(generateCache(testFilePath));
+
+ const QString cacheFilePath = testFilePath + QLatin1Char('c');
+ QVERIFY(QFile::exists(cacheFilePath));
+ QVERIFY(QFile::remove(testFilePath));
+
+ QQmlEngine engine;
+ CleanlyLoadingComponent component(&engine, QUrl::fromLocalFile(testFilePath));
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+
+ QCOMPARE(obj->property("f_called").toBool(), false);
+ QCOMPARE(obj->property("g_handler_called").toBool(), false);
+ QCOMPARE(obj->property("h_connections_handler_called").toBool(), false);
+
+ QMetaObject::invokeMethod(obj.data(), "runTest");
+
+ QCOMPARE(obj->property("f_called").toBool(), true);
+ QCOMPARE(obj->property("g_handler_called").toBool(), true);
+ QCOMPARE(obj->property("h_connections_handler_called").toBool(), true);
+}
+
QTEST_GUILESS_MAIN(tst_qmlcachegen)
#include "tst_qmlcachegen.moc"
diff --git a/tests/auto/qml/qmlcachegen/versionchecks.qml b/tests/auto/qml/qmlcachegen/versionchecks.qml
new file mode 100644
index 0000000000..77d67e7da4
--- /dev/null
+++ b/tests/auto/qml/qmlcachegen/versionchecks.qml
@@ -0,0 +1,4 @@
+import QtQml 2.0
+QtObject {
+ property bool ok: true
+}
diff --git a/tests/auto/qml/qqmlecmascript/data/include_callback.js b/tests/auto/qml/qqmlecmascript/data/include_callback.js
index ea19eba300..7f3195bb1f 100644
--- a/tests/auto/qml/qqmlecmascript/data/include_callback.js
+++ b/tests/auto/qml/qqmlecmascript/data/include_callback.js
@@ -1,6 +1,6 @@
function go() {
var a = Qt.include("missing.js", function(o) { test2 = o.status == o.NETWORK_ERROR });
- test1 = a.status == a.NETWORK_ERROR
+ test1 = (a.status == a.NETWORK_ERROR) && (a.statusText.indexOf("Error opening source file") != -1);
var b = Qt.include("blank.js", function(o) { test4 = o.status == o.OK });
test3 = b.status == b.OK
diff --git a/tests/auto/qml/qqmllanguage/data/assignLiteralToJSValue.qml b/tests/auto/qml/qqmllanguage/data/assignLiteralToJSValue.qml
index fce248a381..69b0096a5e 100644
--- a/tests/auto/qml/qqmllanguage/data/assignLiteralToJSValue.qml
+++ b/tests/auto/qml/qqmllanguage/data/assignLiteralToJSValue.qml
@@ -30,6 +30,7 @@ QtObject {
MyQmlObject { id: testObj22; objectName: "test22"; qjsvalue: null },
MyQmlObject { id: testObj1Bound; objectName: "test1Bound"; qjsvalue: testObj1.qjsvalue + 4 }, // 1 + 4 + 4 = 9
MyQmlObject { id: testObj20Bound; objectName: "test20Bound"; qjsvalue: testObj20.qjsvalue(testObj1Bound.qjsvalue) }, // 9 * 3 = 27
+ MyQmlObject { id: testObj23; objectName: "test23"; qjsvalue: QtObject { objectName: "blah" } },
QtObject {
id: varProperties
objectName: "varProperties"
diff --git a/tests/auto/qml/qqmllanguage/data/empty.errors.txt b/tests/auto/qml/qqmllanguage/data/empty.errors.txt
index 620db2bbba..ba685d78ae 100644
--- a/tests/auto/qml/qqmllanguage/data/empty.errors.txt
+++ b/tests/auto/qml/qqmllanguage/data/empty.errors.txt
@@ -1,2 +1 @@
-1:1:Expected token `numeric literal'
-1:1:Expected a qualified name id
+-1:-1:File is empty
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
index f1f35f9fd4..18b1718ddf 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -934,6 +934,11 @@ void tst_qqmllanguage::assignLiteralToJSValue()
QJSValue value = object->qjsvalue();
QVERIFY(value.isNumber());
QCOMPARE(value.toNumber(), qreal(27));
+ } {
+ MyQmlObject *object = root->findChild<MyQmlObject *>("test23");
+ QJSValue value = object->qjsvalue();
+ QVERIFY(value.isQObject());
+ QCOMPARE(value.toQObject()->objectName(), "blah");
}
}
diff --git a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
index 4618ea4071..9fdc54f067 100644
--- a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
+++ b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
@@ -125,6 +125,7 @@ private slots:
void bindingsOnGetResult();
void stringifyModelEntry();
void qobjectTrackerForDynamicModelObjects();
+ void crash_append_empty_array();
};
bool tst_qqmllistmodel::compareVariantList(const QVariantList &testList, QVariant object)
@@ -1534,6 +1535,27 @@ void tst_qqmllistmodel::qobjectTrackerForDynamicModelObjects()
QVERIFY(!ddata->jsWrapper.isNullOrUndefined());
}
+void tst_qqmllistmodel::crash_append_empty_array()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData(
+ "import QtQuick 2.0\n"
+ "Item {\n"
+ " ListModel {\n"
+ " id: testModel\n"
+ " objectName: \"testModel\""
+ " }\n"
+ "}\n", QUrl());
+ QScopedPointer<QObject> scene(component.create());
+ QQmlListModel *model = scene->findChild<QQmlListModel*>("testModel");
+ QSignalSpy spy(model, &QQmlListModel::rowsAboutToBeInserted);
+ QQmlExpression expr(engine.rootContext(), model, "append(new Array())");
+ expr.evaluate();
+ QVERIFY2(!expr.hasError(), QTest::toString(expr.error().toString()));
+ QCOMPARE(spy.count(), 0);
+}
+
QTEST_MAIN(tst_qqmllistmodel)
#include "tst_qqmllistmodel.moc"
diff --git a/tests/auto/quick/qquickitem/BLACKLIST b/tests/auto/quick/qquickitem/BLACKLIST
index f00b061356..d94a3ef102 100644
--- a/tests/auto/quick/qquickitem/BLACKLIST
+++ b/tests/auto/quick/qquickitem/BLACKLIST
@@ -1,4 +1,2 @@
[contains:hollow square: testing points inside]
xcb
-[ignoreButtonPressNotInAcceptedMouseButtons]
-*