/ src / common / UnitTests-CommonUtils / Window.Tests.cpp
Window.Tests.cpp
  1  #include "pch.h"
  2  #include "TestHelpers.h"
  3  #include <window.h>
  4  
  5  using namespace Microsoft::VisualStudio::CppUnitTestFramework;
  6  
  7  namespace UnitTestsCommonUtils
  8  {
  9      TEST_CLASS(WindowTests)
 10      {
 11      public:
 12          // is_system_window tests
 13          TEST_METHOD(IsSystemWindow_DesktopWindow_ReturnsResult)
 14          {
 15              HWND desktop = GetDesktopWindow();
 16              Assert::IsNotNull(desktop);
 17  
 18              // Get class name
 19              char className[256] = {};
 20              GetClassNameA(desktop, className, sizeof(className));
 21  
 22              bool result = is_system_window(desktop, className);
 23              // Just verify it doesn't crash and returns a boolean
 24              Assert::IsTrue(result == true || result == false);
 25          }
 26  
 27          TEST_METHOD(IsSystemWindow_NullHwnd_ReturnsFalse)
 28          {
 29              auto shell = GetShellWindow();
 30              auto desktop = GetDesktopWindow();
 31              bool result = is_system_window(nullptr, "ClassName");
 32              bool expected = (shell == nullptr) || (desktop == nullptr);
 33              Assert::AreEqual(expected, result);
 34          }
 35  
 36          TEST_METHOD(IsSystemWindow_InvalidHwnd_ReturnsFalse)
 37          {
 38              bool result = is_system_window(reinterpret_cast<HWND>(0x12345678), "ClassName");
 39              Assert::IsFalse(result);
 40          }
 41  
 42          TEST_METHOD(IsSystemWindow_EmptyClassName_DoesNotCrash)
 43          {
 44              HWND desktop = GetDesktopWindow();
 45              bool result = is_system_window(desktop, "");
 46              // Just verify it doesn't crash
 47              Assert::IsTrue(result == true || result == false);
 48          }
 49  
 50          TEST_METHOD(IsSystemWindow_NullClassName_DoesNotCrash)
 51          {
 52              HWND desktop = GetDesktopWindow();
 53              bool result = is_system_window(desktop, nullptr);
 54              // Should handle null className gracefully
 55              Assert::IsTrue(result == true || result == false);
 56          }
 57  
 58          // GetWindowCreateParam tests
 59          TEST_METHOD(GetWindowCreateParam_ValidLparam_ReturnsValue)
 60          {
 61              struct TestData
 62              {
 63                  int value;
 64              };
 65  
 66              TestData data{ 42 };
 67              CREATESTRUCT cs{};
 68              cs.lpCreateParams = &data;
 69  
 70              auto result = GetWindowCreateParam<TestData*>(reinterpret_cast<LPARAM>(&cs));
 71              Assert::IsNotNull(result);
 72              Assert::AreEqual(42, result->value);
 73          }
 74  
 75          // Window data storage tests
 76          TEST_METHOD(WindowData_StoreAndRetrieve_Works)
 77          {
 78              // Create a simple message-only window for testing
 79              WNDCLASSW wc = {};
 80              wc.lpfnWndProc = DefWindowProcW;
 81              wc.hInstance = GetModuleHandleW(nullptr);
 82              wc.lpszClassName = L"TestWindowClass_DataTest";
 83              RegisterClassW(&wc);
 84  
 85              HWND hwnd = CreateWindowExW(0, L"TestWindowClass_DataTest", L"Test",
 86                                          0, 0, 0, 0, 0, HWND_MESSAGE, nullptr,
 87                                          GetModuleHandleW(nullptr), nullptr);
 88  
 89              if (hwnd)
 90              {
 91                  int value = 42;
 92                  int* testValue = &value;
 93                  StoreWindowParam(hwnd, testValue);
 94  
 95                  auto retrieved = GetWindowParam<int*>(hwnd);
 96                  Assert::AreEqual(testValue, retrieved);
 97  
 98                  DestroyWindow(hwnd);
 99              }
100  
101              UnregisterClassW(L"TestWindowClass_DataTest", GetModuleHandleW(nullptr));
102              Assert::IsTrue(true); // Window creation might fail in test environment
103          }
104  
105          // run_message_loop tests
106          TEST_METHOD(RunMessageLoop_UntilIdle_Completes)
107          {
108              // Run message loop until idle with a timeout
109              // This should complete quickly since there are no messages
110              auto start = std::chrono::steady_clock::now();
111  
112              run_message_loop(true, 100);
113  
114              auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
115                  std::chrono::steady_clock::now() - start);
116  
117              // Should complete within reasonable time
118              Assert::IsTrue(elapsed.count() < 500);
119          }
120  
121          TEST_METHOD(RunMessageLoop_WithTimeout_RespectsTimeout)
122          {
123              auto start = std::chrono::steady_clock::now();
124  
125              run_message_loop(false, 50);
126  
127              auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
128                  std::chrono::steady_clock::now() - start);
129  
130              // Should take at least the timeout duration
131              // Allow some tolerance for timing
132              Assert::IsTrue(elapsed.count() >= 40 && elapsed.count() < 500);
133          }
134  
135          TEST_METHOD(RunMessageLoop_ZeroTimeout_CompletesImmediately)
136          {
137              auto start = std::chrono::steady_clock::now();
138  
139              run_message_loop(false, 0);
140  
141              auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
142                  std::chrono::steady_clock::now() - start);
143  
144              // Should complete very quickly
145              Assert::IsTrue(elapsed.count() < 100);
146          }
147  
148          TEST_METHOD(RunMessageLoop_NoTimeout_ProcessesMessages)
149          {
150              // Post a quit message before starting the loop
151              PostQuitMessage(0);
152  
153              // Should process the quit message and exit
154              run_message_loop(false, std::nullopt);
155  
156              Assert::IsTrue(true);
157          }
158      };
159  }