void tst_qmldiskcache::cppRegisteredSingletonDependency() { qmlClearTypeRegistrations(); QScopedPointer<QQmlEngine> engine(new QQmlEngine); 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(); }; writeTempFile("MySingleton.qml", "import QtQml 2.0\npragma Singleton\nQtObject { property int value: 42 }"); qmlRegisterSingletonType(QUrl::fromLocalFile(tempDir.path() + QLatin1String("/MySingleton.qml")), "CppRegisteredSingletonDependency", 1, 0, "Singly"); const QString testFilePath = writeTempFile("main.qml", "import QtQml 2.0\nimport CppRegisteredSingletonDependency 1.0\nQtObject {\n" " function getValue() { return Singly.value; }\n" "}"); { CleanlyLoadingComponent component(engine.data(), QUrl::fromLocalFile(testFilePath)); QScopedPointer<QObject> obj(component.create()); QVERIFY(!obj.isNull()); QVariant value; QVERIFY(QMetaObject::invokeMethod(obj.data(), "getValue", Q_RETURN_ARG(QVariant, value))); QCOMPARE(value.toInt(), 42); } const QString testFileCachePath = testFilePath + QLatin1Char('c'); QVERIFY(QFile::exists(testFileCachePath)); QDateTime initialCacheTimeStamp = QFileInfo(testFileCachePath).lastModified(); engine.reset(new QQmlEngine); waitForFileSystem(); writeTempFile("MySingleton.qml", "import QtQml 2.0\npragma Singleton\nQtObject { property int value: 100 }"); waitForFileSystem(); { CleanlyLoadingComponent component(engine.data(), QUrl::fromLocalFile(testFilePath)); QScopedPointer<QObject> obj(component.create()); QVERIFY(!obj.isNull()); { QVERIFY(QFile::exists(testFileCachePath)); QDateTime newCacheTimeStamp = QFileInfo(testFileCachePath).lastModified(); QVERIFY2(newCacheTimeStamp > initialCacheTimeStamp, qPrintable(newCacheTimeStamp.toString())); } QVariant value; QVERIFY(QMetaObject::invokeMethod(obj.data(), "getValue", Q_RETURN_ARG(QVariant, value))); QCOMPARE(value.toInt(), 100); } }
static void cleanState(QQmlEngine **e) { delete *e; qmlClearTypeRegistrations(); *e = new QQmlEngine; QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); QCoreApplication::processEvents(); }
void TestDriver::tearDown() { delete c; e->collectGarbage(); delete e; qmlClearTypeRegistrations(); //Note that i < 0 will effectively never terminate. This is deliberate as a prime use is to run indefinitely and watch the memory *not* grow i--; if (!i) qApp->quit(); else QTimer::singleShot(interval, this, SLOT(setUp())); }
void tst_qmldiskcache::recompileAfterChange() { QQmlEngine engine; TestCompiler testCompiler(&engine); QVERIFY(testCompiler.tempDir.isValid()); const QByteArray contents = QByteArrayLiteral("import TypeTest 1.0\n" "TypeThatWillChange {\n" "}"); qmlRegisterType<TypeVersion1>("TypeTest", 1, 0, "TypeThatWillChange"); { testCompiler.clearCache(); QVERIFY2(testCompiler.compile(contents), qPrintable(testCompiler.lastErrorString)); QVERIFY2(testCompiler.verify(), qPrintable(testCompiler.lastErrorString)); } QDateTime initialCacheTimeStamp = QFileInfo(testCompiler.cacheFilePath).lastModified(); { CleanlyLoadingComponent component(&engine, testCompiler.testFilePath); QScopedPointer<TypeVersion1> obj(qobject_cast<TypeVersion1*>(component.create())); QVERIFY(!obj.isNull()); QCOMPARE(QFileInfo(testCompiler.cacheFilePath).lastModified(), initialCacheTimeStamp); } engine.clearComponentCache(); { CleanlyLoadingComponent component(&engine, testCompiler.testFilePath); QScopedPointer<TypeVersion1> obj(qobject_cast<TypeVersion1*>(component.create())); QVERIFY(!obj.isNull()); QCOMPARE(QFileInfo(testCompiler.cacheFilePath).lastModified(), initialCacheTimeStamp); } engine.clearComponentCache(); qmlClearTypeRegistrations(); qmlRegisterType<TypeVersion2>("TypeTest", 1, 0, "TypeThatWillChange"); waitForFileSystem(); { CleanlyLoadingComponent component(&engine, testCompiler.testFilePath); QScopedPointer<TypeVersion2> obj(qobject_cast<TypeVersion2*>(component.create())); QVERIFY(!obj.isNull()); QVERIFY(QFileInfo(testCompiler.cacheFilePath).lastModified() > initialCacheTimeStamp); } }
void tst_qqmlenginecleanup::test_qmlClearTypeRegistrations() { //Test for preventing memory leaks is in tests/manual/qmltypememory QQmlEngine* engine; QQmlComponent* component; QUrl testFile = testFileUrl("types.qml"); qmlRegisterType<QObject>("Test", 2, 0, "TestTypeCpp"); engine = new QQmlEngine; component = new QQmlComponent(engine, testFile); QVERIFY(component->isReady()); delete engine; delete component; qmlClearTypeRegistrations(); //2nd run verifies that types can reload after a qmlClearTypeRegistrations qmlRegisterType<QObject>("Test", 2, 0, "TestTypeCpp"); engine = new QQmlEngine; component = new QQmlComponent(engine, testFile); QVERIFY(component->isReady()); delete engine; delete component; qmlClearTypeRegistrations(); //3nd run verifies that TestTypeCpp is no longer registered engine = new QQmlEngine; component = new QQmlComponent(engine, testFile); QVERIFY(component->isError()); QCOMPARE(component->errorString(), testFile.toString() +":46 module \"Test\" is not installed\n"); delete engine; delete component; }