Improve tst_qquickshadereffect

- Use a stack local for the view.
- Don't manually delete stuff.
- Use TRY macros instead of manual waits.
- Use initView and showView helpers to reduce boilerplate.
- Fix an incorrect comment.

Pick-to: 6.2 6.3 6.4
Change-Id: Ia7cde53d46c54cd034ab6fa3b617589839359024
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
Mitch Curtis 2022-06-09 21:28:12 +08:00
parent 067d5a3334
commit 0644ed2d79
1 changed files with 34 additions and 46 deletions

View File

@ -7,9 +7,11 @@
#include <QByteArray>
#include <private/qquickshadereffect_p.h>
#include <QMatrix4x4>
#include <QtQuick/QQuickView>
#include <QtQml/QQmlEngine>
#include <QtQuick/QQuickView>
#include <QtQuick/private/qquickshadereffectsource_p.h>
#include <QtQuickTestUtils/private/qmlutils_p.h>
#include <QtQuickTestUtils/private/viewtestutils_p.h>
class TestShaderEffect : public QQuickShaderEffect
{
@ -95,17 +97,17 @@ void tst_qquickshadereffect::cleanupTestCase()
void tst_qquickshadereffect::testConnection()
{
// verify that the property notify signal is connected
QQuickView *view = new QQuickView(nullptr);
view->setSource(QUrl(QStringLiteral("qrc:/data/connections.qml")));
QQuickView view;
QVERIFY(QQuickTest::initView(view, QStringLiteral("qrc:/data/connections.qml")));
auto *shaderEffectItem = qobject_cast<TestShaderEffect*>(view->rootObject());
auto *shaderEffectItem = qobject_cast<TestShaderEffect*>(view.rootObject());
QVERIFY(shaderEffectItem);
QCOMPARE(shaderEffectItem->signalsConnected, 0);
view->show();
QVERIFY(QTest::qWaitForWindowExposed(view));
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
QSGRendererInterface *rif = view->rendererInterface();
QSGRendererInterface *rif = view.rendererInterface();
if (rif && rif->graphicsApi() != QSGRendererInterface::Software)
QCOMPARE(shaderEffectItem->signalsConnected, 1);
}
@ -113,76 +115,62 @@ void tst_qquickshadereffect::testConnection()
void tst_qquickshadereffect::deleteSourceItem()
{
// purely to ensure that deleting the sourceItem of a shader doesn't cause a crash
QQuickView *view = new QQuickView(nullptr);
view->setSource(QUrl(QStringLiteral("qrc:/data/deleteSourceItem.qml")));
view->show();
QVERIFY(QTest::qWaitForWindowExposed(view));
QVERIFY(view);
QObject *obj = view->rootObject();
QQuickView view;
QVERIFY(QQuickTest::showView(view, QStringLiteral("qrc:/data/deleteSourceItem.qml")));
QObject *obj = view.rootObject();
QVERIFY(obj);
QMetaObject::invokeMethod(obj, "setDeletedSourceItem");
QTest::qWait(50);
delete view;
const auto shaderEffectSource = obj->findChild<QQuickShaderEffectSource*>();
QVERIFY(shaderEffectSource);
QTRY_VERIFY(!shaderEffectSource->sourceItem());
}
void tst_qquickshadereffect::deleteShaderEffectSource()
{
// purely to ensure that deleting the sourceItem of a shader doesn't cause a crash
QQuickView *view = new QQuickView(nullptr);
view->setSource(QUrl(QStringLiteral("qrc:/data/deleteShaderEffectSource.qml")));
view->show();
QVERIFY(QTest::qWaitForWindowExposed(view));
QVERIFY(view);
QObject *obj = view->rootObject();
// purely to ensure that deleting the ShaderEffectSource doesn't cause a crash
QQuickView view;
QVERIFY(QQuickTest::showView(view, QStringLiteral("qrc:/data/deleteShaderEffectSource.qml")));
QObject *obj = view.rootObject();
QVERIFY(obj);
const QPointer<QQuickShaderEffectSource> shaderEffectSource = obj->findChild<QQuickShaderEffectSource*>();
QVERIFY(shaderEffectSource);
QMetaObject::invokeMethod(obj, "setDeletedShaderEffectSource");
QTest::qWait(50);
delete view;
QTRY_VERIFY(shaderEffectSource);
}
void tst_qquickshadereffect::twoImagesOneShaderEffect()
{
// Don't crash when having a ShaderEffect and an Image sharing the texture via supportsAtlasTextures
QQuickView *view = new QQuickView(nullptr);
view->setSource(QUrl(QStringLiteral("qrc:/data/twoImagesOneShaderEffect.qml")));
view->show();
QVERIFY(QTest::qWaitForWindowExposed(view));
QVERIFY(view);
QObject *obj = view->rootObject();
QQuickView view;
QVERIFY(QQuickTest::showView(view, QStringLiteral("qrc:/data/twoImagesOneShaderEffect.qml")));
QObject *obj = view.rootObject();
QVERIFY(obj);
delete view;
}
void tst_qquickshadereffect::withoutQmlEngine()
{
// using a shader without QML engine used to crash
auto window = new QQuickWindow;
auto shaderEffect = new TestShaderEffect(window->contentItem());
const QQuickWindow window;
auto shaderEffect = new TestShaderEffect(window.contentItem());
shaderEffect->setVertexShader(QUrl());
QVERIFY(shaderEffect->isComponentComplete());
delete window;
}
// QTBUG-86402: hiding the parent of an item that uses an effect should not cause a crash.
void tst_qquickshadereffect::hideParent()
{
QScopedPointer<QQuickView> view(new QQuickView);
view->setSource(QUrl(QStringLiteral("qrc:/data/hideParent.qml")));
QCOMPARE(view->status(), QQuickView::Ready);
view->show();
QVERIFY(QTest::qWaitForWindowExposed(view.data()));
QQuickView view;
view.setSource(QUrl(QStringLiteral("qrc:/data/hideParent.qml")));
QVERIFY(QQuickTest::showView(view, QStringLiteral("qrc:/data/hideParent.qml")));
// Should finish without crashing.
QTRY_VERIFY(view->rootObject()->property("finished").toBool());
QTRY_VERIFY(view.rootObject()->property("finished").toBool());
}
void tst_qquickshadereffect::testPropertyMappings()
{
QScopedPointer<QQuickView> view(new QQuickView);
view->setSource(QUrl(QStringLiteral("qrc:/data/testProperties.qml")));
QCOMPARE(view->status(), QQuickView::Ready);
view->show();
QVERIFY(QTest::qWaitForWindowExposed(view.data()));
QTRY_VERIFY(view->rootObject()->property("finished").toBool());
QQuickView view;
view.setSource(QUrl(QStringLiteral("qrc:/data/testProperties.qml")));
QTRY_VERIFY(view.rootObject()->property("finished").toBool());
}
QTEST_MAIN(tst_qquickshadereffect)