terminal/src/host/ut_host/ReadWaitTests.cpp
2021-11-25 00:28:27 +01:00

130 lines
4.6 KiB
C++

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "precomp.h"
#include "WexTestClass.h"
#include "../../inc/consoletaeftemplates.hpp"
#include "misc.h"
#include "dbcs.h"
#include "../../types/inc/IInputEvent.hpp"
#include "../interactivity/inc/ServiceLocator.hpp"
#include <deque>
#include <memory>
using namespace WEX::Logging;
using Microsoft::Console::Interactivity::ServiceLocator;
class InputRecordConversionTests
{
TEST_CLASS(InputRecordConversionTests);
static const size_t INPUT_RECORD_COUNT = 10;
UINT savedCodepage = 0;
TEST_CLASS_SETUP(ClassSetup)
{
CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
savedCodepage = gci.CP;
gci.CP = CP_JAPANESE;
VERIFY_IS_TRUE(!!GetCPInfo(gci.CP, &gci.CPInfo));
return true;
}
TEST_CLASS_CLEANUP(ClassCleanup)
{
CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
gci.CP = savedCodepage;
VERIFY_IS_TRUE(!!GetCPInfo(gci.CP, &gci.CPInfo));
return true;
}
TEST_METHOD(SplitToOemLeavesNonKeyEventsAlone)
{
Log::Comment(L"nothing should happen to input events that aren't key events");
std::deque<std::unique_ptr<IInputEvent>> inEvents;
INPUT_RECORD inRecords[INPUT_RECORD_COUNT] = { 0 };
for (size_t i = 0; i < INPUT_RECORD_COUNT; ++i)
{
inRecords[i].EventType = MOUSE_EVENT;
inRecords[i].Event.MouseEvent.dwMousePosition.X = static_cast<SHORT>(i);
inRecords[i].Event.MouseEvent.dwMousePosition.Y = static_cast<SHORT>(i * 2);
inEvents.push_back(IInputEvent::Create(inRecords[i]));
}
SplitToOem(inEvents);
VERIFY_ARE_EQUAL(INPUT_RECORD_COUNT, inEvents.size());
for (size_t i = 0; i < INPUT_RECORD_COUNT; ++i)
{
VERIFY_ARE_EQUAL(inRecords[i], inEvents[i]->ToInputRecord());
}
}
TEST_METHOD(SplitToOemLeavesNonDbcsCharsAlone)
{
Log::Comment(L"non-dbcs chars shouldn't be split");
std::deque<std::unique_ptr<IInputEvent>> inEvents;
INPUT_RECORD inRecords[INPUT_RECORD_COUNT] = { 0 };
for (size_t i = 0; i < INPUT_RECORD_COUNT; ++i)
{
inRecords[i].EventType = KEY_EVENT;
inRecords[i].Event.KeyEvent.uChar.UnicodeChar = static_cast<wchar_t>(L'a' + i);
inEvents.push_back(IInputEvent::Create(inRecords[i]));
}
SplitToOem(inEvents);
VERIFY_ARE_EQUAL(INPUT_RECORD_COUNT, inEvents.size());
for (size_t i = 0; i < INPUT_RECORD_COUNT; ++i)
{
VERIFY_ARE_EQUAL(inRecords[i], inEvents[i]->ToInputRecord());
}
}
TEST_METHOD(SplitToOemSplitsDbcsChars)
{
Log::Comment(L"dbcs chars should be split");
const UINT codepage = ServiceLocator::LocateGlobals().getConsoleInformation().CP;
INPUT_RECORD inRecords[INPUT_RECORD_COUNT * 2] = { 0 };
std::deque<std::unique_ptr<IInputEvent>> inEvents;
// U+3042 hiragana letter A
wchar_t hiraganaA = 0x3042;
wchar_t inChars[INPUT_RECORD_COUNT];
for (size_t i = 0; i < INPUT_RECORD_COUNT; ++i)
{
wchar_t currentChar = static_cast<wchar_t>(hiraganaA + (i * 2));
inRecords[i].EventType = KEY_EVENT;
inRecords[i].Event.KeyEvent.uChar.UnicodeChar = currentChar;
inChars[i] = currentChar;
inEvents.push_back(IInputEvent::Create(inRecords[i]));
}
SplitToOem(inEvents);
VERIFY_ARE_EQUAL(INPUT_RECORD_COUNT * 2, inEvents.size());
// create the data to compare the output to
char dbcsChars[INPUT_RECORD_COUNT * 2] = { 0 };
int writtenBytes = WideCharToMultiByte(codepage,
0,
inChars,
INPUT_RECORD_COUNT,
dbcsChars,
INPUT_RECORD_COUNT * 2,
nullptr,
FALSE);
VERIFY_ARE_EQUAL(writtenBytes, static_cast<int>(INPUT_RECORD_COUNT * 2));
for (size_t i = 0; i < INPUT_RECORD_COUNT * 2; ++i)
{
const KeyEvent* const pKeyEvent = static_cast<const KeyEvent* const>(inEvents[i].get());
VERIFY_ARE_EQUAL(static_cast<char>(pKeyEvent->GetCharData()), dbcsChars[i]);
}
}
};