aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkshay Nair <phenax5@gmail.com>2025-03-08 20:28:10 +0530
committerAkshay Nair <phenax5@gmail.com>2025-03-08 20:29:03 +0530
commit6d3ee55638164df6521a60b6392a26f855d5f924 (patch)
tree18448793cbb971e76cbaeb7b9d2159ee2ab5d3b6
parentb7ac4dc7a20c624a343c946c5decd1b84eab2b82 (diff)
downloadnull-browser-6d3ee55638164df6521a60b6392a26f855d5f924.tar.gz
null-browser-6d3ee55638164df6521a60b6392a26f855d5f924.zip
Add test setup + spec for command input
-rw-r--r--.gitignore1
-rw-r--r--CMakeLists.txt21
-rw-r--r--Makefile7
-rw-r--r--include/CommandInput.hpp12
-rw-r--r--spec/CommandInputSpec.cpp71
-rw-r--r--spec/TestUtils.h20
-rw-r--r--src/CommandInput.cpp14
7 files changed, 121 insertions, 25 deletions
diff --git a/.gitignore b/.gitignore
index 902f3c7..d3bbb0b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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)
diff --git a/Makefile b/Makefile
index 88eeefa..aad5e9c 100644
--- a/Makefile
+++ b/Makefile
@@ -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(); }