mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-06 03:07:04 +02:00
[FancyZones] Move FancyZones out of the runner process (#11818)
* rename dll -> FancyZonesModuleInterface (#11488) * [FancyZones] Rename "fancyzones/tests" -> "fancyzones/FancyZonesTests" (#11492) * [FancyZones] Rename "fancyzones/lib" -> "fancyzones/FancyZonesLib" (#11489) * [FancyZones] New FancyZones project. (#11544) * [FancyZones] Allow single instance of "PowerToys.FancyZones.exe" (#11558) * [FancyZones] Updated bug reports (#11571) * [FancyZones] Updated installer (#11572) * [FancyZones] Update string resources (#11596) * [FancyZones] Terminate FancyZones with runner (#11696) * [FancyZones] Drop support for the module interface API to save settings (#11661) * Settings telemetry for FancyZones (#11766) * commented out test * enable dpi awareness for the process
This commit is contained in:
@@ -0,0 +1,490 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
#include <FancyZonesLib/FancyZones.h>
|
||||
#include <FancyZonesLib/FancyZonesData.h>
|
||||
#include <FancyZonesLib/Settings.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
|
||||
namespace FancyZonesUnitTests
|
||||
{
|
||||
TEST_CLASS (FancyZonesUnitTests)
|
||||
{
|
||||
HINSTANCE m_hInst;
|
||||
winrt::com_ptr<IFancyZonesSettings> m_settings;
|
||||
const std::wstring_view m_moduleName = L"FancyZonesUnitTests";
|
||||
const std::wstring_view m_modulekey = L"FancyZonesUnitTests";
|
||||
|
||||
TEST_METHOD_INITIALIZE(Init)
|
||||
{
|
||||
m_hInst = (HINSTANCE)GetModuleHandleW(nullptr);
|
||||
m_settings = MakeFancyZonesSettings(m_hInst, m_moduleName.data(), m_modulekey.data());
|
||||
Assert::IsTrue(m_settings != nullptr);
|
||||
}
|
||||
|
||||
TEST_METHOD_CLEANUP(CleanUp)
|
||||
{
|
||||
std::filesystem::remove_all(PTSettingsHelper::get_module_save_folder_location(m_moduleName));
|
||||
}
|
||||
|
||||
TEST_METHOD (Create)
|
||||
{
|
||||
auto actual = MakeFancyZones(m_hInst, m_settings, nullptr);
|
||||
Assert::IsNotNull(actual.get());
|
||||
}
|
||||
TEST_METHOD (CreateWithEmptyHinstance)
|
||||
{
|
||||
auto actual = MakeFancyZones({}, m_settings, nullptr);
|
||||
Assert::IsNotNull(actual.get());
|
||||
}
|
||||
|
||||
TEST_METHOD (CreateWithNullHinstance)
|
||||
{
|
||||
auto actual = MakeFancyZones(nullptr, m_settings, nullptr);
|
||||
Assert::IsNotNull(actual.get());
|
||||
}
|
||||
|
||||
TEST_METHOD (CreateWithNullSettings)
|
||||
{
|
||||
auto actual = MakeFancyZones(m_hInst, nullptr, nullptr);
|
||||
Assert::IsNull(actual.get());
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CLASS (FancyZonesIZoneWindowHostUnitTests)
|
||||
{
|
||||
HINSTANCE m_hInst{};
|
||||
std::wstring m_moduleName = L"FancyZonesUnitTests";
|
||||
std::wstring m_moduleKey = L"FancyZonesUnitTests";
|
||||
winrt::com_ptr<IFancyZonesSettings> m_settings = nullptr;
|
||||
winrt::com_ptr<IZoneWindowHost> m_zoneWindowHost = nullptr;
|
||||
|
||||
std::wstring serializedPowerToySettings(const Settings& settings)
|
||||
{
|
||||
PowerToysSettings::Settings ptSettings(HINSTANCE{}, L"FancyZonesUnitTests");
|
||||
|
||||
ptSettings.add_hotkey(L"fancyzones_editor_hotkey", IDS_SETTING_LAUNCH_EDITOR_HOTKEY_LABEL, settings.editorHotkey);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_shiftDrag", IDS_SETTING_DESCRIPTION_SHIFTDRAG, settings.shiftDrag);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_mouseSwitch", IDS_SETTING_DESCRIPTION_MOUSESWITCH, settings.mouseSwitch);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_overrideSnapHotkeys", IDS_SETTING_DESCRIPTION_OVERRIDE_SNAP_HOTKEYS, settings.overrideSnapHotkeys);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_moveWindowAcrossMonitors", IDS_SETTING_DESCRIPTION_MOVE_WINDOW_ACROSS_MONITORS, settings.moveWindowAcrossMonitors);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_moveWindowsBasedOnPosition", IDS_SETTING_DESCRIPTION_MOVE_WINDOWS_BASED_ON_POSITION, settings.moveWindowsBasedOnPosition);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_zoneSetChange_flashZones", IDS_SETTING_DESCRIPTION_ZONESETCHANGE_FLASHZONES, settings.zoneSetChange_flashZones);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_displayChange_moveWindows", IDS_SETTING_DESCRIPTION_DISPLAYCHANGE_MOVEWINDOWS, settings.displayChange_moveWindows);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_zoneSetChange_moveWindows", IDS_SETTING_DESCRIPTION_ZONESETCHANGE_MOVEWINDOWS, settings.zoneSetChange_moveWindows);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_appLastZone_moveWindows", IDS_SETTING_DESCRIPTION_APPLASTZONE_MOVEWINDOWS, settings.appLastZone_moveWindows);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_restoreSize", IDS_SETTING_DESCRIPTION_RESTORESIZE, settings.restoreSize);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_quickLayoutSwitch", IDS_SETTING_DESCRIPTION_QUICKLAYOUTSWITCH, settings.quickLayoutSwitch);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_flashZonesOnQuickSwitch", IDS_SETTING_DESCRIPTION_FLASHZONESONQUICKSWITCH, settings.flashZonesOnQuickSwitch);
|
||||
ptSettings.add_bool_toggle(L"use_cursorpos_editor_startupscreen", IDS_SETTING_DESCRIPTION_USE_CURSORPOS_EDITOR_STARTUPSCREEN, settings.use_cursorpos_editor_startupscreen);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_show_on_all_monitors", IDS_SETTING_DESCRIPTION_SHOW_FANCY_ZONES_ON_ALL_MONITORS, settings.showZonesOnAllMonitors);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_multi_monitor_mode", IDS_SETTING_DESCRIPTION_SPAN_ZONES_ACROSS_MONITORS, settings.spanZonesAcrossMonitors);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_makeDraggedWindowTransparent", IDS_SETTING_DESCRIPTION_MAKE_DRAGGED_WINDOW_TRANSPARENT, settings.makeDraggedWindowTransparent);
|
||||
ptSettings.add_int_spinner(L"fancyzones_highlight_opacity", IDS_SETTINGS_HIGHLIGHT_OPACITY, settings.zoneHighlightOpacity, 0, 100, 1);
|
||||
ptSettings.add_color_picker(L"fancyzones_zoneColor", IDS_SETTING_DESCRIPTION_ZONECOLOR, settings.zoneColor);
|
||||
ptSettings.add_color_picker(L"fancyzones_zoneBorderColor", IDS_SETTING_DESCRIPTION_ZONE_BORDER_COLOR, settings.zoneBorderColor);
|
||||
ptSettings.add_color_picker(L"fancyzones_zoneHighlightColor", IDS_SETTING_DESCRIPTION_ZONEHIGHLIGHTCOLOR, settings.zoneHighlightColor);
|
||||
ptSettings.add_multiline_string(L"fancyzones_excluded_apps", IDS_SETTING_EXCLUDED_APPS_DESCRIPTION, settings.excludedApps);
|
||||
|
||||
return ptSettings.serialize();
|
||||
}
|
||||
|
||||
TEST_METHOD_INITIALIZE(Init)
|
||||
{
|
||||
m_hInst = (HINSTANCE)GetModuleHandleW(nullptr);
|
||||
m_settings = MakeFancyZonesSettings(m_hInst, m_moduleName.c_str(), m_moduleKey.c_str());
|
||||
Assert::IsTrue(m_settings != nullptr);
|
||||
|
||||
auto fancyZones = MakeFancyZones(m_hInst, m_settings, nullptr);
|
||||
Assert::IsTrue(fancyZones != nullptr);
|
||||
|
||||
m_zoneWindowHost = fancyZones.as<IZoneWindowHost>();
|
||||
Assert::IsTrue(m_zoneWindowHost != nullptr);
|
||||
}
|
||||
|
||||
TEST_METHOD_CLEANUP(Cleanup)
|
||||
{
|
||||
auto settingsFolder = PTSettingsHelper::get_module_save_folder_location(m_moduleName);
|
||||
const auto settingsFile = settingsFolder + L"\\settings.json";
|
||||
std::filesystem::remove(settingsFile);
|
||||
std::filesystem::remove(settingsFolder);
|
||||
}
|
||||
|
||||
TEST_METHOD (GetZoneColor)
|
||||
{
|
||||
const auto expected = RGB(171, 175, 238);
|
||||
const Settings settings{
|
||||
.shiftDrag = true,
|
||||
.mouseSwitch = true,
|
||||
.displayChange_moveWindows = true,
|
||||
.zoneSetChange_flashZones = false,
|
||||
.zoneSetChange_moveWindows = true,
|
||||
.overrideSnapHotkeys = false,
|
||||
.moveWindowAcrossMonitors = false,
|
||||
.moveWindowsBasedOnPosition = false,
|
||||
.appLastZone_moveWindows = true,
|
||||
.restoreSize = false,
|
||||
.use_cursorpos_editor_startupscreen = true,
|
||||
.spanZonesAcrossMonitors = false,
|
||||
.zoneColor = L"#abafee",
|
||||
.zoneBorderColor = L"FAFAFA",
|
||||
.zoneHighlightColor = L"#FAFAFA",
|
||||
.zoneHighlightOpacity = 45,
|
||||
.editorHotkey = PowerToysSettings::HotkeyObject::from_settings(false, false, false, false, VK_OEM_3),
|
||||
.excludedApps = L"app\r\napp2",
|
||||
.excludedAppsArray = { L"APP", L"APP2" },
|
||||
};
|
||||
|
||||
auto config = serializedPowerToySettings(settings);
|
||||
m_settings->SetConfig(config.c_str());
|
||||
|
||||
const auto actual = m_zoneWindowHost->GetZoneColor();
|
||||
Assert::AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
TEST_METHOD (GetZoneBorderColor)
|
||||
{
|
||||
const auto expected = RGB(171, 175, 238);
|
||||
const Settings settings{
|
||||
.shiftDrag = true,
|
||||
.mouseSwitch = true,
|
||||
.displayChange_moveWindows = true,
|
||||
.zoneSetChange_flashZones = false,
|
||||
.zoneSetChange_moveWindows = true,
|
||||
.overrideSnapHotkeys = false,
|
||||
.moveWindowAcrossMonitors = false,
|
||||
.moveWindowsBasedOnPosition = false,
|
||||
.appLastZone_moveWindows = true,
|
||||
.restoreSize = false,
|
||||
.use_cursorpos_editor_startupscreen = true,
|
||||
.spanZonesAcrossMonitors = false,
|
||||
.zoneColor = L"#FAFAFA",
|
||||
.zoneBorderColor = L"#abafee",
|
||||
.zoneHighlightColor = L"#FAFAFA",
|
||||
.zoneHighlightOpacity = 45,
|
||||
.editorHotkey = PowerToysSettings::HotkeyObject::from_settings(false, false, false, false, VK_OEM_3),
|
||||
.excludedApps = L"app\r\napp2",
|
||||
.excludedAppsArray = { L"APP", L"APP2" },
|
||||
};
|
||||
|
||||
auto config = serializedPowerToySettings(settings);
|
||||
m_settings->SetConfig(config.c_str());
|
||||
|
||||
const auto actual = m_zoneWindowHost->GetZoneBorderColor();
|
||||
Assert::AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
TEST_METHOD (GetZoneHighlightColor)
|
||||
{
|
||||
const auto expected = RGB(171, 175, 238);
|
||||
const Settings settings{
|
||||
.shiftDrag = true,
|
||||
.mouseSwitch = true,
|
||||
.displayChange_moveWindows = true,
|
||||
.zoneSetChange_flashZones = false,
|
||||
.zoneSetChange_moveWindows = true,
|
||||
.overrideSnapHotkeys = false,
|
||||
.moveWindowAcrossMonitors = false,
|
||||
.moveWindowsBasedOnPosition = false,
|
||||
.appLastZone_moveWindows = true,
|
||||
.restoreSize = false,
|
||||
.use_cursorpos_editor_startupscreen = true,
|
||||
.showZonesOnAllMonitors = false,
|
||||
.spanZonesAcrossMonitors = false,
|
||||
.makeDraggedWindowTransparent = true,
|
||||
.zoneColor = L"#FAFAFA",
|
||||
.zoneBorderColor = L"FAFAFA",
|
||||
.zoneHighlightColor = L"#abafee",
|
||||
.zoneHighlightOpacity = 45,
|
||||
.editorHotkey = PowerToysSettings::HotkeyObject::from_settings(false, false, false, false, VK_OEM_3),
|
||||
.excludedApps = L"app\r\napp2",
|
||||
.excludedAppsArray = { L"APP", L"APP2" },
|
||||
};
|
||||
|
||||
auto config = serializedPowerToySettings(settings);
|
||||
m_settings->SetConfig(config.c_str());
|
||||
|
||||
const auto actual = m_zoneWindowHost->GetZoneHighlightColor();
|
||||
Assert::AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
TEST_METHOD (GetZoneHighlightOpacity)
|
||||
{
|
||||
const auto expected = 88;
|
||||
const Settings settings{
|
||||
.shiftDrag = true,
|
||||
.mouseSwitch = true,
|
||||
.displayChange_moveWindows = true,
|
||||
.zoneSetChange_flashZones = false,
|
||||
.zoneSetChange_moveWindows = true,
|
||||
.overrideSnapHotkeys = false,
|
||||
.moveWindowAcrossMonitors = false,
|
||||
.moveWindowsBasedOnPosition = false,
|
||||
.appLastZone_moveWindows = true,
|
||||
.restoreSize = false,
|
||||
.use_cursorpos_editor_startupscreen = true,
|
||||
.showZonesOnAllMonitors = false,
|
||||
.spanZonesAcrossMonitors = false,
|
||||
.makeDraggedWindowTransparent = true,
|
||||
.zoneColor = L"#FAFAFA",
|
||||
.zoneBorderColor = L"FAFAFA",
|
||||
.zoneHighlightColor = L"#abafee",
|
||||
.zoneHighlightOpacity = expected,
|
||||
.editorHotkey = PowerToysSettings::HotkeyObject::from_settings(false, false, false, false, VK_OEM_3),
|
||||
.excludedApps = L"app\r\napp2",
|
||||
.excludedAppsArray = { L"APP", L"APP2" },
|
||||
};
|
||||
|
||||
auto config = serializedPowerToySettings(settings);
|
||||
m_settings->SetConfig(config.c_str());
|
||||
|
||||
const auto actual = m_zoneWindowHost->GetZoneHighlightOpacity();
|
||||
Assert::AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
TEST_METHOD (IsMakeDraggenWindowTransparentActive)
|
||||
{
|
||||
const auto expected = true;
|
||||
const Settings settings{
|
||||
.shiftDrag = true,
|
||||
.mouseSwitch = true,
|
||||
.displayChange_moveWindows = true,
|
||||
.zoneSetChange_flashZones = false,
|
||||
.zoneSetChange_moveWindows = true,
|
||||
.overrideSnapHotkeys = false,
|
||||
.moveWindowAcrossMonitors = false,
|
||||
.moveWindowsBasedOnPosition = false,
|
||||
.appLastZone_moveWindows = true,
|
||||
.restoreSize = false,
|
||||
.use_cursorpos_editor_startupscreen = true,
|
||||
.showZonesOnAllMonitors = false,
|
||||
.spanZonesAcrossMonitors = false,
|
||||
.makeDraggedWindowTransparent = true,
|
||||
.zoneColor = L"#FAFAFA",
|
||||
.zoneBorderColor = L"FAFAFA",
|
||||
.zoneHighlightColor = L"#abafee",
|
||||
.zoneHighlightOpacity = expected,
|
||||
.editorHotkey = PowerToysSettings::HotkeyObject::from_settings(false, false, false, false, VK_OEM_3),
|
||||
.excludedApps = L"app\r\napp2",
|
||||
.excludedAppsArray = { L"APP", L"APP2" },
|
||||
};
|
||||
|
||||
auto config = serializedPowerToySettings(settings);
|
||||
m_settings->SetConfig(config.c_str());
|
||||
|
||||
Assert::AreEqual(expected, m_zoneWindowHost->isMakeDraggedWindowTransparentActive());
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CLASS (FancyZonesIFancyZonesCallbackUnitTests)
|
||||
{
|
||||
HINSTANCE m_hInst{};
|
||||
std::wstring m_moduleName = L"FancyZonesUnitTests";
|
||||
std::wstring m_moduleKey = L"FancyZonesUnitTests";
|
||||
winrt::com_ptr<IFancyZonesSettings> m_settings = nullptr;
|
||||
winrt::com_ptr<IFancyZonesCallback> m_fzCallback = nullptr;
|
||||
|
||||
FancyZonesData& m_fancyZonesData = FancyZonesDataInstance();
|
||||
|
||||
std::wstring serializedPowerToySettings(const Settings& settings)
|
||||
{
|
||||
PowerToysSettings::Settings ptSettings(HINSTANCE{}, L"FancyZonesUnitTests");
|
||||
|
||||
ptSettings.add_hotkey(L"fancyzones_editor_hotkey", IDS_SETTING_LAUNCH_EDITOR_HOTKEY_LABEL, settings.editorHotkey);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_shiftDrag", IDS_SETTING_DESCRIPTION_SHIFTDRAG, settings.shiftDrag);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_mouseSwitch", IDS_SETTING_DESCRIPTION_MOUSESWITCH, settings.mouseSwitch);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_overrideSnapHotkeys", IDS_SETTING_DESCRIPTION_OVERRIDE_SNAP_HOTKEYS, settings.overrideSnapHotkeys);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_moveWindowAcrossMonitors", IDS_SETTING_DESCRIPTION_MOVE_WINDOW_ACROSS_MONITORS, settings.moveWindowAcrossMonitors);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_moveWindowsBasedOnPosition", IDS_SETTING_DESCRIPTION_MOVE_WINDOWS_BASED_ON_POSITION, settings.moveWindowsBasedOnPosition);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_zoneSetChange_flashZones", IDS_SETTING_DESCRIPTION_ZONESETCHANGE_FLASHZONES, settings.zoneSetChange_flashZones);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_displayChange_moveWindows", IDS_SETTING_DESCRIPTION_DISPLAYCHANGE_MOVEWINDOWS, settings.displayChange_moveWindows);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_zoneSetChange_moveWindows", IDS_SETTING_DESCRIPTION_ZONESETCHANGE_MOVEWINDOWS, settings.zoneSetChange_moveWindows);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_appLastZone_moveWindows", IDS_SETTING_DESCRIPTION_APPLASTZONE_MOVEWINDOWS, settings.appLastZone_moveWindows);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_restoreSize", IDS_SETTING_DESCRIPTION_RESTORESIZE, settings.restoreSize);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_quickLayoutSwitch", IDS_SETTING_DESCRIPTION_QUICKLAYOUTSWITCH, settings.quickLayoutSwitch);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_flashZonesOnQuickSwitch", IDS_SETTING_DESCRIPTION_FLASHZONESONQUICKSWITCH, settings.flashZonesOnQuickSwitch);
|
||||
ptSettings.add_bool_toggle(L"use_cursorpos_editor_startupscreen", IDS_SETTING_DESCRIPTION_USE_CURSORPOS_EDITOR_STARTUPSCREEN, settings.use_cursorpos_editor_startupscreen);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_show_on_all_monitors", IDS_SETTING_DESCRIPTION_SHOW_FANCY_ZONES_ON_ALL_MONITORS, settings.showZonesOnAllMonitors);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_multi_monitor_mode", IDS_SETTING_DESCRIPTION_SPAN_ZONES_ACROSS_MONITORS, settings.spanZonesAcrossMonitors);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_makeDraggedWindowTransparent", IDS_SETTING_DESCRIPTION_MAKE_DRAGGED_WINDOW_TRANSPARENT, settings.makeDraggedWindowTransparent);
|
||||
ptSettings.add_int_spinner(L"fancyzones_highlight_opacity", IDS_SETTINGS_HIGHLIGHT_OPACITY, settings.zoneHighlightOpacity, 0, 100, 1);
|
||||
ptSettings.add_color_picker(L"fancyzones_zoneColor", IDS_SETTING_DESCRIPTION_ZONECOLOR, settings.zoneColor);
|
||||
ptSettings.add_color_picker(L"fancyzones_zoneBorderColor", IDS_SETTING_DESCRIPTION_ZONE_BORDER_COLOR, settings.zoneBorderColor);
|
||||
ptSettings.add_color_picker(L"fancyzones_zoneHighlightColor", IDS_SETTING_DESCRIPTION_ZONEHIGHLIGHTCOLOR, settings.zoneHighlightColor);
|
||||
ptSettings.add_multiline_string(L"fancyzones_excluded_apps", IDS_SETTING_EXCLUDED_APPS_DESCRIPTION, settings.excludedApps);
|
||||
|
||||
return ptSettings.serialize();
|
||||
}
|
||||
|
||||
void sendKeyboardInput(WORD code, bool release = false)
|
||||
{
|
||||
INPUT ip;
|
||||
ip.type = INPUT_KEYBOARD;
|
||||
ip.ki.wScan = 0; // hardware scan code for key
|
||||
ip.ki.time = 0;
|
||||
ip.ki.dwExtraInfo = 0;
|
||||
ip.ki.wVk = code;
|
||||
ip.ki.dwFlags = release ? KEYEVENTF_KEYUP : 0;
|
||||
SendInput(1, &ip, sizeof(INPUT));
|
||||
}
|
||||
|
||||
TEST_METHOD_INITIALIZE(Init)
|
||||
{
|
||||
m_hInst = (HINSTANCE)GetModuleHandleW(nullptr);
|
||||
m_settings = MakeFancyZonesSettings(m_hInst, m_moduleName.c_str(), m_moduleKey.c_str());
|
||||
Assert::IsTrue(m_settings != nullptr);
|
||||
|
||||
auto fancyZones = MakeFancyZones(m_hInst, m_settings, nullptr);
|
||||
Assert::IsTrue(fancyZones != nullptr);
|
||||
|
||||
m_fzCallback = fancyZones.as<IFancyZonesCallback>();
|
||||
Assert::IsTrue(m_fzCallback != nullptr);
|
||||
|
||||
m_fancyZonesData.clear_data();
|
||||
}
|
||||
|
||||
TEST_METHOD_CLEANUP(Cleanup)
|
||||
{
|
||||
sendKeyboardInput(VK_SHIFT, true);
|
||||
sendKeyboardInput(VK_LWIN, true);
|
||||
sendKeyboardInput(VK_CONTROL, true);
|
||||
|
||||
auto settingsFolder = PTSettingsHelper::get_module_save_folder_location(m_moduleName);
|
||||
const auto settingsFile = settingsFolder + L"\\settings.json";
|
||||
std::filesystem::remove(settingsFile);
|
||||
std::filesystem::remove(settingsFolder);
|
||||
}
|
||||
|
||||
TEST_METHOD (OnKeyDownNothingPressed)
|
||||
{
|
||||
for (DWORD code = '0'; code <= '9'; code++)
|
||||
{
|
||||
tagKBDLLHOOKSTRUCT input{};
|
||||
input.vkCode = code;
|
||||
Assert::IsFalse(m_fzCallback->OnKeyDown(&input));
|
||||
}
|
||||
|
||||
{
|
||||
tagKBDLLHOOKSTRUCT input{};
|
||||
input.vkCode = VK_LEFT;
|
||||
Assert::IsFalse(m_fzCallback->OnKeyDown(&input));
|
||||
}
|
||||
|
||||
{
|
||||
tagKBDLLHOOKSTRUCT input{};
|
||||
input.vkCode = VK_RIGHT;
|
||||
Assert::IsFalse(m_fzCallback->OnKeyDown(&input));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD (OnKeyDownShiftPressed)
|
||||
{
|
||||
sendKeyboardInput(VK_SHIFT);
|
||||
|
||||
for (DWORD code = '0'; code <= '9'; code++)
|
||||
{
|
||||
tagKBDLLHOOKSTRUCT input{};
|
||||
input.vkCode = code;
|
||||
Assert::IsFalse(m_fzCallback->OnKeyDown(&input));
|
||||
}
|
||||
|
||||
{
|
||||
tagKBDLLHOOKSTRUCT input{};
|
||||
input.vkCode = VK_LEFT;
|
||||
Assert::IsFalse(m_fzCallback->OnKeyDown(&input));
|
||||
}
|
||||
|
||||
{
|
||||
tagKBDLLHOOKSTRUCT input{};
|
||||
input.vkCode = VK_RIGHT;
|
||||
Assert::IsFalse(m_fzCallback->OnKeyDown(&input));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD (OnKeyDownWinPressed)
|
||||
{
|
||||
sendKeyboardInput(VK_LWIN);
|
||||
|
||||
for (DWORD code = '0'; code <= '9'; code++)
|
||||
{
|
||||
tagKBDLLHOOKSTRUCT input{};
|
||||
input.vkCode = code;
|
||||
Assert::IsFalse(m_fzCallback->OnKeyDown(&input));
|
||||
}
|
||||
|
||||
{
|
||||
tagKBDLLHOOKSTRUCT input{};
|
||||
input.vkCode = VK_LEFT;
|
||||
Assert::IsFalse(m_fzCallback->OnKeyDown(&input));
|
||||
}
|
||||
|
||||
{
|
||||
tagKBDLLHOOKSTRUCT input{};
|
||||
input.vkCode = VK_RIGHT;
|
||||
Assert::IsFalse(m_fzCallback->OnKeyDown(&input));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD (OnKeyDownWinShiftPressed)
|
||||
{
|
||||
sendKeyboardInput(VK_LWIN);
|
||||
sendKeyboardInput(VK_SHIFT);
|
||||
|
||||
for (DWORD code = '0'; code <= '9'; code++)
|
||||
{
|
||||
tagKBDLLHOOKSTRUCT input{};
|
||||
input.vkCode = code;
|
||||
Assert::IsFalse(m_fzCallback->OnKeyDown(&input));
|
||||
}
|
||||
|
||||
{
|
||||
tagKBDLLHOOKSTRUCT input{};
|
||||
input.vkCode = VK_LEFT;
|
||||
Assert::IsFalse(m_fzCallback->OnKeyDown(&input));
|
||||
}
|
||||
|
||||
{
|
||||
tagKBDLLHOOKSTRUCT input{};
|
||||
input.vkCode = VK_RIGHT;
|
||||
Assert::IsFalse(m_fzCallback->OnKeyDown(&input));
|
||||
}
|
||||
}
|
||||
/*
|
||||
TEST_METHOD (OnKeyDownWinCtrlPressed)
|
||||
{
|
||||
sendKeyboardInput(VK_LWIN);
|
||||
sendKeyboardInput(VK_CONTROL);
|
||||
|
||||
const Settings settings{
|
||||
.overrideSnapHotkeys = false,
|
||||
};
|
||||
|
||||
auto config = serializedPowerToySettings(settings);
|
||||
m_settings->SetConfig(config.c_str());
|
||||
|
||||
for (DWORD code = '0'; code <= '9'; code++)
|
||||
{
|
||||
tagKBDLLHOOKSTRUCT input{};
|
||||
input.vkCode = code;
|
||||
Assert::IsTrue(m_fzCallback->OnKeyDown(&input));
|
||||
}
|
||||
|
||||
{
|
||||
tagKBDLLHOOKSTRUCT input{};
|
||||
input.vkCode = VK_LEFT;
|
||||
Assert::IsFalse(m_fzCallback->OnKeyDown(&input));
|
||||
}
|
||||
|
||||
{
|
||||
tagKBDLLHOOKSTRUCT input{};
|
||||
input.vkCode = VK_RIGHT;
|
||||
Assert::IsFalse(m_fzCallback->OnKeyDown(&input));
|
||||
}
|
||||
}
|
||||
*/
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,687 @@
|
||||
#include "pch.h"
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
|
||||
#include <FancyZonesLib/Settings.h>
|
||||
#include <FancyZonesLib/FancyZones.h>
|
||||
#include <common/SettingsAPI/settings_helpers.h>
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
|
||||
namespace FancyZonesUnitTests
|
||||
{
|
||||
void compareHotkeyObjects(const PowerToysSettings::HotkeyObject& expected, const PowerToysSettings::HotkeyObject& actual)
|
||||
{
|
||||
Assert::AreEqual(expected.alt_pressed(), actual.alt_pressed());
|
||||
Assert::AreEqual(expected.ctrl_pressed(), actual.ctrl_pressed());
|
||||
Assert::AreEqual(expected.shift_pressed(), actual.shift_pressed());
|
||||
Assert::AreEqual(expected.win_pressed(), actual.win_pressed());
|
||||
|
||||
//NOTE: key_from_code may create different values
|
||||
//Assert::AreEqual(expected.get_key(), actual.get_key());
|
||||
Assert::AreEqual(expected.get_code(), actual.get_code());
|
||||
Assert::AreEqual(expected.get_modifiers(), actual.get_modifiers());
|
||||
Assert::AreEqual(expected.get_modifiers_repeat(), actual.get_modifiers_repeat());
|
||||
}
|
||||
|
||||
void compareSettings(const Settings& expected, const Settings& actual)
|
||||
{
|
||||
Assert::AreEqual(expected.shiftDrag, actual.shiftDrag);
|
||||
Assert::AreEqual(expected.mouseSwitch, actual.mouseSwitch);
|
||||
Assert::AreEqual(expected.displayChange_moveWindows, actual.displayChange_moveWindows);
|
||||
Assert::AreEqual(expected.zoneSetChange_flashZones, actual.zoneSetChange_flashZones);
|
||||
Assert::AreEqual(expected.zoneSetChange_moveWindows, actual.zoneSetChange_moveWindows);
|
||||
Assert::AreEqual(expected.overrideSnapHotkeys, actual.overrideSnapHotkeys);
|
||||
Assert::AreEqual(expected.moveWindowAcrossMonitors, actual.moveWindowAcrossMonitors);
|
||||
Assert::AreEqual(expected.moveWindowsBasedOnPosition, actual.moveWindowsBasedOnPosition);
|
||||
Assert::AreEqual(expected.appLastZone_moveWindows, actual.appLastZone_moveWindows);
|
||||
Assert::AreEqual(expected.openWindowOnActiveMonitor, actual.openWindowOnActiveMonitor);
|
||||
Assert::AreEqual(expected.restoreSize, actual.restoreSize);
|
||||
Assert::AreEqual(expected.use_cursorpos_editor_startupscreen, actual.use_cursorpos_editor_startupscreen);
|
||||
Assert::AreEqual(expected.showZonesOnAllMonitors, actual.showZonesOnAllMonitors);
|
||||
Assert::AreEqual(expected.spanZonesAcrossMonitors, actual.spanZonesAcrossMonitors);
|
||||
Assert::AreEqual(expected.makeDraggedWindowTransparent, actual.makeDraggedWindowTransparent);
|
||||
Assert::AreEqual(expected.zoneColor.c_str(), actual.zoneColor.c_str());
|
||||
Assert::AreEqual(expected.zoneBorderColor.c_str(), actual.zoneBorderColor.c_str());
|
||||
Assert::AreEqual(expected.zoneHighlightColor.c_str(), actual.zoneHighlightColor.c_str());
|
||||
Assert::AreEqual(expected.zoneHighlightOpacity, actual.zoneHighlightOpacity);
|
||||
Assert::AreEqual(expected.excludedApps.c_str(), actual.excludedApps.c_str());
|
||||
Assert::AreEqual(expected.excludedAppsArray.size(), actual.excludedAppsArray.size());
|
||||
for (int i = 0; i < expected.excludedAppsArray.size(); i++)
|
||||
{
|
||||
Assert::AreEqual(expected.excludedAppsArray[i].c_str(), actual.excludedAppsArray[i].c_str());
|
||||
}
|
||||
|
||||
compareHotkeyObjects(expected.editorHotkey, actual.editorHotkey);
|
||||
}
|
||||
|
||||
TEST_CLASS (FancyZonesSettingsCreationUnitTest)
|
||||
{
|
||||
HINSTANCE m_hInst;
|
||||
PCWSTR m_moduleName = L"FancyZonesUnitTests";
|
||||
PCWSTR m_moduleKey = L"FancyZonesUnitTests";
|
||||
std::wstring m_tmpName;
|
||||
|
||||
const PowerToysSettings::HotkeyObject m_defaultHotkeyObject = PowerToysSettings::HotkeyObject::from_settings(true, false, false, false, VK_OEM_3);
|
||||
const Settings m_defaultSettings;
|
||||
|
||||
TEST_METHOD_INITIALIZE(Init)
|
||||
{
|
||||
m_hInst = (HINSTANCE)GetModuleHandleW(nullptr);
|
||||
m_tmpName = PTSettingsHelper::get_module_save_folder_location(m_moduleName) + L"\\settings.json";
|
||||
}
|
||||
TEST_METHOD_CLEANUP(Cleanup)
|
||||
{
|
||||
std::filesystem::remove_all(PTSettingsHelper::get_module_save_folder_location(m_moduleName));
|
||||
}
|
||||
|
||||
TEST_METHOD (CreateWithHinstanceDefault)
|
||||
{
|
||||
auto actual = MakeFancyZonesSettings({}, m_moduleName, m_moduleKey);
|
||||
Assert::IsTrue(actual != nullptr);
|
||||
|
||||
auto actualSettings = actual->GetSettings();
|
||||
compareSettings(m_defaultSettings, *actualSettings);
|
||||
}
|
||||
|
||||
TEST_METHOD (CreateWithHinstanceNullptr)
|
||||
{
|
||||
auto actual = MakeFancyZonesSettings(nullptr, m_moduleName, m_moduleKey);
|
||||
Assert::IsTrue(actual != nullptr);
|
||||
|
||||
auto actualSettings = actual->GetSettings();
|
||||
compareSettings(m_defaultSettings, *actualSettings);
|
||||
}
|
||||
|
||||
TEST_METHOD (CreateWithNameEmpty)
|
||||
{
|
||||
auto actual = MakeFancyZonesSettings(m_hInst, L"", m_moduleKey);
|
||||
Assert::IsTrue(actual != nullptr);
|
||||
|
||||
auto actualSettings = actual->GetSettings();
|
||||
compareSettings(m_defaultSettings, *actualSettings);
|
||||
}
|
||||
|
||||
TEST_METHOD (Create)
|
||||
{
|
||||
//prepare data
|
||||
const Settings expected;
|
||||
|
||||
PowerToysSettings::PowerToyValues values(m_moduleName, m_moduleKey);
|
||||
values.add_property(L"fancyzones_shiftDrag", expected.shiftDrag);
|
||||
values.add_property(L"fancyzones_mouseSwitch", expected.mouseSwitch);
|
||||
values.add_property(L"fancyzones_displayChange_moveWindows", expected.displayChange_moveWindows);
|
||||
values.add_property(L"fancyzones_zoneSetChange_flashZones", expected.zoneSetChange_flashZones);
|
||||
values.add_property(L"fancyzones_zoneSetChange_moveWindows", expected.zoneSetChange_moveWindows);
|
||||
values.add_property(L"fancyzones_overrideSnapHotkeys", expected.overrideSnapHotkeys);
|
||||
values.add_property(L"fancyzones_moveWindowAcrossMonitors", expected.moveWindowAcrossMonitors);
|
||||
values.add_property(L"fancyzones_moveWindowsBasedOnPosition", expected.moveWindowsBasedOnPosition);
|
||||
values.add_property(L"fancyzones_appLastZone_moveWindows", expected.appLastZone_moveWindows);
|
||||
values.add_property(L"fancyzones_openWindowOnActiveMonitor", expected.openWindowOnActiveMonitor);
|
||||
values.add_property(L"fancyzones_restoreSize", expected.restoreSize);
|
||||
values.add_property(L"use_cursorpos_editor_startupscreen", expected.use_cursorpos_editor_startupscreen);
|
||||
values.add_property(L"fancyzones_show_on_all_monitors", expected.showZonesOnAllMonitors);
|
||||
values.add_property(L"fancyzones_multi_monitor_mode", expected.spanZonesAcrossMonitors);
|
||||
values.add_property(L"fancyzones_makeDraggedWindowTransparent", expected.makeDraggedWindowTransparent);
|
||||
values.add_property(L"fancyzones_zoneColor", expected.zoneColor);
|
||||
values.add_property(L"fancyzones_zoneBorderColor", expected.zoneBorderColor);
|
||||
values.add_property(L"fancyzones_zoneHighlightColor", expected.zoneHighlightColor);
|
||||
values.add_property(L"fancyzones_highlight_opacity", expected.zoneHighlightOpacity);
|
||||
values.add_property(L"fancyzones_editor_hotkey", expected.editorHotkey.get_json());
|
||||
values.add_property(L"fancyzones_excluded_apps", expected.excludedApps);
|
||||
|
||||
values.save_to_settings_file();
|
||||
|
||||
auto actual = MakeFancyZonesSettings(m_hInst, m_moduleName, m_moduleKey);
|
||||
Assert::IsTrue(actual != nullptr);
|
||||
|
||||
auto actualSettings = actual->GetSettings();
|
||||
compareSettings(expected, *actualSettings);
|
||||
}
|
||||
|
||||
TEST_METHOD (CreateWithMultipleApps)
|
||||
{
|
||||
//prepare data
|
||||
const Settings expected{
|
||||
.excludedApps = L"app\r\napp1\r\napp2\r\nanother app",
|
||||
.excludedAppsArray = { L"APP", L"APP1", L"APP2", L"ANOTHER APP" },
|
||||
};
|
||||
|
||||
PowerToysSettings::PowerToyValues values(m_moduleName, m_moduleKey);
|
||||
values.add_property(L"fancyzones_shiftDrag", expected.shiftDrag);
|
||||
values.add_property(L"fancyzones_mouseSwitch", expected.mouseSwitch);
|
||||
values.add_property(L"fancyzones_displayChange_moveWindows", expected.displayChange_moveWindows);
|
||||
values.add_property(L"fancyzones_zoneSetChange_flashZones", expected.zoneSetChange_flashZones);
|
||||
values.add_property(L"fancyzones_zoneSetChange_moveWindows", expected.zoneSetChange_moveWindows);
|
||||
values.add_property(L"fancyzones_overrideSnapHotkeys", expected.overrideSnapHotkeys);
|
||||
values.add_property(L"fancyzones_moveWindowAcrossMonitors", expected.moveWindowAcrossMonitors);
|
||||
values.add_property(L"fancyzones_moveWindowsBasedOnPosition", expected.moveWindowsBasedOnPosition);
|
||||
values.add_property(L"fancyzones_appLastZone_moveWindows", expected.appLastZone_moveWindows);
|
||||
values.add_property(L"fancyzones_openWindowOnActiveMonitor", expected.openWindowOnActiveMonitor);
|
||||
values.add_property(L"fancyzones_restoreSize", expected.restoreSize);
|
||||
values.add_property(L"use_cursorpos_editor_startupscreen", expected.use_cursorpos_editor_startupscreen);
|
||||
values.add_property(L"fancyzones_show_on_all_monitors", expected.showZonesOnAllMonitors);
|
||||
values.add_property(L"fancyzones_multi_monitor_mode", expected.spanZonesAcrossMonitors);
|
||||
values.add_property(L"fancyzones_makeDraggedWindowTransparent", expected.makeDraggedWindowTransparent);
|
||||
values.add_property(L"fancyzones_zoneColor", expected.zoneColor);
|
||||
values.add_property(L"fancyzones_zoneBorderColor", expected.zoneBorderColor);
|
||||
values.add_property(L"fancyzones_zoneHighlightColor", expected.zoneHighlightColor);
|
||||
values.add_property(L"fancyzones_highlight_opacity", expected.zoneHighlightOpacity);
|
||||
values.add_property(L"fancyzones_editor_hotkey", expected.editorHotkey.get_json());
|
||||
values.add_property(L"fancyzones_excluded_apps", expected.excludedApps);
|
||||
|
||||
values.save_to_settings_file();
|
||||
|
||||
auto actual = MakeFancyZonesSettings(m_hInst, m_moduleName, m_moduleKey);
|
||||
Assert::IsTrue(actual != nullptr);
|
||||
|
||||
auto actualSettings = actual->GetSettings();
|
||||
compareSettings(expected, *actualSettings);
|
||||
}
|
||||
|
||||
TEST_METHOD (CreateWithBoolValuesMissed)
|
||||
{
|
||||
const Settings expected{
|
||||
.shiftDrag = m_defaultSettings.shiftDrag,
|
||||
.mouseSwitch = m_defaultSettings.mouseSwitch,
|
||||
.displayChange_moveWindows = m_defaultSettings.displayChange_moveWindows,
|
||||
.zoneSetChange_flashZones = m_defaultSettings.zoneSetChange_flashZones,
|
||||
.zoneSetChange_moveWindows = m_defaultSettings.zoneSetChange_moveWindows,
|
||||
.overrideSnapHotkeys = m_defaultSettings.overrideSnapHotkeys,
|
||||
.moveWindowAcrossMonitors = m_defaultSettings.moveWindowAcrossMonitors,
|
||||
.moveWindowsBasedOnPosition = m_defaultSettings.moveWindowsBasedOnPosition,
|
||||
.appLastZone_moveWindows = m_defaultSettings.appLastZone_moveWindows,
|
||||
.openWindowOnActiveMonitor = m_defaultSettings.openWindowOnActiveMonitor,
|
||||
.restoreSize = m_defaultSettings.restoreSize,
|
||||
.use_cursorpos_editor_startupscreen = m_defaultSettings.use_cursorpos_editor_startupscreen,
|
||||
.showZonesOnAllMonitors = m_defaultSettings.showZonesOnAllMonitors,
|
||||
.spanZonesAcrossMonitors = m_defaultSettings.spanZonesAcrossMonitors,
|
||||
.makeDraggedWindowTransparent = m_defaultSettings.makeDraggedWindowTransparent,
|
||||
.zoneColor = L"FAFAFA",
|
||||
.zoneBorderColor = L"CCDDEE",
|
||||
.zoneHighlightColor = L"#00FFD7",
|
||||
.zoneHighlightOpacity = 45,
|
||||
.editorHotkey = PowerToysSettings::HotkeyObject::from_settings(false, true, true, false, VK_OEM_3),
|
||||
.excludedApps = L"app",
|
||||
.excludedAppsArray = { L"APP" },
|
||||
};
|
||||
|
||||
PowerToysSettings::PowerToyValues values(m_moduleName, m_moduleKey);
|
||||
values.add_property(L"fancyzones_zoneColor", expected.zoneColor);
|
||||
values.add_property(L"fancyzones_zoneBorderColor", expected.zoneBorderColor);
|
||||
values.add_property(L"fancyzones_zoneHighlightColor", expected.zoneHighlightColor);
|
||||
values.add_property(L"fancyzones_highlight_opacity", expected.zoneHighlightOpacity);
|
||||
values.add_property(L"fancyzones_editor_hotkey", expected.editorHotkey.get_json());
|
||||
values.add_property(L"fancyzones_excluded_apps", expected.excludedApps);
|
||||
|
||||
values.save_to_settings_file();
|
||||
|
||||
auto actual = MakeFancyZonesSettings(m_hInst, m_moduleName, m_moduleKey);
|
||||
Assert::IsTrue(actual != nullptr);
|
||||
|
||||
auto actualSettings = actual->GetSettings();
|
||||
compareSettings(expected, *actualSettings);
|
||||
}
|
||||
|
||||
TEST_METHOD (CreateColorMissed)
|
||||
{
|
||||
//prepare data
|
||||
const Settings expected;
|
||||
|
||||
PowerToysSettings::PowerToyValues values(m_moduleName, m_moduleKey);
|
||||
values.add_property(L"fancyzones_shiftDrag", expected.shiftDrag);
|
||||
values.add_property(L"fancyzones_mouseSwitch", expected.mouseSwitch);
|
||||
values.add_property(L"fancyzones_displayChange_moveWindows", expected.displayChange_moveWindows);
|
||||
values.add_property(L"fancyzones_zoneSetChange_flashZones", expected.zoneSetChange_flashZones);
|
||||
values.add_property(L"fancyzones_zoneSetChange_moveWindows", expected.zoneSetChange_moveWindows);
|
||||
values.add_property(L"fancyzones_overrideSnapHotkeys", expected.overrideSnapHotkeys);
|
||||
values.add_property(L"fancyzones_moveWindowAcrossMonitors", expected.moveWindowAcrossMonitors);
|
||||
values.add_property(L"fancyzones_moveWindowsBasedOnPosition", expected.moveWindowsBasedOnPosition);
|
||||
values.add_property(L"fancyzones_appLastZone_moveWindows", expected.appLastZone_moveWindows);
|
||||
values.add_property(L"fancyzones_openWindowOnActiveMonitor", expected.openWindowOnActiveMonitor);
|
||||
values.add_property(L"fancyzones_restoreSize", expected.restoreSize);
|
||||
values.add_property(L"use_cursorpos_editor_startupscreen", expected.use_cursorpos_editor_startupscreen);
|
||||
values.add_property(L"fancyzones_show_on_all_monitors", expected.showZonesOnAllMonitors);
|
||||
values.add_property(L"fancyzones_multi_monitor_mode", expected.spanZonesAcrossMonitors);
|
||||
values.add_property(L"fancyzones_makeDraggedWindowTransparent", expected.makeDraggedWindowTransparent);
|
||||
values.add_property(L"fancyzones_highlight_opacity", expected.zoneHighlightOpacity);
|
||||
values.add_property(L"fancyzones_editor_hotkey", expected.editorHotkey.get_json());
|
||||
values.add_property(L"fancyzones_excluded_apps", expected.excludedApps);
|
||||
|
||||
values.save_to_settings_file();
|
||||
|
||||
auto actual = MakeFancyZonesSettings(m_hInst, m_moduleName, m_moduleKey);
|
||||
Assert::IsTrue(actual != nullptr);
|
||||
|
||||
auto actualSettings = actual->GetSettings();
|
||||
compareSettings(expected, *actualSettings);
|
||||
}
|
||||
|
||||
TEST_METHOD (CreateOpacityMissed)
|
||||
{
|
||||
//prepare data
|
||||
const Settings expected;
|
||||
|
||||
PowerToysSettings::PowerToyValues values(m_moduleName, m_moduleKey);
|
||||
values.add_property(L"fancyzones_shiftDrag", expected.shiftDrag);
|
||||
values.add_property(L"fancyzones_mouseSwitch", expected.mouseSwitch);
|
||||
values.add_property(L"fancyzones_displayChange_moveWindows", expected.displayChange_moveWindows);
|
||||
values.add_property(L"fancyzones_zoneSetChange_flashZones", expected.zoneSetChange_flashZones);
|
||||
values.add_property(L"fancyzones_zoneSetChange_moveWindows", expected.zoneSetChange_moveWindows);
|
||||
values.add_property(L"fancyzones_overrideSnapHotkeys", expected.overrideSnapHotkeys);
|
||||
values.add_property(L"fancyzones_moveWindowAcrossMonitors", expected.moveWindowAcrossMonitors);
|
||||
values.add_property(L"fancyzones_moveWindowsBasedOnPosition", expected.moveWindowsBasedOnPosition);
|
||||
values.add_property(L"fancyzones_appLastZone_moveWindows", expected.appLastZone_moveWindows);
|
||||
values.add_property(L"fancyzones_openWindowOnActiveMonitor", expected.openWindowOnActiveMonitor);
|
||||
values.add_property(L"fancyzones_restoreSize", expected.restoreSize);
|
||||
values.add_property(L"use_cursorpos_editor_startupscreen", expected.use_cursorpos_editor_startupscreen);
|
||||
values.add_property(L"fancyzones_show_on_all_monitors", expected.showZonesOnAllMonitors);
|
||||
values.add_property(L"fancyzones_multi_monitor_mode", expected.spanZonesAcrossMonitors);
|
||||
values.add_property(L"fancyzones_makeDraggedWindowTransparent", expected.makeDraggedWindowTransparent);
|
||||
values.add_property(L"fancyzones_zoneColor", expected.zoneColor);
|
||||
values.add_property(L"fancyzones_zoneHighlightColor", expected.zoneHighlightColor);
|
||||
values.add_property(L"fancyzones_editor_hotkey", expected.editorHotkey.get_json());
|
||||
values.add_property(L"fancyzones_excluded_apps", expected.excludedApps);
|
||||
|
||||
values.save_to_settings_file();
|
||||
|
||||
auto actual = MakeFancyZonesSettings(m_hInst, m_moduleName, m_moduleKey);
|
||||
Assert::IsTrue(actual != nullptr);
|
||||
|
||||
auto actualSettings = actual->GetSettings();
|
||||
compareSettings(expected, *actualSettings);
|
||||
}
|
||||
|
||||
TEST_METHOD (CreateHotkeyMissed)
|
||||
{
|
||||
//prepare data
|
||||
const Settings expected;
|
||||
|
||||
PowerToysSettings::PowerToyValues values(m_moduleName, m_moduleKey);
|
||||
values.add_property(L"fancyzones_shiftDrag", expected.shiftDrag);
|
||||
values.add_property(L"fancyzones_mouseSwitch", expected.mouseSwitch);
|
||||
values.add_property(L"fancyzones_displayChange_moveWindows", expected.displayChange_moveWindows);
|
||||
values.add_property(L"fancyzones_zoneSetChange_flashZones", expected.zoneSetChange_flashZones);
|
||||
values.add_property(L"fancyzones_zoneSetChange_moveWindows", expected.zoneSetChange_moveWindows);
|
||||
values.add_property(L"fancyzones_overrideSnapHotkeys", expected.overrideSnapHotkeys);
|
||||
values.add_property(L"fancyzones_moveWindowAcrossMonitors", expected.moveWindowAcrossMonitors);
|
||||
values.add_property(L"fancyzones_moveWindowsBasedOnPosition", expected.moveWindowsBasedOnPosition);
|
||||
values.add_property(L"fancyzones_appLastZone_moveWindows", expected.appLastZone_moveWindows);
|
||||
values.add_property(L"fancyzones_openWindowOnActiveMonitor", expected.openWindowOnActiveMonitor);
|
||||
values.add_property(L"fancyzones_restoreSize", expected.restoreSize);
|
||||
values.add_property(L"use_cursorpos_editor_startupscreen", expected.use_cursorpos_editor_startupscreen);
|
||||
values.add_property(L"fancyzones_show_on_all_monitors", expected.showZonesOnAllMonitors);
|
||||
values.add_property(L"fancyzones_multi_monitor_mode", expected.spanZonesAcrossMonitors);
|
||||
values.add_property(L"fancyzones_makeDraggedWindowTransparent", expected.makeDraggedWindowTransparent);
|
||||
values.add_property(L"fancyzones_zoneColor", expected.zoneColor);
|
||||
values.add_property(L"fancyzones_zoneBorderColor", expected.zoneBorderColor);
|
||||
values.add_property(L"fancyzones_zoneHighlightColor", expected.zoneHighlightColor);
|
||||
values.add_property(L"fancyzones_highlight_opacity", expected.zoneHighlightOpacity);
|
||||
values.add_property(L"fancyzones_excluded_apps", expected.excludedApps);
|
||||
|
||||
values.save_to_settings_file();
|
||||
|
||||
auto actual = MakeFancyZonesSettings(m_hInst, m_moduleName, m_moduleKey);
|
||||
Assert::IsTrue(actual != nullptr);
|
||||
|
||||
auto actualSettings = actual->GetSettings();
|
||||
compareSettings(expected, *actualSettings);
|
||||
}
|
||||
|
||||
TEST_METHOD (CreateAppsMissed)
|
||||
{
|
||||
//prepare data
|
||||
const Settings expected;
|
||||
|
||||
PowerToysSettings::PowerToyValues values(m_moduleName, m_moduleKey);
|
||||
values.add_property(L"fancyzones_shiftDrag", expected.shiftDrag);
|
||||
values.add_property(L"fancyzones_mouseSwitch", expected.mouseSwitch);
|
||||
values.add_property(L"fancyzones_displayChange_moveWindows", expected.displayChange_moveWindows);
|
||||
values.add_property(L"fancyzones_zoneSetChange_flashZones", expected.zoneSetChange_flashZones);
|
||||
values.add_property(L"fancyzones_zoneSetChange_moveWindows", expected.zoneSetChange_moveWindows);
|
||||
values.add_property(L"fancyzones_overrideSnapHotkeys", expected.overrideSnapHotkeys);
|
||||
values.add_property(L"fancyzones_moveWindowAcrossMonitors", expected.moveWindowAcrossMonitors);
|
||||
values.add_property(L"fancyzones_moveWindowsBasedOnPosition", expected.moveWindowsBasedOnPosition);
|
||||
values.add_property(L"fancyzones_appLastZone_moveWindows", expected.appLastZone_moveWindows);
|
||||
values.add_property(L"fancyzones_openWindowOnActiveMonitor", expected.openWindowOnActiveMonitor);
|
||||
values.add_property(L"fancyzones_restoreSize", expected.restoreSize);
|
||||
values.add_property(L"use_cursorpos_editor_startupscreen", expected.use_cursorpos_editor_startupscreen);
|
||||
values.add_property(L"fancyzones_show_on_all_monitors", expected.showZonesOnAllMonitors);
|
||||
values.add_property(L"fancyzones_multi_monitor_mode", expected.spanZonesAcrossMonitors);
|
||||
values.add_property(L"fancyzones_makeDraggedWindowTransparent", expected.makeDraggedWindowTransparent);
|
||||
values.add_property(L"fancyzones_zoneColor", expected.zoneColor);
|
||||
values.add_property(L"fancyzones_zoneBorderColor", expected.zoneBorderColor);
|
||||
values.add_property(L"fancyzones_zoneHighlightColor", expected.zoneHighlightColor);
|
||||
values.add_property(L"fancyzones_highlight_opacity", expected.zoneHighlightOpacity);
|
||||
values.add_property(L"fancyzones_editor_hotkey", expected.editorHotkey.get_json());
|
||||
|
||||
values.save_to_settings_file();
|
||||
|
||||
auto actual = MakeFancyZonesSettings(m_hInst, m_moduleName, m_moduleKey);
|
||||
Assert::IsTrue(actual != nullptr);
|
||||
|
||||
auto actualSettings = actual->GetSettings();
|
||||
compareSettings(expected, *actualSettings);
|
||||
}
|
||||
|
||||
TEST_METHOD (CreateWithEmptyJson)
|
||||
{
|
||||
json::to_file(m_tmpName, json::JsonObject());
|
||||
auto actual = MakeFancyZonesSettings(m_hInst, m_moduleName, m_moduleKey);
|
||||
Assert::IsTrue(actual != nullptr);
|
||||
|
||||
auto actualSettings = actual->GetSettings();
|
||||
compareSettings(m_defaultSettings, *actualSettings);
|
||||
}
|
||||
|
||||
TEST_METHOD (CreateWithCorruptedJson)
|
||||
{
|
||||
std::wofstream{ m_tmpName.data(), std::ios::binary } << L"{ \"version\": \"1.0\", \"name\": \"";
|
||||
|
||||
auto actual = MakeFancyZonesSettings(m_hInst, m_moduleName, m_moduleKey);
|
||||
|
||||
Assert::IsTrue(actual != nullptr);
|
||||
auto actualSettings = actual->GetSettings();
|
||||
compareSettings(m_defaultSettings, *actualSettings);
|
||||
}
|
||||
|
||||
TEST_METHOD (CreateWithCyrillicSymbolsInJson)
|
||||
{
|
||||
std::wofstream{ m_tmpName.data(), std::ios::binary } << L"{ \"version\": \"1.0\", \"name\": \"ФансиЗонс\"}";
|
||||
auto actual = MakeFancyZonesSettings(m_hInst, m_moduleName, m_moduleKey);
|
||||
Assert::IsTrue(actual != nullptr);
|
||||
|
||||
auto actualSettings = actual->GetSettings();
|
||||
compareSettings(m_defaultSettings, *actualSettings);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CLASS (FancyZonesSettingsCallbackUnitTests)
|
||||
{
|
||||
winrt::com_ptr<IFancyZonesSettings> m_settings = nullptr;
|
||||
PCWSTR m_moduleName = L"FancyZonesUnitTests";
|
||||
PCWSTR m_moduleKey = L"FancyZonesUnitTests";
|
||||
|
||||
struct FZCallback : public winrt::implements<FZCallback, IFancyZonesCallback>
|
||||
{
|
||||
public:
|
||||
FZCallback(bool* callFlag) :
|
||||
m_callFlag(callFlag)
|
||||
{
|
||||
*m_callFlag = false;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(bool)
|
||||
InMoveSize() noexcept { return false; }
|
||||
IFACEMETHODIMP_(void)
|
||||
MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen) noexcept {}
|
||||
IFACEMETHODIMP_(void)
|
||||
MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen) noexcept {}
|
||||
IFACEMETHODIMP_(void)
|
||||
MoveSizeEnd(HWND window, POINT const& ptScreen) noexcept {}
|
||||
IFACEMETHODIMP_(void)
|
||||
HandleWinHookEvent(const WinHookEvent* data) noexcept {}
|
||||
IFACEMETHODIMP_(void)
|
||||
VirtualDesktopChanged() noexcept {}
|
||||
IFACEMETHODIMP_(void)
|
||||
VirtualDesktopInitialize() noexcept {}
|
||||
IFACEMETHODIMP_(void)
|
||||
WindowCreated(HWND window) noexcept {}
|
||||
IFACEMETHODIMP_(bool)
|
||||
OnKeyDown(PKBDLLHOOKSTRUCT info) noexcept { return false; }
|
||||
|
||||
IFACEMETHODIMP_(void)
|
||||
ToggleEditor() noexcept
|
||||
{
|
||||
Assert::IsNotNull(m_callFlag);
|
||||
*m_callFlag = true;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(void)
|
||||
SettingsChanged() noexcept
|
||||
{
|
||||
Assert::IsNotNull(m_callFlag);
|
||||
*m_callFlag = true;
|
||||
}
|
||||
|
||||
private:
|
||||
bool* m_callFlag = nullptr;
|
||||
};
|
||||
|
||||
TEST_METHOD_INITIALIZE(Init)
|
||||
{
|
||||
HINSTANCE hInst = (HINSTANCE)GetModuleHandleW(nullptr);
|
||||
const Settings expected{
|
||||
.shiftDrag = false,
|
||||
.mouseSwitch = false,
|
||||
.displayChange_moveWindows = true,
|
||||
.zoneSetChange_flashZones = true,
|
||||
.zoneSetChange_moveWindows = true,
|
||||
.overrideSnapHotkeys = false,
|
||||
.moveWindowAcrossMonitors = false,
|
||||
.moveWindowsBasedOnPosition = false,
|
||||
.appLastZone_moveWindows = false,
|
||||
.openWindowOnActiveMonitor = false,
|
||||
.restoreSize = false,
|
||||
.use_cursorpos_editor_startupscreen = true,
|
||||
.showZonesOnAllMonitors = false,
|
||||
.spanZonesAcrossMonitors = false,
|
||||
.makeDraggedWindowTransparent = true,
|
||||
.zoneColor = L"FAFAFA",
|
||||
.zoneBorderColor = L"CCDDEE",
|
||||
.zoneHighlightColor = L"#00FFD7",
|
||||
.zoneHighlightOpacity = 45,
|
||||
.editorHotkey = PowerToysSettings::HotkeyObject::from_settings(false, true, true, false, VK_OEM_3),
|
||||
.excludedApps = L"app",
|
||||
.excludedAppsArray = { L"APP" },
|
||||
};
|
||||
|
||||
PowerToysSettings::PowerToyValues values(m_moduleName, m_moduleKey);
|
||||
values.add_property(L"fancyzones_shiftDrag", expected.shiftDrag);
|
||||
values.add_property(L"fancyzones_mouseSwitch", expected.mouseSwitch);
|
||||
values.add_property(L"fancyzones_displayChange_moveWindows", expected.displayChange_moveWindows);
|
||||
values.add_property(L"fancyzones_zoneSetChange_flashZones", expected.zoneSetChange_flashZones);
|
||||
values.add_property(L"fancyzones_zoneSetChange_moveWindows", expected.zoneSetChange_moveWindows);
|
||||
values.add_property(L"fancyzones_overrideSnapHotkeys", expected.overrideSnapHotkeys);
|
||||
values.add_property(L"fancyzones_moveWindowAcrossMonitors", expected.moveWindowAcrossMonitors);
|
||||
values.add_property(L"fancyzones_moveWindowsBasedOnPosition", expected.moveWindowsBasedOnPosition);
|
||||
values.add_property(L"fancyzones_appLastZone_moveWindows", expected.appLastZone_moveWindows);
|
||||
values.add_property(L"fancyzones_openWindowOnActiveMonitor", expected.openWindowOnActiveMonitor);
|
||||
values.add_property(L"fancyzones_restoreSize", expected.restoreSize);
|
||||
values.add_property(L"use_cursorpos_editor_startupscreen", expected.use_cursorpos_editor_startupscreen);
|
||||
values.add_property(L"fancyzones_show_on_all_monitors", expected.showZonesOnAllMonitors);
|
||||
values.add_property(L"fancyzones_multi_monitor_mode", expected.spanZonesAcrossMonitors);
|
||||
values.add_property(L"fancyzones_makeDraggedWindowTransparent", expected.makeDraggedWindowTransparent);
|
||||
values.add_property(L"fancyzones_zoneColor", expected.zoneColor);
|
||||
values.add_property(L"fancyzones_zoneBorderColor", expected.zoneBorderColor);
|
||||
values.add_property(L"fancyzones_zoneHighlightColor", expected.zoneHighlightColor);
|
||||
values.add_property(L"fancyzones_highlight_opacity", expected.zoneHighlightOpacity);
|
||||
values.add_property(L"fancyzones_editor_hotkey", expected.editorHotkey.get_json());
|
||||
values.add_property(L"fancyzones_excluded_apps", expected.excludedApps);
|
||||
|
||||
values.save_to_settings_file();
|
||||
|
||||
m_settings = MakeFancyZonesSettings(hInst, m_moduleName, m_moduleKey);
|
||||
Assert::IsTrue(m_settings != nullptr);
|
||||
}
|
||||
|
||||
TEST_METHOD_CLEANUP(Cleanup)
|
||||
{
|
||||
std::filesystem::remove_all(PTSettingsHelper::get_module_save_folder_location(m_moduleName));
|
||||
}
|
||||
|
||||
TEST_METHOD (CallbackSetConfig)
|
||||
{
|
||||
bool flag = false;
|
||||
winrt::com_ptr<FZCallback> callback = winrt::make_self<FZCallback>(&flag);
|
||||
|
||||
json::JsonObject json{};
|
||||
json.SetNamedValue(L"name", json::JsonValue::CreateStringValue(L"name"));
|
||||
|
||||
m_settings->SetCallback(callback.get());
|
||||
m_settings->SetConfig(json.Stringify().c_str());
|
||||
|
||||
Assert::IsTrue(flag);
|
||||
}
|
||||
|
||||
TEST_METHOD (CallbackGetConfig)
|
||||
{
|
||||
bool flag = false;
|
||||
winrt::com_ptr<FZCallback> callback = winrt::make_self<FZCallback>(&flag);
|
||||
|
||||
m_settings->SetCallback(callback.get());
|
||||
|
||||
int bufSize = 1;
|
||||
wchar_t buffer{};
|
||||
m_settings->GetConfig(&buffer, &bufSize);
|
||||
|
||||
Assert::IsFalse(flag);
|
||||
}
|
||||
|
||||
TEST_METHOD (CallbackGetSettings)
|
||||
{
|
||||
bool flag = false;
|
||||
winrt::com_ptr<FZCallback> callback = winrt::make_self<FZCallback>(&flag);
|
||||
|
||||
m_settings->SetCallback(callback.get());
|
||||
m_settings->GetSettings();
|
||||
|
||||
Assert::IsFalse(flag);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CLASS (FancyZonesSettingsUnitTests)
|
||||
{
|
||||
winrt::com_ptr<IFancyZonesSettings> m_settings = nullptr;
|
||||
PCWSTR m_moduleName = L"FancyZonesUnitTests";
|
||||
PCWSTR m_moduleKey = L"FancyZonesUnitTests";
|
||||
|
||||
std::wstring serializedPowerToySettings(const Settings& settings)
|
||||
{
|
||||
PowerToysSettings::Settings ptSettings(HINSTANCE{}, m_moduleName);
|
||||
ptSettings.set_description(IDS_SETTING_DESCRIPTION);
|
||||
ptSettings.set_icon_key(L"pt-fancy-zones");
|
||||
ptSettings.set_overview_link(L"https://aka.ms/PowerToysOverview_FancyZones");
|
||||
ptSettings.set_video_link(L"https://youtu.be/rTtGzZYAXgY");
|
||||
|
||||
ptSettings.add_custom_action(
|
||||
L"ToggledFZEditor", // action name.
|
||||
IDS_SETTING_LAUNCH_EDITOR_LABEL,
|
||||
IDS_SETTING_LAUNCH_EDITOR_BUTTON,
|
||||
IDS_SETTING_LAUNCH_EDITOR_DESCRIPTION);
|
||||
ptSettings.add_hotkey(L"fancyzones_editor_hotkey", IDS_SETTING_LAUNCH_EDITOR_HOTKEY_LABEL, settings.editorHotkey);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_shiftDrag", IDS_SETTING_DESCRIPTION_SHIFTDRAG, settings.shiftDrag);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_mouseSwitch", IDS_SETTING_DESCRIPTION_MOUSESWITCH, settings.mouseSwitch);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_overrideSnapHotkeys", IDS_SETTING_DESCRIPTION_OVERRIDE_SNAP_HOTKEYS, settings.overrideSnapHotkeys);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_moveWindowAcrossMonitors", IDS_SETTING_DESCRIPTION_MOVE_WINDOW_ACROSS_MONITORS, settings.moveWindowAcrossMonitors);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_moveWindowsBasedOnPosition", IDS_SETTING_DESCRIPTION_MOVE_WINDOWS_BASED_ON_POSITION, settings.moveWindowsBasedOnPosition);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_zoneSetChange_flashZones", IDS_SETTING_DESCRIPTION_ZONESETCHANGE_FLASHZONES, settings.zoneSetChange_flashZones);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_displayChange_moveWindows", IDS_SETTING_DESCRIPTION_DISPLAYCHANGE_MOVEWINDOWS, settings.displayChange_moveWindows);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_zoneSetChange_moveWindows", IDS_SETTING_DESCRIPTION_ZONESETCHANGE_MOVEWINDOWS, settings.zoneSetChange_moveWindows);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_appLastZone_moveWindows", IDS_SETTING_DESCRIPTION_APPLASTZONE_MOVEWINDOWS, settings.appLastZone_moveWindows);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_openWindowOnActiveMonitor", IDS_SETTING_DESCRIPTION_OPEN_WINDOW_ON_ACTIVE_MONITOR, settings.openWindowOnActiveMonitor);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_restoreSize", IDS_SETTING_DESCRIPTION_RESTORESIZE, settings.restoreSize);
|
||||
ptSettings.add_bool_toggle(L"use_cursorpos_editor_startupscreen", IDS_SETTING_DESCRIPTION_USE_CURSORPOS_EDITOR_STARTUPSCREEN, settings.use_cursorpos_editor_startupscreen);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_show_on_all_monitors", IDS_SETTING_DESCRIPTION_SHOW_FANCY_ZONES_ON_ALL_MONITORS, settings.showZonesOnAllMonitors);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_multi_monitor_mode", IDS_SETTING_DESCRIPTION_SPAN_ZONES_ACROSS_MONITORS, settings.spanZonesAcrossMonitors);
|
||||
ptSettings.add_bool_toggle(L"fancyzones_makeDraggedWindowTransparent", IDS_SETTING_DESCRIPTION_MAKE_DRAGGED_WINDOW_TRANSPARENT, settings.makeDraggedWindowTransparent);
|
||||
ptSettings.add_int_spinner(L"fancyzones_highlight_opacity", IDS_SETTINGS_HIGHLIGHT_OPACITY, settings.zoneHighlightOpacity, 0, 100, 1);
|
||||
ptSettings.add_color_picker(L"fancyzones_zoneColor", IDS_SETTING_DESCRIPTION_ZONECOLOR, settings.zoneColor);
|
||||
ptSettings.add_color_picker(L"fancyzones_zoneBorderColor", IDS_SETTING_DESCRIPTION_ZONE_BORDER_COLOR, settings.zoneBorderColor);
|
||||
ptSettings.add_color_picker(L"fancyzones_zoneHighlightColor", IDS_SETTING_DESCRIPTION_ZONEHIGHLIGHTCOLOR, settings.zoneHighlightColor);
|
||||
ptSettings.add_multiline_string(L"fancyzones_excluded_apps", IDS_SETTING_EXCLUDED_APPS_DESCRIPTION, settings.excludedApps);
|
||||
|
||||
return ptSettings.serialize();
|
||||
}
|
||||
|
||||
TEST_METHOD_INITIALIZE(Init)
|
||||
{
|
||||
HINSTANCE hInst = (HINSTANCE)GetModuleHandleW(nullptr);
|
||||
|
||||
m_settings = MakeFancyZonesSettings(hInst, m_moduleName, m_moduleKey);
|
||||
Assert::IsTrue(m_settings != nullptr);
|
||||
}
|
||||
|
||||
TEST_METHOD_CLEANUP(Cleanup)
|
||||
{
|
||||
std::filesystem::remove_all(PTSettingsHelper::get_module_save_folder_location(m_moduleName));
|
||||
}
|
||||
|
||||
TEST_METHOD (GetConfig)
|
||||
{
|
||||
int expectedSize = 0;
|
||||
m_settings->GetConfig(nullptr, &expectedSize);
|
||||
Assert::AreNotEqual(0, expectedSize);
|
||||
|
||||
int actualBufferSize = expectedSize;
|
||||
PWSTR actualBuffer = new wchar_t[actualBufferSize];
|
||||
|
||||
Assert::IsTrue(m_settings->GetConfig(actualBuffer, &actualBufferSize));
|
||||
Assert::AreEqual(expectedSize, actualBufferSize);
|
||||
}
|
||||
|
||||
TEST_METHOD (GetConfigSmallBuffer)
|
||||
{
|
||||
int size = 0;
|
||||
m_settings->GetConfig(nullptr, &size);
|
||||
Assert::AreNotEqual(0, size);
|
||||
|
||||
int actualBufferSize = size - 1;
|
||||
PWSTR actualBuffer = new wchar_t[actualBufferSize];
|
||||
|
||||
Assert::IsFalse(m_settings->GetConfig(actualBuffer, &actualBufferSize));
|
||||
Assert::AreEqual(size, actualBufferSize);
|
||||
}
|
||||
|
||||
TEST_METHOD (GetConfigNullBuffer)
|
||||
{
|
||||
int expectedSize = 0;
|
||||
m_settings->GetConfig(nullptr, &expectedSize);
|
||||
Assert::AreNotEqual(0, expectedSize);
|
||||
|
||||
int actualBufferSize = 0;
|
||||
|
||||
Assert::IsFalse(m_settings->GetConfig(nullptr, &actualBufferSize));
|
||||
Assert::AreEqual(expectedSize, actualBufferSize);
|
||||
}
|
||||
|
||||
TEST_METHOD (SetConfig)
|
||||
{
|
||||
//cleanup file before call set config
|
||||
const auto settingsFile = PTSettingsHelper::get_module_save_folder_location(m_moduleName) + L"\\settings.json";
|
||||
std::filesystem::remove(settingsFile);
|
||||
|
||||
const Settings expected{
|
||||
.shiftDrag = true,
|
||||
.mouseSwitch = true,
|
||||
.displayChange_moveWindows = true,
|
||||
.zoneSetChange_flashZones = false,
|
||||
.zoneSetChange_moveWindows = true,
|
||||
.overrideSnapHotkeys = false,
|
||||
.moveWindowAcrossMonitors = false,
|
||||
.appLastZone_moveWindows = true,
|
||||
.openWindowOnActiveMonitor = false,
|
||||
.restoreSize = false,
|
||||
.use_cursorpos_editor_startupscreen = true,
|
||||
.showZonesOnAllMonitors = false,
|
||||
.spanZonesAcrossMonitors = false,
|
||||
.makeDraggedWindowTransparent = true,
|
||||
.zoneColor = L"#FAFAFA",
|
||||
.zoneBorderColor = L"CCDDEE",
|
||||
.zoneHighlightColor = L"#00AABB",
|
||||
.zoneHighlightOpacity = 45,
|
||||
.editorHotkey = PowerToysSettings::HotkeyObject::from_settings(false, false, false, false, VK_OEM_3),
|
||||
.excludedApps = L"app\r\napp2",
|
||||
.excludedAppsArray = { L"APP", L"APP2" },
|
||||
};
|
||||
|
||||
auto config = serializedPowerToySettings(expected);
|
||||
m_settings->SetConfig(config.c_str());
|
||||
|
||||
auto actual = m_settings->GetSettings();
|
||||
compareSettings(expected, *actual);
|
||||
|
||||
Assert::IsTrue(std::filesystem::exists(settingsFile));
|
||||
}
|
||||
};
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,36 @@
|
||||
#include <windows.h>
|
||||
#include "resource.h"
|
||||
#include "../../../../common/version/version.h"
|
||||
|
||||
1 VERSIONINFO
|
||||
FILEVERSION FILE_VERSION
|
||||
PRODUCTVERSION PRODUCT_VERSION
|
||||
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS VS_FF_DEBUG
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
FILETYPE VFT_DLL
|
||||
FILESUBTYPE VFT2_UNKNOWN
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0" // US English (0x0409), Unicode (0x04B0) charset
|
||||
BEGIN
|
||||
VALUE "CompanyName", COMPANY_NAME
|
||||
VALUE "FileDescription", FILE_DESCRIPTION
|
||||
VALUE "FileVersion", FILE_VERSION_STRING
|
||||
VALUE "InternalName", INTERNAL_NAME
|
||||
VALUE "LegalCopyright", COPYRIGHT_NOTE
|
||||
VALUE "OriginalFilename", ORIGINAL_FILENAME
|
||||
VALUE "ProductName", PRODUCT_NAME
|
||||
VALUE "ProductVersion", PRODUCT_VERSION_STRING
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200 // US English (0x0409), Unicode (1200) charset
|
||||
END
|
||||
END
|
||||
@@ -0,0 +1,88 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>UnitTests</RootNamespace>
|
||||
<ProjectSubType>NativeUnitTestProject</ProjectSubType>
|
||||
<ProjectName>UnitTests-FancyZones</ProjectName>
|
||||
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\FancyZones\$(ProjectName)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\..\..\..\common\Telemetry;..\..\..\..\;..\..\;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>UNIT_TESTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>gdiplus.lib;dwmapi.lib;shlwapi.lib;uxtheme.lib;shcore.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="FancyZones.Spec.cpp" />
|
||||
<ClCompile Include="FancyZonesSettings.Spec.cpp" />
|
||||
<ClCompile Include="JsonHelpers.Tests.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(CIBuild)'!='true'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Util.Spec.cpp" />
|
||||
<ClCompile Include="Util.cpp" />
|
||||
<ClCompile Include="Zone.Spec.cpp" />
|
||||
<ClCompile Include="ZoneSet.Spec.cpp" />
|
||||
<ClCompile Include="ZoneWindow.Spec.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="Util.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\common\Display\Display.vcxproj">
|
||||
<Project>{caba8dfb-823b-4bf2-93ac-3f31984150d9}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\FancyZonesLib\FancyZonesLib.vcxproj">
|
||||
<Project>{f9c68edf-ac74-4b77-9af1-005d9c9f6a99}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="UnitTests-FancyZones.rc" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="..\..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pch.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ZoneSet.Spec.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Zone.Spec.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Util.Spec.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ZoneWindow.Spec.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="JsonHelpers.Tests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Util.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FancyZonesSettings.Spec.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FancyZones.Spec.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Util.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config">
|
||||
<Filter>Source Files</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="UnitTests-FancyZones.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
373
src/modules/fancyzones/FancyZonesTests/UnitTests/Util.Spec.cpp
Normal file
373
src/modules/fancyzones/FancyZonesTests/UnitTests/Util.Spec.cpp
Normal file
@@ -0,0 +1,373 @@
|
||||
#include "pch.h"
|
||||
#include "Util.h"
|
||||
#include "FancyZonesLib\util.h"
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
|
||||
namespace FancyZonesUnitTests
|
||||
{
|
||||
using namespace FancyZonesUtils;
|
||||
|
||||
void TestMonitorSetPermutations(const std::vector<std::pair<HMONITOR, RECT>>& monitorInfo)
|
||||
{
|
||||
auto monitorInfoPermutation = monitorInfo;
|
||||
|
||||
do {
|
||||
auto monitorInfoCopy = monitorInfoPermutation;
|
||||
OrderMonitors(monitorInfoCopy);
|
||||
CustomAssert::AreEqual(monitorInfo, monitorInfoCopy);
|
||||
} while (std::next_permutation(monitorInfoPermutation.begin(), monitorInfoPermutation.end(), [](auto x, auto y) { return x.first < y.first; }));
|
||||
}
|
||||
|
||||
void TestMonitorSetPermutationsOffsets(const std::vector<std::pair<HMONITOR, RECT>>& monitorInfo)
|
||||
{
|
||||
for (int offsetX = -3000; offsetX <= 3000; offsetX += 1000)
|
||||
{
|
||||
for (int offsetY = -3000; offsetY <= 3000; offsetY += 1000)
|
||||
{
|
||||
auto monitorInfoCopy = monitorInfo;
|
||||
for (auto& [monitor, rect] : monitorInfoCopy)
|
||||
{
|
||||
rect.left += offsetX;
|
||||
rect.right += offsetX;
|
||||
rect.top += offsetY;
|
||||
rect.bottom += offsetY;
|
||||
}
|
||||
TestMonitorSetPermutations(monitorInfoCopy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CLASS(UtilUnitTests)
|
||||
{
|
||||
TEST_METHOD (TestTrimDeviceId)
|
||||
{
|
||||
// We're interested in the unique part between the first and last #'s
|
||||
// Example input: \\?\DISPLAY#DELA026#5&10a58c63&0&UID16777488#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}
|
||||
// Example output: DELA026#5&10a58c63&0&UID16777488
|
||||
const std::wstring input = L"\\\\?\\DISPLAY#DELA026#5&10a58c63&0&UID16777488#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}";
|
||||
const std::wstring actual = TrimDeviceId(input);
|
||||
const std::wstring expected = L"DELA026#5&10a58c63&0&UID16777488";
|
||||
Assert::AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
TEST_METHOD(TestTrimInvalidDeviceId)
|
||||
{
|
||||
// We're interested in the unique part between the first and last #'s
|
||||
// Example input: \\?\DISPLAY#DELA026#5&10a58c63&0&UID16777488#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}
|
||||
// Example output: DELA026#5&10a58c63&0&UID16777488
|
||||
const std::wstring input = L"AnInvalidDeviceId";
|
||||
const std::wstring actual = TrimDeviceId(input);
|
||||
const std::wstring expected = L"FallbackDevice";
|
||||
Assert::AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
TEST_METHOD(TestParseDeviceId01)
|
||||
{
|
||||
const std::wstring input = L"AOC0001#5&37ac4db&0&UID160002_1536_960_{E0A2904E-889C-4532-95B1-28FE15C16F66}";
|
||||
|
||||
GUID guid;
|
||||
const auto expectedGuidStr = L"{E0A2904E-889C-4532-95B1-28FE15C16F66}";
|
||||
CLSIDFromString(expectedGuidStr, &guid);
|
||||
const FancyZonesDataTypes::DeviceIdData expected{ L"AOC0001#5&37ac4db&0&UID160002", 1536, 960, guid };
|
||||
|
||||
const auto actual = ParseDeviceId(input);
|
||||
Assert::IsTrue(actual.has_value());
|
||||
|
||||
Assert::AreEqual(expected.deviceName, actual->deviceName);
|
||||
Assert::AreEqual(expected.height, actual->height);
|
||||
Assert::AreEqual(expected.width, actual->width);
|
||||
Assert::AreEqual(expected.monitorId, actual->monitorId);
|
||||
|
||||
wil::unique_cotaskmem_string actualGuidStr;
|
||||
StringFromCLSID(actual->virtualDesktopId, &actualGuidStr);
|
||||
Assert::AreEqual(expectedGuidStr, actualGuidStr.get());
|
||||
}
|
||||
|
||||
TEST_METHOD (TestParseDeviceId02)
|
||||
{
|
||||
const std::wstring input = L"AOC0001#5&37ac4db&0&UID160002_1536_960_{E0A2904E-889C-4532-95B1-28FE15C16F66}_monitorId";
|
||||
|
||||
GUID guid;
|
||||
const auto expectedGuidStr = L"{E0A2904E-889C-4532-95B1-28FE15C16F66}";
|
||||
CLSIDFromString(expectedGuidStr, &guid);
|
||||
const FancyZonesDataTypes::DeviceIdData expected{ L"AOC0001#5&37ac4db&0&UID160002", 1536, 960, guid, L"monitorId" };
|
||||
|
||||
const auto actual = ParseDeviceId(input);
|
||||
Assert::IsTrue(actual.has_value());
|
||||
|
||||
Assert::AreEqual(expected.deviceName, actual->deviceName);
|
||||
Assert::AreEqual(expected.height, actual->height);
|
||||
Assert::AreEqual(expected.width, actual->width);
|
||||
Assert::AreEqual(expected.monitorId, actual->monitorId);
|
||||
|
||||
wil::unique_cotaskmem_string actualGuidStr;
|
||||
StringFromCLSID(actual->virtualDesktopId, &actualGuidStr);
|
||||
Assert::AreEqual(expectedGuidStr, actualGuidStr.get());
|
||||
}
|
||||
|
||||
TEST_METHOD (TestParseDeviceId03)
|
||||
{
|
||||
// difference with previous tests is in the device name: there is no # symbol
|
||||
const std::wstring input = L"AOC00015&37ac4db&0&UID160002_1536_960_{E0A2904E-889C-4532-95B1-28FE15C16F66}";
|
||||
|
||||
GUID guid;
|
||||
const auto expectedGuidStr = L"{E0A2904E-889C-4532-95B1-28FE15C16F66}";
|
||||
CLSIDFromString(expectedGuidStr, &guid);
|
||||
const FancyZonesDataTypes::DeviceIdData expected{ L"AOC00015&37ac4db&0&UID160002", 1536, 960, guid };
|
||||
|
||||
const auto actual = ParseDeviceId(input);
|
||||
Assert::IsTrue(actual.has_value());
|
||||
|
||||
Assert::AreEqual(expected.deviceName, actual->deviceName);
|
||||
Assert::AreEqual(expected.height, actual->height);
|
||||
Assert::AreEqual(expected.width, actual->width);
|
||||
Assert::AreEqual(expected.monitorId, actual->monitorId);
|
||||
|
||||
wil::unique_cotaskmem_string actualGuidStr;
|
||||
StringFromCLSID(actual->virtualDesktopId, &actualGuidStr);
|
||||
Assert::AreEqual(expectedGuidStr, actualGuidStr.get());
|
||||
}
|
||||
|
||||
TEST_METHOD (TestParseDeviceIdInvalid01)
|
||||
{
|
||||
// no width or height
|
||||
const std::wstring input = L"AOC00015&37ac4db&0&UID160002_1536960_{E0A2904E-889C-4532-95B1-28FE15C16F66}";
|
||||
const auto actual = ParseDeviceId(input);
|
||||
Assert::IsFalse(actual.has_value());
|
||||
}
|
||||
|
||||
TEST_METHOD (TestParseDeviceIdInvalid02)
|
||||
{
|
||||
// no width and height
|
||||
const std::wstring input = L"AOC00015&37ac4db&0&UID160002_{E0A2904E-889C-4532-95B1-28FE15C16F66}_monitorId";
|
||||
const auto actual = ParseDeviceId(input);
|
||||
Assert::IsFalse(actual.has_value());
|
||||
}
|
||||
|
||||
TEST_METHOD (TestParseDeviceIdInvalid03)
|
||||
{
|
||||
// no guid
|
||||
const std::wstring input = L"AOC00015&37ac4db&0&UID160002_1536960_";
|
||||
const auto actual = ParseDeviceId(input);
|
||||
Assert::IsFalse(actual.has_value());
|
||||
}
|
||||
|
||||
TEST_METHOD (TestParseDeviceIdInvalid04)
|
||||
{
|
||||
// invalid guid
|
||||
const std::wstring input = L"AOC00015&37ac4db&0&UID160002_1536960_{asdf}";
|
||||
const auto actual = ParseDeviceId(input);
|
||||
Assert::IsFalse(actual.has_value());
|
||||
}
|
||||
|
||||
TEST_METHOD (TestParseDeviceIdInvalid05)
|
||||
{
|
||||
// invalid width/height
|
||||
const std::wstring input = L"AOC00015&37ac4db&0&UID160002_15a6_960_{E0A2904E-889C-4532-95B1-28FE15C16F66}";
|
||||
const auto actual = ParseDeviceId(input);
|
||||
Assert::IsFalse(actual.has_value());
|
||||
}
|
||||
|
||||
TEST_METHOD (TestParseDeviceIdInvalid06)
|
||||
{
|
||||
// changed order
|
||||
const std::wstring input = L"AOC00015&37ac4db&0&UID160002_15a6_960_monitorId_{E0A2904E-889C-4532-95B1-28FE15C16F66}";
|
||||
const auto actual = ParseDeviceId(input);
|
||||
Assert::IsFalse(actual.has_value());
|
||||
}
|
||||
|
||||
TEST_METHOD(TestMonitorOrdering01)
|
||||
{
|
||||
// Three horizontally arranged monitors, bottom aligned, with increasing sizes
|
||||
std::vector<std::pair<HMONITOR, RECT>> monitorInfo = {
|
||||
{Mocks::Monitor(), RECT{.left = 0, .top = 200, .right = 1600, .bottom = 1100} },
|
||||
{Mocks::Monitor(), RECT{.left = 1600, .top = 100, .right = 3300, .bottom = 1100} },
|
||||
{Mocks::Monitor(), RECT{.left = 3300, .top = 0, .right = 5100, .bottom = 1100} },
|
||||
};
|
||||
|
||||
TestMonitorSetPermutationsOffsets(monitorInfo);
|
||||
}
|
||||
|
||||
TEST_METHOD(TestMonitorOrdering02)
|
||||
{
|
||||
// Three horizontally arranged monitors, bottom aligned, with equal sizes
|
||||
std::vector<std::pair<HMONITOR, RECT>> monitorInfo = {
|
||||
{Mocks::Monitor(), RECT{.left = 0, .top = 0, .right = 1600, .bottom = 900} },
|
||||
{Mocks::Monitor(), RECT{.left = 1600, .top = 0, .right = 3200, .bottom = 900} },
|
||||
{Mocks::Monitor(), RECT{.left = 3200, .top = 0, .right = 4800, .bottom = 900} },
|
||||
};
|
||||
|
||||
TestMonitorSetPermutationsOffsets(monitorInfo);
|
||||
}
|
||||
|
||||
TEST_METHOD(TestMonitorOrdering03)
|
||||
{
|
||||
// Three horizontally arranged monitors, bottom aligned, with decreasing sizes
|
||||
std::vector<std::pair<HMONITOR, RECT>> monitorInfo = {
|
||||
{Mocks::Monitor(), RECT{.left = 0, .top = 0, .right = 1800, .bottom = 1100} },
|
||||
{Mocks::Monitor(), RECT{.left = 1800, .top = 100, .right = 3500, .bottom = 1100} },
|
||||
{Mocks::Monitor(), RECT{.left = 3500, .top = 200, .right = 5100, .bottom = 1100} },
|
||||
};
|
||||
|
||||
TestMonitorSetPermutationsOffsets(monitorInfo);
|
||||
}
|
||||
|
||||
TEST_METHOD(TestMonitorOrdering04)
|
||||
{
|
||||
// Three horizontally arranged monitors, top aligned, with increasing sizes
|
||||
std::vector<std::pair<HMONITOR, RECT>> monitorInfo = {
|
||||
{Mocks::Monitor(), RECT{.left = 0, .top = 0, .right = 1600, .bottom = 900} },
|
||||
{Mocks::Monitor(), RECT{.left = 1600, .top = 0, .right = 3300, .bottom = 1000} },
|
||||
{Mocks::Monitor(), RECT{.left = 3300, .top = 0, .right = 5100, .bottom = 1100} },
|
||||
};
|
||||
|
||||
TestMonitorSetPermutationsOffsets(monitorInfo);
|
||||
}
|
||||
|
||||
TEST_METHOD(TestMonitorOrdering05)
|
||||
{
|
||||
// Three horizontally arranged monitors, top aligned, with equal sizes
|
||||
std::vector<std::pair<HMONITOR, RECT>> monitorInfo = {
|
||||
{Mocks::Monitor(), RECT{.left = 0, .top = 0, .right = 1600, .bottom = 900} },
|
||||
{Mocks::Monitor(), RECT{.left = 1600, .top = 0, .right = 3200, .bottom = 900} },
|
||||
{Mocks::Monitor(), RECT{.left = 3200, .top = 0, .right = 4800, .bottom = 900} },
|
||||
};
|
||||
|
||||
TestMonitorSetPermutationsOffsets(monitorInfo);
|
||||
}
|
||||
|
||||
TEST_METHOD(TestMonitorOrdering06)
|
||||
{
|
||||
// Three horizontally arranged monitors, top aligned, with decreasing sizes
|
||||
std::vector<std::pair<HMONITOR, RECT>> monitorInfo = {
|
||||
{Mocks::Monitor(), RECT{.left = 0, .top = 0, .right = 1800, .bottom = 1100} },
|
||||
{Mocks::Monitor(), RECT{.left = 1800, .top = 0, .right = 3500, .bottom = 1000} },
|
||||
{Mocks::Monitor(), RECT{.left = 3500, .top = 0, .right = 5100, .bottom = 900} },
|
||||
};
|
||||
|
||||
TestMonitorSetPermutationsOffsets(monitorInfo);
|
||||
}
|
||||
|
||||
TEST_METHOD(TestMonitorOrdering07)
|
||||
{
|
||||
// Three vertically arranged monitors, center aligned, with equal sizes, except the middle monitor is a bit wider
|
||||
std::vector<std::pair<HMONITOR, RECT>> monitorInfo = {
|
||||
{Mocks::Monitor(), RECT{.left = 100, .top = 0, .right = 1700, .bottom = 900} },
|
||||
{Mocks::Monitor(), RECT{.left = 0, .top = 900, .right = 1800, .bottom = 1800} },
|
||||
{Mocks::Monitor(), RECT{.left = 100, .top = 1800, .right = 1700, .bottom = 2700} },
|
||||
};
|
||||
|
||||
TestMonitorSetPermutationsOffsets(monitorInfo);
|
||||
}
|
||||
|
||||
TEST_METHOD(TestMonitorOrdering08)
|
||||
{
|
||||
// ------------------
|
||||
// | || || |
|
||||
// | || || |
|
||||
// ------------------
|
||||
// | || |
|
||||
// | || |
|
||||
// ------------------
|
||||
std::vector<std::pair<HMONITOR, RECT>> monitorInfo = {
|
||||
{Mocks::Monitor(), RECT{.left = 0, .top = 0, .right = 600, .bottom = 400} },
|
||||
{Mocks::Monitor(), RECT{.left = 600, .top = 0, .right = 1200, .bottom = 400} },
|
||||
{Mocks::Monitor(), RECT{.left = 1200, .top = 0, .right = 1800, .bottom = 400} },
|
||||
{Mocks::Monitor(), RECT{.left = 0, .top = 400, .right = 900, .bottom = 800} },
|
||||
{Mocks::Monitor(), RECT{.left = 900, .top = 400, .right = 1800, .bottom = 800} },
|
||||
};
|
||||
|
||||
TestMonitorSetPermutationsOffsets(monitorInfo);
|
||||
}
|
||||
|
||||
TEST_METHOD(TestMonitorOrdering09)
|
||||
{
|
||||
// Regular 3x3 grid
|
||||
std::vector<std::pair<HMONITOR, RECT>> monitorInfo = {
|
||||
{Mocks::Monitor(), RECT{.left = 0, .top = 0, .right = 400, .bottom = 300} },
|
||||
{Mocks::Monitor(), RECT{.left = 400, .top = 0, .right = 800, .bottom = 300} },
|
||||
{Mocks::Monitor(), RECT{.left = 800, .top = 0, .right = 1200, .bottom = 300} },
|
||||
{Mocks::Monitor(), RECT{.left = 0, .top = 300, .right = 400, .bottom = 600} },
|
||||
{Mocks::Monitor(), RECT{.left = 400, .top = 300, .right = 800, .bottom = 600} },
|
||||
{Mocks::Monitor(), RECT{.left = 800, .top = 300, .right = 1200, .bottom = 600} },
|
||||
{Mocks::Monitor(), RECT{.left = 0, .top = 600, .right = 400, .bottom = 900} },
|
||||
{Mocks::Monitor(), RECT{.left = 400, .top = 600, .right = 800, .bottom = 900} },
|
||||
{Mocks::Monitor(), RECT{.left = 800, .top = 600, .right = 1200, .bottom = 900} },
|
||||
};
|
||||
|
||||
// Reduce running time by testing only rotations
|
||||
for (int i = 0; i < 9; i++)
|
||||
{
|
||||
auto monitorInfoCopy = monitorInfo;
|
||||
std::rotate(monitorInfoCopy.begin(), monitorInfoCopy.begin() + i, monitorInfoCopy.end());
|
||||
OrderMonitors(monitorInfoCopy);
|
||||
CustomAssert::AreEqual(monitorInfo, monitorInfoCopy);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(TestMonitorOrdering10)
|
||||
{
|
||||
// ------------------
|
||||
// | || |
|
||||
// | || |
|
||||
// ------------------
|
||||
// | || || |
|
||||
// | || || |
|
||||
// ------------------
|
||||
std::vector<std::pair<HMONITOR, RECT>> monitorInfo = {
|
||||
{Mocks::Monitor(), RECT{.left = 0, .top = 0, .right = 900, .bottom = 400} },
|
||||
{Mocks::Monitor(), RECT{.left = 900, .top = 0, .right = 1800, .bottom = 400} },
|
||||
{Mocks::Monitor(), RECT{.left = 0, .top = 400, .right = 600, .bottom = 800} },
|
||||
{Mocks::Monitor(), RECT{.left = 600, .top = 400, .right = 1200, .bottom = 800} },
|
||||
{Mocks::Monitor(), RECT{.left = 1200, .top = 400, .right = 1800, .bottom = 800} },
|
||||
};
|
||||
|
||||
TestMonitorSetPermutationsOffsets(monitorInfo);
|
||||
}
|
||||
|
||||
TEST_METHOD(TestMonitorOrdering11)
|
||||
{
|
||||
// Random values, some monitors overlap, don't check order, just ensure it doesn't crash and it's the same every time
|
||||
std::vector<std::pair<HMONITOR, RECT>> monitorInfo = {
|
||||
{Mocks::Monitor(), RECT{.left = 410, .top = 630, .right = 988, .bottom = 631} },
|
||||
{Mocks::Monitor(), RECT{.left = 302, .top = 189, .right = 550, .bottom = 714} },
|
||||
{Mocks::Monitor(), RECT{.left = 158, .top = 115, .right = 657, .bottom = 499} },
|
||||
{Mocks::Monitor(), RECT{.left = 341, .top = 340, .right = 723, .bottom = 655} },
|
||||
{Mocks::Monitor(), RECT{.left = 433, .top = 393, .right = 846, .bottom = 544} },
|
||||
};
|
||||
|
||||
auto monitorInfoPermutation = monitorInfo;
|
||||
auto firstTime = monitorInfo;
|
||||
OrderMonitors(firstTime);
|
||||
|
||||
do {
|
||||
auto monitorInfoCopy = monitorInfoPermutation;
|
||||
OrderMonitors(monitorInfoCopy);
|
||||
CustomAssert::AreEqual(firstTime, monitorInfoCopy);
|
||||
} while (next_permutation(monitorInfoPermutation.begin(), monitorInfoPermutation.end(), [](auto x, auto y) { return x.first < y.first; }));
|
||||
}
|
||||
|
||||
TEST_METHOD(TestHexToRGB_rgb)
|
||||
{
|
||||
const auto expected = RGB(163, 246, 255);
|
||||
const auto actual = HexToRGB(L"#A3F6FF");
|
||||
Assert::AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
TEST_METHOD (TestHexToRGB_argb)
|
||||
{
|
||||
const auto expected = RGB(163, 246, 255);
|
||||
const auto actual = HexToRGB(L"#FFA3F6FF");
|
||||
Assert::AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
TEST_METHOD (TestHexToRGB_invalid)
|
||||
{
|
||||
const auto expected = RGB(255, 255, 255);
|
||||
const auto actual = HexToRGB(L"zzz");
|
||||
Assert::AreEqual(expected, actual);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
185
src/modules/fancyzones/FancyZonesTests/UnitTests/Util.cpp
Normal file
185
src/modules/fancyzones/FancyZonesTests/UnitTests/Util.cpp
Normal file
@@ -0,0 +1,185 @@
|
||||
#include "pch.h"
|
||||
#include "Util.h"
|
||||
|
||||
static int s_classId = 0;
|
||||
|
||||
namespace Mocks
|
||||
{
|
||||
class HwndCreator
|
||||
{
|
||||
public:
|
||||
HwndCreator(const std::wstring& title = L"");
|
||||
|
||||
~HwndCreator();
|
||||
|
||||
HWND operator()(HINSTANCE hInst);
|
||||
|
||||
void setHwnd(HWND val);
|
||||
void setCondition(bool cond);
|
||||
|
||||
inline HINSTANCE getHInstance() const { return m_hInst; }
|
||||
inline const std::wstring& getTitle() const { return m_windowTitle; }
|
||||
inline const std::wstring& getWindowClassName() const { return m_windowClassName; }
|
||||
|
||||
private:
|
||||
std::wstring m_windowTitle;
|
||||
std::wstring m_windowClassName;
|
||||
|
||||
std::mutex m_mutex;
|
||||
std::condition_variable m_conditionVar;
|
||||
bool m_conditionFlag;
|
||||
HANDLE m_thread;
|
||||
|
||||
HINSTANCE m_hInst;
|
||||
HWND m_hWnd;
|
||||
};
|
||||
|
||||
HWND WindowCreate(HINSTANCE hInst)
|
||||
{
|
||||
return HwndCreator()(hInst);
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CALLBACK DLLWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (message == WM_DESTROY)
|
||||
{
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return DefWindowProc(hwnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
BOOL RegisterDLLWindowClass(LPCWSTR szClassName, Mocks::HwndCreator* creator)
|
||||
{
|
||||
if (!creator)
|
||||
return false;
|
||||
|
||||
WNDCLASSEX wc;
|
||||
|
||||
wc.hInstance = creator->getHInstance();
|
||||
wc.lpszClassName = szClassName;
|
||||
wc.lpfnWndProc = DLLWindowProc;
|
||||
wc.cbSize = sizeof(WNDCLASSEX);
|
||||
|
||||
wc.style = CS_DBLCLKS;
|
||||
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
||||
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
|
||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
|
||||
|
||||
auto regRes = RegisterClassEx(&wc);
|
||||
return regRes;
|
||||
}
|
||||
|
||||
DWORD WINAPI ThreadProc(LPVOID lpParam)
|
||||
{
|
||||
MSG messages;
|
||||
Mocks::HwndCreator* creator = reinterpret_cast<Mocks::HwndCreator*>(lpParam);
|
||||
if (!creator)
|
||||
return -1;
|
||||
|
||||
if (RegisterDLLWindowClass((LPCWSTR)creator->getWindowClassName().c_str(), creator) != 0)
|
||||
{
|
||||
auto hWnd = CreateWindowEx(0, (LPCWSTR)creator->getWindowClassName().c_str(), (LPCWSTR)creator->getTitle().c_str(), WS_EX_APPWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 10, 10, nullptr, nullptr, creator->getHInstance(), NULL);
|
||||
SetWindowPos(hWnd, HWND_TOPMOST, 10, 10, 100, 100, SWP_SHOWWINDOW);
|
||||
creator->setHwnd(hWnd);
|
||||
creator->setCondition(true);
|
||||
|
||||
while (GetMessage(&messages, NULL, 0, 0))
|
||||
{
|
||||
TranslateMessage(&messages);
|
||||
DispatchMessage(&messages);
|
||||
}
|
||||
|
||||
creator->setHwnd(hWnd);
|
||||
}
|
||||
else
|
||||
{
|
||||
creator->setCondition(true);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
namespace Mocks
|
||||
{
|
||||
HwndCreator::HwndCreator(const std::wstring& title) :
|
||||
m_windowTitle(title), m_windowClassName(std::to_wstring(++s_classId)), m_conditionFlag(false), m_thread(nullptr), m_hInst(HINSTANCE{}), m_hWnd(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
HwndCreator::~HwndCreator()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
m_conditionVar.wait(lock, [this] { return m_conditionFlag; });
|
||||
|
||||
if (m_thread)
|
||||
{
|
||||
CloseHandle(m_thread);
|
||||
}
|
||||
}
|
||||
|
||||
HWND HwndCreator::operator()(HINSTANCE hInst)
|
||||
{
|
||||
m_hInst = hInst;
|
||||
m_conditionFlag = false;
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
|
||||
m_thread = CreateThread(0, NULL, ThreadProc, (LPVOID)this, NULL, NULL);
|
||||
m_conditionVar.wait(lock, [this] { return m_conditionFlag; });
|
||||
|
||||
return m_hWnd;
|
||||
}
|
||||
|
||||
void HwndCreator::setHwnd(HWND val)
|
||||
{
|
||||
m_hWnd = val;
|
||||
}
|
||||
|
||||
void HwndCreator::setCondition(bool cond)
|
||||
{
|
||||
m_conditionFlag = cond;
|
||||
m_conditionVar.notify_one();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::wstring Helpers::GuidToString(const GUID& guid)
|
||||
{
|
||||
OLECHAR* guidString;
|
||||
if (StringFromCLSID(guid, &guidString) == S_OK)
|
||||
{
|
||||
std::wstring guidStr{ guidString };
|
||||
CoTaskMemFree(guidString);
|
||||
return guidStr;
|
||||
}
|
||||
|
||||
return L"";
|
||||
}
|
||||
|
||||
std::wstring Helpers::CreateGuidString()
|
||||
{
|
||||
GUID guid;
|
||||
if (CoCreateGuid(&guid) == S_OK)
|
||||
{
|
||||
return GuidToString(guid);
|
||||
}
|
||||
|
||||
return L"";
|
||||
}
|
||||
|
||||
std::optional<GUID> Helpers::StringToGuid(const std::wstring& str)
|
||||
{
|
||||
GUID guid;
|
||||
if (CLSIDFromString(str.c_str(), &guid) == S_OK)
|
||||
{
|
||||
return guid;
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
77
src/modules/fancyzones/FancyZonesTests/UnitTests/Util.h
Normal file
77
src/modules/fancyzones/FancyZonesTests/UnitTests/Util.h
Normal file
@@ -0,0 +1,77 @@
|
||||
#pragma once
|
||||
|
||||
#include "FancyZonesLib/FancyZonesDataTypes.h"
|
||||
|
||||
namespace CustomAssert
|
||||
{
|
||||
static void AreEqual(const RECT& r1, const RECT& r2)
|
||||
{
|
||||
const bool equal = ((r1.left == r2.left) && (r1.right == r2.right) && (r1.top == r2.top) && (r1.bottom == r2.bottom));
|
||||
Microsoft::VisualStudio::CppUnitTestFramework::Assert::IsTrue(equal);
|
||||
}
|
||||
|
||||
static void AreEqual(GUID g1, GUID g2)
|
||||
{
|
||||
Microsoft::VisualStudio::CppUnitTestFramework::Assert::IsTrue(g1 == g2);
|
||||
}
|
||||
|
||||
static void AreEqual(FancyZonesDataTypes::ZoneSetLayoutType t1, FancyZonesDataTypes::ZoneSetLayoutType t2)
|
||||
{
|
||||
Microsoft::VisualStudio::CppUnitTestFramework::Assert::IsTrue(t1 == t2);
|
||||
}
|
||||
|
||||
static void AreEqual(const std::vector<std::pair<HMONITOR, RECT>>& a1, const std::vector<std::pair<HMONITOR, RECT>>& a2)
|
||||
{
|
||||
Microsoft::VisualStudio::CppUnitTestFramework::Assert::IsTrue(a1.size() == a2.size());
|
||||
for (size_t i = 0; i < a1.size(); i++)
|
||||
{
|
||||
Microsoft::VisualStudio::CppUnitTestFramework::Assert::IsTrue(a1[i].first == a2[i].first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace Mocks
|
||||
{
|
||||
static HWND Window()
|
||||
{
|
||||
static UINT_PTR s_nextWindow = 0;
|
||||
return reinterpret_cast<HWND>(++s_nextWindow);
|
||||
}
|
||||
|
||||
static HMONITOR Monitor()
|
||||
{
|
||||
static UINT_PTR s_nextMonitor = 0;
|
||||
return reinterpret_cast<HMONITOR>(++s_nextMonitor);
|
||||
}
|
||||
|
||||
static HINSTANCE Instance()
|
||||
{
|
||||
static UINT_PTR s_nextInstance = 0;
|
||||
return reinterpret_cast<HINSTANCE>(++s_nextInstance);
|
||||
}
|
||||
|
||||
HWND WindowCreate(HINSTANCE hInst);
|
||||
}
|
||||
|
||||
namespace Helpers
|
||||
{
|
||||
std::wstring GuidToString(const GUID& guid);
|
||||
std::wstring CreateGuidString();
|
||||
std::optional<GUID> StringToGuid(const std::wstring& str);
|
||||
}
|
||||
|
||||
template<>
|
||||
std::wstring Microsoft::VisualStudio::CppUnitTestFramework::ToString(const std::vector<int>& vec)
|
||||
{
|
||||
std::wstring str = L"{";
|
||||
for (size_t i = 0; i < vec.size(); i++)
|
||||
{
|
||||
str += std::to_wstring(vec[i]);
|
||||
if (i != vec.size() - 1)
|
||||
{
|
||||
str += L",";
|
||||
}
|
||||
}
|
||||
str += L"}";
|
||||
return str;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
#include "pch.h"
|
||||
#include "FancyZonesLib\Zone.h"
|
||||
#include "FancyZonesLib\Settings.h"
|
||||
|
||||
#include "Util.h"
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
|
||||
namespace FancyZonesUnitTests
|
||||
{
|
||||
TEST_CLASS(ZoneUnitTests)
|
||||
{
|
||||
private:
|
||||
RECT m_zoneRect{ 10, 10, 200, 200 };
|
||||
HINSTANCE m_hInst{};
|
||||
|
||||
TEST_METHOD_INITIALIZE(Init)
|
||||
{
|
||||
m_hInst = (HINSTANCE)GetModuleHandleW(nullptr);
|
||||
}
|
||||
|
||||
public:
|
||||
TEST_METHOD(TestCreateZone)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect, 1);
|
||||
Assert::IsNotNull(&zone);
|
||||
CustomAssert::AreEqual(m_zoneRect, zone->GetZoneRect());
|
||||
}
|
||||
|
||||
TEST_METHOD(TestCreateZoneZeroRect)
|
||||
{
|
||||
RECT zoneRect{ 0, 0, 0, 0 };
|
||||
winrt::com_ptr<IZone> zone = MakeZone(zoneRect, 1);
|
||||
Assert::IsNotNull(&zone);
|
||||
CustomAssert::AreEqual(zoneRect, zone->GetZoneRect());
|
||||
}
|
||||
|
||||
TEST_METHOD(GetSetId)
|
||||
{
|
||||
constexpr size_t zoneId = 123;
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect, zoneId);
|
||||
|
||||
Assert::AreEqual(zone->Id(), zoneId);
|
||||
}
|
||||
};
|
||||
}
|
||||
1127
src/modules/fancyzones/FancyZonesTests/UnitTests/ZoneSet.Spec.cpp
Normal file
1127
src/modules/fancyzones/FancyZonesTests/UnitTests/ZoneSet.Spec.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,514 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
#include <FancyZonesLib/util.h>
|
||||
#include <FancyZonesLib/ZoneSet.h>
|
||||
#include <FancyZonesLib/ZoneWindow.h>
|
||||
#include <FancyZonesLib/FancyZones.h>
|
||||
#include <FancyZonesLib/FancyZonesData.h>
|
||||
#include <FancyZonesLib/FancyZonesDataTypes.h>
|
||||
#include <FancyZonesLib/JsonHelpers.h>
|
||||
#include "Util.h"
|
||||
|
||||
#include <common/utils/process_path.h>
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
|
||||
namespace FancyZonesUnitTests
|
||||
{
|
||||
struct MockZoneWindowHost : public winrt::implements<MockZoneWindowHost, IZoneWindowHost>
|
||||
{
|
||||
IFACEMETHODIMP_(void)
|
||||
MoveWindowsOnActiveZoneSetChange() noexcept {};
|
||||
IFACEMETHODIMP_(COLORREF)
|
||||
GetZoneColor() noexcept
|
||||
{
|
||||
return RGB(0xFF, 0xFF, 0xFF);
|
||||
}
|
||||
IFACEMETHODIMP_(COLORREF)
|
||||
GetZoneBorderColor() noexcept
|
||||
{
|
||||
return RGB(0xFF, 0xFF, 0xFF);
|
||||
}
|
||||
IFACEMETHODIMP_(COLORREF)
|
||||
GetZoneHighlightColor() noexcept
|
||||
{
|
||||
return RGB(0xFF, 0xFF, 0xFF);
|
||||
}
|
||||
IFACEMETHODIMP_(IZoneWindow*)
|
||||
GetParentZoneWindow(HMONITOR monitor) noexcept
|
||||
{
|
||||
return m_zoneWindow;
|
||||
}
|
||||
IFACEMETHODIMP_(int)
|
||||
GetZoneHighlightOpacity() noexcept
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
IFACEMETHODIMP_(bool)
|
||||
isMakeDraggedWindowTransparentActive() noexcept
|
||||
{
|
||||
return true;
|
||||
}
|
||||
IFACEMETHODIMP_(bool)
|
||||
InMoveSize() noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
IFACEMETHODIMP_(Settings::OverlappingZonesAlgorithm)
|
||||
GetOverlappingZonesAlgorithm() noexcept
|
||||
{
|
||||
return Settings::OverlappingZonesAlgorithm::Smallest;
|
||||
}
|
||||
|
||||
IZoneWindow* m_zoneWindow;
|
||||
};
|
||||
|
||||
const std::wstring m_deviceId = L"\\\\?\\DISPLAY#DELA026#5&10a58c63&0&UID16777488#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}";
|
||||
const std::wstring m_virtualDesktopId = L"MyVirtualDesktopId";
|
||||
|
||||
TEST_CLASS (ZoneWindowCreationUnitTests)
|
||||
{
|
||||
std::wstringstream m_parentUniqueId;
|
||||
std::wstringstream m_uniqueId;
|
||||
|
||||
HINSTANCE m_hInst{};
|
||||
HMONITOR m_monitor{};
|
||||
MONITORINFOEX m_monitorInfo{};
|
||||
GUID m_virtualDesktopGuid{};
|
||||
|
||||
FancyZonesData& m_fancyZonesData = FancyZonesDataInstance();
|
||||
|
||||
void testZoneWindow(winrt::com_ptr<IZoneWindow> zoneWindow)
|
||||
{
|
||||
const std::wstring expectedWorkArea = std::to_wstring(m_monitorInfo.rcMonitor.right) + L"_" + std::to_wstring(m_monitorInfo.rcMonitor.bottom);
|
||||
|
||||
Assert::IsNotNull(zoneWindow.get());
|
||||
Assert::AreEqual(m_uniqueId.str().c_str(), zoneWindow->UniqueId().c_str());
|
||||
}
|
||||
|
||||
TEST_METHOD_INITIALIZE(Init)
|
||||
{
|
||||
m_hInst = (HINSTANCE)GetModuleHandleW(nullptr);
|
||||
|
||||
m_monitor = MonitorFromPoint(POINT{ 0, 0 }, MONITOR_DEFAULTTOPRIMARY);
|
||||
m_monitorInfo.cbSize = sizeof(m_monitorInfo);
|
||||
Assert::AreNotEqual(0, GetMonitorInfoW(m_monitor, &m_monitorInfo));
|
||||
|
||||
m_parentUniqueId << L"DELA026#5&10a58c63&0&UID16777488_" << m_monitorInfo.rcMonitor.right << "_" << m_monitorInfo.rcMonitor.bottom << "_{61FA9FC0-26A6-4B37-A834-491C148DFC57}";
|
||||
m_uniqueId << L"DELA026#5&10a58c63&0&UID16777488_" << m_monitorInfo.rcMonitor.right << "_" << m_monitorInfo.rcMonitor.bottom << "_{39B25DD2-130D-4B5D-8851-4791D66B1539}";
|
||||
|
||||
m_fancyZonesData.SetSettingsModulePath(L"FancyZonesUnitTests");
|
||||
m_fancyZonesData.clear_data();
|
||||
|
||||
auto guid = Helpers::StringToGuid(L"{39B25DD2-130D-4B5D-8851-4791D66B1539}");
|
||||
Assert::IsTrue(guid.has_value());
|
||||
m_virtualDesktopGuid = *guid;
|
||||
}
|
||||
|
||||
TEST_METHOD (CreateZoneWindow)
|
||||
{
|
||||
auto zoneWindow = MakeZoneWindow(winrt::make_self<MockZoneWindowHost>().get(), m_hInst, m_monitor, m_uniqueId.str(), {});
|
||||
testZoneWindow(zoneWindow);
|
||||
|
||||
auto* activeZoneSet{ zoneWindow->ActiveZoneSet() };
|
||||
Assert::IsNotNull(activeZoneSet);
|
||||
Assert::AreEqual(static_cast<int>(activeZoneSet->LayoutType()), static_cast<int>(FancyZonesDataTypes::ZoneSetLayoutType::PriorityGrid));
|
||||
Assert::AreEqual(activeZoneSet->GetZones().size(), static_cast<size_t>(3));
|
||||
}
|
||||
|
||||
TEST_METHOD (CreateZoneWindowNoHinst)
|
||||
{
|
||||
auto zoneWindow = MakeZoneWindow(winrt::make_self<MockZoneWindowHost>().get(), {}, m_monitor, m_uniqueId.str(), {});
|
||||
testZoneWindow(zoneWindow);
|
||||
|
||||
auto* activeZoneSet{ zoneWindow->ActiveZoneSet() };
|
||||
Assert::IsNotNull(activeZoneSet);
|
||||
Assert::AreEqual(static_cast<int>(activeZoneSet->LayoutType()), static_cast<int>(FancyZonesDataTypes::ZoneSetLayoutType::PriorityGrid));
|
||||
Assert::AreEqual(activeZoneSet->GetZones().size(), static_cast<size_t>(3));
|
||||
}
|
||||
|
||||
TEST_METHOD (CreateZoneWindowNoHinstFlashZones)
|
||||
{
|
||||
auto zoneWindow = MakeZoneWindow(winrt::make_self<MockZoneWindowHost>().get(), {}, m_monitor, m_uniqueId.str(), {});
|
||||
testZoneWindow(zoneWindow);
|
||||
|
||||
auto* activeZoneSet{ zoneWindow->ActiveZoneSet() };
|
||||
Assert::IsNotNull(activeZoneSet);
|
||||
Assert::AreEqual(static_cast<int>(activeZoneSet->LayoutType()), static_cast<int>(FancyZonesDataTypes::ZoneSetLayoutType::PriorityGrid));
|
||||
Assert::AreEqual(activeZoneSet->GetZones().size(), static_cast<size_t>(3));
|
||||
}
|
||||
|
||||
TEST_METHOD (CreateZoneWindowNoMonitor)
|
||||
{
|
||||
auto zoneWindow = MakeZoneWindow(winrt::make_self<MockZoneWindowHost>().get(), m_hInst, {}, m_uniqueId.str(), {});
|
||||
testZoneWindow(zoneWindow);
|
||||
}
|
||||
|
||||
TEST_METHOD (CreateZoneWindowNoDeviceId)
|
||||
{
|
||||
// Generate unique id without device id
|
||||
std::wstring uniqueId = FancyZonesUtils::GenerateUniqueId(m_monitor, {}, m_virtualDesktopId);
|
||||
auto zoneWindow = MakeZoneWindow(winrt::make_self<MockZoneWindowHost>().get(), m_hInst, m_monitor, uniqueId, {});
|
||||
|
||||
const std::wstring expectedWorkArea = std::to_wstring(m_monitorInfo.rcMonitor.right) + L"_" + std::to_wstring(m_monitorInfo.rcMonitor.bottom);
|
||||
const std::wstring expectedUniqueId = L"FallbackDevice_" + std::to_wstring(m_monitorInfo.rcMonitor.right) + L"_" + std::to_wstring(m_monitorInfo.rcMonitor.bottom) + L"_" + m_virtualDesktopId;
|
||||
|
||||
Assert::IsNotNull(zoneWindow.get());
|
||||
Assert::AreEqual(expectedUniqueId.c_str(), zoneWindow->UniqueId().c_str());
|
||||
|
||||
auto* activeZoneSet{ zoneWindow->ActiveZoneSet() };
|
||||
Assert::IsNotNull(activeZoneSet);
|
||||
Assert::AreEqual(static_cast<int>(activeZoneSet->LayoutType()), static_cast<int>(FancyZonesDataTypes::ZoneSetLayoutType::PriorityGrid));
|
||||
Assert::AreEqual(activeZoneSet->GetZones().size(), static_cast<size_t>(3));
|
||||
}
|
||||
|
||||
TEST_METHOD (CreateZoneWindowNoDesktopId)
|
||||
{
|
||||
// Generate unique id without virtual desktop id
|
||||
std::wstring uniqueId = FancyZonesUtils::GenerateUniqueId(m_monitor, m_deviceId, {});
|
||||
auto zoneWindow = MakeZoneWindow(winrt::make_self<MockZoneWindowHost>().get(), m_hInst, m_monitor, uniqueId, {});
|
||||
|
||||
const std::wstring expectedWorkArea = std::to_wstring(m_monitorInfo.rcMonitor.right) + L"_" + std::to_wstring(m_monitorInfo.rcMonitor.bottom);
|
||||
Assert::IsNotNull(zoneWindow.get());
|
||||
Assert::IsTrue(zoneWindow->UniqueId().empty());
|
||||
|
||||
auto* activeZoneSet{ zoneWindow->ActiveZoneSet() };
|
||||
Assert::IsNotNull(activeZoneSet);
|
||||
Assert::AreEqual(static_cast<int>(activeZoneSet->LayoutType()), static_cast<int>(FancyZonesDataTypes::ZoneSetLayoutType::PriorityGrid));
|
||||
Assert::AreEqual(activeZoneSet->GetZones().size(), static_cast<size_t>(3));
|
||||
}
|
||||
|
||||
TEST_METHOD (CreateZoneWindowClonedFromParent)
|
||||
{
|
||||
using namespace FancyZonesDataTypes;
|
||||
|
||||
const ZoneSetLayoutType type = ZoneSetLayoutType::PriorityGrid;
|
||||
const int spacing = 10;
|
||||
const int zoneCount = 5;
|
||||
const auto customSetGuid = Helpers::CreateGuidString();
|
||||
const auto parentZoneSet = ZoneSetData{ customSetGuid, type };
|
||||
const auto parentDeviceInfo = DeviceInfoData{ parentZoneSet, true, spacing, zoneCount };
|
||||
m_fancyZonesData.SetDeviceInfo(m_parentUniqueId.str(), parentDeviceInfo);
|
||||
|
||||
winrt::com_ptr<MockZoneWindowHost> zoneWindowHost = winrt::make_self<MockZoneWindowHost>();
|
||||
auto parentZoneWindow = MakeZoneWindow(zoneWindowHost.get(), m_hInst, m_monitor, m_parentUniqueId.str(), {});
|
||||
zoneWindowHost->m_zoneWindow = parentZoneWindow.get();
|
||||
|
||||
// newWorkArea = false - zoneWindow won't be cloned from parent
|
||||
auto actualZoneWindow = MakeZoneWindow(winrt::make_self<MockZoneWindowHost>().get(), m_hInst, m_monitor, m_uniqueId.str(), {});
|
||||
|
||||
Assert::IsNotNull(actualZoneWindow->ActiveZoneSet());
|
||||
|
||||
Assert::IsTrue(m_fancyZonesData.GetDeviceInfoMap().contains(m_uniqueId.str()));
|
||||
auto currentDeviceInfo = m_fancyZonesData.GetDeviceInfoMap().at(m_uniqueId.str());
|
||||
// default values
|
||||
Assert::AreEqual(true, currentDeviceInfo.showSpacing);
|
||||
Assert::AreEqual(3, currentDeviceInfo.zoneCount);
|
||||
Assert::AreEqual(16, currentDeviceInfo.spacing);
|
||||
Assert::AreEqual(static_cast<int>(ZoneSetLayoutType::PriorityGrid), static_cast<int>(currentDeviceInfo.activeZoneSet.type));
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CLASS (ZoneWindowUnitTests)
|
||||
{
|
||||
std::wstringstream m_uniqueId;
|
||||
|
||||
HINSTANCE m_hInst{};
|
||||
HMONITOR m_monitor{};
|
||||
MONITORINFO m_monitorInfo{};
|
||||
|
||||
FancyZonesData& m_fancyZonesData = FancyZonesDataInstance();
|
||||
|
||||
TEST_METHOD_INITIALIZE(Init)
|
||||
{
|
||||
m_hInst = (HINSTANCE)GetModuleHandleW(nullptr);
|
||||
|
||||
m_monitor = MonitorFromPoint(POINT{ 0, 0 }, MONITOR_DEFAULTTOPRIMARY);
|
||||
m_monitorInfo.cbSize = sizeof(m_monitorInfo);
|
||||
Assert::AreNotEqual(0, GetMonitorInfoW(m_monitor, &m_monitorInfo));
|
||||
|
||||
m_uniqueId << L"DELA026#5&10a58c63&0&UID16777488_" << m_monitorInfo.rcMonitor.right << "_" << m_monitorInfo.rcMonitor.bottom << "_{39B25DD2-130D-4B5D-8851-4791D66B1539}";
|
||||
|
||||
m_fancyZonesData.SetSettingsModulePath(L"FancyZonesUnitTests");
|
||||
m_fancyZonesData.clear_data();
|
||||
}
|
||||
|
||||
public:
|
||||
TEST_METHOD (MoveSizeEnter)
|
||||
{
|
||||
auto zoneWindow = MakeZoneWindow(winrt::make_self<MockZoneWindowHost>().get(), m_hInst, m_monitor, m_uniqueId.str(), {});
|
||||
|
||||
const auto expected = S_OK;
|
||||
const auto actual = zoneWindow->MoveSizeEnter(Mocks::Window());
|
||||
|
||||
Assert::AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
TEST_METHOD (MoveSizeEnterTwice)
|
||||
{
|
||||
auto zoneWindow = MakeZoneWindow(winrt::make_self<MockZoneWindowHost>().get(), m_hInst, m_monitor, m_uniqueId.str(), {});
|
||||
|
||||
const auto expected = S_OK;
|
||||
|
||||
zoneWindow->MoveSizeEnter(Mocks::Window());
|
||||
const auto actual = zoneWindow->MoveSizeEnter(Mocks::Window());
|
||||
|
||||
Assert::AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
TEST_METHOD (MoveSizeUpdate)
|
||||
{
|
||||
auto zoneWindow = MakeZoneWindow(winrt::make_self<MockZoneWindowHost>().get(), m_hInst, m_monitor, m_uniqueId.str(), {});
|
||||
|
||||
const auto expected = S_OK;
|
||||
const auto actual = zoneWindow->MoveSizeUpdate(POINT{ 0, 0 }, true, false);
|
||||
|
||||
Assert::AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
TEST_METHOD (MoveSizeUpdatePointNegativeCoordinates)
|
||||
{
|
||||
auto zoneWindow = MakeZoneWindow(winrt::make_self<MockZoneWindowHost>().get(), m_hInst, m_monitor, m_uniqueId.str(), {});
|
||||
|
||||
const auto expected = S_OK;
|
||||
const auto actual = zoneWindow->MoveSizeUpdate(POINT{ -10, -10 }, true, false);
|
||||
|
||||
Assert::AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
TEST_METHOD (MoveSizeUpdatePointBigCoordinates)
|
||||
{
|
||||
auto zoneWindow = MakeZoneWindow(winrt::make_self<MockZoneWindowHost>().get(), m_hInst, m_monitor, m_uniqueId.str(), {});
|
||||
|
||||
const auto expected = S_OK;
|
||||
const auto actual = zoneWindow->MoveSizeUpdate(POINT{ m_monitorInfo.rcMonitor.right + 1, m_monitorInfo.rcMonitor.bottom + 1 }, true, false);
|
||||
|
||||
Assert::AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
TEST_METHOD (MoveSizeEnd)
|
||||
{
|
||||
auto zoneWindow = MakeZoneWindow(winrt::make_self<MockZoneWindowHost>().get(), m_hInst, m_monitor, m_uniqueId.str(), {});
|
||||
|
||||
const auto window = Mocks::Window();
|
||||
zoneWindow->MoveSizeEnter(window);
|
||||
|
||||
const auto expected = S_OK;
|
||||
const auto actual = zoneWindow->MoveSizeEnd(window, POINT{ 0, 0 });
|
||||
Assert::AreEqual(expected, actual);
|
||||
|
||||
const auto zoneSet = zoneWindow->ActiveZoneSet();
|
||||
zoneSet->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0);
|
||||
const auto actualZoneIndexSet = zoneSet->GetZoneIndexSetFromWindow(window);
|
||||
Assert::IsFalse(std::vector<size_t>{} == actualZoneIndexSet);
|
||||
}
|
||||
|
||||
TEST_METHOD (MoveSizeEndWindowNotAdded)
|
||||
{
|
||||
auto zoneWindow = MakeZoneWindow(winrt::make_self<MockZoneWindowHost>().get(), m_hInst, m_monitor, m_uniqueId.str(), {});
|
||||
|
||||
const auto window = Mocks::Window();
|
||||
zoneWindow->MoveSizeEnter(window);
|
||||
|
||||
const auto expected = S_OK;
|
||||
const auto actual = zoneWindow->MoveSizeEnd(window, POINT{ -100, -100 });
|
||||
Assert::AreEqual(expected, actual);
|
||||
|
||||
const auto zoneSet = zoneWindow->ActiveZoneSet();
|
||||
const auto actualZoneIndexSet = zoneSet->GetZoneIndexSetFromWindow(window);
|
||||
Assert::IsTrue(std::vector<size_t>{} == actualZoneIndexSet);
|
||||
}
|
||||
|
||||
TEST_METHOD (MoveSizeEndDifferentWindows)
|
||||
{
|
||||
auto zoneWindow = MakeZoneWindow(winrt::make_self<MockZoneWindowHost>().get(), m_hInst, m_monitor, m_uniqueId.str(), {});
|
||||
|
||||
const auto window = Mocks::Window();
|
||||
zoneWindow->MoveSizeEnter(window);
|
||||
|
||||
const auto expected = E_INVALIDARG;
|
||||
const auto actual = zoneWindow->MoveSizeEnd(Mocks::Window(), POINT{ 0, 0 });
|
||||
|
||||
Assert::AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
TEST_METHOD (MoveSizeEndWindowNotSet)
|
||||
{
|
||||
auto zoneWindow = MakeZoneWindow(winrt::make_self<MockZoneWindowHost>().get(), m_hInst, m_monitor, m_uniqueId.str(), {});
|
||||
|
||||
const auto expected = E_INVALIDARG;
|
||||
const auto actual = zoneWindow->MoveSizeEnd(Mocks::Window(), POINT{ 0, 0 });
|
||||
|
||||
Assert::AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
TEST_METHOD (MoveSizeEndInvalidPoint)
|
||||
{
|
||||
auto zoneWindow = MakeZoneWindow(winrt::make_self<MockZoneWindowHost>().get(), m_hInst, m_monitor, m_uniqueId.str(), {});
|
||||
|
||||
const auto window = Mocks::Window();
|
||||
zoneWindow->MoveSizeEnter(window);
|
||||
|
||||
const auto expected = S_OK;
|
||||
const auto actual = zoneWindow->MoveSizeEnd(window, POINT{ -1, -1 });
|
||||
Assert::AreEqual(expected, actual);
|
||||
|
||||
const auto zoneSet = zoneWindow->ActiveZoneSet();
|
||||
zoneSet->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0);
|
||||
const auto actualZoneIndex = zoneSet->GetZoneIndexSetFromWindow(window);
|
||||
Assert::IsFalse(std::vector<size_t>{} == actualZoneIndex); // with invalid point zone remains the same
|
||||
}
|
||||
|
||||
TEST_METHOD (MoveWindowIntoZoneByIndex)
|
||||
{
|
||||
auto zoneWindow = MakeZoneWindow(winrt::make_self<MockZoneWindowHost>().get(), m_hInst, m_monitor, m_uniqueId.str(), {});
|
||||
Assert::IsNotNull(zoneWindow->ActiveZoneSet());
|
||||
|
||||
zoneWindow->MoveWindowIntoZoneByIndex(Mocks::Window(), 0);
|
||||
|
||||
const auto actual = zoneWindow->ActiveZoneSet();
|
||||
}
|
||||
|
||||
TEST_METHOD (MoveWindowIntoZoneByDirectionAndIndex)
|
||||
{
|
||||
auto zoneWindow = MakeZoneWindow(winrt::make_self<MockZoneWindowHost>().get(), m_hInst, m_monitor, m_uniqueId.str(), {});
|
||||
Assert::IsNotNull(zoneWindow->ActiveZoneSet());
|
||||
|
||||
const auto window = Mocks::WindowCreate(m_hInst);
|
||||
zoneWindow->MoveWindowIntoZoneByDirectionAndIndex(window, VK_RIGHT, true);
|
||||
|
||||
const auto& actualAppZoneHistory = m_fancyZonesData.GetAppZoneHistoryMap();
|
||||
Assert::AreEqual((size_t)1, actualAppZoneHistory.size());
|
||||
const auto& appHistoryArray = actualAppZoneHistory.begin()->second;
|
||||
Assert::AreEqual((size_t)1, appHistoryArray.size());
|
||||
Assert::IsTrue(std::vector<size_t>{ 0 } == appHistoryArray[0].zoneIndexSet);
|
||||
}
|
||||
|
||||
TEST_METHOD (MoveWindowIntoZoneByDirectionManyTimes)
|
||||
{
|
||||
auto zoneWindow = MakeZoneWindow(winrt::make_self<MockZoneWindowHost>().get(), m_hInst, m_monitor, m_uniqueId.str(), {});
|
||||
Assert::IsNotNull(zoneWindow->ActiveZoneSet());
|
||||
|
||||
const auto window = Mocks::WindowCreate(m_hInst);
|
||||
zoneWindow->MoveWindowIntoZoneByDirectionAndIndex(window, VK_RIGHT, true);
|
||||
zoneWindow->MoveWindowIntoZoneByDirectionAndIndex(window, VK_RIGHT, true);
|
||||
zoneWindow->MoveWindowIntoZoneByDirectionAndIndex(window, VK_RIGHT, true);
|
||||
|
||||
const auto& actualAppZoneHistory = m_fancyZonesData.GetAppZoneHistoryMap();
|
||||
Assert::AreEqual((size_t)1, actualAppZoneHistory.size());
|
||||
const auto& appHistoryArray = actualAppZoneHistory.begin()->second;
|
||||
Assert::AreEqual((size_t)1, appHistoryArray.size());
|
||||
Assert::IsTrue(std::vector<size_t>{ 2 } == appHistoryArray[0].zoneIndexSet);
|
||||
}
|
||||
|
||||
TEST_METHOD (SaveWindowProcessToZoneIndexNullptrWindow)
|
||||
{
|
||||
auto zoneWindow = MakeZoneWindow(winrt::make_self<MockZoneWindowHost>().get(), m_hInst, m_monitor, m_uniqueId.str(), {});
|
||||
Assert::IsNotNull(zoneWindow->ActiveZoneSet());
|
||||
|
||||
zoneWindow->SaveWindowProcessToZoneIndex(nullptr);
|
||||
|
||||
const auto actualAppZoneHistory = m_fancyZonesData.GetAppZoneHistoryMap();
|
||||
Assert::IsTrue(actualAppZoneHistory.empty());
|
||||
}
|
||||
|
||||
TEST_METHOD (SaveWindowProcessToZoneIndexNoWindowAdded)
|
||||
{
|
||||
auto zoneWindow = MakeZoneWindow(winrt::make_self<MockZoneWindowHost>().get(), m_hInst, m_monitor, m_uniqueId.str(), {});
|
||||
Assert::IsNotNull(zoneWindow->ActiveZoneSet());
|
||||
|
||||
auto window = Mocks::WindowCreate(m_hInst);
|
||||
auto zone = MakeZone(RECT{ 0, 0, 100, 100 }, 1);
|
||||
zoneWindow->ActiveZoneSet()->AddZone(zone);
|
||||
|
||||
zoneWindow->SaveWindowProcessToZoneIndex(window);
|
||||
|
||||
const auto actualAppZoneHistory = m_fancyZonesData.GetAppZoneHistoryMap();
|
||||
Assert::IsTrue(actualAppZoneHistory.empty());
|
||||
}
|
||||
|
||||
TEST_METHOD (SaveWindowProcessToZoneIndexNoWindowAddedWithFilledAppZoneHistory)
|
||||
{
|
||||
auto zoneWindow = MakeZoneWindow(winrt::make_self<MockZoneWindowHost>().get(), m_hInst, m_monitor, m_uniqueId.str(), {});
|
||||
Assert::IsNotNull(zoneWindow->ActiveZoneSet());
|
||||
|
||||
const auto window = Mocks::WindowCreate(m_hInst);
|
||||
const auto processPath = get_process_path(window);
|
||||
const auto deviceId = zoneWindow->UniqueId();
|
||||
const auto zoneSetId = zoneWindow->ActiveZoneSet()->Id();
|
||||
|
||||
// fill app zone history map
|
||||
Assert::IsTrue(m_fancyZonesData.SetAppLastZones(window, deviceId, Helpers::GuidToString(zoneSetId), { 0 }));
|
||||
Assert::AreEqual((size_t)1, m_fancyZonesData.GetAppZoneHistoryMap().size());
|
||||
const auto& appHistoryArray1 = m_fancyZonesData.GetAppZoneHistoryMap().at(processPath);
|
||||
Assert::AreEqual((size_t)1, appHistoryArray1.size());
|
||||
Assert::IsTrue(std::vector<size_t>{ 0 } == appHistoryArray1[0].zoneIndexSet);
|
||||
|
||||
// add zone without window
|
||||
const auto zone = MakeZone(RECT{ 0, 0, 100, 100 }, 1);
|
||||
zoneWindow->ActiveZoneSet()->AddZone(zone);
|
||||
|
||||
zoneWindow->SaveWindowProcessToZoneIndex(window);
|
||||
Assert::AreEqual((size_t)1, m_fancyZonesData.GetAppZoneHistoryMap().size());
|
||||
const auto& appHistoryArray2 = m_fancyZonesData.GetAppZoneHistoryMap().at(processPath);
|
||||
Assert::AreEqual((size_t)1, appHistoryArray2.size());
|
||||
Assert::IsTrue(std::vector<size_t>{ 0 } == appHistoryArray2[0].zoneIndexSet);
|
||||
}
|
||||
|
||||
TEST_METHOD (SaveWindowProcessToZoneIndexWindowAdded)
|
||||
{
|
||||
auto zoneWindow = MakeZoneWindow(winrt::make_self<MockZoneWindowHost>().get(), m_hInst, m_monitor, m_uniqueId.str(), {});
|
||||
Assert::IsNotNull(zoneWindow->ActiveZoneSet());
|
||||
|
||||
auto window = Mocks::WindowCreate(m_hInst);
|
||||
const auto processPath = get_process_path(window);
|
||||
const auto deviceId = zoneWindow->UniqueId();
|
||||
const auto zoneSetId = zoneWindow->ActiveZoneSet()->Id();
|
||||
|
||||
auto zone = MakeZone(RECT{ 0, 0, 100, 100 }, 1);
|
||||
zoneWindow->ActiveZoneSet()->AddZone(zone);
|
||||
zoneWindow->MoveWindowIntoZoneByIndex(window, 0);
|
||||
|
||||
//fill app zone history map
|
||||
Assert::IsTrue(m_fancyZonesData.SetAppLastZones(window, deviceId, Helpers::GuidToString(zoneSetId), { 2 }));
|
||||
Assert::AreEqual((size_t)1, m_fancyZonesData.GetAppZoneHistoryMap().size());
|
||||
const auto& appHistoryArray = m_fancyZonesData.GetAppZoneHistoryMap().at(processPath);
|
||||
Assert::AreEqual((size_t)1, appHistoryArray.size());
|
||||
Assert::IsTrue(std::vector<size_t>{ 2 } == appHistoryArray[0].zoneIndexSet);
|
||||
|
||||
zoneWindow->SaveWindowProcessToZoneIndex(window);
|
||||
|
||||
const auto& actualAppZoneHistory = m_fancyZonesData.GetAppZoneHistoryMap();
|
||||
Assert::AreEqual((size_t)1, actualAppZoneHistory.size());
|
||||
const auto& expected = zoneWindow->ActiveZoneSet()->GetZoneIndexSetFromWindow(window);
|
||||
const auto& actual = appHistoryArray[0].zoneIndexSet;
|
||||
Assert::IsTrue(expected == actual);
|
||||
}
|
||||
|
||||
TEST_METHOD (WhenWindowIsNotResizablePlacingItIntoTheZoneShouldNotResizeIt)
|
||||
{
|
||||
auto zoneWindow = MakeZoneWindow(winrt::make_self<MockZoneWindowHost>().get(), m_hInst, m_monitor, m_uniqueId.str(), {});
|
||||
Assert::IsNotNull(zoneWindow->ActiveZoneSet());
|
||||
|
||||
auto window = Mocks::WindowCreate(m_hInst);
|
||||
|
||||
int originalWidth = 450;
|
||||
int originalHeight = 550;
|
||||
|
||||
SetWindowPos(window, nullptr, 150, 150, originalWidth, originalHeight, SWP_SHOWWINDOW);
|
||||
SetWindowLong(window, GWL_STYLE, GetWindowLong(window, GWL_STYLE) & ~WS_SIZEBOX);
|
||||
|
||||
auto zone = MakeZone(RECT{ 50, 50, 300, 300 }, 1);
|
||||
zoneWindow->ActiveZoneSet()->AddZone(zone);
|
||||
|
||||
zoneWindow->MoveWindowIntoZoneByDirectionAndIndex(window, VK_LEFT, true);
|
||||
|
||||
RECT inZoneRect;
|
||||
GetWindowRect(window, &inZoneRect);
|
||||
Assert::AreEqual(originalWidth, (int)inZoneRect.right - (int)inZoneRect.left);
|
||||
Assert::AreEqual(originalHeight, (int)inZoneRect.bottom - (int)inZoneRect.top);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.200729.8" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.200902.2" targetFramework="native" />
|
||||
</packages>
|
||||
5
src/modules/fancyzones/FancyZonesTests/UnitTests/pch.cpp
Normal file
5
src/modules/fancyzones/FancyZonesTests/UnitTests/pch.cpp
Normal file
@@ -0,0 +1,5 @@
|
||||
// pch.cpp: source file corresponding to the pre-compiled header
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
|
||||
18
src/modules/fancyzones/FancyZonesTests/UnitTests/pch.h
Normal file
18
src/modules/fancyzones/FancyZonesTests/UnitTests/pch.h
Normal file
@@ -0,0 +1,18 @@
|
||||
// pch.h: This is a precompiled header file.
|
||||
// Files listed below are compiled only once, improving build performance for future builds.
|
||||
// This also affects IntelliSense performance, including code completion and many code browsing features.
|
||||
// However, files listed here are ALL re-compiled if any one of them is updated between builds.
|
||||
// Do not add files here that you will be updating frequently as this negates the performance advantage.
|
||||
|
||||
#ifndef PCH_H
|
||||
#define PCH_H
|
||||
|
||||
// add headers that you want to pre-compile here
|
||||
#include <Windows.h>
|
||||
#include <winrt/base.h>
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
#include "FancyZonesLib/pch.h"
|
||||
#include "CppUnitTest.h"
|
||||
|
||||
#endif //PCH_H
|
||||
13
src/modules/fancyzones/FancyZonesTests/UnitTests/resource.h
Normal file
13
src/modules/fancyzones/FancyZonesTests/UnitTests/resource.h
Normal file
@@ -0,0 +1,13 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by UnitTests-FancyZones.rc
|
||||
|
||||
//////////////////////////////
|
||||
// Non-localizable
|
||||
|
||||
#define FILE_DESCRIPTION "PowerToys UnitTests-FancyZones"
|
||||
#define INTERNAL_NAME "UnitTests-FancyZones"
|
||||
#define ORIGINAL_FILENAME "UnitTests-FancyZones.dll"
|
||||
|
||||
// Non-localizable
|
||||
//////////////////////////////
|
||||
Reference in New Issue
Block a user