terminal/src/host/ut_host/CodepointWidthDetectorTests...

102 lines
3.4 KiB
C++

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "precomp.h"
#include "WexTestClass.h"
#include "../../inc/consoletaeftemplates.hpp"
#include "CommonState.hpp"
#include "../types/inc/CodepointWidthDetector.hpp"
using namespace WEX::Logging;
static constexpr std::wstring_view emoji = L"\xD83E\xDD22"; // U+1F922 nauseated face
static constexpr std::wstring_view ambiguous = L"\x414"; // U+0414 cyrillic capital de
// codepoint and utf16 encoded string
static const std::vector<std::tuple<unsigned int, std::wstring, CodepointWidth>> testData = {
{ 0x7, L"\a", CodepointWidth::Narrow }, // BEL
{ 0x20, L" ", CodepointWidth::Narrow },
{ 0x39, L"9", CodepointWidth::Narrow },
{ 0x414, L"\x414", CodepointWidth::Ambiguous }, // U+0414 cyrillic capital de
{ 0x1104, L"\x1104", CodepointWidth::Wide }, // U+1104 hangul choseong ssangtikeut
{ 0x306A, L"\x306A", CodepointWidth::Wide }, // U+306A hiragana na
{ 0x30CA, L"\x30CA", CodepointWidth::Wide }, // U+30CA katakana na
{ 0x72D7, L"\x72D7", CodepointWidth::Wide }, // U+72D7
{ 0x1F47E, L"\xD83D\xDC7E", CodepointWidth::Wide }, // U+1F47E alien monster
{ 0x1F51C, L"\xD83D\xDD1C", CodepointWidth::Wide } // U+1F51C SOON
};
class CodepointWidthDetectorTests
{
TEST_CLASS(CodepointWidthDetectorTests);
TEST_METHOD(CanLookUpEmoji)
{
CodepointWidthDetector widthDetector;
VERIFY_IS_TRUE(widthDetector.IsWide(emoji));
}
TEST_METHOD(CanExtractCodepoint)
{
CodepointWidthDetector widthDetector;
for (const auto& data : testData)
{
const auto& expected = std::get<0>(data);
const auto& wstr = std::get<1>(data);
const auto result = widthDetector._extractCodepoint({ wstr.c_str(), wstr.size() });
VERIFY_ARE_EQUAL(result, expected);
}
}
TEST_METHOD(CanGetWidths)
{
CodepointWidthDetector widthDetector;
for (const auto& data : testData)
{
const auto& expected = std::get<2>(data);
const auto& wstr = std::get<1>(data);
const auto result = widthDetector.GetWidth({ wstr.c_str(), wstr.size() });
VERIFY_ARE_EQUAL(result, expected);
}
}
static bool FallbackMethod(const std::wstring_view glyph)
{
if (glyph.size() < 1)
{
return false;
}
else
{
return (glyph.at(0) % 2) == 1;
}
}
TEST_METHOD(AmbiguousCache)
{
// Set up a detector with fallback.
CodepointWidthDetector widthDetector;
widthDetector.SetFallbackMethod(std::bind(&FallbackMethod, std::placeholders::_1));
// Ensure fallback cache is empty.
VERIFY_ARE_EQUAL(0u, widthDetector._fallbackCache.size());
// Lookup ambiguous width character.
widthDetector.IsWide(ambiguous);
// Cache should hold it.
VERIFY_ARE_EQUAL(1u, widthDetector._fallbackCache.size());
// Cached item should match what we expect
const auto it = widthDetector._fallbackCache.begin();
VERIFY_ARE_EQUAL(ambiguous, it->first);
VERIFY_ARE_EQUAL(FallbackMethod(ambiguous), it->second);
// Cache should empty when font changes.
widthDetector.NotifyFontChanged();
VERIFY_ARE_EQUAL(0u, widthDetector._fallbackCache.size());
}
};