Skip to content

Commit

Permalink
add group tests
Browse files Browse the repository at this point in the history
  • Loading branch information
vaxerski authored and fufexan committed Feb 14, 2025
1 parent b8aafbf commit 5f81b76
Show file tree
Hide file tree
Showing 7 changed files with 278 additions and 36 deletions.
2 changes: 2 additions & 0 deletions hyprtester/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "shared.hpp"
#include "hyprctlCompat.hpp"
#include "tests/window/window.hpp"
#include "tests/window/groups.hpp"

#include <filesystem>
#include <hyprutils/os/Process.hpp>
Expand Down Expand Up @@ -77,6 +78,7 @@ int main(int argc, char** argv, char** envp) {

// now we can start issuing stuff.
EXPECT(testWindows(), true);
EXPECT(testGroups(), true);

// kill hyprland
getFromSocket("/dispatch exit");
Expand Down
33 changes: 33 additions & 0 deletions hyprtester/src/tests/shared.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include "shared.hpp"
#include <csignal>
#include <cerrno>
#include "../shared.hpp"
#include "../hyprctlCompat.hpp"

using namespace Hyprutils::OS;

CProcess Tests::spawnKitty() {
CProcess kitty{"/bin/bash", {"-c", std::format("WAYLAND_DISPLAY={} kitty", WLDISPLAY)}};
kitty.runAsync();
return kitty;
}

bool Tests::processAlive(pid_t pid) {
kill(pid, 0);
return errno != ESRCH;
}

int Tests::windowCount() {
return countOccurrences(getFromSocket("/clients"), "focusHistoryID: ");
}

int Tests::countOccurrences(const std::string& in, const std::string& what) {
int cnt = 0;
auto pos = in.find(what);
while (pos != std::string::npos) {
cnt++;
pos = in.find(what, pos + what.length() - 1);
}

return cnt;
}
12 changes: 12 additions & 0 deletions hyprtester/src/tests/shared.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#pragma once

#include <hyprutils/os/Process.hpp>
#include <sys/types.h>

//NOLINTNEXTLINE
namespace Tests {
Hyprutils::OS::CProcess spawnKitty();
bool processAlive(pid_t pid);
int windowCount();
int countOccurrences(const std::string& in, const std::string& what);
};
214 changes: 214 additions & 0 deletions hyprtester/src/tests/window/groups.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
#include "groups.hpp"
#include "../../shared.hpp"
#include "../../hyprctlCompat.hpp"
#include <print>
#include <thread>
#include <chrono>
#include <hyprutils/os/Process.hpp>
#include <hyprutils/memory/WeakPtr.hpp>
#include <csignal>
#include <cerrno>
#include "../shared.hpp"

static int ret = 0;

using namespace Hyprutils::OS;
using namespace Hyprutils::Memory;

#define UP CUniquePointer
#define SP CSharedPointer

bool testGroups() {
std::println("{}Testing groups", Colors::GREEN);

// test on workspace "window"
getFromSocket("/dispatch workspace name:groups");

auto kittyProcA = Tests::spawnKitty();
int counter = 0;

std::this_thread::sleep_for(std::chrono::milliseconds(100));

while (Tests::processAlive(kittyProcA.pid()) && Tests::windowCount() != 1) {
counter++;
std::this_thread::sleep_for(std::chrono::milliseconds(100));

if (counter > 20) {
EXPECT(Tests::windowCount(), 1);
return !ret;
}
}

EXPECT(Tests::windowCount(), 1);

// check kitty properties. One kitty should take the entire screen, minus the gaps.
{
auto str = getFromSocket("/clients");
EXPECT(Tests::countOccurrences(str, "at: 22,22"), 1);
EXPECT(Tests::countOccurrences(str, "size: 1876,1036"), 1);
EXPECT(Tests::countOccurrences(str, "fullscreen: 0"), 1);
}

// group the kitty
EXPECT(getFromSocket("/dispatch togglegroup"), "ok");
EXPECT(getFromSocket("/keyword group:groupbar:enabled 1"), "ok");

// check the height of the window now
{
auto str = getFromSocket("/clients");
EXPECT(str.contains("at: 22,45"), true);
EXPECT(str.contains("size: 1876,1013"), true);
}

// disable the groupbar for ease of testing for now
EXPECT(getFromSocket("r/keyword group:groupbar:enabled 0"), "ok");

// kill all
{
auto str = getFromSocket("/clients");
auto pos = str.find("Window ");
while (pos != std::string::npos) {
auto pos2 = str.find(" -> ", pos);
getFromSocket("/dispatch killwindow address:0x" + str.substr(pos + 7, pos2 - pos - 7));
pos = str.find("Window ", pos + 5);
}
}

kittyProcA = Tests::spawnKitty();
counter = 0;

std::this_thread::sleep_for(std::chrono::milliseconds(100));

while (Tests::processAlive(kittyProcA.pid()) && Tests::windowCount() != 1) {
counter++;
std::this_thread::sleep_for(std::chrono::milliseconds(100));

if (counter > 20) {
EXPECT(Tests::windowCount(), 1);
return !ret;
}
}

EXPECT(getFromSocket("/dispatch togglegroup"), "ok");

// check the height of the window now
{
auto str = getFromSocket("/clients");
EXPECT(str.contains("at: 22,22"), true);
EXPECT(str.contains("size: 1876,1036"), true);
}

auto kittyProcB = Tests::spawnKitty();
counter = 0;

std::this_thread::sleep_for(std::chrono::milliseconds(100));

while (Tests::processAlive(kittyProcB.pid()) && Tests::windowCount() != 2) {
counter++;
std::this_thread::sleep_for(std::chrono::milliseconds(100));

if (counter > 20) {
EXPECT(Tests::windowCount(), 2);
return !ret;
}
}

EXPECT(Tests::windowCount(), 2);

size_t lastActiveKittyIdx = 0;

{
auto str = getFromSocket("/activewindow");
lastActiveKittyIdx = std::stoull(str.substr(7, str.find(" -> ") - 7));
}

// test cycling through

getFromSocket("/dispatch changegroupactive f");
std::this_thread::sleep_for(std::chrono::milliseconds(25));

{
auto str = getFromSocket("/activewindow");
EXPECT(lastActiveKittyIdx != std::stoull(str.substr(7, str.find(" -> ") - 7)), true);
}

getFromSocket("/dispatch changegroupactive f");
std::this_thread::sleep_for(std::chrono::milliseconds(25));

{
auto str = getFromSocket("/activewindow");
EXPECT(lastActiveKittyIdx == std::stoull(str.substr(7, str.find(" -> ") - 7)), true);
}

EXPECT(getFromSocket("/keyword group:auto_group false"), "ok");

auto kittyProcC = Tests::spawnKitty();
counter = 0;

std::this_thread::sleep_for(std::chrono::milliseconds(100));

while (Tests::processAlive(kittyProcC.pid()) && Tests::windowCount() != 3) {
counter++;
std::this_thread::sleep_for(std::chrono::milliseconds(100));

if (counter > 20) {
EXPECT(Tests::windowCount(), 3);
return !ret;
}
}

EXPECT(Tests::windowCount(), 3);
{
auto str = getFromSocket("/clients");
EXPECT(Tests::countOccurrences(str, "at: 22,22"), 2);
}

EXPECT(getFromSocket("/dispatch movefocus l"), "ok");
EXPECT(getFromSocket("/dispatch changegroupactive 1"), "ok");
EXPECT(getFromSocket("/keyword group:auto_group true"), "ok");
EXPECT(getFromSocket("/keyword group:insert_after_current false"), "ok");
std::this_thread::sleep_for(std::chrono::milliseconds(25));

auto kittyProcD = Tests::spawnKitty();
counter = 0;

std::this_thread::sleep_for(std::chrono::milliseconds(100));

while (Tests::processAlive(kittyProcD.pid()) && Tests::windowCount() != 4) {
counter++;
std::this_thread::sleep_for(std::chrono::milliseconds(100));

if (counter > 20) {
EXPECT(Tests::windowCount(), 4);
return !ret;
}
}

EXPECT(Tests::windowCount(), 4);

EXPECT(getFromSocket("/dispatch changegroupactive 3"), "ok");

std::this_thread::sleep_for(std::chrono::milliseconds(50));

{
auto str = getFromSocket("/activewindow");
EXPECT(str.contains(std::format("pid: {}", kittyProcD.pid())), true);
}

// kill all
{
auto str = getFromSocket("/clients");
auto pos = str.find("Window ");
while (pos != std::string::npos) {
auto pos2 = str.find(" -> ", pos);
getFromSocket("/dispatch killwindow address:0x" + str.substr(pos + 7, pos2 - pos - 7));
pos = str.find("Window ", pos + 5);
}
}

std::this_thread::sleep_for(std::chrono::milliseconds(500));

EXPECT(Tests::windowCount(), 0);

return !ret;
}
3 changes: 3 additions & 0 deletions hyprtester/src/tests/window/groups.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#pragma once

bool testGroups();
Loading

0 comments on commit 5f81b76

Please sign in to comment.