summaryrefslogtreecommitdiffstats
path: root/tests/auto/gui
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/gui')
-rw-r--r--tests/auto/gui/image/qimagereader/tst_qimagereader.cpp38
-rw-r--r--tests/auto/gui/rhi/qrhi/tst_qrhi.cpp95
-rw-r--r--tests/auto/gui/text/qfont/tst_qfont.cpp20
-rw-r--r--tests/auto/gui/util/qshadergenerator/tst_qshadergenerator.cpp193
-rw-r--r--tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp57
5 files changed, 366 insertions, 37 deletions
diff --git a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
index 22d96e76f9..771a4d0a32 100644
--- a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
+++ b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
@@ -45,6 +45,8 @@
#include <algorithm>
+// #define DEBUG_WRITE_OUTPUT
+
typedef QMap<QString, QString> QStringMap;
typedef QList<int> QIntList;
Q_DECLARE_METATYPE(QImage::Format)
@@ -462,24 +464,24 @@ void tst_QImageReader::setScaledClipRect_data()
QTest::addColumn<QRect>("newRect");
QTest::addColumn<QByteArray>("format");
- QTest::newRow("BMP: colorful") << "colorful" << QRect(0, 0, 50, 50) << QByteArray("bmp");
- QTest::newRow("BMP: test32bfv4") << "test32bfv4" << QRect(0, 0, 50, 50) << QByteArray("bmp");
- QTest::newRow("BMP: test32v5") << "test32v5" << QRect(0, 0, 50, 50) << QByteArray("bmp");
- QTest::newRow("BMP: font") << "font" << QRect(0, 0, 50, 50) << QByteArray("bmp");
- QTest::newRow("XPM: marble") << "marble" << QRect(0, 0, 50, 50) << QByteArray("xpm");
- QTest::newRow("PNG: kollada") << "kollada" << QRect(0, 0, 50, 50) << QByteArray("png");
- QTest::newRow("PPM: teapot") << "teapot" << QRect(0, 0, 50, 50) << QByteArray("ppm");
- QTest::newRow("PPM: runners") << "runners.ppm" << QRect(0, 0, 50, 50) << QByteArray("ppm");
- QTest::newRow("PPM: test") << "test.ppm" << QRect(0, 0, 50, 50) << QByteArray("ppm");
- QTest::newRow("XBM: gnus") << "gnus" << QRect(0, 0, 50, 50) << QByteArray("xbm");
+ QTest::newRow("BMP: colorful") << "colorful" << QRect(50, 20, 50, 50) << QByteArray("bmp");
+ QTest::newRow("BMP: test32bfv4") << "test32bfv4" << QRect(50, 20, 50, 50) << QByteArray("bmp");
+ QTest::newRow("BMP: test32v5") << "test32v5" << QRect(50, 20, 50, 50) << QByteArray("bmp");
+ QTest::newRow("BMP: font") << "font" << QRect(50, 20, 50, 50) << QByteArray("bmp");
+ QTest::newRow("XPM: marble") << "marble" << QRect(50, 20, 50, 50) << QByteArray("xpm");
+ QTest::newRow("PNG: kollada") << "kollada" << QRect(50, 20, 50, 50) << QByteArray("png");
+ QTest::newRow("PPM: teapot") << "teapot" << QRect(50, 20, 50, 50) << QByteArray("ppm");
+ QTest::newRow("PPM: runners") << "runners.ppm" << QRect(50, 20, 50, 50) << QByteArray("ppm");
+ QTest::newRow("PPM: test") << "test.ppm" << QRect(50, 20, 50, 50) << QByteArray("ppm");
+ QTest::newRow("XBM: gnus") << "gnus" << QRect(50, 20, 50, 50) << QByteArray("xbm");
- QTest::newRow("JPEG: beavis") << "beavis" << QRect(0, 0, 50, 50) << QByteArray("jpeg");
+ QTest::newRow("JPEG: beavis") << "beavis" << QRect(50, 20, 50, 50) << QByteArray("jpeg");
- QTest::newRow("GIF: earth") << "earth" << QRect(0, 0, 50, 50) << QByteArray("gif");
- QTest::newRow("GIF: trolltech") << "trolltech" << QRect(0, 0, 50, 50) << QByteArray("gif");
+ QTest::newRow("GIF: earth") << "earth" << QRect(50, 20, 50, 50) << QByteArray("gif");
+ QTest::newRow("GIF: trolltech") << "trolltech" << QRect(50, 20, 50, 50) << QByteArray("gif");
- QTest::newRow("SVG: rect") << "rect" << QRect(0, 0, 50, 50) << QByteArray("svg");
- QTest::newRow("SVGZ: rect") << "rect" << QRect(0, 0, 50, 50) << QByteArray("svgz");
+ QTest::newRow("SVG: rect") << "rect" << QRect(50, 20, 50, 50) << QByteArray("svg");
+ QTest::newRow("SVGZ: rect") << "rect" << QRect(50, 20, 50, 50) << QByteArray("svgz");
}
void tst_QImageReader::setScaledClipRect()
@@ -495,7 +497,11 @@ void tst_QImageReader::setScaledClipRect()
reader.setScaledClipRect(newRect);
QImage image = reader.read();
QVERIFY(!image.isNull());
- QCOMPARE(image.rect(), newRect);
+ QCOMPARE(image.rect().translated(50, 20), newRect);
+#ifdef DEBUG_WRITE_OUTPUT
+ QString tempPath = QDir::temp().filePath(fileName) + QLatin1String(".png");
+ image.save(tempPath);
+#endif
QImageReader originalReader(prefix + fileName);
originalReader.setScaledSize(QSize(300, 300));
diff --git a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp
index 191260fd41..549481aa21 100644
--- a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp
+++ b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp
@@ -75,6 +75,8 @@ private slots:
void nativeHandles();
void nativeTexture_data();
void nativeTexture();
+ void nativeBuffer_data();
+ void nativeBuffer();
void resourceUpdateBatchBuffer_data();
void resourceUpdateBatchBuffer();
void resourceUpdateBatchRGBATextureUpload_data();
@@ -294,7 +296,8 @@ void tst_QRhi::create()
QRhi::BaseInstance,
QRhi::TriangleFanTopology,
QRhi::ReadBackNonUniformBuffer,
- QRhi::ReadBackNonBaseMipLevel
+ QRhi::ReadBackNonBaseMipLevel,
+ QRhi::TexelFetch
};
for (size_t i = 0; i <sizeof(features) / sizeof(QRhi::Feature); ++i)
rhi->isFeatureSupported(features[i]);
@@ -545,6 +548,86 @@ void tst_QRhi::nativeTexture()
}
}
+void tst_QRhi::nativeBuffer_data()
+{
+ rhiTestData();
+}
+
+void tst_QRhi::nativeBuffer()
+{
+ QFETCH(QRhi::Implementation, impl);
+ QFETCH(QRhiInitParams *, initParams);
+
+ QScopedPointer<QRhi> rhi(QRhi::create(impl, initParams, QRhi::Flags(), nullptr));
+ if (!rhi)
+ QSKIP("QRhi could not be created, skipping testing native buffer query");
+
+ const QRhiBuffer::Type types[3] = { QRhiBuffer::Immutable, QRhiBuffer::Static, QRhiBuffer::Dynamic };
+ const QRhiBuffer::UsageFlags usages[3] = { QRhiBuffer::VertexBuffer, QRhiBuffer::IndexBuffer, QRhiBuffer::UniformBuffer };
+ for (int typeUsageIdx = 0; typeUsageIdx < 3; ++typeUsageIdx) {
+ QScopedPointer<QRhiBuffer> buf(rhi->newBuffer(types[typeUsageIdx], usages[typeUsageIdx], 256));
+ QVERIFY(buf->build());
+
+ const QRhiBuffer::NativeBuffer nativeBuf = buf->nativeBuffer();
+ QVERIFY(nativeBuf.slotCount <= rhi->resourceLimit(QRhi::FramesInFlight));
+
+ switch (impl) {
+ case QRhi::Null:
+ break;
+ #ifdef TST_VK
+ case QRhi::Vulkan:
+ {
+ QVERIFY(nativeBuf.slotCount >= 1); // always backed by native buffers
+ for (int i = 0; i < nativeBuf.slotCount; ++i) {
+ auto *buffer = static_cast<const VkBuffer *>(nativeBuf.objects[i]);
+ QVERIFY(buffer);
+ QVERIFY(*buffer);
+ }
+ }
+ break;
+ #endif
+ #ifdef TST_GL
+ case QRhi::OpenGLES2:
+ {
+ QVERIFY(nativeBuf.slotCount >= 0); // UniformBuffers are not backed by native buffers, so 0 is perfectly valid
+ for (int i = 0; i < nativeBuf.slotCount; ++i) {
+ auto *bufferId = static_cast<const uint *>(nativeBuf.objects[i]);
+ QVERIFY(bufferId);
+ QVERIFY(*bufferId);
+ }
+ }
+ break;
+ #endif
+ #ifdef TST_D3D11
+ case QRhi::D3D11:
+ {
+ QVERIFY(nativeBuf.slotCount >= 1); // always backed by native buffers
+ for (int i = 0; i < nativeBuf.slotCount; ++i) {
+ auto *buffer = static_cast<void * const *>(nativeBuf.objects[i]);
+ QVERIFY(buffer);
+ QVERIFY(*buffer);
+ }
+ }
+ break;
+ #endif
+ #ifdef TST_MTL
+ case QRhi::Metal:
+ {
+ QVERIFY(nativeBuf.slotCount >= 1); // always backed by native buffers
+ for (int i = 0; i < nativeBuf.slotCount; ++i) {
+ void * const * buffer = (void * const *) nativeBuf.objects[i];
+ QVERIFY(buffer);
+ QVERIFY(*buffer);
+ }
+ }
+ break;
+ #endif
+ default:
+ Q_ASSERT(false);
+ }
+ }
+}
+
static bool submitResourceUpdates(QRhi *rhi, QRhiResourceUpdateBatch *batch)
{
QRhiCommandBuffer *cb = nullptr;
@@ -1671,9 +1754,9 @@ void tst_QRhi::renderToWindowSimple()
QVERIFY(pipeline->build());
- const int framesInFlight = rhi->resourceLimit(QRhi::FramesInFlight);
- QVERIFY(framesInFlight >= 1);
- const int FRAME_COUNT = framesInFlight + 1;
+ const int asyncReadbackFrames = rhi->resourceLimit(QRhi::MaxAsyncReadbackFrames);
+ // one frame issues the readback, then we do MaxAsyncReadbackFrames more to ensure the readback completes
+ const int FRAME_COUNT = asyncReadbackFrames + 1;
bool readCompleted = false;
QRhiReadbackResult readResult;
QImage result;
@@ -1720,8 +1803,8 @@ void tst_QRhi::renderToWindowSimple()
}
// The readback is asynchronous here. However it is guaranteed that it
- // finished at latest after rendering QRhi::FramesInFlight frames after the
- // one that enqueues the readback.
+ // finished at latest after rendering QRhi::MaxAsyncReadbackFrames frames
+ // after the one that enqueues the readback.
QVERIFY(readCompleted);
QVERIFY(readbackWidth > 0);
diff --git a/tests/auto/gui/text/qfont/tst_qfont.cpp b/tests/auto/gui/text/qfont/tst_qfont.cpp
index 9487436336..2d72eef459 100644
--- a/tests/auto/gui/text/qfont/tst_qfont.cpp
+++ b/tests/auto/gui/text/qfont/tst_qfont.cpp
@@ -314,27 +314,33 @@ void tst_QFont::resolve()
void tst_QFont::resetFont()
{
QWidget parent;
+ QWidget firstChild(&parent);
QFont parentFont = parent.font();
parentFont.setPointSize(parentFont.pointSize() + 2);
parent.setFont(parentFont);
- QWidget *child = new QWidget(&parent);
-
- QFont childFont = child->font();
+ QFont childFont = firstChild.font();
childFont.setBold(!childFont.bold());
- child->setFont(childFont);
+ firstChild.setFont(childFont);
+
+ QWidget secondChild(&parent);
+ secondChild.setFont(childFont);
QVERIFY(parentFont.resolve() != 0);
QVERIFY(childFont.resolve() != 0);
QVERIFY(childFont != parentFont);
- child->setFont(QFont()); // reset font
+ // reset font on both children
+ firstChild.setFont(QFont());
+ secondChild.setFont(QFont());
- QCOMPARE(child->font().resolve(), uint(0));
+ QCOMPARE(firstChild.font().resolve(), QFont::SizeResolved);
+ QCOMPARE(secondChild.font().resolve(), QFont::SizeResolved);
#ifdef Q_OS_ANDROID
QEXPECT_FAIL("", "QTBUG-69214", Continue);
#endif
- QCOMPARE(child->font().pointSize(), parent.font().pointSize());
+ QCOMPARE(firstChild.font().pointSize(), parent.font().pointSize());
+ QCOMPARE(secondChild.font().pointSize(), parent.font().pointSize());
QVERIFY(parent.font().resolve() != 0);
}
#endif
diff --git a/tests/auto/gui/util/qshadergenerator/tst_qshadergenerator.cpp b/tests/auto/gui/util/qshadergenerator/tst_qshadergenerator.cpp
index 59e93d127f..56df69dde8 100644
--- a/tests/auto/gui/util/qshadergenerator/tst_qshadergenerator.cpp
+++ b/tests/auto/gui/util/qshadergenerator/tst_qshadergenerator.cpp
@@ -198,6 +198,9 @@ private slots:
void shouldGenerateDifferentCodeDependingOnActiveLayers();
void shouldUseGlobalVariableRatherThanTemporaries();
void shouldGenerateTemporariesWisely();
+ void shouldHandlePortNamesPrefixingOneAnother();
+ void shouldHandleNodesWithMultipleOutputPorts();
+ void shouldHandleExpressionsInInputNodes();
};
void tst_QShaderGenerator::shouldHaveDefaultState()
@@ -1229,6 +1232,196 @@ void tst_QShaderGenerator::shouldGenerateTemporariesWisely()
}
}
+void tst_QShaderGenerator::shouldHandlePortNamesPrefixingOneAnother()
+{
+ // GIVEN
+ const auto gl4 = createFormat(QShaderFormat::OpenGLCoreProfile, 4, 0);
+
+ auto color1 = createNode({
+ createPort(QShaderNodePort::Output, "output")
+ });
+ color1.addRule(gl4, QShaderNode::Rule("vec4 $output = color1;",
+ QByteArrayList() << "in vec4 color1;"));
+
+ auto color2 = createNode({
+ createPort(QShaderNodePort::Output, "output")
+ });
+ color2.addRule(gl4, QShaderNode::Rule("vec4 $output = color2;",
+ QByteArrayList() << "in vec4 color2;"));
+
+ auto addColor = createNode({
+ createPort(QShaderNodePort::Output, "color"),
+ createPort(QShaderNodePort::Input, "color1"),
+ createPort(QShaderNodePort::Input, "color2"),
+ });
+ addColor.addRule(gl4, QShaderNode::Rule("vec4 $color = $color1 + $color2;"));
+
+ auto shaderOutput = createNode({
+ createPort(QShaderNodePort::Input, "input")
+ });
+
+ shaderOutput.addRule(gl4, QShaderNode::Rule("shaderOutput = $input;",
+ QByteArrayList() << "out vec4 shaderOutput;"));
+
+ // WHEN
+ const auto graph = [=] {
+ auto res = QShaderGraph();
+
+ res.addNode(color1);
+ res.addNode(color2);
+ res.addNode(addColor);
+ res.addNode(shaderOutput);
+
+ res.addEdge(createEdge(color1.uuid(), "output", addColor.uuid(), "color1"));
+ res.addEdge(createEdge(color2.uuid(), "output", addColor.uuid(), "color2"));
+ res.addEdge(createEdge(addColor.uuid(), "color", shaderOutput.uuid(), "input"));
+
+ return res;
+ }();
+
+ auto generator = QShaderGenerator();
+ generator.graph = graph;
+ generator.format = gl4;
+
+ const auto code = generator.createShaderCode();
+
+ // THEN
+ const auto expected = QByteArrayList()
+ << "#version 400 core"
+ << ""
+ << "in vec4 color1;"
+ << "in vec4 color2;"
+ << "out vec4 shaderOutput;"
+ << ""
+ << "void main()"
+ << "{"
+ << " shaderOutput = ((color1 + color2));"
+ << "}"
+ << "";
+ QCOMPARE(code, expected.join("\n"));
+}
+
+void tst_QShaderGenerator::shouldHandleNodesWithMultipleOutputPorts()
+{
+ // GIVEN
+ const auto gl4 = createFormat(QShaderFormat::OpenGLCoreProfile, 4, 0);
+
+ auto input = createNode({
+ createPort(QShaderNodePort::Output, "output0"),
+ createPort(QShaderNodePort::Output, "output1")
+ });
+ input.addRule(gl4, QShaderNode::Rule("vec4 $output0 = globalIn0;"
+ "float $output1 = globalIn1;",
+ QByteArrayList() << "in vec4 globalIn0;" << "in float globalIn1;"));
+
+ auto function = createNode({
+ createPort(QShaderNodePort::Input, "input0"),
+ createPort(QShaderNodePort::Input, "input1"),
+ createPort(QShaderNodePort::Output, "output0"),
+ createPort(QShaderNodePort::Output, "output1")
+ });
+ function.addRule(gl4, QShaderNode::Rule("vec4 $output0 = $input0;"
+ "float $output1 = $input1;"));
+
+ auto output = createNode({
+ createPort(QShaderNodePort::Input, "input0"),
+ createPort(QShaderNodePort::Input, "input1")
+ });
+
+ output.addRule(gl4, QShaderNode::Rule("globalOut0 = $input0;"
+ "globalOut1 = $input1;",
+ QByteArrayList() << "out vec4 globalOut0;" << "out float globalOut1;"));
+
+ // WHEN
+ const auto graph = [=] {
+ auto res = QShaderGraph();
+
+ res.addNode(input);
+ res.addNode(function);
+ res.addNode(output);
+
+ res.addEdge(createEdge(input.uuid(), "output0", function.uuid(), "input0"));
+ res.addEdge(createEdge(input.uuid(), "output1", function.uuid(), "input1"));
+
+ res.addEdge(createEdge(function.uuid(), "output0", output.uuid(), "input0"));
+ res.addEdge(createEdge(function.uuid(), "output1", output.uuid(), "input1"));
+
+ return res;
+ }();
+
+ auto generator = QShaderGenerator();
+ generator.graph = graph;
+ generator.format = gl4;
+
+ const auto code = generator.createShaderCode();
+
+ // THEN
+ const auto expected = QByteArrayList()
+ << "#version 400 core"
+ << ""
+ << "in vec4 globalIn0;"
+ << "in float globalIn1;"
+ << "out vec4 globalOut0;"
+ << "out float globalOut1;"
+ << ""
+ << "void main()"
+ << "{"
+ << " globalOut0 = globalIn0;"
+ << " globalOut1 = globalIn1;"
+ << "}"
+ << "";
+ QCOMPARE(code, expected.join("\n"));
+}
+
+void tst_QShaderGenerator::shouldHandleExpressionsInInputNodes()
+{
+ // GIVEN
+ const auto gl4 = createFormat(QShaderFormat::OpenGLCoreProfile, 4, 0);
+
+ auto input = createNode({
+ createPort(QShaderNodePort::Output, "output")
+ });
+ input.addRule(gl4, QShaderNode::Rule("float $output = 3 + 4;"));
+
+ auto output = createNode({
+ createPort(QShaderNodePort::Input, "input")
+ });
+
+ output.addRule(gl4, QShaderNode::Rule("globalOut = $input;",
+ QByteArrayList() << "out float globalOut;"));
+
+ // WHEN
+ const auto graph = [=] {
+ auto res = QShaderGraph();
+
+ res.addNode(input);
+ res.addNode(output);
+
+ res.addEdge(createEdge(input.uuid(), "output", output.uuid(), "input"));
+
+ return res;
+ }();
+
+ auto generator = QShaderGenerator();
+ generator.graph = graph;
+ generator.format = gl4;
+
+ const auto code = generator.createShaderCode();
+
+ // THEN
+ const auto expected = QByteArrayList()
+ << "#version 400 core"
+ << ""
+ << "out float globalOut;"
+ << ""
+ << "void main()"
+ << "{"
+ << " globalOut = 3 + 4;"
+ << "}"
+ << "";
+ QCOMPARE(code, expected.join("\n"));
+}
+
QTEST_MAIN(tst_QShaderGenerator)
#include "tst_qshadergenerator.moc"
diff --git a/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp b/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp
index ce2d38c24f..014a163f58 100644
--- a/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp
+++ b/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp
@@ -114,6 +114,7 @@ private slots:
void shouldSurviveCyclesDuringGraphSerialization();
void shouldDealWithEdgesJumpingOverLayers();
void shouldGenerateDifferentStatementsDependingOnActiveLayers();
+ void shouldDealWithBranchesWithoutOutput();
};
void tst_QShaderGraph::shouldHaveEdgeDefaultState()
@@ -515,12 +516,9 @@ void tst_QShaderGraph::shouldHandleUnboundPortsDuringGraphSerialization()
const auto statements = graph.createStatements();
// THEN
- // Note that no edge leads to the unbound input
+ // Note that no statement has any unbound input
const auto expected = QVector<QShaderGraph::Statement>()
- << createStatement(input, {}, {0})
- << createStatement(function, {-1, 0, -1}, {2, 3, 4})
- << createStatement(unboundOutput, {-1}, {})
- << createStatement(output, {3}, {});
+ << createStatement(input, {}, {0});
dumpStatementsIfNeeded(statements, expected);
QCOMPARE(statements, expected);
}
@@ -567,9 +565,8 @@ void tst_QShaderGraph::shouldSurviveCyclesDuringGraphSerialization()
const auto statements = graph.createStatements();
// THEN
- // Obviously will lead to a compile failure later on since it cuts everything beyond the cycle
- const auto expected = QVector<QShaderGraph::Statement>()
- << createStatement(output, {2}, {});
+ // The cycle is ignored
+ const auto expected = QVector<QShaderGraph::Statement>();
dumpStatementsIfNeeded(statements, expected);
QCOMPARE(statements, expected);
}
@@ -774,6 +771,50 @@ void tst_QShaderGraph::shouldGenerateDifferentStatementsDependingOnActiveLayers(
}
}
+void tst_QShaderGraph::shouldDealWithBranchesWithoutOutput()
+{
+ // GIVEN
+ const auto input = createNode({
+ createPort(QShaderNodePort::Output, "input")
+ });
+ const auto output = createNode({
+ createPort(QShaderNodePort::Input, "output")
+ });
+ const auto danglingFunction = createNode({
+ createPort(QShaderNodePort::Input, "functionInput"),
+ createPort(QShaderNodePort::Output, "unbound")
+ });
+ const auto function = createNode({
+ createPort(QShaderNodePort::Input, "functionInput"),
+ createPort(QShaderNodePort::Output, "functionOutput")
+ });
+
+ const auto graph = [=] {
+ auto res = QShaderGraph();
+ res.addNode(input);
+ res.addNode(function);
+ res.addNode(danglingFunction);
+ res.addNode(output);
+ res.addEdge(createEdge(input.uuid(), "input", function.uuid(), "functionInput"));
+ res.addEdge(createEdge(input.uuid(), "input", danglingFunction.uuid(), "functionInput"));
+ res.addEdge(createEdge(function.uuid(), "functionOutput", output.uuid(), "output"));
+ return res;
+ }();
+
+ // WHEN
+ const auto statements = graph.createStatements();
+
+ // THEN
+ // Note that no edge leads to the unbound input
+ const auto expected = QVector<QShaderGraph::Statement>()
+ << createStatement(input, {}, {0})
+ << createStatement(function, {0}, {1})
+ << createStatement(output, {1}, {})
+ << createStatement(danglingFunction, {0}, {2});
+ dumpStatementsIfNeeded(statements, expected);
+ QCOMPARE(statements, expected);
+}
+
QTEST_MAIN(tst_QShaderGraph)
#include "tst_qshadergraph.moc"