aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorsrdusr <trevorgray@srdusr.com>2025-09-26 12:23:19 +0200
committersrdusr <trevorgray@srdusr.com>2025-09-26 12:23:19 +0200
commite4a0432383331e013808a97b7c24707e4ddc4726 (patch)
tree3ef4465be03bc7b92a0b048f02f76475045404b6 /tests
parent105732dde10b317a81d5a10a3f66b315d6f85015 (diff)
downloadsrdwm-e4a0432383331e013808a97b7c24707e4ddc4726.tar.gz
srdwm-e4a0432383331e013808a97b7c24707e4ddc4726.zip
Initial Commit
Diffstat (limited to 'tests')
-rw-r--r--tests/CMakeLists.txt20
-rw-r--r--tests/test_cross_platform_integration.cc302
-rw-r--r--tests/test_lua_manager.cc231
-rw-r--r--tests/test_macos_platform.cc116
-rw-r--r--tests/test_platform_factory.cc174
-rw-r--r--tests/test_smart_placement.cc187
-rw-r--r--tests/test_wayland_platform.cc225
-rw-r--r--tests/test_windows_platform.cc100
-rw-r--r--tests/test_x11_platform.cc221
9 files changed, 1576 insertions, 0 deletions
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
new file mode 100644
index 0000000..2e9d292
--- /dev/null
+++ b/tests/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Test configuration - temporarily disabled to focus on main executable
+# find_package(GTest REQUIRED)
+
+# Test executables - only build the ones that can work for now
+# add_executable(test_platform_factory test_platform_factory.cc)
+
+# Set include directories for all tests
+# target_include_directories(test_platform_factory PRIVATE ${CMAKE_SOURCE_DIR}/src)
+
+# Set platform-specific settings for tests
+# if(PLATFORM_LINUX)
+# target_include_directories(test_platform_factory PRIVATE ${X11_INCLUDE_DIRS} ${WAYLAND_INCLUDE_DIRS} ${WLROOTS_INCLUDE_DIRS} ${XCB_INCLUDE_DIRS})
+# target_compile_definitions(test_platform_factory PRIVATE ${X11_CFLAGS_OTHER} ${WAYLAND_CFLAGS_OTHER} WLR_USE_UNSTABLE)
+# endif()
+
+# Link test executables
+# target_link_libraries(test_platform_factory GTest::gtest GTest::gtest_main)
+
+# Add tests
+# add_test(NAME PlatformFactory COMMAND test_platform_factory)
diff --git a/tests/test_cross_platform_integration.cc b/tests/test_cross_platform_integration.cc
new file mode 100644
index 0000000..8e9ee72
--- /dev/null
+++ b/tests/test_cross_platform_integration.cc
@@ -0,0 +1,302 @@
+#include <gtest/gtest.h>
+#include "../src/platform/platform_factory.h"
+#include "../src/layouts/smart_placement.h"
+#include "../src/config/lua_manager.h"
+#include "../src/core/window_manager.h"
+#include <memory>
+
+class CrossPlatformIntegrationTest : public ::testing::Test {
+protected:
+ void SetUp() override {
+ // Initialize platform
+ platform = PlatformFactory::create_platform();
+ EXPECT_NE(platform, nullptr);
+
+ // Initialize Lua manager
+ lua_manager = std::make_unique<LuaManager>();
+ EXPECT_TRUE(lua_manager->initialize());
+
+ // Initialize window manager
+ window_manager = std::make_unique<WindowManager>();
+ EXPECT_TRUE(window_manager->initialize());
+ }
+
+ void TearDown() override {
+ if (window_manager) {
+ window_manager->shutdown();
+ }
+ if (lua_manager) {
+ lua_manager->shutdown();
+ }
+ if (platform) {
+ platform->shutdown();
+ }
+ }
+
+ std::unique_ptr<Platform> platform;
+ std::unique_ptr<LuaManager> lua_manager;
+ std::unique_ptr<WindowManager> window_manager;
+};
+
+TEST_F(CrossPlatformIntegrationTest, PlatformDetection) {
+ auto detected_platform = PlatformFactory::detect_platform();
+
+ // Should detect one of the supported platforms
+ EXPECT_TRUE(detected_platform == PlatformType::Linux_X11 ||
+ detected_platform == PlatformType::Linux_Wayland ||
+ detected_platform == PlatformType::Windows ||
+ detected_platform == PlatformType::macOS);
+
+ // Platform name should match detection
+ std::string platform_name = platform->get_platform_name();
+ EXPECT_FALSE(platform_name.empty());
+}
+
+TEST_F(CrossPlatformIntegrationTest, WindowLifecycle) {
+ // Create window through platform
+ auto window = platform->create_window("Integration Test Window", 100, 100, 400, 300);
+ EXPECT_NE(window, nullptr);
+
+ if (window) {
+ // Test window properties
+ EXPECT_EQ(window->getTitle(), "Integration Test Window");
+ EXPECT_EQ(window->getX(), 100);
+ EXPECT_EQ(window->getY(), 100);
+ EXPECT_EQ(window->getWidth(), 400);
+ EXPECT_EQ(window->getHeight(), 300);
+
+ // Test window management
+ platform->set_window_position(window.get(), 200, 200);
+ platform->set_window_size(window.get(), 500, 400);
+ platform->focus_window(window.get());
+
+ // Test decoration controls
+ platform->set_window_decorations(window.get(), true);
+ EXPECT_TRUE(platform->get_window_decorations(window.get()));
+
+ platform->set_window_border_color(window.get(), 255, 0, 0);
+ platform->set_window_border_width(window.get(), 5);
+
+ // Clean up
+ platform->destroy_window(window.get());
+ }
+}
+
+TEST_F(CrossPlatformIntegrationTest, SmartPlacementIntegration) {
+ // Get monitor information
+ auto monitors = platform->get_monitors();
+ EXPECT_FALSE(monitors.empty());
+
+ Monitor monitor = monitors[0];
+
+ // Create test windows
+ std::vector<std::unique_ptr<Window>> existing_windows;
+ for (int i = 0; i < 3; ++i) {
+ auto window = platform->create_window(
+ "Test Window " + std::to_string(i),
+ 100 + i * 50, 100 + i * 50,
+ 400, 300
+ );
+ EXPECT_NE(window, nullptr);
+ existing_windows.push_back(std::move(window));
+ }
+
+ // Test smart placement
+ auto new_window = platform->create_window("Smart Placement Test", 0, 0, 400, 300);
+ EXPECT_NE(new_window, nullptr);
+
+ if (new_window) {
+ // Test grid placement
+ auto grid_result = SmartPlacement::place_in_grid(new_window.get(), monitor, existing_windows);
+ EXPECT_TRUE(grid_result.success);
+
+ // Test cascade placement
+ auto cascade_result = SmartPlacement::cascade_place(new_window.get(), monitor, existing_windows);
+ EXPECT_TRUE(cascade_result.success);
+
+ // Test smart tile
+ auto smart_result = SmartPlacement::smart_tile(new_window.get(), monitor, existing_windows);
+ EXPECT_TRUE(smart_result.success);
+
+ platform->destroy_window(new_window.get());
+ }
+
+ // Clean up existing windows
+ for (auto& window : existing_windows) {
+ platform->destroy_window(window.get());
+ }
+}
+
+TEST_F(CrossPlatformIntegrationTest, LuaConfigurationIntegration) {
+ // Test Lua configuration with platform integration
+ std::string config = R"(
+ -- Platform detection
+ local platform = srd.get_platform()
+ srd.set("detected_platform", platform)
+
+ -- Platform-specific settings
+ if platform == "x11" then
+ srd.set("border_width", 3)
+ srd.set("decorations_enabled", true)
+ elseif platform == "wayland" then
+ srd.set("border_width", 2)
+ srd.set("decorations_enabled", true)
+ elseif platform == "windows" then
+ srd.set("border_width", 2)
+ srd.set("decorations_enabled", true)
+ elseif platform == "macos" then
+ srd.set("border_width", 1)
+ srd.set("decorations_enabled", false)
+ end
+
+ -- Window decoration controls
+ srd.window.set_decorations("test_window", true)
+ srd.window.set_border_color("test_window", 255, 0, 0)
+ srd.window.set_border_width("test_window", 5)
+
+ -- Window state controls
+ srd.window.set_floating("test_window", true)
+ srd.window.toggle_floating("test_window")
+ )";
+
+ EXPECT_TRUE(lua_manager->load_config_string(config));
+
+ // Verify platform detection
+ std::string detected_platform = lua_manager->get_string("detected_platform", "");
+ EXPECT_FALSE(detected_platform.empty());
+ EXPECT_TRUE(detected_platform == "x11" ||
+ detected_platform == "wayland" ||
+ detected_platform == "windows" ||
+ detected_platform == "macos");
+}
+
+TEST_F(CrossPlatformIntegrationTest, EventSystemIntegration) {
+ // Test event polling
+ std::vector<Event> events;
+ bool result = platform->poll_events(events);
+
+ // Should not crash, even if no events are available
+ EXPECT_TRUE(result || events.empty());
+
+ // Test event processing
+ if (!events.empty()) {
+ for (const auto& event : events) {
+ // Process events through window manager
+ window_manager->process_event(event);
+ }
+ }
+}
+
+TEST_F(CrossPlatformIntegrationTest, MonitorIntegration) {
+ // Test monitor detection
+ auto monitors = platform->get_monitors();
+ EXPECT_FALSE(monitors.empty());
+
+ for (const auto& monitor : monitors) {
+ EXPECT_GT(monitor.id, 0);
+ EXPECT_FALSE(monitor.name.empty());
+ EXPECT_GT(monitor.width, 0);
+ EXPECT_GT(monitor.height, 0);
+ EXPECT_GT(monitor.refresh_rate, 0);
+
+ // Test smart placement with monitor
+ auto window = platform->create_window("Monitor Test", 0, 0, 400, 300);
+ EXPECT_NE(window, nullptr);
+
+ if (window) {
+ std::vector<std::unique_ptr<Window>> empty_windows;
+ auto result = SmartPlacement::place_in_grid(window.get(), monitor, empty_windows);
+ EXPECT_TRUE(result.success);
+
+ platform->destroy_window(window.get());
+ }
+ }
+}
+
+TEST_F(CrossPlatformIntegrationTest, InputHandlingIntegration) {
+ // Test input grabbing
+ platform->grab_keyboard();
+ platform->grab_pointer();
+
+ // Test input release
+ platform->ungrab_keyboard();
+ platform->ungrab_pointer();
+}
+
+TEST_F(CrossPlatformIntegrationTest, ConfigurationReloading) {
+ // Test configuration reloading with platform integration
+ std::string initial_config = R"(
+ srd.set("test.value", "initial")
+ srd.set("test.platform", srd.get_platform())
+ )";
+
+ EXPECT_TRUE(lua_manager->load_config_string(initial_config));
+ EXPECT_EQ(lua_manager->get_string("test.value", ""), "initial");
+
+ // Reload configuration
+ EXPECT_TRUE(lua_manager->reload_config());
+
+ // Should be reset to default
+ EXPECT_EQ(lua_manager->get_string("test.value", "default"), "default");
+}
+
+TEST_F(CrossPlatformIntegrationTest, ErrorHandling) {
+ // Test error handling with invalid inputs
+ Window* invalid_window = nullptr;
+
+ // These should not crash
+ platform->set_window_decorations(invalid_window, true);
+ platform->set_window_border_color(invalid_window, 255, 0, 0);
+ platform->set_window_border_width(invalid_window, 5);
+ platform->get_window_decorations(invalid_window);
+
+ // Test invalid Lua configuration
+ std::string invalid_config = "invalid lua code {";
+ EXPECT_FALSE(lua_manager->load_config_string(invalid_config));
+
+ // Should have errors
+ auto errors = lua_manager->get_errors();
+ EXPECT_FALSE(errors.empty());
+}
+
+TEST_F(CrossPlatformIntegrationTest, PerformanceTest) {
+ // Test performance with multiple windows and operations
+ std::vector<std::unique_ptr<Window>> windows;
+
+ // Create multiple windows
+ for (int i = 0; i < 10; ++i) {
+ auto window = platform->create_window(
+ "Performance Test " + std::to_string(i),
+ 100 + i * 10, 100 + i * 10,
+ 400, 300
+ );
+ EXPECT_NE(window, nullptr);
+ windows.push_back(std::move(window));
+ }
+
+ // Perform operations on all windows
+ for (auto& window : windows) {
+ platform->set_window_position(window.get(), 200, 200);
+ platform->set_window_size(window.get(), 500, 400);
+ platform->set_window_decorations(window.get(), true);
+ platform->set_window_border_color(window.get(), 255, 0, 0);
+ platform->set_window_border_width(window.get(), 5);
+ }
+
+ // Clean up
+ for (auto& window : windows) {
+ platform->destroy_window(window.get());
+ }
+}
+
+TEST_F(CrossPlatformIntegrationTest, ShutdownSequence) {
+ // Test proper shutdown sequence
+ EXPECT_TRUE(window_manager->shutdown());
+ EXPECT_TRUE(lua_manager->shutdown());
+ platform->shutdown();
+}
+
+int main(int argc, char **argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/tests/test_lua_manager.cc b/tests/test_lua_manager.cc
new file mode 100644
index 0000000..c50da7e
--- /dev/null
+++ b/tests/test_lua_manager.cc
@@ -0,0 +1,231 @@
+#include <gtest/gtest.h>
+#include "../src/config/lua_manager.h"
+#include <memory>
+
+class LuaManagerTest : public ::testing::Test {
+protected:
+ void SetUp() override {
+ lua_manager = std::make_unique<LuaManager>();
+ EXPECT_TRUE(lua_manager->initialize());
+ }
+
+ void TearDown() override {
+ if (lua_manager) {
+ lua_manager->shutdown();
+ }
+ }
+
+ std::unique_ptr<LuaManager> lua_manager;
+};
+
+TEST_F(LuaManagerTest, Initialization) {
+ EXPECT_TRUE(lua_manager->initialize());
+ EXPECT_TRUE(lua_manager->is_initialized());
+}
+
+TEST_F(LuaManagerTest, ConfigurationValues) {
+ // Test string values
+ lua_manager->set_string("test.string", "test_value");
+ EXPECT_EQ(lua_manager->get_string("test.string", ""), "test_value");
+ EXPECT_EQ(lua_manager->get_string("test.nonexistent", "default"), "default");
+
+ // Test integer values
+ lua_manager->set_int("test.int", 42);
+ EXPECT_EQ(lua_manager->get_int("test.int", 0), 42);
+ EXPECT_EQ(lua_manager->get_int("test.nonexistent", 100), 100);
+
+ // Test boolean values
+ lua_manager->set_bool("test.bool", true);
+ EXPECT_TRUE(lua_manager->get_bool("test.bool", false));
+ EXPECT_FALSE(lua_manager->get_bool("test.nonexistent", false));
+}
+
+TEST_F(LuaManagerTest, KeyBindings) {
+ // Test key binding
+ bool callback_called = false;
+ lua_manager->bind_key("Mod4+Return", [&callback_called]() {
+ callback_called = true;
+ });
+
+ // Simulate key press
+ lua_manager->handle_key_press("Mod4+Return");
+ EXPECT_TRUE(callback_called);
+}
+
+TEST_F(LuaManagerTest, LayoutManagement) {
+ // Test layout setting
+ lua_manager->set_layout(0, "tiling");
+ EXPECT_EQ(lua_manager->get_layout(0), "tiling");
+
+ lua_manager->set_layout(1, "dynamic");
+ EXPECT_EQ(lua_manager->get_layout(1), "dynamic");
+}
+
+TEST_F(LuaManagerTest, WindowDecorationControls) {
+ // Test decoration controls
+ EXPECT_TRUE(lua_manager->set_window_decorations("test_window", true));
+ EXPECT_TRUE(lua_manager->get_window_decorations("test_window"));
+
+ EXPECT_TRUE(lua_manager->set_window_decorations("test_window", false));
+ EXPECT_FALSE(lua_manager->get_window_decorations("test_window"));
+
+ // Test border color
+ EXPECT_TRUE(lua_manager->set_window_border_color("test_window", 255, 0, 0));
+
+ // Test border width
+ EXPECT_TRUE(lua_manager->set_window_border_width("test_window", 5));
+}
+
+TEST_F(LuaManagerTest, WindowStateControls) {
+ // Test floating state
+ EXPECT_TRUE(lua_manager->set_window_floating("test_window", true));
+ EXPECT_TRUE(lua_manager->is_window_floating("test_window"));
+
+ EXPECT_TRUE(lua_manager->set_window_floating("test_window", false));
+ EXPECT_FALSE(lua_manager->is_window_floating("test_window"));
+
+ // Test toggle
+ EXPECT_TRUE(lua_manager->toggle_window_floating("test_window"));
+ EXPECT_TRUE(lua_manager->is_window_floating("test_window"));
+}
+
+TEST_F(LuaManagerTest, ConfigurationLoading) {
+ // Test loading configuration from string
+ std::string config = R"(
+ srd.set("test.loaded", true)
+ srd.set("test.value", 123)
+ srd.set("test.string", "loaded_value")
+ )";
+
+ EXPECT_TRUE(lua_manager->load_config_string(config));
+ EXPECT_TRUE(lua_manager->get_bool("test.loaded", false));
+ EXPECT_EQ(lua_manager->get_int("test.value", 0), 123);
+ EXPECT_EQ(lua_manager->get_string("test.string", ""), "loaded_value");
+}
+
+TEST_F(LuaManagerTest, ErrorHandling) {
+ // Test invalid Lua code
+ std::string invalid_config = "invalid lua code {";
+ EXPECT_FALSE(lua_manager->load_config_string(invalid_config));
+
+ // Test error retrieval
+ auto errors = lua_manager->get_errors();
+ EXPECT_FALSE(errors.empty());
+}
+
+TEST_F(LuaManagerTest, ThemeConfiguration) {
+ // Test theme colors
+ std::map<std::string, std::string> colors = {
+ {"background", "#2e3440"},
+ {"foreground", "#eceff4"},
+ {"accent", "#88c0d0"}
+ };
+
+ EXPECT_TRUE(lua_manager->set_theme_colors(colors));
+
+ // Test theme decorations
+ std::map<std::string, LuaConfigValue> decorations = {
+ {"border_width", {LuaConfigValue::Type::Number, "", 3.0, false, {}, ""}},
+ {"border_color", {LuaConfigValue::Type::String, "#2e3440", 0.0, false, {}, ""}}
+ };
+
+ EXPECT_TRUE(lua_manager->set_theme_decorations(decorations));
+}
+
+TEST_F(LuaManagerTest, ConfigurationReloading) {
+ // Set initial configuration
+ lua_manager->set_string("test.reload", "initial");
+ EXPECT_EQ(lua_manager->get_string("test.reload", ""), "initial");
+
+ // Reload configuration
+ EXPECT_TRUE(lua_manager->reload_config());
+
+ // Should be reset to default
+ EXPECT_EQ(lua_manager->get_string("test.reload", "default"), "default");
+}
+
+TEST_F(LuaManagerTest, LuaAPIFunctions) {
+ // Test Lua API registration
+ std::string api_test = R"(
+ -- Test srd.set
+ srd.set("api.test", "value")
+
+ -- Test srd.get
+ local value = srd.get("api.test")
+ if value ~= "value" then
+ error("srd.get failed")
+ end
+
+ -- Test srd.bind
+ srd.bind("Mod4+Test", function()
+ srd.set("api.callback", "called")
+ end)
+ )";
+
+ EXPECT_TRUE(lua_manager->load_config_string(api_test));
+ EXPECT_EQ(lua_manager->get_string("api.test", ""), "value");
+}
+
+TEST_F(LuaManagerTest, WindowAPIFunctions) {
+ // Test window API functions
+ std::string window_api_test = R"(
+ -- Test window decoration controls
+ srd.window.set_decorations("test_window", true)
+ srd.window.set_border_color("test_window", 255, 0, 0)
+ srd.window.set_border_width("test_window", 5)
+
+ -- Test window state controls
+ srd.window.set_floating("test_window", true)
+ srd.window.toggle_floating("test_window")
+ )";
+
+ EXPECT_TRUE(lua_manager->load_config_string(window_api_test));
+}
+
+TEST_F(LuaManagerTest, LayoutAPIFunctions) {
+ // Test layout API functions
+ std::string layout_api_test = R"(
+ -- Test layout setting
+ srd.layout.set("tiling")
+
+ -- Test layout configuration
+ srd.layout.configure("tiling", {
+ gap = "10",
+ border_width = "2"
+ })
+ )";
+
+ EXPECT_TRUE(lua_manager->load_config_string(layout_api_test));
+}
+
+TEST_F(LuaManagerTest, PerformanceTest) {
+ // Test performance with many configuration values
+ for (int i = 0; i < 1000; ++i) {
+ std::string key = "perf.test." + std::to_string(i);
+ lua_manager->set_int(key, i);
+ }
+
+ // Verify all values
+ for (int i = 0; i < 1000; ++i) {
+ std::string key = "perf.test." + std::to_string(i);
+ EXPECT_EQ(lua_manager->get_int(key, -1), i);
+ }
+}
+
+TEST_F(LuaManagerTest, MemoryManagement) {
+ // Test memory management with large configurations
+ std::string large_config;
+ for (int i = 0; i < 100; ++i) {
+ large_config += "srd.set(\"large.test." + std::to_string(i) + "\", " + std::to_string(i) + ")\n";
+ }
+
+ EXPECT_TRUE(lua_manager->load_config_string(large_config));
+
+ // Reload to test cleanup
+ EXPECT_TRUE(lua_manager->reload_config());
+}
+
+int main(int argc, char **argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/tests/test_macos_platform.cc b/tests/test_macos_platform.cc
new file mode 100644
index 0000000..9bae0b1
--- /dev/null
+++ b/tests/test_macos_platform.cc
@@ -0,0 +1,116 @@
+#include <gtest/gtest.h>
+#include "../src/platform/macos_platform.h"
+#include <memory>
+
+class MacOSPlatformTest : public ::testing::Test {
+protected:
+ void SetUp() override {
+ platform = std::make_unique<MacOSPlatform>();
+ }
+
+ void TearDown() override {
+ if (platform) {
+ platform->shutdown();
+ }
+ }
+
+ std::unique_ptr<MacOSPlatform> platform;
+};
+
+TEST_F(MacOSPlatformTest, Initialization) {
+ bool initialized = platform->initialize();
+
+ if (initialized) {
+ EXPECT_TRUE(platform->get_platform_name() == "macOS");
+ EXPECT_TRUE(platform->is_macos());
+ EXPECT_FALSE(platform->is_x11());
+ EXPECT_FALSE(platform->is_wayland());
+ EXPECT_FALSE(platform->is_windows());
+ }
+}
+
+TEST_F(MacOSPlatformTest, PlatformCapabilities) {
+ EXPECT_TRUE(platform->get_platform_name() == "macOS");
+ EXPECT_TRUE(platform->is_macos());
+ EXPECT_FALSE(platform->is_x11());
+ EXPECT_FALSE(platform->is_wayland());
+ EXPECT_FALSE(platform->is_windows());
+}
+
+TEST_F(MacOSPlatformTest, MonitorDetection) {
+ if (platform->initialize()) {
+ auto monitors = platform->get_monitors();
+ EXPECT_FALSE(monitors.empty());
+
+ for (const auto& monitor : monitors) {
+ EXPECT_GT(monitor.id, 0);
+ EXPECT_FALSE(monitor.name.empty());
+ EXPECT_GT(monitor.width, 0);
+ EXPECT_GT(monitor.height, 0);
+ EXPECT_GT(monitor.refresh_rate, 0);
+ }
+ }
+}
+
+TEST_F(MacOSPlatformTest, WindowCreation) {
+ if (platform->initialize()) {
+ auto window = platform->create_window("macOS Test Window", 100, 100, 400, 300);
+ EXPECT_NE(window, nullptr);
+
+ if (window) {
+ EXPECT_EQ(window->getTitle(), "macOS Test Window");
+ EXPECT_EQ(window->getX(), 100);
+ EXPECT_EQ(window->getY(), 100);
+ EXPECT_EQ(window->getWidth(), 400);
+ EXPECT_EQ(window->getHeight(), 300);
+ }
+ }
+}
+
+TEST_F(MacOSPlatformTest, AccessibilityAPIs) {
+ if (platform->initialize()) {
+ auto window = platform->create_window("macOS Test Window", 100, 100, 400, 300);
+ EXPECT_NE(window, nullptr);
+
+ if (window) {
+ // Test accessibility-based window management
+ platform->set_window_position(window.get(), 200, 200);
+ platform->set_window_size(window.get(), 500, 400);
+ platform->focus_window(window.get());
+
+ platform->destroy_window(window.get());
+ }
+ }
+}
+
+TEST_F(MacOSPlatformTest, EventPolling) {
+ if (platform->initialize()) {
+ std::vector<Event> events;
+ bool result = platform->poll_events(events);
+
+ // Should not crash, even if no events are available
+ EXPECT_TRUE(result || events.empty());
+ }
+}
+
+TEST_F(MacOSPlatformTest, OverlayWindows) {
+ if (platform->initialize()) {
+ auto window = platform->create_window("macOS Test Window", 100, 100, 400, 300);
+ EXPECT_NE(window, nullptr);
+
+ if (window) {
+ // Test overlay window creation for custom decorations
+ // This is the macOS workaround for custom decorations
+ platform->set_window_decorations(window.get(), true);
+ platform->set_window_border_color(window.get(), 255, 0, 0);
+ platform->set_window_border_width(window.get(), 5);
+
+ platform->destroy_window(window.get());
+ }
+ }
+}
+
+int main(int argc, char **argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/tests/test_platform_factory.cc b/tests/test_platform_factory.cc
new file mode 100644
index 0000000..364b193
--- /dev/null
+++ b/tests/test_platform_factory.cc
@@ -0,0 +1,174 @@
+#include <gtest/gtest.h>
+#include "../src/platform/platform_factory.h"
+#include "../src/platform/platform.h"
+
+class PlatformFactoryTest : public ::testing::Test {
+protected:
+ void SetUp() override {
+ // Set up test environment
+ }
+};
+
+TEST_F(PlatformFactoryTest, PlatformDetection) {
+ auto platform = PlatformFactory::create_platform();
+
+ // Should create a valid platform
+ EXPECT_NE(platform, nullptr);
+}
+
+TEST_F(PlatformFactoryTest, PlatformCreation) {
+ auto platform = PlatformFactory::create_platform();
+
+ EXPECT_NE(platform, nullptr);
+ EXPECT_TRUE(platform->initialize());
+}
+
+TEST_F(PlatformFactoryTest, PlatformName) {
+ auto platform = PlatformFactory::create_platform();
+
+ std::string name = platform->get_platform_name();
+ EXPECT_FALSE(name.empty());
+
+ // Should be one of the expected platform names
+ EXPECT_TRUE(name == "X11" || name == "Wayland" || name == "Windows" || name == "macOS");
+}
+
+TEST_F(PlatformFactoryTest, PlatformCapabilities) {
+ auto platform = PlatformFactory::create_platform();
+
+ // Test platform-specific capabilities
+ if (platform->is_x11()) {
+ EXPECT_TRUE(platform->get_platform_name() == "X11");
+ EXPECT_FALSE(platform->is_wayland());
+ EXPECT_FALSE(platform->is_windows());
+ EXPECT_FALSE(platform->is_macos());
+ } else if (platform->is_wayland()) {
+ EXPECT_TRUE(platform->get_platform_name() == "Wayland");
+ EXPECT_FALSE(platform->is_x11());
+ EXPECT_FALSE(platform->is_windows());
+ EXPECT_FALSE(platform->is_macos());
+ } else if (platform->is_windows()) {
+ EXPECT_TRUE(platform->get_platform_name() == "Windows");
+ EXPECT_FALSE(platform->is_x11());
+ EXPECT_FALSE(platform->is_wayland());
+ EXPECT_FALSE(platform->is_macos());
+ } else if (platform->is_macos()) {
+ EXPECT_TRUE(platform->get_platform_name() == "macOS");
+ EXPECT_FALSE(platform->is_x11());
+ EXPECT_FALSE(platform->is_wayland());
+ EXPECT_FALSE(platform->is_windows());
+ }
+}
+
+TEST_F(PlatformFactoryTest, MonitorDetection) {
+ auto platform = PlatformFactory::create_platform();
+
+ auto monitors = platform->get_monitors();
+ EXPECT_FALSE(monitors.empty());
+
+ for (const auto& monitor : monitors) {
+ EXPECT_GT(monitor.id, 0);
+ EXPECT_FALSE(monitor.name.empty());
+ EXPECT_GT(monitor.width, 0);
+ EXPECT_GT(monitor.height, 0);
+ EXPECT_GT(monitor.refresh_rate, 0);
+ }
+}
+
+TEST_F(PlatformFactoryTest, EventPolling) {
+ auto platform = PlatformFactory::create_platform();
+
+ std::vector<Event> events;
+ bool result = platform->poll_events(events);
+
+ // Should not crash, even if no events are available
+ EXPECT_TRUE(result || events.empty());
+}
+
+TEST_F(PlatformFactoryTest, WindowCreation) {
+ auto platform = PlatformFactory::create_platform();
+
+ auto window = platform->create_window("Test Window", 100, 100, 400, 300);
+ EXPECT_NE(window, nullptr);
+
+ if (window) {
+ EXPECT_EQ(window->getTitle(), "Test Window");
+ EXPECT_EQ(window->getX(), 100);
+ EXPECT_EQ(window->getY(), 100);
+ EXPECT_EQ(window->getWidth(), 400);
+ EXPECT_EQ(window->getHeight(), 300);
+ }
+}
+
+TEST_F(PlatformFactoryTest, WindowManagement) {
+ auto platform = PlatformFactory::create_platform();
+
+ auto window = platform->create_window("Test Window", 100, 100, 400, 300);
+ EXPECT_NE(window, nullptr);
+
+ if (window) {
+ // Test window positioning
+ platform->set_window_position(window.get(), 200, 200);
+ EXPECT_EQ(window->getX(), 200);
+ EXPECT_EQ(window->getY(), 200);
+
+ // Test window sizing
+ platform->set_window_size(window.get(), 500, 400);
+ EXPECT_EQ(window->getWidth(), 500);
+ EXPECT_EQ(window->getHeight(), 400);
+
+ // Test window focusing
+ platform->focus_window(window.get());
+
+ // Test window destruction
+ platform->destroy_window(window.get());
+ }
+}
+
+TEST_F(PlatformFactoryTest, DecorationControls) {
+ auto platform = PlatformFactory::create_platform();
+
+ auto window = platform->create_window("Test Window", 100, 100, 400, 300);
+ EXPECT_NE(window, nullptr);
+
+ if (window) {
+ // Test decoration toggling
+ platform->set_window_decorations(window.get(), true);
+ EXPECT_TRUE(platform->get_window_decorations(window.get()));
+
+ platform->set_window_decorations(window.get(), false);
+ EXPECT_FALSE(platform->get_window_decorations(window.get()));
+
+ // Test border color
+ platform->set_window_border_color(window.get(), 255, 0, 0);
+
+ // Test border width
+ platform->set_window_border_width(window.get(), 5);
+
+ platform->destroy_window(window.get());
+ }
+}
+
+TEST_F(PlatformFactoryTest, InputHandling) {
+ auto platform = PlatformFactory::create_platform();
+
+ // Test keyboard grabbing
+ platform->grab_keyboard();
+ platform->ungrab_keyboard();
+
+ // Test pointer grabbing
+ platform->grab_pointer();
+ platform->ungrab_pointer();
+}
+
+TEST_F(PlatformFactoryTest, PlatformShutdown) {
+ auto platform = PlatformFactory::create_platform();
+
+ // Should not crash on shutdown
+ platform->shutdown();
+}
+
+int main(int argc, char **argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/tests/test_smart_placement.cc b/tests/test_smart_placement.cc
new file mode 100644
index 0000000..6690984
--- /dev/null
+++ b/tests/test_smart_placement.cc
@@ -0,0 +1,187 @@
+#include <gtest/gtest.h>
+#include "../src/layouts/smart_placement.h"
+#include "../src/core/window.h"
+#include "../src/layouts/layout.h"
+
+class SmartPlacementTest : public ::testing::Test {
+protected:
+ void SetUp() override {
+ // Create test monitor
+ monitor.id = 1;
+ monitor.name = "Test Monitor";
+ monitor.x = 0;
+ monitor.y = 0;
+ monitor.width = 1920;
+ monitor.height = 1080;
+ monitor.refresh_rate = 60;
+
+ // Create test windows
+ for (int i = 0; i < 5; ++i) {
+ auto window = std::make_unique<Window>();
+ window->setId(i + 1);
+ window->setTitle("Test Window " + std::to_string(i + 1));
+ window->setPosition(100 + i * 50, 100 + i * 50);
+ window->setSize(400, 300);
+ existing_windows.push_back(std::move(window));
+ }
+ }
+
+ Monitor monitor;
+ std::vector<std::unique_ptr<Window>> existing_windows;
+};
+
+TEST_F(SmartPlacementTest, GridPlacement) {
+ auto window = std::make_unique<Window>();
+ window->setId(100);
+ window->setTitle("Grid Test Window");
+ window->setSize(400, 300);
+
+ auto result = SmartPlacement::place_in_grid(window.get(), monitor, existing_windows);
+
+ EXPECT_TRUE(result.success);
+ EXPECT_GE(result.x, monitor.x);
+ EXPECT_LE(result.x + window->getWidth(), monitor.x + monitor.width);
+ EXPECT_GE(result.y, monitor.y);
+ EXPECT_LE(result.y + window->getHeight(), monitor.y + monitor.height);
+}
+
+TEST_F(SmartPlacementTest, CascadePlacement) {
+ auto window = std::make_unique<Window>();
+ window->setId(101);
+ window->setTitle("Cascade Test Window");
+ window->setSize(400, 300);
+
+ auto result = SmartPlacement::cascade_place(window.get(), monitor, existing_windows);
+
+ EXPECT_TRUE(result.success);
+ EXPECT_GE(result.x, monitor.x);
+ EXPECT_LE(result.x + window->getWidth(), monitor.x + monitor.width);
+ EXPECT_GE(result.y, monitor.y);
+ EXPECT_LE(result.y + window->getHeight(), monitor.y + monitor.height);
+}
+
+TEST_F(SmartPlacementTest, SnapToEdge) {
+ auto window = std::make_unique<Window>();
+ window->setId(102);
+ window->setTitle("Snap Test Window");
+ window->setSize(400, 300);
+
+ auto result = SmartPlacement::snap_to_edge(window.get(), monitor, existing_windows);
+
+ EXPECT_TRUE(result.success);
+ EXPECT_GE(result.x, monitor.x);
+ EXPECT_LE(result.x + window->getWidth(), monitor.x + monitor.width);
+ EXPECT_GE(result.y, monitor.y);
+ EXPECT_LE(result.y + window->getHeight(), monitor.y + monitor.height);
+}
+
+TEST_F(SmartPlacementTest, SmartTile) {
+ auto window = std::make_unique<Window>();
+ window->setId(103);
+ window->setTitle("Smart Tile Test Window");
+ window->setSize(400, 300);
+
+ auto result = SmartPlacement::smart_tile(window.get(), monitor, existing_windows);
+
+ EXPECT_TRUE(result.success);
+ EXPECT_GE(result.x, monitor.x);
+ EXPECT_LE(result.x + window->getWidth(), monitor.x + monitor.width);
+ EXPECT_GE(result.y, monitor.y);
+ EXPECT_LE(result.y + window->getHeight(), monitor.y + monitor.height);
+}
+
+TEST_F(SmartPlacementTest, OverlapDetection) {
+ auto window1 = std::make_unique<Window>();
+ window1->setId(200);
+ window1->setPosition(100, 100);
+ window1->setSize(400, 300);
+
+ auto window2 = std::make_unique<Window>();
+ window2->setId(201);
+ window2->setPosition(200, 200);
+ window2->setSize(400, 300);
+
+ EXPECT_TRUE(SmartPlacement::windows_overlap(window1.get(), window2.get()));
+
+ auto window3 = std::make_unique<Window>();
+ window3->setId(202);
+ window3->setPosition(600, 600);
+ window3->setSize(400, 300);
+
+ EXPECT_FALSE(SmartPlacement::windows_overlap(window1.get(), window3.get()));
+}
+
+TEST_F(SmartPlacementTest, OptimalGridSize) {
+ auto grid_size = SmartPlacement::calculate_optimal_grid_size(4, monitor);
+ EXPECT_GT(grid_size.first, 0);
+ EXPECT_GT(grid_size.second, 0);
+ EXPECT_LE(grid_size.first * grid_size.second, 6); // Should fit 4 windows with some margin
+}
+
+TEST_F(SmartPlacementTest, FreeSpaceFinding) {
+ auto free_spaces = SmartPlacement::find_free_spaces(monitor, existing_windows);
+ EXPECT_FALSE(free_spaces.empty());
+
+ for (const auto& space : free_spaces) {
+ EXPECT_GT(space.width, 0);
+ EXPECT_GT(space.height, 0);
+ EXPECT_GE(space.x, monitor.x);
+ EXPECT_GE(space.y, monitor.y);
+ EXPECT_LE(space.x + space.width, monitor.x + monitor.width);
+ EXPECT_LE(space.y + space.height, monitor.y + monitor.height);
+ }
+}
+
+TEST_F(SmartPlacementTest, PositionValidation) {
+ auto window = std::make_unique<Window>();
+ window->setId(300);
+ window->setSize(400, 300);
+
+ // Valid position
+ EXPECT_TRUE(SmartPlacement::is_position_valid(100, 100, window.get(), monitor, existing_windows));
+
+ // Invalid position (outside monitor)
+ EXPECT_FALSE(SmartPlacement::is_position_valid(-100, -100, window.get(), monitor, existing_windows));
+ EXPECT_FALSE(SmartPlacement::is_position_valid(2000, 2000, window.get(), monitor, existing_windows));
+}
+
+TEST_F(SmartPlacementTest, GridPositionCalculation) {
+ auto grid_size = std::make_pair(2, 2);
+ auto cell_size = std::make_pair(monitor.width / 2, monitor.height / 2);
+
+ auto pos = SmartPlacement::calculate_grid_position(0, 0, grid_size, cell_size, monitor);
+ EXPECT_EQ(pos.first, monitor.x);
+ EXPECT_EQ(pos.second, monitor.y);
+
+ pos = SmartPlacement::calculate_grid_position(1, 1, grid_size, cell_size, monitor);
+ EXPECT_EQ(pos.first, monitor.x + cell_size.first);
+ EXPECT_EQ(pos.second, monitor.y + cell_size.second);
+}
+
+TEST_F(SmartPlacementTest, OverlapScoreCalculation) {
+ auto window1 = std::make_unique<Window>();
+ window1->setId(400);
+ window1->setPosition(100, 100);
+ window1->setSize(400, 300);
+
+ auto window2 = std::make_unique<Window>();
+ window2->setId(401);
+ window2->setPosition(200, 200);
+ window2->setSize(400, 300);
+
+ auto score = SmartPlacement::calculate_overlap_score(window1.get(), window2.get());
+ EXPECT_GT(score, 0);
+
+ auto window3 = std::make_unique<Window>();
+ window3->setId(402);
+ window3->setPosition(600, 600);
+ window3->setSize(400, 300);
+
+ score = SmartPlacement::calculate_overlap_score(window1.get(), window3.get());
+ EXPECT_EQ(score, 0);
+}
+
+int main(int argc, char **argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/tests/test_wayland_platform.cc b/tests/test_wayland_platform.cc
new file mode 100644
index 0000000..728c1b1
--- /dev/null
+++ b/tests/test_wayland_platform.cc
@@ -0,0 +1,225 @@
+#include <gtest/gtest.h>
+#include "../src/platform/wayland_platform.h"
+#include <memory>
+
+class WaylandPlatformTest : public ::testing::Test {
+protected:
+ void SetUp() override {
+ platform = std::make_unique<WaylandPlatform>();
+ }
+
+ void TearDown() override {
+ if (platform) {
+ platform->shutdown();
+ }
+ }
+
+ std::unique_ptr<WaylandPlatform> platform;
+};
+
+TEST_F(WaylandPlatformTest, Initialization) {
+ // Note: This test may fail if no Wayland display is available
+ // In a real environment, this should work
+ bool initialized = platform->initialize();
+
+ if (initialized) {
+ EXPECT_TRUE(platform->get_platform_name() == "Wayland");
+ EXPECT_TRUE(platform->is_wayland());
+ EXPECT_FALSE(platform->is_x11());
+ EXPECT_FALSE(platform->is_windows());
+ EXPECT_FALSE(platform->is_macos());
+ }
+}
+
+TEST_F(WaylandPlatformTest, PlatformCapabilities) {
+ EXPECT_TRUE(platform->get_platform_name() == "Wayland");
+ EXPECT_TRUE(platform->is_wayland());
+ EXPECT_FALSE(platform->is_x11());
+ EXPECT_FALSE(platform->is_windows());
+ EXPECT_FALSE(platform->is_macos());
+}
+
+TEST_F(WaylandPlatformTest, MonitorDetection) {
+ if (platform->initialize()) {
+ auto monitors = platform->get_monitors();
+ EXPECT_FALSE(monitors.empty());
+
+ for (const auto& monitor : monitors) {
+ EXPECT_GT(monitor.id, 0);
+ EXPECT_FALSE(monitor.name.empty());
+ EXPECT_GT(monitor.width, 0);
+ EXPECT_GT(monitor.height, 0);
+ EXPECT_GT(monitor.refresh_rate, 0);
+ }
+ }
+}
+
+TEST_F(WaylandPlatformTest, WindowCreation) {
+ if (platform->initialize()) {
+ auto window = platform->create_window("Wayland Test Window", 100, 100, 400, 300);
+ EXPECT_NE(window, nullptr);
+
+ if (window) {
+ EXPECT_EQ(window->getTitle(), "Wayland Test Window");
+ EXPECT_EQ(window->getX(), 100);
+ EXPECT_EQ(window->getY(), 100);
+ EXPECT_EQ(window->getWidth(), 400);
+ EXPECT_EQ(window->getHeight(), 300);
+ }
+ }
+}
+
+TEST_F(WaylandPlatformTest, WindowManagement) {
+ if (platform->initialize()) {
+ auto window = platform->create_window("Wayland Test Window", 100, 100, 400, 300);
+ EXPECT_NE(window, nullptr);
+
+ if (window) {
+ // Test window positioning
+ platform->set_window_position(window.get(), 200, 200);
+ EXPECT_EQ(window->getX(), 200);
+ EXPECT_EQ(window->getY(), 200);
+
+ // Test window sizing
+ platform->set_window_size(window.get(), 500, 400);
+ EXPECT_EQ(window->getWidth(), 500);
+ EXPECT_EQ(window->getHeight(), 400);
+
+ // Test window focusing
+ platform->focus_window(window.get());
+
+ // Test window destruction
+ platform->destroy_window(window.get());
+ }
+ }
+}
+
+TEST_F(WaylandPlatformTest, DecorationControls) {
+ if (platform->initialize()) {
+ auto window = platform->create_window("Wayland Test Window", 100, 100, 400, 300);
+ EXPECT_NE(window, nullptr);
+
+ if (window) {
+ // Test decoration toggling
+ platform->set_window_decorations(window.get(), true);
+ EXPECT_TRUE(platform->get_window_decorations(window.get()));
+
+ platform->set_window_decorations(window.get(), false);
+ EXPECT_FALSE(platform->get_window_decorations(window.get()));
+
+ // Test border color
+ platform->set_window_border_color(window.get(), 255, 0, 0);
+
+ // Test border width
+ platform->set_window_border_width(window.get(), 5);
+
+ platform->destroy_window(window.get());
+ }
+ }
+}
+
+TEST_F(WaylandPlatformTest, EventPolling) {
+ if (platform->initialize()) {
+ std::vector<Event> events;
+ bool result = platform->poll_events(events);
+
+ // Should not crash, even if no events are available
+ EXPECT_TRUE(result || events.empty());
+ }
+}
+
+TEST_F(WaylandPlatformTest, InputHandling) {
+ if (platform->initialize()) {
+ // Test keyboard grabbing
+ platform->grab_keyboard();
+ platform->ungrab_keyboard();
+
+ // Test pointer grabbing
+ platform->grab_pointer();
+ platform->ungrab_pointer();
+ }
+}
+
+TEST_F(WaylandPlatformTest, XWaylandIntegration) {
+ if (platform->initialize()) {
+ // Test XWayland surface handling
+ // This would involve creating XWayland surfaces and testing their management
+ // For now, we just test that the platform doesn't crash
+ EXPECT_TRUE(true);
+ }
+}
+
+TEST_F(WaylandPlatformTest, LayerShellSupport) {
+ if (platform->initialize()) {
+ // Test layer shell surface creation and management
+ // This would involve creating layer shell surfaces for panels, notifications, etc.
+ // For now, we just test that the platform doesn't crash
+ EXPECT_TRUE(true);
+ }
+}
+
+TEST_F(WaylandPlatformTest, DecorationProtocol) {
+ if (platform->initialize()) {
+ auto window = platform->create_window("Wayland Test Window", 100, 100, 400, 300);
+ EXPECT_NE(window, nullptr);
+
+ if (window) {
+ // Test zxdg-decoration protocol
+ platform->set_window_decorations(window.get(), true);
+
+ // Test decoration mode switching
+ platform->set_window_decorations(window.get(), false);
+ platform->set_window_decorations(window.get(), true);
+
+ platform->destroy_window(window.get());
+ }
+ }
+}
+
+TEST_F(WaylandPlatformTest, MultipleWindows) {
+ if (platform->initialize()) {
+ std::vector<std::unique_ptr<Window>> windows;
+
+ // Create multiple windows
+ for (int i = 0; i < 3; ++i) {
+ auto window = platform->create_window(
+ "Wayland Test Window " + std::to_string(i),
+ 100 + i * 50, 100 + i * 50,
+ 400, 300
+ );
+ EXPECT_NE(window, nullptr);
+ windows.push_back(std::move(window));
+ }
+
+ // Test that all windows exist
+ EXPECT_EQ(windows.size(), 3);
+
+ // Clean up
+ for (auto& window : windows) {
+ platform->destroy_window(window.get());
+ }
+ }
+}
+
+TEST_F(WaylandPlatformTest, ErrorHandling) {
+ // Test with invalid window
+ Window* invalid_window = nullptr;
+
+ // These should not crash
+ platform->set_window_decorations(invalid_window, true);
+ platform->set_window_border_color(invalid_window, 255, 0, 0);
+ platform->set_window_border_width(invalid_window, 5);
+ platform->get_window_decorations(invalid_window);
+}
+
+TEST_F(WaylandPlatformTest, Shutdown) {
+ if (platform->initialize()) {
+ // Should not crash on shutdown
+ platform->shutdown();
+ }
+}
+
+int main(int argc, char **argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/tests/test_windows_platform.cc b/tests/test_windows_platform.cc
new file mode 100644
index 0000000..f4d313b
--- /dev/null
+++ b/tests/test_windows_platform.cc
@@ -0,0 +1,100 @@
+#include <gtest/gtest.h>
+#include "../src/platform/windows_platform.h"
+#include <memory>
+
+class WindowsPlatformTest : public ::testing::Test {
+protected:
+ void SetUp() override {
+ platform = std::make_unique<WindowsPlatform>();
+ }
+
+ void TearDown() override {
+ if (platform) {
+ platform->shutdown();
+ }
+ }
+
+ std::unique_ptr<WindowsPlatform> platform;
+};
+
+TEST_F(WindowsPlatformTest, Initialization) {
+ bool initialized = platform->initialize();
+
+ if (initialized) {
+ EXPECT_TRUE(platform->get_platform_name() == "Windows");
+ EXPECT_TRUE(platform->is_windows());
+ EXPECT_FALSE(platform->is_x11());
+ EXPECT_FALSE(platform->is_wayland());
+ EXPECT_FALSE(platform->is_macos());
+ }
+}
+
+TEST_F(WindowsPlatformTest, PlatformCapabilities) {
+ EXPECT_TRUE(platform->get_platform_name() == "Windows");
+ EXPECT_TRUE(platform->is_windows());
+ EXPECT_FALSE(platform->is_x11());
+ EXPECT_FALSE(platform->is_wayland());
+ EXPECT_FALSE(platform->is_macos());
+}
+
+TEST_F(WindowsPlatformTest, MonitorDetection) {
+ if (platform->initialize()) {
+ auto monitors = platform->get_monitors();
+ EXPECT_FALSE(monitors.empty());
+
+ for (const auto& monitor : monitors) {
+ EXPECT_GT(monitor.id, 0);
+ EXPECT_FALSE(monitor.name.empty());
+ EXPECT_GT(monitor.width, 0);
+ EXPECT_GT(monitor.height, 0);
+ EXPECT_GT(monitor.refresh_rate, 0);
+ }
+ }
+}
+
+TEST_F(WindowsPlatformTest, WindowCreation) {
+ if (platform->initialize()) {
+ auto window = platform->create_window("Windows Test Window", 100, 100, 400, 300);
+ EXPECT_NE(window, nullptr);
+
+ if (window) {
+ EXPECT_EQ(window->getTitle(), "Windows Test Window");
+ EXPECT_EQ(window->getX(), 100);
+ EXPECT_EQ(window->getY(), 100);
+ EXPECT_EQ(window->getWidth(), 400);
+ EXPECT_EQ(window->getHeight(), 300);
+ }
+ }
+}
+
+TEST_F(WindowsPlatformTest, DWMIntegration) {
+ if (platform->initialize()) {
+ auto window = platform->create_window("Windows Test Window", 100, 100, 400, 300);
+ EXPECT_NE(window, nullptr);
+
+ if (window) {
+ // Test DWM border color API
+ platform->set_window_border_color(window.get(), 255, 0, 0);
+
+ // Test border width
+ platform->set_window_border_width(window.get(), 5);
+
+ platform->destroy_window(window.get());
+ }
+ }
+}
+
+TEST_F(WindowsPlatformTest, EventPolling) {
+ if (platform->initialize()) {
+ std::vector<Event> events;
+ bool result = platform->poll_events(events);
+
+ // Should not crash, even if no events are available
+ EXPECT_TRUE(result || events.empty());
+ }
+}
+
+int main(int argc, char **argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/tests/test_x11_platform.cc b/tests/test_x11_platform.cc
new file mode 100644
index 0000000..dad7fc0
--- /dev/null
+++ b/tests/test_x11_platform.cc
@@ -0,0 +1,221 @@
+#include <gtest/gtest.h>
+#include "../src/platform/x11_platform.h"
+#include <memory>
+
+class X11PlatformTest : public ::testing::Test {
+protected:
+ void SetUp() override {
+ platform = std::make_unique<X11Platform>();
+ }
+
+ void TearDown() override {
+ if (platform) {
+ platform->shutdown();
+ }
+ }
+
+ std::unique_ptr<X11Platform> platform;
+};
+
+TEST_F(X11PlatformTest, Initialization) {
+ // Note: This test may fail if no X11 display is available
+ // In a real environment, this should work
+ bool initialized = platform->initialize();
+
+ if (initialized) {
+ EXPECT_TRUE(platform->get_platform_name() == "X11");
+ EXPECT_TRUE(platform->is_x11());
+ EXPECT_FALSE(platform->is_wayland());
+ EXPECT_FALSE(platform->is_windows());
+ EXPECT_FALSE(platform->is_macos());
+ }
+}
+
+TEST_F(X11PlatformTest, PlatformCapabilities) {
+ EXPECT_TRUE(platform->get_platform_name() == "X11");
+ EXPECT_TRUE(platform->is_x11());
+ EXPECT_FALSE(platform->is_wayland());
+ EXPECT_FALSE(platform->is_windows());
+ EXPECT_FALSE(platform->is_macos());
+}
+
+TEST_F(X11PlatformTest, MonitorDetection) {
+ if (platform->initialize()) {
+ auto monitors = platform->get_monitors();
+ EXPECT_FALSE(monitors.empty());
+
+ for (const auto& monitor : monitors) {
+ EXPECT_GT(monitor.id, 0);
+ EXPECT_FALSE(monitor.name.empty());
+ EXPECT_GT(monitor.width, 0);
+ EXPECT_GT(monitor.height, 0);
+ EXPECT_GT(monitor.refresh_rate, 0);
+ }
+ }
+}
+
+TEST_F(X11PlatformTest, WindowCreation) {
+ if (platform->initialize()) {
+ auto window = platform->create_window("X11 Test Window", 100, 100, 400, 300);
+ EXPECT_NE(window, nullptr);
+
+ if (window) {
+ EXPECT_EQ(window->getTitle(), "X11 Test Window");
+ EXPECT_EQ(window->getX(), 100);
+ EXPECT_EQ(window->getY(), 100);
+ EXPECT_EQ(window->getWidth(), 400);
+ EXPECT_EQ(window->getHeight(), 300);
+ }
+ }
+}
+
+TEST_F(X11PlatformTest, WindowManagement) {
+ if (platform->initialize()) {
+ auto window = platform->create_window("X11 Test Window", 100, 100, 400, 300);
+ EXPECT_NE(window, nullptr);
+
+ if (window) {
+ // Test window positioning
+ platform->set_window_position(window.get(), 200, 200);
+ EXPECT_EQ(window->getX(), 200);
+ EXPECT_EQ(window->getY(), 200);
+
+ // Test window sizing
+ platform->set_window_size(window.get(), 500, 400);
+ EXPECT_EQ(window->getWidth(), 500);
+ EXPECT_EQ(window->getHeight(), 400);
+
+ // Test window focusing
+ platform->focus_window(window.get());
+
+ // Test window destruction
+ platform->destroy_window(window.get());
+ }
+ }
+}
+
+TEST_F(X11PlatformTest, DecorationControls) {
+ if (platform->initialize()) {
+ auto window = platform->create_window("X11 Test Window", 100, 100, 400, 300);
+ EXPECT_NE(window, nullptr);
+
+ if (window) {
+ // Test decoration toggling
+ platform->set_window_decorations(window.get(), true);
+ EXPECT_TRUE(platform->get_window_decorations(window.get()));
+
+ platform->set_window_decorations(window.get(), false);
+ EXPECT_FALSE(platform->get_window_decorations(window.get()));
+
+ // Test border color
+ platform->set_window_border_color(window.get(), 255, 0, 0);
+
+ // Test border width
+ platform->set_window_border_width(window.get(), 5);
+
+ platform->destroy_window(window.get());
+ }
+ }
+}
+
+TEST_F(X11PlatformTest, EventPolling) {
+ if (platform->initialize()) {
+ std::vector<Event> events;
+ bool result = platform->poll_events(events);
+
+ // Should not crash, even if no events are available
+ EXPECT_TRUE(result || events.empty());
+ }
+}
+
+TEST_F(X11PlatformTest, InputHandling) {
+ if (platform->initialize()) {
+ // Test keyboard grabbing
+ platform->grab_keyboard();
+ platform->ungrab_keyboard();
+
+ // Test pointer grabbing
+ platform->grab_pointer();
+ platform->ungrab_pointer();
+ }
+}
+
+TEST_F(X11PlatformTest, FrameWindowCreation) {
+ if (platform->initialize()) {
+ auto window = platform->create_window("X11 Test Window", 100, 100, 400, 300);
+ EXPECT_NE(window, nullptr);
+
+ if (window) {
+ // Test frame window creation
+ platform->set_window_decorations(window.get(), true);
+
+ // Test titlebar drawing
+ // This is an internal method, but we can test that it doesn't crash
+ // platform->draw_titlebar(window.get());
+
+ platform->destroy_window(window.get());
+ }
+ }
+}
+
+TEST_F(X11PlatformTest, WindowStateOperations) {
+ if (platform->initialize()) {
+ auto window = platform->create_window("X11 Test Window", 100, 100, 400, 300);
+ EXPECT_NE(window, nullptr);
+
+ if (window) {
+ // Test window operations
+ platform->minimize_window(window.get());
+ platform->maximize_window(window.get());
+ platform->close_window(window.get());
+ }
+ }
+}
+
+TEST_F(X11PlatformTest, MultipleWindows) {
+ if (platform->initialize()) {
+ std::vector<std::unique_ptr<Window>> windows;
+
+ // Create multiple windows
+ for (int i = 0; i < 3; ++i) {
+ auto window = platform->create_window(
+ "X11 Test Window " + std::to_string(i),
+ 100 + i * 50, 100 + i * 50,
+ 400, 300
+ );
+ EXPECT_NE(window, nullptr);
+ windows.push_back(std::move(window));
+ }
+
+ // Test that all windows exist
+ EXPECT_EQ(windows.size(), 3);
+
+ // Clean up
+ for (auto& window : windows) {
+ platform->destroy_window(window.get());
+ }
+ }
+}
+
+TEST_F(X11PlatformTest, ErrorHandling) {
+ // Test with invalid window
+ Window* invalid_window = nullptr;
+
+ // These should not crash
+ platform->set_window_decorations(invalid_window, true);
+ platform->set_window_border_color(invalid_window, 255, 0, 0);
+ platform->set_window_border_width(invalid_window, 5);
+ platform->get_window_decorations(invalid_window);
+}
+
+TEST_F(X11PlatformTest, Shutdown) {
+ if (platform->initialize()) {
+ // Should not crash on shutdown
+ platform->shutdown();
+ }
+}
+
+int main(int argc, char **argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}