diff options
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | CMakeLists.txt | 21 | ||||
| -rw-r--r-- | Makefile | 7 | ||||
| -rw-r--r-- | include/CommandInput.hpp | 12 | ||||
| -rw-r--r-- | spec/CommandInputSpec.cpp | 71 | ||||
| -rw-r--r-- | spec/TestUtils.h | 20 | ||||
| -rw-r--r-- | src/CommandInput.cpp | 14 |
7 files changed, 121 insertions, 25 deletions
@@ -1,3 +1,4 @@ build/ .cache/ compile_commands.json +Testing/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a2c531..94365c0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,21 +8,23 @@ project(${PROJECT} set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(AUTOMOC ON) find_package(PkgConfig REQUIRED) -file(GLOB_RECURSE HEADER_FILES include/*.hpp) file(GLOB_RECURSE SOURCE_FILES src/*.cpp) +list(FILTER SOURCE_FILES EXCLUDE REGEX "src/main.cpp$") +file(GLOB_RECURSE HEADER_FILES include/*.hpp) +file(GLOB_RECURSE SPEC_FILES spec/*.cpp) add_executable(${PROJECT}) -target_sources(${PROJECT} PRIVATE ${SOURCE_FILES}) +target_sources(${PROJECT} PRIVATE src/main.cpp ${SOURCE_FILES}) target_include_directories(${PROJECT} PRIVATE include/) # Qt -find_package(Qt6 REQUIRED COMPONENTS Core Widgets WebEngineWidgets) +find_package(Qt6 REQUIRED COMPONENTS Core Widgets WebEngineWidgets Test) qt_standard_project_setup() qt_wrap_cpp(MOC_SRCS ${HEADER_FILES}) target_sources(${PROJECT} PRIVATE ${MOC_SRCS}) -set_target_properties(${PROJECT} PROPERTIES AUTOMOC ON) target_link_libraries(${PROJECT} Qt6::Core Qt6::Widgets @@ -40,4 +42,15 @@ target_link_libraries(${PROJECT} ${LuaJIT_LINK_LIBRARIES}) # include_directories(${CEF_PACKAGE_PATH} ${CEF_PACKAGE_PATH}/include) # link_directories(${CEF_PACKAGE_PATH}/lib) +enable_testing() +add_executable(tests) +target_sources(tests PRIVATE ${SOURCE_FILES} ${MOC_SRCS} ${SPEC_FILES}) +target_include_directories(tests PRIVATE include/ spec/) +target_link_libraries(tests PRIVATE + Qt6::Core + Qt6::Widgets + Qt6::WebEngineWidgets + Qt6::Test) +add_test(NAME CommandInputSpec COMMAND tests) + install(TARGETS ${PROJECT} RUNTIME DESTINATION bin) @@ -1,4 +1,4 @@ -.PHONY: clean build +.PHONY: clean build test all: build @@ -9,11 +9,14 @@ build: # cp --no-preserve=mode,ownership -r ${CEF_PACKAGE_PATH}/share/cef/* ./build/lib/ cp build/compile_commands.json . +test: build + cd build && ctest -V + clean: rm -rf build/ rm -f compile_commands.json -run: +run: build ./build/web-browser # -DCMAKE_BUILD_TYPE=Release diff --git a/include/CommandInput.hpp b/include/CommandInput.hpp index e6dc53d..5cebcd1 100644 --- a/include/CommandInput.hpp +++ b/include/CommandInput.hpp @@ -1,17 +1,8 @@ #pragma once -#include <QApplication> -#include <QDialog> +#include <QBoxLayout> #include <QKeyEvent> -#include <QLabel> #include <QLineEdit> -#include <QObject> -#include <QVBoxLayout> -#include <QWebEnginePage> -#include <QWebEngineView> -#include <QWidget> -#include <QWindow> -#include <lua.hpp> class CommandInput : public QFrame { Q_OBJECT @@ -20,6 +11,7 @@ public: CommandInput(QString defaultInput = "", QWidget *parentNode = nullptr); void setInputFocus(bool focussed); bool isInputFocussed(); + QString getInputCommand(); signals: void submitted(QString command); diff --git a/spec/CommandInputSpec.cpp b/spec/CommandInputSpec.cpp new file mode 100644 index 0000000..7d15f25 --- /dev/null +++ b/spec/CommandInputSpec.cpp @@ -0,0 +1,71 @@ +#include "TestUtils.h" + +#include "CommandInput.hpp" + +class CommandInputSpec : public QObject { + Q_OBJECT + +private slots: + void testWithInitialInput() { + context("when initialized with some text"); + it("sets the initial input text") { + CommandInput inputWidget("Initial content", new QWidget()); + + QCOMPARE(inputWidget.getInputCommand(), QString("Initial content")); + } + } + + void testInputUpdate() { + context("when user types in input"); + it("updates input command") { + CommandInput inputWidget("Initial content", new QWidget()); + + auto input = inputWidget.findChild<QLineEdit *>(); + QTest::keyClicks(input, " updated"); + + QCOMPARE(inputWidget.getInputCommand(), + QString("Initial content updated")); + } + } + + void testSubmitSignalOnReturnKey() { + context("when user hits return key"); + it("emits the submitted signal with the input command") { + CommandInput inputWidget("Initial content", new QWidget()); + QSignalSpy spy(&inputWidget, &CommandInput::submitted); + + auto input = inputWidget.findChild<QLineEdit *>(); + QTest::keyClicks(input, " updated"); + QTest::keyClick(&inputWidget, Qt::Key_Return); + + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.takeFirst().at(0).toString(), + QString("Initial content updated")); + } + } + + void testSetFocus() { + context("when setInputFocus is called with true"); + xit("focusses input field") { + CommandInput inputWidget("Initial content", new QWidget()); + + inputWidget.setInputFocus(true); + QApplication::processEvents(); + + QVERIFY(inputWidget.isInputFocussed()); + } + + context("when setInputFocus is called with false"); + xit("unfocusses input field") { + CommandInput inputWidget("Initial content", new QWidget()); + + inputWidget.setInputFocus(false); + QApplication::processEvents(); + + QVERIFY(!inputWidget.isInputFocussed()); + } + } +}; + +QTEST_MAIN(CommandInputSpec) +#include "CommandInputSpec.moc" diff --git a/spec/TestUtils.h b/spec/TestUtils.h new file mode 100644 index 0000000..b2c1cc6 --- /dev/null +++ b/spec/TestUtils.h @@ -0,0 +1,20 @@ +#include <QtTest/QtTest> +#include <cstdio> + +#define ANSI_BOLD "\x1b[1m" +#define COLOR_CONTEXT "\x1b[32m" ANSI_BOLD +#define COLOR_IT "\x1b[36m" ANSI_BOLD +#define COLOR_SKIP "\x1b[33m" ANSI_BOLD +#define ANSI_RESET "\x1b[0m" + +#define context(msg) printf("⚪" COLOR_CONTEXT "%s" ANSI_RESET "\n", msg); + +#define it(msg) \ + printf(" ⚪" ANSI_BOLD COLOR_IT "it " ANSI_RESET COLOR_IT "%s" ANSI_RESET \ + "\n", \ + msg); \ + if (1) + +#define xit(msg) \ + printf(" ⚪" COLOR_SKIP "SKIPPED it %s" ANSI_RESET "\n", msg); \ + if (0) diff --git a/src/CommandInput.cpp b/src/CommandInput.cpp index b168536..cf7346c 100644 --- a/src/CommandInput.cpp +++ b/src/CommandInput.cpp @@ -1,16 +1,9 @@ -#include <QApplication> -#include <QDialog> #include <QKeyEvent> -#include <QLabel> #include <QLineEdit> -#include <QObject> #include <QVBoxLayout> -#include <QWebEnginePage> -#include <QWebEngineView> #include <QWidget> #include <QWindow> #include <iostream> -#include <lua.hpp> #include "CommandInput.hpp" @@ -27,13 +20,14 @@ CommandInput::CommandInput(QString defaultInput, QWidget *parentNode) layout->setContentsMargins(0, 0, 0, 0); input = new QLineEdit(defaultInput, this); input->setContentsMargins(0, 0, 0, 0); + input->setFocusPolicy(Qt::StrongFocus); layout->addWidget(input); } void CommandInput::keyPressEvent(QKeyEvent *event) { auto combo = event->keyCombination(); if (combo.key() == Qt::Key_Return) { - emit submitted(input->text()); + emit submitted(getInputCommand()); } } @@ -41,7 +35,9 @@ bool CommandInput::isInputFocussed() { return input->hasFocus(); } void CommandInput::setInputFocus(bool focussed) { if (focussed) - input->setFocus(); + input->setFocus(Qt::PopupFocusReason); else input->clearFocus(); } + +QString CommandInput::getInputCommand() { return input->text(); } |
