예제 #1
0
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);
    }
}
예제 #2
0
void Reloader::reload()
{
    qDebug() << "reloading";
    //The engines has a internal cache that prevents reloading.
    QQmlEngine *engine = m_viewer->engine();
    engine->trimComponentCache();
    engine->clearComponentCache();
    m_viewer->setSource(m_mainFile);
}
예제 #3
0
void tst_qqmlengine::clearComponentCache()
{
    QQmlEngine engine;

    // Create original qml file
    {
        QFile file("temp.qml");
        QVERIFY(file.open(QIODevice::WriteOnly));
        file.write("import QtQuick 2.0\nQtObject {\nproperty int test: 10\n}\n");
        file.close();
    }

    // Test "test" property
    {
        QQmlComponent component(&engine, "temp.qml");
        QObject *obj = component.create();
        QVERIFY(obj != 0);
        QCOMPARE(obj->property("test").toInt(), 10);
        delete obj;
    }

    // Modify qml file
    {
        QFile file("temp.qml");
        QVERIFY(file.open(QIODevice::WriteOnly));
        file.write("import QtQuick 2.0\nQtObject {\nproperty int test: 11\n}\n");
        file.close();
    }

    // Test cache hit
    {
        QQmlComponent component(&engine, "temp.qml");
        QObject *obj = component.create();
        QVERIFY(obj != 0);
        QCOMPARE(obj->property("test").toInt(), 10);
        delete obj;
    }

    // Clear cache
    engine.clearComponentCache();

    // Test cache refresh
    {
        QQmlComponent component(&engine, "temp.qml");
        QObject *obj = component.create();
        QVERIFY(obj != 0);
        QCOMPARE(obj->property("test").toInt(), 11);
        delete obj;
    }
}
예제 #4
0
void tst_qmldiskcache::fileSelectors()
{
    QQmlEngine engine;

    QTemporaryDir tempDir;
    QVERIFY(tempDir.isValid());

    const QString testFilePath = tempDir.path() + "/test.qml";
    {
        QFile f(testFilePath);
        QVERIFY2(f.open(QIODevice::WriteOnly), qPrintable(f.errorString()));
        f.write(QByteArrayLiteral("import QtQml 2.0\nQtObject { property int value: 42 }"));
    }

    const QString selector = QStringLiteral("testSelector");
    const QString selectorPath = tempDir.path() + "/+" + selector;
    const QString selectedTestFilePath = selectorPath + "/test.qml";
    {
        QVERIFY(QDir::root().mkpath(selectorPath));
        QFile f(selectorPath + "/test.qml");
        QVERIFY2(f.open(QIODevice::WriteOnly), qPrintable(f.errorString()));
        f.write(QByteArrayLiteral("import QtQml 2.0\nQtObject { property int value: 100 }"));
    }

    {
        QQmlComponent component(&engine, testFilePath);
        QScopedPointer<QObject> obj(component.create());
        QVERIFY(!obj.isNull());
        QCOMPARE(obj->property("value").toInt(), 42);

        QFile cacheFile(testFilePath + "c");
        QVERIFY2(cacheFile.exists(), qPrintable(cacheFile.fileName()));
    }

    QQmlFileSelector qmlSelector(&engine);
    qmlSelector.setExtraSelectors(QStringList() << selector);

    engine.clearComponentCache();

    {
        QQmlComponent component(&engine, testFilePath);
        QScopedPointer<QObject> obj(component.create());
        QVERIFY(!obj.isNull());
        QCOMPARE(obj->property("value").toInt(), 100);

        QFile cacheFile(selectedTestFilePath + "c");
        QVERIFY2(cacheFile.exists(), qPrintable(cacheFile.fileName()));
    }
}
예제 #5
0
void tst_qmldiskcache::localAliases()
{
    QQmlEngine engine;

    TestCompiler testCompiler(&engine);
    QVERIFY(testCompiler.tempDir.isValid());

    const QByteArray contents = QByteArrayLiteral("import QtQml 2.0\n"
                                                  "QtObject {\n"
                                                  "    id: root\n"
                                                  "    property int prop: 100\n"
                                                  "    property alias dummy1: root.prop\n"
                                                  "    property alias dummy2: root.prop\n"
                                                  "    property alias dummy3: root.prop\n"
                                                  "    property alias dummy4: root.prop\n"
                                                  "    property alias dummy5: root.prop\n"
                                                  "    property alias foo: root.prop\n"
                                                  "    property alias bar: root.foo\n"
                                                   "}");

    {
        testCompiler.clearCache();
        QVERIFY2(testCompiler.compile(contents), qPrintable(testCompiler.lastErrorString));
        QVERIFY2(testCompiler.verify(), qPrintable(testCompiler.lastErrorString));
    }

    {
        CleanlyLoadingComponent component(&engine, testCompiler.testFilePath);
        QScopedPointer<QObject> obj(component.create());
        QVERIFY(!obj.isNull());
        QCOMPARE(obj->property("bar").toInt(), 100);
    }

    engine.clearComponentCache();

    {
        CleanlyLoadingComponent component(&engine, testCompiler.testFilePath);
        QScopedPointer<QObject> obj(component.create());
        QVERIFY(!obj.isNull());
        QCOMPARE(obj->property("bar").toInt(), 100);
    }
}
예제 #6
0
void tst_qmldiskcache::stableOrderOfDependentCompositeTypes()
{
    QQmlEngine engine;

    QTemporaryDir tempDir;
    QVERIFY(tempDir.isValid());

    {
        const QString depFilePath = tempDir.path() + "/FirstDependentType.qml";
        QFile f(depFilePath);
        QVERIFY2(f.open(QIODevice::WriteOnly), qPrintable(f.errorString()));
        f.write(QByteArrayLiteral("import QtQml 2.0\nQtObject { property int value: 42 }"));
    }

    {
        const QString depFilePath = tempDir.path() + "/SecondDependentType.qml";
        QFile f(depFilePath);
        QVERIFY2(f.open(QIODevice::WriteOnly), qPrintable(f.errorString()));
        f.write(QByteArrayLiteral("import QtQml 2.0\nQtObject { property int value: 100 }"));
    }

    const QString testFilePath = tempDir.path() + "/main.qml";
    {
        QFile f(testFilePath);
        QVERIFY2(f.open(QIODevice::WriteOnly), qPrintable(f.errorString()));
        f.write(QByteArrayLiteral("import QtQml 2.0\nQtObject {\n"
                                  "    property QtObject dep1: FirstDependentType{}\n"
                                  "    property QtObject dep2: SecondDependentType{}\n"
                                  "    property int value: dep1.value + dep2.value\n"
                                  "}"));
    }

    QByteArray firstDependentTypeClassName;
    QByteArray secondDependentTypeClassName;

    {
        CleanlyLoadingComponent component(&engine, QUrl::fromLocalFile(testFilePath));
        QScopedPointer<QObject> obj(component.create());
        QVERIFY(!obj.isNull());
        QCOMPARE(obj->property("value").toInt(), 142);

        firstDependentTypeClassName = qvariant_cast<QObject *>(obj->property("dep1"))->metaObject()->className();
        secondDependentTypeClassName = qvariant_cast<QObject *>(obj->property("dep2"))->metaObject()->className();
    }

    QVERIFY(firstDependentTypeClassName != secondDependentTypeClassName);
    QVERIFY2(firstDependentTypeClassName.contains("QMLTYPE"), firstDependentTypeClassName.constData());
    QVERIFY2(secondDependentTypeClassName.contains("QMLTYPE"), secondDependentTypeClassName.constData());

    const QString testFileCachePath = testFilePath + QLatin1Char('c');
    QVERIFY(QFile::exists(testFileCachePath));
    QDateTime initialCacheTimeStamp = QFileInfo(testFileCachePath).lastModified();

    engine.clearComponentCache();
    waitForFileSystem();

    // Creating the test component a second time should load it from the cache (same time stamp),
    // despite the class names of the dependent composite types differing.
    {
        CleanlyLoadingComponent component(&engine, QUrl::fromLocalFile(testFilePath));
        QScopedPointer<QObject> obj(component.create());
        QVERIFY(!obj.isNull());
        QCOMPARE(obj->property("value").toInt(), 142);

        QVERIFY(qvariant_cast<QObject *>(obj->property("dep1"))->metaObject()->className() != firstDependentTypeClassName);
        QVERIFY(qvariant_cast<QObject *>(obj->property("dep2"))->metaObject()->className() != secondDependentTypeClassName);
    }

    {
        QVERIFY(QFile::exists(testFileCachePath));
        QDateTime newCacheTimeStamp = QFileInfo(testFileCachePath).lastModified();
        QCOMPARE(newCacheTimeStamp, initialCacheTimeStamp);
    }

    // Now change the first dependent QML type and see if we correctly re-generate the
    // caches.
    engine.clearComponentCache();
    waitForFileSystem();
    {
        const QString depFilePath = tempDir.path() + "/FirstDependentType.qml";
        QFile f(depFilePath);
        QVERIFY2(f.open(QIODevice::WriteOnly), qPrintable(f.errorString()));
        f.write(QByteArrayLiteral("import QtQml 2.0\nQtObject { property int value: 40 }"));
    }

    {
        CleanlyLoadingComponent component(&engine, QUrl::fromLocalFile(testFilePath));
        QScopedPointer<QObject> obj(component.create());
        QVERIFY(!obj.isNull());
        QCOMPARE(obj->property("value").toInt(), 140);
    }

    {
        QVERIFY(QFile::exists(testFileCachePath));
        QDateTime newCacheTimeStamp = QFileInfo(testFileCachePath).lastModified();
        QVERIFY2(newCacheTimeStamp > initialCacheTimeStamp, qPrintable(newCacheTimeStamp.toString()));
    }
}