Merge pull request #3345 from khaneliman/testing
Organize tests and start Hyprland testing
This commit is contained in:
commit
0251e25f23
|
@ -9,6 +9,7 @@ concurrency:
|
|||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
distro:
|
||||
- alpine
|
||||
|
|
|
@ -6,4 +6,4 @@ RUN zypper -n up && \
|
|||
zypper addrepo https://download.opensuse.org/repositories/X11:Wayland/openSUSE_Tumbleweed/X11:Wayland.repo | echo 'a' && \
|
||||
zypper -n refresh && \
|
||||
zypper -n install -t pattern devel_C_C++ && \
|
||||
zypper -n install git meson clang libinput10 libinput-devel pugixml-devel libwayland-client0 libwayland-cursor0 wayland-protocols-devel wayland-devel Mesa-libEGL-devel Mesa-libGLESv2-devel libgbm-devel libxkbcommon-devel libudev-devel libpixman-1-0-devel gtkmm3-devel jsoncpp-devel libxkbregistry-devel scdoc playerctl-devel
|
||||
zypper -n install git meson clang libinput10 libinput-devel pugixml-devel libwayland-client0 libwayland-cursor0 wayland-protocols-devel wayland-devel Mesa-libEGL-devel Mesa-libGLESv2-devel libgbm-devel libxkbcommon-devel libudev-devel libpixman-1-0-devel gtkmm3-devel jsoncpp-devel libxkbregistry-devel scdoc playerctl-devel python3-packaging
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
@ -25,6 +26,10 @@ class IPC {
|
|||
|
||||
static std::string getSocket1Reply(const std::string& rq);
|
||||
Json::Value getSocket1JsonReply(const std::string& rq);
|
||||
static std::filesystem::path getSocketFolder(const char* instanceSig);
|
||||
|
||||
protected:
|
||||
static std::filesystem::path socketFolder_;
|
||||
|
||||
private:
|
||||
void startIPC();
|
||||
|
|
|
@ -100,7 +100,7 @@ class Workspaces : public AModule, public EventHandler {
|
|||
void removeWorkspacesToRemove();
|
||||
void createWorkspacesToCreate();
|
||||
std::vector<std::string> getVisibleWorkspaces();
|
||||
void updateWorkspaceStates(const std::vector<std::string>& visibleWorkspaces);
|
||||
void updateWorkspaceStates();
|
||||
bool updateWindowsToCreate();
|
||||
|
||||
void extendOrphans(int workspaceId, Json::Value const& clientsJson);
|
||||
|
|
|
@ -15,22 +15,31 @@
|
|||
|
||||
namespace waybar::modules::hyprland {
|
||||
|
||||
std::filesystem::path getSocketFolder(const char* instanceSig) {
|
||||
std::filesystem::path IPC::socketFolder_;
|
||||
|
||||
std::filesystem::path IPC::getSocketFolder(const char* instanceSig) {
|
||||
// socket path, specified by EventManager of Hyprland
|
||||
static std::filesystem::path socketFolder;
|
||||
if (!socketFolder.empty()) {
|
||||
return socketFolder;
|
||||
if (!socketFolder_.empty()) {
|
||||
spdlog::warn("socketFolder already set, using {}", socketFolder_.c_str());
|
||||
return socketFolder_;
|
||||
}
|
||||
|
||||
const char* xdgRuntimeDirEnv = std::getenv("XDG_RUNTIME_DIR");
|
||||
std::filesystem::path xdgRuntimeDir;
|
||||
// Only set path if env variable is set
|
||||
if (xdgRuntimeDirEnv) {
|
||||
xdgRuntimeDir = std::filesystem::path(xdgRuntimeDirEnv);
|
||||
}
|
||||
|
||||
std::filesystem::path xdgRuntimeDir = std::filesystem::path(getenv("XDG_RUNTIME_DIR"));
|
||||
if (!xdgRuntimeDir.empty() && std::filesystem::exists(xdgRuntimeDir / "hypr")) {
|
||||
socketFolder = xdgRuntimeDir / "hypr";
|
||||
socketFolder_ = xdgRuntimeDir / "hypr";
|
||||
} else {
|
||||
spdlog::warn("$XDG_RUNTIME_DIR/hypr does not exist, falling back to /tmp/hypr");
|
||||
socketFolder = std::filesystem::path("/tmp") / "hypr";
|
||||
socketFolder_ = std::filesystem::path("/tmp") / "hypr";
|
||||
}
|
||||
socketFolder = socketFolder / instanceSig;
|
||||
return socketFolder;
|
||||
|
||||
socketFolder_ = socketFolder_ / instanceSig;
|
||||
return socketFolder_;
|
||||
}
|
||||
|
||||
void IPC::startIPC() {
|
||||
|
@ -59,7 +68,7 @@ void IPC::startIPC() {
|
|||
|
||||
addr.sun_family = AF_UNIX;
|
||||
|
||||
auto socketPath = getSocketFolder(his) / ".socket2.sock";
|
||||
auto socketPath = IPC::getSocketFolder(his) / ".socket2.sock";
|
||||
strncpy(addr.sun_path, socketPath.c_str(), sizeof(addr.sun_path) - 1);
|
||||
|
||||
addr.sun_path[sizeof(addr.sun_path) - 1] = 0;
|
||||
|
@ -169,7 +178,7 @@ std::string IPC::getSocket1Reply(const std::string& rq) {
|
|||
sockaddr_un serverAddress = {0};
|
||||
serverAddress.sun_family = AF_UNIX;
|
||||
|
||||
std::string socketPath = getSocketFolder(instanceSig) / ".socket.sock";
|
||||
std::string socketPath = IPC::getSocketFolder(instanceSig) / ".socket.sock";
|
||||
|
||||
// Use snprintf to copy the socketPath string into serverAddress.sun_path
|
||||
if (snprintf(serverAddress.sun_path, sizeof(serverAddress.sun_path), "%s", socketPath.c_str()) <
|
||||
|
|
|
@ -128,10 +128,7 @@ void Workspaces::doUpdate() {
|
|||
|
||||
removeWorkspacesToRemove();
|
||||
createWorkspacesToCreate();
|
||||
|
||||
std::vector<std::string> visibleWorkspaces = getVisibleWorkspaces();
|
||||
|
||||
updateWorkspaceStates(visibleWorkspaces);
|
||||
updateWorkspaceStates();
|
||||
updateWindowCount();
|
||||
sortWorkspaces();
|
||||
|
||||
|
@ -870,7 +867,8 @@ bool Workspaces::updateWindowsToCreate() {
|
|||
return anyWindowCreated;
|
||||
}
|
||||
|
||||
void Workspaces::updateWorkspaceStates(const std::vector<std::string> &visibleWorkspaces) {
|
||||
void Workspaces::updateWorkspaceStates() {
|
||||
const std::vector<std::string> visibleWorkspaces = getVisibleWorkspaces();
|
||||
auto updatedWorkspaces = gIPC->getSocket1JsonReply("workspaces");
|
||||
for (auto &workspace : m_workspaces) {
|
||||
workspace->setActive(workspace->name() == m_activeWorkspaceName ||
|
||||
|
|
|
@ -506,9 +506,7 @@ void Workspaces::onButtonReady(const Json::Value &node, Gtk::Button &button) {
|
|||
// check if any of its nodes are focused as well.
|
||||
bool focused = node["focused"].asBool() ||
|
||||
std::any_of(node["nodes"].begin(), node["nodes"].end(),
|
||||
[](const auto &child) {
|
||||
return child["focused"].asBool();
|
||||
});
|
||||
[](const auto &child) { return child["focused"].asBool(); });
|
||||
|
||||
if (focused) {
|
||||
button.show();
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
[wrap-file]
|
||||
directory = spdlog-1.11.0
|
||||
source_url = https://github.com/gabime/spdlog/archive/v1.11.0.tar.gz
|
||||
source_filename = v1.11.0.tar.gz
|
||||
source_hash = ca5cae8d6cac15dae0ec63b21d6ad3530070650f68076f3a4a862ca293a858bb
|
||||
patch_filename = spdlog_1.11.0-2_patch.zip
|
||||
patch_url = https://wrapdb.mesonbuild.com/v2/spdlog_1.11.0-2/get_patch
|
||||
patch_hash = db1364fe89502ac67f245a6c8c51290a52afd74a51eed26fa9ecb5b3443df57a
|
||||
wrapdb_version = 1.11.0-2
|
||||
directory = spdlog-1.12.0
|
||||
source_url = https://github.com/gabime/spdlog/archive/refs/tags/v1.12.0.tar.gz
|
||||
source_filename = spdlog-1.12.0.tar.gz
|
||||
source_hash = 4dccf2d10f410c1e2feaff89966bfc49a1abb29ef6f08246335b110e001e09a9
|
||||
patch_filename = spdlog_1.12.0-2_patch.zip
|
||||
patch_url = https://wrapdb.mesonbuild.com/v2/spdlog_1.12.0-2/get_patch
|
||||
patch_hash = 9596972d1eb2e0a69cea4a53273ca7bbbcb9b2fa872cd734864fc7232dc2d573
|
||||
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/spdlog_1.12.0-2/spdlog-1.12.0.tar.gz
|
||||
wrapdb_version = 1.12.0-2
|
||||
|
||||
[provide]
|
||||
spdlog = spdlog_dep
|
||||
|
|
|
@ -117,3 +117,42 @@ TEST_CASE("Load multiple bar config with include", "[config]") {
|
|||
REQUIRE(data.size() == 4);
|
||||
REQUIRE(data[0]["output"].asString() == "OUT-0");
|
||||
}
|
||||
|
||||
TEST_CASE("Load Hyprland Workspaces bar config", "[config]") {
|
||||
waybar::Config conf;
|
||||
conf.load("test/config/hyprland-workspaces.json");
|
||||
|
||||
auto& data = conf.getConfig();
|
||||
auto hyprland = data[0]["hyprland/workspaces"];
|
||||
auto hyprland_window_rewrite = data[0]["hyprland/workspaces"]["window-rewrite"];
|
||||
auto hyprland_format_icons = data[0]["hyprland/workspaces"]["format-icons"];
|
||||
auto hyprland_persistent_workspaces = data[0]["hyprland/workspaces"]["persistent-workspaces"];
|
||||
|
||||
REQUIRE(data.isArray());
|
||||
REQUIRE(data.size() == 1);
|
||||
REQUIRE(data[0]["height"].asInt() == 20);
|
||||
REQUIRE(data[0]["layer"].asString() == "bottom");
|
||||
REQUIRE(data[0]["output"].isArray());
|
||||
REQUIRE(data[0]["output"][0].asString() == "HDMI-0");
|
||||
REQUIRE(data[0]["output"][1].asString() == "DP-0");
|
||||
|
||||
REQUIRE(hyprland["active-only"].asBool() == true);
|
||||
REQUIRE(hyprland["all-outputs"].asBool() == false);
|
||||
REQUIRE(hyprland["move-to-monitor"].asBool() == true);
|
||||
REQUIRE(hyprland["format"].asString() == "{icon} {windows}");
|
||||
REQUIRE(hyprland["format-window-separator"].asString() == " ");
|
||||
REQUIRE(hyprland["on-scroll-down"].asString() == "hyprctl dispatch workspace e-1");
|
||||
REQUIRE(hyprland["on-scroll-up"].asString() == "hyprctl dispatch workspace e+1");
|
||||
REQUIRE(hyprland["show-special"].asBool() == true);
|
||||
REQUIRE(hyprland["window-rewrite-default"].asString() == "");
|
||||
REQUIRE(hyprland["window-rewrite-separator"].asString() == " ");
|
||||
REQUIRE(hyprland_format_icons["1"].asString() == "");
|
||||
REQUIRE(hyprland_format_icons["2"].asString() == "");
|
||||
REQUIRE(hyprland_format_icons["3"].asString() == "");
|
||||
REQUIRE(hyprland_format_icons["default"].asString() == "");
|
||||
REQUIRE(hyprland_format_icons["empty"].asString() == "");
|
||||
REQUIRE(hyprland_format_icons["urgent"].asString() == "");
|
||||
REQUIRE(hyprland_persistent_workspaces["1"].asString() == "HDMI-0");
|
||||
REQUIRE(hyprland_window_rewrite["title<Steam>"].asString() == "");
|
||||
REQUIRE(hyprland["sort-by"].asString() == "number");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
[
|
||||
{
|
||||
"height": 20,
|
||||
"layer": "bottom",
|
||||
"output": [
|
||||
"HDMI-0",
|
||||
"DP-0"
|
||||
],
|
||||
"hyprland/workspaces": {
|
||||
"active-only": true,
|
||||
"all-outputs": false,
|
||||
"show-special": true,
|
||||
"move-to-monitor": true,
|
||||
"format": "{icon} {windows}",
|
||||
"format-window-separator": " ",
|
||||
"format-icons": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"default": "",
|
||||
"empty": "",
|
||||
"urgent": ""
|
||||
},
|
||||
"persistent-workspaces": {
|
||||
"1": "HDMI-0"
|
||||
},
|
||||
"on-scroll-down": "hyprctl dispatch workspace e-1",
|
||||
"on-scroll-up": "hyprctl dispatch workspace e+1",
|
||||
"window-rewrite": {
|
||||
"title<Steam>": ""
|
||||
},
|
||||
"window-rewrite-default": "",
|
||||
"window-rewrite-separator": " ",
|
||||
"sort-by": "number"
|
||||
}
|
||||
}
|
||||
]
|
|
@ -0,0 +1,55 @@
|
|||
#include <cstdlib>
|
||||
#if __has_include(<catch2/catch_test_macros.hpp>)
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#else
|
||||
#include <catch2/catch.hpp>
|
||||
#endif
|
||||
|
||||
#include "fixtures/IPCTestFixture.hpp"
|
||||
#include "modules/hyprland/backend.hpp"
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
namespace hyprland = waybar::modules::hyprland;
|
||||
|
||||
TEST_CASE_METHOD(IPCTestFixture, "XDGRuntimeDirExists", "[getSocketFolder]") {
|
||||
// Test case: XDG_RUNTIME_DIR exists and contains "hypr" directory
|
||||
// Arrange
|
||||
tempDir = fs::temp_directory_path() / "hypr_test/run/user/1000";
|
||||
fs::path expectedPath = tempDir / "hypr" / instanceSig;
|
||||
fs::create_directories(tempDir / "hypr" / instanceSig);
|
||||
setenv("XDG_RUNTIME_DIR", tempDir.c_str(), 1);
|
||||
|
||||
// Act
|
||||
fs::path actualPath = getSocketFolder(instanceSig);
|
||||
|
||||
// Assert expected result
|
||||
REQUIRE(actualPath == expectedPath);
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(IPCTestFixture, "XDGRuntimeDirDoesNotExist", "[getSocketFolder]") {
|
||||
// Test case: XDG_RUNTIME_DIR does not exist
|
||||
// Arrange
|
||||
unsetenv("XDG_RUNTIME_DIR");
|
||||
fs::path expectedPath = fs::path("/tmp") / "hypr" / instanceSig;
|
||||
|
||||
// Act
|
||||
fs::path actualPath = getSocketFolder(instanceSig);
|
||||
|
||||
// Assert expected result
|
||||
REQUIRE(actualPath == expectedPath);
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(IPCTestFixture, "XDGRuntimeDirExistsNoHyprDir", "[getSocketFolder]") {
|
||||
// Test case: XDG_RUNTIME_DIR exists but does not contain "hypr" directory
|
||||
// Arrange
|
||||
fs::path tempDir = fs::temp_directory_path() / "hypr_test/run/user/1000";
|
||||
fs::create_directories(tempDir);
|
||||
setenv("XDG_RUNTIME_DIR", tempDir.c_str(), 1);
|
||||
fs::path expectedPath = fs::path("/tmp") / "hypr" / instanceSig;
|
||||
|
||||
// Act
|
||||
fs::path actualPath = getSocketFolder(instanceSig);
|
||||
|
||||
// Assert expected result
|
||||
REQUIRE(actualPath == expectedPath);
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
#include "modules/hyprland/backend.hpp"
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
namespace hyprland = waybar::modules::hyprland;
|
||||
|
||||
class IPCTestFixture : public hyprland::IPC {
|
||||
public:
|
||||
IPCTestFixture() : IPC() { IPC::socketFolder_ = ""; }
|
||||
~IPCTestFixture() { fs::remove_all(tempDir); }
|
||||
|
||||
protected:
|
||||
const char* instanceSig = "instance_sig";
|
||||
fs::path tempDir = fs::temp_directory_path() / "hypr_test";
|
||||
|
||||
private:
|
||||
};
|
|
@ -0,0 +1,28 @@
|
|||
test_inc = include_directories('../../include')
|
||||
|
||||
test_dep = [
|
||||
catch2,
|
||||
fmt,
|
||||
gtkmm,
|
||||
jsoncpp,
|
||||
spdlog,
|
||||
]
|
||||
|
||||
test_src = files(
|
||||
'../main.cpp',
|
||||
'backend.cpp',
|
||||
'../../src/modules/hyprland/backend.cpp'
|
||||
)
|
||||
|
||||
hyprland_test = executable(
|
||||
'hyprland_test',
|
||||
test_src,
|
||||
dependencies: test_dep,
|
||||
include_directories: test_inc,
|
||||
)
|
||||
|
||||
test(
|
||||
'hyprland',
|
||||
hyprland_test,
|
||||
workdir: meson.project_source_root(),
|
||||
)
|
|
@ -1,4 +1,5 @@
|
|||
test_inc = include_directories('../include')
|
||||
|
||||
test_dep = [
|
||||
catch2,
|
||||
fmt,
|
||||
|
@ -6,21 +7,13 @@ test_dep = [
|
|||
jsoncpp,
|
||||
spdlog,
|
||||
]
|
||||
|
||||
test_src = files(
|
||||
'main.cpp',
|
||||
'JsonParser.cpp',
|
||||
'SafeSignal.cpp',
|
||||
'config.cpp',
|
||||
'css_reload_helper.cpp',
|
||||
'../src/config.cpp',
|
||||
'../src/util/css_reload_helper.cpp',
|
||||
)
|
||||
|
||||
if tz_dep.found()
|
||||
test_dep += tz_dep
|
||||
test_src += files('date.cpp')
|
||||
endif
|
||||
|
||||
waybar_test = executable(
|
||||
'waybar_test',
|
||||
test_src,
|
||||
|
@ -33,3 +26,6 @@ test(
|
|||
waybar_test,
|
||||
workdir: meson.project_source_root(),
|
||||
)
|
||||
|
||||
subdir('utils')
|
||||
subdir('hyprland')
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include <thread>
|
||||
#include <type_traits>
|
||||
|
||||
#include "GlibTestsFixture.hpp"
|
||||
#include "fixtures/GlibTestsFixture.hpp"
|
||||
|
||||
using namespace waybar;
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
test_inc = include_directories('../../include')
|
||||
|
||||
test_dep = [
|
||||
catch2,
|
||||
fmt,
|
||||
gtkmm,
|
||||
jsoncpp,
|
||||
spdlog,
|
||||
]
|
||||
test_src = files(
|
||||
'../main.cpp',
|
||||
'../config.cpp',
|
||||
'../../src/config.cpp',
|
||||
'JsonParser.cpp',
|
||||
'SafeSignal.cpp',
|
||||
'css_reload_helper.cpp',
|
||||
'../../src/util/css_reload_helper.cpp',
|
||||
)
|
||||
|
||||
if tz_dep.found()
|
||||
test_dep += tz_dep
|
||||
test_src += files('date.cpp')
|
||||
endif
|
||||
|
||||
utils_test = executable(
|
||||
'utils_test',
|
||||
test_src,
|
||||
dependencies: test_dep,
|
||||
include_directories: test_inc,
|
||||
)
|
||||
|
||||
test(
|
||||
'utils',
|
||||
utils_test,
|
||||
workdir: meson.project_source_root(),
|
||||
)
|
Loading…
Reference in New Issue