mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-06 03:07:04 +02:00
Migrate FancyZones data persisting from Registry to JSON file (#1194)
* Migrate FancyZones data persisting from Registry to JSON file * Address PR comment: Remove redundant check * Addres PR comment: Remove unused Dpi and add CmdArgs enum * Address PR comment: Make methods const and inline * Address PR comments: Expose GenerateUniqueId function and use const ref instead of passing wstring by value * Address PR comment: Use lamdba as callback * Address PR comment: Move GenerateUniqueId to ZoneWindowUtils namespace * Address PR comment: Use regular comparison instead of std::wstring::compare * Address PR comment: Use std::wstring_view for tmp file paths * Address PR comment: Use scoped lock when accessing member data * Address PR comment: Remove typedefs to increase code readability * Address PR comment: removed nullptr checks with corresponding tests * Address PR comment: Move ZoneSet object instead of copying * Address PR comment: Make FancyZonesData instance const where possible * Remove unnecessary gutter variable during calculating zone coordinates * Remove uneeded subclass * Avoid unnecessary copying and reserve space for vector if possible * Save FancyZones data after exiting editor * App zone history (#18) * added window and zone set ids to app zone history * Rename JSON file * Remove AppZoneHistory migration * Move parsing of ZoneWindow independent temp files outside of it * Unit tests update (#19) * check device existence in map * updated ZoneSet tests * updated JsonHelpers tests * Use single zone count information * Remove uneeded tests * Remove one more test * Remove uneeded line * Address PR comments - Missing whitespace * Update zoneset data for new virtual desktops (#21) * update active zone set with actual data * Introduce Blank zone set (used to indicate that no layout applied yet). Move parsing completely outside of ZoneWindow. * Fix unit tests to match modifications in implementation * Fix applying layouts on startup (second monitor) Co-authored-by: vldmr11080 <57061786+vldmr11080@users.noreply.github.com> Co-authored-by: Seraphima <zykovas91@gmail.com>
This commit is contained in:
475
src/modules/fancyzones/tests/UnitTests/FancyZones.Spec.cpp
Normal file
475
src/modules/fancyzones/tests/UnitTests/FancyZones.Spec.cpp
Normal file
@@ -0,0 +1,475 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
#include <lib/FancyZones.h>
|
||||
#include <lib/Settings.h>
|
||||
#include <common/common.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
|
||||
namespace FancyZonesUnitTests
|
||||
{
|
||||
TEST_CLASS(FancyZonesUnitTests)
|
||||
{
|
||||
HINSTANCE m_hInst;
|
||||
winrt::com_ptr<IFancyZonesSettings> m_settings;
|
||||
|
||||
TEST_METHOD_INITIALIZE(Init)
|
||||
{
|
||||
m_hInst = (HINSTANCE)GetModuleHandleW(nullptr);
|
||||
m_settings = MakeFancyZonesSettings(m_hInst, L"FancyZonesUnitTests");
|
||||
Assert::IsTrue(m_settings != nullptr);
|
||||
}
|
||||
|
||||
TEST_METHOD(Create)
|
||||
{
|
||||
auto actual = MakeFancyZones(m_hInst, m_settings);
|
||||
Assert::IsNotNull(actual.get());
|
||||
}
|
||||
TEST_METHOD(CreateWithEmptyHinstance)
|
||||
{
|
||||
auto actual = MakeFancyZones({}, m_settings);
|
||||
Assert::IsNotNull(actual.get());
|
||||
}
|
||||
|
||||
TEST_METHOD(CreateWithNullHinstance)
|
||||
{
|
||||
auto actual = MakeFancyZones(nullptr, m_settings);
|
||||
Assert::IsNotNull(actual.get());
|
||||
}
|
||||
|
||||
TEST_METHOD(CreateWithNullSettings)
|
||||
{
|
||||
auto actual = MakeFancyZones(m_hInst, nullptr);
|
||||
Assert::IsNull(actual.get());
|
||||
}
|
||||
|
||||
TEST_METHOD(Run)
|
||||
{
|
||||
auto actual = MakeFancyZones(m_hInst, m_settings);
|
||||
|
||||
std::vector<std::thread> threads;
|
||||
std::atomic<int> counter = 0;
|
||||
const int expectedCount = 10;
|
||||
|
||||
auto runFunc = [&]() {
|
||||
actual->Run();
|
||||
counter++;
|
||||
};
|
||||
|
||||
for (int i = 0; i < expectedCount; i++)
|
||||
{
|
||||
threads.push_back(std::thread(runFunc));
|
||||
}
|
||||
|
||||
for (auto& thread : threads)
|
||||
{
|
||||
thread.join();
|
||||
}
|
||||
|
||||
Assert::AreEqual(expectedCount, counter.load());
|
||||
}
|
||||
|
||||
TEST_METHOD(Destroy)
|
||||
{
|
||||
auto actual = MakeFancyZones(m_hInst, m_settings);
|
||||
|
||||
std::vector<std::thread> threads;
|
||||
std::atomic<int> counter = 0;
|
||||
const int expectedCount = 10;
|
||||
|
||||
auto destroyFunc = [&]() {
|
||||
actual->Destroy();
|
||||
counter++;
|
||||
};
|
||||
|
||||
for (int i = 0; i < expectedCount; i++)
|
||||
{
|
||||
threads.push_back(std::thread(destroyFunc));
|
||||
}
|
||||
|
||||
for (auto& thread : threads)
|
||||
{
|
||||
thread.join();
|
||||
}
|
||||
|
||||
Assert::AreEqual(expectedCount, counter.load());
|
||||
}
|
||||
|
||||
TEST_METHOD(RunDestroy)
|
||||
{
|
||||
auto actual = MakeFancyZones(m_hInst, m_settings);
|
||||
|
||||
std::vector<std::thread> threads;
|
||||
std::atomic<int> counter = 0;
|
||||
const int expectedCount = 20;
|
||||
|
||||
auto func = [&]() {
|
||||
auto idHash = std::hash<std::thread::id>()(std::this_thread::get_id());
|
||||
bool run = (idHash % 2 == 0);
|
||||
run ? actual->Run() : actual->Destroy();
|
||||
counter++;
|
||||
};
|
||||
|
||||
for (int i = 0; i < expectedCount; i++)
|
||||
{
|
||||
threads.push_back(std::thread(func));
|
||||
}
|
||||
|
||||
for (auto& thread : threads)
|
||||
{
|
||||
thread.join();
|
||||
}
|
||||
|
||||
Assert::AreEqual(expectedCount, counter.load());
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CLASS(FancyZonesIZoneWindowHostUnitTests)
|
||||
{
|
||||
HINSTANCE m_hInst{};
|
||||
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_toogle(L"fancyzones_shiftDrag", IDS_SETTING_DESCRIPTION_SHIFTDRAG, settings.shiftDrag);
|
||||
ptSettings.add_bool_toogle(L"fancyzones_overrideSnapHotkeys", IDS_SETTING_DESCRIPTION_OVERRIDE_SNAP_HOTKEYS, settings.overrideSnapHotkeys);
|
||||
ptSettings.add_bool_toogle(L"fancyzones_zoneSetChange_flashZones", IDS_SETTING_DESCRIPTION_ZONESETCHANGE_FLASHZONES, settings.zoneSetChange_flashZones);
|
||||
ptSettings.add_bool_toogle(L"fancyzones_displayChange_moveWindows", IDS_SETTING_DESCRIPTION_DISPLAYCHANGE_MOVEWINDOWS, settings.displayChange_moveWindows);
|
||||
ptSettings.add_bool_toogle(L"fancyzones_zoneSetChange_moveWindows", IDS_SETTING_DESCRIPTION_ZONESETCHANGE_MOVEWINDOWS, settings.zoneSetChange_moveWindows);
|
||||
ptSettings.add_bool_toogle(L"fancyzones_virtualDesktopChange_moveWindows", IDS_SETTING_DESCRIPTION_VIRTUALDESKTOPCHANGE_MOVEWINDOWS, settings.virtualDesktopChange_moveWindows);
|
||||
ptSettings.add_bool_toogle(L"fancyzones_appLastZone_moveWindows", IDS_SETTING_DESCRIPTION_APPLASTZONE_MOVEWINDOWS, settings.appLastZone_moveWindows);
|
||||
ptSettings.add_bool_toogle(L"use_cursorpos_editor_startupscreen", IDS_SETTING_DESCRIPTION_USE_CURSORPOS_EDITOR_STARTUPSCREEN, settings.use_cursorpos_editor_startupscreen);
|
||||
ptSettings.add_int_spinner(L"fancyzones_highlight_opacity", IDS_SETTINGS_HIGHLIGHT_OPACITY, settings.zoneHighlightOpacity, 0, 100, 1);
|
||||
ptSettings.add_color_picker(L"fancyzones_zoneHighlightColor", IDS_SETTING_DESCRIPTION_ZONEHIGHLIGHTCOLOR, settings.zoneHightlightColor);
|
||||
ptSettings.add_multiline_string(L"fancyzones_excluded_apps", IDS_SETTING_EXCLCUDED_APPS_DESCRIPTION, settings.excludedApps);
|
||||
|
||||
return ptSettings.serialize();
|
||||
}
|
||||
|
||||
TEST_METHOD_INITIALIZE(Init)
|
||||
{
|
||||
m_hInst = (HINSTANCE)GetModuleHandleW(nullptr);
|
||||
m_settings = MakeFancyZonesSettings(m_hInst, L"FancyZonesUnitTests");
|
||||
Assert::IsTrue(m_settings != nullptr);
|
||||
|
||||
auto fancyZones = MakeFancyZones(m_hInst, m_settings);
|
||||
Assert::IsTrue(fancyZones != nullptr);
|
||||
|
||||
m_zoneWindowHost = fancyZones.as<IZoneWindowHost>();
|
||||
Assert::IsTrue(m_zoneWindowHost != nullptr);
|
||||
}
|
||||
|
||||
TEST_METHOD_CLEANUP(Cleanup)
|
||||
{
|
||||
const auto settingsFile = PTSettingsHelper::get_module_save_folder_location(L"FancyZonesUnitTests") + L"\\settings.json";
|
||||
std::filesystem::remove(settingsFile);
|
||||
}
|
||||
|
||||
TEST_METHOD(GetZoneHighlightColor)
|
||||
{
|
||||
const auto expected = RGB(171, 175, 238);
|
||||
const Settings settings{
|
||||
.shiftDrag = true,
|
||||
.displayChange_moveWindows = true,
|
||||
.virtualDesktopChange_moveWindows = true,
|
||||
.zoneSetChange_flashZones = false,
|
||||
.zoneSetChange_moveWindows = true,
|
||||
.overrideSnapHotkeys = false,
|
||||
.appLastZone_moveWindows = true,
|
||||
.use_cursorpos_editor_startupscreen = true,
|
||||
.zoneHightlightColor = 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,
|
||||
.displayChange_moveWindows = true,
|
||||
.virtualDesktopChange_moveWindows = true,
|
||||
.zoneSetChange_flashZones = false,
|
||||
.zoneSetChange_moveWindows = true,
|
||||
.overrideSnapHotkeys = false,
|
||||
.appLastZone_moveWindows = true,
|
||||
.use_cursorpos_editor_startupscreen = true,
|
||||
.zoneHightlightColor = 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(GetCurrentMonitorZoneSetEmpty)
|
||||
{
|
||||
const auto* actual = m_zoneWindowHost->GetParentZoneWindow(Mocks::Monitor());
|
||||
Assert::IsNull(actual);
|
||||
}
|
||||
|
||||
TEST_METHOD(GetCurrentMonitorZoneSetNullMonitor)
|
||||
{
|
||||
const auto* actual = m_zoneWindowHost->GetParentZoneWindow(nullptr);
|
||||
Assert::IsNull(actual);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CLASS(FancyZonesIFancyZonesCallbackUnitTests)
|
||||
{
|
||||
HINSTANCE m_hInst{};
|
||||
winrt::com_ptr<IFancyZonesSettings> m_settings = nullptr;
|
||||
winrt::com_ptr<IFancyZonesCallback> m_fzCallback = nullptr;
|
||||
|
||||
JSONHelpers::FancyZonesData& m_fancyZonesData = JSONHelpers::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_toogle(L"fancyzones_shiftDrag", IDS_SETTING_DESCRIPTION_SHIFTDRAG, settings.shiftDrag);
|
||||
ptSettings.add_bool_toogle(L"fancyzones_overrideSnapHotkeys", IDS_SETTING_DESCRIPTION_OVERRIDE_SNAP_HOTKEYS, settings.overrideSnapHotkeys);
|
||||
ptSettings.add_bool_toogle(L"fancyzones_zoneSetChange_flashZones", IDS_SETTING_DESCRIPTION_ZONESETCHANGE_FLASHZONES, settings.zoneSetChange_flashZones);
|
||||
ptSettings.add_bool_toogle(L"fancyzones_displayChange_moveWindows", IDS_SETTING_DESCRIPTION_DISPLAYCHANGE_MOVEWINDOWS, settings.displayChange_moveWindows);
|
||||
ptSettings.add_bool_toogle(L"fancyzones_zoneSetChange_moveWindows", IDS_SETTING_DESCRIPTION_ZONESETCHANGE_MOVEWINDOWS, settings.zoneSetChange_moveWindows);
|
||||
ptSettings.add_bool_toogle(L"fancyzones_virtualDesktopChange_moveWindows", IDS_SETTING_DESCRIPTION_VIRTUALDESKTOPCHANGE_MOVEWINDOWS, settings.virtualDesktopChange_moveWindows);
|
||||
ptSettings.add_bool_toogle(L"fancyzones_appLastZone_moveWindows", IDS_SETTING_DESCRIPTION_APPLASTZONE_MOVEWINDOWS, settings.appLastZone_moveWindows);
|
||||
ptSettings.add_bool_toogle(L"use_cursorpos_editor_startupscreen", IDS_SETTING_DESCRIPTION_USE_CURSORPOS_EDITOR_STARTUPSCREEN, settings.use_cursorpos_editor_startupscreen);
|
||||
ptSettings.add_int_spinner(L"fancyzones_highlight_opacity", IDS_SETTINGS_HIGHLIGHT_OPACITY, settings.zoneHighlightOpacity, 0, 100, 1);
|
||||
ptSettings.add_color_picker(L"fancyzones_zoneHighlightColor", IDS_SETTING_DESCRIPTION_ZONEHIGHLIGHTCOLOR, settings.zoneHightlightColor);
|
||||
ptSettings.add_multiline_string(L"fancyzones_excluded_apps", IDS_SETTING_EXCLCUDED_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, L"FancyZonesUnitTests");
|
||||
Assert::IsTrue(m_settings != nullptr);
|
||||
|
||||
auto fancyZones = MakeFancyZones(m_hInst, m_settings);
|
||||
Assert::IsTrue(fancyZones != nullptr);
|
||||
|
||||
m_fzCallback = fancyZones.as<IFancyZonesCallback>();
|
||||
Assert::IsTrue(m_fzCallback != nullptr);
|
||||
|
||||
m_fancyZonesData = JSONHelpers::FancyZonesData();
|
||||
}
|
||||
|
||||
TEST_METHOD_CLEANUP(Cleanup)
|
||||
{
|
||||
sendKeyboardInput(VK_SHIFT, true);
|
||||
sendKeyboardInput(VK_LWIN, true);
|
||||
sendKeyboardInput(VK_CONTROL, true);
|
||||
|
||||
const auto settingsFile = PTSettingsHelper::get_module_save_folder_location(L"FancyZonesUnitTests") + L"\\settings.json";
|
||||
std::filesystem::remove(settingsFile);
|
||||
}
|
||||
|
||||
TEST_METHOD(InMoveSizeTest)
|
||||
{
|
||||
Assert::IsFalse(m_fzCallback->InMoveSize());
|
||||
|
||||
m_fzCallback->MoveSizeStart(Mocks::Window(), Mocks::Monitor(), POINT{ 0, 0 });
|
||||
Assert::IsFalse(m_fzCallback->InMoveSize()); //point outside of window rect
|
||||
|
||||
const auto window = Mocks::WindowCreate(m_hInst);
|
||||
const int paddingX = 8, paddingY = 6;
|
||||
RECT windowRect{};
|
||||
::GetWindowRect(window, &windowRect);
|
||||
m_fzCallback->MoveSizeStart(window, Mocks::Monitor(), POINT{ windowRect.left + paddingX, windowRect.top + paddingY });
|
||||
Assert::IsTrue(m_fzCallback->InMoveSize());
|
||||
|
||||
m_fzCallback->MoveSizeEnd(Mocks::Window(), POINT{ 0, 0 });
|
||||
Assert::IsFalse(m_fzCallback->InMoveSize());
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(OnKeyDownWinPressedOverride)
|
||||
{
|
||||
sendKeyboardInput(VK_LWIN);
|
||||
|
||||
const Settings settings{
|
||||
.overrideSnapHotkeys = true,
|
||||
};
|
||||
|
||||
auto config = serializedPowerToySettings(settings);
|
||||
m_settings->SetConfig(config.c_str());
|
||||
|
||||
{
|
||||
tagKBDLLHOOKSTRUCT input{};
|
||||
input.vkCode = VK_LEFT;
|
||||
Assert::IsTrue(m_fzCallback->OnKeyDown(&input));
|
||||
}
|
||||
|
||||
{
|
||||
tagKBDLLHOOKSTRUCT input{};
|
||||
input.vkCode = VK_RIGHT;
|
||||
Assert::IsTrue(m_fzCallback->OnKeyDown(&input));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,714 @@
|
||||
#include "pch.h"
|
||||
#include <filesystem>
|
||||
|
||||
#include <lib/Settings.h>
|
||||
#include <lib/FancyZones.h>
|
||||
#include <common/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.displayChange_moveWindows, actual.displayChange_moveWindows);
|
||||
Assert::AreEqual(expected.virtualDesktopChange_moveWindows, actual.virtualDesktopChange_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.appLastZone_moveWindows, actual.appLastZone_moveWindows);
|
||||
Assert::AreEqual(expected.use_cursorpos_editor_startupscreen, actual.use_cursorpos_editor_startupscreen);
|
||||
Assert::AreEqual(expected.zoneHightlightColor.c_str(), actual.zoneHightlightColor.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"FancyZonesTest";
|
||||
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(m_tmpName);
|
||||
}
|
||||
|
||||
TEST_METHOD(CreateWithHinstanceDefault)
|
||||
{
|
||||
auto actual = MakeFancyZonesSettings({}, m_moduleName);
|
||||
Assert::IsTrue(actual != nullptr);
|
||||
|
||||
auto actualSettings = actual->GetSettings();
|
||||
compareSettings(m_defaultSettings, actualSettings);
|
||||
}
|
||||
|
||||
TEST_METHOD(CreateWithHinstanceNullptr)
|
||||
{
|
||||
auto actual = MakeFancyZonesSettings(nullptr, m_moduleName);
|
||||
Assert::IsTrue(actual != nullptr);
|
||||
|
||||
auto actualSettings = actual->GetSettings();
|
||||
compareSettings(m_defaultSettings, actualSettings);
|
||||
}
|
||||
|
||||
TEST_METHOD(CreateWithNameEmpty)
|
||||
{
|
||||
auto actual = MakeFancyZonesSettings(m_hInst, L"");
|
||||
Assert::IsTrue(actual != nullptr);
|
||||
|
||||
auto actualSettings = actual->GetSettings();
|
||||
compareSettings(m_defaultSettings, actualSettings);
|
||||
}
|
||||
|
||||
TEST_METHOD(Create)
|
||||
{
|
||||
//prepare data
|
||||
const Settings expected {
|
||||
.shiftDrag = false,
|
||||
.displayChange_moveWindows = true,
|
||||
.virtualDesktopChange_moveWindows = true,
|
||||
.zoneSetChange_flashZones = true,
|
||||
.zoneSetChange_moveWindows = true,
|
||||
.overrideSnapHotkeys = false,
|
||||
.appLastZone_moveWindows = false,
|
||||
.use_cursorpos_editor_startupscreen = true,
|
||||
.zoneHightlightColor = 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);
|
||||
values.add_property(L"fancyzones_shiftDrag", expected.shiftDrag);
|
||||
values.add_property(L"fancyzones_displayChange_moveWindows", expected.displayChange_moveWindows);
|
||||
values.add_property(L"fancyzones_virtualDesktopChange_moveWindows", expected.virtualDesktopChange_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_appLastZone_moveWindows", expected.appLastZone_moveWindows);
|
||||
values.add_property(L"use_cursorpos_editor_startupscreen", expected.use_cursorpos_editor_startupscreen);
|
||||
values.add_property(L"fancyzones_zoneHighlightColor", expected.zoneHightlightColor);
|
||||
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);
|
||||
Assert::IsTrue(actual != nullptr);
|
||||
|
||||
auto actualSettings = actual->GetSettings();
|
||||
compareSettings(expected, actualSettings);
|
||||
}
|
||||
|
||||
TEST_METHOD(CreateWithMultipleApps)
|
||||
{
|
||||
//prepare data
|
||||
const Settings expected {
|
||||
.shiftDrag = false,
|
||||
.displayChange_moveWindows = true,
|
||||
.virtualDesktopChange_moveWindows = true,
|
||||
.zoneSetChange_flashZones = true,
|
||||
.zoneSetChange_moveWindows = true,
|
||||
.overrideSnapHotkeys = false,
|
||||
.appLastZone_moveWindows = false,
|
||||
.use_cursorpos_editor_startupscreen = true,
|
||||
.zoneHightlightColor = L"#00FFD7",
|
||||
.zoneHighlightOpacity = 45,
|
||||
.editorHotkey = PowerToysSettings::HotkeyObject::from_settings(false, true, true, false, VK_OEM_3),
|
||||
.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);
|
||||
values.add_property(L"fancyzones_shiftDrag", expected.shiftDrag);
|
||||
values.add_property(L"fancyzones_displayChange_moveWindows", expected.displayChange_moveWindows);
|
||||
values.add_property(L"fancyzones_virtualDesktopChange_moveWindows", expected.virtualDesktopChange_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_appLastZone_moveWindows", expected.appLastZone_moveWindows);
|
||||
values.add_property(L"use_cursorpos_editor_startupscreen", expected.use_cursorpos_editor_startupscreen);
|
||||
values.add_property(L"fancyzones_zoneHighlightColor", expected.zoneHightlightColor);
|
||||
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);
|
||||
Assert::IsTrue(actual != nullptr);
|
||||
|
||||
auto actualSettings = actual->GetSettings();
|
||||
compareSettings(expected, actualSettings);
|
||||
}
|
||||
|
||||
TEST_METHOD(CreateWithBoolValuesMissed)
|
||||
{
|
||||
const Settings expected {
|
||||
.shiftDrag = m_defaultSettings.shiftDrag,
|
||||
.displayChange_moveWindows = m_defaultSettings.displayChange_moveWindows,
|
||||
.virtualDesktopChange_moveWindows = m_defaultSettings.virtualDesktopChange_moveWindows,
|
||||
.zoneSetChange_flashZones = m_defaultSettings.zoneSetChange_flashZones,
|
||||
.zoneSetChange_moveWindows = m_defaultSettings.zoneSetChange_moveWindows,
|
||||
.overrideSnapHotkeys = m_defaultSettings.overrideSnapHotkeys,
|
||||
.appLastZone_moveWindows = m_defaultSettings.appLastZone_moveWindows,
|
||||
.use_cursorpos_editor_startupscreen = m_defaultSettings.use_cursorpos_editor_startupscreen,
|
||||
.zoneHightlightColor = 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);
|
||||
values.add_property(L"fancyzones_zoneHighlightColor", expected.zoneHightlightColor);
|
||||
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);
|
||||
Assert::IsTrue(actual != nullptr);
|
||||
|
||||
auto actualSettings = actual->GetSettings();
|
||||
compareSettings(expected, actualSettings);
|
||||
}
|
||||
|
||||
TEST_METHOD(CreateColorMissed)
|
||||
{
|
||||
//prepare data
|
||||
const Settings expected {
|
||||
.shiftDrag = false,
|
||||
.displayChange_moveWindows = true,
|
||||
.virtualDesktopChange_moveWindows = true,
|
||||
.zoneSetChange_flashZones = true,
|
||||
.zoneSetChange_moveWindows = true,
|
||||
.overrideSnapHotkeys = false,
|
||||
.appLastZone_moveWindows = false,
|
||||
.use_cursorpos_editor_startupscreen = true,
|
||||
.zoneHightlightColor = m_defaultSettings.zoneHightlightColor,
|
||||
.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);
|
||||
values.add_property(L"fancyzones_shiftDrag", expected.shiftDrag);
|
||||
values.add_property(L"fancyzones_displayChange_moveWindows", expected.displayChange_moveWindows);
|
||||
values.add_property(L"fancyzones_virtualDesktopChange_moveWindows", expected.virtualDesktopChange_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_appLastZone_moveWindows", expected.appLastZone_moveWindows);
|
||||
values.add_property(L"use_cursorpos_editor_startupscreen", expected.use_cursorpos_editor_startupscreen);
|
||||
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);
|
||||
Assert::IsTrue(actual != nullptr);
|
||||
|
||||
auto actualSettings = actual->GetSettings();
|
||||
compareSettings(expected, actualSettings);
|
||||
}
|
||||
|
||||
TEST_METHOD(CreateOpacityMissed)
|
||||
{
|
||||
//prepare data
|
||||
const Settings expected {
|
||||
.shiftDrag = false,
|
||||
.displayChange_moveWindows = true,
|
||||
.virtualDesktopChange_moveWindows = true,
|
||||
.zoneSetChange_flashZones = true,
|
||||
.zoneSetChange_moveWindows = true,
|
||||
.overrideSnapHotkeys = false,
|
||||
.appLastZone_moveWindows = false,
|
||||
.use_cursorpos_editor_startupscreen = true,
|
||||
.zoneHightlightColor = L"#00FFD7",
|
||||
.zoneHighlightOpacity = m_defaultSettings.zoneHighlightOpacity,
|
||||
.editorHotkey = PowerToysSettings::HotkeyObject::from_settings(false, true, true, false, VK_OEM_3),
|
||||
.excludedApps = L"app",
|
||||
.excludedAppsArray = { L"APP" },
|
||||
};
|
||||
|
||||
PowerToysSettings::PowerToyValues values(m_moduleName);
|
||||
values.add_property(L"fancyzones_shiftDrag", expected.shiftDrag);
|
||||
values.add_property(L"fancyzones_displayChange_moveWindows", expected.displayChange_moveWindows);
|
||||
values.add_property(L"fancyzones_virtualDesktopChange_moveWindows", expected.virtualDesktopChange_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_appLastZone_moveWindows", expected.appLastZone_moveWindows);
|
||||
values.add_property(L"use_cursorpos_editor_startupscreen", expected.use_cursorpos_editor_startupscreen);
|
||||
values.add_property(L"fancyzones_zoneHighlightColor", expected.zoneHightlightColor);
|
||||
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);
|
||||
Assert::IsTrue(actual != nullptr);
|
||||
|
||||
auto actualSettings = actual->GetSettings();
|
||||
compareSettings(expected, actualSettings);
|
||||
}
|
||||
|
||||
TEST_METHOD(CreateHotkeyMissed)
|
||||
{
|
||||
//prepare data
|
||||
const Settings expected = Settings{
|
||||
.shiftDrag = false,
|
||||
.displayChange_moveWindows = true,
|
||||
.virtualDesktopChange_moveWindows = true,
|
||||
.zoneSetChange_flashZones = true,
|
||||
.zoneSetChange_moveWindows = true,
|
||||
.overrideSnapHotkeys = false,
|
||||
.appLastZone_moveWindows = false,
|
||||
.use_cursorpos_editor_startupscreen = true,
|
||||
.zoneHightlightColor = L"#00FFD7",
|
||||
.zoneHighlightOpacity = 45,
|
||||
.editorHotkey = m_defaultSettings.editorHotkey,
|
||||
.excludedApps = L"app",
|
||||
.excludedAppsArray = { L"APP" },
|
||||
};
|
||||
|
||||
PowerToysSettings::PowerToyValues values(m_moduleName);
|
||||
values.add_property(L"fancyzones_shiftDrag", expected.shiftDrag);
|
||||
values.add_property(L"fancyzones_displayChange_moveWindows", expected.displayChange_moveWindows);
|
||||
values.add_property(L"fancyzones_virtualDesktopChange_moveWindows", expected.virtualDesktopChange_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_appLastZone_moveWindows", expected.appLastZone_moveWindows);
|
||||
values.add_property(L"use_cursorpos_editor_startupscreen", expected.use_cursorpos_editor_startupscreen);
|
||||
values.add_property(L"fancyzones_zoneHighlightColor", expected.zoneHightlightColor);
|
||||
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);
|
||||
Assert::IsTrue(actual != nullptr);
|
||||
|
||||
auto actualSettings = actual->GetSettings();
|
||||
compareSettings(expected, actualSettings);
|
||||
}
|
||||
|
||||
TEST_METHOD(CreateAppsMissed)
|
||||
{
|
||||
//prepare data
|
||||
const Settings expected = Settings{
|
||||
.shiftDrag = false,
|
||||
.displayChange_moveWindows = true,
|
||||
.virtualDesktopChange_moveWindows = true,
|
||||
.zoneSetChange_flashZones = true,
|
||||
.zoneSetChange_moveWindows = true,
|
||||
.overrideSnapHotkeys = false,
|
||||
.appLastZone_moveWindows = false,
|
||||
.use_cursorpos_editor_startupscreen = true,
|
||||
.zoneHightlightColor = L"#00FFD7",
|
||||
.zoneHighlightOpacity = 45,
|
||||
.editorHotkey = PowerToysSettings::HotkeyObject::from_settings(false, true, true, false, VK_OEM_3),
|
||||
.excludedApps = m_defaultSettings.excludedApps,
|
||||
.excludedAppsArray = m_defaultSettings.excludedAppsArray,
|
||||
};
|
||||
|
||||
PowerToysSettings::PowerToyValues values(m_moduleName);
|
||||
values.add_property(L"fancyzones_shiftDrag", expected.shiftDrag);
|
||||
values.add_property(L"fancyzones_displayChange_moveWindows", expected.displayChange_moveWindows);
|
||||
values.add_property(L"fancyzones_virtualDesktopChange_moveWindows", expected.virtualDesktopChange_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_appLastZone_moveWindows", expected.appLastZone_moveWindows);
|
||||
values.add_property(L"use_cursorpos_editor_startupscreen", expected.use_cursorpos_editor_startupscreen);
|
||||
values.add_property(L"fancyzones_zoneHighlightColor", expected.zoneHightlightColor);
|
||||
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);
|
||||
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);
|
||||
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"FancyZonesTest";
|
||||
|
||||
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) 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,
|
||||
.displayChange_moveWindows = true,
|
||||
.virtualDesktopChange_moveWindows = true,
|
||||
.zoneSetChange_flashZones = true,
|
||||
.zoneSetChange_moveWindows = true,
|
||||
.overrideSnapHotkeys = false,
|
||||
.appLastZone_moveWindows = false,
|
||||
.use_cursorpos_editor_startupscreen = true,
|
||||
.zoneHightlightColor = 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);
|
||||
values.add_property(L"fancyzones_shiftDrag", expected.shiftDrag);
|
||||
values.add_property(L"fancyzones_displayChange_moveWindows", expected.displayChange_moveWindows);
|
||||
values.add_property(L"fancyzones_virtualDesktopChange_moveWindows", expected.virtualDesktopChange_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_appLastZone_moveWindows", expected.appLastZone_moveWindows);
|
||||
values.add_property(L"use_cursorpos_editor_startupscreen", expected.use_cursorpos_editor_startupscreen);
|
||||
values.add_property(L"fancyzones_zoneHighlightColor", expected.zoneHightlightColor);
|
||||
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);
|
||||
Assert::IsTrue(m_settings != nullptr);
|
||||
}
|
||||
|
||||
TEST_METHOD_CLEANUP(Cleanup)
|
||||
{
|
||||
const auto settingsFile = PTSettingsHelper::get_module_save_folder_location(m_moduleName) + L"\\settings.json";
|
||||
std::filesystem::remove(settingsFile);
|
||||
}
|
||||
|
||||
TEST_METHOD(CallbackSetConfig)
|
||||
{
|
||||
bool flag = false;
|
||||
FZCallback callback(&flag);
|
||||
|
||||
json::JsonObject json{};
|
||||
json.SetNamedValue(L"name", json::JsonValue::CreateStringValue(L"name"));
|
||||
|
||||
m_settings->SetCallback(&callback);
|
||||
m_settings->SetConfig(json.Stringify().c_str());
|
||||
|
||||
Assert::IsTrue(flag);
|
||||
}
|
||||
|
||||
TEST_METHOD(CallbackCallCustomAction)
|
||||
{
|
||||
bool flag = false;
|
||||
FZCallback callback(&flag);
|
||||
|
||||
json::JsonObject action{};
|
||||
action.SetNamedValue(L"action_name", json::JsonValue::CreateStringValue(L"ToggledFZEditor"));
|
||||
|
||||
m_settings->SetCallback(&callback);
|
||||
m_settings->CallCustomAction(action.Stringify().c_str());
|
||||
|
||||
Assert::IsTrue(flag);
|
||||
}
|
||||
|
||||
TEST_METHOD(CallbackCallCustomActionNotToggle)
|
||||
{
|
||||
bool flag = false;
|
||||
FZCallback callback(&flag);
|
||||
|
||||
json::JsonObject action{};
|
||||
action.SetNamedValue(L"action_name", json::JsonValue::CreateStringValue(L"NOT_ToggledFZEditor"));
|
||||
|
||||
m_settings->SetCallback(&callback);
|
||||
m_settings->CallCustomAction(action.Stringify().c_str());
|
||||
|
||||
Assert::IsFalse(flag);
|
||||
}
|
||||
|
||||
TEST_METHOD(CallbackGetConfig)
|
||||
{
|
||||
bool flag = false;
|
||||
FZCallback callback(&flag);
|
||||
|
||||
m_settings->SetCallback(&callback);
|
||||
|
||||
int bufSize = 0;
|
||||
m_settings->GetConfig(L"", &bufSize);
|
||||
|
||||
Assert::IsFalse(flag);
|
||||
}
|
||||
|
||||
TEST_METHOD(CallbackGetSettings)
|
||||
{
|
||||
bool flag = false;
|
||||
FZCallback callback(&flag);
|
||||
|
||||
m_settings->SetCallback(&callback);
|
||||
m_settings->GetSettings();
|
||||
|
||||
Assert::IsFalse(flag);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CLASS(FancyZonesSettingsUnitTests)
|
||||
{
|
||||
winrt::com_ptr<IFancyZonesSettings> m_settings = nullptr;
|
||||
PowerToysSettings::Settings* m_ptSettings = nullptr;
|
||||
PCWSTR m_moduleName = L"FancyZonesTest";
|
||||
|
||||
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://github.com/microsoft/PowerToys/blob/master/src/modules/fancyzones/README.md");
|
||||
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_toogle(L"fancyzones_shiftDrag", IDS_SETTING_DESCRIPTION_SHIFTDRAG, settings.shiftDrag);
|
||||
ptSettings.add_bool_toogle(L"fancyzones_overrideSnapHotkeys", IDS_SETTING_DESCRIPTION_OVERRIDE_SNAP_HOTKEYS, settings.overrideSnapHotkeys);
|
||||
ptSettings.add_bool_toogle(L"fancyzones_zoneSetChange_flashZones", IDS_SETTING_DESCRIPTION_ZONESETCHANGE_FLASHZONES, settings.zoneSetChange_flashZones);
|
||||
ptSettings.add_bool_toogle(L"fancyzones_displayChange_moveWindows", IDS_SETTING_DESCRIPTION_DISPLAYCHANGE_MOVEWINDOWS, settings.displayChange_moveWindows);
|
||||
ptSettings.add_bool_toogle(L"fancyzones_zoneSetChange_moveWindows", IDS_SETTING_DESCRIPTION_ZONESETCHANGE_MOVEWINDOWS, settings.zoneSetChange_moveWindows);
|
||||
ptSettings.add_bool_toogle(L"fancyzones_virtualDesktopChange_moveWindows", IDS_SETTING_DESCRIPTION_VIRTUALDESKTOPCHANGE_MOVEWINDOWS, settings.virtualDesktopChange_moveWindows);
|
||||
ptSettings.add_bool_toogle(L"fancyzones_appLastZone_moveWindows", IDS_SETTING_DESCRIPTION_APPLASTZONE_MOVEWINDOWS, settings.appLastZone_moveWindows);
|
||||
ptSettings.add_bool_toogle(L"use_cursorpos_editor_startupscreen", IDS_SETTING_DESCRIPTION_USE_CURSORPOS_EDITOR_STARTUPSCREEN, settings.use_cursorpos_editor_startupscreen);
|
||||
ptSettings.add_int_spinner(L"fancyzones_highlight_opacity", IDS_SETTINGS_HIGHLIGHT_OPACITY, settings.zoneHighlightOpacity, 0, 100, 1);
|
||||
ptSettings.add_color_picker(L"fancyzones_zoneHighlightColor", IDS_SETTING_DESCRIPTION_ZONEHIGHLIGHTCOLOR, settings.zoneHightlightColor);
|
||||
ptSettings.add_multiline_string(L"fancyzones_excluded_apps", IDS_SETTING_EXCLCUDED_APPS_DESCRIPTION, settings.excludedApps);
|
||||
|
||||
return ptSettings.serialize();
|
||||
}
|
||||
|
||||
TEST_METHOD_INITIALIZE(Init)
|
||||
{
|
||||
HINSTANCE hInst = (HINSTANCE)GetModuleHandleW(nullptr);
|
||||
|
||||
//init m_settings
|
||||
const Settings expected{
|
||||
.shiftDrag = false,
|
||||
.displayChange_moveWindows = true,
|
||||
.virtualDesktopChange_moveWindows = true,
|
||||
.zoneSetChange_flashZones = true,
|
||||
.zoneSetChange_moveWindows = true,
|
||||
.overrideSnapHotkeys = false,
|
||||
.appLastZone_moveWindows = false,
|
||||
.use_cursorpos_editor_startupscreen = true,
|
||||
.zoneHightlightColor = 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);
|
||||
values.add_property(L"fancyzones_shiftDrag", expected.shiftDrag);
|
||||
values.add_property(L"fancyzones_displayChange_moveWindows", expected.displayChange_moveWindows);
|
||||
values.add_property(L"fancyzones_virtualDesktopChange_moveWindows", expected.virtualDesktopChange_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_appLastZone_moveWindows", expected.appLastZone_moveWindows);
|
||||
values.add_property(L"use_cursorpos_editor_startupscreen", expected.use_cursorpos_editor_startupscreen);
|
||||
values.add_property(L"fancyzones_zoneHighlightColor", expected.zoneHightlightColor);
|
||||
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);
|
||||
Assert::IsTrue(m_settings != nullptr);
|
||||
|
||||
//init m_ptSettings
|
||||
m_ptSettings = new PowerToysSettings::Settings(hInst, m_moduleName);
|
||||
m_ptSettings->set_description(IDS_SETTING_DESCRIPTION);
|
||||
m_ptSettings->set_icon_key(L"pt-fancy-zones");
|
||||
m_ptSettings->set_overview_link(L"https://github.com/microsoft/PowerToys/blob/master/src/modules/fancyzones/README.md");
|
||||
m_ptSettings->set_video_link(L"https://youtu.be/rTtGzZYAXgY");
|
||||
|
||||
m_ptSettings->add_custom_action(
|
||||
L"ToggledFZEditor", // action name.
|
||||
IDS_SETTING_LAUNCH_EDITOR_LABEL,
|
||||
IDS_SETTING_LAUNCH_EDITOR_BUTTON,
|
||||
IDS_SETTING_LAUNCH_EDITOR_DESCRIPTION);
|
||||
m_ptSettings->add_hotkey(L"fancyzones_editor_hotkey", IDS_SETTING_LAUNCH_EDITOR_HOTKEY_LABEL, expected.editorHotkey);
|
||||
m_ptSettings->add_bool_toogle(L"fancyzones_shiftDrag", IDS_SETTING_DESCRIPTION_SHIFTDRAG, expected.shiftDrag);
|
||||
m_ptSettings->add_bool_toogle(L"fancyzones_overrideSnapHotkeys", IDS_SETTING_DESCRIPTION_OVERRIDE_SNAP_HOTKEYS, expected.overrideSnapHotkeys);
|
||||
m_ptSettings->add_bool_toogle(L"fancyzones_zoneSetChange_flashZones", IDS_SETTING_DESCRIPTION_ZONESETCHANGE_FLASHZONES, expected.zoneSetChange_flashZones);
|
||||
m_ptSettings->add_bool_toogle(L"fancyzones_displayChange_moveWindows", IDS_SETTING_DESCRIPTION_DISPLAYCHANGE_MOVEWINDOWS, expected.displayChange_moveWindows);
|
||||
m_ptSettings->add_bool_toogle(L"fancyzones_zoneSetChange_moveWindows", IDS_SETTING_DESCRIPTION_ZONESETCHANGE_MOVEWINDOWS, expected.zoneSetChange_moveWindows);
|
||||
m_ptSettings->add_bool_toogle(L"fancyzones_virtualDesktopChange_moveWindows", IDS_SETTING_DESCRIPTION_VIRTUALDESKTOPCHANGE_MOVEWINDOWS, expected.virtualDesktopChange_moveWindows);
|
||||
m_ptSettings->add_bool_toogle(L"fancyzones_appLastZone_moveWindows", IDS_SETTING_DESCRIPTION_APPLASTZONE_MOVEWINDOWS, expected.appLastZone_moveWindows);
|
||||
m_ptSettings->add_bool_toogle(L"use_cursorpos_editor_startupscreen", IDS_SETTING_DESCRIPTION_USE_CURSORPOS_EDITOR_STARTUPSCREEN, expected.use_cursorpos_editor_startupscreen);
|
||||
m_ptSettings->add_int_spinner(L"fancyzones_highlight_opacity", IDS_SETTINGS_HIGHLIGHT_OPACITY, expected.zoneHighlightOpacity, 0, 100, 1);
|
||||
m_ptSettings->add_color_picker(L"fancyzones_zoneHighlightColor", IDS_SETTING_DESCRIPTION_ZONEHIGHLIGHTCOLOR, expected.zoneHightlightColor);
|
||||
m_ptSettings->add_multiline_string(L"fancyzones_excluded_apps", IDS_SETTING_EXCLCUDED_APPS_DESCRIPTION, expected.excludedApps);
|
||||
}
|
||||
|
||||
TEST_METHOD_CLEANUP(Cleanup)
|
||||
{
|
||||
const auto settingsFile = PTSettingsHelper::get_module_save_folder_location(m_moduleName) + L"\\settings.json";
|
||||
std::filesystem::remove(settingsFile);
|
||||
}
|
||||
|
||||
TEST_METHOD(GetConfig)
|
||||
{
|
||||
const int expectedSize = m_ptSettings->serialize().size() + 1;
|
||||
|
||||
int actualBufferSize = expectedSize;
|
||||
PWSTR actualBuffer = new wchar_t[actualBufferSize];
|
||||
|
||||
Assert::IsTrue(m_settings->GetConfig(actualBuffer, &actualBufferSize));
|
||||
Assert::AreEqual(expectedSize, actualBufferSize);
|
||||
|
||||
Assert::AreEqual(m_ptSettings->serialize().c_str(), actualBuffer);
|
||||
}
|
||||
|
||||
TEST_METHOD(GetConfigSmallBuffer)
|
||||
{
|
||||
const auto serialized = m_ptSettings->serialize();
|
||||
const int expectedSize = serialized.size() + 1;
|
||||
|
||||
int actualBufferSize = m_ptSettings->serialize().size() - 1;
|
||||
PWSTR actualBuffer = new wchar_t[actualBufferSize];
|
||||
|
||||
Assert::IsFalse(m_settings->GetConfig(actualBuffer, &actualBufferSize));
|
||||
Assert::AreEqual(expectedSize, actualBufferSize);
|
||||
Assert::AreNotEqual(serialized.c_str(), actualBuffer);
|
||||
}
|
||||
|
||||
TEST_METHOD(GetConfigNullBuffer)
|
||||
{
|
||||
const auto serialized = m_ptSettings->serialize();
|
||||
const int expectedSize = serialized.size() + 1;
|
||||
|
||||
int actualBufferSize = 0;
|
||||
PWSTR actualBuffer = nullptr;
|
||||
|
||||
Assert::IsFalse(m_settings->GetConfig(actualBuffer, &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,
|
||||
.displayChange_moveWindows = true,
|
||||
.virtualDesktopChange_moveWindows = true,
|
||||
.zoneSetChange_flashZones = false,
|
||||
.zoneSetChange_moveWindows = true,
|
||||
.overrideSnapHotkeys = false,
|
||||
.appLastZone_moveWindows = true,
|
||||
.use_cursorpos_editor_startupscreen = true,
|
||||
.zoneHightlightColor = 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));
|
||||
}
|
||||
};
|
||||
}
|
||||
1659
src/modules/fancyzones/tests/UnitTests/JsonHelpers.Tests.cpp
Normal file
1659
src/modules/fancyzones/tests/UnitTests/JsonHelpers.Tests.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,35 +0,0 @@
|
||||
#include "pch.h"
|
||||
#include "lib\RegistryHelpers.h"
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
|
||||
namespace FancyZonesUnitTests
|
||||
{
|
||||
TEST_CLASS(RegistryHelpersUnitTests){
|
||||
public:
|
||||
TEST_METHOD(GetDefaultKey){
|
||||
// Test the path to the key is the same string.
|
||||
wchar_t key[256];
|
||||
Assert::AreEqual(0, wcscmp(RegistryHelpers::GetKey(nullptr, key, ARRAYSIZE(key)), L"Software\\SuperFancyZones"));
|
||||
}
|
||||
|
||||
TEST_METHOD(GetKeyWithMonitor)
|
||||
{
|
||||
// Test the path to the key is the same string.
|
||||
wchar_t key[256];
|
||||
Assert::AreEqual(0, wcscmp(RegistryHelpers::GetKey(L"Monitor1", key, ARRAYSIZE(key)), L"Software\\SuperFancyZones\\Monitor1"));
|
||||
}
|
||||
|
||||
TEST_METHOD(OpenKey)
|
||||
{
|
||||
// The default key should exist.
|
||||
wil::unique_hkey key{ RegistryHelpers::OpenKey({}) };
|
||||
Assert::IsNotNull(key.get());
|
||||
|
||||
// The Monitor1 key shouldn't exist.
|
||||
wil::unique_hkey key2{ RegistryHelpers::OpenKey(L"Monitor1") };
|
||||
Assert::IsNull(key2.get());
|
||||
}
|
||||
}
|
||||
;
|
||||
}
|
||||
@@ -96,12 +96,15 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="FancyZones.Spec.cpp" />
|
||||
<ClCompile Include="FancyZonesSettings.Spec.cpp" />
|
||||
<ClCompile Include="JsonHelpers.Tests.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RegistryHelpers.Spec.cpp" />
|
||||
<ClCompile Include="Util.Spec.cpp" />
|
||||
<ClCompile Include="Util.cpp" />
|
||||
<ClCompile Include="Zone.Spec.cpp" />
|
||||
<ClCompile Include="ZoneSet.Spec.cpp" />
|
||||
<ClCompile Include="ZoneWindow.Spec.cpp" />
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
@@ -24,15 +24,24 @@
|
||||
<ClCompile Include="Zone.Spec.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RegistryHelpers.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">
|
||||
|
||||
149
src/modules/fancyzones/tests/UnitTests/Util.cpp
Normal file
149
src/modules/fancyzones/tests/UnitTests/Util.cpp
Normal file
@@ -0,0 +1,149 @@
|
||||
#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);
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "lib/JsonHelpers.h"
|
||||
|
||||
namespace CustomAssert
|
||||
{
|
||||
static void AreEqual(const RECT& r1, const RECT& r2)
|
||||
@@ -13,9 +15,9 @@ namespace CustomAssert
|
||||
Microsoft::VisualStudio::CppUnitTestFramework::Assert::IsTrue(g1 == g2);
|
||||
}
|
||||
|
||||
static void AreEqual(WORD w1, WORD w2)
|
||||
static void AreEqual(JSONHelpers::ZoneSetLayoutType t1, JSONHelpers::ZoneSetLayoutType t2)
|
||||
{
|
||||
Microsoft::VisualStudio::CppUnitTestFramework::Assert::IsTrue(w1 == w2);
|
||||
Microsoft::VisualStudio::CppUnitTestFramework::Assert::IsTrue(t1 == t2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,4 +41,5 @@ namespace Mocks
|
||||
return reinterpret_cast<HINSTANCE>(++s_nextInstance);
|
||||
}
|
||||
|
||||
}
|
||||
HWND WindowCreate(HINSTANCE hInst);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "pch.h"
|
||||
#include "lib\Zone.h"
|
||||
#include "lib\Settings.h"
|
||||
|
||||
#include "Util.h"
|
||||
|
||||
@@ -7,48 +8,419 @@ using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
|
||||
namespace FancyZonesUnitTests
|
||||
{
|
||||
TEST_CLASS(ZoneUnitTests){
|
||||
public:
|
||||
TEST_METHOD(TestCreateZone){
|
||||
RECT zoneRect{ 10, 10, 200, 200 };
|
||||
winrt::com_ptr<IZone> zone = MakeZone(zoneRect);
|
||||
Assert::IsNotNull(&zone);
|
||||
CustomAssert::AreEqual(zoneRect, zone->GetZoneRect());
|
||||
TEST_CLASS(ZoneUnitTests)
|
||||
{
|
||||
private:
|
||||
RECT m_zoneRect{ 10, 10, 200, 200 };
|
||||
HINSTANCE m_hInst{};
|
||||
|
||||
constexpr size_t id = 10;
|
||||
zone->SetId(id);
|
||||
Assert::AreEqual(zone->Id(), id);
|
||||
}
|
||||
HWND addWindow(const winrt::com_ptr<IZone>& zone, bool stamp)
|
||||
{
|
||||
HWND window = Mocks::WindowCreate(m_hInst);
|
||||
HWND zoneWindow = Mocks::WindowCreate(m_hInst);
|
||||
zone->AddWindowToZone(window, zoneWindow, stamp);
|
||||
|
||||
TEST_METHOD(ContainsWindow)
|
||||
{
|
||||
RECT zoneRect{ 10, 10, 200, 200 };
|
||||
winrt::com_ptr<IZone> zone = MakeZone(zoneRect);
|
||||
HWND newWindow = Mocks::Window();
|
||||
Assert::IsFalse(zone->ContainsWindow(newWindow));
|
||||
}
|
||||
return window;
|
||||
}
|
||||
|
||||
TEST_METHOD(TestAddRemoveWindow)
|
||||
{
|
||||
RECT zoneRect{ 10, 10, 200, 200 };
|
||||
winrt::com_ptr<IZone> zone = MakeZone(zoneRect);
|
||||
HWND newWindow = Mocks::Window();
|
||||
void addMany(const winrt::com_ptr<IZone>& zone)
|
||||
{
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
addWindow(zone, i % 2 == 0);
|
||||
}
|
||||
}
|
||||
|
||||
Assert::IsFalse(zone->ContainsWindow(newWindow));
|
||||
zone->AddWindowToZone(newWindow, Mocks::Window(), true);
|
||||
Assert::IsTrue(zone->ContainsWindow(newWindow));
|
||||
TEST_METHOD_INITIALIZE(Init)
|
||||
{
|
||||
m_hInst = (HINSTANCE)GetModuleHandleW(nullptr);
|
||||
}
|
||||
|
||||
zone->RemoveWindowFromZone(newWindow, false);
|
||||
Assert::IsFalse(zone->ContainsWindow(newWindow));
|
||||
}
|
||||
public:
|
||||
TEST_METHOD(TestCreateZone)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect);
|
||||
Assert::IsNotNull(&zone);
|
||||
CustomAssert::AreEqual(m_zoneRect, zone->GetZoneRect());
|
||||
}
|
||||
|
||||
TEST_METHOD(TestRemoveInvalidWindow)
|
||||
{
|
||||
RECT zoneRect{ 10, 10, 200, 200 };
|
||||
winrt::com_ptr<IZone> zone = MakeZone(zoneRect);
|
||||
HWND newWindow = Mocks::Window();
|
||||
zone->RemoveWindowFromZone(newWindow, false);
|
||||
}
|
||||
}
|
||||
;
|
||||
TEST_METHOD(TestCreateZoneZeroRect)
|
||||
{
|
||||
RECT zoneRect{ 0, 0, 0, 0 };
|
||||
winrt::com_ptr<IZone> zone = MakeZone(zoneRect);
|
||||
Assert::IsNotNull(&zone);
|
||||
CustomAssert::AreEqual(zoneRect, zone->GetZoneRect());
|
||||
}
|
||||
|
||||
TEST_METHOD(GetSetId)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect);
|
||||
|
||||
constexpr size_t id = 10;
|
||||
zone->SetId(id);
|
||||
Assert::AreEqual(zone->Id(), id);
|
||||
}
|
||||
|
||||
TEST_METHOD(IsEmpty)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect);
|
||||
Assert::IsTrue(zone->IsEmpty());
|
||||
}
|
||||
|
||||
TEST_METHOD(IsNonEmptyStampTrue)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect);
|
||||
addWindow(zone, true);
|
||||
|
||||
Assert::IsFalse(zone->IsEmpty());
|
||||
}
|
||||
|
||||
TEST_METHOD(IsNonEmptyStampFalse)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect);
|
||||
addWindow(zone, false);
|
||||
|
||||
Assert::IsFalse(zone->IsEmpty());
|
||||
}
|
||||
|
||||
TEST_METHOD(IsNonEmptyManyWindows)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect);
|
||||
|
||||
HWND zoneWindow = Mocks::WindowCreate(m_hInst);
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
HWND window = Mocks::WindowCreate(m_hInst);
|
||||
zone->AddWindowToZone(window, zoneWindow, i % 2 == 0);
|
||||
}
|
||||
|
||||
Assert::IsFalse(zone->IsEmpty());
|
||||
}
|
||||
|
||||
TEST_METHOD(IsNonEmptyManyZoneWindows)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect);
|
||||
|
||||
HWND window = Mocks::WindowCreate(m_hInst);
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
HWND zoneWindow = Mocks::WindowCreate(m_hInst);
|
||||
zone->AddWindowToZone(window, zoneWindow, i % 2 == 0);
|
||||
}
|
||||
|
||||
Assert::IsFalse(zone->IsEmpty());
|
||||
}
|
||||
|
||||
TEST_METHOD(IsNonEmptyMany)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect);
|
||||
addMany(zone);
|
||||
|
||||
Assert::IsFalse(zone->IsEmpty());
|
||||
}
|
||||
|
||||
TEST_METHOD(ContainsWindowEmpty)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect);
|
||||
HWND newWindow = Mocks::WindowCreate(m_hInst);
|
||||
Assert::IsFalse(zone->ContainsWindow(newWindow));
|
||||
}
|
||||
|
||||
TEST_METHOD(ContainsWindowNot)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect);
|
||||
addMany(zone);
|
||||
|
||||
HWND newWindow = Mocks::WindowCreate(m_hInst);
|
||||
Assert::IsFalse(zone->ContainsWindow(newWindow));
|
||||
}
|
||||
|
||||
TEST_METHOD(ContainsWindowStampTrue)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect);
|
||||
HWND window = addWindow(zone, true);
|
||||
|
||||
Assert::IsTrue(zone->ContainsWindow(window));
|
||||
}
|
||||
|
||||
TEST_METHOD(ContainsWindowStampFalse)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect);
|
||||
HWND window = addWindow(zone, false);
|
||||
|
||||
Assert::IsTrue(zone->ContainsWindow(window));
|
||||
}
|
||||
|
||||
TEST_METHOD(ContainsWindowManyWindows)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect);
|
||||
|
||||
HWND zoneWindow = Mocks::WindowCreate(m_hInst);
|
||||
std::vector<HWND> windowVec{};
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
HWND window = Mocks::WindowCreate(m_hInst);
|
||||
windowVec.push_back(window);
|
||||
zone->AddWindowToZone(window, zoneWindow, i % 2 == 0);
|
||||
}
|
||||
|
||||
for (auto wnd : windowVec)
|
||||
{
|
||||
Assert::IsTrue(zone->ContainsWindow(wnd));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(ContainsWindowManyZoneWindows)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect);
|
||||
|
||||
HWND window = Mocks::WindowCreate(m_hInst);
|
||||
std::vector<HWND> windowVec{};
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
HWND zoneWindow = Mocks::WindowCreate(m_hInst);
|
||||
windowVec.push_back(window);
|
||||
zone->AddWindowToZone(window, zoneWindow, i % 2 == 0);
|
||||
}
|
||||
|
||||
for (auto wnd : windowVec)
|
||||
{
|
||||
Assert::IsTrue(zone->ContainsWindow(wnd));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(ContainsWindowMany)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect);
|
||||
|
||||
std::vector<HWND> windowVec{};
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
HWND window = addWindow(zone, i % 2 == 0);
|
||||
windowVec.push_back(window);
|
||||
}
|
||||
|
||||
for (auto wnd : windowVec)
|
||||
{
|
||||
Assert::IsTrue(zone->ContainsWindow(wnd));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(AddWindowNullptr)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect);
|
||||
|
||||
HWND window = nullptr;
|
||||
HWND zoneWindow = Mocks::WindowCreate(m_hInst);
|
||||
zone->AddWindowToZone(window, zoneWindow, true);
|
||||
|
||||
Assert::IsFalse(zone->IsEmpty());
|
||||
Assert::IsTrue(zone->ContainsWindow(window));
|
||||
}
|
||||
|
||||
TEST_METHOD(AddWindowZoneNullptr)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect);
|
||||
|
||||
HWND window = Mocks::WindowCreate(m_hInst);
|
||||
HWND zoneWindow = nullptr;
|
||||
zone->AddWindowToZone(window, zoneWindow, true);
|
||||
|
||||
Assert::IsFalse(zone->IsEmpty());
|
||||
Assert::IsTrue(zone->ContainsWindow(window));
|
||||
}
|
||||
|
||||
TEST_METHOD(AddManySame)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect);
|
||||
|
||||
HWND zoneWindow = Mocks::WindowCreate(m_hInst);
|
||||
HWND window = Mocks::WindowCreate(m_hInst);
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
zone->AddWindowToZone(window, zoneWindow, i % 2 == 0);
|
||||
}
|
||||
|
||||
Assert::IsFalse(zone->IsEmpty());
|
||||
Assert::IsTrue(zone->ContainsWindow(window));
|
||||
}
|
||||
|
||||
TEST_METHOD(AddManySameNullptr)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect);
|
||||
|
||||
HWND zoneWindow = nullptr;
|
||||
HWND window = nullptr;
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
zone->AddWindowToZone(window, zoneWindow, i % 2 == 0);
|
||||
}
|
||||
|
||||
Assert::IsTrue(zone->ContainsWindow(window));
|
||||
}
|
||||
|
||||
TEST_METHOD(RemoveWindowRestoreSizeTrue)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect);
|
||||
HWND newWindow = Mocks::WindowCreate(m_hInst);
|
||||
|
||||
zone->AddWindowToZone(newWindow, Mocks::WindowCreate(m_hInst), true);
|
||||
Assert::IsFalse(zone->IsEmpty());
|
||||
Assert::IsTrue(zone->ContainsWindow(newWindow));
|
||||
|
||||
zone->RemoveWindowFromZone(newWindow, true);
|
||||
Assert::IsTrue(zone->IsEmpty());
|
||||
Assert::IsFalse(zone->ContainsWindow(newWindow));
|
||||
}
|
||||
|
||||
TEST_METHOD(RemoveWindowRestoreSizeFalse)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect);
|
||||
HWND newWindow = Mocks::WindowCreate(m_hInst);
|
||||
|
||||
zone->AddWindowToZone(newWindow, Mocks::WindowCreate(m_hInst), true);
|
||||
Assert::IsFalse(zone->IsEmpty());
|
||||
Assert::IsTrue(zone->ContainsWindow(newWindow));
|
||||
|
||||
zone->RemoveWindowFromZone(newWindow, false);
|
||||
Assert::IsTrue(zone->IsEmpty());
|
||||
Assert::IsFalse(zone->ContainsWindow(newWindow));
|
||||
}
|
||||
|
||||
TEST_METHOD(RemoveInvalidWindowRestoreSizeTrue)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect);
|
||||
HWND newWindow = Mocks::WindowCreate(m_hInst);
|
||||
zone->RemoveWindowFromZone(newWindow, true);
|
||||
|
||||
Assert::IsTrue(zone->IsEmpty());
|
||||
Assert::IsFalse(zone->ContainsWindow(newWindow));
|
||||
}
|
||||
|
||||
TEST_METHOD(RemoveInvalidWindowRestoreSizeFalse)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect);
|
||||
HWND newWindow = Mocks::WindowCreate(m_hInst);
|
||||
zone->RemoveWindowFromZone(newWindow, false);
|
||||
|
||||
Assert::IsTrue(zone->IsEmpty());
|
||||
Assert::IsFalse(zone->ContainsWindow(newWindow));
|
||||
}
|
||||
|
||||
TEST_METHOD(RemoveNullptrWindowRestoreSizeTrue)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect);
|
||||
HWND newWindow = nullptr;
|
||||
|
||||
zone->AddWindowToZone(newWindow, Mocks::WindowCreate(m_hInst), true);
|
||||
Assert::IsFalse(zone->IsEmpty());
|
||||
Assert::IsTrue(zone->ContainsWindow(newWindow));
|
||||
|
||||
zone->RemoveWindowFromZone(newWindow, true);
|
||||
Assert::IsTrue(zone->IsEmpty());
|
||||
Assert::IsFalse(zone->ContainsWindow(newWindow));
|
||||
}
|
||||
|
||||
TEST_METHOD(RemoveNullptrWindowRestoreSizeFalse)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect);
|
||||
HWND newWindow = nullptr;
|
||||
|
||||
zone->AddWindowToZone(newWindow, Mocks::WindowCreate(m_hInst), true);
|
||||
Assert::IsFalse(zone->IsEmpty());
|
||||
Assert::IsTrue(zone->ContainsWindow(newWindow));
|
||||
|
||||
zone->RemoveWindowFromZone(newWindow, false);
|
||||
Assert::IsTrue(zone->IsEmpty());
|
||||
Assert::IsFalse(zone->ContainsWindow(newWindow));
|
||||
}
|
||||
|
||||
TEST_METHOD(RemoveMany)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect);
|
||||
|
||||
std::vector<HWND> windowVec{};
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
HWND window = addWindow(zone, i % 2 == 0);
|
||||
windowVec.push_back(window);
|
||||
}
|
||||
|
||||
for (auto wnd : windowVec)
|
||||
{
|
||||
zone->RemoveWindowFromZone(wnd, true);
|
||||
}
|
||||
|
||||
Assert::IsTrue(zone->IsEmpty());
|
||||
}
|
||||
|
||||
TEST_METHOD(RemoveManySame)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect);
|
||||
|
||||
HWND zoneWindow = Mocks::WindowCreate(m_hInst);
|
||||
HWND window = Mocks::WindowCreate(m_hInst);
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
zone->AddWindowToZone(window, zoneWindow, i % 2 == 0);
|
||||
}
|
||||
|
||||
zone->RemoveWindowFromZone(window, true);
|
||||
|
||||
Assert::IsTrue(zone->IsEmpty());
|
||||
Assert::IsFalse(zone->ContainsWindow(window));
|
||||
}
|
||||
|
||||
TEST_METHOD(RemoveDouble)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect);
|
||||
|
||||
HWND zoneWindow = Mocks::WindowCreate(m_hInst);
|
||||
HWND window = Mocks::WindowCreate(m_hInst);
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
zone->AddWindowToZone(window, zoneWindow, i % 2 == 0);
|
||||
}
|
||||
|
||||
zone->RemoveWindowFromZone(window, true);
|
||||
zone->RemoveWindowFromZone(window, true);
|
||||
|
||||
Assert::IsTrue(zone->IsEmpty());
|
||||
}
|
||||
|
||||
TEST_METHOD(StampTrue)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect);
|
||||
size_t expected = 123456;
|
||||
zone->SetId(expected);
|
||||
|
||||
HWND window = addWindow(zone, true);
|
||||
|
||||
HANDLE actual = GetProp(window, ZONE_STAMP);
|
||||
Assert::IsNotNull(actual);
|
||||
|
||||
size_t actualVal = HandleToLong(actual);
|
||||
Assert::AreEqual(expected, actualVal);
|
||||
}
|
||||
|
||||
TEST_METHOD(StampTrueNoId)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect);
|
||||
|
||||
HWND window = addWindow(zone, true);
|
||||
|
||||
HANDLE actual = GetProp(window, ZONE_STAMP);
|
||||
Assert::IsNull(actual);
|
||||
}
|
||||
|
||||
TEST_METHOD(StampFalse)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect);
|
||||
|
||||
HWND window = addWindow(zone, false);
|
||||
|
||||
HANDLE actual = GetProp(window, ZONE_STAMP);
|
||||
Assert::IsNull(actual);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,14 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
#include <common/common.h>
|
||||
#include <lib/util.h>
|
||||
#include <lib/ZoneSet.h>
|
||||
#include <lib/ZoneWindow.h>
|
||||
#include <lib/FancyZones.h>
|
||||
#include "Util.h"
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
|
||||
namespace FancyZonesUnitTests
|
||||
@@ -17,10 +22,10 @@ namespace FancyZonesUnitTests
|
||||
{
|
||||
return RGB(0xFF, 0xFF, 0xFF);
|
||||
}
|
||||
IFACEMETHODIMP_(GUID)
|
||||
GetCurrentMonitorZoneSetId(HMONITOR monitor) noexcept
|
||||
IFACEMETHODIMP_(IZoneWindow*)
|
||||
GetParentZoneWindow(HMONITOR monitor) noexcept
|
||||
{
|
||||
return m_guid;
|
||||
return m_zoneWindow;
|
||||
}
|
||||
IFACEMETHODIMP_(int)
|
||||
GetZoneHighlightOpacity() noexcept
|
||||
@@ -28,47 +33,636 @@ namespace FancyZonesUnitTests
|
||||
return 100;
|
||||
}
|
||||
|
||||
GUID m_guid;
|
||||
IZoneWindow* m_zoneWindow;
|
||||
};
|
||||
|
||||
TEST_CLASS(ZoneWindowUnitTests){
|
||||
public:
|
||||
TEST_CLASS(ZoneWindowUnitTests)
|
||||
{
|
||||
const std::wstring m_deviceId = L"\\\\?\\DISPLAY#DELA026#5&10a58c63&0&UID16777488#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}";
|
||||
const std::wstring m_virtualDesktopId = L"MyVirtualDesktopId";
|
||||
std::wstringstream m_uniqueId;
|
||||
|
||||
TEST_METHOD(TestCreateZoneWindow){
|
||||
winrt::com_ptr<IZoneWindow> zoneWindow = MakeZoneWindow(nullptr, Mocks::Instance(), Mocks::Monitor(), L"DeviceId", L"MyVirtualDesktopId", false);
|
||||
Assert::IsNotNull(zoneWindow.get());
|
||||
}
|
||||
|
||||
TEST_METHOD(TestDeviceId)
|
||||
{
|
||||
// Window initialization requires a valid HMONITOR - just use the primary for now.
|
||||
HMONITOR pimaryMonitor = MonitorFromWindow(HWND(), MONITOR_DEFAULTTOPRIMARY);
|
||||
MockZoneWindowHost host;
|
||||
std::wstring expectedDeviceId = L"SomeRandomValue";
|
||||
winrt::com_ptr<IZoneWindow> zoneWindow = MakeZoneWindow(dynamic_cast<IZoneWindowHost*>(&host), Mocks::Instance(), pimaryMonitor, expectedDeviceId.c_str(), L"MyVirtualDesktopId", false);
|
||||
|
||||
Assert::AreEqual(expectedDeviceId, zoneWindow->DeviceId());
|
||||
}
|
||||
|
||||
TEST_METHOD(TestUniqueId)
|
||||
{
|
||||
// Unique id of the format "ParsedMonitorDeviceId_MonitorWidth_MonitorHeight_VirtualDesktopId
|
||||
// Example: "DELA026#5&10a58c63&0&UID16777488_1024_768_MyVirtualDesktopId"
|
||||
std::wstring deviceId(L"\\\\?\\DISPLAY#DELA026#5&10a58c63&0&UID16777488#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}");
|
||||
// Window initialization requires a valid HMONITOR - just use the primary for now.
|
||||
HMONITOR pimaryMonitor = MonitorFromWindow(HWND(), MONITOR_DEFAULTTOPRIMARY);
|
||||
MONITORINFO info;
|
||||
info.cbSize = sizeof(info);
|
||||
Assert::IsTrue(GetMonitorInfo(pimaryMonitor, &info));
|
||||
|
||||
Rect monitorRect = Rect(info.rcMonitor);
|
||||
std::wstringstream ss;
|
||||
ss << L"DELA026#5&10a58c63&0&UID16777488_" << monitorRect.width() << "_" << monitorRect.height() << "_MyVirtualDesktopId";
|
||||
|
||||
MockZoneWindowHost host;
|
||||
winrt::com_ptr<IZoneWindow> zoneWindow = MakeZoneWindow(dynamic_cast<IZoneWindowHost*>(&host), Mocks::Instance(), pimaryMonitor, deviceId.c_str(), L"MyVirtualDesktopId", false);
|
||||
Assert::AreEqual(zoneWindow->UniqueId().compare(ss.str()), 0);
|
||||
}
|
||||
}
|
||||
;
|
||||
HINSTANCE m_hInst{};
|
||||
HMONITOR m_monitor{};
|
||||
MONITORINFO m_monitorInfo{};
|
||||
MockZoneWindowHost m_zoneWindowHost{};
|
||||
IZoneWindowHost* m_hostPtr = m_zoneWindowHost.get_strong().get();
|
||||
|
||||
winrt::com_ptr<IZoneWindow> m_zoneWindow;
|
||||
|
||||
JSONHelpers::FancyZonesData& m_fancyZonesData = JSONHelpers::FancyZonesDataInstance();
|
||||
|
||||
std::wstring GuidString(const GUID& guid)
|
||||
{
|
||||
OLECHAR* guidString;
|
||||
Assert::AreEqual(S_OK, StringFromCLSID(guid, &guidString));
|
||||
|
||||
std::wstring guidStr{ guidString };
|
||||
CoTaskMemFree(guidString);
|
||||
|
||||
return guidStr;
|
||||
}
|
||||
|
||||
std::wstring CreateGuidString()
|
||||
{
|
||||
GUID guid;
|
||||
Assert::AreEqual(S_OK, CoCreateGuid(&guid));
|
||||
|
||||
return GuidString(guid);
|
||||
}
|
||||
|
||||
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 << "_MyVirtualDesktopId";
|
||||
|
||||
Assert::IsFalse(ZoneWindowUtils::GetActiveZoneSetTmpPath().empty());
|
||||
Assert::IsFalse(ZoneWindowUtils::GetAppliedZoneSetTmpPath().empty());
|
||||
Assert::IsFalse(ZoneWindowUtils::GetCustomZoneSetsTmpPath().empty());
|
||||
|
||||
Assert::IsFalse(std::filesystem::exists(ZoneWindowUtils::GetActiveZoneSetTmpPath()));
|
||||
Assert::IsFalse(std::filesystem::exists(ZoneWindowUtils::GetAppliedZoneSetTmpPath()));
|
||||
Assert::IsFalse(std::filesystem::exists(ZoneWindowUtils::GetCustomZoneSetsTmpPath()));
|
||||
|
||||
m_fancyZonesData = JSONHelpers::FancyZonesData();
|
||||
}
|
||||
|
||||
TEST_METHOD_CLEANUP(Cleanup)
|
||||
{
|
||||
//cleanup temp files if were created
|
||||
std::filesystem::remove(ZoneWindowUtils::GetActiveZoneSetTmpPath());
|
||||
std::filesystem::remove(ZoneWindowUtils::GetAppliedZoneSetTmpPath());
|
||||
std::filesystem::remove(ZoneWindowUtils::GetCustomZoneSetsTmpPath());
|
||||
|
||||
m_zoneWindow = nullptr;
|
||||
}
|
||||
|
||||
winrt::com_ptr<IZoneWindow> InitZoneWindowWithActiveZoneSet()
|
||||
{
|
||||
const auto activeZoneSetTempPath = ZoneWindowUtils::GetActiveZoneSetTmpPath();
|
||||
Assert::IsFalse(std::filesystem::exists(activeZoneSetTempPath));
|
||||
|
||||
const auto type = JSONHelpers::ZoneSetLayoutType::Columns;
|
||||
const auto expectedZoneSet = JSONHelpers::ZoneSetData{ CreateGuidString(), type };
|
||||
const auto data = JSONHelpers::DeviceInfoData{ expectedZoneSet, true, 16, 3 };
|
||||
const auto deviceInfo = JSONHelpers::DeviceInfoJSON{ m_uniqueId.str(), data };
|
||||
const auto json = JSONHelpers::DeviceInfoJSON::ToJson(deviceInfo);
|
||||
json::to_file(activeZoneSetTempPath, json);
|
||||
Assert::IsTrue(std::filesystem::exists(activeZoneSetTempPath));
|
||||
|
||||
m_fancyZonesData.ParseDeviceInfoFromTmpFile(activeZoneSetTempPath);
|
||||
|
||||
return MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
}
|
||||
|
||||
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::IsFalse(zoneWindow->IsDragEnabled());
|
||||
Assert::AreEqual(m_uniqueId.str().c_str(), zoneWindow->UniqueId().c_str());
|
||||
Assert::AreEqual(expectedWorkArea, zoneWindow->WorkAreaKey());
|
||||
}
|
||||
|
||||
public:
|
||||
TEST_METHOD(CreateZoneWindow)
|
||||
{
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
testZoneWindow(m_zoneWindow);
|
||||
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
|
||||
}
|
||||
|
||||
TEST_METHOD(CreateZoneWindowNoHinst)
|
||||
{
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, {}, m_monitor, m_uniqueId.str(), false);
|
||||
|
||||
testZoneWindow(m_zoneWindow);
|
||||
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
|
||||
}
|
||||
|
||||
TEST_METHOD(CreateZoneWindowNoHinstFlashZones)
|
||||
{
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, {}, m_monitor, m_uniqueId.str(), true);
|
||||
|
||||
testZoneWindow(m_zoneWindow);
|
||||
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
|
||||
}
|
||||
|
||||
TEST_METHOD(CreateZoneWindowNoMonitor)
|
||||
{
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, {}, m_uniqueId.str(), false);
|
||||
|
||||
Assert::IsNull(m_zoneWindow.get());
|
||||
Assert::IsNotNull(m_hostPtr);
|
||||
}
|
||||
|
||||
TEST_METHOD(CreateZoneWindowNoMonitorFlashZones)
|
||||
{
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, {}, m_uniqueId.str(), true);
|
||||
|
||||
Assert::IsNull(m_zoneWindow.get());
|
||||
Assert::IsNotNull(m_hostPtr);
|
||||
}
|
||||
|
||||
TEST_METHOD(CreateZoneWindowNoDeviceId)
|
||||
{
|
||||
// Generate unique id without device id
|
||||
std::wstring uniqueId = ZoneWindowUtils::GenerateUniqueId(m_monitor, nullptr, m_virtualDesktopId.c_str());
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, uniqueId, false);
|
||||
|
||||
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(m_zoneWindow.get());
|
||||
Assert::IsFalse(m_zoneWindow->IsDragEnabled());
|
||||
Assert::AreEqual(expectedUniqueId.c_str(), m_zoneWindow->UniqueId().c_str());
|
||||
Assert::AreEqual(expectedWorkArea, m_zoneWindow->WorkAreaKey());
|
||||
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
|
||||
}
|
||||
|
||||
TEST_METHOD(CreateZoneWindowNoDesktopId)
|
||||
{
|
||||
// Generate unique id without virtual desktop id
|
||||
std::wstring uniqueId = ZoneWindowUtils::GenerateUniqueId(m_monitor, m_deviceId.c_str(), nullptr);
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, uniqueId, false);
|
||||
|
||||
const std::wstring expectedWorkArea = std::to_wstring(m_monitorInfo.rcMonitor.right) + L"_" + std::to_wstring(m_monitorInfo.rcMonitor.bottom);
|
||||
Assert::IsNotNull(m_zoneWindow.get());
|
||||
Assert::IsFalse(m_zoneWindow->IsDragEnabled());
|
||||
Assert::IsTrue(m_zoneWindow->UniqueId().empty());
|
||||
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
|
||||
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
|
||||
}
|
||||
|
||||
TEST_METHOD(CreateZoneWindowWithActiveZoneTmpFile)
|
||||
{
|
||||
using namespace JSONHelpers;
|
||||
|
||||
const auto activeZoneSetTempPath = ZoneWindowUtils::GetActiveZoneSetTmpPath();
|
||||
|
||||
for (int type = static_cast<int>(ZoneSetLayoutType::Focus); type < static_cast<int>(ZoneSetLayoutType::Custom); type++)
|
||||
{
|
||||
const auto expectedZoneSet = ZoneSetData{ CreateGuidString(), static_cast<ZoneSetLayoutType>(type) };
|
||||
const auto data = DeviceInfoData{ expectedZoneSet, true, 16, 3 };
|
||||
const auto deviceInfo = DeviceInfoJSON{ m_uniqueId.str(), data };
|
||||
const auto json = DeviceInfoJSON::ToJson(deviceInfo);
|
||||
json::to_file(activeZoneSetTempPath, json);
|
||||
|
||||
m_fancyZonesData.ParseDeviceInfoFromTmpFile(activeZoneSetTempPath);
|
||||
|
||||
//temp file read on initialization
|
||||
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
|
||||
testZoneWindow(actual);
|
||||
|
||||
Assert::IsNotNull(actual->ActiveZoneSet());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(CreateZoneWindowWithActiveCustomZoneTmpFile)
|
||||
{
|
||||
using namespace JSONHelpers;
|
||||
|
||||
const auto activeZoneSetTempPath = ZoneWindowUtils::GetActiveZoneSetTmpPath();
|
||||
|
||||
const ZoneSetLayoutType type = ZoneSetLayoutType::Custom;
|
||||
const auto expectedZoneSet = ZoneSetData{ CreateGuidString(), type };
|
||||
const auto data = DeviceInfoData{ expectedZoneSet, true, 16, 3 };
|
||||
const auto deviceInfo = DeviceInfoJSON{ m_uniqueId.str(), data };
|
||||
const auto json = DeviceInfoJSON::ToJson(deviceInfo);
|
||||
json::to_file(activeZoneSetTempPath, json);
|
||||
|
||||
m_fancyZonesData.ParseDeviceInfoFromTmpFile(activeZoneSetTempPath);
|
||||
|
||||
//temp file read on initialization
|
||||
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
|
||||
testZoneWindow(actual);
|
||||
|
||||
//custom zone needs temp file for applied zone
|
||||
Assert::IsNotNull(actual->ActiveZoneSet());
|
||||
const auto actualZoneSet = actual->ActiveZoneSet()->GetZones();
|
||||
Assert::AreEqual((size_t)0, actualZoneSet.size());
|
||||
}
|
||||
|
||||
TEST_METHOD(CreateZoneWindowWithActiveCustomZoneAppliedTmpFile)
|
||||
{
|
||||
using namespace JSONHelpers;
|
||||
|
||||
//save required data
|
||||
const auto activeZoneSetTempPath = ZoneWindowUtils::GetActiveZoneSetTmpPath();
|
||||
const auto appliedZoneSetTempPath = ZoneWindowUtils::GetAppliedZoneSetTmpPath();
|
||||
|
||||
const ZoneSetLayoutType type = ZoneSetLayoutType::Custom;
|
||||
const auto customSetGuid = CreateGuidString();
|
||||
const auto expectedZoneSet = ZoneSetData{ customSetGuid, type };
|
||||
const auto data = DeviceInfoData{ expectedZoneSet, true, 16, 3 };
|
||||
const auto deviceInfo = DeviceInfoJSON{ m_uniqueId.str(), data };
|
||||
const auto json = DeviceInfoJSON::ToJson(deviceInfo);
|
||||
json::to_file(activeZoneSetTempPath, json);
|
||||
|
||||
const auto info = CanvasLayoutInfo{
|
||||
100, 100, std::vector{ CanvasLayoutInfo::Rect{ 0, 0, 100, 100 } }
|
||||
};
|
||||
const auto customZoneData = CustomZoneSetData{ L"name", CustomLayoutType::Canvas, info };
|
||||
auto customZoneJson = CustomZoneSetJSON::ToJson(CustomZoneSetJSON{ customSetGuid, customZoneData });
|
||||
json::to_file(appliedZoneSetTempPath, customZoneJson);
|
||||
m_fancyZonesData.ParseDeviceInfoFromTmpFile(activeZoneSetTempPath);
|
||||
m_fancyZonesData.ParseCustomZoneSetFromTmpFile(appliedZoneSetTempPath);
|
||||
|
||||
//temp file read on initialization
|
||||
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
|
||||
testZoneWindow(actual);
|
||||
|
||||
//custom zone needs temp file for applied zone
|
||||
Assert::IsNotNull(actual->ActiveZoneSet());
|
||||
const auto actualZoneSet = actual->ActiveZoneSet()->GetZones();
|
||||
Assert::AreEqual((size_t)1, actualZoneSet.size());
|
||||
}
|
||||
|
||||
TEST_METHOD(CreateZoneWindowWithActiveCustomZoneAppliedTmpFileWithDeletedCustomZones)
|
||||
{
|
||||
using namespace JSONHelpers;
|
||||
|
||||
//save required data
|
||||
const auto activeZoneSetTempPath = ZoneWindowUtils::GetActiveZoneSetTmpPath();
|
||||
const auto appliedZoneSetTempPath = ZoneWindowUtils::GetAppliedZoneSetTmpPath();
|
||||
const auto deletedZonesTempPath = ZoneWindowUtils::GetCustomZoneSetsTmpPath();
|
||||
|
||||
const ZoneSetLayoutType type = ZoneSetLayoutType::Custom;
|
||||
const auto customSetGuid = CreateGuidString();
|
||||
const auto expectedZoneSet = ZoneSetData{ customSetGuid, type };
|
||||
const auto data = DeviceInfoData{ expectedZoneSet, true, 16, 3 };
|
||||
const auto deviceInfo = DeviceInfoJSON{ m_uniqueId.str(), data };
|
||||
const auto json = DeviceInfoJSON::ToJson(deviceInfo);
|
||||
json::to_file(activeZoneSetTempPath, json);
|
||||
|
||||
const auto info = CanvasLayoutInfo{
|
||||
100, 100, std::vector{ CanvasLayoutInfo::Rect{ 0, 0, 100, 100 } }
|
||||
};
|
||||
const auto customZoneData = CustomZoneSetData{ L"name", CustomLayoutType::Canvas, info };
|
||||
const auto customZoneSet = CustomZoneSetJSON{ customSetGuid, customZoneData };
|
||||
auto customZoneJson = CustomZoneSetJSON::ToJson(customZoneSet);
|
||||
json::to_file(appliedZoneSetTempPath, customZoneJson);
|
||||
|
||||
//save same zone as deleted
|
||||
json::JsonObject deletedCustomZoneSets = {};
|
||||
json::JsonArray zonesArray{};
|
||||
zonesArray.Append(json::JsonValue::CreateStringValue(customZoneSet.uuid.substr(1, customZoneSet.uuid.size() - 2).c_str()));
|
||||
deletedCustomZoneSets.SetNamedValue(L"deleted-custom-zone-sets", zonesArray);
|
||||
json::to_file(deletedZonesTempPath, deletedCustomZoneSets);
|
||||
|
||||
m_fancyZonesData.ParseDeviceInfoFromTmpFile(activeZoneSetTempPath);
|
||||
m_fancyZonesData.ParseDeletedCustomZoneSetsFromTmpFile(deletedZonesTempPath);
|
||||
m_fancyZonesData.ParseCustomZoneSetFromTmpFile(appliedZoneSetTempPath);
|
||||
|
||||
//temp file read on initialization
|
||||
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
|
||||
testZoneWindow(actual);
|
||||
|
||||
Assert::IsNotNull(actual->ActiveZoneSet());
|
||||
const auto actualZoneSet = actual->ActiveZoneSet()->GetZones();
|
||||
Assert::AreEqual((size_t)1, actualZoneSet.size());
|
||||
}
|
||||
|
||||
TEST_METHOD(CreateZoneWindowWithActiveCustomZoneAppliedTmpFileWithUnusedDeletedCustomZones)
|
||||
{
|
||||
using namespace JSONHelpers;
|
||||
|
||||
//save required data
|
||||
const auto activeZoneSetTempPath = ZoneWindowUtils::GetActiveZoneSetTmpPath();
|
||||
const auto appliedZoneSetTempPath = ZoneWindowUtils::GetAppliedZoneSetTmpPath();
|
||||
const auto deletedZonesTempPath = ZoneWindowUtils::GetCustomZoneSetsTmpPath();
|
||||
|
||||
const ZoneSetLayoutType type = ZoneSetLayoutType::Custom;
|
||||
const auto customSetGuid = CreateGuidString();
|
||||
const auto expectedZoneSet = ZoneSetData{ customSetGuid, type };
|
||||
const auto data = DeviceInfoData{ expectedZoneSet, true, 16, 3 };
|
||||
const auto deviceInfo = DeviceInfoJSON{ m_uniqueId.str(), data };
|
||||
const auto json = DeviceInfoJSON::ToJson(deviceInfo);
|
||||
json::to_file(activeZoneSetTempPath, json);
|
||||
|
||||
const auto info = CanvasLayoutInfo{
|
||||
100, 100, std::vector{ CanvasLayoutInfo::Rect{ 0, 0, 100, 100 } }
|
||||
};
|
||||
const auto customZoneData = CustomZoneSetData{ L"name", CustomLayoutType::Canvas, info };
|
||||
const auto customZoneSet = CustomZoneSetJSON{ customSetGuid, customZoneData };
|
||||
auto customZoneJson = CustomZoneSetJSON::ToJson(customZoneSet);
|
||||
json::to_file(appliedZoneSetTempPath, customZoneJson);
|
||||
|
||||
//save different zone as deleted
|
||||
json::JsonObject deletedCustomZoneSets = {};
|
||||
json::JsonArray zonesArray{};
|
||||
const auto uuid = CreateGuidString();
|
||||
zonesArray.Append(json::JsonValue::CreateStringValue(uuid.substr(1, uuid.size() - 2).c_str()));
|
||||
deletedCustomZoneSets.SetNamedValue(L"deleted-custom-zone-sets", zonesArray);
|
||||
json::to_file(deletedZonesTempPath, deletedCustomZoneSets);
|
||||
|
||||
m_fancyZonesData.ParseDeviceInfoFromTmpFile(activeZoneSetTempPath);
|
||||
m_fancyZonesData.ParseDeletedCustomZoneSetsFromTmpFile(deletedZonesTempPath);
|
||||
m_fancyZonesData.ParseCustomZoneSetFromTmpFile(appliedZoneSetTempPath);
|
||||
|
||||
//temp file read on initialization
|
||||
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
|
||||
testZoneWindow(actual);
|
||||
|
||||
Assert::IsNotNull(actual->ActiveZoneSet());
|
||||
const auto actualZoneSet = actual->ActiveZoneSet()->GetZones();
|
||||
Assert::AreEqual((size_t)1, actualZoneSet.size());
|
||||
}
|
||||
|
||||
TEST_METHOD(MoveSizeEnter)
|
||||
{
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
|
||||
const auto expected = S_OK;
|
||||
const auto actual = m_zoneWindow->MoveSizeEnter(Mocks::Window(), true);
|
||||
|
||||
Assert::AreEqual(expected, actual);
|
||||
Assert::IsTrue(m_zoneWindow->IsDragEnabled());
|
||||
}
|
||||
|
||||
TEST_METHOD(MoveSizeEnterTwice)
|
||||
{
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
|
||||
const auto expected = E_INVALIDARG;
|
||||
|
||||
m_zoneWindow->MoveSizeEnter(Mocks::Window(), true);
|
||||
const auto actual = m_zoneWindow->MoveSizeEnter(Mocks::Window(), false);
|
||||
|
||||
Assert::AreEqual(expected, actual);
|
||||
Assert::IsTrue(m_zoneWindow->IsDragEnabled());
|
||||
}
|
||||
|
||||
TEST_METHOD(MoveSizeUpdate)
|
||||
{
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
|
||||
const auto expected = S_OK;
|
||||
const auto actual = m_zoneWindow->MoveSizeUpdate(POINT{ 0, 0 }, true);
|
||||
|
||||
Assert::AreEqual(expected, actual);
|
||||
Assert::IsTrue(m_zoneWindow->IsDragEnabled());
|
||||
}
|
||||
|
||||
TEST_METHOD(MoveSizeUpdatePointNegativeCoordinates)
|
||||
{
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
|
||||
const auto expected = S_OK;
|
||||
const auto actual = m_zoneWindow->MoveSizeUpdate(POINT{ -10, -10 }, true);
|
||||
|
||||
Assert::AreEqual(expected, actual);
|
||||
Assert::IsTrue(m_zoneWindow->IsDragEnabled());
|
||||
}
|
||||
|
||||
TEST_METHOD(MoveSizeUpdatePointBigCoordinates)
|
||||
{
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
|
||||
const auto expected = S_OK;
|
||||
const auto actual = m_zoneWindow->MoveSizeUpdate(POINT{ m_monitorInfo.rcMonitor.right + 1, m_monitorInfo.rcMonitor.bottom + 1 }, true);
|
||||
|
||||
Assert::AreEqual(expected, actual);
|
||||
Assert::IsTrue(m_zoneWindow->IsDragEnabled());
|
||||
}
|
||||
|
||||
TEST_METHOD(MoveSizeEnd)
|
||||
{
|
||||
auto zoneWindow = InitZoneWindowWithActiveZoneSet();
|
||||
|
||||
const auto window = Mocks::Window();
|
||||
zoneWindow->MoveSizeEnter(window, true);
|
||||
|
||||
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(), false);
|
||||
const auto actualZoneIndex = zoneSet->GetZoneIndexFromWindow(window);
|
||||
Assert::AreNotEqual(-1, actualZoneIndex);
|
||||
}
|
||||
|
||||
TEST_METHOD(MoveSizeEndWindowNotAdded)
|
||||
{
|
||||
auto zoneWindow = InitZoneWindowWithActiveZoneSet();
|
||||
|
||||
const auto window = Mocks::Window();
|
||||
zoneWindow->MoveSizeEnter(window, true);
|
||||
|
||||
const auto expected = S_OK;
|
||||
const auto actual = zoneWindow->MoveSizeEnd(window, POINT{ 0, 0 });
|
||||
Assert::AreEqual(expected, actual);
|
||||
|
||||
const auto zoneSet = zoneWindow->ActiveZoneSet();
|
||||
const auto actualZoneIndex = zoneSet->GetZoneIndexFromWindow(window);
|
||||
Assert::AreEqual(-1, actualZoneIndex);
|
||||
}
|
||||
|
||||
TEST_METHOD(MoveSizeEndDifferentWindows)
|
||||
{
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
|
||||
const auto window = Mocks::Window();
|
||||
m_zoneWindow->MoveSizeEnter(window, true);
|
||||
|
||||
const auto expected = E_INVALIDARG;
|
||||
const auto actual = m_zoneWindow->MoveSizeEnd(Mocks::Window(), POINT{ 0, 0 });
|
||||
|
||||
Assert::AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
TEST_METHOD(MoveSizeEndWindowNotSet)
|
||||
{
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
|
||||
const auto expected = E_INVALIDARG;
|
||||
const auto actual = m_zoneWindow->MoveSizeEnd(Mocks::Window(), POINT{ 0, 0 });
|
||||
|
||||
Assert::AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
TEST_METHOD(MoveSizeEndInvalidPoint)
|
||||
{
|
||||
auto zoneWindow = InitZoneWindowWithActiveZoneSet();
|
||||
|
||||
const auto window = Mocks::Window();
|
||||
zoneWindow->MoveSizeEnter(window, true);
|
||||
|
||||
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(), false);
|
||||
const auto actualZoneIndex = zoneSet->GetZoneIndexFromWindow(window);
|
||||
Assert::AreNotEqual(-1, actualZoneIndex); //with invalid point zone remains the same
|
||||
}
|
||||
|
||||
TEST_METHOD(MoveSizeCancel)
|
||||
{
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
|
||||
const auto expected = S_OK;
|
||||
const auto actual = m_zoneWindow->MoveSizeCancel();
|
||||
|
||||
Assert::AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
TEST_METHOD(MoveWindowIntoZoneByIndexNoActiveZoneSet)
|
||||
{
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
|
||||
|
||||
m_zoneWindow->MoveWindowIntoZoneByIndex(Mocks::Window(), 0);
|
||||
}
|
||||
|
||||
TEST_METHOD(MoveWindowIntoZoneByIndex)
|
||||
{
|
||||
m_zoneWindow = InitZoneWindowWithActiveZoneSet();
|
||||
Assert::IsNotNull(m_zoneWindow->ActiveZoneSet());
|
||||
|
||||
m_zoneWindow->MoveWindowIntoZoneByIndex(Mocks::Window(), 0);
|
||||
|
||||
const auto actual = m_zoneWindow->ActiveZoneSet();
|
||||
}
|
||||
|
||||
TEST_METHOD(MoveWindowIntoZoneByDirectionNoActiveZoneSet)
|
||||
{
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
|
||||
|
||||
m_zoneWindow->MoveWindowIntoZoneByIndex(Mocks::Window(), 0);
|
||||
}
|
||||
|
||||
TEST_METHOD(MoveWindowIntoZoneByDirection)
|
||||
{
|
||||
m_zoneWindow = InitZoneWindowWithActiveZoneSet();
|
||||
Assert::IsNotNull(m_zoneWindow->ActiveZoneSet());
|
||||
|
||||
const auto window = Mocks::WindowCreate(m_hInst);
|
||||
m_zoneWindow->MoveWindowIntoZoneByDirection(window, VK_RIGHT);
|
||||
|
||||
const auto actualAppZoneHistory = m_fancyZonesData.GetAppZoneHistoryMap();
|
||||
Assert::AreEqual((size_t)1, actualAppZoneHistory.size());
|
||||
const auto actual = actualAppZoneHistory.begin()->second;
|
||||
Assert::AreEqual(0, actual.zoneIndex);
|
||||
}
|
||||
|
||||
TEST_METHOD(MoveWindowIntoZoneByDirectionManyTimes)
|
||||
{
|
||||
m_zoneWindow = InitZoneWindowWithActiveZoneSet();
|
||||
Assert::IsNotNull(m_zoneWindow->ActiveZoneSet());
|
||||
|
||||
const auto window = Mocks::WindowCreate(m_hInst);
|
||||
m_zoneWindow->MoveWindowIntoZoneByDirection(window, VK_RIGHT);
|
||||
m_zoneWindow->MoveWindowIntoZoneByDirection(window, VK_RIGHT);
|
||||
m_zoneWindow->MoveWindowIntoZoneByDirection(window, VK_RIGHT);
|
||||
|
||||
const auto actualAppZoneHistory = m_fancyZonesData.GetAppZoneHistoryMap();
|
||||
Assert::AreEqual((size_t)1, actualAppZoneHistory.size());
|
||||
const auto actual = actualAppZoneHistory.begin()->second;
|
||||
Assert::AreEqual(2, actual.zoneIndex);
|
||||
}
|
||||
|
||||
TEST_METHOD(SaveWindowProcessToZoneIndexNoActiveZoneSet)
|
||||
{
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
|
||||
|
||||
m_zoneWindow->SaveWindowProcessToZoneIndex(Mocks::Window());
|
||||
|
||||
const auto actualAppZoneHistory = m_fancyZonesData.GetAppZoneHistoryMap();
|
||||
Assert::IsTrue(actualAppZoneHistory.empty());
|
||||
}
|
||||
|
||||
TEST_METHOD(SaveWindowProcessToZoneIndexNullptrWindow)
|
||||
{
|
||||
m_zoneWindow = InitZoneWindowWithActiveZoneSet();
|
||||
Assert::IsNotNull(m_zoneWindow->ActiveZoneSet());
|
||||
|
||||
m_zoneWindow->SaveWindowProcessToZoneIndex(nullptr);
|
||||
|
||||
const auto actualAppZoneHistory = m_fancyZonesData.GetAppZoneHistoryMap();
|
||||
Assert::IsTrue(actualAppZoneHistory.empty());
|
||||
}
|
||||
|
||||
TEST_METHOD(SaveWindowProcessToZoneIndexNoWindowAdded)
|
||||
{
|
||||
m_zoneWindow = InitZoneWindowWithActiveZoneSet();
|
||||
Assert::IsNotNull(m_zoneWindow->ActiveZoneSet());
|
||||
|
||||
auto window = Mocks::WindowCreate(m_hInst);
|
||||
auto zone = MakeZone(RECT{ 0, 0, 100, 100 });
|
||||
m_zoneWindow->ActiveZoneSet()->AddZone(zone);
|
||||
|
||||
m_zoneWindow->SaveWindowProcessToZoneIndex(window);
|
||||
|
||||
const auto actualAppZoneHistory = m_fancyZonesData.GetAppZoneHistoryMap();
|
||||
Assert::IsTrue(actualAppZoneHistory.empty());
|
||||
}
|
||||
|
||||
TEST_METHOD(SaveWindowProcessToZoneIndexNoWindowAddedWithFilledAppZoneHistory)
|
||||
{
|
||||
m_zoneWindow = InitZoneWindowWithActiveZoneSet();
|
||||
Assert::IsNotNull(m_zoneWindow->ActiveZoneSet());
|
||||
|
||||
const auto window = Mocks::WindowCreate(m_hInst);
|
||||
const auto processPath = get_process_path(window);
|
||||
const auto deviceId = m_zoneWindow->UniqueId();
|
||||
const auto zoneSetId = m_zoneWindow->ActiveZoneSet()->Id();
|
||||
|
||||
//fill app zone history map
|
||||
Assert::IsTrue(m_fancyZonesData.SetAppLastZone(window, deviceId, GuidString(zoneSetId), 0));
|
||||
Assert::AreEqual((size_t)1, m_fancyZonesData.GetAppZoneHistoryMap().size());
|
||||
Assert::AreEqual(0, m_fancyZonesData.GetAppZoneHistoryMap().at(processPath).zoneIndex);
|
||||
|
||||
//add zone without window
|
||||
const auto zone = MakeZone(RECT{ 0, 0, 100, 100 });
|
||||
m_zoneWindow->ActiveZoneSet()->AddZone(zone);
|
||||
|
||||
m_zoneWindow->SaveWindowProcessToZoneIndex(window);
|
||||
Assert::AreEqual((size_t)1, m_fancyZonesData.GetAppZoneHistoryMap().size());
|
||||
Assert::AreEqual(0, m_fancyZonesData.GetAppZoneHistoryMap().at(processPath).zoneIndex);
|
||||
}
|
||||
|
||||
TEST_METHOD(SaveWindowProcessToZoneIndexWindowAdded)
|
||||
{
|
||||
m_zoneWindow = InitZoneWindowWithActiveZoneSet();
|
||||
Assert::IsNotNull(m_zoneWindow->ActiveZoneSet());
|
||||
|
||||
auto window = Mocks::WindowCreate(m_hInst);
|
||||
const auto processPath = get_process_path(window);
|
||||
const auto deviceId = m_zoneWindow->UniqueId();
|
||||
const auto zoneSetId = m_zoneWindow->ActiveZoneSet()->Id();
|
||||
|
||||
auto zone = MakeZone(RECT{ 0, 0, 100, 100 });
|
||||
zone->AddWindowToZone(window, Mocks::Window(), false);
|
||||
m_zoneWindow->ActiveZoneSet()->AddZone(zone);
|
||||
|
||||
//fill app zone history map
|
||||
Assert::IsTrue(m_fancyZonesData.SetAppLastZone(window, deviceId, GuidString(zoneSetId), 2));
|
||||
Assert::AreEqual((size_t)1, m_fancyZonesData.GetAppZoneHistoryMap().size());
|
||||
Assert::AreEqual(2, m_fancyZonesData.GetAppZoneHistoryMap().at(processPath).zoneIndex);
|
||||
|
||||
m_zoneWindow->SaveWindowProcessToZoneIndex(window);
|
||||
|
||||
const auto actualAppZoneHistory = m_fancyZonesData.GetAppZoneHistoryMap();
|
||||
Assert::AreEqual((size_t)1, actualAppZoneHistory.size());
|
||||
const auto expected = m_zoneWindow->ActiveZoneSet()->GetZoneIndexFromWindow(window);
|
||||
const auto actual = m_fancyZonesData.GetAppZoneHistoryMap().at(processPath).zoneIndex;
|
||||
Assert::AreEqual(expected, actual);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user