summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorSean Harmer <sean.harmer@kdab.com>2016-08-25 14:57:09 +0100
committerSean Harmer <sean.harmer@kdab.com>2016-08-25 14:57:09 +0100
commitb8372b52809378f860dfb0a9a9a97b30b5ad1a08 (patch)
tree271b70645f97f7fbb97c04c2d8337b781d042bcd /tests
parent7a3db1facaac54053af5c8956ec04fcd8762a311 (diff)
parent150af04197682ccdbab509a95758fcdf957f63b2 (diff)
Merge branch '5.7' into 5.8
Conflicts: tests/auto/input/input.pro Change-Id: Ic89c7d9093c95bc1c5ca50f04ed34c00b5f261f4
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/auto.pro3
-rw-r--r--tests/auto/extras/extras.pro4
-rw-r--r--tests/auto/extras/qcuboidgeometry/qcuboidgeometry.pro (renamed from tests/auto/render/qcuboidgeometry/qcuboidgeometry.pro)3
-rw-r--r--tests/auto/extras/qcuboidgeometry/tst_qcuboidgeometry.cpp (renamed from tests/auto/render/qcuboidgeometry/tst_qcuboidgeometry.cpp)0
-rw-r--r--tests/auto/input/abstractaxisinput/abstractaxisinput.pro1
-rw-r--r--tests/auto/input/actioninput/actioninput.pro11
-rw-r--r--tests/auto/input/actioninput/tst_actioninput.cpp179
-rw-r--r--tests/auto/input/analogaxisinput/analogaxisinput.pro1
-rw-r--r--tests/auto/input/buttonaxisinput/buttonaxisinput.pro1
-rw-r--r--tests/auto/input/commons/commons.pri3
-rw-r--r--tests/auto/input/commons/testdevice.h107
-rw-r--r--tests/auto/input/input.pro5
-rw-r--r--tests/auto/input/inputchord/inputchord.pro11
-rw-r--r--tests/auto/input/inputchord/tst_inputchord.cpp281
-rw-r--r--tests/auto/input/inputsequence/inputsequence.pro11
-rw-r--r--tests/auto/input/inputsequence/tst_inputsequence.cpp400
-rw-r--r--tests/auto/input/keyboardhandler/keyboardhandler.pro1
-rw-r--r--tests/auto/render/qcameralens/qcameralens.pro12
-rw-r--r--tests/auto/render/qcameralens/tst_qcameralens.cpp717
-rw-r--r--tests/auto/render/qcomputecommand/qcomputecommand.pro12
-rw-r--r--tests/auto/render/qcomputecommand/tst_qcomputecommand.cpp282
-rw-r--r--tests/auto/render/qrendertargetoutput/qrendertargetoutput.pro12
-rw-r--r--tests/auto/render/qrendertargetoutput/tst_qrendertargetoutput.cpp407
-rw-r--r--tests/auto/render/qsceneloader/tst_qsceneloader.cpp68
-rw-r--r--tests/auto/render/render.pro6
-rw-r--r--tests/auto/render/sceneloader/tst_sceneloader.cpp22
26 files changed, 2548 insertions, 12 deletions
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index 7d19ad26d..e5745a99e 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -5,6 +5,7 @@ SUBDIRS = \
render \
quick3d \
cmake \
- input
+ input \
+ extras
installed_cmake.depends = cmake
diff --git a/tests/auto/extras/extras.pro b/tests/auto/extras/extras.pro
new file mode 100644
index 000000000..3bba4d37b
--- /dev/null
+++ b/tests/auto/extras/extras.pro
@@ -0,0 +1,4 @@
+TEMPLATE = subdirs
+
+SUBDIRS = \
+ qcuboidgeometry
diff --git a/tests/auto/render/qcuboidgeometry/qcuboidgeometry.pro b/tests/auto/extras/qcuboidgeometry/qcuboidgeometry.pro
index 2599b5fe6..7208f1c7b 100644
--- a/tests/auto/render/qcuboidgeometry/qcuboidgeometry.pro
+++ b/tests/auto/extras/qcuboidgeometry/qcuboidgeometry.pro
@@ -8,6 +8,3 @@ CONFIG += testcase
SOURCES += \
tst_qcuboidgeometry.cpp
-
-include(../../core/common/common.pri)
-include(../commons/commons.pri)
diff --git a/tests/auto/render/qcuboidgeometry/tst_qcuboidgeometry.cpp b/tests/auto/extras/qcuboidgeometry/tst_qcuboidgeometry.cpp
index ddd9eed22..ddd9eed22 100644
--- a/tests/auto/render/qcuboidgeometry/tst_qcuboidgeometry.cpp
+++ b/tests/auto/extras/qcuboidgeometry/tst_qcuboidgeometry.cpp
diff --git a/tests/auto/input/abstractaxisinput/abstractaxisinput.pro b/tests/auto/input/abstractaxisinput/abstractaxisinput.pro
index 3f9c521de..574b9af9e 100644
--- a/tests/auto/input/abstractaxisinput/abstractaxisinput.pro
+++ b/tests/auto/input/abstractaxisinput/abstractaxisinput.pro
@@ -8,5 +8,4 @@ CONFIG += testcase
SOURCES += tst_abstractaxisinput.cpp
-include(../../core/common/common.pri)
include(../commons/commons.pri)
diff --git a/tests/auto/input/actioninput/actioninput.pro b/tests/auto/input/actioninput/actioninput.pro
new file mode 100644
index 000000000..1091f2b76
--- /dev/null
+++ b/tests/auto/input/actioninput/actioninput.pro
@@ -0,0 +1,11 @@
+TEMPLATE = app
+
+TARGET = tst_actioninput
+
+QT += core-private 3dcore 3dcore-private 3dinput 3dinput-private testlib
+
+CONFIG += testcase
+
+SOURCES += tst_actioninput.cpp
+
+include(../commons/commons.pri)
diff --git a/tests/auto/input/actioninput/tst_actioninput.cpp b/tests/auto/input/actioninput/tst_actioninput.cpp
new file mode 100644
index 000000000..2db4cf760
--- /dev/null
+++ b/tests/auto/input/actioninput/tst_actioninput.cpp
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QTest>
+#include <qbackendnodetester.h>
+#include "testdevice.h"
+
+#include <Qt3DCore/QPropertyUpdatedChange>
+#include <Qt3DInput/private/actioninput_p.h>
+#include <Qt3DInput/private/inputhandler_p.h>
+#include <Qt3DInput/QActionInput>
+
+class tst_ActionInput : public Qt3DCore::QBackendNodeTester
+{
+ Q_OBJECT
+private Q_SLOTS:
+ void shouldMirrorPeerProperties()
+ {
+ // GIVEN
+ Qt3DInput::Input::ActionInput backendActionInput;
+ Qt3DInput::QActionInput actionInput;
+ TestDevice sourceDevice;
+
+ actionInput.setButtons(QVector<int>() << (1 << 8));
+ actionInput.setSourceDevice(&sourceDevice);
+
+ // WHEN
+ simulateInitialization(&actionInput, &backendActionInput);
+
+ // THEN
+ QCOMPARE(backendActionInput.peerId(), actionInput.id());
+ QCOMPARE(backendActionInput.isEnabled(), actionInput.isEnabled());
+ QCOMPARE(backendActionInput.buttons(), actionInput.buttons());
+ QCOMPARE(backendActionInput.sourceDevice(), sourceDevice.id());
+ }
+
+ void shouldHaveInitialAndCleanedUpStates()
+ {
+ // GIVEN
+ Qt3DInput::Input::ActionInput backendActionInput;
+
+ // THEN
+ QVERIFY(backendActionInput.peerId().isNull());
+ QVERIFY(backendActionInput.buttons().isEmpty());
+ QCOMPARE(backendActionInput.isEnabled(), false);
+ QCOMPARE(backendActionInput.sourceDevice(), Qt3DCore::QNodeId());
+
+ // GIVEN
+ Qt3DInput::QActionInput actionInput;
+ TestDevice sourceDevice;
+
+ actionInput.setButtons(QVector<int>() << (1 << 8));
+ actionInput.setSourceDevice(&sourceDevice);
+
+ // WHEN
+ simulateInitialization(&actionInput, &backendActionInput);
+ backendActionInput.cleanup();
+
+ // THEN
+ QVERIFY(backendActionInput.buttons().isEmpty());
+ QCOMPARE(backendActionInput.isEnabled(), false);
+ QCOMPARE(backendActionInput.sourceDevice(), Qt3DCore::QNodeId());
+ }
+
+ void shouldHandlePropertyChanges()
+ {
+ // GIVEN
+ Qt3DInput::Input::ActionInput backendActionInput;
+
+ // WHEN
+ Qt3DCore::QPropertyUpdatedChangePtr updateChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange->setValue(QVariant::fromValue(QVector<int>() << 64));
+ updateChange->setPropertyName("buttons");
+ backendActionInput.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backendActionInput.buttons(), QVector<int>() << 64);
+
+ // WHEN
+ updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange->setPropertyName("enabled");
+ updateChange->setValue(true);
+ backendActionInput.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backendActionInput.isEnabled(), true);
+
+ // WHEN
+ TestDevice device;
+ updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange->setPropertyName("sourceDevice");
+ updateChange->setValue(QVariant::fromValue(device.id()));
+ backendActionInput.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backendActionInput.sourceDevice(), device.id());
+ }
+
+ void shouldDealWithKeyPresses()
+ {
+ // GIVEN
+ TestDeviceIntegration deviceIntegration;
+ TestDevice *device = deviceIntegration.createPhysicalDevice("keyboard");
+ TestDeviceBackendNode *deviceBackend = deviceIntegration.physicalDevice(device->id());
+ Qt3DInput::Input::InputHandler handler;
+ handler.addInputDeviceIntegration(&deviceIntegration);
+
+ Qt3DInput::Input::ActionInput backendActionInput;
+ Qt3DInput::QActionInput actionInput;
+ actionInput.setButtons(QVector<int>() << Qt::Key_Space << Qt::Key_Return);
+ actionInput.setSourceDevice(device);
+ simulateInitialization(&actionInput, &backendActionInput);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Up, true);
+
+ // THEN
+ QCOMPARE(backendActionInput.process(&handler, 1000000000), false);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Space, true);
+
+ // THEN
+ QCOMPARE(backendActionInput.process(&handler, 1000000000), true);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Return, true);
+
+ // THEN
+ QCOMPARE(backendActionInput.process(&handler, 1000000000), true);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Space, false);
+
+ // THEN
+ QCOMPARE(backendActionInput.process(&handler, 1000000000), true);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Up, false);
+
+ // THEN
+ QCOMPARE(backendActionInput.process(&handler, 1000000000), true);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Return, false);
+
+ // THEN
+ QCOMPARE(backendActionInput.process(&handler, 1000000000), false);
+ }
+};
+
+QTEST_APPLESS_MAIN(tst_ActionInput)
+
+#include "tst_actioninput.moc"
diff --git a/tests/auto/input/analogaxisinput/analogaxisinput.pro b/tests/auto/input/analogaxisinput/analogaxisinput.pro
index 7bd0a9865..16d237bf9 100644
--- a/tests/auto/input/analogaxisinput/analogaxisinput.pro
+++ b/tests/auto/input/analogaxisinput/analogaxisinput.pro
@@ -8,5 +8,4 @@ CONFIG += testcase
SOURCES += tst_analogaxisinput.cpp
-include(../../core/common/common.pri)
include(../commons/commons.pri)
diff --git a/tests/auto/input/buttonaxisinput/buttonaxisinput.pro b/tests/auto/input/buttonaxisinput/buttonaxisinput.pro
index f012ca1d3..1aa492aa4 100644
--- a/tests/auto/input/buttonaxisinput/buttonaxisinput.pro
+++ b/tests/auto/input/buttonaxisinput/buttonaxisinput.pro
@@ -8,5 +8,4 @@ CONFIG += testcase
SOURCES += tst_buttonaxisinput.cpp
-include(../../core/common/common.pri)
include(../commons/commons.pri)
diff --git a/tests/auto/input/commons/commons.pri b/tests/auto/input/commons/commons.pri
index cc65e8a41..ccc14075b 100644
--- a/tests/auto/input/commons/commons.pri
+++ b/tests/auto/input/commons/commons.pri
@@ -1,3 +1,6 @@
HEADERS += $$PWD/testdevice.h
INCLUDEPATH += $$PWD
+
+include(../../core/common/common.pri)
+
diff --git a/tests/auto/input/commons/testdevice.h b/tests/auto/input/commons/testdevice.h
index c58835a38..c6fc4995b 100644
--- a/tests/auto/input/commons/testdevice.h
+++ b/tests/auto/input/commons/testdevice.h
@@ -28,6 +28,9 @@
#include <Qt3DCore/private/qnode_p.h>
#include <Qt3DInput/QAbstractPhysicalDevice>
+#include <Qt3DInput/private/qabstractphysicaldevicebackendnode_p.h>
+#include <Qt3DInput/private/qinputdeviceintegration_p.h>
+#include <qbackendnodetester.h>
class TestDevice : public Qt3DInput::QAbstractPhysicalDevice
{
@@ -43,4 +46,108 @@ public:
QStringList buttonNames() const Q_DECL_FINAL { return QStringList(); }
int axisIdentifier(const QString &name) const Q_DECL_FINAL { Q_UNUSED(name) return 0; }
int buttonIdentifier(const QString &name) const Q_DECL_FINAL { Q_UNUSED(name) return 0; }
+
+private:
+ friend class TestDeviceBackendNode;
+};
+
+class TestDeviceBackendNode : public Qt3DInput::QAbstractPhysicalDeviceBackendNode
+{
+public:
+ explicit TestDeviceBackendNode(TestDevice *device)
+ : Qt3DInput::QAbstractPhysicalDeviceBackendNode(ReadOnly)
+ {
+ Qt3DCore::QBackendNodeTester().simulateInitialization(device, this);
+ }
+
+ float axisValue(int axisIdentifier) const Q_DECL_FINAL
+ {
+ return m_axisValues.value(axisIdentifier);
+ }
+
+ void setAxisValue(int axisIdentifier, float value)
+ {
+ m_axisValues.insert(axisIdentifier, value);
+ }
+
+ bool isButtonPressed(int buttonIdentifier) const Q_DECL_FINAL
+ {
+ return m_buttonStates.value(buttonIdentifier);
+ }
+
+ void setButtonPressed(int buttonIdentifier, bool pressed)
+ {
+ m_buttonStates.insert(buttonIdentifier, pressed);
+ }
+
+private:
+ QHash<int, float> m_axisValues;
+ QHash<int, bool> m_buttonStates;
+};
+
+class TestDeviceIntegration : public Qt3DInput::QInputDeviceIntegration
+{
+ Q_OBJECT
+public:
+ explicit TestDeviceIntegration(QObject *parent = nullptr)
+ : Qt3DInput::QInputDeviceIntegration(parent),
+ m_devicesParent(new Qt3DCore::QNode)
+ {
+ }
+
+ ~TestDeviceIntegration()
+ {
+ qDeleteAll(m_deviceBackendNodes);
+ }
+
+ QVector<Qt3DCore::QAspectJobPtr> jobsToExecute(qint64 time) Q_DECL_FINAL
+ {
+ Q_UNUSED(time);
+ return QVector<Qt3DCore::QAspectJobPtr>();
+ }
+
+ TestDevice *createPhysicalDevice(const QString &name) Q_DECL_FINAL
+ {
+ Q_ASSERT(!deviceNames().contains(name));
+ auto device = new TestDevice(m_devicesParent.data()); // Avoids unwanted reparenting
+ device->setObjectName(name);
+ m_devices.append(device);
+ m_deviceBackendNodes.append(new TestDeviceBackendNode(device));
+ return device;
+ }
+
+ QVector<Qt3DCore::QNodeId> physicalDevices() const Q_DECL_FINAL
+ {
+ QVector<Qt3DCore::QNodeId> ids;
+ std::transform(m_devices.constBegin(), m_devices.constEnd(),
+ std::back_inserter(ids),
+ [] (TestDevice *device) { return device->id(); });
+ return ids;
+ }
+
+ TestDeviceBackendNode *physicalDevice(Qt3DCore::QNodeId id) const Q_DECL_FINAL
+ {
+ auto it = std::find_if(m_deviceBackendNodes.constBegin(), m_deviceBackendNodes.constEnd(),
+ [id] (TestDeviceBackendNode *node) { return node->peerId() == id; });
+ if (it == m_deviceBackendNodes.constEnd())
+ return nullptr;
+ else
+ return *it;
+ }
+
+ QStringList deviceNames() const Q_DECL_FINAL
+ {
+ QStringList names;
+ std::transform(m_devices.constBegin(), m_devices.constEnd(),
+ std::back_inserter(names),
+ [] (TestDevice *device) { return device->objectName(); });
+ return names;
+ }
+
+private:
+ void onInitialize() Q_DECL_FINAL {}
+
+ QScopedPointer<Qt3DCore::QNode> m_devicesParent;
+ QVector<TestDevice*> m_devices;
+ QVector<TestDeviceBackendNode*> m_deviceBackendNodes;
};
diff --git a/tests/auto/input/input.pro b/tests/auto/input/input.pro
index fa447730d..05668c036 100644
--- a/tests/auto/input/input.pro
+++ b/tests/auto/input/input.pro
@@ -13,8 +13,11 @@ qtConfig(private_tests) {
axis \
action \
abstractaxisinput \
+ actioninput \
analogaxisinput \
buttonaxisinput \
keyboardhandler \
- qaxisaccumulator
+ qaxisaccumulator \
+ inputsequence \
+ inputchord
}
diff --git a/tests/auto/input/inputchord/inputchord.pro b/tests/auto/input/inputchord/inputchord.pro
new file mode 100644
index 000000000..09bbbb3ec
--- /dev/null
+++ b/tests/auto/input/inputchord/inputchord.pro
@@ -0,0 +1,11 @@
+TEMPLATE = app
+
+TARGET = tst_inputchord
+
+QT += core-private 3dcore 3dcore-private 3dinput 3dinput-private testlib
+
+CONFIG += testcase
+
+SOURCES += tst_inputchord.cpp
+
+include(../commons/commons.pri)
diff --git a/tests/auto/input/inputchord/tst_inputchord.cpp b/tests/auto/input/inputchord/tst_inputchord.cpp
new file mode 100644
index 000000000..a840d7dee
--- /dev/null
+++ b/tests/auto/input/inputchord/tst_inputchord.cpp
@@ -0,0 +1,281 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QTest>
+#include <qbackendnodetester.h>
+#include "testdevice.h"
+
+#include <Qt3DCore/QPropertyUpdatedChange>
+#include <Qt3DCore/QPropertyNodeAddedChange>
+#include <Qt3DCore/QPropertyNodeRemovedChange>
+#include <Qt3DInput/private/actioninput_p.h>
+#include <Qt3DInput/private/inputchord_p.h>
+#include <Qt3DInput/private/inputhandler_p.h>
+#include <Qt3DInput/private/inputmanagers_p.h>
+#include <Qt3DInput/QActionInput>
+#include <Qt3DInput/QInputChord>
+
+class tst_InputChord : public Qt3DCore::QBackendNodeTester
+{
+ Q_OBJECT
+private Q_SLOTS:
+ void shouldMirrorPeerProperties()
+ {
+ // GIVEN
+ Qt3DInput::Input::InputChord backendInputChord;
+ Qt3DInput::QInputChord inputChord;
+ Qt3DInput::QActionInput actionInput;
+
+ inputChord.setTimeout(250);
+ inputChord.addChord(&actionInput);
+
+ // WHEN
+ simulateInitialization(&inputChord, &backendInputChord);
+
+ // THEN
+ QCOMPARE(backendInputChord.peerId(), inputChord.id());
+ QCOMPARE(backendInputChord.isEnabled(), inputChord.isEnabled());
+ QCOMPARE(backendInputChord.timeout(), inputChord.timeout() * 1000000);
+ QCOMPARE(backendInputChord.chords().size(), inputChord.chords().size());
+
+ const int inputsCount = backendInputChord.chords().size();
+ if (inputsCount > 0) {
+ for (int i = 0; i < inputsCount; ++i)
+ QCOMPARE(backendInputChord.chords().at(i), inputChord.chords().at(i)->id());
+ }
+ }
+
+ void shouldHaveInitialAndCleanedUpStates()
+ {
+ // GIVEN
+ Qt3DInput::Input::InputChord backendInputChord;
+
+ // THEN
+ QVERIFY(backendInputChord.peerId().isNull());
+ QCOMPARE(backendInputChord.isEnabled(), false);
+ QCOMPARE(backendInputChord.timeout(), 0);
+ QCOMPARE(backendInputChord.chords().size(), 0);
+
+ // GIVEN
+ Qt3DInput::QInputChord inputChord;
+ Qt3DInput::QActionInput actionInput;
+
+ inputChord.setTimeout(250);
+ inputChord.addChord(&actionInput);
+
+ // WHEN
+ simulateInitialization(&inputChord, &backendInputChord);
+ backendInputChord.cleanup();
+
+ // THEN
+ QCOMPARE(backendInputChord.isEnabled(), false);
+ QCOMPARE(backendInputChord.timeout(), 0);
+ QCOMPARE(backendInputChord.chords().size(), 0);
+ }
+
+ void shouldHandlePropertyChanges()
+ {
+ // GIVEN
+ Qt3DInput::Input::InputChord backendInputChord;
+
+ // WHEN
+ Qt3DCore::QPropertyUpdatedChangePtr updateChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange->setValue(250);
+ updateChange->setPropertyName("timeout");
+ backendInputChord.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backendInputChord.timeout(), 250000000);
+
+ // WHEN
+ updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange->setPropertyName("enabled");
+ updateChange->setValue(true);
+ backendInputChord.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backendInputChord.isEnabled(), true);
+
+ // WHEN
+ Qt3DInput::QActionInput input;
+ const Qt3DCore::QNodeId inputId = input.id();
+ const auto nodeAddedChange = Qt3DCore::QPropertyNodeAddedChangePtr::create(Qt3DCore::QNodeId(), &input);
+ nodeAddedChange->setPropertyName("chord");
+ backendInputChord.sceneChangeEvent(nodeAddedChange);
+
+ // THEN
+ QCOMPARE(backendInputChord.chords().size(), 1);
+ QCOMPARE(backendInputChord.chords().first(), inputId);
+
+ // WHEN
+ const auto nodeRemovedChange = Qt3DCore::QPropertyNodeRemovedChangePtr::create(Qt3DCore::QNodeId(), &input);
+ nodeRemovedChange->setPropertyName("chord");
+ backendInputChord.sceneChangeEvent(nodeRemovedChange);
+
+ // THEN
+ QCOMPARE(backendInputChord.chords().size(), 0);
+ }
+
+ void shouldActivateWhenAllArePressed()
+ {
+ // GIVEN
+ TestDeviceIntegration deviceIntegration;
+ TestDevice *device = deviceIntegration.createPhysicalDevice("keyboard");
+ TestDeviceBackendNode *deviceBackend = deviceIntegration.physicalDevice(device->id());
+ Qt3DInput::Input::InputHandler handler;
+ handler.addInputDeviceIntegration(&deviceIntegration);
+
+ auto firstInput = new Qt3DInput::QActionInput;
+ firstInput->setButtons(QVector<int>() << Qt::Key_Q << Qt::Key_W);
+ firstInput->setSourceDevice(device);
+ auto backendFirstInput = handler.actionInputManager()->getOrCreateResource(firstInput->id());
+ simulateInitialization(firstInput, backendFirstInput);
+
+ auto secondInput = new Qt3DInput::QActionInput;
+ secondInput->setButtons(QVector<int>() << Qt::Key_A << Qt::Key_S);
+ secondInput->setSourceDevice(device);
+ auto backendSecondInput = handler.actionInputManager()->getOrCreateResource(secondInput->id());
+ simulateInitialization(secondInput, backendSecondInput);
+
+ Qt3DInput::Input::InputChord backendInputChord;
+ Qt3DInput::QInputChord inputChord;
+ inputChord.setTimeout(300);
+ inputChord.addChord(firstInput);
+ inputChord.addChord(secondInput);
+ simulateInitialization(&inputChord, &backendInputChord);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Up, true);
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 1000000000), false);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Up, false);
+ deviceBackend->setButtonPressed(Qt::Key_Q, true);
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 1100000000), false);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_A, true);
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 1200000000), true);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_S, true);
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 1300000000), true);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_W, true);
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 1400000000), true);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_W, false);
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 1500000000), true);
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 1600000000), true);
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 1700000000), true);
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 1800000000), true);
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 1900000000), true);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Q, false);
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 2000000000), false);
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 2100000000), false);
+ }
+
+ void shouldRespectChordTimeout()
+ {
+ // GIVEN
+ TestDeviceIntegration deviceIntegration;
+ TestDevice *device = deviceIntegration.createPhysicalDevice("keyboard");
+ TestDeviceBackendNode *deviceBackend = deviceIntegration.physicalDevice(device->id());
+ Qt3DInput::Input::InputHandler handler;
+ handler.addInputDeviceIntegration(&deviceIntegration);
+
+ auto firstInput = new Qt3DInput::QActionInput;
+ firstInput->setButtons(QVector<int>() << Qt::Key_Q);
+ firstInput->setSourceDevice(device);
+ auto backendFirstInput = handler.actionInputManager()->getOrCreateResource(firstInput->id());
+ simulateInitialization(firstInput, backendFirstInput);
+
+ auto secondInput = new Qt3DInput::QActionInput;
+ secondInput->setButtons(QVector<int>() << Qt::Key_W);
+ secondInput->setSourceDevice(device);
+ auto backendSecondInput = handler.actionInputManager()->getOrCreateResource(secondInput->id());
+ simulateInitialization(secondInput, backendSecondInput);
+
+ Qt3DInput::Input::InputChord backendInputChord;
+ Qt3DInput::QInputChord inputChord;
+ inputChord.setTimeout(300);
+ inputChord.addChord(firstInput);
+ inputChord.addChord(secondInput);
+ simulateInitialization(&inputChord, &backendInputChord);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Q, true);
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 1000000000), false);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_W, true);
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 1400000000), false); // Too late
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 1600000000), false);
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 1800000000), false);
+ }
+};
+
+QTEST_APPLESS_MAIN(tst_InputChord)
+
+#include "tst_inputchord.moc"
diff --git a/tests/auto/input/inputsequence/inputsequence.pro b/tests/auto/input/inputsequence/inputsequence.pro
new file mode 100644
index 000000000..1fdb21f5b
--- /dev/null
+++ b/tests/auto/input/inputsequence/inputsequence.pro
@@ -0,0 +1,11 @@
+TEMPLATE = app
+
+TARGET = tst_inputsequence
+
+QT += core-private 3dcore 3dcore-private 3dinput 3dinput-private testlib
+
+CONFIG += testcase
+
+SOURCES += tst_inputsequence.cpp
+
+include(../commons/commons.pri)
diff --git a/tests/auto/input/inputsequence/tst_inputsequence.cpp b/tests/auto/input/inputsequence/tst_inputsequence.cpp
new file mode 100644
index 000000000..6b4a39b68
--- /dev/null
+++ b/tests/auto/input/inputsequence/tst_inputsequence.cpp
@@ -0,0 +1,400 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QTest>
+#include <qbackendnodetester.h>
+#include "testdevice.h"
+
+#include <Qt3DCore/QPropertyUpdatedChange>
+#include <Qt3DCore/QPropertyNodeAddedChange>
+#include <Qt3DCore/QPropertyNodeRemovedChange>
+#include <Qt3DInput/private/actioninput_p.h>
+#include <Qt3DInput/private/inputhandler_p.h>
+#include <Qt3DInput/private/inputmanagers_p.h>
+#include <Qt3DInput/private/inputsequence_p.h>
+#include <Qt3DInput/QActionInput>
+#include <Qt3DInput/QInputSequence>
+
+class tst_InputSequence : public Qt3DCore::QBackendNodeTester
+{
+ Q_OBJECT
+private Q_SLOTS:
+ void shouldMirrorPeerProperties()
+ {
+ // GIVEN
+ Qt3DInput::Input::InputSequence backendInputSequence;
+ Qt3DInput::QInputSequence inputSequence;
+ Qt3DInput::QActionInput actionInput;
+
+ inputSequence.setTimeout(250);
+ inputSequence.setButtonInterval(100);
+ inputSequence.addSequence(&actionInput);
+
+ // WHEN
+ simulateInitialization(&inputSequence, &backendInputSequence);
+
+ // THEN
+ QCOMPARE(backendInputSequence.peerId(), inputSequence.id());
+ QCOMPARE(backendInputSequence.isEnabled(), inputSequence.isEnabled());
+ QCOMPARE(backendInputSequence.timeout(), inputSequence.timeout() * 1000000);
+ QCOMPARE(backendInputSequence.buttonInterval(), inputSequence.buttonInterval() * 1000000);
+ QCOMPARE(backendInputSequence.sequences().size(), inputSequence.sequences().size());
+
+ const int inputsCount = backendInputSequence.sequences().size();
+ if (inputsCount > 0) {
+ for (int i = 0; i < inputsCount; ++i)
+ QCOMPARE(backendInputSequence.sequences().at(i), inputSequence.sequences().at(i)->id());
+ }
+ }
+
+ void shouldHaveInitialAndCleanedUpStates()
+ {
+ // GIVEN
+ Qt3DInput::Input::InputSequence backendInputSequence;
+
+ // THEN
+ QVERIFY(backendInputSequence.peerId().isNull());
+ QCOMPARE(backendInputSequence.isEnabled(), false);
+ QCOMPARE(backendInputSequence.timeout(), 0);
+ QCOMPARE(backendInputSequence.buttonInterval(), 0);
+ QCOMPARE(backendInputSequence.sequences().size(), 0);
+
+ // GIVEN
+ Qt3DInput::QInputSequence inputSequence;
+ Qt3DInput::QActionInput actionInput;
+
+ inputSequence.setTimeout(250);
+ inputSequence.setButtonInterval(100);
+ inputSequence.addSequence(&actionInput);
+
+ // WHEN
+ simulateInitialization(&inputSequence, &backendInputSequence);
+ backendInputSequence.cleanup();
+
+ // THEN
+ QCOMPARE(backendInputSequence.isEnabled(), false);
+ QCOMPARE(backendInputSequence.timeout(), 0);
+ QCOMPARE(backendInputSequence.buttonInterval(), 0);
+ QCOMPARE(backendInputSequence.sequences().size(), 0);
+ }
+
+ void shouldHandlePropertyChanges()
+ {
+ // GIVEN
+ Qt3DInput::Input::InputSequence backendInputSequence;
+
+ // WHEN
+ Qt3DCore::QPropertyUpdatedChangePtr updateChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange->setValue(250);
+ updateChange->setPropertyName("timeout");
+ backendInputSequence.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backendInputSequence.timeout(), 250000000);
+
+ // WHEN
+ updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange->setValue(150);
+ updateChange->setPropertyName("buttonInterval");
+ backendInputSequence.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backendInputSequence.buttonInterval(), 150000000);
+
+ // WHEN
+ updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange->setPropertyName("enabled");
+ updateChange->setValue(true);
+ backendInputSequence.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backendInputSequence.isEnabled(), true);
+
+ // WHEN
+ Qt3DInput::QActionInput input;
+ const Qt3DCore::QNodeId inputId = input.id();
+ const auto nodeAddedChange = Qt3DCore::QPropertyNodeAddedChangePtr::create(Qt3DCore::QNodeId(), &input);
+ nodeAddedChange->setPropertyName("sequence");
+ backendInputSequence.sceneChangeEvent(nodeAddedChange);
+
+ // THEN
+ QCOMPARE(backendInputSequence.sequences().size(), 1);
+ QCOMPARE(backendInputSequence.sequences().first(), inputId);
+
+ // WHEN
+ const auto nodeRemovedChange = Qt3DCore::QPropertyNodeRemovedChangePtr::create(Qt3DCore::QNodeId(), &input);
+ nodeRemovedChange->setPropertyName("sequence");
+ backendInputSequence.sceneChangeEvent(nodeRemovedChange);
+
+ // THEN
+ QCOMPARE(backendInputSequence.sequences().size(), 0);
+ }
+
+ void shouldActivateWhenSequenceIsConsumedInOrderOnly()
+ {
+ // GIVEN
+ TestDeviceIntegration deviceIntegration;
+ TestDevice *device = deviceIntegration.createPhysicalDevice("keyboard");
+ TestDeviceBackendNode *deviceBackend = deviceIntegration.physicalDevice(device->id());
+ Qt3DInput::Input::InputHandler handler;
+ handler.addInputDeviceIntegration(&deviceIntegration);
+
+ auto firstInput = new Qt3DInput::QActionInput;
+ firstInput->setButtons(QVector<int>() << Qt::Key_Q << Qt::Key_A);
+ firstInput->setSourceDevice(device);
+ auto backendFirstInput = handler.actionInputManager()->getOrCreateResource(firstInput->id());
+ simulateInitialization(firstInput, backendFirstInput);
+
+ auto secondInput = new Qt3DInput::QActionInput;
+ secondInput->setButtons(QVector<int>() << Qt::Key_S << Qt::Key_W);
+ secondInput->setSourceDevice(device);
+ auto backendSecondInput = handler.actionInputManager()->getOrCreateResource(secondInput->id());
+ simulateInitialization(secondInput, backendSecondInput);
+
+ auto thirdInput = new Qt3DInput::QActionInput;
+ thirdInput->setButtons(QVector<int>() << Qt::Key_D << Qt::Key_E);
+ thirdInput->setSourceDevice(device);
+ auto backendThirdInput = handler.actionInputManager()->getOrCreateResource(thirdInput->id());
+ simulateInitialization(thirdInput, backendThirdInput);
+
+ Qt3DInput::Input::InputSequence backendInputSequence;
+ Qt3DInput::QInputSequence inputSequence;
+ inputSequence.setButtonInterval(150);
+ inputSequence.setTimeout(450);
+ inputSequence.addSequence(firstInput);
+ inputSequence.addSequence(secondInput);
+ inputSequence.addSequence(thirdInput);
+ simulateInitialization(&inputSequence, &backendInputSequence);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Up, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1000000000), false);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Up, false);
+ deviceBackend->setButtonPressed(Qt::Key_Q, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1100000000), false);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Q, false);
+ deviceBackend->setButtonPressed(Qt::Key_S, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1200000000), false);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_S, false);
+ deviceBackend->setButtonPressed(Qt::Key_E, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1300000000), true);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_E, false);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1400000000), false);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Q, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1500000000), false);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Q, false);
+ deviceBackend->setButtonPressed(Qt::Key_S, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1600000000), false);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_S, false);
+ deviceBackend->setButtonPressed(Qt::Key_E, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1700000000), true);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_E, false);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1800000000), false);
+
+
+ // Now out of order
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_S, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1900000000), false);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_S, false);
+ deviceBackend->setButtonPressed(Qt::Key_Q, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 2000000000), false);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Q, false);
+ deviceBackend->setButtonPressed(Qt::Key_D, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 2100000000), false);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_D, false);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 22000000000), false);
+ }
+
+ void shouldRespectSequenceTimeout()
+ {
+ // GIVEN
+ TestDeviceIntegration deviceIntegration;
+ TestDevice *device = deviceIntegration.createPhysicalDevice("keyboard");
+ TestDeviceBackendNode *deviceBackend = deviceIntegration.physicalDevice(device->id());
+ Qt3DInput::Input::InputHandler handler;
+ handler.addInputDeviceIntegration(&deviceIntegration);
+
+ auto firstInput = new Qt3DInput::QActionInput;
+ firstInput->setButtons(QVector<int>() << Qt::Key_Q << Qt::Key_A);
+ firstInput->setSourceDevice(device);
+ auto backendFirstInput = handler.actionInputManager()->getOrCreateResource(firstInput->id());
+ simulateInitialization(firstInput, backendFirstInput);
+
+ auto secondInput = new Qt3DInput::QActionInput;
+ secondInput->setButtons(QVector<int>() << Qt::Key_S << Qt::Key_W);
+ secondInput->setSourceDevice(device);
+ auto backendSecondInput = handler.actionInputManager()->getOrCreateResource(secondInput->id());
+ simulateInitialization(secondInput, backendSecondInput);
+
+ auto thirdInput = new Qt3DInput::QActionInput;
+ thirdInput->setButtons(QVector<int>() << Qt::Key_D << Qt::Key_E);
+ thirdInput->setSourceDevice(device);
+ auto backendThirdInput = handler.actionInputManager()->getOrCreateResource(thirdInput->id());
+ simulateInitialization(thirdInput, backendThirdInput);
+
+ Qt3DInput::Input::InputSequence backendInputSequence;
+ Qt3DInput::QInputSequence inputSequence;
+ inputSequence.setButtonInterval(250);
+ inputSequence.setTimeout(450);
+ inputSequence.addSequence(firstInput);
+ inputSequence.addSequence(secondInput);
+ inputSequence.addSequence(thirdInput);
+ simulateInitialization(&inputSequence, &backendInputSequence);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Q, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1100000000), false);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Q, false);
+ deviceBackend->setButtonPressed(Qt::Key_S, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1300000000), false);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_S, false);
+ deviceBackend->setButtonPressed(Qt::Key_E, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1600000000), false); // Too late
+ }
+
+ void shouldRespectSequenceButtonInterval()
+ {
+ // GIVEN
+ TestDeviceIntegration deviceIntegration;
+ TestDevice *device = deviceIntegration.createPhysicalDevice("keyboard");
+ TestDeviceBackendNode *deviceBackend = deviceIntegration.physicalDevice(device->id());
+ Qt3DInput::Input::InputHandler handler;
+ handler.addInputDeviceIntegration(&deviceIntegration);
+
+ auto firstInput = new Qt3DInput::QActionInput;
+ firstInput->setButtons(QVector<int>() << Qt::Key_Q << Qt::Key_A);
+ firstInput->setSourceDevice(device);
+ auto backendFirstInput = handler.actionInputManager()->getOrCreateResource(firstInput->id());
+ simulateInitialization(firstInput, backendFirstInput);
+
+ auto secondInput = new Qt3DInput::QActionInput;
+ secondInput->setButtons(QVector<int>() << Qt::Key_S << Qt::Key_W);
+ secondInput->setSourceDevice(device);
+ auto backendSecondInput = handler.actionInputManager()->getOrCreateResource(secondInput->id());
+ simulateInitialization(secondInput, backendSecondInput);
+
+ auto thirdInput = new Qt3DInput::QActionInput;
+ thirdInput->setButtons(QVector<int>() << Qt::Key_D << Qt::Key_E);
+ thirdInput->setSourceDevice(device);
+ auto backendThirdInput = handler.actionInputManager()->getOrCreateResource(thirdInput->id());
+ simulateInitialization(thirdInput, backendThirdInput);
+
+ Qt3DInput::Input::InputSequence backendInputSequence;
+ Qt3DInput::QInputSequence inputSequence;
+ inputSequence.setButtonInterval(100);
+ inputSequence.setTimeout(450);
+ inputSequence.addSequence(firstInput);
+ inputSequence.addSequence(secondInput);
+ inputSequence.addSequence(thirdInput);
+ simulateInitialization(&inputSequence, &backendInputSequence);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Q, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1100000000), false);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Q, false);
+ deviceBackend->setButtonPressed(Qt::Key_S, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1250000000), false); // Too late
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_S, false);
+ deviceBackend->setButtonPressed(Qt::Key_E, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1300000000), false);
+ }
+};
+
+QTEST_APPLESS_MAIN(tst_InputSequence)
+
+#include "tst_inputsequence.moc"
diff --git a/tests/auto/input/keyboardhandler/keyboardhandler.pro b/tests/auto/input/keyboardhandler/keyboardhandler.pro
index f3f7b6c63..2e28c5045 100644
--- a/tests/auto/input/keyboardhandler/keyboardhandler.pro
+++ b/tests/auto/input/keyboardhandler/keyboardhandler.pro
@@ -8,5 +8,4 @@ CONFIG += testcase
SOURCES += tst_keyboardhandler.cpp
-include(../../core/common/common.pri)
include(../commons/commons.pri)
diff --git a/tests/auto/render/qcameralens/qcameralens.pro b/tests/auto/render/qcameralens/qcameralens.pro
new file mode 100644
index 000000000..0f517d5ef
--- /dev/null
+++ b/tests/auto/render/qcameralens/qcameralens.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+
+TARGET = tst_qcameralens
+
+QT += 3dcore 3dcore-private 3drender 3drender-private testlib
+
+CONFIG += testcase
+
+SOURCES += tst_qcameralens.cpp
+
+include(../../core/common/common.pri)
+include(../commons/commons.pri)
diff --git a/tests/auto/render/qcameralens/tst_qcameralens.cpp b/tests/auto/render/qcameralens/tst_qcameralens.cpp
new file mode 100644
index 000000000..aab43d553
--- /dev/null
+++ b/tests/auto/render/qcameralens/tst_qcameralens.cpp
@@ -0,0 +1,717 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Paul Lemire <paul.lemire350@gmail.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QTest>
+#include <Qt3DRender/qcameralens.h>
+#include <Qt3DRender/private/qcameralens_p.h>
+#include <QObject>
+#include <QSignalSpy>
+#include <Qt3DCore/qpropertyupdatedchange.h>
+#include <Qt3DCore/private/qnodecreatedchangegenerator_p.h>
+#include <Qt3DCore/qnodecreatedchange.h>
+#include "testpostmanarbiter.h"
+
+class tst_QCameraLens : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+
+ void initTestCase()
+ {
+ qRegisterMetaType<Qt3DRender::QCameraLens::ProjectionType>("QCameraLens::ProjectionType");
+ }
+
+ void checkDefaultConstruction()
+ {
+ // GIVEN
+ Qt3DRender::QCameraLens cameraLens;
+
+ // THEN
+ QCOMPARE(cameraLens.projectionType(), Qt3DRender::QCameraLens::PerspectiveProjection);
+ QCOMPARE(cameraLens.nearPlane(), 0.1f);
+ QCOMPARE(cameraLens.farPlane(), 1024.0f);
+ QCOMPARE(cameraLens.fieldOfView(), 25.0f);
+ QCOMPARE(cameraLens.aspectRatio(), 1.0f);
+ QCOMPARE(cameraLens.left(), -0.5f);
+ QCOMPARE(cameraLens.right(), 0.5f);
+ QCOMPARE(cameraLens.bottom(), -0.5f);
+ QCOMPARE(cameraLens.top(), 0.5f);
+ }
+
+ void checkPropertyChanges()
+ {
+ // GIVEN
+ Qt3DRender::QCameraLens cameraLens;
+
+ {
+ // WHEN
+ QSignalSpy spy(&cameraLens, SIGNAL(projectionTypeChanged(QCameraLens::ProjectionType)));
+ const Qt3DRender::QCameraLens::ProjectionType newValue = Qt3DRender::QCameraLens::OrthographicProjection;
+ cameraLens.setProjectionType(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(cameraLens.projectionType(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ cameraLens.setProjectionType(newValue);
+
+ // THEN
+ QCOMPARE(cameraLens.projectionType(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+ {
+ // WHEN
+ QSignalSpy spy(&cameraLens, SIGNAL(nearPlaneChanged(float)));
+ const float newValue = 10.0f;
+ cameraLens.setNearPlane(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(cameraLens.nearPlane(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ cameraLens.setNearPlane(newValue);
+
+ // THEN
+ QCOMPARE(cameraLens.nearPlane(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+ {
+ // WHEN
+ QSignalSpy spy(&cameraLens, SIGNAL(farPlaneChanged(float)));
+ const float newValue = 1.0f;
+ cameraLens.setFarPlane(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(cameraLens.farPlane(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ cameraLens.setFarPlane(newValue);
+
+ // THEN
+ QCOMPARE(cameraLens.farPlane(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+ {
+ // WHEN
+ QSignalSpy spy(&cameraLens, SIGNAL(fieldOfViewChanged(float)));
+ const float newValue = 5.0f;
+ cameraLens.setFieldOfView(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(cameraLens.fieldOfView(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ cameraLens.setFieldOfView(newValue);
+
+ // THEN
+ QCOMPARE(cameraLens.fieldOfView(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+ {
+ // WHEN
+ QSignalSpy spy(&cameraLens, SIGNAL(aspectRatioChanged(float)));
+ const float newValue = 4.0f / 3.0f;
+ cameraLens.setAspectRatio(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(cameraLens.aspectRatio(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ cameraLens.setAspectRatio(newValue);
+
+ // THEN
+ QCOMPARE(cameraLens.aspectRatio(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+ {
+ // WHEN
+ QSignalSpy spy(&cameraLens, SIGNAL(leftChanged(float)));
+ const float newValue = 0.0f;
+ cameraLens.setLeft(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(cameraLens.left(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ cameraLens.setLeft(newValue);
+
+ // THEN
+ QCOMPARE(cameraLens.left(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+ {
+ // WHEN
+ QSignalSpy spy(&cameraLens, SIGNAL(rightChanged(float)));
+ const float newValue = 1.0f;
+ cameraLens.setRight(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(cameraLens.right(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ cameraLens.setRight(newValue);
+
+ // THEN
+ QCOMPARE(cameraLens.right(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+ {
+ // WHEN
+ QSignalSpy spy(&cameraLens, SIGNAL(bottomChanged(float)));
+ const float newValue = 2.0f;
+ cameraLens.setBottom(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(cameraLens.bottom(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ cameraLens.setBottom(newValue);
+
+ // THEN
+ QCOMPARE(cameraLens.bottom(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+ {
+ // WHEN
+ QSignalSpy spy(&cameraLens, SIGNAL(topChanged(float)));
+ const float newValue = -2.0f;
+ cameraLens.setTop(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(cameraLens.top(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ cameraLens.setTop(newValue);
+
+ // THEN
+ QCOMPARE(cameraLens.top(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+ {
+ // WHEN
+ QSignalSpy spy(&cameraLens, SIGNAL(projectionMatrixChanged(QMatrix4x4)));
+ QMatrix4x4 newValue;
+ newValue.translate(5.0f, 2.0f, 4.3f);
+ cameraLens.setProjectionMatrix(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(cameraLens.projectionMatrix(), newValue);
+ QCOMPARE(cameraLens.projectionType(), Qt3DRender::QCameraLens::CustomProjection);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ cameraLens.setProjectionMatrix(newValue);
+
+ // THEN
+ QCOMPARE(cameraLens.projectionMatrix(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+ }
+
+ void checkSetOrthographicProjection()
+ {
+ // GIVEN
+ Qt3DRender::QCameraLens cameraLens;
+
+ {
+ // WHEN
+ QSignalSpy spy(&cameraLens, SIGNAL(projectionMatrixChanged(QMatrix4x4)));
+ cameraLens.setOrthographicProjection(-1.0f, 1.0f, -1.0f, 1.0f, 0.5f, 50.0f);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(spy.count(), 8); // Triggered for each property being set + 1
+ QCOMPARE(cameraLens.projectionType(), Qt3DRender::QCameraLens::OrthographicProjection);
+ QCOMPARE(cameraLens.nearPlane(), 0.5f);
+ QCOMPARE(cameraLens.farPlane(), 50.0f);
+ QCOMPARE(cameraLens.left(), -1.0f);
+ QCOMPARE(cameraLens.right(), 1.0f);
+ QCOMPARE(cameraLens.bottom(), -1.0f);
+ QCOMPARE(cameraLens.top(), 1.0f);
+ }
+ }
+
+ void checkSetPerspectiveProjection()
+ {
+ // GIVEN
+ Qt3DRender::QCameraLens cameraLens;
+
+ {
+ // WHEN
+ QSignalSpy spy(&cameraLens, SIGNAL(projectionMatrixChanged(QMatrix4x4)));
+ cameraLens.setPerspectiveProjection(20.0f, 16.0f / 9.0f, 0.5f, 50.0f);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(spy.count(), 5); // Triggered for each property being set (- projectionTye which is the default value) + 1
+ QCOMPARE(cameraLens.projectionType(), Qt3DRender::QCameraLens::PerspectiveProjection);
+ QCOMPARE(cameraLens.nearPlane(), 0.5f);
+ QCOMPARE(cameraLens.farPlane(), 50.0f);
+ QCOMPARE(cameraLens.fieldOfView(), 20.0f);
+ QCOMPARE(cameraLens.aspectRatio(), 16.0f / 9.0f);
+ }
+ }
+
+ void checkSetFrustumProjection()
+ {
+ // GIVEN
+ Qt3DRender::QCameraLens cameraLens;
+
+ {
+ // WHEN
+ QSignalSpy spy(&cameraLens, SIGNAL(projectionMatrixChanged(QMatrix4x4)));
+ cameraLens.setFrustumProjection(-1.0f, 1.0f, -1.0f, 1.0f, 0.5f, 50.0f);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(spy.count(), 8); // Triggered for each property being set + 1
+ QCOMPARE(cameraLens.projectionType(), Qt3DRender::QCameraLens::FrustumProjection);
+ QCOMPARE(cameraLens.nearPlane(), 0.5f);
+ QCOMPARE(cameraLens.farPlane(), 50.0f);
+ QCOMPARE(cameraLens.left(), -1.0f);
+ QCOMPARE(cameraLens.right(), 1.0f);
+ QCOMPARE(cameraLens.bottom(), -1.0f);
+ QCOMPARE(cameraLens.top(), 1.0f);
+ }
+ }
+
+ void checkCreationData()
+ {
+ // GIVEN
+ Qt3DRender::QCameraLens cameraLens;
+
+ cameraLens.setNearPlane(0.5);
+ cameraLens.setFarPlane(1005.0f);
+ cameraLens.setFieldOfView(35.0f);
+ cameraLens.setAspectRatio(16.0f/9.0f);
+
+ // WHEN
+ QVector<Qt3DCore::QNodeCreatedChangeBasePtr> creationChanges;
+
+ {
+ Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&cameraLens);
+ creationChanges = creationChangeGenerator.creationChanges();
+ }
+
+ // THEN
+ {
+ QCOMPARE(creationChanges.size(), 1);
+
+ const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DRender::QCameraLensData>>(creationChanges.first());
+ const Qt3DRender::QCameraLensData cloneData = creationChangeData->data;
+
+ QCOMPARE(cameraLens.projectionMatrix(), cloneData.projectionMatrix);
+ QCOMPARE(cameraLens.id(), creationChangeData->subjectId());
+ QCOMPARE(cameraLens.isEnabled(), true);
+ QCOMPARE(cameraLens.isEnabled(), creationChangeData->isNodeEnabled());
+ QCOMPARE(cameraLens.metaObject(), creationChangeData->metaObject());
+ }
+
+ // WHEN
+ cameraLens.setEnabled(false);
+
+ {
+ Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&cameraLens);
+ creationChanges = creationChangeGenerator.creationChanges();
+ }
+
+ // THEN
+ {
+ QCOMPARE(creationChanges.size(), 1);
+
+ const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DRender::QCameraLensData>>(creationChanges.first());
+ const Qt3DRender::QCameraLensData cloneData = creationChangeData->data;
+
+ QCOMPARE(cameraLens.projectionMatrix(), cloneData.projectionMatrix);
+ QCOMPARE(cameraLens.id(), creationChangeData->subjectId());
+ QCOMPARE(cameraLens.isEnabled(), false);
+ QCOMPARE(cameraLens.isEnabled(), creationChangeData->isNodeEnabled());
+ QCOMPARE(cameraLens.metaObject(), creationChangeData->metaObject());
+ }
+ }
+
+ void checkProjectionTypeUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QCameraLens cameraLens;
+ arbiter.setArbiterOnNode(&cameraLens);
+
+ {
+ // WHEN
+ cameraLens.setProjectionType(Qt3DRender::QCameraLens::FrustumProjection);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "projectionMatrix");
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ cameraLens.setProjectionType(Qt3DRender::QCameraLens::FrustumProjection);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
+ }
+
+ void checkNearPlaneUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QCameraLens cameraLens;
+ arbiter.setArbiterOnNode(&cameraLens);
+
+ {
+ // WHEN
+ cameraLens.setNearPlane(5.0f);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "projectionMatrix");
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ cameraLens.setNearPlane(5.0f);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
+ }
+
+ void checkFarPlaneUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QCameraLens cameraLens;
+ arbiter.setArbiterOnNode(&cameraLens);
+
+ {
+ // WHEN
+ cameraLens.setFarPlane(5.0f);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "projectionMatrix");
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ cameraLens.setFarPlane(5.0f);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
+ }
+
+ void checkFieldOfViewUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QCameraLens cameraLens;
+ arbiter.setArbiterOnNode(&cameraLens);
+
+ {
+ // WHEN
+ cameraLens.setFieldOfView(5.0f);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "projectionMatrix");
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ cameraLens.setFieldOfView(5.0f);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
+ }
+
+ void checkAspectRatioUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QCameraLens cameraLens;
+ arbiter.setArbiterOnNode(&cameraLens);
+
+ {
+ // WHEN
+ cameraLens.setAspectRatio(9.0f);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "projectionMatrix");
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ cameraLens.setAspectRatio(9.0f);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
+ }
+
+ void checkLeftUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QCameraLens cameraLens;
+ arbiter.setArbiterOnNode(&cameraLens);
+
+ {
+ // WHEN
+ cameraLens.setLeft(0.0f);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "projectionMatrix");
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ cameraLens.setLeft(0.0f);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
+ }
+
+ void checkRightUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QCameraLens cameraLens;
+ arbiter.setArbiterOnNode(&cameraLens);
+
+ {
+ // WHEN
+ cameraLens.setRight(24.0f);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "projectionMatrix");
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ cameraLens.setRight(24.0f);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
+ }
+
+ void checkBottomUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QCameraLens cameraLens;
+ arbiter.setArbiterOnNode(&cameraLens);
+
+ {
+ // WHEN
+ cameraLens.setBottom(-12.0f);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "projectionMatrix");
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ cameraLens.setBottom(-12.0f);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
+ }
+
+ void checkTopUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QCameraLens cameraLens;
+ arbiter.setArbiterOnNode(&cameraLens);
+
+ {
+ // WHEN
+ cameraLens.setTop(12.0f);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "projectionMatrix");
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ cameraLens.setTop(12.0f);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
+ }
+
+ void checkProjectionMatrixUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QCameraLens cameraLens;
+ arbiter.setArbiterOnNode(&cameraLens);
+
+ QMatrix4x4 m;
+ m.translate(-5.0f, 5.0f, 25.0f);
+
+ {
+ // WHEN
+ cameraLens.setProjectionMatrix(m);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "projectionMatrix");
+ QCOMPARE(change->value().value<QMatrix4x4>(), m);
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ cameraLens.setProjectionMatrix(m);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
+ }
+
+};
+
+QTEST_MAIN(tst_QCameraLens)
+
+#include "tst_qcameralens.moc"
diff --git a/tests/auto/render/qcomputecommand/qcomputecommand.pro b/tests/auto/render/qcomputecommand/qcomputecommand.pro
new file mode 100644
index 000000000..92c971c51
--- /dev/null
+++ b/tests/auto/render/qcomputecommand/qcomputecommand.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+
+TARGET = tst_qcomputecommand
+
+QT += 3dcore 3dcore-private 3drender 3drender-private testlib
+
+CONFIG += testcase
+
+SOURCES += tst_qcomputecommand.cpp
+
+include(../../core/common/common.pri)
+include(../commons/commons.pri)
diff --git a/tests/auto/render/qcomputecommand/tst_qcomputecommand.cpp b/tests/auto/render/qcomputecommand/tst_qcomputecommand.cpp
new file mode 100644
index 000000000..94609c129
--- /dev/null
+++ b/tests/auto/render/qcomputecommand/tst_qcomputecommand.cpp
@@ -0,0 +1,282 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Paul Lemire <paul.lemire350@gmail.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QTest>
+#include <Qt3DRender/qcomputecommand.h>
+#include <Qt3DRender/private/qcomputecommand_p.h>
+#include <QObject>
+#include <QSignalSpy>
+#include <Qt3DCore/qpropertyupdatedchange.h>
+#include <Qt3DCore/private/qnodecreatedchangegenerator_p.h>
+#include <Qt3DCore/qnodecreatedchange.h>
+#include "testpostmanarbiter.h"
+
+class tst_QComputeCommand : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+
+ void checkDefaultConstruction()
+ {
+ // GIVEN
+ Qt3DRender::QComputeCommand computeCommand;
+
+ // THEN
+ QCOMPARE(computeCommand.workGroupX(), 1);
+ QCOMPARE(computeCommand.workGroupY(), 1);
+ QCOMPARE(computeCommand.workGroupZ(), 1);
+ }
+
+ void checkPropertyChanges()
+ {
+ // GIVEN
+ Qt3DRender::QComputeCommand computeCommand;
+
+ {
+ // WHEN
+ QSignalSpy spy(&computeCommand, SIGNAL(workGroupXChanged()));
+ const int newValue = 128;
+ computeCommand.setWorkGroupX(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(computeCommand.workGroupX(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ computeCommand.setWorkGroupX(newValue);
+
+ // THEN
+ QCOMPARE(computeCommand.workGroupX(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+ {
+ // WHEN
+ QSignalSpy spy(&computeCommand, SIGNAL(workGroupYChanged()));
+ const int newValue = 256;
+ computeCommand.setWorkGroupY(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(computeCommand.workGroupY(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ computeCommand.setWorkGroupY(newValue);
+
+ // THEN
+ QCOMPARE(computeCommand.workGroupY(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+ {
+ // WHEN
+ QSignalSpy spy(&computeCommand, SIGNAL(workGroupZChanged()));
+ const int newValue = 512;
+ computeCommand.setWorkGroupZ(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(computeCommand.workGroupZ(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ computeCommand.setWorkGroupZ(newValue);
+
+ // THEN
+ QCOMPARE(computeCommand.workGroupZ(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+ }
+
+ void checkCreationData()
+ {
+ // GIVEN
+ Qt3DRender::QComputeCommand computeCommand;
+
+ computeCommand.setWorkGroupX(128);
+ computeCommand.setWorkGroupY(512);
+ computeCommand.setWorkGroupZ(1024);
+
+ // WHEN
+ QVector<Qt3DCore::QNodeCreatedChangeBasePtr> creationChanges;
+
+ {
+ Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&computeCommand);
+ creationChanges = creationChangeGenerator.creationChanges();
+ }
+
+ // THEN
+ {
+ QCOMPARE(creationChanges.size(), 1);
+
+ const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DRender::QComputeCommandData>>(creationChanges.first());
+ const Qt3DRender::QComputeCommandData cloneData = creationChangeData->data;
+
+ QCOMPARE(computeCommand.workGroupX(), cloneData.workGroupX);
+ QCOMPARE(computeCommand.workGroupY(), cloneData.workGroupY);
+ QCOMPARE(computeCommand.workGroupZ(), cloneData.workGroupZ);
+ QCOMPARE(computeCommand.id(), creationChangeData->subjectId());
+ QCOMPARE(computeCommand.isEnabled(), true);
+ QCOMPARE(computeCommand.isEnabled(), creationChangeData->isNodeEnabled());
+ QCOMPARE(computeCommand.metaObject(), creationChangeData->metaObject());
+ }
+
+ // WHEN
+ computeCommand.setEnabled(false);
+
+ {
+ Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&computeCommand);
+ creationChanges = creationChangeGenerator.creationChanges();
+ }
+
+ // THEN
+ {
+ QCOMPARE(creationChanges.size(), 1);
+
+ const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DRender::QComputeCommandData>>(creationChanges.first());
+ const Qt3DRender::QComputeCommandData cloneData = creationChangeData->data;
+
+ QCOMPARE(computeCommand.workGroupX(), cloneData.workGroupX);
+ QCOMPARE(computeCommand.workGroupY(), cloneData.workGroupY);
+ QCOMPARE(computeCommand.workGroupZ(), cloneData.workGroupZ);
+ QCOMPARE(computeCommand.id(), creationChangeData->subjectId());
+ QCOMPARE(computeCommand.isEnabled(), false);
+ QCOMPARE(computeCommand.isEnabled(), creationChangeData->isNodeEnabled());
+ QCOMPARE(computeCommand.metaObject(), creationChangeData->metaObject());
+ }
+ }
+
+ void checkWorkGroupXUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QComputeCommand computeCommand;
+ arbiter.setArbiterOnNode(&computeCommand);
+
+ {
+ // WHEN
+ computeCommand.setWorkGroupX(256);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "workGroupX");
+ QCOMPARE(change->value().value<int>(), computeCommand.workGroupX());
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ computeCommand.setWorkGroupX(256);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
+ }
+
+ void checkWorkGroupYUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QComputeCommand computeCommand;
+ arbiter.setArbiterOnNode(&computeCommand);
+
+ {
+ // WHEN
+ computeCommand.setWorkGroupY(512);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "workGroupY");
+ QCOMPARE(change->value().value<int>(), computeCommand.workGroupY());
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ computeCommand.setWorkGroupY(512);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
+ }
+
+ void checkWorkGroupZUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QComputeCommand computeCommand;
+ arbiter.setArbiterOnNode(&computeCommand);
+
+ {
+ // WHEN
+ computeCommand.setWorkGroupZ(64);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "workGroupZ");
+ QCOMPARE(change->value().value<int>(), computeCommand.workGroupZ());
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ computeCommand.setWorkGroupZ(64);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
+ }
+
+};
+
+QTEST_MAIN(tst_QComputeCommand)
+
+#include "tst_qcomputecommand.moc"
diff --git a/tests/auto/render/qrendertargetoutput/qrendertargetoutput.pro b/tests/auto/render/qrendertargetoutput/qrendertargetoutput.pro
new file mode 100644
index 000000000..e42f4fc22
--- /dev/null
+++ b/tests/auto/render/qrendertargetoutput/qrendertargetoutput.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+
+TARGET = tst_qrendertargetoutput
+
+QT += 3dcore 3dcore-private 3drender 3drender-private testlib
+
+CONFIG += testcase
+
+SOURCES += tst_qrendertargetoutput.cpp
+
+include(../../core/common/common.pri)
+include(../commons/commons.pri)
diff --git a/tests/auto/render/qrendertargetoutput/tst_qrendertargetoutput.cpp b/tests/auto/render/qrendertargetoutput/tst_qrendertargetoutput.cpp
new file mode 100644
index 000000000..c847095dc
--- /dev/null
+++ b/tests/auto/render/qrendertargetoutput/tst_qrendertargetoutput.cpp
@@ -0,0 +1,407 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Paul Lemire <paul.lemire350@gmail.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QTest>
+#include <QObject>
+#include <QMetaObject>
+#include <Qt3DRender/qrendertargetoutput.h>
+#include <Qt3DRender/private/qrendertargetoutput_p.h>
+#include <Qt3DRender/qabstracttexture.h>
+#include <Qt3DRender/qtexture.h>
+#include <QSignalSpy>
+#include <Qt3DCore/qpropertyupdatedchange.h>
+#include <Qt3DCore/private/qnodecreatedchangegenerator_p.h>
+#include <Qt3DCore/qnodecreatedchange.h>
+#include "testpostmanarbiter.h"
+
+class tst_QRenderTargetOutput : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+
+ void initTestCase()
+ {
+ qRegisterMetaType<Qt3DRender::QRenderTargetOutput::AttachmentPoint>("AttachmentPoint");
+ qRegisterMetaType<Qt3DRender::QAbstractTexture::CubeMapFace>("QAbstractTexture::CubeMapFace");
+ }
+
+ void checkDefaultConstruction()
+ {
+ // GIVEN
+ Qt3DRender::QRenderTargetOutput renderTargetOutput;
+
+ // THEN
+ QCOMPARE(renderTargetOutput.attachmentPoint(), Qt3DRender::QRenderTargetOutput::Color0);
+ QVERIFY(renderTargetOutput.texture() == nullptr);
+ QCOMPARE(renderTargetOutput.mipLevel(), 0);
+ QCOMPARE(renderTargetOutput.layer(), 0);
+ QCOMPARE(renderTargetOutput.face(), Qt3DRender::QAbstractTexture::CubeMapNegativeX);
+ }
+
+ void checkPropertyChanges()
+ {
+ // GIVEN
+ Qt3DRender::QRenderTargetOutput renderTargetOutput;
+
+ {
+ // WHEN
+ QSignalSpy spy(&renderTargetOutput, SIGNAL(attachmentPointChanged(AttachmentPoint)));
+ const Qt3DRender::QRenderTargetOutput::AttachmentPoint newValue = Qt3DRender::QRenderTargetOutput::Color15;
+ renderTargetOutput.setAttachmentPoint(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(renderTargetOutput.attachmentPoint(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ renderTargetOutput.setAttachmentPoint(newValue);
+
+ // THEN
+ QCOMPARE(renderTargetOutput.attachmentPoint(), newValue);
+ QCOMPARE(spy.count(), 0);
+
+ }
+ {
+ // WHEN
+ QSignalSpy spy(&renderTargetOutput, SIGNAL(textureChanged(QAbstractTexture *)));
+ Qt3DRender::QTexture3D newValue;
+ renderTargetOutput.setTexture(&newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(renderTargetOutput.texture(), &newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ renderTargetOutput.setTexture(&newValue);
+
+ // THEN
+ QCOMPARE(renderTargetOutput.texture(), &newValue);
+ QCOMPARE(spy.count(), 0);
+
+ }
+ {
+ // WHEN
+ QSignalSpy spy(&renderTargetOutput, SIGNAL(mipLevelChanged(int)));
+ const int newValue = 5;
+ renderTargetOutput.setMipLevel(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(renderTargetOutput.mipLevel(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ renderTargetOutput.setMipLevel(newValue);
+
+ // THEN
+ QCOMPARE(renderTargetOutput.mipLevel(), newValue);
+ QCOMPARE(spy.count(), 0);
+
+ }
+ {
+ // WHEN
+ QSignalSpy spy(&renderTargetOutput, SIGNAL(layerChanged(int)));
+ const int newValue = 300;
+ renderTargetOutput.setLayer(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(renderTargetOutput.layer(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ renderTargetOutput.setLayer(newValue);
+
+ // THEN
+ QCOMPARE(renderTargetOutput.layer(), newValue);
+ QCOMPARE(spy.count(), 0);
+
+ }
+ {
+ // WHEN
+ QSignalSpy spy(&renderTargetOutput, SIGNAL(faceChanged(QAbstractTexture::CubeMapFace)));
+ const Qt3DRender::QAbstractTexture::CubeMapFace newValue = Qt3DRender::QAbstractTexture::CubeMapNegativeZ;
+ renderTargetOutput.setFace(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(renderTargetOutput.face(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ renderTargetOutput.setFace(newValue);
+
+ // THEN
+ QCOMPARE(renderTargetOutput.face(), newValue);
+ QCOMPARE(spy.count(), 0);
+
+ }
+ }
+
+ void checkCreationData()
+ {
+ // GIVEN
+ Qt3DRender::QRenderTargetOutput renderTargetOutput;
+
+ renderTargetOutput.setAttachmentPoint(Qt3DRender::QRenderTargetOutput::Color5);
+ renderTargetOutput.setMipLevel(10);
+ renderTargetOutput.setLayer(2);
+ renderTargetOutput.setFace(Qt3DRender::QAbstractTexture::CubeMapNegativeY);
+
+ // WHEN
+ QVector<Qt3DCore::QNodeCreatedChangeBasePtr> creationChanges;
+
+ {
+ Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&renderTargetOutput);
+ creationChanges = creationChangeGenerator.creationChanges();
+ }
+
+ // THEN
+ {
+ QCOMPARE(creationChanges.size(), 1);
+
+ const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DRender::QRenderTargetOutputData>>(creationChanges.first());
+ const Qt3DRender::QRenderTargetOutputData cloneData = creationChangeData->data;
+
+ QCOMPARE(renderTargetOutput.attachmentPoint(), cloneData.attachmentPoint);
+ QCOMPARE(Qt3DCore::QNodeId(), cloneData.textureId);
+ QCOMPARE(renderTargetOutput.mipLevel(), cloneData.mipLevel);
+ QCOMPARE(renderTargetOutput.layer(), cloneData.layer);
+ QCOMPARE(renderTargetOutput.face(), cloneData.face);
+ QCOMPARE(renderTargetOutput.id(), creationChangeData->subjectId());
+ QCOMPARE(renderTargetOutput.isEnabled(), true);
+ QCOMPARE(renderTargetOutput.isEnabled(), creationChangeData->isNodeEnabled());
+ QCOMPARE(renderTargetOutput.metaObject(), creationChangeData->metaObject());
+ }
+
+ // WHEN
+ renderTargetOutput.setEnabled(false);
+
+ {
+ Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&renderTargetOutput);
+ creationChanges = creationChangeGenerator.creationChanges();
+ }
+
+ // THEN
+ {
+ QCOMPARE(creationChanges.size(), 1);
+
+ const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DRender::QRenderTargetOutputData>>(creationChanges.first());
+ const Qt3DRender::QRenderTargetOutputData cloneData = creationChangeData->data;
+
+ QCOMPARE(renderTargetOutput.attachmentPoint(), cloneData.attachmentPoint);
+ QCOMPARE(Qt3DCore::QNodeId(), cloneData.textureId);
+ QCOMPARE(renderTargetOutput.mipLevel(), cloneData.mipLevel);
+ QCOMPARE(renderTargetOutput.layer(), cloneData.layer);
+ QCOMPARE(renderTargetOutput.face(), cloneData.face);
+ QCOMPARE(renderTargetOutput.id(), creationChangeData->subjectId());
+ QCOMPARE(renderTargetOutput.isEnabled(), false);
+ QCOMPARE(renderTargetOutput.isEnabled(), creationChangeData->isNodeEnabled());
+ QCOMPARE(renderTargetOutput.metaObject(), creationChangeData->metaObject());
+ }
+ }
+
+ void checkAttachmentPointUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QRenderTargetOutput renderTargetOutput;
+ arbiter.setArbiterOnNode(&renderTargetOutput);
+
+ {
+ // WHEN
+ renderTargetOutput.setAttachmentPoint(Qt3DRender::QRenderTargetOutput::Color1);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "attachmentPoint");
+ QCOMPARE(change->value().value<Qt3DRender::QRenderTargetOutput::AttachmentPoint>(), renderTargetOutput.attachmentPoint());
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ renderTargetOutput.setAttachmentPoint(Qt3DRender::QRenderTargetOutput::Color1);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
+ }
+
+ void checkTextureUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QRenderTargetOutput renderTargetOutput;
+ Qt3DRender::QTexture3D texture;
+ arbiter.setArbiterOnNode(&renderTargetOutput);
+
+ {
+ // WHEN
+ renderTargetOutput.setTexture(&texture);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "texture");
+ QCOMPARE(change->value().value<Qt3DCore::QNodeId>(), renderTargetOutput.texture()->id());
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ renderTargetOutput.setTexture(&texture);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
+ }
+
+ void checkMipLevelUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QRenderTargetOutput renderTargetOutput;
+ arbiter.setArbiterOnNode(&renderTargetOutput);
+
+ {
+ // WHEN
+ renderTargetOutput.setMipLevel(6);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "mipLevel");
+ QCOMPARE(change->value().value<int>(), renderTargetOutput.mipLevel());
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ renderTargetOutput.setMipLevel(6);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
+ }
+
+ void checkLayerUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QRenderTargetOutput renderTargetOutput;
+ arbiter.setArbiterOnNode(&renderTargetOutput);
+
+ {
+ // WHEN
+ renderTargetOutput.setLayer(8);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "layer");
+ QCOMPARE(change->value().value<int>(), renderTargetOutput.layer());
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ renderTargetOutput.setLayer(8);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
+ }
+
+ void checkFaceUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QRenderTargetOutput renderTargetOutput;
+ arbiter.setArbiterOnNode(&renderTargetOutput);
+
+ {
+ // WHEN
+ renderTargetOutput.setFace(Qt3DRender::QAbstractTexture::CubeMapPositiveY);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "face");
+ QCOMPARE(change->value().value<Qt3DRender::QAbstractTexture::CubeMapFace>(), renderTargetOutput.face());
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ renderTargetOutput.setFace(Qt3DRender::QAbstractTexture::CubeMapPositiveY);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
+ }
+
+};
+
+QTEST_MAIN(tst_QRenderTargetOutput)
+
+#include "tst_qrendertargetoutput.moc"
diff --git a/tests/auto/render/qsceneloader/tst_qsceneloader.cpp b/tests/auto/render/qsceneloader/tst_qsceneloader.cpp
index 1d434f5d3..dd3babb06 100644
--- a/tests/auto/render/qsceneloader/tst_qsceneloader.cpp
+++ b/tests/auto/render/qsceneloader/tst_qsceneloader.cpp
@@ -27,12 +27,15 @@
****************************************************************************/
#include <QtTest/QTest>
+#include <Qt3DCore/qentity.h>
#include <Qt3DCore/private/qnode_p.h>
#include <Qt3DCore/private/qscene_p.h>
#include <Qt3DCore/private/qnodecreatedchangegenerator_p.h>
+#include <Qt3DCore/QPropertyUpdatedChange>
#include <Qt3DRender/qsceneloader.h>
#include <Qt3DRender/private/qsceneloader_p.h>
+#include <QSignalSpy>
#include "testpostmanarbiter.h"
@@ -42,6 +45,17 @@ class tst_QSceneLoader: public QObject
private Q_SLOTS:
+ void checkInitialState()
+ {
+ // GIVEN
+ Qt3DRender::QSceneLoader sceneLoader;
+
+ // THEN
+ QCOMPARE(sceneLoader.status(), Qt3DRender::QSceneLoader::None);
+ QVERIFY(sceneLoader.source().isEmpty());
+ QVERIFY(static_cast<Qt3DRender::QSceneLoaderPrivate *>(Qt3DCore::QNodePrivate::get(&sceneLoader))->m_subTreeRoot == nullptr);
+ }
+
void checkCreationData()
{
// GIVEN
@@ -98,7 +112,7 @@ private Q_SLOTS:
}
}
- void checkPropertyUpdates()
+ void checkSourcePropertyUpdate()
{
// GIVEN
TestArbiter arbiter;
@@ -118,6 +132,58 @@ private Q_SLOTS:
arbiter.events.clear();
}
+
+ void checkStatusPropertyUpdate()
+ {
+ // GIVEN
+ qRegisterMetaType<Qt3DRender::QSceneLoader::Status>("Status");
+ TestArbiter arbiter;
+ QScopedPointer<Qt3DRender::QSceneLoader> sceneLoader(new Qt3DRender::QSceneLoader());
+ arbiter.setArbiterOnNode(sceneLoader.data());
+ QSignalSpy spy(sceneLoader.data(), SIGNAL(statusChanged(Status)));
+
+
+ // WHEN
+ const Qt3DRender::QSceneLoader::Status newStatus = Qt3DRender::QSceneLoader::Ready;
+ sceneLoader->setStatus(newStatus);
+
+ // THEN
+ QVERIFY(arbiter.events.empty());
+ QCOMPARE(spy.count(), 1);
+
+ spy.clear();
+ }
+
+ void checkPropertyChanges()
+ {
+ // GIVEN
+ Qt3DCore::QScene scene;
+ Qt3DCore::QEntity rootEntity;
+ QScopedPointer<Qt3DRender::QSceneLoader> sceneLoader(new Qt3DRender::QSceneLoader());
+ Qt3DCore::QNodePrivate::get(&rootEntity)->setScene(&scene);
+ Qt3DCore::QNodePrivate::get(sceneLoader.data())->setScene(&scene);
+ rootEntity.addComponent(sceneLoader.data());
+
+ // WHEN
+ Qt3DCore::QEntity backendCreatedSubtree;
+ Qt3DCore::QPropertyUpdatedChangePtr valueChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ valueChange->setPropertyName("scene");
+ valueChange->setValue(QVariant::fromValue(&backendCreatedSubtree));
+ sceneLoader->sceneChangeEvent(valueChange);
+
+ // THEN
+ QCOMPARE(static_cast<Qt3DRender::QSceneLoaderPrivate *>(Qt3DCore::QNodePrivate::get(sceneLoader.data()))->m_subTreeRoot, &backendCreatedSubtree);
+
+ // WHEN
+ const Qt3DRender::QSceneLoader::Status newStatus = Qt3DRender::QSceneLoader::Ready;
+ valueChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ valueChange->setPropertyName("status");
+ valueChange->setValue(QVariant::fromValue(newStatus));
+ sceneLoader->sceneChangeEvent(valueChange);
+
+ // THEN
+ QCOMPARE(sceneLoader->status(), newStatus);
+ }
};
QTEST_MAIN(tst_QSceneLoader)
diff --git a/tests/auto/render/render.pro b/tests/auto/render/render.pro
index 7f62f609c..36eda8afb 100644
--- a/tests/auto/render/render.pro
+++ b/tests/auto/render/render.pro
@@ -53,7 +53,9 @@ qtConfig(private_tests) {
qgraphicsapifilter \
qrendersurfaceselector \
sortpolicy \
- qcuboidgeometry \
sceneloader \
- qsceneloader
+ qsceneloader \
+ qrendertargetoutput \
+ qcameralens \
+ qcomputecommand
}
diff --git a/tests/auto/render/sceneloader/tst_sceneloader.cpp b/tests/auto/render/sceneloader/tst_sceneloader.cpp
index 7d31590d9..05f4f08b6 100644
--- a/tests/auto/render/sceneloader/tst_sceneloader.cpp
+++ b/tests/auto/render/sceneloader/tst_sceneloader.cpp
@@ -149,6 +149,28 @@ private Q_SLOTS:
arbiter.events.clear();
}
+
+ void checkStatusTransmission()
+ {
+ // GIVEN
+ TestRenderer renderer;
+ TestArbiter arbiter;
+ Qt3DRender::Render::Scene sceneLoader;
+
+ Qt3DCore::QBackendNodePrivate::get(&sceneLoader)->setArbiter(&arbiter);
+ sceneLoader.setRenderer(&renderer);
+
+ // WHEN
+ sceneLoader.setStatus(Qt3DRender::QSceneLoader::Ready);
+
+ // THEN
+ Qt3DCore::QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(arbiter.events.count(), 1);
+ QCOMPARE(change->propertyName(), "status");
+ QCOMPARE(change->value().value<Qt3DRender::QSceneLoader::Status>(), Qt3DRender::QSceneLoader::Ready);
+
+ arbiter.events.clear();
+ }
};
// Note: setSceneSubtree needs a QCoreApplication