aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/tracing
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2018-05-03 09:50:11 +0200
committerUlf Hermann <ulf.hermann@qt.io>2018-05-04 14:08:47 +0000
commit734611131dc20283b118353130bdd5e16ce0aeaf (patch)
tree91adf7b62f98765a46bc5c544a1808cde1b1bf82 /tests/auto/tracing
parentb9b2f2c1875030b8259d22cba69161304ada7011 (diff)
Move Timeline and FlameGraph into a common "Tracing" library
This allows us to share code between the two, in particular the QML code for the Details window, and the theme code. This way we can potentially deduplicate some code. Change-Id: I3a0d26b18488bd2a46b5b077b5b5d79ac2dfc5ce Reviewed-by: Christian Kandeler <christian.kandeler@qt.io> Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Diffstat (limited to 'tests/auto/tracing')
-rw-r--r--tests/auto/tracing/flamegraph/flamegraph.pro7
-rw-r--r--tests/auto/tracing/flamegraph/flamegraph.qbs12
-rw-r--r--tests/auto/tracing/flamegraph/tst_flamegraph.cpp161
-rw-r--r--tests/auto/tracing/timelineabstractrenderer/timelineabstractrenderer.pro7
-rw-r--r--tests/auto/tracing/timelineabstractrenderer/timelineabstractrenderer.qbs12
-rw-r--r--tests/auto/tracing/timelineabstractrenderer/tst_timelineabstractrenderer.cpp157
-rw-r--r--tests/auto/tracing/timelineitemsrenderpass/timelineitemsrenderpass.pro7
-rw-r--r--tests/auto/tracing/timelineitemsrenderpass/timelineitemsrenderpass.qbs13
-rw-r--r--tests/auto/tracing/timelineitemsrenderpass/tst_timelineitemsrenderpass.cpp157
-rw-r--r--tests/auto/tracing/timelinemodel/timelinemodel.pro5
-rw-r--r--tests/auto/tracing/timelinemodel/timelinemodel.qbs12
-rw-r--r--tests/auto/tracing/timelinemodel/tst_timelinemodel.cpp491
-rw-r--r--tests/auto/tracing/timelinemodelaggregator/timelinemodelaggregator.pro5
-rw-r--r--tests/auto/tracing/timelinemodelaggregator/timelinemodelaggregator.qbs12
-rw-r--r--tests/auto/tracing/timelinemodelaggregator/tst_timelinemodelaggregator.cpp166
-rw-r--r--tests/auto/tracing/timelinenotesmodel/timelinenotesmodel.pro5
-rw-r--r--tests/auto/tracing/timelinenotesmodel/timelinenotesmodel.qbs12
-rw-r--r--tests/auto/tracing/timelinenotesmodel/tst_timelinenotesmodel.cpp198
-rw-r--r--tests/auto/tracing/timelinenotesrenderpass/timelinenotesrenderpass.pro7
-rw-r--r--tests/auto/tracing/timelinenotesrenderpass/timelinenotesrenderpass.qbs13
-rw-r--r--tests/auto/tracing/timelinenotesrenderpass/tst_timelinenotesrenderpass.cpp143
-rw-r--r--tests/auto/tracing/timelineoverviewrenderer/timelineoverviewrenderer.pro7
-rw-r--r--tests/auto/tracing/timelineoverviewrenderer/timelineoverviewrenderer.qbs12
-rw-r--r--tests/auto/tracing/timelineoverviewrenderer/tst_timelineoverviewrenderer.cpp80
-rw-r--r--tests/auto/tracing/timelinerenderer/timelinerenderer.pro7
-rw-r--r--tests/auto/tracing/timelinerenderer/timelinerenderer.qbs12
-rw-r--r--tests/auto/tracing/timelinerenderer/tst_timelinerenderer.cpp180
-rw-r--r--tests/auto/tracing/timelinerenderpass/timelinerenderpass.pro5
-rw-r--r--tests/auto/tracing/timelinerenderpass/timelinerenderpass.qbs13
-rw-r--r--tests/auto/tracing/timelinerenderpass/tst_timelinerenderpass.cpp92
-rw-r--r--tests/auto/tracing/timelinerenderstate/timelinerenderstate.pro7
-rw-r--r--tests/auto/tracing/timelinerenderstate/timelinerenderstate.qbs13
-rw-r--r--tests/auto/tracing/timelinerenderstate/tst_timelinerenderstate.cpp177
-rw-r--r--tests/auto/tracing/timelineselectionrenderpass/timelineselectionrenderpass.pro7
-rw-r--r--tests/auto/tracing/timelineselectionrenderpass/timelineselectionrenderpass.qbs13
-rw-r--r--tests/auto/tracing/timelineselectionrenderpass/tst_timelineselectionrenderpass.cpp182
-rw-r--r--tests/auto/tracing/timelinezoomcontrol/timelinezoomcontrol.pro5
-rw-r--r--tests/auto/tracing/timelinezoomcontrol/timelinezoomcontrol.qbs12
-rw-r--r--tests/auto/tracing/timelinezoomcontrol/tst_timelinezoomcontrol.cpp222
-rw-r--r--tests/auto/tracing/tracing.pro20
-rw-r--r--tests/auto/tracing/tracing.qbs21
-rw-r--r--tests/auto/tracing/tracingautotest.qbs7
42 files changed, 2696 insertions, 0 deletions
diff --git a/tests/auto/tracing/flamegraph/flamegraph.pro b/tests/auto/tracing/flamegraph/flamegraph.pro
new file mode 100644
index 0000000000..b668b987d1
--- /dev/null
+++ b/tests/auto/tracing/flamegraph/flamegraph.pro
@@ -0,0 +1,7 @@
+QT += quick
+
+QTC_LIB_DEPENDS += tracing
+include(../../qttest.pri)
+
+SOURCES += \
+ tst_flamegraph.cpp
diff --git a/tests/auto/tracing/flamegraph/flamegraph.qbs b/tests/auto/tracing/flamegraph/flamegraph.qbs
new file mode 100644
index 0000000000..7323dd7fb7
--- /dev/null
+++ b/tests/auto/tracing/flamegraph/flamegraph.qbs
@@ -0,0 +1,12 @@
+import qbs
+import "../tracingautotest.qbs" as TracingAutotest
+
+TracingAutotest {
+ name: "FlameGraph autotest"
+ Group {
+ name: "Test sources"
+ files: [
+ "tst_flamegraph.cpp"
+ ]
+ }
+}
diff --git a/tests/auto/tracing/flamegraph/tst_flamegraph.cpp b/tests/auto/tracing/flamegraph/tst_flamegraph.cpp
new file mode 100644
index 0000000000..e8335e034c
--- /dev/null
+++ b/tests/auto/tracing/flamegraph/tst_flamegraph.cpp
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include <tracing/flamegraph.h>
+#include <tracing/flamegraphattached.h>
+#include <QObject>
+#include <QStandardItemModel>
+#include <QQmlComponent>
+#include <QQuickItem>
+#include <QtTest>
+#include <QQuickItem>
+
+class DelegateObject : public QQuickItem
+{
+ Q_OBJECT
+};
+
+class DelegateComponent : public QQmlComponent
+{
+ Q_OBJECT
+public:
+ QObject *create(QQmlContext *context) override;
+ QObject *beginCreate(QQmlContext *) override;
+ void completeCreate() override;
+};
+
+class tst_FlameGraph : public QObject
+{
+ Q_OBJECT
+private slots:
+ void initTestCase();
+ void testRebuild();
+ void cleanupTestCase();
+
+private:
+ static const int sizeRole = Qt::UserRole + 1;
+ static const int dataRole = Qt::UserRole + 2;
+ FlameGraph::FlameGraph flameGraph;
+ QStandardItemModel model;
+ DelegateComponent delegate;
+};
+
+void tst_FlameGraph::initTestCase()
+{
+ flameGraph.setDelegate(&delegate);
+ flameGraph.setModel(&model);
+ flameGraph.setSizeRole(sizeRole);
+ flameGraph.setWidth(100);
+ flameGraph.setHeight(100);
+ flameGraph.setSizeThreshold(0.01);
+
+ QCOMPARE(flameGraph.delegate(), &delegate);
+ QCOMPARE(flameGraph.model(), &model);
+ QCOMPARE(flameGraph.sizeRole(), Qt::UserRole + 1);
+ QCOMPARE(flameGraph.sizeThreshold(), 0.01);
+}
+
+void tst_FlameGraph::testRebuild()
+{
+ flameGraph.setModel(nullptr);
+ qreal sum = 0;
+ for (int i = 1; i < 10; ++i) {
+ QStandardItem *item = new QStandardItem;
+ item->setData(i, sizeRole);
+ item->setData(100 / i, dataRole);
+
+ for (int j = 1; j < i; ++j) {
+ QStandardItem *item2 = new QStandardItem;
+ item2->setData(1, sizeRole);
+ for (int k = 0; k < 10; ++k) {
+ QStandardItem *skipped = new QStandardItem;
+ skipped->setData(0.001, sizeRole);
+ item2->appendRow(skipped);
+ }
+ item->appendRow(item2);
+ }
+
+ model.appendRow(item);
+ sum += i;
+ }
+ model.invisibleRootItem()->setData(sum, sizeRole);
+ flameGraph.setModel(nullptr);
+ flameGraph.setModel(&model);
+ QCOMPARE(flameGraph.depth(), 3);
+ qreal i = 0;
+ qreal position = 0;
+ foreach (QQuickItem *child, flameGraph.childItems()) {
+ FlameGraph::FlameGraphAttached *attached =
+ FlameGraph::FlameGraph::qmlAttachedProperties(child);
+ QVERIFY(attached);
+ QCOMPARE(attached->relativeSize(), (++i) / sum);
+ QCOMPARE(attached->relativePosition(), position / sum);
+ QCOMPARE(attached->data(dataRole).toInt(), 100 / static_cast<int>(i));
+ QVERIFY(attached->isDataValid());
+
+ qreal j = 0;
+ foreach (QQuickItem *grandchild, child->childItems()) {
+ FlameGraph::FlameGraphAttached *attached2 =
+ FlameGraph::FlameGraph::qmlAttachedProperties(grandchild);
+ QVERIFY(attached2);
+ QCOMPARE(attached2->relativeSize(), 1.0 / i);
+ QCOMPARE(attached2->relativePosition(), (j++) / i);
+ QCOMPARE(grandchild->childItems().count(), 1);
+ FlameGraph::FlameGraphAttached *skipped =
+ FlameGraph::FlameGraph::qmlAttachedProperties(grandchild->childItems()[0]);
+ QVERIFY(skipped);
+ QCOMPARE(skipped->relativePosition(), 0.0);
+ QCOMPARE(skipped->relativeSize(), 0.001 * 10);
+ }
+
+ position += i;
+ }
+ QCOMPARE(i, 9.0);
+}
+
+void tst_FlameGraph::cleanupTestCase()
+{
+
+}
+
+QObject *DelegateComponent::create(QQmlContext *context)
+{
+ QObject *ret = beginCreate(context);
+ completeCreate();
+ return ret;
+}
+
+QObject *DelegateComponent::beginCreate(QQmlContext *)
+{
+ return new DelegateObject;
+}
+
+void DelegateComponent::completeCreate()
+{
+}
+
+QTEST_MAIN(tst_FlameGraph)
+
+#include "tst_flamegraph.moc"
diff --git a/tests/auto/tracing/timelineabstractrenderer/timelineabstractrenderer.pro b/tests/auto/tracing/timelineabstractrenderer/timelineabstractrenderer.pro
new file mode 100644
index 0000000000..53038ebfdf
--- /dev/null
+++ b/tests/auto/tracing/timelineabstractrenderer/timelineabstractrenderer.pro
@@ -0,0 +1,7 @@
+QT += quick
+
+QTC_LIB_DEPENDS += tracing
+include(../../qttest.pri)
+
+SOURCES += \
+ tst_timelineabstractrenderer.cpp
diff --git a/tests/auto/tracing/timelineabstractrenderer/timelineabstractrenderer.qbs b/tests/auto/tracing/timelineabstractrenderer/timelineabstractrenderer.qbs
new file mode 100644
index 0000000000..99880dd7c9
--- /dev/null
+++ b/tests/auto/tracing/timelineabstractrenderer/timelineabstractrenderer.qbs
@@ -0,0 +1,12 @@
+import qbs
+import "../tracingautotest.qbs" as TracingAutotest
+
+TracingAutotest {
+ name: "TimelineAbstractRenderer autotest"
+ Group {
+ name: "Test sources"
+ files: [
+ "tst_timelineabstractrenderer.cpp"
+ ]
+ }
+}
diff --git a/tests/auto/tracing/timelineabstractrenderer/tst_timelineabstractrenderer.cpp b/tests/auto/tracing/timelineabstractrenderer/tst_timelineabstractrenderer.cpp
new file mode 100644
index 0000000000..e4f8e7b69d
--- /dev/null
+++ b/tests/auto/tracing/timelineabstractrenderer/tst_timelineabstractrenderer.cpp
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include <QtTest>
+#include <tracing/timelinemodelaggregator.h>
+#include <tracing/timelineabstractrenderer_p.h>
+
+using namespace Timeline;
+
+class DummyRenderer : public TimelineAbstractRenderer {
+ friend class tst_TimelineAbstractRenderer;
+public:
+ DummyRenderer() : TimelineAbstractRenderer(*new TimelineAbstractRendererPrivate) {}
+};
+
+class tst_TimelineAbstractRenderer : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void privateCtor();
+ void selectionLocked();
+ void selectedItem();
+ void model();
+ void notes();
+ void zoomer();
+ void dirty();
+};
+
+void tst_TimelineAbstractRenderer::privateCtor()
+{
+ DummyRenderer renderer;
+ QVERIFY(renderer.d_func() != 0);
+}
+
+void tst_TimelineAbstractRenderer::selectionLocked()
+{
+ TimelineAbstractRenderer renderer;
+ QSignalSpy spy(&renderer, SIGNAL(selectionLockedChanged(bool)));
+ QCOMPARE(spy.count(), 0);
+ QVERIFY(renderer.selectionLocked());
+ renderer.setSelectionLocked(false);
+ QCOMPARE(spy.count(), 1);
+ QVERIFY(!renderer.selectionLocked());
+ renderer.setSelectionLocked(true);
+ QCOMPARE(spy.count(), 2);
+ QVERIFY(renderer.selectionLocked());
+}
+
+void tst_TimelineAbstractRenderer::selectedItem()
+{
+ TimelineAbstractRenderer renderer;
+ QSignalSpy spy(&renderer, SIGNAL(selectedItemChanged(int)));
+ QCOMPARE(spy.count(), 0);
+ QCOMPARE(renderer.selectedItem(), -1);
+ renderer.setSelectedItem(12);
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(renderer.selectedItem(), 12);
+}
+
+void tst_TimelineAbstractRenderer::model()
+{
+ TimelineAbstractRenderer renderer;
+ TimelineModelAggregator aggregator;
+ QSignalSpy spy(&renderer, SIGNAL(modelChanged(TimelineModel*)));
+ QVERIFY(!renderer.modelDirty());
+ QCOMPARE(spy.count(), 0);
+ TimelineModel model(&aggregator);
+ QCOMPARE(renderer.model(), static_cast<TimelineModel *>(0));
+ renderer.setModel(&model);
+ QVERIFY(renderer.modelDirty());
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(renderer.model(), &model);
+ renderer.setModel(0);
+ QVERIFY(renderer.modelDirty());
+ QCOMPARE(spy.count(), 2);
+ QCOMPARE(renderer.model(), static_cast<TimelineModel *>(0));
+}
+
+void tst_TimelineAbstractRenderer::notes()
+{
+ TimelineAbstractRenderer renderer;
+ QSignalSpy spy(&renderer, SIGNAL(notesChanged(TimelineNotesModel*)));
+ QVERIFY(!renderer.notesDirty());
+ QCOMPARE(spy.count(), 0);
+ TimelineNotesModel notes;
+ QCOMPARE(renderer.notes(), static_cast<TimelineNotesModel *>(0));
+ renderer.setNotes(&notes);
+ QVERIFY(renderer.notesDirty());
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(renderer.notes(), &notes);
+ renderer.setNotes(0);
+ QVERIFY(renderer.notesDirty());
+ QCOMPARE(spy.count(), 2);
+ QCOMPARE(renderer.notes(), static_cast<TimelineNotesModel *>(0));
+}
+
+void tst_TimelineAbstractRenderer::zoomer()
+{
+ TimelineAbstractRenderer renderer;
+ QSignalSpy spy(&renderer, SIGNAL(zoomerChanged(TimelineZoomControl*)));
+ QCOMPARE(spy.count(), 0);
+ TimelineZoomControl zoomer;
+ QCOMPARE(renderer.zoomer(), static_cast<TimelineZoomControl *>(0));
+ renderer.setZoomer(&zoomer);
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(renderer.zoomer(), &zoomer);
+ renderer.setZoomer(0);
+ QCOMPARE(spy.count(), 2);
+ QCOMPARE(renderer.zoomer(), static_cast<TimelineZoomControl *>(0));
+}
+
+void tst_TimelineAbstractRenderer::dirty()
+{
+ DummyRenderer renderer;
+ QVERIFY(!renderer.modelDirty());
+ QVERIFY(!renderer.notesDirty());
+ QVERIFY(!renderer.rowHeightsDirty());
+
+ renderer.setModelDirty();
+ QVERIFY(renderer.modelDirty());
+ renderer.setNotesDirty();
+ QVERIFY(renderer.notesDirty());
+ renderer.setRowHeightsDirty();
+ QVERIFY(renderer.rowHeightsDirty());
+
+ renderer.updatePaintNode(0, 0);
+ QVERIFY(!renderer.modelDirty());
+ QVERIFY(!renderer.notesDirty());
+ QVERIFY(!renderer.rowHeightsDirty());
+}
+
+QTEST_MAIN(tst_TimelineAbstractRenderer)
+
+#include "tst_timelineabstractrenderer.moc"
diff --git a/tests/auto/tracing/timelineitemsrenderpass/timelineitemsrenderpass.pro b/tests/auto/tracing/timelineitemsrenderpass/timelineitemsrenderpass.pro
new file mode 100644
index 0000000000..ba37591590
--- /dev/null
+++ b/tests/auto/tracing/timelineitemsrenderpass/timelineitemsrenderpass.pro
@@ -0,0 +1,7 @@
+QT += quick
+
+QTC_LIB_DEPENDS += tracing
+include(../../qttest.pri)
+
+SOURCES += \
+ tst_timelineitemsrenderpass.cpp
diff --git a/tests/auto/tracing/timelineitemsrenderpass/timelineitemsrenderpass.qbs b/tests/auto/tracing/timelineitemsrenderpass/timelineitemsrenderpass.qbs
new file mode 100644
index 0000000000..0ba6f6ca64
--- /dev/null
+++ b/tests/auto/tracing/timelineitemsrenderpass/timelineitemsrenderpass.qbs
@@ -0,0 +1,13 @@
+import qbs
+import QtcFunctions
+import "../tracingautotest.qbs" as TracingAutotest
+
+TracingAutotest {
+ name: "TimelineItemsRenderPass autotest"
+ Group {
+ name: "Test sources"
+ files: [
+ "tst_timelineitemsrenderpass.cpp"
+ ]
+ }
+}
diff --git a/tests/auto/tracing/timelineitemsrenderpass/tst_timelineitemsrenderpass.cpp b/tests/auto/tracing/timelineitemsrenderpass/tst_timelineitemsrenderpass.cpp
new file mode 100644
index 0000000000..7a987332b8
--- /dev/null
+++ b/tests/auto/tracing/timelineitemsrenderpass/tst_timelineitemsrenderpass.cpp
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include <tracing/runscenegraphtest.h>
+#include <tracing/timelineitemsrenderpass.h>
+#include <tracing/timelinemodelaggregator.h>
+#include <tracing/timelinerenderstate.h>
+
+#include <QtTest>
+#include <QSGMaterialShader>
+
+using namespace Timeline;
+
+class DummyModel : public TimelineModel {
+public:
+ DummyModel(TimelineModelAggregator *parent);
+ void loadData();
+ float relativeHeight(int index) const;
+};
+
+class tst_TimelineItemsRenderPass : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void instance();
+ void update();
+};
+
+DummyModel::DummyModel(TimelineModelAggregator *parent) : TimelineModel(parent)
+{
+}
+
+void DummyModel::loadData()
+{
+ for (int i = 0; i < 10; ++i)
+ insert(i, 1, 1);
+
+ insert(5, 0, 10);
+}
+
+float DummyModel::relativeHeight(int index) const
+{
+ return 1.0 / static_cast<float>(index / 3 + 1);
+}
+
+void tst_TimelineItemsRenderPass::instance()
+{
+ const TimelineItemsRenderPass *inst = TimelineItemsRenderPass::instance();
+ const TimelineItemsRenderPass *inst2 = TimelineItemsRenderPass::instance();
+ QCOMPARE(inst, inst2);
+ QVERIFY(inst != 0);
+}
+
+void tst_TimelineItemsRenderPass::update()
+{
+ const TimelineItemsRenderPass *inst = TimelineItemsRenderPass::instance();
+ TimelineAbstractRenderer renderer;
+ TimelineModelAggregator aggregator;
+ TimelineRenderState parentState(0, 8, 1, 1);
+ TimelineRenderPass::State *nullState = 0;
+ QSGNode *nullNode = 0;
+ TimelineRenderPass::State *result = inst->update(&renderer, &parentState, 0, 0, 0, true, 1);
+ QCOMPARE(result, nullState);
+
+ DummyModel model(&aggregator);
+ renderer.setModel(&model);
+ result = inst->update(&renderer, &parentState, 0, 0, 0, true, 1);
+ QCOMPARE(result, nullState);
+
+ model.loadData();
+ result = inst->update(&renderer, &parentState, 0, 0, 0, true, 1);
+ QCOMPARE(result, nullState);
+
+ result = inst->update(&renderer, &parentState, 0, 2, 9, true, 1);
+ QVERIFY(result != nullState);
+ QCOMPARE(result->expandedOverlay(), nullNode);
+ QCOMPARE(result->expandedOverlay(), nullNode);
+ QCOMPARE(result->expandedRows().count(), 1);
+ QCOMPARE(result->collapsedRows().count(), 1);
+ QCOMPARE(result->expandedRows()[0]->childCount(), 1);
+ QCOMPARE(result->collapsedRows()[0]->childCount(), 1);
+ QSGGeometryNode *node = static_cast<QSGGeometryNode *>(result->expandedRows()[0]->firstChild());
+ QSGMaterial *material1 = node->material();
+ QVERIFY(material1 != 0);
+ QCOMPARE(node->geometry()->vertexCount(), 30);
+ node = static_cast<QSGGeometryNode *>(result->collapsedRows()[0]->firstChild());
+ QSGMaterial *material2 = node->material();
+ QCOMPARE(node->geometry()->vertexCount(), 30);
+ QVERIFY(material2 != 0);
+ QCOMPARE(material1->type(), material2->type());
+ QSGMaterialShader *shader1 = material1->createShader();
+ QVERIFY(shader1 != 0);
+ QSGMaterialShader *shader2 = material2->createShader();
+ QVERIFY(shader2 != 0);
+ QCOMPARE(shader1->attributeNames(), shader2->attributeNames());
+
+ delete shader1;
+ delete shader2;
+
+ result = inst->update(&renderer, &parentState, result, 0, 11, true, 1);
+ QVERIFY(result != nullState);
+ QCOMPARE(result->expandedOverlay(), nullNode);
+ QCOMPARE(result->expandedOverlay(), nullNode);
+ QCOMPARE(result->expandedRows().count(), 1);
+ QCOMPARE(result->collapsedRows().count(), 1);
+
+ // 0-sized node starting at 8 may also be added. We don't test for this one.
+ QVERIFY(result->expandedRows()[0]->childCount() > 1);
+ QVERIFY(result->collapsedRows()[0]->childCount() > 1);
+
+ node = static_cast<QSGGeometryNode *>(result->expandedRows()[0]->childAtIndex(1));
+ QCOMPARE(node->geometry()->vertexCount(), 8);
+ node = static_cast<QSGGeometryNode *>(result->collapsedRows()[0]->childAtIndex(1));
+ QCOMPARE(node->geometry()->vertexCount(), 8);
+
+ model.setExpanded(true);
+ result = inst->update(&renderer, &parentState, result, 0, 10, true, 1);
+ QVERIFY(result != nullState);
+ QCOMPARE(result->expandedOverlay(), nullNode);
+ QCOMPARE(result->expandedOverlay(), nullNode);
+ QCOMPARE(result->expandedRows().count(), 1);
+ QCOMPARE(result->collapsedRows().count(), 1);
+
+ parentState.setPassState(0, result);
+ parentState.assembleNodeTree(&model, 1, 1);
+
+ runSceneGraphTest(parentState.collapsedRowRoot());
+ runSceneGraphTest(parentState.expandedRowRoot());
+}
+
+QTEST_MAIN(tst_TimelineItemsRenderPass)
+
+#include "tst_timelineitemsrenderpass.moc"
+
diff --git a/tests/auto/tracing/timelinemodel/timelinemodel.pro b/tests/auto/tracing/timelinemodel/timelinemodel.pro
new file mode 100644
index 0000000000..a14fd3a09f
--- /dev/null
+++ b/tests/auto/tracing/timelinemodel/timelinemodel.pro
@@ -0,0 +1,5 @@
+QTC_LIB_DEPENDS += tracing
+include(../../qttest.pri)
+
+SOURCES += \
+ tst_timelinemodel.cpp
diff --git a/tests/auto/tracing/timelinemodel/timelinemodel.qbs b/tests/auto/tracing/timelinemodel/timelinemodel.qbs
new file mode 100644
index 0000000000..b936a29a14
--- /dev/null
+++ b/tests/auto/tracing/timelinemodel/timelinemodel.qbs
@@ -0,0 +1,12 @@
+import qbs
+import "../tracingautotest.qbs" as TracingAutotest
+
+TracingAutotest {
+ name: "TimelineModel autotest"
+ Group {
+ name: "Test sources"
+ files: [
+ "tst_timelinemodel.cpp"
+ ]
+ }
+}
diff --git a/tests/auto/tracing/timelinemodel/tst_timelinemodel.cpp b/tests/auto/tracing/timelinemodel/tst_timelinemodel.cpp
new file mode 100644
index 0000000000..be527af127
--- /dev/null
+++ b/tests/auto/tracing/timelinemodel/tst_timelinemodel.cpp
@@ -0,0 +1,491 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include <QtTest>
+#include <QColor>
+#include <tracing/timelinemodel_p.h>
+#include <tracing/timelinemodelaggregator.h>
+
+static const int NumItems = 32;
+static const qint64 ItemDuration = 1 << 19;
+static const qint64 ItemSpacing = 1 << 20;
+
+class DummyModel : public Timeline::TimelineModel
+{
+ Q_OBJECT
+ friend class tst_TimelineModel;
+public:
+ DummyModel(Timeline::TimelineModelAggregator *parent);
+ DummyModel(QString displayName, Timeline::TimelineModelAggregator *parent);
+ int expandedRow(int) const { return 2; }
+ int collapsedRow(int) const { return 1; }
+
+protected:
+ void loadData();
+};
+
+class tst_TimelineModel : public QObject
+{
+ Q_OBJECT
+
+public:
+ const int DefaultRowHeight;
+ tst_TimelineModel();
+
+private slots:
+ void isEmpty();
+ void modelId();
+ void rowHeight();
+ void rowOffset();
+ void height();
+ void count();
+ void times();
+ void selectionId();
+ void firstLast();
+ void expand();
+ void hide();
+ void displayName();
+ void defaultValues();
+ void row();
+ void colorByHue();
+ void colorBySelectionId();
+ void colorByFraction();
+ void supportedRenderPasses();
+ void insertStartEnd();
+ void rowCount();
+ void prevNext();
+ void parentingOfEqualStarts();
+
+private:
+ Timeline::TimelineModelAggregator aggregator;
+};
+
+DummyModel::DummyModel(Timeline::TimelineModelAggregator *parent) :
+ Timeline::TimelineModel(parent)
+{
+}
+
+DummyModel::DummyModel(QString displayName, Timeline::TimelineModelAggregator *parent) :
+ TimelineModel(parent)
+{
+ setDisplayName(displayName);
+}
+
+void DummyModel::loadData()
+{
+ // TimelineModel is clever enough to sort the longer events before the short ones with the same
+ // start time to avoid unnecessary complications when assigning parents. So, if you do e.g.
+ // firstIndex(0) you get the first event insered in the third iteration of the loop.
+
+ for (int i = 0; i < NumItems / 4; ++i) {
+ insert((i / 3) * ItemSpacing, ItemDuration * (i + 1) + 2, 4);
+ insert((i / 3) * ItemSpacing + 1, ItemDuration * (i + 1), 5);
+ insert(i * ItemSpacing / 3 + 1, ItemDuration * (i + 1) + 3, 6);
+ insert(i * ItemSpacing / 3 + 2, 1, 7);
+ }
+ computeNesting();
+ setCollapsedRowCount(2);
+ setExpandedRowCount(3);
+}
+
+tst_TimelineModel::tst_TimelineModel() :
+ DefaultRowHeight(Timeline::TimelineModel::defaultRowHeight())
+{
+}
+
+void tst_TimelineModel::isEmpty()
+{
+ DummyModel dummy(&aggregator);
+ QVERIFY(dummy.isEmpty());
+ dummy.loadData();
+ QVERIFY(!dummy.isEmpty());
+ dummy.clear();
+ QVERIFY(dummy.isEmpty());
+}
+
+void tst_TimelineModel::modelId()
+{
+ DummyModel dummy(&aggregator);
+ QCOMPARE(dummy.modelId(), aggregator.generateModelId() - 1);
+}
+
+void tst_TimelineModel::rowHeight()
+{
+ DummyModel dummy(&aggregator);
+ QCOMPARE(dummy.rowHeight(0), DefaultRowHeight);
+ QCOMPARE(dummy.collapsedRowHeight(0), DefaultRowHeight);
+ QCOMPARE(dummy.expandedRowHeight(0), DefaultRowHeight);
+
+ dummy.setExpandedRowHeight(0, 100);
+ QCOMPARE(dummy.rowHeight(0), DefaultRowHeight);
+ QCOMPARE(dummy.collapsedRowHeight(0), DefaultRowHeight);
+ QCOMPARE(dummy.expandedRowHeight(0), 100);
+
+ dummy.setExpanded(true);
+ QCOMPARE(dummy.rowHeight(0), 100);
+
+ // Cannot set smaller than default
+ dummy.setExpandedRowHeight(0, DefaultRowHeight - 1);
+ QCOMPARE(dummy.rowHeight(0), DefaultRowHeight);
+
+ dummy.setExpandedRowHeight(0, 100);
+ QCOMPARE(dummy.rowHeight(0), 100);
+
+ dummy.loadData();
+ dummy.setExpandedRowHeight(1, 50);
+ QCOMPARE(dummy.rowHeight(0), 100);
+ QCOMPARE(dummy.rowHeight(1), 50);
+
+ // Row heights ignored while collapsed ...
+ dummy.setExpanded(false);
+ QCOMPARE(dummy.rowHeight(0), DefaultRowHeight);
+ QCOMPARE(dummy.rowHeight(1), DefaultRowHeight);
+
+ // ... but restored when re-expanding
+ dummy.setExpanded(true);
+ QCOMPARE(dummy.rowHeight(0), 100);
+ QCOMPARE(dummy.rowHeight(1), 50);
+
+ QSignalSpy expandedSpy(&dummy, SIGNAL(expandedRowHeightChanged(int,int)));
+ dummy.clear();
+ QCOMPARE(expandedSpy.count(), 1);
+}
+
+void tst_TimelineModel::rowOffset()
+{
+ DummyModel dummy(&aggregator);
+ QCOMPARE(dummy.rowOffset(0), 0);
+
+ dummy.loadData();
+ dummy.setExpanded(true);
+ QCOMPARE(dummy.rowOffset(0), 0);
+ QCOMPARE(dummy.rowOffset(1), DefaultRowHeight);
+ QCOMPARE(dummy.collapsedRowOffset(1), DefaultRowHeight);
+ QCOMPARE(dummy.expandedRowOffset(1), DefaultRowHeight);
+
+ dummy.setExpandedRowHeight(0, 100);
+ QCOMPARE(dummy.rowOffset(0), 0);
+ QCOMPARE(dummy.rowOffset(1), 100);
+ QCOMPARE(dummy.collapsedRowOffset(1), DefaultRowHeight);
+ QCOMPARE(dummy.expandedRowOffset(1), 100);
+ QCOMPARE(dummy.expandedRowOffset(2), 100 + DefaultRowHeight);
+
+ dummy.setExpandedRowHeight(1, 50);
+ QCOMPARE(dummy.rowOffset(0), 0);
+ QCOMPARE(dummy.rowOffset(1), 100);
+
+ // Row heights ignored while collapsed ...
+ dummy.setExpanded(false);
+ QCOMPARE(dummy.rowOffset(0), 0);
+ QCOMPARE(dummy.rowOffset(1), DefaultRowHeight);
+ QCOMPARE(dummy.collapsedRowOffset(1), DefaultRowHeight);
+ QCOMPARE(dummy.expandedRowOffset(1), 100);
+ QCOMPARE(dummy.expandedRowOffset(2), 150);
+
+ // ... but restored when re-expanding
+ dummy.setExpanded(true);
+ QCOMPARE(dummy.rowOffset(0), 0);
+ QCOMPARE(dummy.rowOffset(1), 100);
+}
+
+void tst_TimelineModel::height()
+{
+ DummyModel dummy(&aggregator);
+ int heightAfterLastSignal = 0;
+ int heightChangedSignals = 0;
+ connect(&dummy, &Timeline::TimelineModel::heightChanged, [&](){
+ QVERIFY(dummy.height() != heightAfterLastSignal);
+ ++heightChangedSignals;
+ heightAfterLastSignal = dummy.height();
+ });
+ QCOMPARE(dummy.height(), 0);
+
+ dummy.loadData();
+ QCOMPARE(heightChangedSignals, 1);
+ QCOMPARE(heightAfterLastSignal, dummy.height());
+ QCOMPARE(dummy.height(), 2 * DefaultRowHeight);
+
+ dummy.setExpanded(true);
+ QCOMPARE(heightChangedSignals, 2);
+ QCOMPARE(heightAfterLastSignal, dummy.height());
+ QCOMPARE(dummy.height(), 3 * DefaultRowHeight);
+
+ dummy.setExpandedRowHeight(1, 80);
+ QCOMPARE(heightChangedSignals, 3);
+ QCOMPARE(heightAfterLastSignal, dummy.height());
+ QCOMPARE(dummy.height(), 2 * DefaultRowHeight + 80);
+
+ dummy.setHidden(true);
+ QCOMPARE(heightChangedSignals, 4);
+ QCOMPARE(heightAfterLastSignal, dummy.height());
+ QCOMPARE(dummy.height(), 0);
+
+ dummy.clear();
+ // When clearing the height can change several times in a row.
+ QVERIFY(heightChangedSignals > 4);
+ QCOMPARE(heightAfterLastSignal, dummy.height());
+
+ dummy.loadData();
+ dummy.setExpanded(true);
+ QCOMPARE(heightAfterLastSignal, dummy.height());
+ QCOMPARE(dummy.rowHeight(1), DefaultRowHeight); // Make sure the row height gets reset.
+}
+
+void tst_TimelineModel::count()
+{
+ DummyModel dummy(&aggregator);
+ QCOMPARE(dummy.count(), 0);
+ dummy.loadData();
+ QCOMPARE(dummy.count(), NumItems);
+ QSignalSpy emptySpy(&dummy, SIGNAL(contentChanged()));
+ dummy.clear();
+ QCOMPARE(emptySpy.count(), 1);
+ QCOMPARE(dummy.count(), 0);
+}
+
+void tst_TimelineModel::times()
+{
+ DummyModel dummy(&aggregator);
+ dummy.loadData();
+ QCOMPARE(dummy.startTime(0), 0);
+ QCOMPARE(dummy.duration(0), ItemDuration * 3 + 2);
+ QCOMPARE(dummy.endTime(0), ItemDuration * 3 + 2);
+
+}
+
+void tst_TimelineModel::selectionId()
+{
+ DummyModel dummy(&aggregator);
+ dummy.loadData();
+ QCOMPARE(dummy.selectionId(0), 4);
+}
+
+void tst_TimelineModel::firstLast()
+{
+ DummyModel dummy(&aggregator);
+ QCOMPARE(dummy.firstIndex(0), -1);
+ QCOMPARE(dummy.firstIndex(ItemSpacing), -1);
+ QCOMPARE(dummy.lastIndex(0), -1);
+ QCOMPARE(dummy.lastIndex(ItemSpacing), -1);
+ dummy.insert(0, 10, 5); // test special case for only one item
+ QCOMPARE(dummy.firstIndex(5), 0);
+ QCOMPARE(dummy.lastIndex(5), 0);
+ dummy.clear();
+ dummy.loadData();
+ QCOMPARE(dummy.firstIndex(0), 0);
+ QCOMPARE(dummy.firstIndex(ItemSpacing + 1), 0);
+ QCOMPARE(dummy.lastIndex(0), -1);
+ QCOMPARE(dummy.lastIndex(ItemSpacing + 1), 14);
+ QCOMPARE(dummy.firstIndex(ItemDuration * 5000), -1);
+ QCOMPARE(dummy.lastIndex(ItemDuration * 5000), NumItems - 1);
+}
+
+void tst_TimelineModel::expand()
+{
+ DummyModel dummy(&aggregator);
+ QSignalSpy spy(&dummy, SIGNAL(expandedChanged()));
+ QVERIFY(!dummy.expanded());
+ dummy.setExpanded(true);
+ QVERIFY(dummy.expanded());
+ QCOMPARE(spy.count(), 1);
+ dummy.setExpanded(true);
+ QVERIFY(dummy.expanded());
+ QCOMPARE(spy.count(), 1);
+ dummy.setExpanded(false);
+ QVERIFY(!dummy.expanded());
+ QCOMPARE(spy.count(), 2);
+ dummy.setExpanded(false);
+ QVERIFY(!dummy.expanded());
+ QCOMPARE(spy.count(), 2);
+}
+
+void tst_TimelineModel::hide()
+{
+ DummyModel dummy(&aggregator);
+ QSignalSpy spy(&dummy, SIGNAL(hiddenChanged()));
+ QVERIFY(!dummy.hidden());
+ dummy.setHidden(true);
+ QVERIFY(dummy.hidden());
+ QCOMPARE(spy.count(), 1);
+ dummy.setHidden(true);
+ QVERIFY(dummy.hidden());
+ QCOMPARE(spy.count(), 1);
+ dummy.setHidden(false);
+ QVERIFY(!dummy.hidden());
+ QCOMPARE(spy.count(), 2);
+ dummy.setHidden(false);
+ QVERIFY(!dummy.hidden());
+ QCOMPARE(spy.count(), 2);
+}
+
+void tst_TimelineModel::displayName()
+{
+ QLatin1String name("testest");
+ DummyModel dummy(name, &aggregator);
+ QSignalSpy spy(&dummy, SIGNAL(displayNameChanged()));
+ QCOMPARE(dummy.displayName(), name);
+ QCOMPARE(spy.count(), 0);
+ dummy.setDisplayName(name);
+ QCOMPARE(dummy.displayName(), name);
+ QCOMPARE(spy.count(), 0);
+ name = QLatin1String("testerei");
+ dummy.setDisplayName(name);
+ QCOMPARE(dummy.displayName(), name);
+ QCOMPARE(spy.count(), 1);
+}
+
+void tst_TimelineModel::defaultValues()
+{
+ Timeline::TimelineModel dummy(&aggregator);
+ QCOMPARE(dummy.location(0), QVariantMap());
+ QCOMPARE(dummy.handlesTypeId(0), false);
+ QCOMPARE(dummy.relativeHeight(0), 1.0);
+ QCOMPARE(dummy.rowMinValue(0), 0);
+ QCOMPARE(dummy.rowMaxValue(0), 0);
+ QCOMPARE(dummy.typeId(0), -1);
+ QCOMPARE(dummy.color(0), QRgb());
+ QCOMPARE(dummy.labels(), QVariantList());
+ QCOMPARE(dummy.details(0), QVariantMap());
+ QCOMPARE(dummy.collapsedRow(0), 0);
+ QCOMPARE(dummy.expandedRow(0), 0);
+}
+
+void tst_TimelineModel::row()
+{
+ DummyModel dummy(&aggregator);
+ dummy.loadData();
+ QCOMPARE(dummy.row(0), 1);
+ dummy.setExpanded(true);
+ QCOMPARE(dummy.row(0), 2);
+}
+
+void tst_TimelineModel::colorByHue()
+{
+ Timeline::TimelineModelAggregator aggregator;
+ DummyModel dummy(&aggregator);
+ QCOMPARE(dummy.colorByHue(10), QColor::fromHsl(10, 150, 166).rgb());
+ QCOMPARE(dummy.colorByHue(500), QColor::fromHsl(140, 150, 166).rgb());
+}
+
+void tst_TimelineModel::colorBySelectionId()
+{
+ DummyModel dummy(&aggregator);
+ dummy.loadData();
+ QCOMPARE(dummy.colorBySelectionId(5), QColor::fromHsl(6 * 25, 150, 166).rgb());
+}
+
+void tst_TimelineModel::colorByFraction()
+{
+ DummyModel dummy(&aggregator);
+ QCOMPARE(dummy.colorByFraction(0.5), QColor::fromHsl(0.5 * 96 + 10, 150, 166).rgb());
+}
+
+void tst_TimelineModel::supportedRenderPasses()
+{
+ DummyModel dummy(&aggregator);
+ QVERIFY(!dummy.supportedRenderPasses().isEmpty());
+}
+
+void tst_TimelineModel::insertStartEnd()
+{
+ DummyModel dummy(&aggregator);
+ int id = dummy.insertStart(10, 0);
+ dummy.insertEnd(id, 10);
+ QCOMPARE(dummy.startTime(id), 10);
+ QCOMPARE(dummy.endTime(id), 20);
+ int id2 = dummy.insertStart(5, 3);
+ dummy.insertEnd(id2, 10);
+ QCOMPARE(dummy.startTime(id2), 5);
+ QCOMPARE(dummy.endTime(id2), 15);
+
+ int id3 = dummy.insertStart(10, 1);
+ QVERIFY(id3 > id);
+ dummy.insertEnd(id3, 20);
+
+ // Make sure that even though the new range is larger than the one pointed to by id, we still
+ // get to search from id when looking up a timestamp which is in both ranges.
+ QCOMPARE(dummy.firstIndex(11), id);
+}
+
+void tst_TimelineModel::rowCount()
+{
+ DummyModel dummy(&aggregator);
+ QSignalSpy expandedSpy(&dummy, SIGNAL(expandedRowCountChanged()));
+ QSignalSpy collapsedSpy(&dummy, SIGNAL(collapsedRowCountChanged()));
+ QCOMPARE(dummy.rowCount(), 1);
+ dummy.setExpanded(true);
+ QCOMPARE(dummy.rowCount(), 1);
+ dummy.loadData();
+ QCOMPARE(expandedSpy.count(), 1);
+ QCOMPARE(collapsedSpy.count(), 1);
+ QCOMPARE(dummy.rowCount(), 3);
+ dummy.setExpanded(false);
+ QCOMPARE(dummy.rowCount(), 2);
+ dummy.clear();
+ QCOMPARE(expandedSpy.count(), 2);
+ QCOMPARE(collapsedSpy.count(), 2);
+ QCOMPARE(dummy.rowCount(), 1);
+}
+
+void tst_TimelineModel::prevNext()
+{
+ DummyModel dummy(&aggregator);
+ QCOMPARE(dummy.nextItemBySelectionId(5, 10, 5), -1);
+ QCOMPARE(dummy.prevItemBySelectionId(5, 10, 5), -1);
+
+ dummy.loadData();
+ QCOMPARE(dummy.nextItemBySelectionId(5, 5000 * ItemSpacing, -1), 3);
+ QCOMPARE(dummy.prevItemBySelectionId(5, 5000 * ItemSpacing, -1), 28);
+
+ QCOMPARE(dummy.nextItemBySelectionId(15, 10, -1), -1);
+ QCOMPARE(dummy.prevItemBySelectionId(15, 10, -1), -1);
+
+ QCOMPARE(dummy.nextItemBySelectionId(5, 10, -1), 15);
+ QCOMPARE(dummy.prevItemBySelectionId(5, 10, -1), 6);
+ QCOMPARE(dummy.nextItemBySelectionId(5, 10, 5), 6);
+ QCOMPARE(dummy.prevItemBySelectionId(5, 10, 5), 4);
+ QCOMPARE(dummy.nextItemByTypeId(-1, 10, 5), 6);
+ QCOMPARE(dummy.prevItemByTypeId(-1, 10, 5), 4);
+}
+
+void tst_TimelineModel::parentingOfEqualStarts()
+{
+ DummyModel dummy(&aggregator);
+ // Trick it so that it cannot reorder the events and has to parent them in the "wrong" way ...
+ QCOMPARE(dummy.insert(1, 10, 998), 0);
+ QCOMPARE(dummy.insertStart(1, 999), 1);
+ dummy.insertEnd(1, 20);
+ dummy.computeNesting();
+
+ // .. which is reflected in the resulting order.
+ QCOMPARE(dummy.selectionId(0), 998);
+ QCOMPARE(dummy.selectionId(1), 999);
+ QCOMPARE(dummy.firstIndex(10), 0);
+ QCOMPARE(dummy.lastIndex(2), 1);
+}
+
+QTEST_MAIN(tst_TimelineModel)
+
+#include "tst_timelinemodel.moc"
diff --git a/tests/auto/tracing/timelinemodelaggregator/timelinemodelaggregator.pro b/tests/auto/tracing/timelinemodelaggregator/timelinemodelaggregator.pro
new file mode 100644
index 0000000000..8eff246b1b
--- /dev/null
+++ b/tests/auto/tracing/timelinemodelaggregator/timelinemodelaggregator.pro
@@ -0,0 +1,5 @@
+QTC_LIB_DEPENDS += tracing
+include(../../qttest.pri)
+
+SOURCES += \
+ tst_timelinemodelaggregator.cpp
diff --git a/tests/auto/tracing/timelinemodelaggregator/timelinemodelaggregator.qbs b/tests/auto/tracing/timelinemodelaggregator/timelinemodelaggregator.qbs
new file mode 100644
index 0000000000..2329ae3ed1
--- /dev/null
+++ b/tests/auto/tracing/timelinemodelaggregator/timelinemodelaggregator.qbs
@@ -0,0 +1,12 @@
+import qbs
+import "../tracingautotest.qbs" as TracingAutotest
+
+TracingAutotest {
+ name: "TimelineModelAggregator autotest"
+ Group {
+ name: "Test sources"
+ files: [
+ "tst_timelinemodelaggregator.cpp"
+ ]
+ }
+}
diff --git a/tests/auto/tracing/timelinemodelaggregator/tst_timelinemodelaggregator.cpp b/tests/auto/tracing/timelinemodelaggregator/tst_timelinemodelaggregator.cpp
new file mode 100644
index 0000000000..fedd3dfafa
--- /dev/null
+++ b/tests/auto/tracing/timelinemodelaggregator/tst_timelinemodelaggregator.cpp
@@ -0,0 +1,166 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include <QtTest>
+#include <tracing/timelinemodelaggregator.h>
+
+class tst_TimelineModelAggregator : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void height();
+ void addRemoveModel();
+ void prevNext();
+};
+
+class HeightTestModel : public Timeline::TimelineModel {
+public:
+ HeightTestModel(Timeline::TimelineModelAggregator *parent) : TimelineModel(parent)
+ {
+ insert(0, 1, 1);
+ }
+};
+
+void tst_TimelineModelAggregator::height()
+{
+ Timeline::TimelineModelAggregator aggregator;
+ QCOMPARE(aggregator.height(), 0);
+
+ QSignalSpy heightSpy(&aggregator, SIGNAL(heightChanged()));
+ Timeline::TimelineModel *model = new Timeline::TimelineModel(&aggregator);
+ aggregator.addModel(model);
+ QCOMPARE(aggregator.height(), 0);
+ QCOMPARE(heightSpy.count(), 0);
+ aggregator.addModel(new HeightTestModel(&aggregator));
+ QVERIFY(aggregator.height() > 0);
+ QCOMPARE(heightSpy.count(), 1);
+ aggregator.clear();
+ QCOMPARE(aggregator.height(), 0);
+ QCOMPARE(heightSpy.count(), 2);
+}
+
+void tst_TimelineModelAggregator::addRemoveModel()
+{
+ Timeline::TimelineNotesModel notes;
+ Timeline::TimelineModelAggregator aggregator(&notes);
+ QSignalSpy spy(&aggregator, SIGNAL(modelsChanged()));
+
+ QCOMPARE(aggregator.notes(), &notes);
+
+ Timeline::TimelineModel *model1 = new Timeline::TimelineModel(&aggregator);
+ Timeline::TimelineModel *model2 = new Timeline::TimelineModel(&aggregator);
+ aggregator.addModel(model1);
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(aggregator.modelCount(), 1);
+ QCOMPARE(aggregator.model(0), model1);
+ QCOMPARE(aggregator.models().count(), 1);
+
+ aggregator.addModel(model2);
+ QCOMPARE(spy.count(), 2);
+ QCOMPARE(aggregator.modelCount(), 2);
+ QCOMPARE(aggregator.model(1), model2);
+ QCOMPARE(aggregator.models().count(), 2);
+
+ QCOMPARE(aggregator.modelIndexById(model1->modelId()), 0);
+ QCOMPARE(aggregator.modelIndexById(model2->modelId()), 1);
+ QCOMPARE(aggregator.modelIndexById(aggregator.generateModelId()), -1);
+
+ QCOMPARE(aggregator.modelOffset(0), 0);
+ QCOMPARE(aggregator.modelOffset(1), 0);
+
+ aggregator.clear();
+ QCOMPARE(spy.count(), 3);
+ QCOMPARE(aggregator.modelCount(), 0);
+}
+
+class PrevNextTestModel : public Timeline::TimelineModel
+{
+public:
+ PrevNextTestModel(Timeline::TimelineModelAggregator *parent) : TimelineModel(parent)
+ {
+ for (int i = 0; i < 20; ++i)
+ insert(i + modelId(), i * modelId(), modelId());
+ }
+};
+
+void tst_TimelineModelAggregator::prevNext()
+{
+ Timeline::TimelineModelAggregator aggregator;
+ aggregator.generateModelId(); // start modelIds at 1
+ aggregator.addModel(new PrevNextTestModel(&aggregator));
+ aggregator.addModel(new PrevNextTestModel(&aggregator));
+ aggregator.addModel(new PrevNextTestModel(&aggregator));
+
+ // Add an empty model to trigger the special code paths that skip it
+ aggregator.addModel(new Timeline::TimelineModel(&aggregator));
+ QLatin1String item("item");
+ QLatin1String model("model");
+ QVariantMap result;
+
+ {
+ int indexes[] = {-1, -1, -1};
+ int lastModel = -1;
+ int lastIndex = -1;
+ for (int i = 0; i < 60; ++i) {
+ result = aggregator.nextItem(lastModel, lastIndex, -1);
+ int nextModel = result.value(model).toInt();
+ int nextIndex = result.value(item).toInt();
+ QVERIFY(nextModel < 3);
+ QVERIFY(nextModel >= 0);
+ QCOMPARE(nextIndex, ++indexes[nextModel]);
+ lastModel = nextModel;
+ lastIndex = nextIndex;
+ }
+
+ result = aggregator.nextItem(lastModel, lastIndex, -1);
+ QCOMPARE(result.value(model).toInt(), 0);
+ QCOMPARE(result.value(item).toInt(), 0);
+ }
+
+ {
+ int indexes[] = {20, 20, 20};
+ int lastModel = -1;
+ int lastIndex = -1;
+ for (int i = 0; i < 60; ++i) {
+ result = aggregator.prevItem(lastModel, lastIndex, -1);
+ int prevModel = result.value(model).toInt();
+ int prevIndex = result.value(item).toInt();
+ QVERIFY(prevModel < 3);
+ QVERIFY(prevModel >= 0);
+ QCOMPARE(prevIndex, --indexes[prevModel]);
+ lastModel = prevModel;
+ lastIndex = prevIndex;
+ }
+
+ result = aggregator.prevItem(lastModel, lastIndex, -1);
+ QCOMPARE(result.value(model).toInt(), 2);
+ QCOMPARE(result.value(item).toInt(), 19);
+ }
+}
+
+QTEST_MAIN(tst_TimelineModelAggregator)
+
+#include "tst_timelinemodelaggregator.moc"
diff --git a/tests/auto/tracing/timelinenotesmodel/timelinenotesmodel.pro b/tests/auto/tracing/timelinenotesmodel/timelinenotesmodel.pro
new file mode 100644
index 0000000000..bc7a68e570
--- /dev/null
+++ b/tests/auto/tracing/timelinenotesmodel/timelinenotesmodel.pro
@@ -0,0 +1,5 @@
+QTC_LIB_DEPENDS += tracing
+include(../../qttest.pri)
+
+SOURCES += \
+ tst_timelinenotesmodel.cpp
diff --git a/tests/auto/tracing/timelinenotesmodel/timelinenotesmodel.qbs b/tests/auto/tracing/timelinenotesmodel/timelinenotesmodel.qbs
new file mode 100644
index 0000000000..adcacb7d99
--- /dev/null
+++ b/tests/auto/tracing/timelinenotesmodel/timelinenotesmodel.qbs
@@ -0,0 +1,12 @@
+import qbs
+import "../tracingautotest.qbs" as TracingAutotest
+
+TracingAutotest {
+ name: "TimelineNotesModel autotest"
+ Group {
+ name: "Test sources"
+ files: [
+ "tst_timelinenotesmodel.cpp"
+ ]
+ }
+}
diff --git a/tests/auto/tracing/timelinenotesmodel/tst_timelinenotesmodel.cpp b/tests/auto/tracing/timelinenotesmodel/tst_timelinenotesmodel.cpp
new file mode 100644
index 0000000000..dd861cb5a9
--- /dev/null
+++ b/tests/auto/tracing/timelinenotesmodel/tst_timelinenotesmodel.cpp
@@ -0,0 +1,198 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include <QtTest>
+#include <QColor>
+#include <tracing/timelinemodelaggregator.h>
+#include <tracing/timelinenotesmodel.h>
+
+class tst_TimelineNotesModel : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void timelineModel();
+ void addRemove();
+ void properties();
+ void selection();
+ void modify();
+
+private:
+ Timeline::TimelineModelAggregator aggregator;
+};
+
+class TestModel : public Timeline::TimelineModel {
+public:
+ TestModel(Timeline::TimelineModelAggregator *parent) : TimelineModel(parent)
+ {
+ insert(0, 10, 10);
+ }
+
+ int typeId(int) const
+ {
+ return 7;
+ }
+};
+
+class TestNotesModel : public Timeline::TimelineNotesModel {
+ friend class tst_TimelineNotesModel;
+};
+
+void tst_TimelineNotesModel::timelineModel()
+{
+ TestNotesModel notes;
+ TestModel *model = new TestModel(&aggregator);
+ TestModel *model2 = new TestModel(&aggregator);
+ notes.addTimelineModel(model);
+ notes.addTimelineModel(model2);
+ QCOMPARE(notes.timelineModelByModelId(model->modelId()), model);
+ QCOMPARE(notes.timelineModels().count(), 2);
+ QVERIFY(notes.timelineModels().contains(model));
+ QVERIFY(notes.timelineModels().contains(model2));
+ QVERIFY(!notes.isModified());
+ notes.clear(); // clear() only clears the data, not the models
+ QCOMPARE(notes.timelineModels().count(), 2);
+ delete model; // notes model does monitor the destroyed() signal
+ QCOMPARE(notes.timelineModels().count(), 1);
+ delete model2;
+}
+
+void tst_TimelineNotesModel::addRemove()
+{
+ TestNotesModel notes;
+ TestModel model(&aggregator);
+ notes.addTimelineModel(&model);
+
+ QSignalSpy spy(&notes, SIGNAL(changed(int,int,int)));
+ int id = notes.add(model.modelId(), 0, QLatin1String("xyz"));
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(notes.isModified(), true);
+ QCOMPARE(notes.count(), 1);
+ notes.resetModified();
+ QCOMPARE(notes.isModified(), false);
+ notes.remove(id);
+ QCOMPARE(spy.count(), 2);
+ QCOMPARE(notes.isModified(), true);
+ QCOMPARE(notes.count(), 0);
+}
+
+void tst_TimelineNotesModel::properties()
+{
+
+ TestNotesModel notes;
+ int id = -1;
+ int modelId = -1;
+ {
+ TestModel model(&aggregator);
+ modelId = model.modelId();
+ notes.addTimelineModel(&model);
+
+ id = notes.add(model.modelId(), 0, QLatin1String("xyz"));
+ QVERIFY(id >= 0);
+ QCOMPARE(notes.typeId(id), 7);
+ QCOMPARE(notes.timelineIndex(id), 0);
+ QCOMPARE(notes.timelineModel(id), modelId);
+ QCOMPARE(notes.text(id), QLatin1String("xyz"));
+ }
+
+ QCOMPARE(notes.typeId(id), -1); // cannot ask the model anymore
+ QCOMPARE(notes.timelineIndex(id), 0);
+ QCOMPARE(notes.timelineModel(id), modelId);
+ QCOMPARE(notes.text(id), QLatin1String("xyz"));
+}
+
+void tst_TimelineNotesModel::selection()
+{
+ TestNotesModel notes;
+ TestModel model(&aggregator);
+ notes.addTimelineModel(&model);
+ int id1 = notes.add(model.modelId(), 0, QLatin1String("blablub"));
+ int id2 = notes.add(model.modelId(), 0, QLatin1String("xyz"));
+ QVariantList ids = notes.byTimelineModel(model.modelId());
+ QCOMPARE(ids.length(), 2);
+ QVERIFY(ids.contains(id1));
+ QVERIFY(ids.contains(id2));
+
+ ids = notes.byTypeId(7);
+ QCOMPARE(ids.length(), 2);
+ QVERIFY(ids.contains(id1));
+ QVERIFY(ids.contains(id2));
+
+ int got = notes.get(model.modelId(), 0);
+ QVERIFY(got == id1 || got == id2);
+ QCOMPARE(notes.get(model.modelId(), 20), -1);
+ QCOMPARE(notes.get(model.modelId() + 10, 10), -1);
+}
+
+void tst_TimelineNotesModel::modify()
+{
+ TestNotesModel notes;
+ TestModel model(&aggregator);
+ notes.addTimelineModel(&model);
+ QSignalSpy spy(&notes, SIGNAL(changed(int,int,int)));
+ int id = notes.add(model.modelId(), 0, QLatin1String("a"));
+ QCOMPARE(spy.count(), 1);
+ notes.resetModified();
+ notes.update(id, QLatin1String("b"));
+ QVERIFY(notes.isModified());
+ QCOMPARE(spy.count(), 2);
+ QCOMPARE(notes.text(id), QLatin1String("b"));
+ notes.resetModified();
+ notes.update(id, QLatin1String("b"));
+ QVERIFY(!notes.isModified());
+ QCOMPARE(spy.count(), 2);
+ QCOMPARE(notes.text(id), QLatin1String("b"));
+
+ notes.setText(id, QLatin1String("a"));
+ QVERIFY(notes.isModified());
+ QCOMPARE(spy.count(), 3);
+ QCOMPARE(notes.text(id), QLatin1String("a"));
+ notes.resetModified();
+
+ notes.setText(model.modelId(), 0, QLatin1String("x"));
+ QVERIFY(notes.isModified());
+ QCOMPARE(spy.count(), 4);
+ QCOMPARE(notes.text(id), QLatin1String("x"));
+ notes.resetModified();
+
+ TestModel model2(&aggregator);
+ notes.addTimelineModel(&model2);
+ notes.setText(model2.modelId(), 0, QLatin1String("hh"));
+ QVERIFY(notes.isModified());
+ QCOMPARE(spy.count(), 5);
+ QCOMPARE(notes.count(), 2);
+ notes.resetModified();
+
+ notes.setText(id, QString());
+ QVERIFY(notes.isModified());
+ QCOMPARE(spy.count(), 6);
+ QCOMPARE(notes.count(), 1);
+ notes.resetModified();
+
+}
+
+QTEST_MAIN(tst_TimelineNotesModel)
+
+#include "tst_timelinenotesmodel.moc"
diff --git a/tests/auto/tracing/timelinenotesrenderpass/timelinenotesrenderpass.pro b/tests/auto/tracing/timelinenotesrenderpass/timelinenotesrenderpass.pro
new file mode 100644
index 0000000000..33c09eb66c
--- /dev/null
+++ b/tests/auto/tracing/timelinenotesrenderpass/timelinenotesrenderpass.pro
@@ -0,0 +1,7 @@
+QT += quick
+
+QTC_LIB_DEPENDS += tracing
+include(../../qttest.pri)
+
+SOURCES += \
+ tst_timelinenotesrenderpass.cpp
diff --git a/tests/auto/tracing/timelinenotesrenderpass/timelinenotesrenderpass.qbs b/tests/auto/tracing/timelinenotesrenderpass/timelinenotesrenderpass.qbs
new file mode 100644
index 0000000000..3b0efa5b53
--- /dev/null
+++ b/tests/auto/tracing/timelinenotesrenderpass/timelinenotesrenderpass.qbs
@@ -0,0 +1,13 @@
+import qbs
+import QtcFunctions
+import "../tracingautotest.qbs" as TracingAutotest
+
+TracingAutotest {
+ name: "TimelineNotesRenderPass autotest"
+ Group {
+ name: "Test sources"
+ files: [
+ "tst_timelinenotesrenderpass.cpp"
+ ]
+ }
+}
diff --git a/tests/auto/tracing/timelinenotesrenderpass/tst_timelinenotesrenderpass.cpp b/tests/auto/tracing/timelinenotesrenderpass/tst_timelinenotesrenderpass.cpp
new file mode 100644
index 0000000000..f7891b37d7
--- /dev/null
+++ b/tests/auto/tracing/timelinenotesrenderpass/tst_timelinenotesrenderpass.cpp
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include <tracing/runscenegraphtest.h>
+#include <tracing/timelinemodelaggregator.h>
+#include <tracing/timelinenotesrenderpass.h>
+#include <tracing/timelinerenderstate.h>
+#include <tracing/timelineabstractrenderer_p.h>
+
+#include <QtTest>
+#include <QSGMaterialShader>
+
+using namespace Timeline;
+
+class DummyModel : public TimelineModel {
+public:
+ DummyModel(TimelineModelAggregator *parent);
+ void loadData();
+};
+
+class tst_TimelineNotesRenderPass : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void instance();
+ void update();
+};
+
+DummyModel::DummyModel(TimelineModelAggregator *parent) : TimelineModel(parent)
+{
+}
+
+void DummyModel::loadData()
+{
+ for (int i = 0; i < 10; ++i)
+ insert(i, 1, 1);
+}
+
+void tst_TimelineNotesRenderPass::instance()
+{
+ const TimelineNotesRenderPass *inst = TimelineNotesRenderPass::instance();
+ const TimelineNotesRenderPass *inst2 = TimelineNotesRenderPass::instance();
+ QCOMPARE(inst, inst2);
+ QVERIFY(inst != 0);
+}
+
+void tst_TimelineNotesRenderPass::update()
+{
+ const TimelineNotesRenderPass *inst = TimelineNotesRenderPass::instance();
+ TimelineAbstractRenderer renderer;
+ TimelineModelAggregator aggregator;
+ TimelineRenderState parentState(0, 8, 1, 1);
+ TimelineRenderPass::State *nullState = 0;
+ QSGNode *nullNode = 0;
+ TimelineRenderPass::State *result = inst->update(&renderer, &parentState, 0, 0, 0, true, 1);
+ QCOMPARE(result, nullState);
+
+ DummyModel model(&aggregator);
+ DummyModel otherModel(&aggregator);
+
+ TimelineNotesModel notes;
+ notes.addTimelineModel(&model);
+ notes.addTimelineModel(&otherModel);
+ result = inst->update(&renderer, &parentState, 0, 0, 0, true, 1);
+ QCOMPARE(result, nullState);
+
+ renderer.setModel(&model);
+ result = inst->update(&renderer, &parentState, 0, 0, 0, true, 1);
+ QCOMPARE(result, nullState);
+
+ renderer.setNotes(&notes);
+ model.loadData();
+ result = inst->update(&renderer, &parentState, 0, 0, 0, true, 1);
+ QVERIFY(result != nullState);
+
+ // The notes renderer creates a collapsed overlay and expanded nodes per row.
+ QVERIFY(result->collapsedOverlay() != nullNode);
+ QCOMPARE(result->expandedOverlay(), nullNode);
+ QCOMPARE(result->expandedRows().count(), 1);
+ QCOMPARE(result->collapsedRows().count(), 0);
+
+ TimelineRenderPass::State *result2 = inst->update(&renderer, &parentState, result, 0, 0, false,
+ 1);
+ QCOMPARE(result2, result);
+
+ notes.add(model.modelId(), 0, QLatin1String("x"));
+ notes.add(model.modelId(), 9, QLatin1String("xx"));
+ notes.add(otherModel.modelId(), 0, QLatin1String("y"));
+ QVERIFY(renderer.notesDirty());
+ result = inst->update(&renderer, &parentState, result, 0, 0, true, 1);
+ QVERIFY(result != nullState);
+ QSGGeometryNode *node = static_cast<QSGGeometryNode *>(result->expandedRows()[0]);
+ QSGMaterial *material1 = node->material();
+ QVERIFY(material1 != 0);
+ QCOMPARE(node->geometry()->vertexCount(), 2);
+ node = static_cast<QSGGeometryNode *>(result->collapsedOverlay());
+ QSGMaterial *material2 = node->material();
+ QCOMPARE(node->geometry()->vertexCount(), 2);
+ QVERIFY(material2 != 0);
+ QCOMPARE(material1->type(), material2->type());
+ QSGMaterialShader *shader1 = material1->createShader();
+ QVERIFY(shader1 != 0);
+ QSGMaterialShader *shader2 = material2->createShader();
+ QVERIFY(shader2 != 0);
+ QCOMPARE(shader1->attributeNames(), shader2->attributeNames());
+
+ delete shader1;
+ delete shader2;
+
+ parentState.setPassState(0, result);
+ parentState.assembleNodeTree(&model, 1, 1);
+
+ runSceneGraphTest(parentState.collapsedOverlayRoot());
+ runSceneGraphTest(parentState.expandedRowRoot());
+}
+
+QTEST_MAIN(tst_TimelineNotesRenderPass)
+
+#include "tst_timelinenotesrenderpass.moc"
+
diff --git a/tests/auto/tracing/timelineoverviewrenderer/timelineoverviewrenderer.pro b/tests/auto/tracing/timelineoverviewrenderer/timelineoverviewrenderer.pro
new file mode 100644
index 0000000000..5529911590
--- /dev/null
+++ b/tests/auto/tracing/timelineoverviewrenderer/timelineoverviewrenderer.pro
@@ -0,0 +1,7 @@
+QT += quick
+
+QTC_LIB_DEPENDS += tracing
+include(../../qttest.pri)
+
+SOURCES += \
+ tst_timelineoverviewrenderer.cpp
diff --git a/tests/auto/tracing/timelineoverviewrenderer/timelineoverviewrenderer.qbs b/tests/auto/tracing/timelineoverviewrenderer/timelineoverviewrenderer.qbs
new file mode 100644
index 0000000000..2144dba1f9
--- /dev/null
+++ b/tests/auto/tracing/timelineoverviewrenderer/timelineoverviewrenderer.qbs
@@ -0,0 +1,12 @@
+import qbs
+import "../tracingautotest.qbs" as TracingAutotest
+
+TracingAutotest {
+ name: "TimelineOverviewRenderer autotest"
+ Group {
+ name: "Test sources"
+ files: [
+ "tst_timelineoverviewrenderer.cpp"
+ ]
+ }
+}
diff --git a/tests/auto/tracing/timelineoverviewrenderer/tst_timelineoverviewrenderer.cpp b/tests/auto/tracing/timelineoverviewrenderer/tst_timelineoverviewrenderer.cpp
new file mode 100644
index 0000000000..0dfed3eec8
--- /dev/null
+++ b/tests/auto/tracing/timelineoverviewrenderer/tst_timelineoverviewrenderer.cpp
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include <QtTest>
+#include <tracing/timelinemodelaggregator.h>
+#include <tracing/timelineoverviewrenderer_p.h>
+
+using namespace Timeline;
+
+class DummyRenderer : public TimelineOverviewRenderer {
+ friend class tst_TimelineOverviewRenderer;
+};
+
+class DummyModel : public TimelineModel {
+public:
+ DummyModel(TimelineModelAggregator *parent) : TimelineModel(parent) {}
+
+ void loadData()
+ {
+ setCollapsedRowCount(3);
+ setExpandedRowCount(3);
+ for (int i = 0; i < 10; ++i)
+ insert(i, i, i);
+ emit contentChanged();
+ }
+};
+
+class tst_TimelineOverviewRenderer : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void updatePaintNode();
+};
+
+void tst_TimelineOverviewRenderer::updatePaintNode()
+{
+ DummyRenderer renderer;
+ TimelineModelAggregator aggregator;
+ QCOMPARE(renderer.updatePaintNode(0, 0), static_cast<QSGNode *>(0));
+ DummyModel model(&aggregator);
+ renderer.setModel(&model);
+ QCOMPARE(renderer.updatePaintNode(0, 0), static_cast<QSGNode *>(0));
+ model.loadData();
+ QCOMPARE(renderer.updatePaintNode(0, 0), static_cast<QSGNode *>(0));
+ TimelineZoomControl zoomer;
+ renderer.setZoomer(&zoomer);
+ QCOMPARE(renderer.updatePaintNode(0, 0), static_cast<QSGNode *>(0));
+ zoomer.setTrace(0, 10);
+ QSGNode *node = renderer.updatePaintNode(0, 0);
+ QVERIFY(node != 0);
+ QCOMPARE(renderer.updatePaintNode(node, 0), node);
+ delete node;
+}
+
+QTEST_MAIN(tst_TimelineOverviewRenderer)
+
+#include "tst_timelineoverviewrenderer.moc"
diff --git a/tests/auto/tracing/timelinerenderer/timelinerenderer.pro b/tests/auto/tracing/timelinerenderer/timelinerenderer.pro
new file mode 100644
index 0000000000..1c49cfdfbf
--- /dev/null
+++ b/tests/auto/tracing/timelinerenderer/timelinerenderer.pro
@@ -0,0 +1,7 @@
+QT += quick
+
+QTC_LIB_DEPENDS += tracing
+include(../../qttest.pri)
+
+SOURCES += \
+ tst_timelinerenderer.cpp
diff --git a/tests/auto/tracing/timelinerenderer/timelinerenderer.qbs b/tests/auto/tracing/timelinerenderer/timelinerenderer.qbs
new file mode 100644
index 0000000000..45a97acc6d
--- /dev/null
+++ b/tests/auto/tracing/timelinerenderer/timelinerenderer.qbs
@@ -0,0 +1,12 @@
+import qbs
+import "../tracingautotest.qbs" as TracingAutotest
+
+TracingAutotest {
+ name: "TimelineRenderer autotest"
+ Group {
+ name: "Test sources"
+ files: [
+ "tst_timelinerenderer.cpp"
+ ]
+ }
+}
diff --git a/tests/auto/tracing/timelinerenderer/tst_timelinerenderer.cpp b/tests/auto/tracing/timelinerenderer/tst_timelinerenderer.cpp
new file mode 100644
index 0000000000..5378df4467
--- /dev/null
+++ b/tests/auto/tracing/timelinerenderer/tst_timelinerenderer.cpp
@@ -0,0 +1,180 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include <QtTest>
+#include <tracing/timelinemodelaggregator.h>
+#include <tracing/timelinerenderer_p.h>
+
+using namespace Timeline;
+
+class DummyRenderer : public TimelineRenderer {
+ friend class tst_TimelineRenderer;
+};
+
+class DummyModel : public TimelineModel {
+public:
+ DummyModel(TimelineModelAggregator *parent) : TimelineModel(parent) {}
+
+ void loadData()
+ {
+ setCollapsedRowCount(3);
+ setExpandedRowCount(3);
+ for (int i = 0; i < 10; ++i)
+ insert(i, i, i);
+ for (int i = 0; i < 10; ++i)
+ insert(i, 10 - i, i);
+ computeNesting();
+ emit contentChanged();
+ }
+};
+
+class tst_TimelineRenderer : public QObject
+{
+ Q_OBJECT
+
+private:
+ void testMouseEvents(DummyRenderer *renderer, int x, int y);
+ TimelineModelAggregator aggregator;
+
+private slots:
+ void updatePaintNode();
+ void mouseEvents();
+};
+
+void tst_TimelineRenderer::updatePaintNode()
+{
+ DummyRenderer renderer;
+ QCOMPARE(renderer.updatePaintNode(0, 0), static_cast<QSGNode *>(0));
+ DummyModel model(&aggregator);
+ renderer.setModel(&model);
+ QCOMPARE(renderer.updatePaintNode(0, 0), static_cast<QSGNode *>(0));
+ model.loadData();
+ QCOMPARE(renderer.updatePaintNode(0, 0), static_cast<QSGNode *>(0));
+ TimelineZoomControl zoomer;
+ renderer.setZoomer(&zoomer);
+ QCOMPARE(renderer.updatePaintNode(0, 0), static_cast<QSGNode *>(0));
+ zoomer.setTrace(0, 10);
+ QSGNode *node = renderer.updatePaintNode(0, 0);
+ QVERIFY(node != 0);
+ QCOMPARE(renderer.updatePaintNode(node, 0), node);
+ renderer.setModelDirty();
+ QCOMPARE(renderer.updatePaintNode(node, 0), node);
+ renderer.setRowHeightsDirty();
+ QCOMPARE(renderer.updatePaintNode(node, 0), node);
+ delete node;
+}
+
+void tst_TimelineRenderer::testMouseEvents(DummyRenderer *renderer, int x, int y)
+{
+ QMouseEvent event(QMouseEvent::MouseMove, QPointF(x - 1, y), Qt::NoButton,
+ Qt::NoButton, Qt::NoModifier);
+ renderer->mouseMoveEvent(&event);
+
+ QHoverEvent hover(QMouseEvent::HoverMove, QPointF(x, y), QPointF(x - 1, y));
+ renderer->hoverMoveEvent(&hover);
+
+ event = QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(x, y), Qt::LeftButton,
+ Qt::LeftButton, Qt::NoModifier);
+ renderer->mousePressEvent(&event);
+
+ event = QMouseEvent(QMouseEvent::MouseButtonRelease, QPointF(x, y), Qt::LeftButton,
+ Qt::LeftButton, Qt::NoModifier);
+ renderer->mouseReleaseEvent(&event);
+
+
+}
+
+void tst_TimelineRenderer::mouseEvents()
+{
+ DummyRenderer renderer;
+ QCOMPARE(renderer.selectedItem(), -1);
+ QCOMPARE(renderer.selectionLocked(), true);
+ testMouseEvents(&renderer, 1, 1); // make sure it doesn't crash without model and zoomer
+ QCOMPARE(renderer.selectedItem(), -1);
+ QCOMPARE(renderer.selectionLocked(), true);
+ renderer.setWidth(10);
+ renderer.setHeight(90);
+ testMouseEvents(&renderer, 1, 1);
+ QCOMPARE(renderer.selectedItem(), -1);
+ QCOMPARE(renderer.selectionLocked(), true);
+
+ TimelineZoomControl zoomer;
+ renderer.setZoomer(&zoomer);
+ testMouseEvents(&renderer, 1, 1);
+ QCOMPARE(renderer.selectedItem(), -1);
+ QCOMPARE(renderer.selectionLocked(), true);
+
+ DummyModel model(&aggregator);
+ renderer.setModel(&model);
+ testMouseEvents(&renderer, 1, 1);
+ QCOMPARE(renderer.selectedItem(), -1);
+ QCOMPARE(renderer.selectionLocked(), true);
+
+ zoomer.setTrace(0, 10);
+ testMouseEvents(&renderer, 1, 1);
+ QCOMPARE(renderer.selectedItem(), -1);
+ QCOMPARE(renderer.selectionLocked(), true);
+
+ model.loadData();
+ testMouseEvents(&renderer, 1, 1);
+ QCOMPARE(renderer.selectedItem(), 2);
+ QCOMPARE(renderer.selectionLocked(), true);
+
+ model.setExpanded(true);
+ testMouseEvents(&renderer, 1, 1);
+ QCOMPARE(renderer.selectedItem(), 2);
+ QCOMPARE(renderer.selectionLocked(), true); // Don't toggle locked status by clicking same item
+ renderer.setSelectionLocked(false);
+ testMouseEvents(&renderer, 1, 1);
+ QCOMPARE(renderer.selectedItem(), 2);
+ QCOMPARE(renderer.selectionLocked(), false);
+ renderer.setSelectionLocked(true);
+ testMouseEvents(&renderer, 1, 40);
+ QCOMPARE(renderer.selectedItem(), -1);
+ QCOMPARE(renderer.selectionLocked(), true); // Don't unset locked by clicking empty space
+ renderer.setSelectionLocked(false);
+ testMouseEvents(&renderer, 1, 400);
+ QCOMPARE(renderer.selectedItem(), -1);
+ QCOMPARE(renderer.selectionLocked(), false);
+ testMouseEvents(&renderer, 10, 1);
+ QCOMPARE(renderer.selectedItem(), 14);
+ QCOMPARE(renderer.selectionLocked(), false);
+ renderer.setSelectionLocked(true);
+
+ renderer.selectNextFromSelectionId(4);
+ QCOMPARE(renderer.selectedItem(), 8);
+ QCOMPARE(renderer.selectionLocked(), true); // no toggling as we're clicking a different one
+ renderer.selectPrevFromSelectionId(3);
+ QCOMPARE(renderer.selectedItem(), 7);
+ QCOMPARE(renderer.selectionLocked(), true);
+
+ renderer.clearData();
+ QCOMPARE(renderer.selectedItem(), -1);
+ QCOMPARE(renderer.selectionLocked(), true);
+}
+
+QTEST_MAIN(tst_TimelineRenderer)
+
+#include "tst_timelinerenderer.moc"
diff --git a/tests/auto/tracing/timelinerenderpass/timelinerenderpass.pro b/tests/auto/tracing/timelinerenderpass/timelinerenderpass.pro
new file mode 100644
index 0000000000..2bf096ae0b
--- /dev/null
+++ b/tests/auto/tracing/timelinerenderpass/timelinerenderpass.pro
@@ -0,0 +1,5 @@
+QTC_LIB_DEPENDS += tracing
+include(../../qttest.pri)
+
+SOURCES += \
+ tst_timelinerenderpass.cpp
diff --git a/tests/auto/tracing/timelinerenderpass/timelinerenderpass.qbs b/tests/auto/tracing/timelinerenderpass/timelinerenderpass.qbs
new file mode 100644
index 0000000000..b2bc54fec2
--- /dev/null
+++ b/tests/auto/tracing/timelinerenderpass/timelinerenderpass.qbs
@@ -0,0 +1,13 @@
+import qbs
+import QtcFunctions
+import "../tracingautotest.qbs" as TracingAutotest
+
+TracingAutotest {
+ name: "TimelineRenderPass autotest"
+ Group {
+ name: "Test sources"
+ files: [
+ "tst_timelinerenderpass.cpp"
+ ]
+ }
+}
diff --git a/tests/auto/tracing/timelinerenderpass/tst_timelinerenderpass.cpp b/tests/auto/tracing/timelinerenderpass/tst_timelinerenderpass.cpp
new file mode 100644
index 0000000000..cfff804e52
--- /dev/null
+++ b/tests/auto/tracing/timelinerenderpass/tst_timelinerenderpass.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include <tracing/timelinerenderpass.h>
+#include <QtTest>
+
+using namespace Timeline;
+
+class DummyRenderPass : public TimelineRenderPass
+{
+public:
+ static bool s_dtorRan;
+
+ State *update(const TimelineAbstractRenderer *renderer, const TimelineRenderState *parentState,
+ State *state, int indexFrom, int indexTo, bool stateChanged, float spacing) const;
+ ~DummyRenderPass();
+};
+
+bool DummyRenderPass::s_dtorRan = false;
+
+TimelineRenderPass::State *DummyRenderPass::update(const TimelineAbstractRenderer *renderer,
+ const TimelineRenderState *parentState,
+ State *state, int indexFrom, int indexTo,
+ bool stateChanged, float spacing) const
+{
+ Q_UNUSED(renderer);
+ Q_UNUSED(parentState);
+ Q_UNUSED(indexFrom);
+ Q_UNUSED(indexTo);
+ Q_UNUSED(stateChanged);
+ Q_UNUSED(spacing);
+ return state;
+}
+
+DummyRenderPass::~DummyRenderPass()
+{
+ s_dtorRan = true;
+}
+
+class tst_TimelineRenderPass : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void virtualDtor();
+ void emptyState();
+};
+
+void tst_TimelineRenderPass::virtualDtor()
+{
+ QVERIFY(!DummyRenderPass::s_dtorRan);
+ TimelineRenderPass *pass = new DummyRenderPass;
+ QVERIFY(!DummyRenderPass::s_dtorRan);
+ delete pass;
+ QVERIFY(DummyRenderPass::s_dtorRan);
+}
+
+void tst_TimelineRenderPass::emptyState()
+{
+ TimelineRenderPass::State state;
+ QCOMPARE(state.collapsedOverlay(), static_cast<QSGNode *>(0));
+ QCOMPARE(state.expandedOverlay(), static_cast<QSGNode *>(0));
+ QVERIFY(state.collapsedRows().isEmpty());
+ QVERIFY(state.expandedRows().isEmpty());
+}
+
+QTEST_MAIN(tst_TimelineRenderPass)
+
+#include "tst_timelinerenderpass.moc"
+
diff --git a/tests/auto/tracing/timelinerenderstate/timelinerenderstate.pro b/tests/auto/tracing/timelinerenderstate/timelinerenderstate.pro
new file mode 100644
index 0000000000..b6ccbd0727
--- /dev/null
+++ b/tests/auto/tracing/timelinerenderstate/timelinerenderstate.pro
@@ -0,0 +1,7 @@
+QT += quick
+
+QTC_LIB_DEPENDS += tracing
+include(../../qttest.pri)
+
+SOURCES += \
+ tst_timelinerenderstate.cpp
diff --git a/tests/auto/tracing/timelinerenderstate/timelinerenderstate.qbs b/tests/auto/tracing/timelinerenderstate/timelinerenderstate.qbs
new file mode 100644
index 0000000000..b35b97e296
--- /dev/null
+++ b/tests/auto/tracing/timelinerenderstate/timelinerenderstate.qbs
@@ -0,0 +1,13 @@
+import qbs
+import QtcFunctions
+import "../tracingautotest.qbs" as TracingAutotest
+
+TracingAutotest {
+ name: "TimelineRenderState autotest"
+ Group {
+ name: "Test sources"
+ files: [
+ "tst_timelinerenderstate.cpp"
+ ]
+ }
+}
diff --git a/tests/auto/tracing/timelinerenderstate/tst_timelinerenderstate.cpp b/tests/auto/tracing/timelinerenderstate/tst_timelinerenderstate.cpp
new file mode 100644
index 0000000000..08329bb69a
--- /dev/null
+++ b/tests/auto/tracing/timelinerenderstate/tst_timelinerenderstate.cpp
@@ -0,0 +1,177 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include <tracing/timelinemodelaggregator.h>
+#include <tracing/timelinerenderstate.h>
+#include <QtTest>
+#include <QSGSimpleRectNode>
+
+using namespace Timeline;
+
+class DummyPassState : public TimelineRenderPass::State
+{
+private:
+ QVector<QSGNode *> m_collapsedRows;
+ QVector<QSGNode *> m_expandedRows;
+ QSGNode *m_collapsedOverlay;
+ QSGNode *m_expandedOverlay;
+
+public:
+ DummyPassState();
+ ~DummyPassState();
+
+ const QVector<QSGNode *> &expandedRows() const;
+ const QVector<QSGNode *> &collapsedRows() const;
+ QSGNode *expandedOverlay() const;
+ QSGNode *collapsedOverlay() const;
+};
+
+QSGGeometryNode *createNode()
+{
+ QSGGeometryNode *node = new QSGSimpleRectNode;
+ node->setFlag(QSGNode::OwnedByParent, false);
+ return node;
+}
+
+DummyPassState::DummyPassState()
+{
+ m_collapsedRows << createNode() << createNode();
+ m_expandedRows << createNode() << createNode();
+ m_collapsedOverlay = createNode();
+ m_expandedOverlay = createNode();
+}
+
+DummyPassState::~DummyPassState()
+{
+ delete m_collapsedOverlay;
+ delete m_expandedOverlay;
+ qDeleteAll(m_collapsedRows);
+ qDeleteAll(m_expandedRows);
+}
+
+const QVector<QSGNode *> &DummyPassState::expandedRows() const
+{
+ return m_expandedRows;
+}
+
+const QVector<QSGNode *> &DummyPassState::collapsedRows() const
+{
+ return m_collapsedRows;
+}
+
+QSGNode *DummyPassState::expandedOverlay() const
+{
+ return m_expandedOverlay;
+}
+
+QSGNode *DummyPassState::collapsedOverlay() const
+{
+ return m_collapsedOverlay;
+}
+
+class tst_TimelineRenderState : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void startEndScale();
+ void passStates();
+ void emptyRoots();
+ void assembleNodeTree();
+};
+
+void tst_TimelineRenderState::startEndScale()
+{
+ TimelineRenderState state(1, 2, 0.5, 3);
+ QCOMPARE(state.start(), 1);
+ QCOMPARE(state.end(), 2);
+ QCOMPARE(state.scale(), 0.5);
+}
+
+void tst_TimelineRenderState::passStates()
+{
+ TimelineRenderState state(1, 2, 0.5, 3);
+ const TimelineRenderState &constState = state;
+ QCOMPARE(state.passState(0), static_cast<TimelineRenderPass::State *>(0));
+ QCOMPARE(constState.passState(0), static_cast<const TimelineRenderPass::State *>(0));
+ TimelineRenderPass::State *passState = new TimelineRenderPass::State;
+ state.setPassState(0, passState);
+ QCOMPARE(state.passState(0), passState);
+ QCOMPARE(constState.passState(0), passState);
+}
+
+void tst_TimelineRenderState::emptyRoots()
+{
+ TimelineRenderState state(1, 2, 0.5, 3);
+ QCOMPARE(state.expandedRowRoot()->childCount(), 0);
+ QCOMPARE(state.collapsedRowRoot()->childCount(), 0);
+ QCOMPARE(state.expandedOverlayRoot()->childCount(), 0);
+ QCOMPARE(state.collapsedOverlayRoot()->childCount(), 0);
+
+ const TimelineRenderState &constState = state;
+ QCOMPARE(constState.expandedRowRoot()->childCount(), 0);
+ QCOMPARE(constState.collapsedRowRoot()->childCount(), 0);
+ QCOMPARE(constState.expandedOverlayRoot()->childCount(), 0);
+ QCOMPARE(constState.collapsedOverlayRoot()->childCount(), 0);
+
+ QVERIFY(state.isEmpty());
+}
+
+void tst_TimelineRenderState::assembleNodeTree()
+{
+ TimelineModelAggregator aggregator;
+ TimelineModel model(&aggregator);
+ TimelineRenderState state1(1, 2, 0.5, 3);
+ state1.assembleNodeTree(&model, 30, 30);
+ QSGTransformNode *node = state1.finalize(0, true, QMatrix4x4());
+ QVERIFY(node != static_cast<QSGTransformNode *>(0));
+ QVERIFY(node->childCount() == 2);
+
+ TimelineRenderState state2(3, 4, 0.5, 3);
+ state2.setPassState(0, new TimelineRenderPass::State);
+ state2.assembleNodeTree(&model, 30, 30);
+ QCOMPARE(state2.finalize(node, true, QMatrix4x4()), node);
+ QVERIFY(node->childCount() == 2);
+
+ TimelineRenderState state3(4, 5, 0.5, 3);
+ DummyPassState *dummyState = new DummyPassState;
+ state3.setPassState(0, new TimelineRenderPass::State);
+ state3.setPassState(1, dummyState);
+ state3.assembleNodeTree(&model, 30, 30);
+ node = state3.finalize(node, true, QMatrix4x4());
+ QCOMPARE(node->firstChild()->firstChild()->firstChild(), dummyState->expandedRows()[0]);
+ QCOMPARE(node->lastChild()->firstChild(), dummyState->expandedOverlay());
+
+ node = state3.finalize(node, false, QMatrix4x4());
+ QCOMPARE(node->firstChild()->firstChild()->firstChild(), dummyState->collapsedRows()[0]);
+ QCOMPARE(node->lastChild()->firstChild(), dummyState->collapsedOverlay());
+
+ delete node;
+}
+
+QTEST_MAIN(tst_TimelineRenderState)
+
+#include "tst_timelinerenderstate.moc"
+
diff --git a/tests/auto/tracing/timelineselectionrenderpass/timelineselectionrenderpass.pro b/tests/auto/tracing/timelineselectionrenderpass/timelineselectionrenderpass.pro
new file mode 100644
index 0000000000..77f723bc1c
--- /dev/null
+++ b/tests/auto/tracing/timelineselectionrenderpass/timelineselectionrenderpass.pro
@@ -0,0 +1,7 @@
+QT += quick
+
+QTC_LIB_DEPENDS += tracing
+include(../../qttest.pri)
+
+SOURCES += \
+ tst_timelineselectionrenderpass.cpp
diff --git a/tests/auto/tracing/timelineselectionrenderpass/timelineselectionrenderpass.qbs b/tests/auto/tracing/timelineselectionrenderpass/timelineselectionrenderpass.qbs
new file mode 100644
index 0000000000..0cdf08d0c0
--- /dev/null
+++ b/tests/auto/tracing/timelineselectionrenderpass/timelineselectionrenderpass.qbs
@@ -0,0 +1,13 @@
+import qbs
+import QtcFunctions
+import "../tracingautotest.qbs" as TracingAutotest
+
+TracingAutotest {
+ name: "TimelineSelectionRenderPass autotest"
+ Group {
+ name: "Test sources"
+ files: [
+ "tst_timelineselectionrenderpass.cpp"
+ ]
+ }
+}
diff --git a/tests/auto/tracing/timelineselectionrenderpass/tst_timelineselectionrenderpass.cpp b/tests/auto/tracing/timelineselectionrenderpass/tst_timelineselectionrenderpass.cpp
new file mode 100644
index 0000000000..2456ab6674
--- /dev/null
+++ b/tests/auto/tracing/timelineselectionrenderpass/tst_timelineselectionrenderpass.cpp
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include <tracing/runscenegraphtest.h>
+#include <tracing/timelineselectionrenderpass.h>
+#include <tracing/timelinerenderstate.h>
+#include <tracing/timelineabstractrenderer_p.h>
+#include <tracing/timelineitemsrenderpass.h>
+#include <tracing/timelinemodelaggregator.h>
+
+#include <QtTest>
+#include <QSGMaterialShader>
+#include <QSGSimpleRectNode>
+
+using namespace Timeline;
+
+class DummyModel : public TimelineModel {
+public:
+ DummyModel(TimelineModelAggregator *parent);
+ void loadData();
+ float relativeHeight(int index) const;
+};
+
+class tst_TimelineSelectionRenderPass : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void instance();
+ void update();
+};
+
+DummyModel::DummyModel(TimelineModelAggregator *parent) : TimelineModel(parent)
+{
+}
+
+void DummyModel::loadData()
+{
+ for (int i = 0; i < 10; ++i)
+ insert(i, 1, 1);
+ insert(10, 200, 200);
+ insert(11, 200, 200);
+}
+
+float DummyModel::relativeHeight(int index) const
+{
+ if (index == 10)
+ return 0.002f;
+ return 1.0f;
+}
+
+void tst_TimelineSelectionRenderPass::instance()
+{
+ const TimelineSelectionRenderPass *inst = TimelineSelectionRenderPass::instance();
+ const TimelineSelectionRenderPass *inst2 = TimelineSelectionRenderPass::instance();
+ QCOMPARE(inst, inst2);
+ QVERIFY(inst != 0);
+}
+
+void compareSelectionNode(QSGNode *node, const QRectF &rect, int selectionId)
+{
+ QSGGeometryNode *geometryNode = static_cast<QSGGeometryNode *>(node);
+ QSGGeometry *geometry = geometryNode->geometry();
+ QCOMPARE(geometry->vertexCount(), 4);
+ QCOMPARE(geometry->drawingMode(), (GLenum)GL_TRIANGLE_STRIP);
+ OpaqueColoredPoint2DWithSize *data =
+ static_cast<OpaqueColoredPoint2DWithSize *>(geometry->vertexData());
+ float *lowerLeft = reinterpret_cast<float *>(data);
+ float *lowerRight = reinterpret_cast<float *>(++data);
+ float *upperLeft = reinterpret_cast<float *>(++data);
+ float *upperRight = reinterpret_cast<float *>(++data);
+
+ QCOMPARE(QRectF(QPointF(upperLeft[0], upperLeft[1]), QPointF(lowerRight[0], lowerRight[1])),
+ rect);
+ QCOMPARE(lowerRight[0], upperRight[0]);
+ QCOMPARE(lowerRight[1], lowerLeft[1]);
+ QCOMPARE(upperLeft[0], lowerLeft[0]);
+ QCOMPARE(upperLeft[1], upperRight[1]);
+
+ QCOMPARE(int(lowerLeft[4]), selectionId);
+ QCOMPARE(int(lowerRight[4]), selectionId);
+ QCOMPARE(int(upperLeft[4]), selectionId);
+ QCOMPARE(int(upperRight[4]), selectionId);
+
+ TimelineItemsMaterial *material = static_cast<TimelineItemsMaterial *>(
+ geometryNode->material());
+ QVERIFY(!(material->flags() & QSGMaterial::Blending));
+}
+
+void tst_TimelineSelectionRenderPass::update()
+{
+ const TimelineSelectionRenderPass *inst = TimelineSelectionRenderPass::instance();
+ TimelineAbstractRenderer renderer;
+ TimelineModelAggregator aggregator;
+ TimelineRenderState parentState(0, 400, 1, 1);
+ TimelineRenderPass::State *nullState = 0;
+ QSGNode *nullNode = 0;
+ TimelineRenderPass::State *result = inst->update(&renderer, &parentState, 0, 0, 10, true, 1);
+ QCOMPARE(result, nullState);
+
+ DummyModel model(&aggregator);
+
+ result = inst->update(&renderer, &parentState, 0, 0, 10, true, 1);
+ QCOMPARE(result, nullState);
+
+ renderer.setModel(&model);
+ result = inst->update(&renderer, &parentState, 0, 0, 10, true, 1);
+ QCOMPARE(result, nullState);
+
+ model.loadData();
+ result = inst->update(&renderer, &parentState, 0, 0, 10, true, 1);
+ QVERIFY(result != nullState);
+
+ renderer.setSelectedItem(0);
+ result = inst->update(&renderer, &parentState, 0, 0, 10, true, 1);
+ QVERIFY(result != nullState);
+
+ // The selection renderer creates a overlays.
+ QVERIFY(result->collapsedOverlay() != nullNode);
+ QVERIFY(result->expandedOverlay() != nullNode);
+ QCOMPARE(result->expandedRows().count(), 0);
+ QCOMPARE(result->collapsedRows().count(), 0);
+
+ TimelineRenderPass::State *result2 = inst->update(&renderer, &parentState, result, 0, 10, false,
+ 1);
+ QCOMPARE(result2, result);
+
+ renderer.setSelectedItem(1);
+ result = inst->update(&renderer, &parentState, result, 0, 10, false, 1);
+ QVERIFY(result != nullState);
+ compareSelectionNode(result->collapsedOverlay(), QRectF(1, 0, 1, 30), model.selectionId(1));
+
+ model.setExpanded(true);
+ result = inst->update(&renderer, &parentState, result, 0, 10, false, 1);
+ QVERIFY(result != nullState);
+ compareSelectionNode(result->expandedOverlay(), QRectF(1, 0, 1, 30), model.selectionId(1));
+
+ renderer.setSelectedItem(10);
+ result = inst->update(&renderer, &parentState, result, 0, 11, false, 1);
+ QVERIFY(result != nullState);
+ float top = 30 * (1.0 - model.relativeHeight(10));
+ compareSelectionNode(result->expandedOverlay(), QRectF(10, top, 200, 30 - top),
+ model.selectionId(10));
+
+ renderer.setSelectedItem(11);
+ result = inst->update(&renderer, &parentState, result, 0, 12, false, 1);
+ QVERIFY(result != nullState);
+ compareSelectionNode(result->expandedOverlay(), QRectF(11, 0, 200, 30), model.selectionId(11));
+
+ parentState.setPassState(0, result);
+ parentState.assembleNodeTree(&model, 1, 1);
+
+ runSceneGraphTest(parentState.collapsedOverlayRoot());
+ runSceneGraphTest(parentState.expandedOverlayRoot());
+}
+
+QTEST_MAIN(tst_TimelineSelectionRenderPass)
+
+#include "tst_timelineselectionrenderpass.moc"
+
diff --git a/tests/auto/tracing/timelinezoomcontrol/timelinezoomcontrol.pro b/tests/auto/tracing/timelinezoomcontrol/timelinezoomcontrol.pro
new file mode 100644
index 0000000000..8923467c49
--- /dev/null
+++ b/tests/auto/tracing/timelinezoomcontrol/timelinezoomcontrol.pro
@@ -0,0 +1,5 @@
+QTC_LIB_DEPENDS += tracing
+include(../../qttest.pri)
+
+SOURCES += \
+ tst_timelinezoomcontrol.cpp
diff --git a/tests/auto/tracing/timelinezoomcontrol/timelinezoomcontrol.qbs b/tests/auto/tracing/timelinezoomcontrol/timelinezoomcontrol.qbs
new file mode 100644
index 0000000000..5981e1cb9a
--- /dev/null
+++ b/tests/auto/tracing/timelinezoomcontrol/timelinezoomcontrol.qbs
@@ -0,0 +1,12 @@
+import qbs
+import "../tracingautotest.qbs" as TracingAutotest
+
+TracingAutotest {
+ name: "TimelineZoomcontrol autotest"
+ Group {
+ name: "Test sources"
+ files: [
+ "tst_timelinezoomcontrol.cpp"
+ ]
+ }
+}
diff --git a/tests/auto/tracing/timelinezoomcontrol/tst_timelinezoomcontrol.cpp b/tests/auto/tracing/timelinezoomcontrol/tst_timelinezoomcontrol.cpp
new file mode 100644
index 0000000000..e57763cf66
--- /dev/null
+++ b/tests/auto/tracing/timelinezoomcontrol/tst_timelinezoomcontrol.cpp
@@ -0,0 +1,222 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include <QtTest>
+#include <QColor>
+#include <tracing/timelinezoomcontrol.h>
+
+class tst_TimelineZoomControl : public QObject
+{
+ Q_OBJECT
+private:
+ void verifyWindow(const Timeline::TimelineZoomControl &zoomControl);
+
+private slots:
+ void trace();
+ void window();
+ void range();
+ void selection();
+};
+
+void tst_TimelineZoomControl::verifyWindow(const Timeline::TimelineZoomControl &zoomControl)
+{
+ QVERIFY(zoomControl.windowStart() <= zoomControl.rangeStart());
+ QVERIFY(zoomControl.windowEnd() >= zoomControl.rangeEnd());
+ QVERIFY(zoomControl.traceStart() <= zoomControl.windowStart());
+ QVERIFY(zoomControl.traceEnd() >= zoomControl.windowEnd());
+}
+
+void tst_TimelineZoomControl::trace()
+{
+ Timeline::TimelineZoomControl zoomControl;
+ QSignalSpy spy(&zoomControl, SIGNAL(traceChanged(qint64,qint64)));
+ QCOMPARE(zoomControl.traceStart(), -1);
+ QCOMPARE(zoomControl.traceEnd(), -1);
+ QCOMPARE(zoomControl.traceDuration(), 0);
+
+ zoomControl.setTrace(100, 200);
+ QCOMPARE(zoomControl.traceStart(), 100);
+ QCOMPARE(zoomControl.traceEnd(), 200);
+ QCOMPARE(zoomControl.traceDuration(), 100);
+ QCOMPARE(spy.count(), 1);
+
+ zoomControl.clear();
+ QCOMPARE(zoomControl.traceStart(), -1);
+ QCOMPARE(zoomControl.traceEnd(), -1);
+ QCOMPARE(zoomControl.traceDuration(), 0);
+ QCOMPARE(spy.count(), 2);
+}
+
+void tst_TimelineZoomControl::window()
+{
+ Timeline::TimelineZoomControl zoomControl;
+
+ QTimer timer;
+ timer.setSingleShot(true);
+ connect(&timer, &QTimer::timeout, [&](){
+ QVERIFY(zoomControl.windowLocked());
+ zoomControl.setWindowLocked(false);
+ });
+
+ int numWindowChanges = 0;
+
+ connect(&zoomControl, &Timeline::TimelineZoomControl::windowChanged,
+ [&](qint64, qint64) {
+ verifyWindow(zoomControl);
+
+ QVERIFY(!timer.isActive());
+ if (++numWindowChanges == 9) { // delay a bit during a move
+ zoomControl.setWindowLocked(true);
+ timer.start(300);
+ }
+ });
+
+ QCOMPARE(zoomControl.windowStart(), -1);
+ QCOMPARE(zoomControl.windowEnd(), -1);
+ QCOMPARE(zoomControl.windowDuration(), 0);
+
+ zoomControl.setTrace(100, 200);
+ QCOMPARE(zoomControl.windowStart(), 100);
+ QCOMPARE(zoomControl.windowEnd(), 200);
+ QCOMPARE(zoomControl.windowDuration(), 100);
+
+ zoomControl.clear();
+ QCOMPARE(zoomControl.windowStart(), -1);
+ QCOMPARE(zoomControl.windowEnd(), -1);
+ QCOMPARE(zoomControl.windowDuration(), 0);
+
+ zoomControl.setTrace(100000, 200000);
+ QCOMPARE(zoomControl.windowStart(), 100000);
+ QVERIFY(zoomControl.windowEnd() < 110000);
+
+ zoomControl.setRange(199995, 200000); // jump to end
+ verifyWindow(zoomControl);
+ zoomControl.setRange(100000, 100005); // jump to start
+ verifyWindow(zoomControl);
+
+ zoomControl.setRange(150000, 150005);
+ zoomControl.setRange(152000, 152005); // move right
+
+ QMetaObject::Connection connection = connect(
+ &zoomControl, &Timeline::TimelineZoomControl::windowMovingChanged,
+ [&](bool moving) {
+ if (moving)
+ return;
+
+ verifyWindow(zoomControl);
+ if (zoomControl.windowEnd() == zoomControl.traceEnd()) {
+ zoomControl.setRange(104005, 104010); // jump left
+ verifyWindow(zoomControl);
+ zoomControl.setRange(102005, 102010); // make sure it doesn't overrun trace start
+ } else if (zoomControl.windowStart() == zoomControl.traceStart()) {
+ QCoreApplication::exit();
+ } else {
+ QVERIFY(zoomControl.rangeStart() - zoomControl.windowStart() ==
+ zoomControl.windowEnd() - zoomControl.rangeEnd());
+ if (zoomControl.rangeStart() == 152000) {
+ zoomControl.setRange(150000, 150005); // move left
+ } else if (zoomControl.rangeStart() == 150000) {
+ zoomControl.setRange(196990, 196995); // jump right
+ verifyWindow(zoomControl);
+ zoomControl.setRange(198990, 198995); // make sure it doesn't overrun trace end
+ }
+ }
+ verifyWindow(zoomControl);
+ });
+
+ QGuiApplication::exec();
+
+ disconnect(connection);
+
+ bool stopDetected = false;
+ connect(&zoomControl, &Timeline::TimelineZoomControl::windowMovingChanged, [&](bool moving) {
+ if (!moving) {
+ QCOMPARE(stopDetected, false);
+ stopDetected = true;
+ } else {
+ zoomControl.clear();
+ QCOMPARE(zoomControl.windowStart(), -1);
+ QCOMPARE(zoomControl.windowEnd(), -1);
+ QCOMPARE(zoomControl.rangeStart(), -1);
+ QCOMPARE(zoomControl.rangeEnd(), -1);
+ zoomControl.clear(); // no second windowMovingChanged(false), please
+ }
+ });
+
+ zoomControl.setRange(180010, 180015);
+}
+
+void tst_TimelineZoomControl::range()
+{
+ Timeline::TimelineZoomControl zoomControl;
+ QSignalSpy spy(&zoomControl, SIGNAL(rangeChanged(qint64,qint64)));
+ QCOMPARE(zoomControl.rangeStart(), -1);
+ QCOMPARE(zoomControl.rangeEnd(), -1);
+ QCOMPARE(zoomControl.rangeDuration(), 0);
+
+ zoomControl.setTrace(10, 500);
+ QCOMPARE(zoomControl.rangeStart(), 10);
+ QCOMPARE(zoomControl.rangeEnd(), 10);
+ QCOMPARE(zoomControl.rangeDuration(), 0);
+ QCOMPARE(spy.count(), 1);
+
+ zoomControl.setRange(100, 200);
+ QCOMPARE(zoomControl.rangeStart(), 100);
+ QCOMPARE(zoomControl.rangeEnd(), 200);
+ QCOMPARE(zoomControl.rangeDuration(), 100);
+ QCOMPARE(spy.count(), 2);
+
+ zoomControl.clear();
+ QCOMPARE(zoomControl.rangeStart(), -1);
+ QCOMPARE(zoomControl.rangeEnd(), -1);
+ QCOMPARE(zoomControl.rangeDuration(), 0);
+ QCOMPARE(spy.count(), 3);
+}
+
+void tst_TimelineZoomControl::selection()
+{
+ Timeline::TimelineZoomControl zoomControl;
+ QSignalSpy spy(&zoomControl, SIGNAL(selectionChanged(qint64,qint64)));
+ QCOMPARE(zoomControl.selectionStart(), -1);
+ QCOMPARE(zoomControl.selectionEnd(), -1);
+ QCOMPARE(zoomControl.selectionDuration(), 0);
+
+ zoomControl.setTrace(10, 500);
+ zoomControl.setSelection(100, 200);
+ QCOMPARE(zoomControl.selectionStart(), 100);
+ QCOMPARE(zoomControl.selectionEnd(), 200);
+ QCOMPARE(zoomControl.selectionDuration(), 100);
+ QCOMPARE(spy.count(), 1);
+
+ zoomControl.clear();
+ QCOMPARE(zoomControl.selectionStart(), -1);
+ QCOMPARE(zoomControl.selectionEnd(), -1);
+ QCOMPARE(zoomControl.selectionDuration(), 0);
+ QCOMPARE(spy.count(), 2);
+}
+
+QTEST_MAIN(tst_TimelineZoomControl)
+
+#include "tst_timelinezoomcontrol.moc"
diff --git a/tests/auto/tracing/tracing.pro b/tests/auto/tracing/tracing.pro
new file mode 100644
index 0000000000..7772d6ec6b
--- /dev/null
+++ b/tests/auto/tracing/tracing.pro
@@ -0,0 +1,20 @@
+include(../../../qtcreator.pri)
+TEMPLATE = subdirs
+
+SUBDIRS = \
+ flamegraph \
+ timelineabstractrenderer \
+ timelineitemsrenderpass \
+ timelinemodel \
+ timelinemodelaggregator \
+ timelinenotesmodel \
+ timelinenotesrenderpass \
+ timelineoverviewrenderer \
+ timelinerenderer \
+ timelinerenderpass \
+ timelinerenderstate \
+ timelineselectionrenderpass \
+ timelinezoomcontrol
+
+OTHER_FILES += \
+ tracingautotest.qbs
diff --git a/tests/auto/tracing/tracing.qbs b/tests/auto/tracing/tracing.qbs
new file mode 100644
index 0000000000..643d25f31a
--- /dev/null
+++ b/tests/auto/tracing/tracing.qbs
@@ -0,0 +1,21 @@
+import qbs
+
+Project {
+ name: "Tracing autotests"
+
+ references: [
+ "flamegraph/flamegraph.qbs",
+ "timelinemodel/timelinemodel.qbs",
+ "timelinemodelaggregator/timelinemodelaggregator.qbs",
+ "timelinenotesmodel/timelinenotesmodel.qbs",
+ "timelineabstractrenderer/timelineabstractrenderer.qbs",
+ "timelineitemsrenderpass/timelineitemsrenderpass.qbs",
+ "timelinenotesrenderpass/timelinenotesrenderpass.qbs",
+ "timelineoverviewrenderer/timelineoverviewrenderer.qbs",
+ "timelinerenderer/timelinerenderer.qbs",
+ "timelinerenderpass/timelinerenderpass.qbs",
+ "timelinerenderstate/timelinerenderstate.qbs",
+ "timelineselectionrenderpass/timelineselectionrenderpass.qbs",
+ "timelinezoomcontrol/timelinezoomcontrol.qbs"
+ ]
+}
diff --git a/tests/auto/tracing/tracingautotest.qbs b/tests/auto/tracing/tracingautotest.qbs
new file mode 100644
index 0000000000..3a6f47961f
--- /dev/null
+++ b/tests/auto/tracing/tracingautotest.qbs
@@ -0,0 +1,7 @@
+import qbs
+
+QtcAutotest {
+ Depends { name: "Tracing" }
+ Depends { name: "Qt.quick" }
+ Depends { name: "Qt.gui" }
+}