Skip to content

Commit db51d90

Browse files
Quincunx271paceholder
authored andcommitted
Implement automated tests (paceholder#177)
* add basic test support * fix travis.yml * fix-travis-osx * fix .appveyor.yml * Added some dragging tests * remove failing test * Improve naming, reuse of code * fix bug
1 parent f587e98 commit db51d90

File tree

10 files changed

+316
-10
lines changed

10 files changed

+316
-10
lines changed

.appveyor.yml

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,20 @@ clone_depth: 5
22

33
environment:
44
matrix:
5-
- GENERATOR : "MinGW Makefiles"
6-
QTDIR: C:\Qt\5.6\mingw49_32
7-
PLATFORM: x86
85
- GENERATOR : "Visual Studio 14 2015 Win64"
96
QTDIR: C:\Qt\5.6.3\msvc2015_64
107
PLATFORM: x64
8+
BUILD_TESTING: ON
119
- GENERATOR : "Visual Studio 14 2015"
1210
QTDIR: C:\Qt\5.6.3\msvc2015
1311
PLATFORM: Win32
12+
BUILD_TESTING: ON
13+
- GENERATOR : "MinGW Makefiles"
14+
QTDIR: C:\Qt\5.6\mingw49_32
15+
PLATFORM: x86
16+
BUILD_TESTING: OFF
17+
18+
image: Visual Studio 2015
1419

1520
configuration:
1621
- Release
@@ -21,20 +26,44 @@ image: Visual Studio 2015
2126
#only:
2227
#- master
2328

24-
before_build:
25-
- mkdir build
26-
- cd build
29+
install:
2730
- set PATH=%QTDIR%\bin;%PATH%
31+
- set Qt5_DIR=%QTDIR%\lib\cmake\Qt5
2832
- set PATH=C:\MinGW\bin;C:\MinGW\msys\1.0;%PATH%
2933
- set PATH=%PATH:C:\Program Files\Git\usr\bin=% # trick to remove sh.exe
30-
- cmake "-G%GENERATOR%" -DCMAKE_PREFIX_PATH="%QTDIR/lib/cmake/Qt5" ..
34+
- mkdir dependencies
35+
- cd dependencies
36+
- mkdir install
37+
- set CMAKE_INSTALL_PREFIX=%cd%\install
38+
- set DEPENDENCIES=%cd%\install
39+
- git clone https://github.com/catchorg/Catch2.git
40+
- cd Catch2
41+
- mkdir build
42+
- cd build
43+
- cmake "-G%GENERATOR%" -DBUILD_TESTING=OFF ..
44+
- cmake --build . --target install
45+
- set Catch2_DIR=%DEPENDENCIES=%cd%\install\lib\cmake\Catch2
46+
- cd ..
47+
- cd ..
48+
- cd ..
49+
50+
before_build:
51+
- mkdir build
52+
- cd build
53+
- mkdir bin
54+
- set OUTPUT_DIR=%cd%\bin
55+
- echo %BUILD_TESTING%
56+
- cmake "-G%GENERATOR%" -DBUILD_TESTING=%BUILD_TESTING%
57+
-DCMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG="%OUTPUT_DIR%"
58+
-DCMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE="%OUTPUT_DIR%"
59+
..
3160

3261

3362
build_script:
34-
- if "%PLATFORM%" == "x86" cmake --build .
35-
- if "%PLATFORM%" == "x64" msbuild NodeEditor.sln
36-
- if "%PLATFORM%" == "Win32" msbuild NodeEditor.sln
63+
- cmake --build .
3764

65+
test_script:
66+
- if "%BUILD_TESTING%" == "ON" .\bin\test_nodes.exe
3867

3968

4069
after_build:

.travis.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,27 @@ before_install:
4343
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install build-essential libgl1-mesa-dev ; fi
4444
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get -yy install qtbase5-dev ; fi
4545

46+
install:
47+
- DEPS_DIR="${TRAVIS_BUILD_DIR}/deps"
48+
- |
49+
mkdir -p ${DEPS_DIR}
50+
pushd ${DEPS_DIR}
51+
- travis_retry git clone https://github.com/catchorg/Catch2.git # Install Catch2
52+
- |
53+
pushd Catch2
54+
git checkout tags/v2.2.2
55+
mkdir build && cd build
56+
- cmake .. -DBUILD_TESTING=OFF -DCMAKE_INSTALL_PREFIX="${DEPS_DIR}/install"
57+
- cmake --build . -- install
58+
- export CMAKE_PREFIX_PATH="${DEPS_DIR}/install/:$CMAKE_PREFIX_PATH"
59+
- popd; popd
4660

4761
script:
4862
- mkdir build
4963
- cd build
5064
- cmake -DCMAKE_VERBOSE_MAKEFILE=$VERBOSE_BUILD .. && make -j
65+
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then xvfb-run --server-args="-screen 0 1024x768x24" ./test/test_nodes; fi
66+
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ./test/test_nodes; fi
5167

5268
notifications:
5369
email: false

CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ project(NodeEditor CXX)
66
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
77
set(CMAKE_DISABLE_SOURCE_CHANGES ON)
88

9+
include(CTest)
10+
911
option(BUILD_EXAMPLES "Build Examples" ON)
1012

1113
# Find the QtWidgets library
@@ -52,6 +54,7 @@ add_library(nodes SHARED
5254
${CPP_SOURCE_FILES}
5355
${RESOURCES}
5456
)
57+
add_library(NodeEditor::nodes ALIAS nodes)
5558

5659
target_include_directories(nodes
5760
PUBLIC
@@ -120,6 +123,14 @@ if(BUILD_EXAMPLES)
120123
add_subdirectory(examples)
121124
endif()
122125

126+
##################
127+
# Automated Tests
128+
##
129+
130+
if(BUILD_TESTING)
131+
add_subdirectory(test)
132+
endif()
133+
123134
###############
124135
# Installation
125136
##

test/CMakeLists.txt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
find_package(Catch2 REQUIRED)
2+
find_package(Qt5 COMPONENTS Test)
3+
4+
add_executable(test_nodes
5+
test_main.cpp
6+
src/test_dragging.cpp
7+
src/TestDataModelRegistry.cpp
8+
)
9+
10+
target_include_directories(test_nodes
11+
PRIVATE
12+
../src
13+
../include/internal
14+
include
15+
)
16+
17+
target_link_libraries(test_nodes
18+
PRIVATE
19+
NodeEditor::nodes
20+
Catch2::Catch
21+
Qt5::Test
22+
)
23+
24+
add_test(test_nodes test_nodes)

test/include/ApplicationSetup.hpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#pragma once
2+
3+
#include <memory>
4+
5+
#include <QApplication>
6+
7+
8+
inline std::unique_ptr<QApplication>
9+
applicationSetup()
10+
{
11+
static int Argc = 0;
12+
static char ArgvVal = '\0';
13+
static char* ArgvValPtr = &ArgvVal;
14+
static char** Argv = &ArgvValPtr;
15+
16+
auto app = std::make_unique<QApplication>(Argc, Argv);
17+
app->setAttribute(Qt::AA_Use96Dpi, true);
18+
19+
return app;
20+
}

test/include/Stringify.hpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#pragma once
2+
3+
#include <QtCore/QPoint>
4+
#include <QtCore/QPointF>
5+
6+
#include <catch.hpp>
7+
8+
#include <QtTest>
9+
10+
namespace Catch
11+
{
12+
template <>
13+
struct StringMaker<QPointF>
14+
{
15+
static std::string
16+
convert(QPointF const& p)
17+
{
18+
return std::string(QTest::toString(p));
19+
}
20+
};
21+
22+
template <>
23+
struct StringMaker<QPoint>
24+
{
25+
static std::string
26+
convert(QPoint const& p)
27+
{
28+
return std::string(QTest::toString(p));
29+
}
30+
};
31+
}

test/include/StubNodeDataModel.hpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#pragma once
2+
3+
#include <utility>
4+
5+
#include <nodes/NodeDataModel>
6+
7+
class StubNodeDataModel : public QtNodes::NodeDataModel
8+
{
9+
public:
10+
QString
11+
name() const override
12+
{
13+
return _name;
14+
}
15+
16+
QString
17+
caption() const override
18+
{
19+
return _caption;
20+
}
21+
22+
unsigned int nPorts(QtNodes::PortType) const override { return 0; }
23+
24+
QWidget*
25+
embeddedWidget() override
26+
{
27+
return nullptr;
28+
}
29+
30+
QtNodes::NodeDataType dataType(QtNodes::PortType, QtNodes::PortIndex) const override
31+
{
32+
return QtNodes::NodeDataType();
33+
}
34+
35+
std::shared_ptr<QtNodes::NodeData> outData(QtNodes::PortIndex) override
36+
{
37+
return nullptr;
38+
}
39+
40+
void setInData(std::shared_ptr<QtNodes::NodeData>, QtNodes::PortIndex) override
41+
{
42+
}
43+
44+
void
45+
name(QString name)
46+
{
47+
_name = std::move(name);
48+
}
49+
50+
void
51+
caption(QString caption)
52+
{
53+
_caption = std::move(caption);
54+
}
55+
56+
private:
57+
QString _name = "name";
58+
QString _caption = "caption";
59+
};

test/src/TestDataModelRegistry.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#include <nodes/DataModelRegistry>
2+
3+
#include <catch.hpp>
4+
5+
#include "StubNodeDataModel.hpp"
6+
7+
using QtNodes::DataModelRegistry;
8+
using QtNodes::NodeData;
9+
using QtNodes::NodeDataModel;
10+
using QtNodes::NodeDataType;
11+
using QtNodes::PortIndex;
12+
using QtNodes::PortType;
13+
14+
namespace
15+
{
16+
class StubModelStaticName : public StubNodeDataModel
17+
{
18+
public:
19+
static QString
20+
Name()
21+
{
22+
return "Name";
23+
}
24+
};
25+
}
26+
27+
TEST_CASE("DataModelRegistry::registerModel", "[interface]")
28+
{
29+
DataModelRegistry registry;
30+
31+
SECTION("stub model")
32+
{
33+
registry.registerModel<StubNodeDataModel>();
34+
auto model = registry.create("name");
35+
36+
CHECK(model->name() == "name");
37+
}
38+
SECTION("stub model with static name")
39+
{
40+
registry.registerModel<StubModelStaticName>();
41+
auto model = registry.create("Name");
42+
43+
CHECK(model->name() == "name");
44+
}
45+
}

test/src/test_dragging.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#include <nodes/Connection>
2+
#include <nodes/FlowScene>
3+
#include <nodes/FlowView>
4+
#include <nodes/Node>
5+
6+
#include <catch.hpp>
7+
8+
#include <QtTest>
9+
#include <QtWidgets/QApplication>
10+
11+
#include <iostream>
12+
13+
#include "ApplicationSetup.hpp"
14+
#include "Stringify.hpp"
15+
#include "StubNodeDataModel.hpp"
16+
17+
using QtNodes::Connection;
18+
using QtNodes::DataModelRegistry;
19+
using QtNodes::FlowScene;
20+
using QtNodes::FlowView;
21+
using QtNodes::Node;
22+
using QtNodes::NodeData;
23+
using QtNodes::NodeDataModel;
24+
using QtNodes::NodeDataType;
25+
using QtNodes::PortIndex;
26+
using QtNodes::PortType;
27+
28+
TEST_CASE("Dragging node changes position", "[gui]")
29+
{
30+
auto app = applicationSetup();
31+
32+
FlowScene scene;
33+
FlowView view(&scene);
34+
35+
view.show();
36+
REQUIRE(QTest::qWaitForWindowExposed(&view));
37+
38+
SECTION("just one node")
39+
{
40+
auto& node = scene.createNode(std::make_unique<StubNodeDataModel>());
41+
42+
auto& ngo = node.nodeGraphicsObject();
43+
44+
QPointF scPosBefore = ngo.pos();
45+
46+
QPointF scClickPos = ngo.boundingRect().center();
47+
scClickPos = QPointF(ngo.sceneTransform().map(scClickPos).toPoint());
48+
49+
QPoint vwClickPos = view.mapFromScene(scClickPos);
50+
QPoint vwDestPos = vwClickPos + QPoint(10, 20);
51+
52+
QPointF scExpectedDelta = view.mapToScene(vwDestPos) - scClickPos;
53+
54+
CAPTURE(scClickPos);
55+
CAPTURE(vwClickPos);
56+
CAPTURE(vwDestPos);
57+
CAPTURE(scExpectedDelta);
58+
59+
QTest::mouseMove(view.windowHandle(), vwClickPos);
60+
QTest::mousePress(view.windowHandle(), Qt::LeftButton, Qt::NoModifier, vwClickPos);
61+
QTest::mouseMove(view.windowHandle(), vwDestPos);
62+
63+
QPointF scDelta = ngo.pos() - scPosBefore;
64+
QPoint roundDelta = scDelta.toPoint();
65+
QPoint roundExpectedDelta = scExpectedDelta.toPoint();
66+
67+
CHECK(roundDelta == roundExpectedDelta);
68+
}
69+
}

test/test_main.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#define CATCH_CONFIG_MAIN
2+
#include <catch.hpp>

0 commit comments

Comments
 (0)