terminal/src/host/ft_host/API_FontTests.cpp
Dustin Howett a89b66f770 Merged PR 6598109: [Git2Git] Pull Request 6508625: Update TAEF to vPack 10.63 (latest)
A change required significant changes in TAEF published headers. This PR consumes those changes.

Related work items: #20301352
2021-11-09 19:21:35 +00:00

297 lines
12 KiB
C++

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "precomp.h"
using namespace WEX::TestExecution;
using namespace WEX::Common;
using namespace WEX::Logging;
static const COORD c_coordZero = { 0, 0 };
static const PCWSTR pwszLongFontPath = L"%WINDIR%\\Fonts\\ltype.ttf";
class FontTests
{
BEGIN_TEST_CLASS(FontTests)
END_TEST_CLASS()
TEST_METHOD_SETUP(TestSetup);
TEST_METHOD_CLEANUP(TestCleanup);
BEGIN_TEST_METHOD(TestCurrentFontAPIsInvalid)
TEST_METHOD_PROPERTY(L"Data:dwConsoleOutput", L"{0, 1, 0xFFFFFFFF}")
TEST_METHOD_PROPERTY(L"Data:bMaximumWindow", L"{TRUE, FALSE}")
TEST_METHOD_PROPERTY(L"Data:strOperation", L"{Get, GetEx, SetEx}")
END_TEST_METHOD();
BEGIN_TEST_METHOD(TestGetFontSizeInvalid)
TEST_METHOD_PROPERTY(L"Data:dwConsoleOutput", L"{0, 0xFFFFFFFF}")
END_TEST_METHOD();
TEST_METHOD(TestGetFontSizeLargeIndexInvalid);
TEST_METHOD(TestSetConsoleFontNegativeSize);
TEST_METHOD(TestFontScenario);
TEST_METHOD(TestLongFontNameScenario);
TEST_METHOD(TestSetFontAdjustsWindow);
};
bool FontTests::TestSetup()
{
SetVerifyOutput verifySettings(VerifyOutputSettings::LogOnlyFailures);
return true;
}
bool FontTests::TestCleanup()
{
SetVerifyOutput verifySettings(VerifyOutputSettings::LogOnlyFailures);
return true;
}
void FontTests::TestCurrentFontAPIsInvalid()
{
DWORD dwConsoleOutput;
bool bMaximumWindow;
String strOperation;
VERIFY_SUCCEEDED(TestData::TryGetValue(L"dwConsoleOutput", dwConsoleOutput), L"Get output handle value");
VERIFY_SUCCEEDED(TestData::TryGetValue(L"bMaximumWindow", bMaximumWindow), L"Get maximized window value");
VERIFY_SUCCEEDED(TestData::TryGetValue(L"strOperation", strOperation), L"Get operation value");
const bool bUseValidOutputHandle = (dwConsoleOutput == 1);
HANDLE hConsoleOutput;
if (bUseValidOutputHandle)
{
hConsoleOutput = GetStdOutputHandle();
}
else
{
hConsoleOutput = (HANDLE)dwConsoleOutput;
}
if (strOperation == L"Get")
{
CONSOLE_FONT_INFO cfi = { 0 };
if (bUseValidOutputHandle)
{
VERIFY_WIN32_BOOL_SUCCEEDED(OneCoreDelay::GetCurrentConsoleFont(hConsoleOutput, (BOOL)bMaximumWindow, &cfi));
}
else
{
VERIFY_WIN32_BOOL_FAILED(OneCoreDelay::GetCurrentConsoleFont(hConsoleOutput, (BOOL)bMaximumWindow, &cfi));
}
}
else if (strOperation == L"GetEx")
{
CONSOLE_FONT_INFOEX cfie = { 0 };
VERIFY_WIN32_BOOL_FAILED(OneCoreDelay::GetCurrentConsoleFontEx(hConsoleOutput, (BOOL)bMaximumWindow, &cfie));
}
else if (strOperation == L"SetEx")
{
CONSOLE_FONT_INFOEX cfie = { 0 };
VERIFY_WIN32_BOOL_FAILED(OneCoreDelay::SetCurrentConsoleFontEx(hConsoleOutput, (BOOL)bMaximumWindow, &cfie));
}
else
{
VERIFY_FAIL(L"Unrecognized operation");
}
}
void FontTests::TestGetFontSizeInvalid()
{
DWORD dwConsoleOutput;
VERIFY_SUCCEEDED(TestData::TryGetValue(L"dwConsoleOutput", dwConsoleOutput), L"Get input handle value");
// Need to make sure that last error is cleared so that we can verify that lasterror was set by GetConsoleFontSize
SetLastError(0);
COORD coordFontSize = OneCoreDelay::GetConsoleFontSize((HANDLE)dwConsoleOutput, 0);
VERIFY_ARE_EQUAL(coordFontSize, c_coordZero, L"Ensure (0,0) coord returned to indicate failure");
VERIFY_ARE_EQUAL(GetLastError(), (DWORD)ERROR_INVALID_HANDLE, L"Ensure last error was set appropriately");
}
void FontTests::TestGetFontSizeLargeIndexInvalid()
{
SetLastError(0);
COORD coordFontSize = OneCoreDelay::GetConsoleFontSize(GetStdOutputHandle(), 0xFFFFFFFF);
VERIFY_ARE_EQUAL(coordFontSize, c_coordZero, L"Ensure (0,0) coord returned to indicate failure");
VERIFY_ARE_EQUAL(GetLastError(), (DWORD)ERROR_INVALID_PARAMETER, L"Ensure last error was set appropriately");
}
void FontTests::TestSetConsoleFontNegativeSize()
{
const HANDLE hConsoleOutput = GetStdOutputHandle();
CONSOLE_FONT_INFOEX cfie = { 0 };
cfie.cbSize = sizeof(cfie);
VERIFY_WIN32_BOOL_SUCCEEDED(OneCoreDelay::GetCurrentConsoleFontEx(hConsoleOutput, FALSE, &cfie));
cfie.dwFontSize.X = -4;
cfie.dwFontSize.Y = -12;
// as strange as it sounds, we don't filter out negative font sizes. under the hood, this call ends up in
// FindCreateFont, which runs through our list of loaded fonts, fails to find, takes the absolute value of Y, and
// then performs a GDI font enumeration for fonts that match. we should hold on to this behavior until we can
// establish that it's no longer necessary.
VERIFY_WIN32_BOOL_SUCCEEDED(OneCoreDelay::SetCurrentConsoleFontEx(hConsoleOutput, FALSE, &cfie));
}
void FontTests::TestFontScenario()
{
const HANDLE hConsoleOutput = GetStdOutputHandle();
Log::Comment(L"1. Ensure that the various GET APIs for font information align with each other.");
CONSOLE_FONT_INFOEX cfie = { 0 };
cfie.cbSize = sizeof(cfie);
VERIFY_WIN32_BOOL_SUCCEEDED(OneCoreDelay::GetCurrentConsoleFontEx(hConsoleOutput, FALSE, &cfie));
CONSOLE_FONT_INFO cfi = { 0 };
VERIFY_WIN32_BOOL_SUCCEEDED(OneCoreDelay::GetCurrentConsoleFont(hConsoleOutput, FALSE, &cfi));
VERIFY_ARE_EQUAL(cfi.nFont, cfie.nFont, L"Ensure regular and Ex APIs return same nFont");
VERIFY_ARE_NOT_EQUAL(cfi.dwFontSize, c_coordZero, L"Ensure non-zero font size");
VERIFY_ARE_EQUAL(cfi.dwFontSize, cfie.dwFontSize, L"Ensure regular and Ex APIs return same dwFontSize");
const COORD coordCurrentFontSize = OneCoreDelay::GetConsoleFontSize(hConsoleOutput, cfi.nFont);
VERIFY_ARE_EQUAL(coordCurrentFontSize, cfi.dwFontSize, L"Ensure GetConsoleFontSize output matches GetCurrentConsoleFont");
// ---------------------
Log::Comment(L"2. Ensure that our font settings round-trip appropriately through the Ex APIs");
CONSOLE_FONT_INFOEX cfieSet = { 0 };
cfieSet.cbSize = sizeof(cfieSet);
cfieSet.dwFontSize.Y = 12;
VERIFY_SUCCEEDED(StringCchCopy(cfieSet.FaceName, ARRAYSIZE(cfieSet.FaceName), L"Lucida Console"));
VERIFY_WIN32_BOOL_SUCCEEDED(OneCoreDelay::SetCurrentConsoleFontEx(hConsoleOutput, FALSE, &cfieSet));
CONSOLE_FONT_INFOEX cfiePost = { 0 };
cfiePost.cbSize = sizeof(cfiePost);
VERIFY_WIN32_BOOL_SUCCEEDED(OneCoreDelay::GetCurrentConsoleFontEx(hConsoleOutput, FALSE, &cfiePost));
// Ensure that the two values we attempted to set did accurately round-trip through the API.
// The other unspecified values may have been adjusted/updated by GDI.
if (0 != NoThrowString(cfieSet.FaceName).CompareNoCase(cfiePost.FaceName))
{
Log::Comment(L"We cannot test changing fonts on systems that do not have alternatives available. Skipping test.");
Log::Result(WEX::Logging::TestResults::Result::Skipped);
return;
}
VERIFY_ARE_EQUAL(cfieSet.dwFontSize.Y, cfiePost.dwFontSize.Y);
// Ensure that the entire structure we received matches what we expect to usually get for this Lucida Console Size 12 ask.
CONSOLE_FONT_INFOEX cfieFullExpected = { 0 };
cfieFullExpected.cbSize = sizeof(cfieFullExpected);
wcscpy_s(cfieFullExpected.FaceName, L"Lucida Console");
if (!OneCoreDelay::IsIsWindowPresent())
{
// On OneCore Windows without GDI, this is what we expect to get.
cfieFullExpected.dwFontSize.X = 8;
cfieFullExpected.dwFontSize.Y = 12;
cfieFullExpected.FontFamily = 4;
cfieFullExpected.FontWeight = 0;
}
else
{
// On client Windows with GDI, this is what we expect to get.
cfieFullExpected.dwFontSize.X = 7;
cfieFullExpected.dwFontSize.Y = 12;
cfieFullExpected.FontFamily = 54;
cfieFullExpected.FontWeight = 400;
}
VERIFY_ARE_EQUAL(cfieFullExpected, cfiePost);
}
void FontTests::TestLongFontNameScenario()
{
std::wstring expandedLongFontPath = wil::ExpandEnvironmentStringsW<std::wstring>(pwszLongFontPath);
if (!CheckIfFileExists(expandedLongFontPath.c_str()))
{
Log::Comment(L"Lucida Sans Typewriter doesn't exist; skipping long font test.");
Log::Result(WEX::Logging::TestResults::Result::Skipped);
return;
}
const HANDLE hConsoleOutput = GetStdOutputHandle();
CONSOLE_FONT_INFOEX cfieSetLong = { 0 };
cfieSetLong.cbSize = sizeof(cfieSetLong);
cfieSetLong.FontFamily = 54;
cfieSetLong.dwFontSize.Y = 12;
VERIFY_SUCCEEDED(StringCchCopy(cfieSetLong.FaceName, ARRAYSIZE(cfieSetLong.FaceName), L"Lucida Sans Typewriter"));
VERIFY_WIN32_BOOL_SUCCEEDED(OneCoreDelay::SetCurrentConsoleFontEx(hConsoleOutput, FALSE, &cfieSetLong));
CONSOLE_FONT_INFOEX cfiePostLong = { 0 };
cfiePostLong.cbSize = sizeof(cfiePostLong);
VERIFY_WIN32_BOOL_SUCCEEDED(OneCoreDelay::GetCurrentConsoleFontEx(hConsoleOutput, FALSE, &cfiePostLong));
Log::Comment(NoThrowString().Format(L"%ls %ls", cfieSetLong.FaceName, cfiePostLong.FaceName));
VERIFY_ARE_EQUAL(0, NoThrowString(cfieSetLong.FaceName).CompareNoCase(cfiePostLong.FaceName));
}
void FontTests::TestSetFontAdjustsWindow()
{
if (!OneCoreDelay::IsIsWindowPresent())
{
Log::Comment(L"Adjusting window size by changing font scenario can't be checked on platform without classic window operations.");
Log::Result(WEX::Logging::TestResults::Skipped);
return;
}
const HANDLE hConsoleOutput = GetStdOutputHandle();
const HWND hwnd = GetConsoleWindow();
VERIFY_IS_TRUE(!!IsWindow(hwnd));
RECT rc = { 0 };
CONSOLE_FONT_INFOEX cfiex = { 0 };
cfiex.cbSize = sizeof(cfiex);
Log::Comment(L"First set the console window to Consolas 16.");
wcscpy_s(cfiex.FaceName, L"Consolas");
cfiex.dwFontSize.Y = 16;
VERIFY_WIN32_BOOL_SUCCEEDED(OneCoreDelay::SetCurrentConsoleFontEx(hConsoleOutput, FALSE, &cfiex));
Sleep(250);
VERIFY_WIN32_BOOL_SUCCEEDED(GetClientRect(hwnd, &rc), L"Retrieve client rectangle size for Consolas 16.");
SIZE szConsolas;
szConsolas.cx = rc.right - rc.left;
szConsolas.cy = rc.bottom - rc.top;
Log::Comment(NoThrowString().Format(L"Client rect size is (X: %d, Y: %d)", szConsolas.cx, szConsolas.cy));
Log::Comment(L"Adjust console window to Lucida Console 12.");
wcscpy_s(cfiex.FaceName, L"Lucida Console");
cfiex.dwFontSize.Y = 12;
VERIFY_WIN32_BOOL_SUCCEEDED(OneCoreDelay::SetCurrentConsoleFontEx(hConsoleOutput, FALSE, &cfiex));
Sleep(250);
VERIFY_WIN32_BOOL_SUCCEEDED(GetClientRect(hwnd, &rc), L"Retrieve client rectangle size for Lucida Console 12.");
SIZE szLucida;
szLucida.cx = rc.right - rc.left;
szLucida.cy = rc.bottom - rc.top;
Log::Comment(NoThrowString().Format(L"Client rect size is (X: %d, Y: %d)", szLucida.cx, szLucida.cy));
Log::Comment(L"Window should shrink in size when going to Lucida 12 from Consolas 16.");
VERIFY_IS_LESS_THAN(szLucida.cx, szConsolas.cx);
VERIFY_IS_LESS_THAN(szLucida.cy, szConsolas.cy);
Log::Comment(L"Adjust console window back to Consolas 16.");
wcscpy_s(cfiex.FaceName, L"Consolas");
cfiex.dwFontSize.Y = 16;
VERIFY_WIN32_BOOL_SUCCEEDED(OneCoreDelay::SetCurrentConsoleFontEx(hConsoleOutput, FALSE, &cfiex));
Sleep(250);
VERIFY_WIN32_BOOL_SUCCEEDED(GetClientRect(hwnd, &rc), L"Retrieve client rectangle size for Consolas 16.");
szConsolas.cx = rc.right - rc.left;
szConsolas.cy = rc.bottom - rc.top;
Log::Comment(NoThrowString().Format(L"Client rect size is (X: %d, Y: %d)", szConsolas.cx, szConsolas.cy));
Log::Comment(L"Window should grow in size when going from Lucida 12 to Consolas 16.");
VERIFY_IS_LESS_THAN(szLucida.cx, szConsolas.cx);
VERIFY_IS_LESS_THAN(szLucida.cy, szConsolas.cy);
}